FFmpeg
error_resilience.c
Go to the documentation of this file.
1 /*
2  * Error resilience / concealment
3  *
4  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * Error resilience / concealment.
26  */
27 
28 #include <limits.h>
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/attributes.h"
32 #include "libavutil/mem.h"
33 #include "avcodec.h"
34 #include "error_resilience.h"
35 #include "mathops.h"
36 #include "me_cmp.h"
37 #include "mpegutils.h"
38 #include "mpegvideo.h"
39 #include "threadframe.h"
40 #include "threadprogress.h"
41 
43 {
44  MECmpContext mecc;
45  unsigned mb_array_size = s->mb_height * s->mb_stride;
46 
47  s->error_status_table = av_mallocz(mb_array_size);
48  if (!s->error_status_table)
49  return AVERROR(ENOMEM);
50  s->er_temp_buffer = av_malloc_array(mb_array_size, 4*sizeof(int) + 1);
51  if (!s->er_temp_buffer)
52  return AVERROR(ENOMEM);
53 
54  ff_me_cmp_init(&mecc, s->avctx);
55  s->sad = mecc.sad[0];
56 
57  return 0;
58 }
59 
60 /**
61  * @param stride the number of MVs to get to the next row
62  * @param mv_step the number of MVs per row or column in a macroblock
63  */
64 static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
65 {
66  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
67  av_assert0(s->quarter_sample);
68  *mv_step = 4;
69  *stride = s->mb_width * 4;
70  } else {
71  *mv_step = 2;
72  *stride = s->b8_stride;
73  }
74 }
75 
76 /**
77  * Replace the current MB with a flat dc-only version.
78  */
79 static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
80  uint8_t *dest_cr, int mb_x, int mb_y)
81 {
82  int *linesize = s->cur_pic.f->linesize;
83  int dc, dcu, dcv, y, i;
84  for (i = 0; i < 4; i++) {
85  dc = s->dc_val[0][mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
86  if (dc < 0)
87  dc = 0;
88  else if (dc > 2040)
89  dc = 2040;
90  for (y = 0; y < 8; y++) {
91  int x;
92  for (x = 0; x < 8; x++)
93  dest_y[x + (i & 1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
94  }
95  }
96  dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
97  dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
98  if (dcu < 0)
99  dcu = 0;
100  else if (dcu > 2040)
101  dcu = 2040;
102  if (dcv < 0)
103  dcv = 0;
104  else if (dcv > 2040)
105  dcv = 2040;
106 
107  if (dest_cr)
108  for (y = 0; y < 8; y++) {
109  int x;
110  for (x = 0; x < 8; x++) {
111  dest_cb[x + y * linesize[1]] = dcu / 8;
112  dest_cr[x + y * linesize[2]] = dcv / 8;
113  }
114  }
115 }
116 
117 static void filter181(int16_t *data, int width, int height, ptrdiff_t stride)
118 {
119  int x, y;
120 
121  /* horizontal filter */
122  for (y = 1; y < height - 1; y++) {
123  int prev_dc = data[0 + y * stride];
124 
125  for (x = 1; x < width - 1; x++) {
126  int dc;
127  dc = -prev_dc +
128  data[x + y * stride] * 8 -
129  data[x + 1 + y * stride];
130  dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
131  prev_dc = data[x + y * stride];
132  data[x + y * stride] = dc;
133  }
134  }
135 
136  /* vertical filter */
137  for (x = 1; x < width - 1; x++) {
138  int prev_dc = data[x];
139 
140  for (y = 1; y < height - 1; y++) {
141  int dc;
142 
143  dc = -prev_dc +
144  data[x + y * stride] * 8 -
145  data[x + (y + 1) * stride];
146  dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
147  prev_dc = data[x + y * stride];
148  data[x + y * stride] = dc;
149  }
150  }
151 }
152 
153 /**
154  * guess the dc of blocks which do not have an undamaged dc
155  * @param w width in 8 pixel blocks
156  * @param h height in 8 pixel blocks
157  */
158 static void guess_dc(ERContext *s, int16_t *dc, int w,
159  int h, ptrdiff_t stride, int is_luma)
160 {
161  int b_x, b_y;
162  int16_t (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4);
163  uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4);
164 
165  if(!col || !dist) {
166  av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
167  goto fail;
168  }
169 
170  for(b_y=0; b_y<h; b_y++){
171  int color= 1024;
172  int distance= -1;
173  for(b_x=0; b_x<w; b_x++){
174  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
175  int error_j= s->error_status_table[mb_index_j];
176  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
177  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
178  color= dc[b_x + b_y*stride];
179  distance= b_x;
180  }
181  col [b_x + b_y*stride][1]= color;
182  dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
183  }
184  color= 1024;
185  distance= -1;
186  for(b_x=w-1; b_x>=0; b_x--){
187  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
188  int error_j= s->error_status_table[mb_index_j];
189  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
190  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
191  color= dc[b_x + b_y*stride];
192  distance= b_x;
193  }
194  col [b_x + b_y*stride][0]= color;
195  dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
196  }
197  }
198  for(b_x=0; b_x<w; b_x++){
199  int color= 1024;
200  int distance= -1;
201  for(b_y=0; b_y<h; b_y++){
202  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
203  int error_j= s->error_status_table[mb_index_j];
204  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
205  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
206  color= dc[b_x + b_y*stride];
207  distance= b_y;
208  }
209  col [b_x + b_y*stride][3]= color;
210  dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
211  }
212  color= 1024;
213  distance= -1;
214  for(b_y=h-1; b_y>=0; b_y--){
215  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
216  int error_j= s->error_status_table[mb_index_j];
217  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
218  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
219  color= dc[b_x + b_y*stride];
220  distance= b_y;
221  }
222  col [b_x + b_y*stride][2]= color;
223  dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
224  }
225  }
226 
227  for (b_y = 0; b_y < h; b_y++) {
228  for (b_x = 0; b_x < w; b_x++) {
229  int mb_index, error, j;
230  int64_t guess, weight_sum;
231  mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
232  error = s->error_status_table[mb_index];
233 
234  if (IS_INTER(s->cur_pic.mb_type[mb_index]))
235  continue; // inter
236  if (!(error & ER_DC_ERROR))
237  continue; // dc-ok
238 
239  weight_sum = 0;
240  guess = 0;
241  for (j = 0; j < 4; j++) {
242  int64_t weight = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
243  guess += weight*(int64_t)col[b_x + b_y*stride][j];
244  weight_sum += weight;
245  }
246  guess = (guess + weight_sum / 2) / weight_sum;
247  dc[b_x + b_y * stride] = guess;
248  }
249  }
250 
251 fail:
252  av_freep(&col);
253  av_freep(&dist);
254 }
255 
256 /**
257  * simple horizontal deblocking filter used for error resilience
258  * @param w width in 8 pixel blocks
259  * @param h height in 8 pixel blocks
260  */
261 static void h_block_filter(ERContext *s, uint8_t *dst, int w,
262  int h, ptrdiff_t stride, int is_luma)
263 {
264  int b_x, b_y;
265  ptrdiff_t mvx_stride, mvy_stride;
266  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
267  set_mv_strides(s, &mvx_stride, &mvy_stride);
268  mvx_stride >>= is_luma;
269  mvy_stride *= mvx_stride;
270 
271  for (b_y = 0; b_y < h; b_y++) {
272  for (b_x = 0; b_x < w - 1; b_x++) {
273  int y;
274  int left_status = s->error_status_table[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
275  int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
276  int left_intra = IS_INTRA(s->cur_pic.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
277  int right_intra = IS_INTRA(s->cur_pic.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
278  int left_damage = left_status & ER_MB_ERROR;
279  int right_damage = right_status & ER_MB_ERROR;
280  int offset = b_x * 8 + b_y * stride * 8;
281  int16_t *left_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
282  int16_t *right_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
283  if (!(left_damage || right_damage))
284  continue; // both undamaged
285  if ((!left_intra) && (!right_intra) &&
286  FFABS(left_mv[0] - right_mv[0]) +
287  FFABS(left_mv[1] + right_mv[1]) < 2)
288  continue;
289 
290  for (y = 0; y < 8; y++) {
291  int a, b, c, d;
292 
293  a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
294  b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
295  c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];
296 
297  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
298  d = FFMAX(d, 0);
299  if (b < 0)
300  d = -d;
301 
302  if (d == 0)
303  continue;
304 
305  if (!(left_damage && right_damage))
306  d = d * 16 / 9;
307 
308  if (left_damage) {
309  dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
310  dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
311  dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
312  dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
313  }
314  if (right_damage) {
315  dst[offset + 8 + y * stride] = cm[dst[offset + 8 + y * stride] - ((d * 7) >> 4)];
316  dst[offset + 9 + y * stride] = cm[dst[offset + 9 + y * stride] - ((d * 5) >> 4)];
317  dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
318  dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)];
319  }
320  }
321  }
322  }
323 }
324 
325 /**
326  * simple vertical deblocking filter used for error resilience
327  * @param w width in 8 pixel blocks
328  * @param h height in 8 pixel blocks
329  */
330 static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
331  ptrdiff_t stride, int is_luma)
332 {
333  int b_x, b_y;
334  ptrdiff_t mvx_stride, mvy_stride;
335  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
336  set_mv_strides(s, &mvx_stride, &mvy_stride);
337  mvx_stride >>= is_luma;
338  mvy_stride *= mvx_stride;
339 
340  for (b_y = 0; b_y < h - 1; b_y++) {
341  for (b_x = 0; b_x < w; b_x++) {
342  int x;
343  int top_status = s->error_status_table[(b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
344  int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
345  int top_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]);
346  int bottom_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
347  int top_damage = top_status & ER_MB_ERROR;
348  int bottom_damage = bottom_status & ER_MB_ERROR;
349  int offset = b_x * 8 + b_y * stride * 8;
350 
351  int16_t *top_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
352  int16_t *bottom_mv = s->cur_pic.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
353 
354  if (!(top_damage || bottom_damage))
355  continue; // both undamaged
356 
357  if ((!top_intra) && (!bottom_intra) &&
358  FFABS(top_mv[0] - bottom_mv[0]) +
359  FFABS(top_mv[1] + bottom_mv[1]) < 2)
360  continue;
361 
362  for (x = 0; x < 8; x++) {
363  int a, b, c, d;
364 
365  a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
366  b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
367  c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
368 
369  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
370  d = FFMAX(d, 0);
371  if (b < 0)
372  d = -d;
373 
374  if (d == 0)
375  continue;
376 
377  if (!(top_damage && bottom_damage))
378  d = d * 16 / 9;
379 
380  if (top_damage) {
381  dst[offset + x + 7 * stride] = cm[dst[offset + x + 7 * stride] + ((d * 7) >> 4)];
382  dst[offset + x + 6 * stride] = cm[dst[offset + x + 6 * stride] + ((d * 5) >> 4)];
383  dst[offset + x + 5 * stride] = cm[dst[offset + x + 5 * stride] + ((d * 3) >> 4)];
384  dst[offset + x + 4 * stride] = cm[dst[offset + x + 4 * stride] + ((d * 1) >> 4)];
385  }
386  if (bottom_damage) {
387  dst[offset + x + 8 * stride] = cm[dst[offset + x + 8 * stride] - ((d * 7) >> 4)];
388  dst[offset + x + 9 * stride] = cm[dst[offset + x + 9 * stride] - ((d * 5) >> 4)];
389  dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
390  dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
391  }
392  }
393  }
394  }
395 }
396 
397 #define MV_FROZEN 8
398 #define MV_CHANGED 4
399 #define MV_UNCHANGED 2
400 #define MV_LISTED 1
401 static av_always_inline void add_blocklist(int (*blocklist)[2], int *blocklist_length, uint8_t *fixed, int mb_x, int mb_y, int mb_xy)
402 {
403  if (fixed[mb_xy])
404  return;
405  fixed[mb_xy] = MV_LISTED;
406  blocklist[ *blocklist_length ][0] = mb_x;
407  blocklist[(*blocklist_length)++][1] = mb_y;
408 }
409 
410 static void guess_mv(ERContext *s)
411 {
412  int (*blocklist)[2], (*next_blocklist)[2];
413  uint8_t *fixed;
414  const ptrdiff_t mb_stride = s->mb_stride;
415  const int mb_width = s->mb_width;
416  int mb_height = s->mb_height;
417  int i, num_avail;
418  int mb_x, mb_y;
419  ptrdiff_t mot_step, mot_stride;
420  int blocklist_length, next_blocklist_length;
421 
422  if (s->last_pic.f && s->last_pic.f->data[0])
423  mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
424  if (s->next_pic.f && s->next_pic.f->data[0])
425  mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);
426 
427  blocklist = (int (*)[2])s->er_temp_buffer;
428  next_blocklist = blocklist + s->mb_stride * s->mb_height;
429  fixed = (uint8_t *)(next_blocklist + s->mb_stride * s->mb_height);
430 
431  set_mv_strides(s, &mot_step, &mot_stride);
432 
433  num_avail = 0;
434  if (s->last_pic.motion_val[0]) {
435  if (s->last_pic.tf)
436  ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0);
437  else
438  ff_thread_progress_await(s->last_pic.progress, mb_height - 1);
439  }
440  for (i = 0; i < mb_width * mb_height; i++) {
441  const int mb_xy = s->mb_index2xy[i];
442  int f = 0;
443  int error = s->error_status_table[mb_xy];
444 
445  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
446  f = MV_FROZEN; // intra // FIXME check
447  if (!(error & ER_MV_ERROR))
448  f = MV_FROZEN; // inter with undamaged MV
449 
450  fixed[mb_xy] = f;
451  if (f == MV_FROZEN)
452  num_avail++;
453  else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
454  const int mb_y= mb_xy / s->mb_stride;
455  const int mb_x= mb_xy % s->mb_stride;
456  const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
457  s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
458  s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
459  s->cur_pic.ref_index[0][4*mb_xy] = s->last_pic.ref_index[0][4*mb_xy];
460  }
461  }
462 
463  if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
464  num_avail <= FFMAX(mb_width, mb_height) / 2) {
465  for (mb_y = 0; mb_y < mb_height; mb_y++) {
466  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
467  const int mb_xy = mb_x + mb_y * s->mb_stride;
468  int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
469 
470  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
471  continue;
472  if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
473  continue;
474 
475  s->mv[0][0][0] = 0;
476  s->mv[0][0][1] = 0;
477  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
478  mb_x, mb_y, 0, 0);
479  }
480  }
481  return;
482  }
483 
484  blocklist_length = 0;
485  for (mb_y = 0; mb_y < mb_height; mb_y++) {
486  for (mb_x = 0; mb_x < mb_width; mb_x++) {
487  const int mb_xy = mb_x + mb_y * mb_stride;
488  if (fixed[mb_xy] == MV_FROZEN) {
489  if (mb_x) add_blocklist(blocklist, &blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
490  if (mb_y) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
491  if (mb_x+1 < mb_width) add_blocklist(blocklist, &blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
492  if (mb_y+1 < mb_height) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
493  }
494  }
495  }
496 
497  for (;;) {
498  int changed, pass, none_left;
499  int blocklist_index;
500 
501  none_left = 1;
502  changed = 1;
503  for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
504  changed = 0;
505  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
506  const int mb_x = blocklist[blocklist_index][0];
507  const int mb_y = blocklist[blocklist_index][1];
508  const int mb_xy = mb_x + mb_y * mb_stride;
509  int mv_predictor[8][2];
510  int ref[8];
511  int pred_count;
512  int j;
513  int best_score;
514  int best_pred;
515  int mot_index;
516  int prev_x, prev_y, prev_ref;
517 
518  if ((mb_x ^ mb_y ^ pass) & 1)
519  continue;
520  av_assert2(fixed[mb_xy] != MV_FROZEN);
521 
522 
523  av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
524  av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
525 
526  j = 0;
527  if (mb_x > 0)
528  j |= fixed[mb_xy - 1];
529  if (mb_x + 1 < mb_width)
530  j |= fixed[mb_xy + 1];
531  if (mb_y > 0)
532  j |= fixed[mb_xy - mb_stride];
533  if (mb_y + 1 < mb_height)
534  j |= fixed[mb_xy + mb_stride];
535 
536  av_assert2(j & MV_FROZEN);
537 
538  if (!(j & MV_CHANGED) && pass > 1)
539  continue;
540 
541  none_left = 0;
542  pred_count = 0;
543  mot_index = (mb_x + mb_y * mot_stride) * mot_step;
544 
545  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
546  mv_predictor[pred_count][0] =
547  s->cur_pic.motion_val[0][mot_index - mot_step][0];
548  mv_predictor[pred_count][1] =
549  s->cur_pic.motion_val[0][mot_index - mot_step][1];
550  ref[pred_count] =
551  s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
552  pred_count++;
553  }
554  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
555  mv_predictor[pred_count][0] =
556  s->cur_pic.motion_val[0][mot_index + mot_step][0];
557  mv_predictor[pred_count][1] =
558  s->cur_pic.motion_val[0][mot_index + mot_step][1];
559  ref[pred_count] =
560  s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
561  pred_count++;
562  }
563  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
564  mv_predictor[pred_count][0] =
565  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
566  mv_predictor[pred_count][1] =
567  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
568  ref[pred_count] =
569  s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
570  pred_count++;
571  }
572  if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride] > 1) {
573  mv_predictor[pred_count][0] =
574  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
575  mv_predictor[pred_count][1] =
576  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
577  ref[pred_count] =
578  s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
579  pred_count++;
580  }
581  if (pred_count == 0)
582  continue;
583 
584  if (pred_count > 1) {
585  int sum_x = 0, sum_y = 0, sum_r = 0;
586  int max_x, max_y, min_x, min_y, max_r, min_r;
587 
588  for (j = 0; j < pred_count; j++) {
589  sum_x += mv_predictor[j][0];
590  sum_y += mv_predictor[j][1];
591  sum_r += ref[j];
592  if (j && ref[j] != ref[j - 1])
593  goto skip_mean_and_median;
594  }
595 
596  /* mean */
597  mv_predictor[pred_count][0] = sum_x / j;
598  mv_predictor[pred_count][1] = sum_y / j;
599  ref[pred_count] = sum_r / j;
600 
601  /* median */
602  if (pred_count >= 3) {
603  min_y = min_x = min_r = 99999;
604  max_y = max_x = max_r = -99999;
605  } else {
606  min_x = min_y = max_x = max_y = min_r = max_r = 0;
607  }
608  for (j = 0; j < pred_count; j++) {
609  max_x = FFMAX(max_x, mv_predictor[j][0]);
610  max_y = FFMAX(max_y, mv_predictor[j][1]);
611  max_r = FFMAX(max_r, ref[j]);
612  min_x = FFMIN(min_x, mv_predictor[j][0]);
613  min_y = FFMIN(min_y, mv_predictor[j][1]);
614  min_r = FFMIN(min_r, ref[j]);
615  }
616  mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
617  mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
618  ref[pred_count + 1] = sum_r - max_r - min_r;
619 
620  if (pred_count == 4) {
621  mv_predictor[pred_count + 1][0] /= 2;
622  mv_predictor[pred_count + 1][1] /= 2;
623  ref[pred_count + 1] /= 2;
624  }
625  pred_count += 2;
626  }
627 
628 skip_mean_and_median:
629  /* zero MV */
630  mv_predictor[pred_count][0] =
631  mv_predictor[pred_count][1] =
632  ref[pred_count] = 0;
633  pred_count++;
634 
635  prev_x = s->cur_pic.motion_val[0][mot_index][0];
636  prev_y = s->cur_pic.motion_val[0][mot_index][1];
637  prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
638 
639  /* last MV */
640  mv_predictor[pred_count][0] = prev_x;
641  mv_predictor[pred_count][1] = prev_y;
642  ref[pred_count] = prev_ref;
643  pred_count++;
644 
645  best_pred = 0;
646  best_score = 256 * 256 * 256 * 64;
647  for (j = 0; j < pred_count; j++) {
648  int *linesize = s->cur_pic.f->linesize;
649  int score = 0;
650  uint8_t *src = s->cur_pic.f->data[0] +
651  mb_x * 16 + mb_y * 16 * linesize[0];
652 
653  s->cur_pic.motion_val[0][mot_index][0] =
654  s->mv[0][0][0] = mv_predictor[j][0];
655  s->cur_pic.motion_val[0][mot_index][1] =
656  s->mv[0][0][1] = mv_predictor[j][1];
657 
658  // predictor intra or otherwise not available
659  if (ref[j] < 0)
660  continue;
661 
662  s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
663  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
664 
665  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
666  int k;
667  for (k = 0; k < 16; k++)
668  score += FFABS(src[k * linesize[0] - 1] -
669  src[k * linesize[0]]);
670  }
671  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
672  int k;
673  for (k = 0; k < 16; k++)
674  score += FFABS(src[k * linesize[0] + 15] -
675  src[k * linesize[0] + 16]);
676  }
677  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
678  int k;
679  for (k = 0; k < 16; k++)
680  score += FFABS(src[k - linesize[0]] - src[k]);
681  }
682  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) {
683  int k;
684  for (k = 0; k < 16; k++)
685  score += FFABS(src[k + linesize[0] * 15] -
686  src[k + linesize[0] * 16]);
687  }
688 
689  if (score <= best_score) { // <= will favor the last MV
690  best_score = score;
691  best_pred = j;
692  }
693  }
694  s->mv[0][0][0] = mv_predictor[best_pred][0];
695  s->mv[0][0][1] = mv_predictor[best_pred][1];
696 
697  for (i = 0; i < mot_step; i++)
698  for (j = 0; j < mot_step; j++) {
699  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
700  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
701  }
702 
703  s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
704  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
705 
706 
707  if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
708  fixed[mb_xy] = MV_CHANGED;
709  changed++;
710  } else
711  fixed[mb_xy] = MV_UNCHANGED;
712  }
713  }
714 
715  if (none_left)
716  return;
717 
718  next_blocklist_length = 0;
719 
720  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
721  const int mb_x = blocklist[blocklist_index][0];
722  const int mb_y = blocklist[blocklist_index][1];
723  const int mb_xy = mb_x + mb_y * mb_stride;
724 
725  if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) {
726  fixed[mb_xy] = MV_FROZEN;
727  if (mb_x > 0)
728  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
729  if (mb_y > 0)
730  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
731  if (mb_x + 1 < mb_width)
732  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
733  if (mb_y + 1 < mb_height)
734  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
735  }
736  }
737  av_assert0(next_blocklist_length <= mb_height * mb_width);
738  FFSWAP(int , blocklist_length, next_blocklist_length);
739  FFSWAP(void*, blocklist, next_blocklist);
740  }
741 }
742 
744 {
745  int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
746 
747  if (!s->last_pic.f || !s->last_pic.f->data[0])
748  return 1; // no previous frame available -> use spatial prediction
749 
750  if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
751  return 0;
752 
753  undamaged_count = 0;
754  for (i = 0; i < s->mb_num; i++) {
755  const int mb_xy = s->mb_index2xy[i];
756  const int error = s->error_status_table[mb_xy];
757  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
758  undamaged_count++;
759  }
760 
761  if (undamaged_count < 5)
762  return 0; // almost all MBs damaged -> use temporal prediction
763 
764  skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
765  is_intra_likely = 0;
766 
767  j = 0;
768  for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
769  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
770  int error;
771  const int mb_xy = mb_x + mb_y * s->mb_stride;
772 
773  error = s->error_status_table[mb_xy];
774  if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
775  continue; // skip damaged
776 
777  j++;
778  // skip a few to speed things up
779  if ((j % skip_amount) != 0)
780  continue;
781 
782  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
783  int *linesize = s->cur_pic.f->linesize;
784  uint8_t *mb_ptr = s->cur_pic.f->data[0] +
785  mb_x * 16 + mb_y * 16 * linesize[0];
786  uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
787  mb_x * 16 + mb_y * 16 * linesize[0];
788 
789  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
790  // FIXME
791  } else {
792  ff_thread_progress_await(s->last_pic.progress, mb_y);
793  }
794  is_intra_likely += s->sad(NULL, last_mb_ptr, mb_ptr,
795  linesize[0], 16);
796  // FIXME need await_progress() here
797  is_intra_likely -= s->sad(NULL, last_mb_ptr,
798  last_mb_ptr + linesize[0] * 16,
799  linesize[0], 16);
800  } else {
801  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
802  is_intra_likely++;
803  else
804  is_intra_likely--;
805  }
806  }
807  }
808 // av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
809  return is_intra_likely > 0;
810 }
811 
813 {
814  if (!s->avctx->error_concealment)
815  return;
816 
817  memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
818  s->mb_stride * s->mb_height * sizeof(uint8_t));
819  atomic_init(&s->error_count, 3 * s->mb_num);
820  s->error_occurred = 0;
821 }
822 
824 {
825  if (s->avctx->hwaccel ||
826  !s->cur_pic.f ||
827  s->cur_pic.field_picture
828  )
829  return 0;
830  return 1;
831 }
832 
833 /**
834  * Add a slice.
835  * @param endx x component of the last macroblock, can be -1
836  * for the last of the previous line
837  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
838  * assumed that no earlier end or error of the same type occurred
839  */
840 void ff_er_add_slice(ERContext *s, int startx, int starty,
841  int endx, int endy, int status)
842 {
843  const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
844  const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num);
845  const int start_xy = s->mb_index2xy[start_i];
846  const int end_xy = s->mb_index2xy[end_i];
847  int mask = -1;
848 
849  if (s->avctx->hwaccel)
850  return;
851 
852  if (start_i > end_i || start_xy > end_xy) {
853  av_log(s->avctx, AV_LOG_ERROR,
854  "internal error, slice end before start\n");
855  return;
856  }
857 
858  if (!s->avctx->error_concealment)
859  return;
860 
861  mask &= ~VP_START;
862  if (status & (ER_AC_ERROR | ER_AC_END)) {
863  mask &= ~(ER_AC_ERROR | ER_AC_END);
864  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
865  }
866  if (status & (ER_DC_ERROR | ER_DC_END)) {
867  mask &= ~(ER_DC_ERROR | ER_DC_END);
868  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
869  }
870  if (status & (ER_MV_ERROR | ER_MV_END)) {
871  mask &= ~(ER_MV_ERROR | ER_MV_END);
872  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
873  }
874 
875  if (status & ER_MB_ERROR) {
876  s->error_occurred = 1;
877  atomic_store(&s->error_count, INT_MAX);
878  }
879 
880  if (mask == ~0x7F) {
881  memset(&s->error_status_table[start_xy], 0,
882  (end_xy - start_xy) * sizeof(uint8_t));
883  } else {
884  int i;
885  for (i = start_xy; i < end_xy; i++)
886  s->error_status_table[i] &= mask;
887  }
888 
889  if (end_i == s->mb_num)
890  atomic_store(&s->error_count, INT_MAX);
891  else {
892  s->error_status_table[end_xy] &= mask;
893  s->error_status_table[end_xy] |= status;
894  }
895 
896  s->error_status_table[start_xy] |= VP_START;
897 
898  if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
899  er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
900  int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
901 
902  prev_status &= ~ VP_START;
903  if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
904  s->error_occurred = 1;
905  atomic_store(&s->error_count, INT_MAX);
906  }
907  }
908 }
909 
910 void ff_er_frame_end(ERContext *s, int *decode_error_flags)
911 {
912  int *linesize = NULL;
913  int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
914  int distance;
915  int threshold_part[4] = { 100, 100, 100 };
916  int threshold = 50;
917  int is_intra_likely;
918  int size = s->b8_stride * 2 * s->mb_height;
919  int guessed_mb_type;
920 
921  /* We do not support ER of field pictures yet,
922  * though it should not crash if enabled. */
923  if (!s->avctx->error_concealment || !atomic_load(&s->error_count) ||
924  s->avctx->lowres ||
925  !er_supported(s) ||
926  atomic_load(&s->error_count) == 3 * s->mb_width *
927  (s->avctx->skip_top + s->avctx->skip_bottom)) {
928  return;
929  }
930  linesize = s->cur_pic.f->linesize;
931 
932  if ( s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
933  && (FFALIGN(s->avctx->height, 16)&16)
934  && atomic_load(&s->error_count) == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)) {
935  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
936  int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
937  if (status != 0x7F)
938  break;
939  }
940 
941  if (mb_x == s->mb_width) {
942  av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
943  return;
944  }
945  }
946 
947  if (s->last_pic.f) {
948  if (s->last_pic.f->width != s->cur_pic.f->width ||
949  s->last_pic.f->height != s->cur_pic.f->height ||
950  s->last_pic.f->format != s->cur_pic.f->format) {
951  av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
952  memset(&s->last_pic, 0, sizeof(s->last_pic));
953  }
954  }
955  if (s->next_pic.f) {
956  if (s->next_pic.f->width != s->cur_pic.f->width ||
957  s->next_pic.f->height != s->cur_pic.f->height ||
958  s->next_pic.f->format != s->cur_pic.f->format) {
959  av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
960  memset(&s->next_pic, 0, sizeof(s->next_pic));
961  }
962  }
963 
964  if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
965  av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
966 
967  for (i = 0; i < 2; i++) {
968  s->ref_index[i] = av_calloc(s->mb_stride * s->mb_height, 4 * sizeof(uint8_t));
969  s->motion_val_base[i] = av_calloc(size + 4, 2 * sizeof(uint16_t));
970  if (!s->ref_index[i] || !s->motion_val_base[i])
971  goto cleanup;
972  s->cur_pic.ref_index[i] = s->ref_index[i];
973  s->cur_pic.motion_val[i] = s->motion_val_base[i] + 4;
974  }
975  }
976 
977  if (s->avctx->debug & FF_DEBUG_ER) {
978  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
979  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
980  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
981 
982  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
983  }
984  av_log(s->avctx, AV_LOG_DEBUG, "\n");
985  }
986  }
987 
988 #if 1
989  /* handle overlapping slices */
990  for (error_type = 1; error_type <= 3; error_type++) {
991  int end_ok = 0;
992 
993  for (i = s->mb_num - 1; i >= 0; i--) {
994  const int mb_xy = s->mb_index2xy[i];
995  int error = s->error_status_table[mb_xy];
996 
997  if (error & (1 << error_type))
998  end_ok = 1;
999  if (error & (8 << error_type))
1000  end_ok = 1;
1001 
1002  if (!end_ok)
1003  s->error_status_table[mb_xy] |= 1 << error_type;
1004 
1005  if (error & VP_START)
1006  end_ok = 0;
1007  }
1008  }
1009 #endif
1010 #if 1
1011  /* handle slices with partitions of different length */
1012  if (s->partitioned_frame) {
1013  int end_ok = 0;
1014 
1015  for (i = s->mb_num - 1; i >= 0; i--) {
1016  const int mb_xy = s->mb_index2xy[i];
1017  int error = s->error_status_table[mb_xy];
1018 
1019  if (error & ER_AC_END)
1020  end_ok = 0;
1021  if ((error & ER_MV_END) ||
1022  (error & ER_DC_END) ||
1023  (error & ER_AC_ERROR))
1024  end_ok = 1;
1025 
1026  if (!end_ok)
1027  s->error_status_table[mb_xy]|= ER_AC_ERROR;
1028 
1029  if (error & VP_START)
1030  end_ok = 0;
1031  }
1032  }
1033 #endif
1034  /* handle missing slices */
1035  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
1036  int end_ok = 1;
1037 
1038  // FIXME + 100 hack
1039  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
1040  const int mb_xy = s->mb_index2xy[i];
1041  int error1 = s->error_status_table[mb_xy];
1042  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
1043 
1044  if (error1 & VP_START)
1045  end_ok = 1;
1046 
1047  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1048  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1049  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1050  (error1 & ER_MV_END))) {
1051  // end & uninit
1052  end_ok = 0;
1053  }
1054 
1055  if (!end_ok)
1056  s->error_status_table[mb_xy] |= ER_MB_ERROR;
1057  }
1058  }
1059 
1060 #if 1
1061  /* backward mark errors */
1062  distance = 9999999;
1063  for (error_type = 1; error_type <= 3; error_type++) {
1064  for (i = s->mb_num - 1; i >= 0; i--) {
1065  const int mb_xy = s->mb_index2xy[i];
1066  int error = s->error_status_table[mb_xy];
1067 
1068  if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1069  distance++;
1070  if (error & (1 << error_type))
1071  distance = 0;
1072 
1073  if (s->partitioned_frame) {
1074  if (distance < threshold_part[error_type - 1])
1075  s->error_status_table[mb_xy] |= 1 << error_type;
1076  } else {
1077  if (distance < threshold)
1078  s->error_status_table[mb_xy] |= 1 << error_type;
1079  }
1080 
1081  if (error & VP_START)
1082  distance = 9999999;
1083  }
1084  }
1085 #endif
1086 
1087  /* forward mark errors */
1088  error = 0;
1089  for (i = 0; i < s->mb_num; i++) {
1090  const int mb_xy = s->mb_index2xy[i];
1091  int old_error = s->error_status_table[mb_xy];
1092 
1093  if (old_error & VP_START) {
1094  error = old_error & ER_MB_ERROR;
1095  } else {
1096  error |= old_error & ER_MB_ERROR;
1097  s->error_status_table[mb_xy] |= error;
1098  }
1099  }
1100 #if 1
1101  /* handle not partitioned case */
1102  if (!s->partitioned_frame) {
1103  for (i = 0; i < s->mb_num; i++) {
1104  const int mb_xy = s->mb_index2xy[i];
1105  int error = s->error_status_table[mb_xy];
1106  if (error & ER_MB_ERROR)
1107  error |= ER_MB_ERROR;
1108  s->error_status_table[mb_xy] = error;
1109  }
1110  }
1111 #endif
1112 
1113  dc_error = ac_error = mv_error = 0;
1114  for (i = 0; i < s->mb_num; i++) {
1115  const int mb_xy = s->mb_index2xy[i];
1116  int error = s->error_status_table[mb_xy];
1117  if (error & ER_DC_ERROR)
1118  dc_error++;
1119  if (error & ER_AC_ERROR)
1120  ac_error++;
1121  if (error & ER_MV_ERROR)
1122  mv_error++;
1123  }
1124  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1125  dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1126 
1127  if (decode_error_flags)
1128  *decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1129  else
1130  s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1131 
1132  is_intra_likely = is_intra_more_likely(s);
1133 
1134  /* set unknown mb-type to most likely */
1135  guessed_mb_type = is_intra_likely ? MB_TYPE_INTRA4x4 :
1136  (MB_TYPE_16x16 | (s->avctx->codec_id == AV_CODEC_ID_H264 ? MB_TYPE_L0 : MB_TYPE_FORWARD_MV));
1137  for (i = 0; i < s->mb_num; i++) {
1138  const int mb_xy = s->mb_index2xy[i];
1139  int error = s->error_status_table[mb_xy];
1140  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1141  continue;
1142 
1143  s->cur_pic.mb_type[mb_xy] = guessed_mb_type;
1144  }
1145 
1146  // change inter to intra blocks if no reference frames are available
1147  if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1148  !(s->next_pic.f && s->next_pic.f->data[0]))
1149  for (i = 0; i < s->mb_num; i++) {
1150  const int mb_xy = s->mb_index2xy[i];
1151  if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1152  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1153  }
1154 
1155  /* handle inter blocks with damaged AC */
1156  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1157  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1158  const int mb_xy = mb_x + mb_y * s->mb_stride;
1159  const int mb_type = s->cur_pic.mb_type[mb_xy];
1160  const int dir = !(s->last_pic.f && s->last_pic.f->data[0]);
1161  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1162  int mv_type;
1163 
1164  int error = s->error_status_table[mb_xy];
1165 
1166  if (IS_INTRA(mb_type))
1167  continue; // intra
1168  if (error & ER_MV_ERROR)
1169  continue; // inter with damaged MV
1170  if (!(error & ER_AC_ERROR))
1171  continue; // undamaged inter
1172 
1173  if (IS_8X8(mb_type)) {
1174  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1175  int j;
1176  mv_type = MV_TYPE_8X8;
1177  for (j = 0; j < 4; j++) {
1178  s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1179  s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1180  }
1181  } else {
1182  mv_type = MV_TYPE_16X16;
1183  s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1184  s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1185  }
1186 
1187  s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1188  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1189  }
1190  }
1191 
1192  /* guess MVs */
1193  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1194  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1195  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1196  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1197  const int mb_xy = mb_x + mb_y * s->mb_stride;
1198  const int mb_type = s->cur_pic.mb_type[mb_xy];
1199  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1200 
1201  int error = s->error_status_table[mb_xy];
1202 
1203  if (IS_INTRA(mb_type))
1204  continue;
1205  if (!(error & ER_MV_ERROR))
1206  continue; // inter with undamaged MV
1207  if (!(error & ER_AC_ERROR))
1208  continue; // undamaged inter
1209 
1210  if (!(s->last_pic.f && s->last_pic.f->data[0]))
1211  mv_dir &= ~MV_DIR_FORWARD;
1212  if (!(s->next_pic.f && s->next_pic.f->data[0]))
1213  mv_dir &= ~MV_DIR_BACKWARD;
1214 
1215  if (s->pp_time) {
1216  int time_pp = s->pp_time;
1217  int time_pb = s->pb_time;
1218 
1219  av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1220  ff_thread_progress_await(s->next_pic.progress, mb_y);
1221 
1222  s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp;
1223  s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp;
1224  s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1225  s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1226  } else {
1227  s->mv[0][0][0] = 0;
1228  s->mv[0][0][1] = 0;
1229  s->mv[1][0][0] = 0;
1230  s->mv[1][0][1] = 0;
1231  }
1232 
1233  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1234  mb_x, mb_y, 0, 0);
1235  }
1236  }
1237  } else
1238  guess_mv(s);
1239 
1240  /* fill DC for inter blocks */
1241  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1242  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1243  int dc, dcu, dcv, y, n;
1244  int16_t *dc_ptr;
1245  uint8_t *dest_y, *dest_cb, *dest_cr;
1246  const int mb_xy = mb_x + mb_y * s->mb_stride;
1247  const int mb_type = s->cur_pic.mb_type[mb_xy];
1248 
1249  // error = s->error_status_table[mb_xy];
1250 
1251  if (IS_INTRA(mb_type) && s->partitioned_frame)
1252  continue;
1253  // if (error & ER_MV_ERROR)
1254  // continue; // inter data damaged FIXME is this good?
1255 
1256  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1257  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1258  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1259 
1260  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1261  for (n = 0; n < 4; n++) {
1262  dc = 0;
1263  for (y = 0; y < 8; y++) {
1264  int x;
1265  for (x = 0; x < 8; x++)
1266  dc += dest_y[x + (n & 1) * 8 +
1267  (y + (n >> 1) * 8) * linesize[0]];
1268  }
1269  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1270  }
1271 
1272  if (!s->cur_pic.f->data[2])
1273  continue;
1274 
1275  dcu = dcv = 0;
1276  for (y = 0; y < 8; y++) {
1277  int x;
1278  for (x = 0; x < 8; x++) {
1279  dcu += dest_cb[x + y * linesize[1]];
1280  dcv += dest_cr[x + y * linesize[2]];
1281  }
1282  }
1283  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1284  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1285  }
1286  }
1287 #if 1
1288  /* guess DC for damaged blocks */
1289  guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1290  guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1291  guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1292 #endif
1293 
1294  /* filter luma DC */
1295  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1296 
1297 #if 1
1298  /* render DC only intra */
1299  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1300  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1301  uint8_t *dest_y, *dest_cb, *dest_cr;
1302  const int mb_xy = mb_x + mb_y * s->mb_stride;
1303  const int mb_type = s->cur_pic.mb_type[mb_xy];
1304 
1305  int error = s->error_status_table[mb_xy];
1306 
1307  if (IS_INTER(mb_type))
1308  continue;
1309  if (!(error & ER_AC_ERROR))
1310  continue; // undamaged
1311 
1312  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1313  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1314  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1315  if (!s->cur_pic.f->data[2])
1316  dest_cb = dest_cr = NULL;
1317 
1318  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1319  }
1320  }
1321 #endif
1322 
1323  if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1324  /* filter horizontal block boundaries */
1325  h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1326  s->mb_height * 2, linesize[0], 1);
1327 
1328  /* filter vertical block boundaries */
1329  v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1330  s->mb_height * 2, linesize[0], 1);
1331 
1332  if (s->cur_pic.f->data[2]) {
1333  h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1334  s->mb_height, linesize[1], 0);
1335  h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1336  s->mb_height, linesize[2], 0);
1337  v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1338  s->mb_height, linesize[1], 0);
1339  v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1340  s->mb_height, linesize[2], 0);
1341  }
1342  }
1343 
1344  /* clean a few tables */
1345  for (i = 0; i < s->mb_num; i++) {
1346  const int mb_xy = s->mb_index2xy[i];
1347  int error = s->error_status_table[mb_xy];
1348 
1349  if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1351  s->mbskip_table[mb_xy] = 0;
1352  }
1353  if (s->mbintra_table)
1354  s->mbintra_table[mb_xy] = 1;
1355  }
1356 
1357  memset(&s->cur_pic, 0, sizeof(ERPicture));
1358  memset(&s->last_pic, 0, sizeof(ERPicture));
1359  memset(&s->next_pic, 0, sizeof(ERPicture));
1360 
1361 cleanup:
1362  for (i = 0; i < 2; i++) {
1363  av_freep(&s->ref_index[i]);
1364  av_freep(&s->motion_val_base[i]);
1365  s->cur_pic.ref_index[i] = NULL;
1366  s->cur_pic.motion_val[i] = NULL;
1367  }
1368 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
FF_DECODE_ERROR_CONCEALMENT_ACTIVE
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE
Definition: frame.h:717
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:83
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:57
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:172
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
av_clip
#define av_clip
Definition: common.h:100
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
MV_UNCHANGED
#define MV_UNCHANGED
Definition: error_resilience.c:399
threadprogress.h
color
Definition: vf_paletteuse.c:513
MV_CHANGED
#define MV_CHANGED
Definition: error_resilience.c:398
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:137
is_intra_more_likely
static int is_intra_more_likely(ERContext *s)
Definition: error_resilience.c:743
set_mv_strides
static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
Definition: error_resilience.c:64
int64_t
long long int64_t
Definition: coverity.c:34
mask
int mask
Definition: mediacodecdec_common.c:154
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
MB_TYPE_INTRA4x4
#define MB_TYPE_INTRA4x4
Definition: mpegutils.h:38
b
#define b
Definition: input.c:42
data
const char data[16]
Definition: mxf.c:149
MV_FROZEN
#define MV_FROZEN
Definition: error_resilience.c:397
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:41
ff_er_frame_start
void ff_er_frame_start(ERContext *s)
Definition: error_resilience.c:812
ERContext
Definition: error_resilience.h:54
ff_er_add_slice
void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy, int status)
Add a slice.
Definition: error_resilience.c:840
FF_EC_GUESS_MVS
#define FF_EC_GUESS_MVS
Definition: avcodec.h:1373
mpegvideo.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ER_DC_END
#define ER_DC_END
Definition: error_resilience.h:33
h_block_filter
static void h_block_filter(ERContext *s, uint8_t *dst, int w, int h, ptrdiff_t stride, int is_luma)
simple horizontal deblocking filter used for error resilience
Definition: error_resilience.c:261
mpegutils.h
ER_MV_ERROR
#define ER_MV_ERROR
Definition: error_resilience.h:31
ff_crop_tab
#define ff_crop_tab
Definition: motionpixels_tablegen.c:26
MV_DIR_BACKWARD
#define MV_DIR_BACKWARD
Definition: mpegvideo.h:169
ERPicture
Definition: error_resilience.h:41
fail
#define fail()
Definition: checkasm.h:219
FF_DEBUG_ER
#define FF_DEBUG_ER
Definition: avcodec.h:1391
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:961
weight
const h264_weight_func weight
Definition: h264dsp_init.c:33
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
ER_DC_ERROR
#define ER_DC_ERROR
Definition: error_resilience.h:30
av_cold
#define av_cold
Definition: attributes.h:106
ff_er_init
av_cold int ff_er_init(ERContext *const s)
Definition: error_resilience.c:42
ff_er_frame_end
void ff_er_frame_end(ERContext *s, int *decode_error_flags)
Indicate that a frame has finished decoding and perform error concealment in case it has been enabled...
Definition: error_resilience.c:910
s
#define s(width, name)
Definition: cbs_vp9.c:198
FF_EC_DEBLOCK
#define FF_EC_DEBLOCK
Definition: avcodec.h:1374
er_supported
static int er_supported(ERContext *s)
Definition: error_resilience.c:823
guess_mv
static void guess_mv(ERContext *s)
Definition: error_resilience.c:410
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
limits.h
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
v_block_filter
static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, ptrdiff_t stride, int is_luma)
simple vertical deblocking filter used for error resilience
Definition: error_resilience.c:330
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
add_blocklist
static av_always_inline void add_blocklist(int(*blocklist)[2], int *blocklist_length, uint8_t *fixed, int mb_x, int mb_y, int mb_xy)
Definition: error_resilience.c:401
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
if
if(ret)
Definition: filter_design.txt:179
threadframe.h
MECmpContext
Definition: me_cmp.h:50
ff_thread_progress_await
void ff_thread_progress_await(const ThreadProgress *pro_c, int n)
This function is a no-op in no-op mode; otherwise it waits until other threads have reached a certain...
Definition: threadprogress.c:64
NULL
#define NULL
Definition: coverity.c:32
ER_AC_ERROR
#define ER_AC_ERROR
Definition: error_resilience.h:29
ff_thread_await_progress
void ff_thread_await_progress(const ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread_frame.c:651
MECmpContext::sad
me_cmp_func sad[6]
Definition: me_cmp.h:53
ER_MB_ERROR
#define ER_MB_ERROR
Definition: error_resilience.h:36
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
mathops.h
guess_dc
static void guess_dc(ERContext *s, int16_t *dc, int w, int h, ptrdiff_t stride, int is_luma)
guess the dc of blocks which do not have an undamaged dc
Definition: error_resilience.c:158
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:173
IS_INTRA
#define IS_INTRA(x, y)
f
f
Definition: af_crystalizer.c:122
dc
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
height
#define height
Definition: dsp.h:89
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
VP_START
#define VP_START
current MB is the first after a resync marker
Definition: error_resilience.h:28
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:98
FF_THREAD_SLICE
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
Definition: avcodec.h:1581
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
attributes.h
fixed
#define fixed(width, name, value)
Definition: cbs_apv.c:75
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
av_get_picture_type_char
char av_get_picture_type_char(enum AVPictureType pict_type)
Return a single letter to describe the given picture type pict_type.
Definition: utils.c:40
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
av_always_inline
#define av_always_inline
Definition: attributes.h:63
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
me_cmp.h
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:280
error_resilience.h
cm
#define cm
Definition: dvbsubdec.c:40
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
MV_LISTED
#define MV_LISTED
Definition: error_resilience.c:400
put_dc
static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
Replace the current MB with a flat dc-only version.
Definition: error_resilience.c:79
IS_INTER
#define IS_INTER(a)
Definition: mpegutils.h:73
mem.h
ER_MB_END
#define ER_MB_END
Definition: error_resilience.h:37
w
uint8_t w
Definition: llvidencdsp.c:39
ER_MV_END
#define ER_MV_END
Definition: error_resilience.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
MV_DIR_FORWARD
#define MV_DIR_FORWARD
Definition: mpegvideo.h:168
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
ER_AC_END
#define ER_AC_END
Definition: error_resilience.h:32
stride
#define stride
Definition: h264pred_template.c:536
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
width
#define width
Definition: dsp.h:89
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31
FF_EC_FAVOR_INTER
#define FF_EC_FAVOR_INTER
Definition: avcodec.h:1375
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
MB_TYPE_FORWARD_MV
#define MB_TYPE_FORWARD_MV
Definition: mpegutils.h:49
src
#define src
Definition: vp8dsp.c:248
filter181
static void filter181(int16_t *data, int width, int height, ptrdiff_t stride)
Definition: error_resilience.c:117