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 Libav.
7  *
8  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
28 #include <limits.h>
29 
30 #include "avcodec.h"
31 #include "dsputil.h"
32 #include "error_resilience.h"
33 #include "mpegvideo.h"
34 #include "rectangle.h"
35 #include "thread.h"
36 
41 static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
42 {
43  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
44  assert(s->quarter_sample);
45  *mv_step = 4;
46  *stride = s->mb_width * 4;
47  } else {
48  *mv_step = 2;
49  *stride = s->b8_stride;
50  }
51 }
52 
56 static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
57  uint8_t *dest_cr, int mb_x, int mb_y)
58 {
59  int *linesize = s->cur_pic->f.linesize;
60  int dc, dcu, dcv, y, i;
61  for (i = 0; i < 4; i++) {
62  dc = s->dc_val[0][mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
63  if (dc < 0)
64  dc = 0;
65  else if (dc > 2040)
66  dc = 2040;
67  for (y = 0; y < 8; y++) {
68  int x;
69  for (x = 0; x < 8; x++)
70  dest_y[x + (i & 1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
71  }
72  }
73  dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
74  dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
75  if (dcu < 0)
76  dcu = 0;
77  else if (dcu > 2040)
78  dcu = 2040;
79  if (dcv < 0)
80  dcv = 0;
81  else if (dcv > 2040)
82  dcv = 2040;
83  for (y = 0; y < 8; y++) {
84  int x;
85  for (x = 0; x < 8; x++) {
86  dest_cb[x + y * linesize[1]] = dcu / 8;
87  dest_cr[x + y * linesize[2]] = dcv / 8;
88  }
89  }
90 }
91 
92 static void filter181(int16_t *data, int width, int height, int stride)
93 {
94  int x, y;
95 
96  /* horizontal filter */
97  for (y = 1; y < height - 1; y++) {
98  int prev_dc = data[0 + y * stride];
99 
100  for (x = 1; x < width - 1; x++) {
101  int dc;
102  dc = -prev_dc +
103  data[x + y * stride] * 8 -
104  data[x + 1 + y * stride];
105  dc = (dc * 10923 + 32768) >> 16;
106  prev_dc = data[x + y * stride];
107  data[x + y * stride] = dc;
108  }
109  }
110 
111  /* vertical filter */
112  for (x = 1; x < width - 1; x++) {
113  int prev_dc = data[x];
114 
115  for (y = 1; y < height - 1; y++) {
116  int dc;
117 
118  dc = -prev_dc +
119  data[x + y * stride] * 8 -
120  data[x + (y + 1) * stride];
121  dc = (dc * 10923 + 32768) >> 16;
122  prev_dc = data[x + y * stride];
123  data[x + y * stride] = dc;
124  }
125  }
126 }
127 
133 static void guess_dc(ERContext *s, int16_t *dc, int w,
134  int h, int stride, int is_luma)
135 {
136  int b_x, b_y;
137 
138  for (b_y = 0; b_y < h; b_y++) {
139  for (b_x = 0; b_x < w; b_x++) {
140  int color[4] = { 1024, 1024, 1024, 1024 };
141  int distance[4] = { 9999, 9999, 9999, 9999 };
142  int mb_index, error, j;
143  int64_t guess, weight_sum;
144  mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
145  error = s->error_status_table[mb_index];
146 
147  if (IS_INTER(s->cur_pic->f.mb_type[mb_index]))
148  continue; // inter
149  if (!(error & ER_DC_ERROR))
150  continue; // dc-ok
151 
152  /* right block */
153  for (j = b_x + 1; j < w; j++) {
154  int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride;
155  int error_j = s->error_status_table[mb_index_j];
156  int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
157  if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
158  color[0] = dc[j + b_y * stride];
159  distance[0] = j - b_x;
160  break;
161  }
162  }
163 
164  /* left block */
165  for (j = b_x - 1; j >= 0; j--) {
166  int mb_index_j = (j >> 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->f.mb_type[mb_index_j]);
169  if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
170  color[1] = dc[j + b_y * stride];
171  distance[1] = b_x - j;
172  break;
173  }
174  }
175 
176  /* bottom block */
177  for (j = b_y + 1; j < h; j++) {
178  int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride;
179  int error_j = s->error_status_table[mb_index_j];
180  int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
181 
182  if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
183  color[2] = dc[b_x + j * stride];
184  distance[2] = j - b_y;
185  break;
186  }
187  }
188 
189  /* top block */
190  for (j = b_y - 1; j >= 0; j--) {
191  int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride;
192  int error_j = s->error_status_table[mb_index_j];
193  int intra_j = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
194  if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
195  color[3] = dc[b_x + j * stride];
196  distance[3] = b_y - j;
197  break;
198  }
199  }
200 
201  weight_sum = 0;
202  guess = 0;
203  for (j = 0; j < 4; j++) {
204  int64_t weight = 256 * 256 * 256 * 16 / distance[j];
205  guess += weight * (int64_t) color[j];
206  weight_sum += weight;
207  }
208  guess = (guess + weight_sum / 2) / weight_sum;
209  dc[b_x + b_y * stride] = guess;
210  }
211  }
212 }
213 
219 static void h_block_filter(ERContext *s, uint8_t *dst, int w,
220  int h, int stride, int is_luma)
221 {
222  int b_x, b_y, mvx_stride, mvy_stride;
224  set_mv_strides(s, &mvx_stride, &mvy_stride);
225  mvx_stride >>= is_luma;
226  mvy_stride *= mvx_stride;
227 
228  for (b_y = 0; b_y < h; b_y++) {
229  for (b_x = 0; b_x < w - 1; b_x++) {
230  int y;
231  int left_status = s->error_status_table[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
232  int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
233  int left_intra = IS_INTRA(s->cur_pic->f.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
234  int right_intra = IS_INTRA(s->cur_pic->f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
235  int left_damage = left_status & ER_MB_ERROR;
236  int right_damage = right_status & ER_MB_ERROR;
237  int offset = b_x * 8 + b_y * stride * 8;
238  int16_t *left_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
239  int16_t *right_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
240  if (!(left_damage || right_damage))
241  continue; // both undamaged
242  if ((!left_intra) && (!right_intra) &&
243  FFABS(left_mv[0] - right_mv[0]) +
244  FFABS(left_mv[1] + right_mv[1]) < 2)
245  continue;
246 
247  for (y = 0; y < 8; y++) {
248  int a, b, c, d;
249 
250  a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
251  b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
252  c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];
253 
254  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
255  d = FFMAX(d, 0);
256  if (b < 0)
257  d = -d;
258 
259  if (d == 0)
260  continue;
261 
262  if (!(left_damage && right_damage))
263  d = d * 16 / 9;
264 
265  if (left_damage) {
266  dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
267  dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
268  dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
269  dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
270  }
271  if (right_damage) {
272  dst[offset + 8 + y * stride] = cm[dst[offset + 8 + y * stride] - ((d * 7) >> 4)];
273  dst[offset + 9 + y * stride] = cm[dst[offset + 9 + y * stride] - ((d * 5) >> 4)];
274  dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
275  dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)];
276  }
277  }
278  }
279  }
280 }
281 
287 static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
288  int stride, int is_luma)
289 {
290  int b_x, b_y, mvx_stride, mvy_stride;
292  set_mv_strides(s, &mvx_stride, &mvy_stride);
293  mvx_stride >>= is_luma;
294  mvy_stride *= mvx_stride;
295 
296  for (b_y = 0; b_y < h - 1; b_y++) {
297  for (b_x = 0; b_x < w; b_x++) {
298  int x;
299  int top_status = s->error_status_table[(b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride];
300  int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
301  int top_intra = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]);
302  int bottom_intra = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
303  int top_damage = top_status & ER_MB_ERROR;
304  int bottom_damage = bottom_status & ER_MB_ERROR;
305  int offset = b_x * 8 + b_y * stride * 8;
306 
307  int16_t *top_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
308  int16_t *bottom_mv = s->cur_pic->f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
309 
310  if (!(top_damage || bottom_damage))
311  continue; // both undamaged
312 
313  if ((!top_intra) && (!bottom_intra) &&
314  FFABS(top_mv[0] - bottom_mv[0]) +
315  FFABS(top_mv[1] + bottom_mv[1]) < 2)
316  continue;
317 
318  for (x = 0; x < 8; x++) {
319  int a, b, c, d;
320 
321  a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
322  b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
323  c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
324 
325  d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
326  d = FFMAX(d, 0);
327  if (b < 0)
328  d = -d;
329 
330  if (d == 0)
331  continue;
332 
333  if (!(top_damage && bottom_damage))
334  d = d * 16 / 9;
335 
336  if (top_damage) {
337  dst[offset + x + 7 * stride] = cm[dst[offset + x + 7 * stride] + ((d * 7) >> 4)];
338  dst[offset + x + 6 * stride] = cm[dst[offset + x + 6 * stride] + ((d * 5) >> 4)];
339  dst[offset + x + 5 * stride] = cm[dst[offset + x + 5 * stride] + ((d * 3) >> 4)];
340  dst[offset + x + 4 * stride] = cm[dst[offset + x + 4 * stride] + ((d * 1) >> 4)];
341  }
342  if (bottom_damage) {
343  dst[offset + x + 8 * stride] = cm[dst[offset + x + 8 * stride] - ((d * 7) >> 4)];
344  dst[offset + x + 9 * stride] = cm[dst[offset + x + 9 * stride] - ((d * 5) >> 4)];
345  dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
346  dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
347  }
348  }
349  }
350  }
351 }
352 
353 static void guess_mv(ERContext *s)
354 {
355  uint8_t *fixed = s->er_temp_buffer;
356 #define MV_FROZEN 3
357 #define MV_CHANGED 2
358 #define MV_UNCHANGED 1
359  const int mb_stride = s->mb_stride;
360  const int mb_width = s->mb_width;
361  const int mb_height = s->mb_height;
362  int i, depth, num_avail;
363  int mb_x, mb_y, mot_step, mot_stride;
364 
365  set_mv_strides(s, &mot_step, &mot_stride);
366 
367  num_avail = 0;
368  for (i = 0; i < s->mb_num; i++) {
369  const int mb_xy = s->mb_index2xy[i];
370  int f = 0;
371  int error = s->error_status_table[mb_xy];
372 
373  if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
374  f = MV_FROZEN; // intra // FIXME check
375  if (!(error & ER_MV_ERROR))
376  f = MV_FROZEN; // inter with undamaged MV
377 
378  fixed[mb_xy] = f;
379  if (f == MV_FROZEN)
380  num_avail++;
381  }
382 
383  if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
384  num_avail <= mb_width / 2) {
385  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
386  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
387  const int mb_xy = mb_x + mb_y * s->mb_stride;
388  int mv_dir = (s->last_pic && s->last_pic->f.data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
389 
390  if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
391  continue;
392  if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
393  continue;
394 
395  s->mv[0][0][0] = 0;
396  s->mv[0][0][1] = 0;
397  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
398  mb_x, mb_y, 0, 0);
399  }
400  }
401  return;
402  }
403 
404  for (depth = 0; ; depth++) {
405  int changed, pass, none_left;
406 
407  none_left = 1;
408  changed = 1;
409  for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
410  int mb_x, mb_y;
411  int score_sum = 0;
412 
413  changed = 0;
414  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
415  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
416  const int mb_xy = mb_x + mb_y * s->mb_stride;
417  int mv_predictor[8][2] = { { 0 } };
418  int ref[8] = { 0 };
419  int pred_count = 0;
420  int j;
421  int best_score = 256 * 256 * 256 * 64;
422  int best_pred = 0;
423  const int mot_index = (mb_x + mb_y * mot_stride) * mot_step;
424  int prev_x, prev_y, prev_ref;
425 
426  if ((mb_x ^ mb_y ^ pass) & 1)
427  continue;
428 
429  if (fixed[mb_xy] == MV_FROZEN)
430  continue;
431  assert(!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]));
432  assert(s->last_pic && s->last_pic->f.data[0]);
433 
434  j = 0;
435  if (mb_x > 0 && fixed[mb_xy - 1] == MV_FROZEN)
436  j = 1;
437  if (mb_x + 1 < mb_width && fixed[mb_xy + 1] == MV_FROZEN)
438  j = 1;
439  if (mb_y > 0 && fixed[mb_xy - mb_stride] == MV_FROZEN)
440  j = 1;
441  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_FROZEN)
442  j = 1;
443  if (j == 0)
444  continue;
445 
446  j = 0;
447  if (mb_x > 0 && fixed[mb_xy - 1 ] == MV_CHANGED)
448  j = 1;
449  if (mb_x + 1 < mb_width && fixed[mb_xy + 1 ] == MV_CHANGED)
450  j = 1;
451  if (mb_y > 0 && fixed[mb_xy - mb_stride] == MV_CHANGED)
452  j = 1;
453  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_CHANGED)
454  j = 1;
455  if (j == 0 && pass > 1)
456  continue;
457 
458  none_left = 0;
459 
460  if (mb_x > 0 && fixed[mb_xy - 1]) {
461  mv_predictor[pred_count][0] =
462  s->cur_pic->f.motion_val[0][mot_index - mot_step][0];
463  mv_predictor[pred_count][1] =
464  s->cur_pic->f.motion_val[0][mot_index - mot_step][1];
465  ref[pred_count] =
466  s->cur_pic->f.ref_index[0][4 * (mb_xy - 1)];
467  pred_count++;
468  }
469  if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
470  mv_predictor[pred_count][0] =
471  s->cur_pic->f.motion_val[0][mot_index + mot_step][0];
472  mv_predictor[pred_count][1] =
473  s->cur_pic->f.motion_val[0][mot_index + mot_step][1];
474  ref[pred_count] =
475  s->cur_pic->f.ref_index[0][4 * (mb_xy + 1)];
476  pred_count++;
477  }
478  if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
479  mv_predictor[pred_count][0] =
480  s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][0];
481  mv_predictor[pred_count][1] =
482  s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][1];
483  ref[pred_count] =
484  s->cur_pic->f.ref_index[0][4 * (mb_xy - s->mb_stride)];
485  pred_count++;
486  }
487  if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
488  mv_predictor[pred_count][0] =
489  s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][0];
490  mv_predictor[pred_count][1] =
491  s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][1];
492  ref[pred_count] =
493  s->cur_pic->f.ref_index[0][4 * (mb_xy + s->mb_stride)];
494  pred_count++;
495  }
496  if (pred_count == 0)
497  continue;
498 
499  if (pred_count > 1) {
500  int sum_x = 0, sum_y = 0, sum_r = 0;
501  int max_x, max_y, min_x, min_y, max_r, min_r;
502 
503  for (j = 0; j < pred_count; j++) {
504  sum_x += mv_predictor[j][0];
505  sum_y += mv_predictor[j][1];
506  sum_r += ref[j];
507  if (j && ref[j] != ref[j - 1])
508  goto skip_mean_and_median;
509  }
510 
511  /* mean */
512  mv_predictor[pred_count][0] = sum_x / j;
513  mv_predictor[pred_count][1] = sum_y / j;
514  ref[pred_count] = sum_r / j;
515 
516  /* median */
517  if (pred_count >= 3) {
518  min_y = min_x = min_r = 99999;
519  max_y = max_x = max_r = -99999;
520  } else {
521  min_x = min_y = max_x = max_y = min_r = max_r = 0;
522  }
523  for (j = 0; j < pred_count; j++) {
524  max_x = FFMAX(max_x, mv_predictor[j][0]);
525  max_y = FFMAX(max_y, mv_predictor[j][1]);
526  max_r = FFMAX(max_r, ref[j]);
527  min_x = FFMIN(min_x, mv_predictor[j][0]);
528  min_y = FFMIN(min_y, mv_predictor[j][1]);
529  min_r = FFMIN(min_r, ref[j]);
530  }
531  mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
532  mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
533  ref[pred_count + 1] = sum_r - max_r - min_r;
534 
535  if (pred_count == 4) {
536  mv_predictor[pred_count + 1][0] /= 2;
537  mv_predictor[pred_count + 1][1] /= 2;
538  ref[pred_count + 1] /= 2;
539  }
540  pred_count += 2;
541  }
542 
543 skip_mean_and_median:
544  /* zero MV */
545  pred_count++;
546 
547  if (!fixed[mb_xy]) {
548  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
549  // FIXME
550  } else {
552  mb_y, 0);
553  }
554  if (!s->last_pic->f.motion_val[0] ||
555  !s->last_pic->f.ref_index[0])
556  goto skip_last_mv;
557  prev_x = s->last_pic->f.motion_val[0][mot_index][0];
558  prev_y = s->last_pic->f.motion_val[0][mot_index][1];
559  prev_ref = s->last_pic->f.ref_index[0][4 * mb_xy];
560  } else {
561  prev_x = s->cur_pic->f.motion_val[0][mot_index][0];
562  prev_y = s->cur_pic->f.motion_val[0][mot_index][1];
563  prev_ref = s->cur_pic->f.ref_index[0][4 * mb_xy];
564  }
565 
566  /* last MV */
567  mv_predictor[pred_count][0] = prev_x;
568  mv_predictor[pred_count][1] = prev_y;
569  ref[pred_count] = prev_ref;
570  pred_count++;
571 
572 skip_last_mv:
573 
574  for (j = 0; j < pred_count; j++) {
575  int *linesize = s->cur_pic->f.linesize;
576  int score = 0;
577  uint8_t *src = s->cur_pic->f.data[0] +
578  mb_x * 16 + mb_y * 16 * linesize[0];
579 
580  s->cur_pic->f.motion_val[0][mot_index][0] =
581  s->mv[0][0][0] = mv_predictor[j][0];
582  s->cur_pic->f.motion_val[0][mot_index][1] =
583  s->mv[0][0][1] = mv_predictor[j][1];
584 
585  // predictor intra or otherwise not available
586  if (ref[j] < 0)
587  continue;
588 
589  s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
590  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
591 
592  if (mb_x > 0 && fixed[mb_xy - 1]) {
593  int k;
594  for (k = 0; k < 16; k++)
595  score += FFABS(src[k * linesize[0] - 1] -
596  src[k * linesize[0]]);
597  }
598  if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
599  int k;
600  for (k = 0; k < 16; k++)
601  score += FFABS(src[k * linesize[0] + 15] -
602  src[k * linesize[0] + 16]);
603  }
604  if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
605  int k;
606  for (k = 0; k < 16; k++)
607  score += FFABS(src[k - linesize[0]] - src[k]);
608  }
609  if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {
610  int k;
611  for (k = 0; k < 16; k++)
612  score += FFABS(src[k + linesize[0] * 15] -
613  src[k + linesize[0] * 16]);
614  }
615 
616  if (score <= best_score) { // <= will favor the last MV
617  best_score = score;
618  best_pred = j;
619  }
620  }
621  score_sum += best_score;
622  s->mv[0][0][0] = mv_predictor[best_pred][0];
623  s->mv[0][0][1] = mv_predictor[best_pred][1];
624 
625  for (i = 0; i < mot_step; i++)
626  for (j = 0; j < mot_step; j++) {
627  s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
628  s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
629  }
630 
631  s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
632  MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
633 
634 
635  if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
636  fixed[mb_xy] = MV_CHANGED;
637  changed++;
638  } else
639  fixed[mb_xy] = MV_UNCHANGED;
640  }
641  }
642  }
643 
644  if (none_left)
645  return;
646 
647  for (i = 0; i < s->mb_num; i++) {
648  int mb_xy = s->mb_index2xy[i];
649  if (fixed[mb_xy])
650  fixed[mb_xy] = MV_FROZEN;
651  }
652  }
653 }
654 
656 {
657  int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
658 
659  if (!s->last_pic || !s->last_pic->f.data[0])
660  return 1; // no previous frame available -> use spatial prediction
661 
662  undamaged_count = 0;
663  for (i = 0; i < s->mb_num; i++) {
664  const int mb_xy = s->mb_index2xy[i];
665  const int error = s->error_status_table[mb_xy];
666  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
667  undamaged_count++;
668  }
669 
670  if (s->avctx->codec_id == AV_CODEC_ID_H264 && s->ref_count <= 0)
671  return 1;
672 
673  if (undamaged_count < 5)
674  return 0; // almost all MBs damaged -> use temporal prediction
675 
676  // prevent dsp.sad() check, that requires access to the image
678  s->avctx->xvmc_acceleration &&
680  return 1;
681 
682  skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
683  is_intra_likely = 0;
684 
685  j = 0;
686  for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
687  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
688  int error;
689  const int mb_xy = mb_x + mb_y * s->mb_stride;
690 
691  error = s->error_status_table[mb_xy];
692  if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
693  continue; // skip damaged
694 
695  j++;
696  // skip a few to speed things up
697  if ((j % skip_amount) != 0)
698  continue;
699 
700  if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) {
701  int *linesize = s->cur_pic->f.linesize;
702  uint8_t *mb_ptr = s->cur_pic->f.data[0] +
703  mb_x * 16 + mb_y * 16 * linesize[0];
704  uint8_t *last_mb_ptr = s->last_pic->f.data[0] +
705  mb_x * 16 + mb_y * 16 * linesize[0];
706 
707  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
708  // FIXME
709  } else {
710  ff_thread_await_progress(&s->last_pic->f, mb_y, 0);
711  }
712  is_intra_likely += s->dsp->sad[0](NULL, last_mb_ptr, mb_ptr,
713  linesize[0], 16);
714  is_intra_likely -= s->dsp->sad[0](NULL, last_mb_ptr,
715  last_mb_ptr + linesize[0] * 16,
716  linesize[0], 16);
717  } else {
718  if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
719  is_intra_likely++;
720  else
721  is_intra_likely--;
722  }
723  }
724  }
725  return is_intra_likely > 0;
726 }
727 
729 {
730  if (!s->avctx->err_recognition)
731  return;
732 
734  s->mb_stride * s->mb_height * sizeof(uint8_t));
735  s->error_count = 3 * s->mb_num;
736  s->error_occurred = 0;
737 }
738 
746 void ff_er_add_slice(ERContext *s, int startx, int starty,
747  int endx, int endy, int status)
748 {
749  const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
750  const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num);
751  const int start_xy = s->mb_index2xy[start_i];
752  const int end_xy = s->mb_index2xy[end_i];
753  int mask = -1;
754 
755  if (s->avctx->hwaccel)
756  return;
757 
758  if (start_i > end_i || start_xy > end_xy) {
760  "internal error, slice end before start\n");
761  return;
762  }
763 
764  if (!s->avctx->err_recognition)
765  return;
766 
767  mask &= ~VP_START;
768  if (status & (ER_AC_ERROR | ER_AC_END)) {
769  mask &= ~(ER_AC_ERROR | ER_AC_END);
770  s->error_count -= end_i - start_i + 1;
771  }
772  if (status & (ER_DC_ERROR | ER_DC_END)) {
773  mask &= ~(ER_DC_ERROR | ER_DC_END);
774  s->error_count -= end_i - start_i + 1;
775  }
776  if (status & (ER_MV_ERROR | ER_MV_END)) {
777  mask &= ~(ER_MV_ERROR | ER_MV_END);
778  s->error_count -= end_i - start_i + 1;
779  }
780 
781  if (status & ER_MB_ERROR) {
782  s->error_occurred = 1;
783  s->error_count = INT_MAX;
784  }
785 
786  if (mask == ~0x7F) {
787  memset(&s->error_status_table[start_xy], 0,
788  (end_xy - start_xy) * sizeof(uint8_t));
789  } else {
790  int i;
791  for (i = start_xy; i < end_xy; i++)
792  s->error_status_table[i] &= mask;
793  }
794 
795  if (end_i == s->mb_num)
796  s->error_count = INT_MAX;
797  else {
798  s->error_status_table[end_xy] &= mask;
799  s->error_status_table[end_xy] |= status;
800  }
801 
802  s->error_status_table[start_xy] |= VP_START;
803 
804  if (start_xy > 0 && s->avctx->thread_count <= 1 &&
805  s->avctx->skip_top * s->mb_width < start_i) {
806  int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
807 
808  prev_status &= ~ VP_START;
809  if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END))
810  s->error_count = INT_MAX;
811  }
812 }
813 
815 {
816  int *linesize = s->cur_pic->f.linesize;
817  int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
818  int distance;
819  int threshold_part[4] = { 100, 100, 100 };
820  int threshold = 50;
821  int is_intra_likely;
822  int size = s->b8_stride * 2 * s->mb_height;
823 
824  /* We do not support ER of field pictures yet,
825  * though it should not crash if enabled. */
826  if (!s->avctx->err_recognition || s->error_count == 0 ||
827  s->avctx->hwaccel ||
829  !s->cur_pic || s->cur_pic->field_picture ||
830  s->error_count == 3 * s->mb_width *
831  (s->avctx->skip_top + s->avctx->skip_bottom)) {
832  return;
833  };
834 
835  if (s->cur_pic->f.motion_val[0] == NULL) {
836  av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
837 
838  for (i = 0; i < 2; i++) {
839  s->cur_pic->f.ref_index[i] = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
840  s->cur_pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
841  s->cur_pic->f.motion_val[i] = s->cur_pic->motion_val_base[i] + 4;
842  }
844  }
845 
846  if (s->avctx->debug & FF_DEBUG_ER) {
847  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
848  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
849  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
850 
851  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
852  }
853  av_log(s->avctx, AV_LOG_DEBUG, "\n");
854  }
855  }
856 
857  /* handle overlapping slices */
858  for (error_type = 1; error_type <= 3; error_type++) {
859  int end_ok = 0;
860 
861  for (i = s->mb_num - 1; i >= 0; i--) {
862  const int mb_xy = s->mb_index2xy[i];
863  int error = s->error_status_table[mb_xy];
864 
865  if (error & (1 << error_type))
866  end_ok = 1;
867  if (error & (8 << error_type))
868  end_ok = 1;
869 
870  if (!end_ok)
871  s->error_status_table[mb_xy] |= 1 << error_type;
872 
873  if (error & VP_START)
874  end_ok = 0;
875  }
876  }
877 
878  /* handle slices with partitions of different length */
879  if (s->partitioned_frame) {
880  int end_ok = 0;
881 
882  for (i = s->mb_num - 1; i >= 0; i--) {
883  const int mb_xy = s->mb_index2xy[i];
884  int error = s->error_status_table[mb_xy];
885 
886  if (error & ER_AC_END)
887  end_ok = 0;
888  if ((error & ER_MV_END) ||
889  (error & ER_DC_END) ||
890  (error & ER_AC_ERROR))
891  end_ok = 1;
892 
893  if (!end_ok)
894  s->error_status_table[mb_xy]|= ER_AC_ERROR;
895 
896  if (error & VP_START)
897  end_ok = 0;
898  }
899  }
900 
901  /* handle missing slices */
902  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
903  int end_ok = 1;
904 
905  // FIXME + 100 hack
906  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
907  const int mb_xy = s->mb_index2xy[i];
908  int error1 = s->error_status_table[mb_xy];
909  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
910 
911  if (error1 & VP_START)
912  end_ok = 1;
913 
914  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
915  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
916  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
917  (error1 & ER_MV_END))) {
918  // end & uninit
919  end_ok = 0;
920  }
921 
922  if (!end_ok)
923  s->error_status_table[mb_xy] |= ER_MB_ERROR;
924  }
925  }
926 
927  /* backward mark errors */
928  distance = 9999999;
929  for (error_type = 1; error_type <= 3; error_type++) {
930  for (i = s->mb_num - 1; i >= 0; i--) {
931  const int mb_xy = s->mb_index2xy[i];
932  int error = s->error_status_table[mb_xy];
933 
934  if (!s->mbskip_table[mb_xy]) // FIXME partition specific
935  distance++;
936  if (error & (1 << error_type))
937  distance = 0;
938 
939  if (s->partitioned_frame) {
940  if (distance < threshold_part[error_type - 1])
941  s->error_status_table[mb_xy] |= 1 << error_type;
942  } else {
943  if (distance < threshold)
944  s->error_status_table[mb_xy] |= 1 << error_type;
945  }
946 
947  if (error & VP_START)
948  distance = 9999999;
949  }
950  }
951 
952  /* forward mark errors */
953  error = 0;
954  for (i = 0; i < s->mb_num; i++) {
955  const int mb_xy = s->mb_index2xy[i];
956  int old_error = s->error_status_table[mb_xy];
957 
958  if (old_error & VP_START) {
959  error = old_error & ER_MB_ERROR;
960  } else {
961  error |= old_error & ER_MB_ERROR;
962  s->error_status_table[mb_xy] |= error;
963  }
964  }
965 
966  /* handle not partitioned case */
967  if (!s->partitioned_frame) {
968  for (i = 0; i < s->mb_num; i++) {
969  const int mb_xy = s->mb_index2xy[i];
970  error = s->error_status_table[mb_xy];
971  if (error & ER_MB_ERROR)
972  error |= ER_MB_ERROR;
973  s->error_status_table[mb_xy] = error;
974  }
975  }
976 
977  dc_error = ac_error = mv_error = 0;
978  for (i = 0; i < s->mb_num; i++) {
979  const int mb_xy = s->mb_index2xy[i];
980  error = s->error_status_table[mb_xy];
981  if (error & ER_DC_ERROR)
982  dc_error++;
983  if (error & ER_AC_ERROR)
984  ac_error++;
985  if (error & ER_MV_ERROR)
986  mv_error++;
987  }
988  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n",
989  dc_error, ac_error, mv_error);
990 
991  is_intra_likely = is_intra_more_likely(s);
992 
993  /* set unknown mb-type to most likely */
994  for (i = 0; i < s->mb_num; i++) {
995  const int mb_xy = s->mb_index2xy[i];
996  error = s->error_status_table[mb_xy];
997  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
998  continue;
999 
1000  if (is_intra_likely)
1001  s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1002  else
1003  s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
1004  }
1005 
1006  // change inter to intra blocks if no reference frames are available
1007  if (!(s->last_pic && s->last_pic->f.data[0]) &&
1008  !(s->next_pic && s->next_pic->f.data[0]))
1009  for (i = 0; i < s->mb_num; i++) {
1010  const int mb_xy = s->mb_index2xy[i];
1011  if (!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
1012  s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1013  }
1014 
1015  /* handle inter blocks with damaged AC */
1016  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1017  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1018  const int mb_xy = mb_x + mb_y * s->mb_stride;
1019  const int mb_type = s->cur_pic->f.mb_type[mb_xy];
1020  const int dir = !(s->last_pic && s->last_pic->f.data[0]);
1021  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1022  int mv_type;
1023 
1024  error = s->error_status_table[mb_xy];
1025 
1026  if (IS_INTRA(mb_type))
1027  continue; // intra
1028  if (error & ER_MV_ERROR)
1029  continue; // inter with damaged MV
1030  if (!(error & ER_AC_ERROR))
1031  continue; // undamaged inter
1032 
1033  if (IS_8X8(mb_type)) {
1034  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1035  int j;
1036  mv_type = MV_TYPE_8X8;
1037  for (j = 0; j < 4; j++) {
1038  s->mv[0][j][0] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1039  s->mv[0][j][1] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1040  }
1041  } else {
1042  mv_type = MV_TYPE_16X16;
1043  s->mv[0][0][0] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1044  s->mv[0][0][1] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1045  }
1046 
1047  s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
1048  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1049  }
1050  }
1051 
1052  /* guess MVs */
1053  if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_B) {
1054  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1055  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1056  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1057  const int mb_xy = mb_x + mb_y * s->mb_stride;
1058  const int mb_type = s->cur_pic->f.mb_type[mb_xy];
1059  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1060 
1061  error = s->error_status_table[mb_xy];
1062 
1063  if (IS_INTRA(mb_type))
1064  continue;
1065  if (!(error & ER_MV_ERROR))
1066  continue; // inter with undamaged MV
1067  if (!(error & ER_AC_ERROR))
1068  continue; // undamaged inter
1069 
1070  if (!(s->last_pic && s->last_pic->f.data[0]))
1071  mv_dir &= ~MV_DIR_FORWARD;
1072  if (!(s->next_pic && s->next_pic->f.data[0]))
1073  mv_dir &= ~MV_DIR_BACKWARD;
1074 
1075  if (s->pp_time) {
1076  int time_pp = s->pp_time;
1077  int time_pb = s->pb_time;
1078 
1079  if (s->avctx->codec_id == AV_CODEC_ID_H264) {
1080  // FIXME
1081  } else {
1082  ff_thread_await_progress(&s->next_pic->f, mb_y, 0);
1083  }
1084  s->mv[0][0][0] = s->next_pic->f.motion_val[0][xy][0] * time_pb / time_pp;
1085  s->mv[0][0][1] = s->next_pic->f.motion_val[0][xy][1] * time_pb / time_pp;
1086  s->mv[1][0][0] = s->next_pic->f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1087  s->mv[1][0][1] = s->next_pic->f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1088  } else {
1089  s->mv[0][0][0] = 0;
1090  s->mv[0][0][1] = 0;
1091  s->mv[1][0][0] = 0;
1092  s->mv[1][0][1] = 0;
1093  }
1094 
1095  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1096  mb_x, mb_y, 0, 0);
1097  }
1098  }
1099  } else
1100  guess_mv(s);
1101 
1102  /* the filters below are not XvMC compatible, skip them */
1104  goto ec_clean;
1105  /* fill DC for inter blocks */
1106  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1107  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1108  int dc, dcu, dcv, y, n;
1109  int16_t *dc_ptr;
1110  uint8_t *dest_y, *dest_cb, *dest_cr;
1111  const int mb_xy = mb_x + mb_y * s->mb_stride;
1112  const int mb_type = s->cur_pic->f.mb_type[mb_xy];
1113 
1114  error = s->error_status_table[mb_xy];
1115 
1116  if (IS_INTRA(mb_type) && s->partitioned_frame)
1117  continue;
1118  // if (error & ER_MV_ERROR)
1119  // continue; // inter data damaged FIXME is this good?
1120 
1121  dest_y = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1122  dest_cb = s->cur_pic->f.data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1123  dest_cr = s->cur_pic->f.data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1124 
1125  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1126  for (n = 0; n < 4; n++) {
1127  dc = 0;
1128  for (y = 0; y < 8; y++) {
1129  int x;
1130  for (x = 0; x < 8; x++)
1131  dc += dest_y[x + (n & 1) * 8 +
1132  (y + (n >> 1) * 8) * linesize[0]];
1133  }
1134  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1135  }
1136 
1137  dcu = dcv = 0;
1138  for (y = 0; y < 8; y++) {
1139  int x;
1140  for (x = 0; x < 8; x++) {
1141  dcu += dest_cb[x + y * linesize[1]];
1142  dcv += dest_cr[x + y * linesize[2]];
1143  }
1144  }
1145  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1146  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1147  }
1148  }
1149 
1150  /* guess DC for damaged blocks */
1151  guess_dc(s, s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride, 1);
1152  guess_dc(s, s->dc_val[1], s->mb_width, s->mb_height, s->mb_stride, 0);
1153  guess_dc(s, s->dc_val[2], s->mb_width, s->mb_height, s->mb_stride, 0);
1154 
1155  /* filter luma DC */
1156  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1157 
1158  /* render DC only intra */
1159  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1160  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1161  uint8_t *dest_y, *dest_cb, *dest_cr;
1162  const int mb_xy = mb_x + mb_y * s->mb_stride;
1163  const int mb_type = s->cur_pic->f.mb_type[mb_xy];
1164 
1165  error = s->error_status_table[mb_xy];
1166 
1167  if (IS_INTER(mb_type))
1168  continue;
1169  if (!(error & ER_AC_ERROR))
1170  continue; // undamaged
1171 
1172  dest_y = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1173  dest_cb = s->cur_pic->f.data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1174  dest_cr = s->cur_pic->f.data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1175 
1176  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1177  }
1178  }
1179 
1181  /* filter horizontal block boundaries */
1182  h_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
1183  s->mb_height * 2, linesize[0], 1);
1184  h_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
1185  s->mb_height, linesize[1], 0);
1186  h_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
1187  s->mb_height, linesize[2], 0);
1188 
1189  /* filter vertical block boundaries */
1190  v_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
1191  s->mb_height * 2, linesize[0], 1);
1192  v_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
1193  s->mb_height, linesize[1], 0);
1194  v_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
1195  s->mb_height, linesize[2], 0);
1196  }
1197 
1198 ec_clean:
1199  /* clean a few tables */
1200  for (i = 0; i < s->mb_num; i++) {
1201  const int mb_xy = s->mb_index2xy[i];
1202  int error = s->error_status_table[mb_xy];
1203 
1204  if (s->cur_pic->f.pict_type != AV_PICTURE_TYPE_B &&
1205  (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
1206  s->mbskip_table[mb_xy] = 0;
1207  }
1208  s->mbintra_table[mb_xy] = 1;
1209  }
1210  s->cur_pic = NULL;
1211  s->next_pic = NULL;
1212  s->last_pic = NULL;
1213 }
const struct AVCodec * codec
Definition: avcodec.h:1348
#define ff_cropTbl
int size
#define MV_CHANGED
#define ER_MB_END
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.
void ff_er_frame_end(ERContext *s)
static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma)
simple vertical deblocking filter used for error resilience
#define MAX_NEG_CROP
Definition: dsputil.h:83
static void filter181(int16_t *data, int width, int height, int stride)
int16_t(*[2] motion_val_base)[2]
Definition: mpegvideo.h:103
#define VP_START
< current MB is the first after a resync marker
int field_picture
whether or not the picture was encoded in separate fields
Definition: mpegvideo.h:140
#define pass
Definition: fft.c:334
static void guess_mv(ERContext *s)
mpegvideo header.
#define ER_MV_ERROR
int stride
Definition: mace.c:144
#define MV_FROZEN
uint16_t pp_time
struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:2622
#define IS_INTER(a)
Definition: mpegvideo.h:110
uint8_t
#define b
Definition: input.c:52
#define ER_MB_ERROR
uint8_t motion_subsample_log2
log2 of the size of the block which a single vector in motion_val represents: (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
Definition: avcodec.h:1302
const char data[16]
Definition: mxf.c:66
#define ER_MV_END
static void guess_dc(ERContext *s, int16_t *dc, int w, int h, int stride, int is_luma)
guess the dc of blocks which do not have an undamaged dc
#define cm
Definition: dvbsubdec.c:34
void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy, int status)
Add a slice.
Multithreading support functions.
static const uint16_t mask[17]
Definition: lzw.c:38
int error_concealment
error concealment flags
Definition: avcodec.h:2559
int capabilities
Codec capabilities.
Definition: avcodec.h:2979
void(* decode_mb)(void *opaque, int ref, int mv_dir, int mv_type, int(*mv)[2][4][2], int mb_x, int mb_y, int mb_intra, int mb_skipped)
struct Picture * next_pic
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
#define IS_INTRA(a)
Definition: mpegvideo.h:109
uint8_t * mbintra_table
int * mb_index2xy
static float distance(float x, float y, int band)
uint8_t * error_status_table
#define ER_AC_ERROR
useful rectangle filling function
#define IS_8X8(a)
Definition: mpegvideo.h:119
enum AVPictureType pict_type
Picture type of the frame, see ?_TYPE below.
Definition: avcodec.h:1065
struct Picture * last_pic
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:2602
uint8_t * er_temp_buffer
#define ER_DC_END
uint16_t pb_time
DSPContext * dsp
int skip_top
Number of macroblock rows at the top which are skipped.
Definition: avcodec.h:1958
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:2733
int xvmc_acceleration
XVideo Motion Acceleration.
Definition: avcodec.h:1875
uint32_t * mb_type
macroblock type table mb_type_base + mb_width + 2
Definition: avcodec.h:1180
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:390
NULL
Definition: eval.c:52
#define MV_DIR_BACKWARD
Definition: mpegvideo.h:387
struct Picture * cur_pic
static int width
Definition: utils.c:156
external API header
void ff_thread_await_progress(AVFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
Definition: pthread.c:684
enum AVCodecID codec_id
Definition: avcodec.h:1350
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
Definition: avcodec.h:1008
int debug
debug
Definition: avcodec.h:2568
int16_t(*[2] motion_val)[2]
motion vector table
Definition: avcodec.h:1172
int8_t * ref_index[2]
motion reference frame index the order in which these are stored can depend on the codec...
Definition: avcodec.h:1195
#define ER_DC_ERROR
AVCodecContext * avctx
#define MV_DIR_FORWARD
Definition: mpegvideo.h:386
int skip_bottom
Number of macroblock rows at the bottom which are skipped.
Definition: avcodec.h:1965
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
int height
Definition: gxfenc.c:72
int partitioned_frame
#define MV_UNCHANGED
int16_t * dc_val[3]
Bi-dir predicted.
Definition: avutil.h:247
me_cmp_func sad[6]
Definition: dsputil.h:224
static const uint8_t color[]
Definition: log.c:52
DSP utils.
static int is_intra_more_likely(ERContext *s)
int mv[2][4][2]
struct AVFrame f
Definition: mpegvideo.h:96
void ff_er_frame_start(ERContext *s)
static void h_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma)
simple horizontal deblocking filter used for error resilience
#define ER_AC_END
#define MV_TYPE_8X8
4 vectors (h263, mpeg4 4MV)
Definition: mpegvideo.h:391
#define CONFIG_MPEG_XVMC_DECODER
Definition: config.h:442
uint8_t * mbskip_table
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:158
static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
if(!(ptr_align%ac->ptr_align)&&samples_align >=aligned_len)