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