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