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 = s->cur_pic.f->linesize;
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  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
879  int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
880  if (status != 0x7F)
881  break;
882  }
883 
884  if ( mb_x == s->mb_width
886  && (s->avctx->height&16)
887  && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)
888  ) {
889  av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
890  return;
891  }
892 
893  if (s->last_pic.f) {
894  if (s->last_pic.f->width != s->cur_pic.f->width ||
895  s->last_pic.f->height != s->cur_pic.f->height ||
896  s->last_pic.f->format != s->cur_pic.f->format) {
897  av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
898  memset(&s->last_pic, 0, sizeof(s->last_pic));
899  }
900  }
901  if (s->next_pic.f) {
902  if (s->next_pic.f->width != s->cur_pic.f->width ||
903  s->next_pic.f->height != s->cur_pic.f->height ||
904  s->next_pic.f->format != s->cur_pic.f->format) {
905  av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
906  memset(&s->next_pic, 0, sizeof(s->next_pic));
907  }
908  }
909 
910  if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
911  av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
912 
913  for (i = 0; i < 2; i++) {
914  s->ref_index_buf[i] = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
915  s->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
916  if (!s->ref_index_buf[i] || !s->motion_val_buf[i])
917  break;
918  s->cur_pic.ref_index[i] = s->ref_index_buf[i]->data;
919  s->cur_pic.motion_val[i] = (int16_t (*)[2])s->motion_val_buf[i]->data + 4;
920  }
921  if (i < 2) {
922  for (i = 0; i < 2; i++) {
925  s->cur_pic.ref_index[i] = NULL;
926  s->cur_pic.motion_val[i] = NULL;
927  }
928  return;
929  }
930  }
931 
932  if (s->avctx->debug & FF_DEBUG_ER) {
933  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
934  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
935  int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
936 
937  av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
938  }
939  av_log(s->avctx, AV_LOG_DEBUG, "\n");
940  }
941  }
942 
943 #if 1
944  /* handle overlapping slices */
945  for (error_type = 1; error_type <= 3; error_type++) {
946  int end_ok = 0;
947 
948  for (i = s->mb_num - 1; i >= 0; i--) {
949  const int mb_xy = s->mb_index2xy[i];
950  int error = s->error_status_table[mb_xy];
951 
952  if (error & (1 << error_type))
953  end_ok = 1;
954  if (error & (8 << error_type))
955  end_ok = 1;
956 
957  if (!end_ok)
958  s->error_status_table[mb_xy] |= 1 << error_type;
959 
960  if (error & VP_START)
961  end_ok = 0;
962  }
963  }
964 #endif
965 #if 1
966  /* handle slices with partitions of different length */
967  if (s->partitioned_frame) {
968  int end_ok = 0;
969 
970  for (i = s->mb_num - 1; i >= 0; i--) {
971  const int mb_xy = s->mb_index2xy[i];
972  int error = s->error_status_table[mb_xy];
973 
974  if (error & ER_AC_END)
975  end_ok = 0;
976  if ((error & ER_MV_END) ||
977  (error & ER_DC_END) ||
978  (error & ER_AC_ERROR))
979  end_ok = 1;
980 
981  if (!end_ok)
982  s->error_status_table[mb_xy]|= ER_AC_ERROR;
983 
984  if (error & VP_START)
985  end_ok = 0;
986  }
987  }
988 #endif
989  /* handle missing slices */
990  if (s->avctx->err_recognition & AV_EF_EXPLODE) {
991  int end_ok = 1;
992 
993  // FIXME + 100 hack
994  for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
995  const int mb_xy = s->mb_index2xy[i];
996  int error1 = s->error_status_table[mb_xy];
997  int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
998 
999  if (error1 & VP_START)
1000  end_ok = 1;
1001 
1002  if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1003  error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1004  ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1005  (error1 & ER_MV_END))) {
1006  // end & uninit
1007  end_ok = 0;
1008  }
1009 
1010  if (!end_ok)
1011  s->error_status_table[mb_xy] |= ER_MB_ERROR;
1012  }
1013  }
1014 
1015 #if 1
1016  /* backward mark errors */
1017  distance = 9999999;
1018  for (error_type = 1; error_type <= 3; error_type++) {
1019  for (i = s->mb_num - 1; i >= 0; i--) {
1020  const int mb_xy = s->mb_index2xy[i];
1021  int error = s->error_status_table[mb_xy];
1022 
1023  if (!s->mbskip_table[mb_xy]) // FIXME partition specific
1024  distance++;
1025  if (error & (1 << error_type))
1026  distance = 0;
1027 
1028  if (s->partitioned_frame) {
1029  if (distance < threshold_part[error_type - 1])
1030  s->error_status_table[mb_xy] |= 1 << error_type;
1031  } else {
1032  if (distance < threshold)
1033  s->error_status_table[mb_xy] |= 1 << error_type;
1034  }
1035 
1036  if (error & VP_START)
1037  distance = 9999999;
1038  }
1039  }
1040 #endif
1041 
1042  /* forward mark errors */
1043  error = 0;
1044  for (i = 0; i < s->mb_num; i++) {
1045  const int mb_xy = s->mb_index2xy[i];
1046  int old_error = s->error_status_table[mb_xy];
1047 
1048  if (old_error & VP_START) {
1049  error = old_error & ER_MB_ERROR;
1050  } else {
1051  error |= old_error & ER_MB_ERROR;
1052  s->error_status_table[mb_xy] |= error;
1053  }
1054  }
1055 #if 1
1056  /* handle not partitioned case */
1057  if (!s->partitioned_frame) {
1058  for (i = 0; i < s->mb_num; i++) {
1059  const int mb_xy = s->mb_index2xy[i];
1060  int error = s->error_status_table[mb_xy];
1061  if (error & ER_MB_ERROR)
1062  error |= ER_MB_ERROR;
1063  s->error_status_table[mb_xy] = error;
1064  }
1065  }
1066 #endif
1067 
1068  dc_error = ac_error = mv_error = 0;
1069  for (i = 0; i < s->mb_num; i++) {
1070  const int mb_xy = s->mb_index2xy[i];
1071  int error = s->error_status_table[mb_xy];
1072  if (error & ER_DC_ERROR)
1073  dc_error++;
1074  if (error & ER_AC_ERROR)
1075  ac_error++;
1076  if (error & ER_MV_ERROR)
1077  mv_error++;
1078  }
1079  av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1080  dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1081 
1082  is_intra_likely = is_intra_more_likely(s);
1083 
1084  /* set unknown mb-type to most likely */
1085  for (i = 0; i < s->mb_num; i++) {
1086  const int mb_xy = s->mb_index2xy[i];
1087  int error = s->error_status_table[mb_xy];
1088  if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1089  continue;
1090 
1091  if (is_intra_likely)
1092  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1093  else
1094  s->cur_pic.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
1095  }
1096 
1097  // change inter to intra blocks if no reference frames are available
1098  if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1099  !(s->next_pic.f && s->next_pic.f->data[0]))
1100  for (i = 0; i < s->mb_num; i++) {
1101  const int mb_xy = s->mb_index2xy[i];
1102  if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1103  s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1104  }
1105 
1106  /* handle inter blocks with damaged AC */
1107  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1108  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1109  const int mb_xy = mb_x + mb_y * s->mb_stride;
1110  const int mb_type = s->cur_pic.mb_type[mb_xy];
1111  const int dir = !(s->last_pic.f && s->last_pic.f->data[0]);
1112  const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1113  int mv_type;
1114 
1115  int error = s->error_status_table[mb_xy];
1116 
1117  if (IS_INTRA(mb_type))
1118  continue; // intra
1119  if (error & ER_MV_ERROR)
1120  continue; // inter with damaged MV
1121  if (!(error & ER_AC_ERROR))
1122  continue; // undamaged inter
1123 
1124  if (IS_8X8(mb_type)) {
1125  int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1126  int j;
1127  mv_type = MV_TYPE_8X8;
1128  for (j = 0; j < 4; j++) {
1129  s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1130  s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1131  }
1132  } else {
1133  mv_type = MV_TYPE_16X16;
1134  s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1135  s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1136  }
1137 
1138  s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
1139  mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1140  }
1141  }
1142 
1143  /* guess MVs */
1144  if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1145  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1146  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1147  int xy = mb_x * 2 + mb_y * 2 * s->b8_stride;
1148  const int mb_xy = mb_x + mb_y * s->mb_stride;
1149  const int mb_type = s->cur_pic.mb_type[mb_xy];
1150  int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1151 
1152  int error = s->error_status_table[mb_xy];
1153 
1154  if (IS_INTRA(mb_type))
1155  continue;
1156  if (!(error & ER_MV_ERROR))
1157  continue; // inter with undamaged MV
1158  if (!(error & ER_AC_ERROR))
1159  continue; // undamaged inter
1160 
1161  if (!(s->last_pic.f && s->last_pic.f->data[0]))
1162  mv_dir &= ~MV_DIR_FORWARD;
1163  if (!(s->next_pic.f && s->next_pic.f->data[0]))
1164  mv_dir &= ~MV_DIR_BACKWARD;
1165 
1166  if (s->pp_time) {
1167  int time_pp = s->pp_time;
1168  int time_pb = s->pb_time;
1169 
1171  ff_thread_await_progress(s->next_pic.tf, mb_y, 0);
1172 
1173  s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp;
1174  s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp;
1175  s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1176  s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1177  } else {
1178  s->mv[0][0][0] = 0;
1179  s->mv[0][0][1] = 0;
1180  s->mv[1][0][0] = 0;
1181  s->mv[1][0][1] = 0;
1182  }
1183 
1184  s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1185  mb_x, mb_y, 0, 0);
1186  }
1187  }
1188  } else
1189  guess_mv(s);
1190 
1191  /* the filters below manipulate raw image, skip them */
1192  if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb)
1193  goto ec_clean;
1194  /* fill DC for inter blocks */
1195  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1196  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1197  int dc, dcu, dcv, y, n;
1198  int16_t *dc_ptr;
1199  uint8_t *dest_y, *dest_cb, *dest_cr;
1200  const int mb_xy = mb_x + mb_y * s->mb_stride;
1201  const int mb_type = s->cur_pic.mb_type[mb_xy];
1202 
1203  // error = s->error_status_table[mb_xy];
1204 
1205  if (IS_INTRA(mb_type) && s->partitioned_frame)
1206  continue;
1207  // if (error & ER_MV_ERROR)
1208  // continue; // inter data damaged FIXME is this good?
1209 
1210  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1211  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1212  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1213 
1214  dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1215  for (n = 0; n < 4; n++) {
1216  dc = 0;
1217  for (y = 0; y < 8; y++) {
1218  int x;
1219  for (x = 0; x < 8; x++)
1220  dc += dest_y[x + (n & 1) * 8 +
1221  (y + (n >> 1) * 8) * linesize[0]];
1222  }
1223  dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1224  }
1225 
1226  dcu = dcv = 0;
1227  for (y = 0; y < 8; y++) {
1228  int x;
1229  for (x = 0; x < 8; x++) {
1230  dcu += dest_cb[x + y * linesize[1]];
1231  dcv += dest_cr[x + y * linesize[2]];
1232  }
1233  }
1234  s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1235  s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1236  }
1237  }
1238 #if 1
1239  /* guess DC for damaged blocks */
1240  guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1241  guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1242  guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1243 #endif
1244 
1245  /* filter luma DC */
1246  filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1247 
1248 #if 1
1249  /* render DC only intra */
1250  for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1251  for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1252  uint8_t *dest_y, *dest_cb, *dest_cr;
1253  const int mb_xy = mb_x + mb_y * s->mb_stride;
1254  const int mb_type = s->cur_pic.mb_type[mb_xy];
1255 
1256  int error = s->error_status_table[mb_xy];
1257 
1258  if (IS_INTER(mb_type))
1259  continue;
1260  if (!(error & ER_AC_ERROR))
1261  continue; // undamaged
1262 
1263  dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1264  dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1];
1265  dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2];
1266 
1267  put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1268  }
1269  }
1270 #endif
1271 
1273  /* filter horizontal block boundaries */
1274  h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1275  s->mb_height * 2, linesize[0], 1);
1276  h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1277  s->mb_height, linesize[1], 0);
1278  h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1279  s->mb_height, linesize[2], 0);
1280 
1281  /* filter vertical block boundaries */
1282  v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1283  s->mb_height * 2, linesize[0], 1);
1284  v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1285  s->mb_height, linesize[1], 0);
1286  v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1287  s->mb_height, linesize[2], 0);
1288  }
1289 
1290 ec_clean:
1291  /* clean a few tables */
1292  for (i = 0; i < s->mb_num; i++) {
1293  const int mb_xy = s->mb_index2xy[i];
1294  int error = s->error_status_table[mb_xy];
1295 
1296  if (s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1297  (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
1298  s->mbskip_table[mb_xy] = 0;
1299  }
1300  s->mbintra_table[mb_xy] = 1;
1301  }
1302 
1303  for (i = 0; i < 2; i++) {
1306  s->cur_pic.ref_index[i] = NULL;
1307  s->cur_pic.motion_val[i] = NULL;
1308  }
1309 
1310  memset(&s->cur_pic, 0, sizeof(ERPicture));
1311  memset(&s->last_pic, 0, sizeof(ERPicture));
1312  memset(&s->next_pic, 0, sizeof(ERPicture));
1313 }