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