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