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