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 "thread.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  int score_sum = 0;
480 
481  changed = 0;
482  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
483  const int mb_x = blocklist[blocklist_index][0];
484  const int mb_y = blocklist[blocklist_index][1];
485  const int mb_xy = mb_x + mb_y * mb_stride;
486  int mv_predictor[8][2];
487  int ref[8];
488  int pred_count;
489  int j;
490  int best_score;
491  int best_pred;
492  int mot_index;
493  int prev_x, prev_y, prev_ref;
494 
495  if ((mb_x ^ mb_y ^ pass) & 1)
496  continue;
497  av_assert2(fixed[mb_xy] != MV_FROZEN);
498 
499 
500  av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
501  av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
502 
503  j = 0;
504  if (mb_x > 0)
505  j |= fixed[mb_xy - 1];
506  if (mb_x + 1 < mb_width)
507  j |= fixed[mb_xy + 1];
508  if (mb_y > 0)
509  j |= fixed[mb_xy - mb_stride];
510  if (mb_y + 1 < mb_height)
511  j |= fixed[mb_xy + mb_stride];
512 
513  av_assert2(j & MV_FROZEN);
514 
515  if (!(j & MV_CHANGED) && pass > 1)
516  continue;
517 
518  none_left = 0;
519  pred_count = 0;
520  mot_index = (mb_x + mb_y * mot_stride) * mot_step;
521 
522  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
523  mv_predictor[pred_count][0] =
524  s->cur_pic.motion_val[0][mot_index - mot_step][0];
525  mv_predictor[pred_count][1] =
526  s->cur_pic.motion_val[0][mot_index - mot_step][1];
527  ref[pred_count] =
528  s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
529  pred_count++;
530  }
531  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
532  mv_predictor[pred_count][0] =
533  s->cur_pic.motion_val[0][mot_index + mot_step][0];
534  mv_predictor[pred_count][1] =
535  s->cur_pic.motion_val[0][mot_index + mot_step][1];
536  ref[pred_count] =
537  s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
538  pred_count++;
539  }
540  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
541  mv_predictor[pred_count][0] =
542  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
543  mv_predictor[pred_count][1] =
544  s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
545  ref[pred_count] =
546  s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
547  pred_count++;
548  }
549  if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride] > 1) {
550  mv_predictor[pred_count][0] =
551  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
552  mv_predictor[pred_count][1] =
553  s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
554  ref[pred_count] =
555  s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
556  pred_count++;
557  }
558  if (pred_count == 0)
559  continue;
560 
561  if (pred_count > 1) {
562  int sum_x = 0, sum_y = 0, sum_r = 0;
563  int max_x, max_y, min_x, min_y, max_r, min_r;
564 
565  for (j = 0; j < pred_count; j++) {
566  sum_x += mv_predictor[j][0];
567  sum_y += mv_predictor[j][1];
568  sum_r += ref[j];
569  if (j && ref[j] != ref[j - 1])
570  goto skip_mean_and_median;
571  }
572 
573  /* mean */
574  mv_predictor[pred_count][0] = sum_x / j;
575  mv_predictor[pred_count][1] = sum_y / j;
576  ref[pred_count] = sum_r / j;
577 
578  /* median */
579  if (pred_count >= 3) {
580  min_y = min_x = min_r = 99999;
581  max_y = max_x = max_r = -99999;
582  } else {
583  min_x = min_y = max_x = max_y = min_r = max_r = 0;
584  }
585  for (j = 0; j < pred_count; j++) {
586  max_x = FFMAX(max_x, mv_predictor[j][0]);
587  max_y = FFMAX(max_y, mv_predictor[j][1]);
588  max_r = FFMAX(max_r, ref[j]);
589  min_x = FFMIN(min_x, mv_predictor[j][0]);
590  min_y = FFMIN(min_y, mv_predictor[j][1]);
591  min_r = FFMIN(min_r, ref[j]);
592  }
593  mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
594  mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
595  ref[pred_count + 1] = sum_r - max_r - min_r;
596 
597  if (pred_count == 4) {
598  mv_predictor[pred_count + 1][0] /= 2;
599  mv_predictor[pred_count + 1][1] /= 2;
600  ref[pred_count + 1] /= 2;
601  }
602  pred_count += 2;
603  }
604 
605 skip_mean_and_median:
606  /* zero MV */
607  mv_predictor[pred_count][0] =
608  mv_predictor[pred_count][1] =
609  ref[pred_count] = 0;
610  pred_count++;
611 
612  prev_x = s->cur_pic.motion_val[0][mot_index][0];
613  prev_y = s->cur_pic.motion_val[0][mot_index][1];
614  prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
615 
616  /* last MV */
617  mv_predictor[pred_count][0] = prev_x;
618  mv_predictor[pred_count][1] = prev_y;
619  ref[pred_count] = prev_ref;
620  pred_count++;
621 
622  best_pred = 0;
623  best_score = 256 * 256 * 256 * 64;
624  for (j = 0; j < pred_count; j++) {
625  int *linesize = s->cur_pic.f->linesize;
626  int score = 0;
627  uint8_t *src = s->cur_pic.f->data[0] +
628  mb_x * 16 + mb_y * 16 * linesize[0];
629 
630  s->cur_pic.motion_val[0][mot_index][0] =
631  s->mv[0][0][0] = mv_predictor[j][0];
632  s->cur_pic.motion_val[0][mot_index][1] =
633  s->mv[0][0][1] = mv_predictor[j][1];
634 
635  // predictor intra or otherwise not available
636  if (ref[j] < 0)
637  continue;
638 
639  s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
640  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
641 
642  if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
643  int k;
644  for (k = 0; k < 16; k++)
645  score += FFABS(src[k * linesize[0] - 1] -
646  src[k * linesize[0]]);
647  }
648  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
649  int k;
650  for (k = 0; k < 16; k++)
651  score += FFABS(src[k * linesize[0] + 15] -
652  src[k * linesize[0] + 16]);
653  }
654  if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
655  int k;
656  for (k = 0; k < 16; k++)
657  score += FFABS(src[k - linesize[0]] - src[k]);
658  }
659  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) {
660  int k;
661  for (k = 0; k < 16; k++)
662  score += FFABS(src[k + linesize[0] * 15] -
663  src[k + linesize[0] * 16]);
664  }
665 
666  if (score <= best_score) { // <= will favor the last MV
667  best_score = score;
668  best_pred = j;
669  }
670  }
671  score_sum += best_score;
672  s->mv[0][0][0] = mv_predictor[best_pred][0];
673  s->mv[0][0][1] = mv_predictor[best_pred][1];
674 
675  for (i = 0; i < mot_step; i++)
676  for (j = 0; j < mot_step; j++) {
677  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
678  s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
679  }
680 
681  s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
682  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
683 
684 
685  if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
686  fixed[mb_xy] = MV_CHANGED;
687  changed++;
688  } else
689  fixed[mb_xy] = MV_UNCHANGED;
690  }
691  }
692 
693  if (none_left)
694  return;
695 
696  next_blocklist_length = 0;
697 
698  for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
699  const int mb_x = blocklist[blocklist_index][0];
700  const int mb_y = blocklist[blocklist_index][1];
701  const int mb_xy = mb_x + mb_y * mb_stride;
702 
703  if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) {
704  fixed[mb_xy] = MV_FROZEN;
705  if (mb_x > 0)
706  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
707  if (mb_y > 0)
708  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
709  if (mb_x + 1 < mb_width)
710  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
711  if (mb_y + 1 < mb_height)
712  add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
713  }
714  }
715  av_assert0(next_blocklist_length <= mb_height * mb_width);
716  FFSWAP(int , blocklist_length, next_blocklist_length);
717  FFSWAP(void*, blocklist, next_blocklist);
718  }
719 }
720 
722 {
723  int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
724 
725  if (!s->last_pic.f || !s->last_pic.f->data[0])
726  return 1; // no previous frame available -> use spatial prediction
727 
728  if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
729  return 0;
730 
731  undamaged_count = 0;
732  for (i = 0; i < s->mb_num; i++) {
733  const int mb_xy = s->mb_index2xy[i];
734  const int error = s->error_status_table[mb_xy];
735  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
736  undamaged_count++;
737  }
738 
739  if (undamaged_count < 5)
740  return 0; // almost all MBs damaged -> use temporal prediction
741 
742  // prevent dsp.sad() check, that requires access to the image
743  if (CONFIG_XVMC &&
744  s->avctx->hwaccel && s->avctx->hwaccel->decode_mb &&
745  s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I)
746  return 1;
747 
748  skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
749  is_intra_likely = 0;
750 
751  j = 0;
752  for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
753  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
754  int error;
755  const int mb_xy = mb_x + mb_y * s->mb_stride;
756 
757  error = s->error_status_table[mb_xy];
758  if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
759  continue; // skip damaged
760 
761  j++;
762  // skip a few to speed things up
763  if ((j % skip_amount) != 0)
764  continue;
765 
766  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
767  int *linesize = s->cur_pic.f->linesize;
768  uint8_t *mb_ptr = s->cur_pic.f->data[0] +
769  mb_x * 16 + mb_y * 16 * linesize[0];
770  uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
771  mb_x * 16 + mb_y * 16 * linesize[0];
772 
773  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
774  // FIXME
775  } else {
776  ff_thread_await_progress(s->last_pic.tf, mb_y, 0);
777  }
778  is_intra_likely += s->mecc.sad[0](NULL, last_mb_ptr, mb_ptr,
779  linesize[0], 16);
780  // FIXME need await_progress() here
781  is_intra_likely -= s->mecc.sad[0](NULL, last_mb_ptr,
782  last_mb_ptr + linesize[0] * 16,
783  linesize[0], 16);
784  } else {
785  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
786  is_intra_likely++;
787  else
788  is_intra_likely--;
789  }
790  }
791  }
792 // av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
793  return is_intra_likely > 0;
794 }
795 
797 {
798  if (!s->avctx->error_concealment)
799  return;
800 
801  if (!s->mecc_inited) {
802  ff_me_cmp_init(&s->mecc, s->avctx);
803  s->mecc_inited = 1;
804  }
805 
806  memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
807  s->mb_stride * s->mb_height * sizeof(uint8_t));
808  atomic_init(&s->error_count, 3 * s->mb_num);
809  s->error_occurred = 0;
810 }
811 
813 {
814  if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice ||
815  !s->cur_pic.f ||
816  s->cur_pic.field_picture
817  )
818  return 0;
819  return 1;
820 }
821 
822 /**
823  * Add a slice.
824  * @param endx x component of the last macroblock, can be -1
825  * for the last of the previous line
826  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
827  * assumed that no earlier end or error of the same type occurred
828  */
829 void ff_er_add_slice(ERContext *s, int startx, int starty,
830  int endx, int endy, int status)
831 {
832  const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
833  const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num);
834  const int start_xy = s->mb_index2xy[start_i];
835  const int end_xy = s->mb_index2xy[end_i];
836  int mask = -1;
837 
838  if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice)
839  return;
840 
841  if (start_i > end_i || start_xy > end_xy) {
842  av_log(s->avctx, AV_LOG_ERROR,
843  "internal error, slice end before start\n");
844  return;
845  }
846 
847  if (!s->avctx->error_concealment)
848  return;
849 
850  mask &= ~VP_START;
851  if (status & (ER_AC_ERROR | ER_AC_END)) {
852  mask &= ~(ER_AC_ERROR | ER_AC_END);
853  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
854  }
855  if (status & (ER_DC_ERROR | ER_DC_END)) {
856  mask &= ~(ER_DC_ERROR | ER_DC_END);
857  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
858  }
859  if (status & (ER_MV_ERROR | ER_MV_END)) {
860  mask &= ~(ER_MV_ERROR | ER_MV_END);
861  atomic_fetch_add(&s->error_count, start_i - end_i - 1);
862  }
863 
864  if (status & ER_MB_ERROR) {
865  s->error_occurred = 1;
866  atomic_store(&s->error_count, INT_MAX);
867  }
868 
869  if (mask == ~0x7F) {
870  memset(&s->error_status_table[start_xy], 0,
871  (end_xy - start_xy) * sizeof(uint8_t));
872  } else {
873  int i;
874  for (i = start_xy; i < end_xy; i++)
875  s->error_status_table[i] &= mask;
876  }
877 
878  if (end_i == s->mb_num)
879  atomic_store(&s->error_count, INT_MAX);
880  else {
881  s->error_status_table[end_xy] &= mask;
882  s->error_status_table[end_xy] |= status;
883  }
884 
885  s->error_status_table[start_xy] |= VP_START;
886 
887  if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
888  er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
889  int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
890 
891  prev_status &= ~ VP_START;
892  if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
893  s->error_occurred = 1;
894  atomic_store(&s->error_count, INT_MAX);
895  }
896  }
897 }
898 
900 {
901  int *linesize = NULL;
902  int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
903  int distance;
904  int threshold_part[4] = { 100, 100, 100 };
905  int threshold = 50;
906  int is_intra_likely;
907  int size = s->b8_stride * 2 * s->mb_height;
908 
909  /* We do not support ER of field pictures yet,
910  * though it should not crash if enabled. */
911  if (!s->avctx->error_concealment || !atomic_load(&s->error_count) ||
912  s->avctx->lowres ||
913  !er_supported(s) ||
914  atomic_load(&s->error_count) == 3 * s->mb_width *
915  (s->avctx->skip_top + s->avctx->skip_bottom)) {
916  return;
917  }
918  linesize = s->cur_pic.f->linesize;
919 
920  if ( s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
921  && (FFALIGN(s->avctx->height, 16)&16)
922  && atomic_load(&s->error_count) == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)) {
923  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
924  int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
925  if (status != 0x7F)
926  break;
927  }
928 
929  if (mb_x == s->mb_width) {
930  av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
931  return;
932  }
933  }
934 
935  if (s->last_pic.f) {
936  if (s->last_pic.f->width != s->cur_pic.f->width ||
937  s->last_pic.f->height != s->cur_pic.f->height ||
938  s->last_pic.f->format != s->cur_pic.f->format) {
939  av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
940  memset(&s->last_pic, 0, sizeof(s->last_pic));
941  }
942  }
943  if (s->next_pic.f) {
944  if (s->next_pic.f->width != s->cur_pic.f->width ||
945  s->next_pic.f->height != s->cur_pic.f->height ||
946  s->next_pic.f->format != s->cur_pic.f->format) {
947  av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
948  memset(&s->next_pic, 0, sizeof(s->next_pic));
949  }
950  }
951 
952  if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
953  av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
954 
955  for (i = 0; i < 2; i++) {
956  s->ref_index_buf[i] = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
957  s->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
958  if (!s->ref_index_buf[i] || !s->motion_val_buf[i])
959  break;
960  s->cur_pic.ref_index[i] = s->ref_index_buf[i]->data;
961  s->cur_pic.motion_val[i] = (int16_t (*)[2])s->motion_val_buf[i]->data + 4;
962  }
963  if (i < 2) {
964  for (i = 0; i < 2; i++) {
965  av_buffer_unref(&s->ref_index_buf[i]);
966  av_buffer_unref(&s->motion_val_buf[i]);
967  s->cur_pic.ref_index[i] = NULL;
968  s->cur_pic.motion_val[i] = NULL;
969  }
970  return;
971  }
972  }
973 
974  if (s->avctx->debug & FF_DEBUG_ER) {
975  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
976  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
977  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
978 
979  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
980  }
981  av_log(s->avctx, AV_LOG_DEBUG, "\n");
982  }
983  }
984 
985 #if 1
986  /* handle overlapping slices */
987  for (error_type = 1; error_type <= 3; error_type++) {
988  int end_ok = 0;
989 
990  for (i = s->mb_num - 1; i >= 0; i--) {
991  const int mb_xy = s->mb_index2xy[i];
992  int error = s->error_status_table[mb_xy];
993 
994  if (error & (1 << error_type))
995  end_ok = 1;
996  if (error & (8 << error_type))
997  end_ok = 1;
998 
999  if (!end_ok)
1000  s->error_status_table[mb_xy] |= 1 << error_type;
1001 
1002  if (error & VP_START)
1003  end_ok = 0;
1004  }
1005  }
1006 #endif
1007 #if 1
1008  /* handle slices with partitions of different length */
1009  if (s->partitioned_frame) {
1010  int end_ok = 0;
1011 
1012  for (i = s->mb_num - 1; i >= 0; i--) {
1013  const int mb_xy = s->mb_index2xy[i];
1014  int error = s->error_status_table[mb_xy];
1015 
1016  if (error & ER_AC_END)
1017  end_ok = 0;
1018  if ((error & ER_MV_END) ||
1019  (error & ER_DC_END) ||
1020  (error & ER_AC_ERROR))
1021  end_ok = 1;
1022 
1023  if (!end_ok)
1024  s->error_status_table[mb_xy]|= ER_AC_ERROR;
1025 
1026  if (error & VP_START)
1027  end_ok = 0;
1028  }
1029  }
1030 #endif
1031  /* handle missing slices */
1032  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
1033  int end_ok = 1;
1034 
1035  // FIXME + 100 hack
1036  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
1037  const int mb_xy = s->mb_index2xy[i];
1038  int error1 = s->error_status_table[mb_xy];
1039  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
1040 
1041  if (error1 & VP_START)
1042  end_ok = 1;
1043 
1044  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1045  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1046  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1047  (error1 & ER_MV_END))) {
1048  // end & uninit
1049  end_ok = 0;
1050  }
1051 
1052  if (!end_ok)
1053  s->error_status_table[mb_xy] |= ER_MB_ERROR;
1054  }
1055  }
1056 
1057 #if 1
1058  /* backward mark errors */
1059  distance = 9999999;
1060  for (error_type = 1; error_type <= 3; error_type++) {
1061  for (i = s->mb_num - 1; i >= 0; i--) {
1062  const int mb_xy = s->mb_index2xy[i];
1063  int error = s->error_status_table[mb_xy];
1064 
1065  if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1066  distance++;
1067  if (error & (1 << error_type))
1068  distance = 0;
1069 
1070  if (s->partitioned_frame) {
1071  if (distance < threshold_part[error_type - 1])
1072  s->error_status_table[mb_xy] |= 1 << error_type;
1073  } else {
1074  if (distance < threshold)
1075  s->error_status_table[mb_xy] |= 1 << error_type;
1076  }
1077 
1078  if (error & VP_START)
1079  distance = 9999999;
1080  }
1081  }
1082 #endif
1083 
1084  /* forward mark errors */
1085  error = 0;
1086  for (i = 0; i < s->mb_num; i++) {
1087  const int mb_xy = s->mb_index2xy[i];
1088  int old_error = s->error_status_table[mb_xy];
1089 
1090  if (old_error & VP_START) {
1091  error = old_error & ER_MB_ERROR;
1092  } else {
1093  error |= old_error & ER_MB_ERROR;
1094  s->error_status_table[mb_xy] |= error;
1095  }
1096  }
1097 #if 1
1098  /* handle not partitioned case */
1099  if (!s->partitioned_frame) {
1100  for (i = 0; i < s->mb_num; i++) {
1101  const int mb_xy = s->mb_index2xy[i];
1102  int error = s->error_status_table[mb_xy];
1103  if (error & ER_MB_ERROR)
1104  error |= ER_MB_ERROR;
1105  s->error_status_table[mb_xy] = error;
1106  }
1107  }
1108 #endif
1109 
1110  dc_error = ac_error = mv_error = 0;
1111  for (i = 0; i < s->mb_num; i++) {
1112  const int mb_xy = s->mb_index2xy[i];
1113  int error = s->error_status_table[mb_xy];
1114  if (error & ER_DC_ERROR)
1115  dc_error++;
1116  if (error & ER_AC_ERROR)
1117  ac_error++;
1118  if (error & ER_MV_ERROR)
1119  mv_error++;
1120  }
1121  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1122  dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1123 
1124  s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1125 
1126  is_intra_likely = is_intra_more_likely(s);
1127 
1128  /* set unknown mb-type to most likely */
1129  for (i = 0; i < s->mb_num; i++) {
1130  const int mb_xy = s->mb_index2xy[i];
1131  int error = s->error_status_table[mb_xy];
1132  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1133  continue;
1134 
1135  if (is_intra_likely)
1136  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1137  else
1138  s->cur_pic.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
1139  }
1140 
1141  // change inter to intra blocks if no reference frames are available
1142  if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1143  !(s->next_pic.f && s->next_pic.f->data[0]))
1144  for (i = 0; i < s->mb_num; i++) {
1145  const int mb_xy = s->mb_index2xy[i];
1146  if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1147  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1148  }
1149 
1150  /* handle inter blocks with damaged AC */
1151  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1152  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1153  const int mb_xy = mb_x + mb_y * s->mb_stride;
1154  const int mb_type = s->cur_pic.mb_type[mb_xy];
1155  const int dir = !(s->last_pic.f && s->last_pic.f->data[0]);
1156  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1157  int mv_type;
1158 
1159  int error = s->error_status_table[mb_xy];
1160 
1161  if (IS_INTRA(mb_type))
1162  continue; // intra
1163  if (error & ER_MV_ERROR)
1164  continue; // inter with damaged MV
1165  if (!(error & ER_AC_ERROR))
1166  continue; // undamaged inter
1167 
1168  if (IS_8X8(mb_type)) {
1169  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1170  int j;
1171  mv_type = MV_TYPE_8X8;
1172  for (j = 0; j < 4; j++) {
1173  s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1174  s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1175  }
1176  } else {
1177  mv_type = MV_TYPE_16X16;
1178  s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1179  s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1180  }
1181 
1182  s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1183  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1184  }
1185  }
1186 
1187  /* guess MVs */
1188  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1189  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1190  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1191  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1192  const int mb_xy = mb_x + mb_y * s->mb_stride;
1193  const int mb_type = s->cur_pic.mb_type[mb_xy];
1194  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1195 
1196  int error = s->error_status_table[mb_xy];
1197 
1198  if (IS_INTRA(mb_type))
1199  continue;
1200  if (!(error & ER_MV_ERROR))
1201  continue; // inter with undamaged MV
1202  if (!(error & ER_AC_ERROR))
1203  continue; // undamaged inter
1204 
1205  if (!(s->last_pic.f && s->last_pic.f->data[0]))
1206  mv_dir &= ~MV_DIR_FORWARD;
1207  if (!(s->next_pic.f && s->next_pic.f->data[0]))
1208  mv_dir &= ~MV_DIR_BACKWARD;
1209 
1210  if (s->pp_time) {
1211  int time_pp = s->pp_time;
1212  int time_pb = s->pb_time;
1213 
1214  av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1215  ff_thread_await_progress(s->next_pic.tf, mb_y, 0);
1216 
1217  s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp;
1218  s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp;
1219  s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1220  s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1221  } else {
1222  s->mv[0][0][0] = 0;
1223  s->mv[0][0][1] = 0;
1224  s->mv[1][0][0] = 0;
1225  s->mv[1][0][1] = 0;
1226  }
1227 
1228  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1229  mb_x, mb_y, 0, 0);
1230  }
1231  }
1232  } else
1233  guess_mv(s);
1234 
1235  /* the filters below manipulate raw image, skip them */
1236  if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb)
1237  goto ec_clean;
1238  /* fill DC for inter blocks */
1239  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1240  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1241  int dc, dcu, dcv, y, n;
1242  int16_t *dc_ptr;
1243  uint8_t *dest_y, *dest_cb, *dest_cr;
1244  const int mb_xy = mb_x + mb_y * s->mb_stride;
1245  const int mb_type = s->cur_pic.mb_type[mb_xy];
1246 
1247  // error = s->error_status_table[mb_xy];
1248 
1249  if (IS_INTRA(mb_type) && s->partitioned_frame)
1250  continue;
1251  // if (error & ER_MV_ERROR)
1252  // continue; // inter data damaged FIXME is this good?
1253 
1254  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1255  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1256  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1257 
1258  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1259  for (n = 0; n < 4; n++) {
1260  dc = 0;
1261  for (y = 0; y < 8; y++) {
1262  int x;
1263  for (x = 0; x < 8; x++)
1264  dc += dest_y[x + (n & 1) * 8 +
1265  (y + (n >> 1) * 8) * linesize[0]];
1266  }
1267  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1268  }
1269 
1270  if (!s->cur_pic.f->data[2])
1271  continue;
1272 
1273  dcu = dcv = 0;
1274  for (y = 0; y < 8; y++) {
1275  int x;
1276  for (x = 0; x < 8; x++) {
1277  dcu += dest_cb[x + y * linesize[1]];
1278  dcv += dest_cr[x + y * linesize[2]];
1279  }
1280  }
1281  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1282  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1283  }
1284  }
1285 #if 1
1286  /* guess DC for damaged blocks */
1287  guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1288  guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1289  guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1290 #endif
1291 
1292  /* filter luma DC */
1293  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1294 
1295 #if 1
1296  /* render DC only intra */
1297  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1298  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1299  uint8_t *dest_y, *dest_cb, *dest_cr;
1300  const int mb_xy = mb_x + mb_y * s->mb_stride;
1301  const int mb_type = s->cur_pic.mb_type[mb_xy];
1302 
1303  int error = s->error_status_table[mb_xy];
1304 
1305  if (IS_INTER(mb_type))
1306  continue;
1307  if (!(error & ER_AC_ERROR))
1308  continue; // undamaged
1309 
1310  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1311  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1312  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1313  if (!s->cur_pic.f->data[2])
1314  dest_cb = dest_cr = NULL;
1315 
1316  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1317  }
1318  }
1319 #endif
1320 
1321  if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1322  /* filter horizontal block boundaries */
1323  h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1324  s->mb_height * 2, linesize[0], 1);
1325 
1326  /* filter vertical block boundaries */
1327  v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1328  s->mb_height * 2, linesize[0], 1);
1329 
1330  if (s->cur_pic.f->data[2]) {
1331  h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1332  s->mb_height, linesize[1], 0);
1333  h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1334  s->mb_height, linesize[2], 0);
1335  v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1336  s->mb_height, linesize[1], 0);
1337  v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1338  s->mb_height, linesize[2], 0);
1339  }
1340  }
1341 
1342 ec_clean:
1343  /* clean a few tables */
1344  for (i = 0; i < s->mb_num; i++) {
1345  const int mb_xy = s->mb_index2xy[i];
1346  int error = s->error_status_table[mb_xy];
1347 
1348  if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1350  s->mbskip_table[mb_xy] = 0;
1351  }
1352  if (s->mbintra_table)
1353  s->mbintra_table[mb_xy] = 1;
1354  }
1355 
1356  for (i = 0; i < 2; i++) {
1357  av_buffer_unref(&s->ref_index_buf[i]);
1358  av_buffer_unref(&s->motion_val_buf[i]);
1359  s->cur_pic.ref_index[i] = NULL;
1360  s->cur_pic.motion_val[i] = NULL;
1361  }
1362 
1363  memset(&s->cur_pic, 0, sizeof(ERPicture));
1364  memset(&s->last_pic, 0, sizeof(ERPicture));
1365  memset(&s->next_pic, 0, sizeof(ERPicture));
1366 }
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:584
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:88
MB_TYPE_L0
#define MB_TYPE_L0
Definition: mpegutils.h:66
stride
int stride
Definition: mace.c:144
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:256
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_clip
#define av_clip
Definition: common.h:96
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:599
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:721
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:50
b
#define b
Definition: input.c:40
data
const char data[16]
Definition: mxf.c:143
MV_FROZEN
#define MV_FROZEN
Definition: error_resilience.c:376
MB_TYPE_16x16
#define MB_TYPE_16x16
Definition: mpegutils.h:53
ff_er_frame_start
void ff_er_frame_start(ERContext *s)
Definition: error_resilience.c:796
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:829
FF_EC_GUESS_MVS
#define FF_EC_GUESS_MVS
Definition: avcodec.h:1293
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
thread.h
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:253
ERPicture
Definition: error_resilience.h:41
fail
#define fail()
Definition: checkasm.h:127
FF_DEBUG_ER
#define FF_DEBUG_ER
Definition: avcodec.h:1311
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:1015
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:257
FF_EC_DEBLOCK
#define FF_EC_DEBLOCK
Definition: avcodec.h:1294
er_supported
static int er_supported(ERContext *s)
Definition: error_resilience.c:812
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
pass
#define pass
Definition: fft_template.c:601
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
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:65
if
if(ret)
Definition: filter_design.txt:179
NULL
#define NULL
Definition: coverity.c:32
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
ER_AC_ERROR
#define ER_AC_ERROR
Definition: error_resilience.h:31
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
src
#define src
Definition: vp8dsp.c:255
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
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:1335
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:1561
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:257
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:92
FF_THREAD_SLICE
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
Definition: avcodec.h:1452
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:83
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:271
internal.h
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
avcodec.h
av_buffer_allocz
AVBufferRef * av_buffer_allocz(size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition: buffer.c:93
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:38
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
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:78
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:252
ff_er_frame_end
void ff_er_frame_end(ERContext *s)
Definition: error_resilience.c:899
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:233
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
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:1295
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:52
filter181
static void filter181(int16_t *data, int width, int height, ptrdiff_t stride)
Definition: error_resilience.c:96