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/internal.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 "rectangle.h"
37 #include "threadframe.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, depth, 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  ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0);
415  for (i = 0; i < mb_width * mb_height; i++) {
416  const int mb_xy = s->mb_index2xy[i];
417  int f = 0;
418  int error = s->error_status_table[mb_xy];
419 
420  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
421  f = MV_FROZEN; // intra // FIXME check
422  if (!(error & ER_MV_ERROR))
423  f = MV_FROZEN; // inter with undamaged MV
424 
425  fixed[mb_xy] = f;
426  if (f == MV_FROZEN)
427  num_avail++;
428  else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
429  const int mb_y= mb_xy / s->mb_stride;
430  const int mb_x= mb_xy % s->mb_stride;
431  const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
432  s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
433  s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
434  s->cur_pic.ref_index[0][4*mb_xy] = s->last_pic.ref_index[0][4*mb_xy];
435  }
436  }
437 
438  if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
439  num_avail <= FFMAX(mb_width, mb_height) / 2) {
440  for (mb_y = 0; mb_y < mb_height; mb_y++) {
441  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
442  const int mb_xy = mb_x + mb_y * s->mb_stride;
443  int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
444 
445  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
446  continue;
447  if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
448  continue;
449 
450  s->mv[0][0][0] = 0;
451  s->mv[0][0][1] = 0;
452  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
453  mb_x, mb_y, 0, 0);
454  }
455  }
456  return;
457  }
458 
459  blocklist_length = 0;
460  for (mb_y = 0; mb_y < mb_height; mb_y++) {
461  for (mb_x = 0; mb_x < mb_width; mb_x++) {
462  const int mb_xy = mb_x + mb_y * mb_stride;
463  if (fixed[mb_xy] == MV_FROZEN) {
464  if (mb_x) add_blocklist(blocklist, &blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
465  if (mb_y) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
466  if (mb_x+1 < mb_width) add_blocklist(blocklist, &blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
467  if (mb_y+1 < mb_height) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
468  }
469  }
470  }
471 
472  for (depth = 0; ; depth++) {
473  int changed, pass, none_left;
474  int blocklist_index;
475 
476  none_left = 1;
477  changed = 1;
478  for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
479  changed = 0;
480  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
481  const int mb_x = blocklist[blocklist_index][0];
482  const int mb_y = blocklist[blocklist_index][1];
483  const int mb_xy = mb_x + mb_y * mb_stride;
484  int mv_predictor[8][2];
485  int ref[8];
486  int pred_count;
487  int j;
488  int best_score;
489  int best_pred;
490  int mot_index;
491  int prev_x, prev_y, prev_ref;
492 
493  if ((mb_x ^ mb_y ^ pass) & 1)
494  continue;
495  av_assert2(fixed[mb_xy] != MV_FROZEN);
496 
497 
498  av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
499  av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
500 
501  j = 0;
502  if (mb_x > 0)
503  j |= fixed[mb_xy - 1];
504  if (mb_x + 1 < mb_width)
505  j |= fixed[mb_xy + 1];
506  if (mb_y > 0)
507  j |= fixed[mb_xy - mb_stride];
508  if (mb_y + 1 < mb_height)
509  j |= fixed[mb_xy + mb_stride];
510 
511  av_assert2(j & MV_FROZEN);
512 
513  if (!(j & MV_CHANGED) && pass > 1)
514  continue;
515 
516  none_left = 0;
517  pred_count = 0;
518  mot_index = (mb_x + mb_y * mot_stride) * mot_step;
519 
520  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
521  mv_predictor[pred_count][0] =
522  s->cur_pic.motion_val[0][mot_index - mot_step][0];
523  mv_predictor[pred_count][1] =
524  s->cur_pic.motion_val[0][mot_index - mot_step][1];
525  ref[pred_count] =
526  s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
527  pred_count++;
528  }
529  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
530  mv_predictor[pred_count][0] =
531  s->cur_pic.motion_val[0][mot_index + mot_step][0];
532  mv_predictor[pred_count][1] =
533  s->cur_pic.motion_val[0][mot_index + mot_step][1];
534  ref[pred_count] =
535  s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
536  pred_count++;
537  }
538  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
539  mv_predictor[pred_count][0] =
540  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
541  mv_predictor[pred_count][1] =
542  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
543  ref[pred_count] =
544  s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
545  pred_count++;
546  }
547  if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride] > 1) {
548  mv_predictor[pred_count][0] =
549  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
550  mv_predictor[pred_count][1] =
551  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
552  ref[pred_count] =
553  s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
554  pred_count++;
555  }
556  if (pred_count == 0)
557  continue;
558 
559  if (pred_count > 1) {
560  int sum_x = 0, sum_y = 0, sum_r = 0;
561  int max_x, max_y, min_x, min_y, max_r, min_r;
562 
563  for (j = 0; j < pred_count; j++) {
564  sum_x += mv_predictor[j][0];
565  sum_y += mv_predictor[j][1];
566  sum_r += ref[j];
567  if (j && ref[j] != ref[j - 1])
568  goto skip_mean_and_median;
569  }
570 
571  /* mean */
572  mv_predictor[pred_count][0] = sum_x / j;
573  mv_predictor[pred_count][1] = sum_y / j;
574  ref[pred_count] = sum_r / j;
575 
576  /* median */
577  if (pred_count >= 3) {
578  min_y = min_x = min_r = 99999;
579  max_y = max_x = max_r = -99999;
580  } else {
581  min_x = min_y = max_x = max_y = min_r = max_r = 0;
582  }
583  for (j = 0; j < pred_count; j++) {
584  max_x = FFMAX(max_x, mv_predictor[j][0]);
585  max_y = FFMAX(max_y, mv_predictor[j][1]);
586  max_r = FFMAX(max_r, ref[j]);
587  min_x = FFMIN(min_x, mv_predictor[j][0]);
588  min_y = FFMIN(min_y, mv_predictor[j][1]);
589  min_r = FFMIN(min_r, ref[j]);
590  }
591  mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
592  mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
593  ref[pred_count + 1] = sum_r - max_r - min_r;
594 
595  if (pred_count == 4) {
596  mv_predictor[pred_count + 1][0] /= 2;
597  mv_predictor[pred_count + 1][1] /= 2;
598  ref[pred_count + 1] /= 2;
599  }
600  pred_count += 2;
601  }
602 
603 skip_mean_and_median:
604  /* zero MV */
605  mv_predictor[pred_count][0] =
606  mv_predictor[pred_count][1] =
607  ref[pred_count] = 0;
608  pred_count++;
609 
610  prev_x = s->cur_pic.motion_val[0][mot_index][0];
611  prev_y = s->cur_pic.motion_val[0][mot_index][1];
612  prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
613 
614  /* last MV */
615  mv_predictor[pred_count][0] = prev_x;
616  mv_predictor[pred_count][1] = prev_y;
617  ref[pred_count] = prev_ref;
618  pred_count++;
619 
620  best_pred = 0;
621  best_score = 256 * 256 * 256 * 64;
622  for (j = 0; j < pred_count; j++) {
623  int *linesize = s->cur_pic.f->linesize;
624  int score = 0;
625  uint8_t *src = s->cur_pic.f->data[0] +
626  mb_x * 16 + mb_y * 16 * linesize[0];
627 
628  s->cur_pic.motion_val[0][mot_index][0] =
629  s->mv[0][0][0] = mv_predictor[j][0];
630  s->cur_pic.motion_val[0][mot_index][1] =
631  s->mv[0][0][1] = mv_predictor[j][1];
632 
633  // predictor intra or otherwise not available
634  if (ref[j] < 0)
635  continue;
636 
637  s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
638  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
639 
640  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
641  int k;
642  for (k = 0; k < 16; k++)
643  score += FFABS(src[k * linesize[0] - 1] -
644  src[k * linesize[0]]);
645  }
646  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
647  int k;
648  for (k = 0; k < 16; k++)
649  score += FFABS(src[k * linesize[0] + 15] -
650  src[k * linesize[0] + 16]);
651  }
652  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
653  int k;
654  for (k = 0; k < 16; k++)
655  score += FFABS(src[k - linesize[0]] - src[k]);
656  }
657  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) {
658  int k;
659  for (k = 0; k < 16; k++)
660  score += FFABS(src[k + linesize[0] * 15] -
661  src[k + linesize[0] * 16]);
662  }
663 
664  if (score <= best_score) { // <= will favor the last MV
665  best_score = score;
666  best_pred = j;
667  }
668  }
669  s->mv[0][0][0] = mv_predictor[best_pred][0];
670  s->mv[0][0][1] = mv_predictor[best_pred][1];
671 
672  for (i = 0; i < mot_step; i++)
673  for (j = 0; j < mot_step; j++) {
674  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
675  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
676  }
677 
678  s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
679  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
680 
681 
682  if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
683  fixed[mb_xy] = MV_CHANGED;
684  changed++;
685  } else
686  fixed[mb_xy] = MV_UNCHANGED;
687  }
688  }
689 
690  if (none_left)
691  return;
692 
693  next_blocklist_length = 0;
694 
695  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
696  const int mb_x = blocklist[blocklist_index][0];
697  const int mb_y = blocklist[blocklist_index][1];
698  const int mb_xy = mb_x + mb_y * mb_stride;
699 
700  if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) {
701  fixed[mb_xy] = MV_FROZEN;
702  if (mb_x > 0)
703  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
704  if (mb_y > 0)
705  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
706  if (mb_x + 1 < mb_width)
707  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
708  if (mb_y + 1 < mb_height)
709  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
710  }
711  }
712  av_assert0(next_blocklist_length <= mb_height * mb_width);
713  FFSWAP(int , blocklist_length, next_blocklist_length);
714  FFSWAP(void*, blocklist, next_blocklist);
715  }
716 }
717 
719 {
720  int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
721 
722  if (!s->last_pic.f || !s->last_pic.f->data[0])
723  return 1; // no previous frame available -> use spatial prediction
724 
725  if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
726  return 0;
727 
728  undamaged_count = 0;
729  for (i = 0; i < s->mb_num; i++) {
730  const int mb_xy = s->mb_index2xy[i];
731  const int error = s->error_status_table[mb_xy];
732  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
733  undamaged_count++;
734  }
735 
736  if (undamaged_count < 5)
737  return 0; // almost all MBs damaged -> use temporal prediction
738 
739  skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
740  is_intra_likely = 0;
741 
742  j = 0;
743  for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
744  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
745  int error;
746  const int mb_xy = mb_x + mb_y * s->mb_stride;
747 
748  error = s->error_status_table[mb_xy];
749  if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
750  continue; // skip damaged
751 
752  j++;
753  // skip a few to speed things up
754  if ((j % skip_amount) != 0)
755  continue;
756 
757  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
758  int *linesize = s->cur_pic.f->linesize;
759  uint8_t *mb_ptr = s->cur_pic.f->data[0] +
760  mb_x * 16 + mb_y * 16 * linesize[0];
761  uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
762  mb_x * 16 + mb_y * 16 * linesize[0];
763 
764  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
765  // FIXME
766  } else {
767  ff_thread_await_progress(s->last_pic.tf, mb_y, 0);
768  }
769  is_intra_likely += s->sad(NULL, last_mb_ptr, mb_ptr,
770  linesize[0], 16);
771  // FIXME need await_progress() here
772  is_intra_likely -= s->sad(NULL, last_mb_ptr,
773  last_mb_ptr + linesize[0] * 16,
774  linesize[0], 16);
775  } else {
776  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
777  is_intra_likely++;
778  else
779  is_intra_likely--;
780  }
781  }
782  }
783 // av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
784  return is_intra_likely > 0;
785 }
786 
788 {
789  if (!s->avctx->error_concealment)
790  return;
791 
792  if (!s->mecc_inited) {
793  MECmpContext mecc;
794  ff_me_cmp_init(&mecc, s->avctx);
795  s->sad = mecc.sad[0];
796  s->mecc_inited = 1;
797  }
798 
799  memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
800  s->mb_stride * s->mb_height * sizeof(uint8_t));
801  atomic_init(&s->error_count, 3 * s->mb_num);
802  s->error_occurred = 0;
803 }
804 
806 {
807  if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice ||
808  !s->cur_pic.f
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 && s->avctx->hwaccel->decode_slice)
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 
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 
911  if (!s->warned_fields && (s->cur_pic.field_picture || s->cur_pic.f->interlaced_frame)) {
912  av_log(s->avctx, AV_LOG_WARNING, "Error concealment is not fully implemented for field pictures.\n");
913  s->warned_fields = 1;
914  }
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  break;
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  if (i < 2) {
962  for (i = 0; i < 2; i++) {
963  av_freep(&s->ref_index[i]);
964  av_freep(&s->motion_val_base[i]);
965  s->cur_pic.ref_index[i] = NULL;
966  s->cur_pic.motion_val[i] = NULL;
967  }
968  return;
969  }
970  }
971 
972  if (s->avctx->debug & FF_DEBUG_ER) {
973  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
974  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
975  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
976 
977  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
978  }
979  av_log(s->avctx, AV_LOG_DEBUG, "\n");
980  }
981  }
982 
983 #if 1
984  /* handle overlapping slices */
985  for (error_type = 1; error_type <= 3; error_type++) {
986  int end_ok = 0;
987 
988  for (i = s->mb_num - 1; i >= 0; i--) {
989  const int mb_xy = s->mb_index2xy[i];
990  int error = s->error_status_table[mb_xy];
991 
992  if (error & (1 << error_type))
993  end_ok = 1;
994  if (error & (8 << error_type))
995  end_ok = 1;
996 
997  if (!end_ok)
998  s->error_status_table[mb_xy] |= 1 << error_type;
999 
1000  if (error & VP_START)
1001  end_ok = 0;
1002  }
1003  }
1004 #endif
1005 #if 1
1006  /* handle slices with partitions of different length */
1007  if (s->partitioned_frame) {
1008  int end_ok = 0;
1009 
1010  for (i = s->mb_num - 1; i >= 0; i--) {
1011  const int mb_xy = s->mb_index2xy[i];
1012  int error = s->error_status_table[mb_xy];
1013 
1014  if (error & ER_AC_END)
1015  end_ok = 0;
1016  if ((error & ER_MV_END) ||
1017  (error & ER_DC_END) ||
1018  (error & ER_AC_ERROR))
1019  end_ok = 1;
1020 
1021  if (!end_ok)
1022  s->error_status_table[mb_xy]|= ER_AC_ERROR;
1023 
1024  if (error & VP_START)
1025  end_ok = 0;
1026  }
1027  }
1028 #endif
1029  /* handle missing slices */
1030  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
1031  int end_ok = 1;
1032 
1033  // FIXME + 100 hack
1034  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
1035  const int mb_xy = s->mb_index2xy[i];
1036  int error1 = s->error_status_table[mb_xy];
1037  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
1038 
1039  if (error1 & VP_START)
1040  end_ok = 1;
1041 
1042  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1043  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1044  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1045  (error1 & ER_MV_END))) {
1046  // end & uninit
1047  end_ok = 0;
1048  }
1049 
1050  if (!end_ok)
1051  s->error_status_table[mb_xy] |= ER_MB_ERROR;
1052  }
1053  }
1054 
1055 #if 1
1056  /* backward mark errors */
1057  distance = 9999999;
1058  for (error_type = 1; error_type <= 3; error_type++) {
1059  for (i = s->mb_num - 1; i >= 0; i--) {
1060  const int mb_xy = s->mb_index2xy[i];
1061  int error = s->error_status_table[mb_xy];
1062 
1063  if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1064  distance++;
1065  if (error & (1 << error_type))
1066  distance = 0;
1067 
1068  if (s->partitioned_frame) {
1069  if (distance < threshold_part[error_type - 1])
1070  s->error_status_table[mb_xy] |= 1 << error_type;
1071  } else {
1072  if (distance < threshold)
1073  s->error_status_table[mb_xy] |= 1 << error_type;
1074  }
1075 
1076  if (error & VP_START)
1077  distance = 9999999;
1078  }
1079  }
1080 #endif
1081 
1082  /* forward mark errors */
1083  error = 0;
1084  for (i = 0; i < s->mb_num; i++) {
1085  const int mb_xy = s->mb_index2xy[i];
1086  int old_error = s->error_status_table[mb_xy];
1087 
1088  if (old_error & VP_START) {
1089  error = old_error & ER_MB_ERROR;
1090  } else {
1091  error |= old_error & ER_MB_ERROR;
1092  s->error_status_table[mb_xy] |= error;
1093  }
1094  }
1095 #if 1
1096  /* handle not partitioned case */
1097  if (!s->partitioned_frame) {
1098  for (i = 0; i < s->mb_num; i++) {
1099  const int mb_xy = s->mb_index2xy[i];
1100  int error = s->error_status_table[mb_xy];
1101  if (error & ER_MB_ERROR)
1102  error |= ER_MB_ERROR;
1103  s->error_status_table[mb_xy] = error;
1104  }
1105  }
1106 #endif
1107 
1108  dc_error = ac_error = mv_error = 0;
1109  for (i = 0; i < s->mb_num; i++) {
1110  const int mb_xy = s->mb_index2xy[i];
1111  int error = s->error_status_table[mb_xy];
1112  if (error & ER_DC_ERROR)
1113  dc_error++;
1114  if (error & ER_AC_ERROR)
1115  ac_error++;
1116  if (error & ER_MV_ERROR)
1117  mv_error++;
1118  }
1119  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1120  dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1121 
1122  s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1123 
1124  is_intra_likely = is_intra_more_likely(s);
1125 
1126  /* set unknown mb-type to most likely */
1127  for (i = 0; i < s->mb_num; i++) {
1128  const int mb_xy = s->mb_index2xy[i];
1129  int error = s->error_status_table[mb_xy];
1130  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1131  continue;
1132 
1133  if (is_intra_likely)
1134  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1135  else
1136  s->cur_pic.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
1137  }
1138 
1139  // change inter to intra blocks if no reference frames are available
1140  if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1141  !(s->next_pic.f && s->next_pic.f->data[0]))
1142  for (i = 0; i < s->mb_num; i++) {
1143  const int mb_xy = s->mb_index2xy[i];
1144  if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1145  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1146  }
1147 
1148  /* handle inter blocks with damaged AC */
1149  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1150  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1151  const int mb_xy = mb_x + mb_y * s->mb_stride;
1152  const int mb_type = s->cur_pic.mb_type[mb_xy];
1153  const int dir = !(s->last_pic.f && s->last_pic.f->data[0]);
1154  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1155  int mv_type;
1156 
1157  int error = s->error_status_table[mb_xy];
1158 
1159  if (IS_INTRA(mb_type))
1160  continue; // intra
1161  if (error & ER_MV_ERROR)
1162  continue; // inter with damaged MV
1163  if (!(error & ER_AC_ERROR))
1164  continue; // undamaged inter
1165 
1166  if (IS_8X8(mb_type)) {
1167  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1168  int j;
1169  mv_type = MV_TYPE_8X8;
1170  for (j = 0; j < 4; j++) {
1171  s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1172  s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1173  }
1174  } else {
1175  mv_type = MV_TYPE_16X16;
1176  s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1177  s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1178  }
1179 
1180  s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1181  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1182  }
1183  }
1184 
1185  /* guess MVs */
1186  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1187  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1188  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1189  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1190  const int mb_xy = mb_x + mb_y * s->mb_stride;
1191  const int mb_type = s->cur_pic.mb_type[mb_xy];
1192  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1193 
1194  int error = s->error_status_table[mb_xy];
1195 
1196  if (IS_INTRA(mb_type))
1197  continue;
1198  if (!(error & ER_MV_ERROR))
1199  continue; // inter with undamaged MV
1200  if (!(error & ER_AC_ERROR))
1201  continue; // undamaged inter
1202 
1203  if (!(s->last_pic.f && s->last_pic.f->data[0]))
1204  mv_dir &= ~MV_DIR_FORWARD;
1205  if (!(s->next_pic.f && s->next_pic.f->data[0]))
1206  mv_dir &= ~MV_DIR_BACKWARD;
1207 
1208  if (s->pp_time) {
1209  int time_pp = s->pp_time;
1210  int time_pb = s->pb_time;
1211 
1212  av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1213  ff_thread_await_progress(s->next_pic.tf, mb_y, 0);
1214 
1215  s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp;
1216  s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp;
1217  s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1218  s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1219  } else {
1220  s->mv[0][0][0] = 0;
1221  s->mv[0][0][1] = 0;
1222  s->mv[1][0][0] = 0;
1223  s->mv[1][0][1] = 0;
1224  }
1225 
1226  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1227  mb_x, mb_y, 0, 0);
1228  }
1229  }
1230  } else
1231  guess_mv(s);
1232 
1233  /* fill DC for inter blocks */
1234  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1235  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1236  int dc, dcu, dcv, y, n;
1237  int16_t *dc_ptr;
1238  uint8_t *dest_y, *dest_cb, *dest_cr;
1239  const int mb_xy = mb_x + mb_y * s->mb_stride;
1240  const int mb_type = s->cur_pic.mb_type[mb_xy];
1241 
1242  // error = s->error_status_table[mb_xy];
1243 
1244  if (IS_INTRA(mb_type) && s->partitioned_frame)
1245  continue;
1246  // if (error & ER_MV_ERROR)
1247  // continue; // inter data damaged FIXME is this good?
1248 
1249  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1250  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1251  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1252 
1253  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1254  for (n = 0; n < 4; n++) {
1255  dc = 0;
1256  for (y = 0; y < 8; y++) {
1257  int x;
1258  for (x = 0; x < 8; x++)
1259  dc += dest_y[x + (n & 1) * 8 +
1260  (y + (n >> 1) * 8) * linesize[0]];
1261  }
1262  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1263  }
1264 
1265  if (!s->cur_pic.f->data[2])
1266  continue;
1267 
1268  dcu = dcv = 0;
1269  for (y = 0; y < 8; y++) {
1270  int x;
1271  for (x = 0; x < 8; x++) {
1272  dcu += dest_cb[x + y * linesize[1]];
1273  dcv += dest_cr[x + y * linesize[2]];
1274  }
1275  }
1276  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1277  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1278  }
1279  }
1280 #if 1
1281  /* guess DC for damaged blocks */
1282  guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1283  guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1284  guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1285 #endif
1286 
1287  /* filter luma DC */
1288  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1289 
1290 #if 1
1291  /* render DC only intra */
1292  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1293  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1294  uint8_t *dest_y, *dest_cb, *dest_cr;
1295  const int mb_xy = mb_x + mb_y * s->mb_stride;
1296  const int mb_type = s->cur_pic.mb_type[mb_xy];
1297 
1298  int error = s->error_status_table[mb_xy];
1299 
1300  if (IS_INTER(mb_type))
1301  continue;
1302  if (!(error & ER_AC_ERROR))
1303  continue; // undamaged
1304 
1305  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1306  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1307  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1308  if (!s->cur_pic.f->data[2])
1309  dest_cb = dest_cr = NULL;
1310 
1311  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1312  }
1313  }
1314 #endif
1315 
1316  if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1317  /* filter horizontal block boundaries */
1318  h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1319  s->mb_height * 2, linesize[0], 1);
1320 
1321  /* filter vertical block boundaries */
1322  v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1323  s->mb_height * 2, linesize[0], 1);
1324 
1325  if (s->cur_pic.f->data[2]) {
1326  h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1327  s->mb_height, linesize[1], 0);
1328  h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1329  s->mb_height, linesize[2], 0);
1330  v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1331  s->mb_height, linesize[1], 0);
1332  v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1333  s->mb_height, linesize[2], 0);
1334  }
1335  }
1336 
1337  /* clean a few tables */
1338  for (i = 0; i < s->mb_num; i++) {
1339  const int mb_xy = s->mb_index2xy[i];
1340  int error = s->error_status_table[mb_xy];
1341 
1342  if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1344  s->mbskip_table[mb_xy] = 0;
1345  }
1346  if (s->mbintra_table)
1347  s->mbintra_table[mb_xy] = 1;
1348  }
1349 
1350  for (i = 0; i < 2; i++) {
1351  av_freep(&s->ref_index[i]);
1352  av_freep(&s->motion_val_base[i]);
1353  s->cur_pic.ref_index[i] = NULL;
1354  s->cur_pic.motion_val[i] = NULL;
1355  }
1356 
1357  memset(&s->cur_pic, 0, sizeof(ERPicture));
1358  memset(&s->last_pic, 0, sizeof(ERPicture));
1359  memset(&s->next_pic, 0, sizeof(ERPicture));
1360 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
FF_DECODE_ERROR_CONCEALMENT_ACTIVE
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE
Definition: frame.h:667
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:82
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:60
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:262
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
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:95
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
MV_UNCHANGED
#define MV_UNCHANGED
Definition: error_resilience.c:378
color
Definition: vf_paletteuse.c:509
MV_CHANGED
#define MV_CHANGED
Definition: error_resilience.c:377
is_intra_more_likely
static int is_intra_more_likely(ERContext *s)
Definition: error_resilience.c:718
set_mv_strides
static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
Definition: error_resilience.c:43
w
uint8_t w
Definition: llviddspenc.c:38
MB_TYPE_INTRA4x4
#define MB_TYPE_INTRA4x4
Definition: mpegutils.h:44
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:146
MV_FROZEN
#define MV_FROZEN
Definition: error_resilience.c:376
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:47
ff_er_frame_start
void ff_er_frame_start(ERContext *s)
Definition: error_resilience.c:787
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:821
FF_EC_GUESS_MVS
#define FF_EC_GUESS_MVS
Definition: avcodec.h:1362
mpegvideo.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ER_DC_END
#define ER_DC_END
Definition: error_resilience.h:35
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:33
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:259
ERPicture
Definition: error_resilience.h:41
fail
#define fail()
Definition: checkasm.h:135
FF_DEBUG_ER
#define FF_DEBUG_ER
Definition: avcodec.h:1380
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:1003
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:32
mask
static const uint16_t mask[17]
Definition: lzw.c:38
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:256
FF_EC_DEBLOCK
#define FF_EC_DEBLOCK
Definition: avcodec.h:1363
er_supported
static int er_supported(ERContext *s)
Definition: error_resilience.c:805
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:37
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:309
pass
#define pass
Definition: fft_template.c:608
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:64
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:31
MECmpContext::sad
me_cmp_func sad[6]
Definition: me_cmp.h:58
ER_MB_ERROR
#define ER_MB_ERROR
Definition: error_resilience.h:38
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
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
weight
static int weight(int i, int blen, int offset)
Definition: diracdec.c:1562
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:263
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
rectangle.h
VP_START
#define VP_START
< current MB is the first after a resync marker
Definition: error_resilience.h:30
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:1527
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:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
internal.h
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:53
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:262
avcodec.h
stride
#define stride
Definition: h264pred_template.c:537
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
me_cmp.h
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
error_resilience.h
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:131
cm
#define cm
Definition: dvbsubdec.c:39
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
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:72
ER_MB_END
#define ER_MB_END
Definition: error_resilience.h:39
ER_MV_END
#define ER_MV_END
Definition: error_resilience.h:36
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
MV_DIR_FORWARD
#define MV_DIR_FORWARD
Definition: mpegvideo.h:258
ff_er_frame_end
void ff_er_frame_end(ERContext *s)
Definition: error_resilience.c:891
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:156
fixed
#define fixed(width, name, value)
Definition: cbs_av1.c:566
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:230
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:34
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:1364
int
int
Definition: ffmpeg_filter.c:156
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:96