error_resilience.c 49.7 KB
Newer Older
1 2 3
/*
 * Error resilience / concealment
 *
4
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5
 *
6 7 8
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
9 10
 * modify it under the terms of the GNU Lesser General Public
 * 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 15 16 17 18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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

Michael Niedermayer's avatar
Michael Niedermayer committed
23
/**
24
 * @file
Michael Niedermayer's avatar
Michael Niedermayer committed
25 26
 * Error resilience / concealment.
 */
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 41 42

/**
 * @param stride the number of MVs to get to the next row
 * @param mv_step the number of MVs per row or column in a macroblock
 */
43
static 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 50 51
    } else {
        *mv_step = 2;
        *stride  = s->b8_stride;
52 53 54
    }
}

55
/**
56
 * Replace the current MB with a flat dc-only version.
57
 */
58
static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
59
                   uint8_t *dest_cr, int mb_x, int mb_y)
60
{
61
    int *linesize = s->cur_pic.f->linesize;
62
    int dc, dcu, dcv, y, i;
63 64 65 66 67 68 69
    for (i = 0; i < 4; i++) {
        dc = s->dc_val[0][mb_x * 2 + (i &  1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
        if (dc < 0)
            dc = 0;
        else if (dc > 2040)
            dc = 2040;
        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 76 77 78 79 80 81 82 83 84 85
    dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
    dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
    if (dcu < 0)
        dcu = 0;
    else if (dcu > 2040)
        dcu = 2040;
    if (dcv < 0)
        dcv = 0;
    else if (dcv > 2040)
        dcv = 2040;
    for (y = 0; y < 8; y++) {
86
        int x;
87
        for (x = 0; x < 8; x++) {
88 89
            dest_cb[x + y * linesize[1]] = dcu / 8;
            dest_cr[x + y * linesize[2]] = dcv / 8;
90 91 92 93
        }
    }
}

94 95 96
static void filter181(int16_t *data, int width, int height, int stride)
{
    int x, y;
97 98

    /* horizontal filter */
99 100
    for (y = 1; y < height - 1; y++) {
        int prev_dc = data[0 + y * stride];
101

102
        for (x = 1; x < width - 1; x++) {
103
            int dc;
104 105 106 107 108 109
            dc = -prev_dc +
                 data[x     + y * stride] * 8 -
                 data[x + 1 + y * stride];
            dc = (dc * 10923 + 32768) >> 16;
            prev_dc = data[x + y * stride];
            data[x + y * stride] = dc;
110 111
        }
    }
112

113
    /* vertical filter */
114 115
    for (x = 1; x < width - 1; x++) {
        int prev_dc = data[x];
116

117
        for (y = 1; y < height - 1; y++) {
118
            int dc;
119

120 121 122 123 124 125
            dc = -prev_dc +
                 data[x +  y      * stride] * 8 -
                 data[x + (y + 1) * stride];
            dc = (dc * 10923 + 32768) >> 16;
            prev_dc = data[x + y * stride];
            data[x + y * stride] = dc;
126 127 128 129 130
        }
    }
}

/**
Diego Biurrun's avatar
Diego Biurrun committed
131
 * guess the dc of blocks which do not have an undamaged dc
132 133
 * @param w     width in 8 pixel blocks
 * @param h     height in 8 pixel blocks
134
 */
135
static void guess_dc(ERContext *s, int16_t *dc, int w,
136 137
                     int h, int stride, int is_luma)
{
138
    int b_x, b_y;
139 140
    int16_t  (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4);
    uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4);
141

142 143 144 145 146
    if(!col || !dist) {
        av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
        goto fail;
    }

147 148 149 150 151 152
    for(b_y=0; b_y<h; b_y++){
        int color= 1024;
        int distance= -1;
        for(b_x=0; b_x<w; b_x++){
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
            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 155 156 157 158 159 160 161 162 163 164 165
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                color= dc[b_x + b_y*stride];
                distance= b_x;
            }
            col [b_x + b_y*stride][1]= color;
            dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
        }
        color= 1024;
        distance= -1;
        for(b_x=w-1; b_x>=0; b_x--){
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
            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 168 169 170 171 172 173 174 175 176 177 178 179 180
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                color= dc[b_x + b_y*stride];
                distance= b_x;
            }
            col [b_x + b_y*stride][0]= color;
            dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
        }
    }
    for(b_x=0; b_x<w; b_x++){
        int color= 1024;
        int distance= -1;
        for(b_y=0; b_y<h; b_y++){
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
            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 183 184 185 186 187 188 189 190 191 192 193
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                color= dc[b_x + b_y*stride];
                distance= b_y;
            }
            col [b_x + b_y*stride][3]= color;
            dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
        }
        color= 1024;
        distance= -1;
        for(b_y=h-1; b_y>=0; b_y--){
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
            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 196 197 198 199 200 201 202
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
                color= dc[b_x + b_y*stride];
                distance= b_y;
            }
            col [b_x + b_y*stride][2]= color;
            dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
        }
    }
203

204 205
    for (b_y = 0; b_y < h; b_y++) {
        for (b_x = 0; b_x < w; b_x++) {
206
            int mb_index, error, j;
207
            int64_t guess, weight_sum;
208 209
            mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
            error    = s->error_status_table[mb_index];
210

211
            if (IS_INTER(s->cur_pic.mb_type[mb_index]))
212 213 214
                continue; // inter
            if (!(error & ER_DC_ERROR))
                continue; // dc-ok
215

216 217 218
            weight_sum = 0;
            guess      = 0;
            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 224
            guess = (guess + weight_sum / 2) / weight_sum;
            dc[b_x + b_y * stride] = guess;
225 226
        }
    }
227 228

fail:
229 230
    av_freep(&col);
    av_freep(&dist);
231 232 233 234
}

/**
 * simple horizontal deblocking filter used for error resilience
235 236
 * @param w     width in 8 pixel blocks
 * @param h     height in 8 pixel blocks
237
 */
238
static void h_block_filter(ERContext *s, uint8_t *dst, int w,
239 240
                           int h, int stride, int is_luma)
{
241
    int b_x, b_y, mvx_stride, mvy_stride;
242
    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
243 244 245
    set_mv_strides(s, &mvx_stride, &mvy_stride);
    mvx_stride >>= is_luma;
    mvy_stride *= mvx_stride;
246

247 248
    for (b_y = 0; b_y < h; b_y++) {
        for (b_x = 0; b_x < w - 1; b_x++) {
249
            int y;
250 251
            int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
            int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
252 253
            int left_intra   = IS_INTRA(s->cur_pic.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
            int right_intra  = IS_INTRA(s->cur_pic.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
254 255 256
            int left_damage  = left_status & ER_MB_ERROR;
            int right_damage = right_status & ER_MB_ERROR;
            int offset       = b_x * 8 + b_y * stride * 8;
257 258
            int16_t *left_mv  = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
            int16_t *right_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
            if (!(left_damage || right_damage))
                continue; // both undamaged
            if ((!left_intra) && (!right_intra) &&
                FFABS(left_mv[0] - right_mv[0]) +
                FFABS(left_mv[1] + right_mv[1]) < 2)
                continue;

            for (y = 0; y < 8; y++) {
                int a, b, c, d;

                a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
                b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
                c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];

                d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
                d = FFMAX(d, 0);
                if (b < 0)
                    d = -d;

                if (d == 0)
                    continue;

                if (!(left_damage && right_damage))
                    d = d * 16 / 9;

                if (left_damage) {
                    dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
                    dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
                    dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
                    dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
289
                }
290 291 292 293 294
                if (right_damage) {
                    dst[offset + 8 + y * stride] = cm[dst[offset +  8 + y * stride] - ((d * 7) >> 4)];
                    dst[offset + 9 + y * stride] = cm[dst[offset +  9 + y * stride] - ((d * 5) >> 4)];
                    dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
                    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 304
 * @param w     width in 8 pixel blocks
 * @param h     height in 8 pixel blocks
305
 */
306
static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
307 308
                           int stride, int is_luma)
{
309
    int b_x, b_y, mvx_stride, mvy_stride;
310
    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
311 312 313
    set_mv_strides(s, &mvx_stride, &mvy_stride);
    mvx_stride >>= is_luma;
    mvy_stride *= mvx_stride;
314

315 316
    for (b_y = 0; b_y < h - 1; b_y++) {
        for (b_x = 0; b_x < w; b_x++) {
317
            int x;
318 319
            int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
            int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
320 321
            int top_intra     = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
            int bottom_intra  = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
322 323 324 325
            int top_damage    = top_status & ER_MB_ERROR;
            int bottom_damage = bottom_status & ER_MB_ERROR;
            int offset        = b_x * 8 + b_y * stride * 8;

326 327
            int16_t *top_mv    = s->cur_pic.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
            int16_t *bottom_mv = s->cur_pic.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
328

329 330
            if (!(top_damage || bottom_damage))
                continue; // both undamaged
331

332 333 334 335
            if ((!top_intra) && (!bottom_intra) &&
                FFABS(top_mv[0] - bottom_mv[0]) +
                FFABS(top_mv[1] + bottom_mv[1]) < 2)
                continue;
336

337 338
            for (x = 0; x < 8; x++) {
                int a, b, c, d;
339

340 341 342
                a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
                b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
                c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
343

344 345 346 347
                d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
                d = FFMAX(d, 0);
                if (b < 0)
                    d = -d;
348

349 350
                if (d == 0)
                    continue;
351

352 353
                if (!(top_damage && bottom_damage))
                    d = d * 16 / 9;
354

355 356 357 358 359
                if (top_damage) {
                    dst[offset + x +  7 * stride] = cm[dst[offset + x +  7 * stride] + ((d * 7) >> 4)];
                    dst[offset + x +  6 * stride] = cm[dst[offset + x +  6 * stride] + ((d * 5) >> 4)];
                    dst[offset + x +  5 * stride] = cm[dst[offset + x +  5 * stride] + ((d * 3) >> 4)];
                    dst[offset + x +  4 * stride] = cm[dst[offset + x +  4 * stride] + ((d * 1) >> 4)];
360
                }
361 362 363 364 365
                if (bottom_damage) {
                    dst[offset + x +  8 * stride] = cm[dst[offset + x +  8 * stride] - ((d * 7) >> 4)];
                    dst[offset + x +  9 * stride] = cm[dst[offset + x +  9 * stride] - ((d * 5) >> 4)];
                    dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
                    dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
366 367 368 369 370 371
                }
            }
        }
    }
}

372
static void guess_mv(ERContext *s)
373
{
374
    uint8_t *fixed = s->er_temp_buffer;
375 376 377
#define MV_FROZEN    3
#define MV_CHANGED   2
#define MV_UNCHANGED 1
378
    const int mb_stride = s->mb_stride;
379 380
    const int mb_width  = s->mb_width;
    const int mb_height = s->mb_height;
381
    int i, depth, num_avail;
382 383 384
    int mb_x, mb_y, mot_step, mot_stride;

    set_mv_strides(s, &mot_step, &mot_stride);
385

386 387 388 389 390
    num_avail = 0;
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
        int f = 0;
        int error = s->error_status_table[mb_xy];
391

392
        if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
393 394 395
            f = MV_FROZEN; // intra // FIXME check
        if (!(error & ER_MV_ERROR))
            f = MV_FROZEN; // inter with undamaged MV
396

397 398
        fixed[mb_xy] = f;
        if (f == MV_FROZEN)
399
            num_avail++;
400
        else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
401 402 403
            const int mb_y= mb_xy / s->mb_stride;
            const int mb_x= mb_xy % s->mb_stride;
            const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
404 405 406
            s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
            s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
            s->cur_pic.ref_index[0][4*mb_xy]      = s->last_pic.ref_index[0][4*mb_xy];
407
        }
408
    }
409

410 411 412 413 414
    if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
        num_avail <= mb_width / 2) {
        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                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 419 420
                    continue;
                if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
                    continue;
421

422 423
                s->mv[0][0][0] = 0;
                s->mv[0][0][1] = 0;
424 425
                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
                             mb_x, mb_y, 0, 0);
426 427 428 429
            }
        }
        return;
    }
430

431
    for (depth = 0; ; depth++) {
432 433
        int changed, pass, none_left;

434 435 436
        none_left = 1;
        changed   = 1;
        for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
437
            int mb_x, mb_y;
438 439 440 441 442 443 444 445 446
            int score_sum = 0;

            changed = 0;
            for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
                for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                    const int mb_xy        = mb_x + mb_y * s->mb_stride;
                    int mv_predictor[8][2] = { { 0 } };
                    int ref[8]             = { 0 };
                    int pred_count         = 0;
447
                    int j;
448 449 450
                    int best_score         = 256 * 256 * 256 * 64;
                    int best_pred          = 0;
                    const int mot_index    = (mb_x + mb_y * mot_stride) * mot_step;
451
                    int prev_x = 0, prev_y = 0, prev_ref = 0;
452

453 454
                    if ((mb_x ^ mb_y ^ pass) & 1)
                        continue;
455

456 457
                    if (fixed[mb_xy] == MV_FROZEN)
                        continue;
458 459
                    av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
                    av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
460

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
                    j = 0;
                    if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
                        j = 1;
                    if (mb_x + 1 < mb_width  && fixed[mb_xy + 1]         == MV_FROZEN)
                        j = 1;
                    if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_FROZEN)
                        j = 1;
                    if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_FROZEN)
                        j = 1;
                    if (j == 0)
                        continue;

                    j = 0;
                    if (mb_x > 0             && fixed[mb_xy - 1        ] == MV_CHANGED)
                        j = 1;
                    if (mb_x + 1 < mb_width  && fixed[mb_xy + 1        ] == MV_CHANGED)
                        j = 1;
                    if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_CHANGED)
                        j = 1;
                    if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_CHANGED)
                        j = 1;
                    if (j == 0 && pass > 1)
                        continue;

                    none_left = 0;

                    if (mb_x > 0 && fixed[mb_xy - 1]) {
                        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 495
                        pred_count++;
                    }
496 497
                    if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                        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 504
                        pred_count++;
                    }
505 506
                    if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                        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 513
                        pred_count++;
                    }
514 515
                    if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
                        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 522
                        pred_count++;
                    }
523 524
                    if (pred_count == 0)
                        continue;
525

526 527
                    if (pred_count > 1) {
                        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 531 532 533 534
                        for (j = 0; j < pred_count; j++) {
                            sum_x += mv_predictor[j][0];
                            sum_y += mv_predictor[j][1];
                            sum_r += ref[j];
                            if (j && ref[j] != ref[j - 1])
535
                                goto skip_mean_and_median;
536
                        }
537

538
                        /* mean */
539 540 541
                        mv_predictor[pred_count][0] = sum_x / j;
                        mv_predictor[pred_count][1] = sum_y / j;
                                 ref[pred_count]    = sum_r / j;
542

543
                        /* median */
544 545 546 547 548
                        if (pred_count >= 3) {
                            min_y = min_x = min_r =  99999;
                            max_y = max_x = max_r = -99999;
                        } else {
                            min_x = min_y = max_x = max_y = min_r = max_r = 0;
549
                        }
550 551 552 553 554 555 556
                        for (j = 0; j < pred_count; j++) {
                            max_x = FFMAX(max_x, mv_predictor[j][0]);
                            max_y = FFMAX(max_y, mv_predictor[j][1]);
                            max_r = FFMAX(max_r, ref[j]);
                            min_x = FFMIN(min_x, mv_predictor[j][0]);
                            min_y = FFMIN(min_y, mv_predictor[j][1]);
                            min_r = FFMIN(min_r, ref[j]);
557
                        }
558 559 560 561 562 563 564 565
                        mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
                        mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
                                 ref[pred_count + 1]    = sum_r - max_r - min_r;

                        if (pred_count == 4) {
                            mv_predictor[pred_count + 1][0] /= 2;
                            mv_predictor[pred_count + 1][1] /= 2;
                                     ref[pred_count + 1]    /= 2;
566
                        }
567
                        pred_count += 2;
568
                    }
569

570
skip_mean_and_median:
571 572 573
                    /* zero MV */
                    pred_count++;

574
                    if (!fixed[mb_xy] && 0) {
575
                        if (s->avctx->codec_id == AV_CODEC_ID_H264) {
576 577
                            // FIXME
                        } else {
578
                            ff_thread_await_progress(s->last_pic.tf,
579 580
                                                     mb_y, 0);
                        }
581 582
                        if (!s->last_pic.motion_val[0] ||
                            !s->last_pic.ref_index[0])
583
                            goto skip_last_mv;
584 585 586
                        prev_x   = s->last_pic.motion_val[0][mot_index][0];
                        prev_y   = s->last_pic.motion_val[0][mot_index][1];
                        prev_ref = s->last_pic.ref_index[0][4 * mb_xy];
587
                    } else {
588 589 590
                        prev_x   = s->cur_pic.motion_val[0][mot_index][0];
                        prev_y   = s->cur_pic.motion_val[0][mot_index][1];
                        prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
591 592
                    }

593
                    /* last MV */
594 595 596
                    mv_predictor[pred_count][0] = prev_x;
                    mv_predictor[pred_count][1] = prev_y;
                             ref[pred_count]    = prev_ref;
597 598
                    pred_count++;

599
skip_last_mv:
600

601
                    for (j = 0; j < pred_count; j++) {
602
                        int *linesize = s->cur_pic.f->linesize;
603
                        int score = 0;
604
                        uint8_t *src = s->cur_pic.f->data[0] +
605
                                       mb_x * 16 + mb_y * 16 * linesize[0];
606

607
                        s->cur_pic.motion_val[0][mot_index][0] =
608
                            s->mv[0][0][0] = mv_predictor[j][0];
609
                        s->cur_pic.motion_val[0][mot_index][1] =
610
                            s->mv[0][0][1] = mv_predictor[j][1];
611

612 613
                        // predictor intra or otherwise not available
                        if (ref[j] < 0)
614 615
                            continue;

616 617
                        s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
                                     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 623
                                score += FFABS(src[k * linesize[0] - 1] -
                                               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 629
                                score += FFABS(src[k * linesize[0] + 15] -
                                               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 640
                                score += FFABS(src[k + linesize[0] * 15] -
                                               src[k + linesize[0] * 16]);
641
                        }
642

643 644 645
                        if (score <= best_score) { // <= will favor the last MV
                            best_score = score;
                            best_pred  = j;
646 647
                        }
                    }
648 649 650
                    score_sum += best_score;
                    s->mv[0][0][0] = mv_predictor[best_pred][0];
                    s->mv[0][0][1] = mv_predictor[best_pred][1];
651

652 653
                    for (i = 0; i < mot_step; i++)
                        for (j = 0; j < mot_step; j++) {
654 655
                            s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
                            s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
656
                        }
657

658 659
                    s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
660

661

662 663
                    if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
                        fixed[mb_xy] = MV_CHANGED;
664
                        changed++;
665 666
                    } else
                        fixed[mb_xy] = MV_UNCHANGED;
667 668 669
                }
            }
        }
670

671
        if (none_left)
672
            return;
673

674 675 676 677
        for (i = 0; i < s->mb_num; i++) {
            int mb_xy = s->mb_index2xy[i];
            if (fixed[mb_xy])
                fixed[mb_xy] = MV_FROZEN;
678 679 680
        }
    }
}
681

682
static 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 690 691
    if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
        return 0;

692 693 694 695 696
    undamaged_count = 0;
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
        const int error = s->error_status_table[mb_xy];
        if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
697 698
            undamaged_count++;
    }
699

700 701
    if (s->avctx->codec_id == AV_CODEC_ID_H264 && s->ref_count <= 0)
        return 1;
702

703 704
    if (undamaged_count < 5)
        return 0; // almost all MBs damaged -> use temporal prediction
705

706
    // prevent dsp.sad() check, that requires access to the image
707 708
    if (CONFIG_XVMC    &&
        s->avctx->hwaccel && s->avctx->hwaccel->decode_mb &&
709
        s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I)
710
        return 1;
711

712 713
    skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
    is_intra_likely = 0;
714

715 716 717
    j = 0;
    for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
        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 722 723
            error = s->error_status_table[mb_xy];
            if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
                continue; // skip damaged
724 725

            j++;
726 727 728
            // skip a few to speed things up
            if ((j % skip_amount) != 0)
                continue;
729

730 731 732
            if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
                int *linesize = s->cur_pic.f->linesize;
                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 739
                    // FIXME
                } else {
740
                    ff_thread_await_progress(s->last_pic.tf, mb_y, 0);
741
                }
742 743
                is_intra_likely += s->mecc->sad[0](NULL, last_mb_ptr, mb_ptr,
                                                   linesize[0], 16);
744
                // FIXME need await_progress() here
745 746 747
                is_intra_likely -= s->mecc->sad[0](NULL, last_mb_ptr,
                                                   last_mb_ptr + linesize[0] * 16,
                                                   linesize[0], 16);
748
            } else {
749
                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
750 751 752 753 754 755
                   is_intra_likely++;
                else
                   is_intra_likely--;
            }
        }
    }
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
}

760
void ff_er_frame_start(ERContext *s)
761
{
762
    if (!s->avctx->error_concealment)
763
        return;
764

765 766 767
    memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
           s->mb_stride * s->mb_height * sizeof(uint8_t));
    s->error_count    = 3 * s->mb_num;
768
    s->error_occurred = 0;
769 770
}

771 772
static int er_supported(ERContext *s)
{
773
    if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice           ||
774
       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
775 776
       !s->cur_pic.f                                                  ||
       s->cur_pic.field_picture
777 778 779 780 781
    )
        return 0;
    return 1;
}

782
/**
783
 * Add a slice.
784 785 786 787
 * @param endx   x component of the last macroblock, can be -1
 *               for the last of the previous line
 * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
 *               assumed that no earlier end or error of the same type occurred
788
 */
789
void ff_er_add_slice(ERContext *s, int startx, int starty,
790 791 792 793 794 795 796 797
                     int endx, int endy, int status)
{
    const int start_i  = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
    const int end_i    = av_clip(endx   + endy   * s->mb_width, 0, s->mb_num);
    const int start_xy = s->mb_index2xy[start_i];
    const int end_xy   = s->mb_index2xy[end_i];
    int mask           = -1;

798
    if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice)
799 800
        return;

801 802 803
    if (start_i > end_i || start_xy > end_xy) {
        av_log(s->avctx, AV_LOG_ERROR,
               "internal error, slice end before start\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
804 805
        return;
    }
806

807
    if (!s->avctx->error_concealment)
808
        return;
809 810

    mask &= ~VP_START;
811 812
    if (status & (ER_AC_ERROR | ER_AC_END)) {
        mask           &= ~(ER_AC_ERROR | ER_AC_END);
813 814
        s->error_count -= end_i - start_i + 1;
    }
815 816
    if (status & (ER_DC_ERROR | ER_DC_END)) {
        mask           &= ~(ER_DC_ERROR | ER_DC_END);
817 818
        s->error_count -= end_i - start_i + 1;
    }
819 820
    if (status & (ER_MV_ERROR | ER_MV_END)) {
        mask           &= ~(ER_MV_ERROR | ER_MV_END);
821 822 823
        s->error_count -= end_i - start_i + 1;
    }

824
    if (status & ER_MB_ERROR) {
825
        s->error_occurred = 1;
826
        s->error_count    = INT_MAX;
827
    }
828

829 830 831 832
    if (mask == ~0x7F) {
        memset(&s->error_status_table[start_xy], 0,
               (end_xy - start_xy) * sizeof(uint8_t));
    } else {
833
        int i;
834 835
        for (i = start_xy; i < end_xy; i++)
            s->error_status_table[i] &= mask;
836
    }
837

838 839 840
    if (end_i == s->mb_num)
        s->error_count = INT_MAX;
    else {
841 842 843
        s->error_status_table[end_xy] &= mask;
        s->error_status_table[end_xy] |= status;
    }
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 853
        if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
            s->error_occurred = 1;
854
            s->error_count = INT_MAX;
855
        }
856
    }
857 858
}

859
void ff_er_frame_end(ERContext *s)
860
{
861
    int *linesize = NULL;
862
    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
863
    int distance;
864 865
    int threshold_part[4] = { 100, 100, 100 };
    int threshold = 50;
866
    int is_intra_likely;
Michael Niedermayer's avatar
Michael Niedermayer committed
867
    int size = s->b8_stride * 2 * s->mb_height;
868 869 870

    /* We do not support ER of field pictures yet,
     * 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 875 876
        s->error_count == 3 * s->mb_width *
                          (s->avctx->skip_top + s->avctx->skip_bottom)) {
        return;
877
    }
878
    linesize = s->cur_pic.f->linesize;
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
        int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
        if (status != 0x7F)
            break;
    }

    if (   mb_x == s->mb_width
        && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
        && (s->avctx->height&16)
        && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)
    ) {
        av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
        return;
    }

894 895 896 897
    if (s->last_pic.f) {
        if (s->last_pic.f->width  != s->cur_pic.f->width  ||
            s->last_pic.f->height != s->cur_pic.f->height ||
            s->last_pic.f->format != s->cur_pic.f->format) {
898
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
899
            memset(&s->last_pic, 0, sizeof(s->last_pic));
900 901
        }
    }
902 903 904 905
    if (s->next_pic.f) {
        if (s->next_pic.f->width  != s->cur_pic.f->width  ||
            s->next_pic.f->height != s->cur_pic.f->height ||
            s->next_pic.f->format != s->cur_pic.f->format) {
906
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
907
            memset(&s->next_pic, 0, sizeof(s->next_pic));
908 909
        }
    }
910

911
    if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");

        for (i = 0; i < 2; i++) {
            s->ref_index_buf[i]  = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
            s->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
            if (!s->ref_index_buf[i] || !s->motion_val_buf[i])
                break;
            s->cur_pic.ref_index[i]  = s->ref_index_buf[i]->data;
            s->cur_pic.motion_val[i] = (int16_t (*)[2])s->motion_val_buf[i]->data + 4;
        }
        if (i < 2) {
            for (i = 0; i < 2; i++) {
                av_buffer_unref(&s->ref_index_buf[i]);
                av_buffer_unref(&s->motion_val_buf[i]);
                s->cur_pic.ref_index[i]  = NULL;
                s->cur_pic.motion_val[i] = NULL;
            }
            return;
        }
931
    }
932

933 934 935 936
    if (s->avctx->debug & FF_DEBUG_ER) {
        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
937 938

                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
939
            }
940
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
941 942
        }
    }
943

944
#if 1
945
    /* handle overlapping slices */
946 947
    for (error_type = 1; error_type <= 3; error_type++) {
        int end_ok = 0;
948

949 950 951
        for (i = s->mb_num - 1; i >= 0; i--) {
            const int mb_xy = s->mb_index2xy[i];
            int error       = s->error_status_table[mb_xy];
952

953 954 955 956
            if (error & (1 << error_type))
                end_ok = 1;
            if (error & (8 << error_type))
                end_ok = 1;
957

958 959
            if (!end_ok)
                s->error_status_table[mb_xy] |= 1 << error_type;
960

961 962
            if (error & VP_START)
                end_ok = 0;
963 964
        }
    }
965 966
#endif
#if 1
967
    /* handle slices with partitions of different length */
968 969
    if (s->partitioned_frame) {
        int end_ok = 0;
970

971 972 973
        for (i = s->mb_num - 1; i >= 0; i--) {
            const int mb_xy = s->mb_index2xy[i];
            int error       = s->error_status_table[mb_xy];
974

975 976 977 978 979 980
            if (error & ER_AC_END)
                end_ok = 0;
            if ((error & ER_MV_END) ||
                (error & ER_DC_END) ||
                (error & ER_AC_ERROR))
                end_ok = 1;
981

982
            if (!end_ok)
983
                s->error_status_table[mb_xy]|= ER_AC_ERROR;
984

985 986
            if (error & VP_START)
                end_ok = 0;
987 988
        }
    }
989
#endif
990
    /* handle missing slices */
991
    if (s->avctx->err_recognition & AV_EF_EXPLODE) {
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
        int end_ok = 1;

        // FIXME + 100 hack
        for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
            const int mb_xy = s->mb_index2xy[i];
            int error1 = s->error_status_table[mb_xy];
            int error2 = s->error_status_table[s->mb_index2xy[i + 1]];

            if (error1 & VP_START)
                end_ok = 1;

            if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
                error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
                ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
                (error1 & ER_MV_END))) {
                // end & uninit
                end_ok = 0;
1009
            }
1010

1011 1012
            if (!end_ok)
                s->error_status_table[mb_xy] |= ER_MB_ERROR;
1013 1014
        }
    }
1015

1016
#if 1
1017
    /* backward mark errors */
1018 1019 1020 1021 1022
    distance = 9999999;
    for (error_type = 1; error_type <= 3; error_type++) {
        for (i = s->mb_num - 1; i >= 0; i--) {
            const int mb_xy = s->mb_index2xy[i];
            int       error = s->error_status_table[mb_xy];
1023

1024
            if (!s->mbskip_table[mb_xy]) // FIXME partition specific
1025
                distance++;
1026 1027 1028 1029 1030 1031 1032 1033 1034
            if (error & (1 << error_type))
                distance = 0;

            if (s->partitioned_frame) {
                if (distance < threshold_part[error_type - 1])
                    s->error_status_table[mb_xy] |= 1 << error_type;
            } else {
                if (distance < threshold)
                    s->error_status_table[mb_xy] |= 1 << error_type;
1035 1036
            }

1037 1038
            if (error & VP_START)
                distance = 9999999;
1039 1040
        }
    }
1041
#endif
1042 1043

    /* forward mark errors */
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
    error = 0;
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
        int old_error   = s->error_status_table[mb_xy];

        if (old_error & VP_START) {
            error = old_error & ER_MB_ERROR;
        } else {
            error |= old_error & ER_MB_ERROR;
            s->error_status_table[mb_xy] |= error;
1054 1055
        }
    }
1056
#if 1
1057
    /* handle not partitioned case */
1058 1059 1060
    if (!s->partitioned_frame) {
        for (i = 0; i < s->mb_num; i++) {
            const int mb_xy = s->mb_index2xy[i];
1061
            int error = s->error_status_table[mb_xy];
1062 1063 1064
            if (error & ER_MB_ERROR)
                error |= ER_MB_ERROR;
            s->error_status_table[mb_xy] = error;
1065 1066
        }
    }
1067
#endif
1068

1069 1070 1071
    dc_error = ac_error = mv_error = 0;
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
1072
        int error = s->error_status_table[mb_xy];
1073 1074 1075 1076 1077 1078
        if (error & ER_DC_ERROR)
            dc_error++;
        if (error & ER_AC_ERROR)
            ac_error++;
        if (error & ER_MV_ERROR)
            mv_error++;
1079
    }
1080
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1081
           dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1082

1083
    is_intra_likely = is_intra_more_likely(s);
1084 1085

    /* set unknown mb-type to most likely */
1086 1087
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
1088
        int error = s->error_status_table[mb_xy];
1089
        if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1090
            continue;
1091

1092
        if (is_intra_likely)
1093
            s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1094
        else
1095
            s->cur_pic.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
1096
    }
1097

1098
    // change inter to intra blocks if no reference frames are available
1099 1100
    if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
        !(s->next_pic.f && s->next_pic.f->data[0]))
1101 1102
        for (i = 0; i < s->mb_num; i++) {
            const int mb_xy = s->mb_index2xy[i];
1103 1104
            if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
                s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1105 1106
        }

1107
    /* handle inter blocks with damaged AC */
1108 1109 1110
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1111 1112
            const int mb_type = s->cur_pic.mb_type[mb_xy];
            const int dir     = !(s->last_pic.f && s->last_pic.f->data[0]);
1113 1114
            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
            int mv_type;
1115

1116
            int error = s->error_status_table[mb_xy];
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126

            if (IS_INTRA(mb_type))
                continue; // intra
            if (error & ER_MV_ERROR)
                continue; // inter with damaged MV
            if (!(error & ER_AC_ERROR))
                continue; // undamaged inter

            if (IS_8X8(mb_type)) {
                int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1127
                int j;
1128
                mv_type = MV_TYPE_8X8;
1129
                for (j = 0; j < 4; j++) {
1130 1131
                    s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
                    s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1132
                }
1133
            } else {
1134
                mv_type     = MV_TYPE_16X16;
1135 1136
                s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
                s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1137
            }
1138

1139 1140
            s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1141 1142 1143 1144
        }
    }

    /* guess MVs */
1145
    if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1146 1147 1148 1149
        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;
                const int mb_xy   = mb_x + mb_y * s->mb_stride;
1150
                const int mb_type = s->cur_pic.mb_type[mb_xy];
1151
                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1152

1153
                int error = s->error_status_table[mb_xy];
1154 1155 1156 1157 1158 1159 1160 1161

                if (IS_INTRA(mb_type))
                    continue;
                if (!(error & ER_MV_ERROR))
                    continue; // inter with undamaged MV
                if (!(error & ER_AC_ERROR))
                    continue; // undamaged inter

1162
                if (!(s->last_pic.f && s->last_pic.f->data[0]))
1163
                    mv_dir &= ~MV_DIR_FORWARD;
1164
                if (!(s->next_pic.f && s->next_pic.f->data[0]))
1165
                    mv_dir &= ~MV_DIR_BACKWARD;
1166 1167 1168 1169

                if (s->pp_time) {
                    int time_pp = s->pp_time;
                    int time_pb = s->pb_time;
1170

1171
                    av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1172
                    ff_thread_await_progress(s->next_pic.tf, mb_y, 0);
1173

1174 1175 1176 1177
                    s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] *  time_pb            / time_pp;
                    s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] *  time_pb            / time_pp;
                    s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
                    s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1178 1179 1180 1181 1182
                } else {
                    s->mv[0][0][0] = 0;
                    s->mv[0][0][1] = 0;
                    s->mv[1][0][0] = 0;
                    s->mv[1][0][1] = 0;
1183
                }
1184

1185 1186
                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
                             mb_x, mb_y, 0, 0);
1187 1188
            }
        }
1189
    } else
1190 1191
        guess_mv(s);

1192 1193
    /* the filters below manipulate raw image, skip them */
    if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb)
1194
        goto ec_clean;
1195
    /* fill DC for inter blocks */
1196 1197
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1198
            int dc, dcu, dcv, y, n;
1199
            int16_t *dc_ptr;
1200
            uint8_t *dest_y, *dest_cb, *dest_cr;
1201
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1202
            const int mb_type = s->cur_pic.mb_type[mb_xy];
1203

1204
            // error = s->error_status_table[mb_xy];
1205

1206 1207 1208 1209
            if (IS_INTRA(mb_type) && s->partitioned_frame)
                continue;
            // if (error & ER_MV_ERROR)
            //     continue; // inter data damaged FIXME is this good?
1210

1211 1212 1213
            dest_y  = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
            dest_cb = s->cur_pic.f->data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
            dest_cr = s->cur_pic.f->data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
1214

1215 1216 1217 1218
            dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
            for (n = 0; n < 4; n++) {
                dc = 0;
                for (y = 0; y < 8; y++) {
1219
                    int x;
1220 1221
                    for (x = 0; x < 8; x++)
                       dc += dest_y[x + (n & 1) * 8 +
1222
                             (y + (n >> 1) * 8) * linesize[0]];
1223
                }
1224
                dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1225 1226
            }

1227 1228
            dcu = dcv = 0;
            for (y = 0; y < 8; y++) {
1229
                int x;
1230
                for (x = 0; x < 8; x++) {
1231 1232
                    dcu += dest_cb[x + y * linesize[1]];
                    dcv += dest_cr[x + y * linesize[2]];
1233 1234
                }
            }
1235 1236
            s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
            s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1237 1238
        }
    }
1239
#if 1
1240
    /* guess DC for damaged blocks */
1241 1242 1243
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1244
#endif
1245

1246
    /* filter luma DC */
1247
    filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1248

1249
#if 1
1250
    /* render DC only intra */
1251 1252
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1253
            uint8_t *dest_y, *dest_cb, *dest_cr;
1254
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1255
            const int mb_type = s->cur_pic.mb_type[mb_xy];
1256

1257
            int error = s->error_status_table[mb_xy];
1258

1259 1260 1261 1262
            if (IS_INTER(mb_type))
                continue;
            if (!(error & ER_AC_ERROR))
                continue; // undamaged
1263

1264 1265 1266
            dest_y  = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
            dest_cb = s->cur_pic.f->data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
            dest_cr = s->cur_pic.f->data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
1267

1268 1269 1270
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
        }
    }
1271
#endif
1272

1273
    if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1274
        /* filter horizontal block boundaries */
1275
        h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1276
                       s->mb_height * 2, linesize[0], 1);
1277
        h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1278
                       s->mb_height, linesize[1], 0);
1279
        h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1280
                       s->mb_height, linesize[2], 0);
1281 1282

        /* filter vertical block boundaries */
1283
        v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1284
                       s->mb_height * 2, linesize[0], 1);
1285
        v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1286
                       s->mb_height, linesize[1], 0);
1287
        v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1288
                       s->mb_height, linesize[2], 0);
1289 1290
    }

Ivan Kalvachev's avatar
Ivan Kalvachev committed
1291
ec_clean:
1292
    /* clean a few tables */
1293 1294 1295
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
        int       error = s->error_status_table[mb_xy];
1296

1297
        if (s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1298 1299
            (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
            s->mbskip_table[mb_xy] = 0;
1300
        }
1301
        s->mbintra_table[mb_xy] = 1;
1302
    }
1303

1304 1305 1306 1307 1308 1309 1310
    for (i = 0; i < 2; i++) {
        av_buffer_unref(&s->ref_index_buf[i]);
        av_buffer_unref(&s->motion_val_buf[i]);
        s->cur_pic.ref_index[i]  = NULL;
        s->cur_pic.motion_val[i] = NULL;
    }

1311 1312 1313
    memset(&s->cur_pic, 0, sizeof(ERPicture));
    memset(&s->last_pic, 0, sizeof(ERPicture));
    memset(&s->next_pic, 0, sizeof(ERPicture));
1314
}