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