]> git.sesse.net Git - ffmpeg/blob - libavcodec/error_resilience.c
Merge commit 'ef5d41a5534b65f03d02f2e11a503ab8416bfc3b'
[ffmpeg] / libavcodec / error_resilience.c
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
49     ff_init_block_index(s);
50     ff_update_block_index(s);
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         }
73         fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
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 =
79         h->mb_field_decoding_flag = 0;
80         ff_h264_hl_decode_mb(h);
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;
95         av_assert0(s->quarter_sample);
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;
290     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
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;
358     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
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
469                 s->mv_dir     = s->last_picture.f.data[0] ? MV_DIR_FORWARD
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;
514                     av_assert1(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
515                     av_assert1(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
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 {
634                             ff_thread_await_progress(&s->last_picture_ptr->f,
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
744 static int is_intra_more_likely(MpegEncContext *s)
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 &&
772         s->pict_type == AV_PICTURE_TYPE_I)
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 {
802                     ff_thread_await_progress(&s->last_picture_ptr->f,
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
820 void ff_er_frame_start(MpegEncContext *s)
821 {
822     if (!s->err_recognition)
823         return;
824
825     memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
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) {
851         av_log(s->avctx, AV_LOG_ERROR,
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
906 void ff_er_frame_end(MpegEncContext *s)
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                                              ||
920         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
921         s->picture_structure != PICT_FRAME                             ||
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
928         && s->current_picture.f.linesize[0] != s->current_picture_ptr->f.linesize[0]) {
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;
942         s->current_picture = *s->current_picture_ptr;
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)
1105             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1106         else
1107             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
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]))
1115                 s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
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
1176                 s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
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 {
1192                         ff_thread_await_progress(&s->next_picture_ptr->f, mb_y, 0);
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
1295     if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
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);
1299         h_block_filter(s, s->current_picture.f.data[1], s->mb_width,
1300                        s->mb_height  , s->uvlinesize, 0);
1301         h_block_filter(s, s->current_picture.f.data[2], s->mb_width,
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);
1307         v_block_filter(s, s->current_picture.f.data[1], s->mb_width,
1308                        s->mb_height  , s->uvlinesize, 0);
1309         v_block_filter(s, s->current_picture.f.data[2], s->mb_width,
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 }