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