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