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/mem.h"
31 #include "avcodec.h"
32 #include "error_resilience.h"
33 #include "me_cmp.h"
34 #include "mpegutils.h"
35 #include "mpegvideo.h"
36 #include "threadframe.h"
37 #include "threadprogress.h"
38 
39 /**
40  * @param stride the number of MVs to get to the next row
41  * @param mv_step the number of MVs per row or column in a macroblock
42  */
43 static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
44 {
45  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
46  av_assert0(s->quarter_sample);
47  *mv_step = 4;
48  *stride = s->mb_width * 4;
49  } else {
50  *mv_step = 2;
51  *stride = s->b8_stride;
52  }
53 }
54 
55 /**
56  * Replace the current MB with a flat dc-only version.
57  */
58 static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
59  uint8_t *dest_cr, int mb_x, int mb_y)
60 {
61  int *linesize = s->cur_pic.f->linesize;
62  int dc, dcu, dcv, y, i;
63  for (i = 0; i < 4; i++) {
64  dc = s->dc_val[0][mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
65  if (dc < 0)
66  dc = 0;
67  else if (dc > 2040)
68  dc = 2040;
69  for (y = 0; y < 8; y++) {
70  int x;
71  for (x = 0; x < 8; x++)
72  dest_y[x + (i & 1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
73  }
74  }
75  dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
76  dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
77  if (dcu < 0)
78  dcu = 0;
79  else if (dcu > 2040)
80  dcu = 2040;
81  if (dcv < 0)
82  dcv = 0;
83  else if (dcv > 2040)
84  dcv = 2040;
85 
86  if (dest_cr)
87  for (y = 0; y < 8; y++) {
88  int x;
89  for (x = 0; x < 8; x++) {
90  dest_cb[x + y * linesize[1]] = dcu / 8;
91  dest_cr[x + y * linesize[2]] = dcv / 8;
92  }
93  }
94 }
95 
96 static void filter181(int16_t *data, int width, int height, ptrdiff_t stride)
97 {
98  int x, y;
99 
100  /* horizontal filter */
101  for (y = 1; y < height - 1; y++) {
102  int prev_dc = data[0 + y * stride];
103 
104  for (x = 1; x < width - 1; x++) {
105  int dc;
106  dc = -prev_dc +
107  data[x + y * stride] * 8 -
108  data[x + 1 + y * stride];
109  dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
110  prev_dc = data[x + y * stride];
111  data[x + y * stride] = dc;
112  }
113  }
114 
115  /* vertical filter */
116  for (x = 1; x < width - 1; x++) {
117  int prev_dc = data[x];
118 
119  for (y = 1; y < height - 1; y++) {
120  int dc;
121 
122  dc = -prev_dc +
123  data[x + y * stride] * 8 -
124  data[x + (y + 1) * stride];
125  dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
126  prev_dc = data[x + y * stride];
127  data[x + y * stride] = dc;
128  }
129  }
130 }
131 
132 /**
133  * guess the dc of blocks which do not have an undamaged dc
134  * @param w width in 8 pixel blocks
135  * @param h height in 8 pixel blocks
136  */
137 static void guess_dc(ERContext *s, int16_t *dc, int w,
138  int h, ptrdiff_t stride, int is_luma)
139 {
140  int b_x, b_y;
141  int16_t (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4);
142  uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4);
143 
144  if(!col || !dist) {
145  av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
146  goto fail;
147  }
148 
149  for(b_y=0; b_y<h; b_y++){
150  int color= 1024;
151  int distance= -1;
152  for(b_x=0; b_x<w; b_x++){
153  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
154  int error_j= s->error_status_table[mb_index_j];
155  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
156  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
157  color= dc[b_x + b_y*stride];
158  distance= b_x;
159  }
160  col [b_x + b_y*stride][1]= color;
161  dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
162  }
163  color= 1024;
164  distance= -1;
165  for(b_x=w-1; b_x>=0; b_x--){
166  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
167  int error_j= s->error_status_table[mb_index_j];
168  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
169  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
170  color= dc[b_x + b_y*stride];
171  distance= b_x;
172  }
173  col [b_x + b_y*stride][0]= color;
174  dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
175  }
176  }
177  for(b_x=0; b_x<w; b_x++){
178  int color= 1024;
179  int distance= -1;
180  for(b_y=0; b_y<h; b_y++){
181  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
182  int error_j= s->error_status_table[mb_index_j];
183  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
184  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
185  color= dc[b_x + b_y*stride];
186  distance= b_y;
187  }
188  col [b_x + b_y*stride][3]= color;
189  dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
190  }
191  color= 1024;
192  distance= -1;
193  for(b_y=h-1; b_y>=0; b_y--){
194  int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
195  int error_j= s->error_status_table[mb_index_j];
196  int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
197  if(intra_j==0 || !(error_j&ER_DC_ERROR)){
198  color= dc[b_x + b_y*stride];
199  distance= b_y;
200  }
201  col [b_x + b_y*stride][2]= color;
202  dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
203  }
204  }
205 
206  for (b_y = 0; b_y < h; b_y++) {
207  for (b_x = 0; b_x < w; b_x++) {
208  int mb_index, error, j;
209  int64_t guess, weight_sum;
210  mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
211  error = s->error_status_table[mb_index];
212 
213  if (IS_INTER(s->cur_pic.mb_type[mb_index]))
214  continue; // inter
215  if (!(error & ER_DC_ERROR))
216  continue; // dc-ok
217 
218  weight_sum = 0;
219  guess = 0;
220  for (j = 0; j < 4; j++) {
221  int64_t weight = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
222  guess += weight*(int64_t)col[b_x + b_y*stride][j];
223  weight_sum += weight;
224  }
225  guess = (guess + weight_sum / 2) / weight_sum;
226  dc[b_x + b_y * stride] = guess;
227  }
228  }
229 
230 fail:
231  av_freep(&col);
232  av_freep(&dist);
233 }
234 
235 /**
236  * simple horizontal deblocking filter used for error resilience
237  * @param w width in 8 pixel blocks
238  * @param h height in 8 pixel blocks
239  */
240 static void h_block_filter(ERContext *s, uint8_t *dst, int w,
241  int h, ptrdiff_t stride, int is_luma)
242 {
243  int b_x, b_y;
244  ptrdiff_t mvx_stride, mvy_stride;
245  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
246  set_mv_strides(s, &mvx_stride, &mvy_stride);
247  mvx_stride >>= is_luma;
248  mvy_stride *= mvx_stride;
249 
250  for (b_y = 0; b_y < h; b_y++) {
251  for (b_x = 0; b_x < w - 1; b_x++) {
252  int y;
253  int left_status = s->error_status_table[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
254  int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
255  int left_intra = IS_INTRA(s->cur_pic.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
256  int right_intra = IS_INTRA(s->cur_pic.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
257  int left_damage = left_status & ER_MB_ERROR;
258  int right_damage = right_status & ER_MB_ERROR;
259  int offset = b_x * 8 + b_y * stride * 8;
260  int16_t *left_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
261  int16_t *right_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
262  if (!(left_damage || right_damage))
263  continue; // both undamaged
264  if ((!left_intra) && (!right_intra) &&
265  FFABS(left_mv[0] - right_mv[0]) +
266  FFABS(left_mv[1] + right_mv[1]) < 2)
267  continue;
268 
269  for (y = 0; y < 8; y++) {
270  int a, b, c, d;
271 
272  a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
273  b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
274  c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];
275 
276  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
277  d = FFMAX(d, 0);
278  if (b < 0)
279  d = -d;
280 
281  if (d == 0)
282  continue;
283 
284  if (!(left_damage && right_damage))
285  d = d * 16 / 9;
286 
287  if (left_damage) {
288  dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
289  dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
290  dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
291  dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
292  }
293  if (right_damage) {
294  dst[offset + 8 + y * stride] = cm[dst[offset + 8 + y * stride] - ((d * 7) >> 4)];
295  dst[offset + 9 + y * stride] = cm[dst[offset + 9 + y * stride] - ((d * 5) >> 4)];
296  dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
297  dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)];
298  }
299  }
300  }
301  }
302 }
303 
304 /**
305  * simple vertical deblocking filter used for error resilience
306  * @param w width in 8 pixel blocks
307  * @param h height in 8 pixel blocks
308  */
309 static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
310  ptrdiff_t stride, int is_luma)
311 {
312  int b_x, b_y;
313  ptrdiff_t mvx_stride, mvy_stride;
314  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
315  set_mv_strides(s, &mvx_stride, &mvy_stride);
316  mvx_stride >>= is_luma;
317  mvy_stride *= mvx_stride;
318 
319  for (b_y = 0; b_y < h - 1; b_y++) {
320  for (b_x = 0; b_x < w; b_x++) {
321  int x;
322  int top_status = s->error_status_table[(b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
323  int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
324  int top_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]);
325  int bottom_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
326  int top_damage = top_status & ER_MB_ERROR;
327  int bottom_damage = bottom_status & ER_MB_ERROR;
328  int offset = b_x * 8 + b_y * stride * 8;
329 
330  int16_t *top_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
331  int16_t *bottom_mv = s->cur_pic.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
332 
333  if (!(top_damage || bottom_damage))
334  continue; // both undamaged
335 
336  if ((!top_intra) && (!bottom_intra) &&
337  FFABS(top_mv[0] - bottom_mv[0]) +
338  FFABS(top_mv[1] + bottom_mv[1]) < 2)
339  continue;
340 
341  for (x = 0; x < 8; x++) {
342  int a, b, c, d;
343 
344  a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
345  b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
346  c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
347 
348  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
349  d = FFMAX(d, 0);
350  if (b < 0)
351  d = -d;
352 
353  if (d == 0)
354  continue;
355 
356  if (!(top_damage && bottom_damage))
357  d = d * 16 / 9;
358 
359  if (top_damage) {
360  dst[offset + x + 7 * stride] = cm[dst[offset + x + 7 * stride] + ((d * 7) >> 4)];
361  dst[offset + x + 6 * stride] = cm[dst[offset + x + 6 * stride] + ((d * 5) >> 4)];
362  dst[offset + x + 5 * stride] = cm[dst[offset + x + 5 * stride] + ((d * 3) >> 4)];
363  dst[offset + x + 4 * stride] = cm[dst[offset + x + 4 * stride] + ((d * 1) >> 4)];
364  }
365  if (bottom_damage) {
366  dst[offset + x + 8 * stride] = cm[dst[offset + x + 8 * stride] - ((d * 7) >> 4)];
367  dst[offset + x + 9 * stride] = cm[dst[offset + x + 9 * stride] - ((d * 5) >> 4)];
368  dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
369  dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
370  }
371  }
372  }
373  }
374 }
375 
376 #define MV_FROZEN 8
377 #define MV_CHANGED 4
378 #define MV_UNCHANGED 2
379 #define MV_LISTED 1
380 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)
381 {
382  if (fixed[mb_xy])
383  return;
384  fixed[mb_xy] = MV_LISTED;
385  blocklist[ *blocklist_length ][0] = mb_x;
386  blocklist[(*blocklist_length)++][1] = mb_y;
387 }
388 
389 static void guess_mv(ERContext *s)
390 {
391  int (*blocklist)[2], (*next_blocklist)[2];
392  uint8_t *fixed;
393  const ptrdiff_t mb_stride = s->mb_stride;
394  const int mb_width = s->mb_width;
395  int mb_height = s->mb_height;
396  int i, num_avail;
397  int mb_x, mb_y;
398  ptrdiff_t mot_step, mot_stride;
399  int blocklist_length, next_blocklist_length;
400 
401  if (s->last_pic.f && s->last_pic.f->data[0])
402  mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
403  if (s->next_pic.f && s->next_pic.f->data[0])
404  mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);
405 
406  blocklist = (int (*)[2])s->er_temp_buffer;
407  next_blocklist = blocklist + s->mb_stride * s->mb_height;
408  fixed = (uint8_t *)(next_blocklist + s->mb_stride * s->mb_height);
409 
410  set_mv_strides(s, &mot_step, &mot_stride);
411 
412  num_avail = 0;
413  if (s->last_pic.motion_val[0]) {
414  if (s->last_pic.tf)
415  ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0);
416  else
417  ff_thread_progress_await(s->last_pic.progress, mb_height - 1);
418  }
419  for (i = 0; i < mb_width * mb_height; i++) {
420  const int mb_xy = s->mb_index2xy[i];
421  int f = 0;
422  int error = s->error_status_table[mb_xy];
423 
424  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
425  f = MV_FROZEN; // intra // FIXME check
426  if (!(error & ER_MV_ERROR))
427  f = MV_FROZEN; // inter with undamaged MV
428 
429  fixed[mb_xy] = f;
430  if (f == MV_FROZEN)
431  num_avail++;
432  else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
433  const int mb_y= mb_xy / s->mb_stride;
434  const int mb_x= mb_xy % s->mb_stride;
435  const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
436  s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
437  s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
438  s->cur_pic.ref_index[0][4*mb_xy] = s->last_pic.ref_index[0][4*mb_xy];
439  }
440  }
441 
442  if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
443  num_avail <= FFMAX(mb_width, mb_height) / 2) {
444  for (mb_y = 0; mb_y < mb_height; mb_y++) {
445  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
446  const int mb_xy = mb_x + mb_y * s->mb_stride;
447  int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
448 
449  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
450  continue;
451  if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
452  continue;
453 
454  s->mv[0][0][0] = 0;
455  s->mv[0][0][1] = 0;
456  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
457  mb_x, mb_y, 0, 0);
458  }
459  }
460  return;
461  }
462 
463  blocklist_length = 0;
464  for (mb_y = 0; mb_y < mb_height; mb_y++) {
465  for (mb_x = 0; mb_x < mb_width; mb_x++) {
466  const int mb_xy = mb_x + mb_y * mb_stride;
467  if (fixed[mb_xy] == MV_FROZEN) {
468  if (mb_x) add_blocklist(blocklist, &blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
469  if (mb_y) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
470  if (mb_x+1 < mb_width) add_blocklist(blocklist, &blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
471  if (mb_y+1 < mb_height) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
472  }
473  }
474  }
475 
476  for (;;) {
477  int changed, pass, none_left;
478  int blocklist_index;
479 
480  none_left = 1;
481  changed = 1;
482  for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
483  changed = 0;
484  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
485  const int mb_x = blocklist[blocklist_index][0];
486  const int mb_y = blocklist[blocklist_index][1];
487  const int mb_xy = mb_x + mb_y * mb_stride;
488  int mv_predictor[8][2];
489  int ref[8];
490  int pred_count;
491  int j;
492  int best_score;
493  int best_pred;
494  int mot_index;
495  int prev_x, prev_y, prev_ref;
496 
497  if ((mb_x ^ mb_y ^ pass) & 1)
498  continue;
499  av_assert2(fixed[mb_xy] != MV_FROZEN);
500 
501 
502  av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
503  av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
504 
505  j = 0;
506  if (mb_x > 0)
507  j |= fixed[mb_xy - 1];
508  if (mb_x + 1 < mb_width)
509  j |= fixed[mb_xy + 1];
510  if (mb_y > 0)
511  j |= fixed[mb_xy - mb_stride];
512  if (mb_y + 1 < mb_height)
513  j |= fixed[mb_xy + mb_stride];
514 
515  av_assert2(j & MV_FROZEN);
516 
517  if (!(j & MV_CHANGED) && pass > 1)
518  continue;
519 
520  none_left = 0;
521  pred_count = 0;
522  mot_index = (mb_x + mb_y * mot_stride) * mot_step;
523 
524  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
525  mv_predictor[pred_count][0] =
526  s->cur_pic.motion_val[0][mot_index - mot_step][0];
527  mv_predictor[pred_count][1] =
528  s->cur_pic.motion_val[0][mot_index - mot_step][1];
529  ref[pred_count] =
530  s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
531  pred_count++;
532  }
533  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
534  mv_predictor[pred_count][0] =
535  s->cur_pic.motion_val[0][mot_index + mot_step][0];
536  mv_predictor[pred_count][1] =
537  s->cur_pic.motion_val[0][mot_index + mot_step][1];
538  ref[pred_count] =
539  s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
540  pred_count++;
541  }
542  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
543  mv_predictor[pred_count][0] =
544  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
545  mv_predictor[pred_count][1] =
546  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
547  ref[pred_count] =
548  s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
549  pred_count++;
550  }
551  if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride] > 1) {
552  mv_predictor[pred_count][0] =
553  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
554  mv_predictor[pred_count][1] =
555  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
556  ref[pred_count] =
557  s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
558  pred_count++;
559  }
560  if (pred_count == 0)
561  continue;
562 
563  if (pred_count > 1) {
564  int sum_x = 0, sum_y = 0, sum_r = 0;
565  int max_x, max_y, min_x, min_y, max_r, min_r;
566 
567  for (j = 0; j < pred_count; j++) {
568  sum_x += mv_predictor[j][0];
569  sum_y += mv_predictor[j][1];
570  sum_r += ref[j];
571  if (j && ref[j] != ref[j - 1])
572  goto skip_mean_and_median;
573  }
574 
575  /* mean */
576  mv_predictor[pred_count][0] = sum_x / j;
577  mv_predictor[pred_count][1] = sum_y / j;
578  ref[pred_count] = sum_r / j;
579 
580  /* median */
581  if (pred_count >= 3) {
582  min_y = min_x = min_r = 99999;
583  max_y = max_x = max_r = -99999;
584  } else {
585  min_x = min_y = max_x = max_y = min_r = max_r = 0;
586  }
587  for (j = 0; j < pred_count; j++) {
588  max_x = FFMAX(max_x, mv_predictor[j][0]);
589  max_y = FFMAX(max_y, mv_predictor[j][1]);
590  max_r = FFMAX(max_r, ref[j]);
591  min_x = FFMIN(min_x, mv_predictor[j][0]);
592  min_y = FFMIN(min_y, mv_predictor[j][1]);
593  min_r = FFMIN(min_r, ref[j]);
594  }
595  mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
596  mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
597  ref[pred_count + 1] = sum_r - max_r - min_r;
598 
599  if (pred_count == 4) {
600  mv_predictor[pred_count + 1][0] /= 2;
601  mv_predictor[pred_count + 1][1] /= 2;
602  ref[pred_count + 1] /= 2;
603  }
604  pred_count += 2;
605  }
606 
607 skip_mean_and_median:
608  /* zero MV */
609  mv_predictor[pred_count][0] =
610  mv_predictor[pred_count][1] =
611  ref[pred_count] = 0;
612  pred_count++;
613 
614  prev_x = s->cur_pic.motion_val[0][mot_index][0];
615  prev_y = s->cur_pic.motion_val[0][mot_index][1];
616  prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
617 
618  /* last MV */
619  mv_predictor[pred_count][0] = prev_x;
620  mv_predictor[pred_count][1] = prev_y;
621  ref[pred_count] = prev_ref;
622  pred_count++;
623 
624  best_pred = 0;
625  best_score = 256 * 256 * 256 * 64;
626  for (j = 0; j < pred_count; j++) {
627  int *linesize = s->cur_pic.f->linesize;
628  int score = 0;
629  uint8_t *src = s->cur_pic.f->data[0] +
630  mb_x * 16 + mb_y * 16 * linesize[0];
631 
632  s->cur_pic.motion_val[0][mot_index][0] =
633  s->mv[0][0][0] = mv_predictor[j][0];
634  s->cur_pic.motion_val[0][mot_index][1] =
635  s->mv[0][0][1] = mv_predictor[j][1];
636 
637  // predictor intra or otherwise not available
638  if (ref[j] < 0)
639  continue;
640 
641  s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
642  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
643 
644  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
645  int k;
646  for (k = 0; k < 16; k++)
647  score += FFABS(src[k * linesize[0] - 1] -
648  src[k * linesize[0]]);
649  }
650  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
651  int k;
652  for (k = 0; k < 16; k++)
653  score += FFABS(src[k * linesize[0] + 15] -
654  src[k * linesize[0] + 16]);
655  }
656  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
657  int k;
658  for (k = 0; k < 16; k++)
659  score += FFABS(src[k - linesize[0]] - src[k]);
660  }
661  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) {
662  int k;
663  for (k = 0; k < 16; k++)
664  score += FFABS(src[k + linesize[0] * 15] -
665  src[k + linesize[0] * 16]);
666  }
667 
668  if (score <= best_score) { // <= will favor the last MV
669  best_score = score;
670  best_pred = j;
671  }
672  }
673  s->mv[0][0][0] = mv_predictor[best_pred][0];
674  s->mv[0][0][1] = mv_predictor[best_pred][1];
675 
676  for (i = 0; i < mot_step; i++)
677  for (j = 0; j < mot_step; j++) {
678  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
679  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
680  }
681 
682  s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
683  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
684 
685 
686  if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
687  fixed[mb_xy] = MV_CHANGED;
688  changed++;
689  } else
690  fixed[mb_xy] = MV_UNCHANGED;
691  }
692  }
693 
694  if (none_left)
695  return;
696 
697  next_blocklist_length = 0;
698 
699  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
700  const int mb_x = blocklist[blocklist_index][0];
701  const int mb_y = blocklist[blocklist_index][1];
702  const int mb_xy = mb_x + mb_y * mb_stride;
703 
704  if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) {
705  fixed[mb_xy] = MV_FROZEN;
706  if (mb_x > 0)
707  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
708  if (mb_y > 0)
709  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
710  if (mb_x + 1 < mb_width)
711  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
712  if (mb_y + 1 < mb_height)
713  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
714  }
715  }
716  av_assert0(next_blocklist_length <= mb_height * mb_width);
717  FFSWAP(int , blocklist_length, next_blocklist_length);
718  FFSWAP(void*, blocklist, next_blocklist);
719  }
720 }
721 
723 {
724  int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
725 
726  if (!s->last_pic.f || !s->last_pic.f->data[0])
727  return 1; // no previous frame available -> use spatial prediction
728 
729  if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
730  return 0;
731 
732  undamaged_count = 0;
733  for (i = 0; i < s->mb_num; i++) {
734  const int mb_xy = s->mb_index2xy[i];
735  const int error = s->error_status_table[mb_xy];
736  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
737  undamaged_count++;
738  }
739 
740  if (undamaged_count < 5)
741  return 0; // almost all MBs damaged -> use temporal prediction
742 
743  skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
744  is_intra_likely = 0;
745 
746  j = 0;
747  for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
748  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
749  int error;
750  const int mb_xy = mb_x + mb_y * s->mb_stride;
751 
752  error = s->error_status_table[mb_xy];
753  if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
754  continue; // skip damaged
755 
756  j++;
757  // skip a few to speed things up
758  if ((j % skip_amount) != 0)
759  continue;
760 
761  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
762  int *linesize = s->cur_pic.f->linesize;
763  uint8_t *mb_ptr = s->cur_pic.f->data[0] +
764  mb_x * 16 + mb_y * 16 * linesize[0];
765  uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
766  mb_x * 16 + mb_y * 16 * linesize[0];
767 
768  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
769  // FIXME
770  } else {
771  ff_thread_progress_await(s->last_pic.progress, mb_y);
772  }
773  is_intra_likely += s->sad(NULL, last_mb_ptr, mb_ptr,
774  linesize[0], 16);
775  // FIXME need await_progress() here
776  is_intra_likely -= s->sad(NULL, last_mb_ptr,
777  last_mb_ptr + linesize[0] * 16,
778  linesize[0], 16);
779  } else {
780  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
781  is_intra_likely++;
782  else
783  is_intra_likely--;
784  }
785  }
786  }
787 // av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
788  return is_intra_likely > 0;
789 }
790 
792 {
793  if (!s->avctx->error_concealment)
794  return;
795 
796  if (!s->mecc_inited) {
797  MECmpContext mecc;
798  ff_me_cmp_init(&mecc, s->avctx);
799  s->sad = mecc.sad[0];
800  s->mecc_inited = 1;
801  }
802 
803  memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
804  s->mb_stride * s->mb_height * sizeof(uint8_t));
805  atomic_init(&s->error_count, 3 * s->mb_num);
806  s->error_occurred = 0;
807 }
808 
810 {
811  if (s->avctx->hwaccel ||
812  !s->cur_pic.f ||
813  s->cur_pic.field_picture
814  )
815  return 0;
816  return 1;
817 }
818 
819 /**
820  * Add a slice.
821  * @param endx x component of the last macroblock, can be -1
822  * for the last of the previous line
823  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
824  * assumed that no earlier end or error of the same type occurred
825  */
826 void ff_er_add_slice(ERContext *s, int startx, int starty,
827  int endx, int endy, int status)
828 {
829  const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
830  const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num);
831  const int start_xy = s->mb_index2xy[start_i];
832  const int end_xy = s->mb_index2xy[end_i];
833  int mask = -1;
834 
835  if (s->avctx->hwaccel)
836  return;
837 
838  if (start_i > end_i || start_xy > end_xy) {
839  av_log(s->avctx, AV_LOG_ERROR,
840  "internal error, slice end before start\n");
841  return;
842  }
843 
844  if (!s->avctx->error_concealment)
845  return;
846 
847  mask &= ~VP_START;
848  if (status & (ER_AC_ERROR | ER_AC_END)) {
849  mask &= ~(ER_AC_ERROR | ER_AC_END);
850  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
851  }
852  if (status & (ER_DC_ERROR | ER_DC_END)) {
853  mask &= ~(ER_DC_ERROR | ER_DC_END);
854  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
855  }
856  if (status & (ER_MV_ERROR | ER_MV_END)) {
857  mask &= ~(ER_MV_ERROR | ER_MV_END);
858  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
859  }
860 
861  if (status & ER_MB_ERROR) {
862  s->error_occurred = 1;
863  atomic_store(&s->error_count, INT_MAX);
864  }
865 
866  if (mask == ~0x7F) {
867  memset(&s->error_status_table[start_xy], 0,
868  (end_xy - start_xy) * sizeof(uint8_t));
869  } else {
870  int i;
871  for (i = start_xy; i < end_xy; i++)
872  s->error_status_table[i] &= mask;
873  }
874 
875  if (end_i == s->mb_num)
876  atomic_store(&s->error_count, INT_MAX);
877  else {
878  s->error_status_table[end_xy] &= mask;
879  s->error_status_table[end_xy] |= status;
880  }
881 
882  s->error_status_table[start_xy] |= VP_START;
883 
884  if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
885  er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
886  int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
887 
888  prev_status &= ~ VP_START;
889  if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
890  s->error_occurred = 1;
891  atomic_store(&s->error_count, INT_MAX);
892  }
893  }
894 }
895 
896 void ff_er_frame_end(ERContext *s, int *decode_error_flags)
897 {
898  int *linesize = NULL;
899  int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
900  int distance;
901  int threshold_part[4] = { 100, 100, 100 };
902  int threshold = 50;
903  int is_intra_likely;
904  int size = s->b8_stride * 2 * s->mb_height;
905  int guessed_mb_type;
906 
907  /* We do not support ER of field pictures yet,
908  * though it should not crash if enabled. */
909  if (!s->avctx->error_concealment || !atomic_load(&s->error_count) ||
910  s->avctx->lowres ||
911  !er_supported(s) ||
912  atomic_load(&s->error_count) == 3 * s->mb_width *
913  (s->avctx->skip_top + s->avctx->skip_bottom)) {
914  return;
915  }
916  linesize = s->cur_pic.f->linesize;
917 
918  if ( s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
919  && (FFALIGN(s->avctx->height, 16)&16)
920  && atomic_load(&s->error_count) == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)) {
921  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
922  int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
923  if (status != 0x7F)
924  break;
925  }
926 
927  if (mb_x == s->mb_width) {
928  av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
929  return;
930  }
931  }
932 
933  if (s->last_pic.f) {
934  if (s->last_pic.f->width != s->cur_pic.f->width ||
935  s->last_pic.f->height != s->cur_pic.f->height ||
936  s->last_pic.f->format != s->cur_pic.f->format) {
937  av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
938  memset(&s->last_pic, 0, sizeof(s->last_pic));
939  }
940  }
941  if (s->next_pic.f) {
942  if (s->next_pic.f->width != s->cur_pic.f->width ||
943  s->next_pic.f->height != s->cur_pic.f->height ||
944  s->next_pic.f->format != s->cur_pic.f->format) {
945  av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
946  memset(&s->next_pic, 0, sizeof(s->next_pic));
947  }
948  }
949 
950  if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
951  av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
952 
953  for (i = 0; i < 2; i++) {
954  s->ref_index[i] = av_calloc(s->mb_stride * s->mb_height, 4 * sizeof(uint8_t));
955  s->motion_val_base[i] = av_calloc(size + 4, 2 * sizeof(uint16_t));
956  if (!s->ref_index[i] || !s->motion_val_base[i])
957  goto cleanup;
958  s->cur_pic.ref_index[i] = s->ref_index[i];
959  s->cur_pic.motion_val[i] = s->motion_val_base[i] + 4;
960  }
961  }
962 
963  if (s->avctx->debug & FF_DEBUG_ER) {
964  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
965  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
966  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
967 
968  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
969  }
970  av_log(s->avctx, AV_LOG_DEBUG, "\n");
971  }
972  }
973 
974 #if 1
975  /* handle overlapping slices */
976  for (error_type = 1; error_type <= 3; error_type++) {
977  int end_ok = 0;
978 
979  for (i = s->mb_num - 1; i >= 0; i--) {
980  const int mb_xy = s->mb_index2xy[i];
981  int error = s->error_status_table[mb_xy];
982 
983  if (error & (1 << error_type))
984  end_ok = 1;
985  if (error & (8 << error_type))
986  end_ok = 1;
987 
988  if (!end_ok)
989  s->error_status_table[mb_xy] |= 1 << error_type;
990 
991  if (error & VP_START)
992  end_ok = 0;
993  }
994  }
995 #endif
996 #if 1
997  /* handle slices with partitions of different length */
998  if (s->partitioned_frame) {
999  int end_ok = 0;
1000 
1001  for (i = s->mb_num - 1; i >= 0; i--) {
1002  const int mb_xy = s->mb_index2xy[i];
1003  int error = s->error_status_table[mb_xy];
1004 
1005  if (error & ER_AC_END)
1006  end_ok = 0;
1007  if ((error & ER_MV_END) ||
1008  (error & ER_DC_END) ||
1009  (error & ER_AC_ERROR))
1010  end_ok = 1;
1011 
1012  if (!end_ok)
1013  s->error_status_table[mb_xy]|= ER_AC_ERROR;
1014 
1015  if (error & VP_START)
1016  end_ok = 0;
1017  }
1018  }
1019 #endif
1020  /* handle missing slices */
1021  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
1022  int end_ok = 1;
1023 
1024  // FIXME + 100 hack
1025  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
1026  const int mb_xy = s->mb_index2xy[i];
1027  int error1 = s->error_status_table[mb_xy];
1028  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
1029 
1030  if (error1 & VP_START)
1031  end_ok = 1;
1032 
1033  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1034  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1035  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1036  (error1 & ER_MV_END))) {
1037  // end & uninit
1038  end_ok = 0;
1039  }
1040 
1041  if (!end_ok)
1042  s->error_status_table[mb_xy] |= ER_MB_ERROR;
1043  }
1044  }
1045 
1046 #if 1
1047  /* backward mark errors */
1048  distance = 9999999;
1049  for (error_type = 1; error_type <= 3; error_type++) {
1050  for (i = s->mb_num - 1; i >= 0; i--) {
1051  const int mb_xy = s->mb_index2xy[i];
1052  int error = s->error_status_table[mb_xy];
1053 
1054  if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1055  distance++;
1056  if (error & (1 << error_type))
1057  distance = 0;
1058 
1059  if (s->partitioned_frame) {
1060  if (distance < threshold_part[error_type - 1])
1061  s->error_status_table[mb_xy] |= 1 << error_type;
1062  } else {
1063  if (distance < threshold)
1064  s->error_status_table[mb_xy] |= 1 << error_type;
1065  }
1066 
1067  if (error & VP_START)
1068  distance = 9999999;
1069  }
1070  }
1071 #endif
1072 
1073  /* forward mark errors */
1074  error = 0;
1075  for (i = 0; i < s->mb_num; i++) {
1076  const int mb_xy = s->mb_index2xy[i];
1077  int old_error = s->error_status_table[mb_xy];
1078 
1079  if (old_error & VP_START) {
1080  error = old_error & ER_MB_ERROR;
1081  } else {
1082  error |= old_error & ER_MB_ERROR;
1083  s->error_status_table[mb_xy] |= error;
1084  }
1085  }
1086 #if 1
1087  /* handle not partitioned case */
1088  if (!s->partitioned_frame) {
1089  for (i = 0; i < s->mb_num; i++) {
1090  const int mb_xy = s->mb_index2xy[i];
1091  int error = s->error_status_table[mb_xy];
1092  if (error & ER_MB_ERROR)
1093  error |= ER_MB_ERROR;
1094  s->error_status_table[mb_xy] = error;
1095  }
1096  }
1097 #endif
1098 
1099  dc_error = ac_error = mv_error = 0;
1100  for (i = 0; i < s->mb_num; i++) {
1101  const int mb_xy = s->mb_index2xy[i];
1102  int error = s->error_status_table[mb_xy];
1103  if (error & ER_DC_ERROR)
1104  dc_error++;
1105  if (error & ER_AC_ERROR)
1106  ac_error++;
1107  if (error & ER_MV_ERROR)
1108  mv_error++;
1109  }
1110  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1111  dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1112 
1113  if (decode_error_flags)
1114  *decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1115  else
1116  s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1117 
1118  is_intra_likely = is_intra_more_likely(s);
1119 
1120  /* set unknown mb-type to most likely */
1121  guessed_mb_type = is_intra_likely ? MB_TYPE_INTRA4x4 :
1122  (MB_TYPE_16x16 | (s->avctx->codec_id == AV_CODEC_ID_H264 ? MB_TYPE_L0 : MB_TYPE_FORWARD_MV));
1123  for (i = 0; i < s->mb_num; i++) {
1124  const int mb_xy = s->mb_index2xy[i];
1125  int error = s->error_status_table[mb_xy];
1126  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1127  continue;
1128 
1129  s->cur_pic.mb_type[mb_xy] = guessed_mb_type;
1130  }
1131 
1132  // change inter to intra blocks if no reference frames are available
1133  if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1134  !(s->next_pic.f && s->next_pic.f->data[0]))
1135  for (i = 0; i < s->mb_num; i++) {
1136  const int mb_xy = s->mb_index2xy[i];
1137  if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1138  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1139  }
1140 
1141  /* handle inter blocks with damaged AC */
1142  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1143  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1144  const int mb_xy = mb_x + mb_y * s->mb_stride;
1145  const int mb_type = s->cur_pic.mb_type[mb_xy];
1146  const int dir = !(s->last_pic.f && s->last_pic.f->data[0]);
1147  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1148  int mv_type;
1149 
1150  int error = s->error_status_table[mb_xy];
1151 
1152  if (IS_INTRA(mb_type))
1153  continue; // intra
1154  if (error & ER_MV_ERROR)
1155  continue; // inter with damaged MV
1156  if (!(error & ER_AC_ERROR))
1157  continue; // undamaged inter
1158 
1159  if (IS_8X8(mb_type)) {
1160  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1161  int j;
1162  mv_type = MV_TYPE_8X8;
1163  for (j = 0; j < 4; j++) {
1164  s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1165  s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1166  }
1167  } else {
1168  mv_type = MV_TYPE_16X16;
1169  s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1170  s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1171  }
1172 
1173  s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1174  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1175  }
1176  }
1177 
1178  /* guess MVs */
1179  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1180  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1181  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1182  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1183  const int mb_xy = mb_x + mb_y * s->mb_stride;
1184  const int mb_type = s->cur_pic.mb_type[mb_xy];
1185  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1186 
1187  int error = s->error_status_table[mb_xy];
1188 
1189  if (IS_INTRA(mb_type))
1190  continue;
1191  if (!(error & ER_MV_ERROR))
1192  continue; // inter with undamaged MV
1193  if (!(error & ER_AC_ERROR))
1194  continue; // undamaged inter
1195 
1196  if (!(s->last_pic.f && s->last_pic.f->data[0]))
1197  mv_dir &= ~MV_DIR_FORWARD;
1198  if (!(s->next_pic.f && s->next_pic.f->data[0]))
1199  mv_dir &= ~MV_DIR_BACKWARD;
1200 
1201  if (s->pp_time) {
1202  int time_pp = s->pp_time;
1203  int time_pb = s->pb_time;
1204 
1205  av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1206  ff_thread_progress_await(s->next_pic.progress, mb_y);
1207 
1208  s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp;
1209  s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp;
1210  s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1211  s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1212  } else {
1213  s->mv[0][0][0] = 0;
1214  s->mv[0][0][1] = 0;
1215  s->mv[1][0][0] = 0;
1216  s->mv[1][0][1] = 0;
1217  }
1218 
1219  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1220  mb_x, mb_y, 0, 0);
1221  }
1222  }
1223  } else
1224  guess_mv(s);
1225 
1226  /* fill DC for inter blocks */
1227  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1228  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1229  int dc, dcu, dcv, y, n;
1230  int16_t *dc_ptr;
1231  uint8_t *dest_y, *dest_cb, *dest_cr;
1232  const int mb_xy = mb_x + mb_y * s->mb_stride;
1233  const int mb_type = s->cur_pic.mb_type[mb_xy];
1234 
1235  // error = s->error_status_table[mb_xy];
1236 
1237  if (IS_INTRA(mb_type) && s->partitioned_frame)
1238  continue;
1239  // if (error & ER_MV_ERROR)
1240  // continue; // inter data damaged FIXME is this good?
1241 
1242  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1243  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1244  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1245 
1246  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1247  for (n = 0; n < 4; n++) {
1248  dc = 0;
1249  for (y = 0; y < 8; y++) {
1250  int x;
1251  for (x = 0; x < 8; x++)
1252  dc += dest_y[x + (n & 1) * 8 +
1253  (y + (n >> 1) * 8) * linesize[0]];
1254  }
1255  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1256  }
1257 
1258  if (!s->cur_pic.f->data[2])
1259  continue;
1260 
1261  dcu = dcv = 0;
1262  for (y = 0; y < 8; y++) {
1263  int x;
1264  for (x = 0; x < 8; x++) {
1265  dcu += dest_cb[x + y * linesize[1]];
1266  dcv += dest_cr[x + y * linesize[2]];
1267  }
1268  }
1269  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1270  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1271  }
1272  }
1273 #if 1
1274  /* guess DC for damaged blocks */
1275  guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1276  guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1277  guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1278 #endif
1279 
1280  /* filter luma DC */
1281  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1282 
1283 #if 1
1284  /* render DC only intra */
1285  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1286  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1287  uint8_t *dest_y, *dest_cb, *dest_cr;
1288  const int mb_xy = mb_x + mb_y * s->mb_stride;
1289  const int mb_type = s->cur_pic.mb_type[mb_xy];
1290 
1291  int error = s->error_status_table[mb_xy];
1292 
1293  if (IS_INTER(mb_type))
1294  continue;
1295  if (!(error & ER_AC_ERROR))
1296  continue; // undamaged
1297 
1298  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1299  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1300  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1301  if (!s->cur_pic.f->data[2])
1302  dest_cb = dest_cr = NULL;
1303 
1304  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1305  }
1306  }
1307 #endif
1308 
1309  if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1310  /* filter horizontal block boundaries */
1311  h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1312  s->mb_height * 2, linesize[0], 1);
1313 
1314  /* filter vertical block boundaries */
1315  v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1316  s->mb_height * 2, linesize[0], 1);
1317 
1318  if (s->cur_pic.f->data[2]) {
1319  h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1320  s->mb_height, linesize[1], 0);
1321  h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1322  s->mb_height, linesize[2], 0);
1323  v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1324  s->mb_height, linesize[1], 0);
1325  v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1326  s->mb_height, linesize[2], 0);
1327  }
1328  }
1329 
1330  /* clean a few tables */
1331  for (i = 0; i < s->mb_num; i++) {
1332  const int mb_xy = s->mb_index2xy[i];
1333  int error = s->error_status_table[mb_xy];
1334 
1335  if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1337  s->mbskip_table[mb_xy] = 0;
1338  }
1339  if (s->mbintra_table)
1340  s->mbintra_table[mb_xy] = 1;
1341  }
1342 
1343  memset(&s->cur_pic, 0, sizeof(ERPicture));
1344  memset(&s->last_pic, 0, sizeof(ERPicture));
1345  memset(&s->next_pic, 0, sizeof(ERPicture));
1346 
1347 cleanup:
1348  for (i = 0; i < 2; i++) {
1349  av_freep(&s->ref_index[i]);
1350  av_freep(&s->motion_val_base[i]);
1351  s->cur_pic.ref_index[i] = NULL;
1352  s->cur_pic.motion_val[i] = NULL;
1353  }
1354 }
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:719
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:84
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:58
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:265
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
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
MV_UNCHANGED
#define MV_UNCHANGED
Definition: error_resilience.c:378
threadprogress.h
color
Definition: vf_paletteuse.c:513
MV_CHANGED
#define MV_CHANGED
Definition: error_resilience.c:377
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:722
set_mv_strides
static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
Definition: error_resilience.c:43
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
w
uint8_t w
Definition: llviddspenc.c:38
MB_TYPE_INTRA4x4
#define MB_TYPE_INTRA4x4
Definition: mpegutils.h:39
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:149
MV_FROZEN
#define MV_FROZEN
Definition: error_resilience.c:376
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:42
ff_er_frame_start
void ff_er_frame_start(ERContext *s)
Definition: error_resilience.c:791
ERContext
Definition: error_resilience.h:53
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:826
FF_EC_GUESS_MVS
#define FF_EC_GUESS_MVS
Definition: avcodec.h:1397
mpegvideo.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ER_DC_END
#define ER_DC_END
Definition: error_resilience.h:34
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:240
mpegutils.h
ER_MV_ERROR
#define ER_MV_ERROR
Definition: error_resilience.h:32
ff_crop_tab
#define ff_crop_tab
Definition: motionpixels_tablegen.c:26
MV_DIR_BACKWARD
#define MV_DIR_BACKWARD
Definition: mpegvideo.h:262
ERPicture
Definition: error_resilience.h:40
fail
#define fail()
Definition: checkasm.h:189
FF_DEBUG_ER
#define FF_DEBUG_ER
Definition: avcodec.h:1415
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:996
weight
const h264_weight_func weight
Definition: h264dsp_init.c:33
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
ER_DC_ERROR
#define ER_DC_ERROR
Definition: error_resilience.h:31
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:896
s
#define s(width, name)
Definition: cbs_vp9.c:198
FF_EC_DEBLOCK
#define FF_EC_DEBLOCK
Definition: avcodec.h:1398
er_supported
static int er_supported(ERContext *s)
Definition: error_resilience.c:809
guess_mv
static void guess_mv(ERContext *s)
Definition: error_resilience.c:389
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
limits.h
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:309
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:380
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:55
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:65
NULL
#define NULL
Definition: coverity.c:32
ER_AC_ERROR
#define ER_AC_ERROR
Definition: error_resilience.h:30
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:650
MECmpContext::sad
me_cmp_func sad[6]
Definition: me_cmp.h:58
ER_MB_ERROR
#define ER_MB_ERROR
Definition: error_resilience.h:37
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
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:137
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:266
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:85
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
VP_START
#define VP_START
< current MB is the first after a resync marker
Definition: error_resilience.h:29
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
FF_THREAD_SLICE
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
Definition: avcodec.h:1605
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
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
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:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
av_always_inline
#define av_always_inline
Definition: attributes.h:49
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
stride
#define stride
Definition: h264pred_template.c:537
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:281
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:379
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:58
IS_INTER
#define IS_INTER(a)
Definition: mpegutils.h:74
mem.h
ER_MB_END
#define ER_MB_END
Definition: error_resilience.h:38
ER_MV_END
#define ER_MV_END
Definition: error_resilience.h:35
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
MV_DIR_FORWARD
#define MV_DIR_FORWARD
Definition: mpegvideo.h:261
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
fixed
#define fixed(width, name, value)
Definition: cbs_av1.c:487
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:33
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
width
#define width
Definition: dsp.h:85
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31
FF_EC_FAVOR_INTER
#define FF_EC_FAVOR_INTER
Definition: avcodec.h:1399
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:50
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:96