error_resilience.c 49.8 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/atomic.h"
31
#include "libavutil/internal.h"
32
#include "avcodec.h"
33
#include "error_resilience.h"
34
#include "me_cmp.h"
35
#include "mpegutils.h"
36
#include "mpegvideo.h"
37
#include "rectangle.h"
38
#include "thread.h"
39
#include "version.h"
40 41 42 43 44

/**
 * @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
 */
45
static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
46
{
47
    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
48
        av_assert0(s->quarter_sample);
49
        *mv_step = 4;
50
        *stride  = s->mb_width * 4;
51 52 53
    } else {
        *mv_step = 2;
        *stride  = s->b8_stride;
54 55 56
    }
}

57
/**
58
 * Replace the current MB with a flat dc-only version.
59
 */
60
static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
61
                   uint8_t *dest_cr, int mb_x, int mb_y)
62
{
63
    int *linesize = s->cur_pic.f->linesize;
64
    int dc, dcu, dcv, y, i;
65 66 67 68 69 70 71
    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++) {
72
            int x;
73
            for (x = 0; x < 8; x++)
74
                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
75 76
        }
    }
77 78 79 80 81 82 83 84 85 86
    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;
87 88

    if (dest_cr)
89
    for (y = 0; y < 8; y++) {
90
        int x;
91
        for (x = 0; x < 8; x++) {
92 93
            dest_cb[x + y * linesize[1]] = dcu / 8;
            dest_cr[x + y * linesize[2]] = dcv / 8;
94 95 96 97
        }
    }
}

98 99 100
static void filter181(int16_t *data, int width, int height, int stride)
{
    int x, y;
101 102

    /* horizontal filter */
103 104
    for (y = 1; y < height - 1; y++) {
        int prev_dc = data[0 + y * stride];
105

106
        for (x = 1; x < width - 1; x++) {
107
            int dc;
108 109 110 111 112 113
            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;
114 115
        }
    }
116

117
    /* vertical filter */
118 119
    for (x = 1; x < width - 1; x++) {
        int prev_dc = data[x];
120

121
        for (y = 1; y < height - 1; y++) {
122
            int dc;
123

124 125 126 127 128 129
            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;
130 131 132 133 134
        }
    }
}

/**
Diego Biurrun's avatar
Diego Biurrun committed
135
 * guess the dc of blocks which do not have an undamaged dc
136 137
 * @param w     width in 8 pixel blocks
 * @param h     height in 8 pixel blocks
138
 */
139
static void guess_dc(ERContext *s, int16_t *dc, int w,
140 141
                     int h, int stride, int is_luma)
{
142
    int b_x, b_y;
143 144
    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);
145

146 147 148 149 150
    if(!col || !dist) {
        av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
        goto fail;
    }

151 152 153 154 155 156
    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];
157
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
158 159 160 161 162 163 164 165 166 167 168 169
            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];
170
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
171 172 173 174 175 176 177 178 179 180 181 182 183 184
            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];
185
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
186 187 188 189 190 191 192 193 194 195 196 197
            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];
198
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
199 200 201 202 203 204 205 206
            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;
        }
    }
207

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

215
            if (IS_INTER(s->cur_pic.mb_type[mb_index]))
216 217 218
                continue; // inter
            if (!(error & ER_DC_ERROR))
                continue; // dc-ok
219

220 221 222
            weight_sum = 0;
            guess      = 0;
            for (j = 0; j < 4; j++) {
223
                int64_t weight  = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
224
                guess          += weight*(int64_t)col[b_x + b_y*stride][j];
225
                weight_sum     += weight;
226
            }
227 228
            guess = (guess + weight_sum / 2) / weight_sum;
            dc[b_x + b_y * stride] = guess;
229 230
        }
    }
231 232

fail:
233 234
    av_freep(&col);
    av_freep(&dist);
235 236 237 238
}

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

251 252
    for (b_y = 0; b_y < h; b_y++) {
        for (b_x = 0; b_x < w - 1; b_x++) {
253
            int y;
254 255
            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];
256 257
            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]);
258 259 260
            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;
261 262
            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)];
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 289 290 291 292
            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)];
293
                }
294 295 296 297 298
                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)];
299 300 301 302 303 304 305 306
                }
            }
        }
    }
}

/**
 * simple vertical deblocking filter used for error resilience
307 308
 * @param w     width in 8 pixel blocks
 * @param h     height in 8 pixel blocks
309
 */
310
static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
311 312
                           int stride, int is_luma)
{
313
    int b_x, b_y, mvx_stride, mvy_stride;
314
    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
315 316 317
    set_mv_strides(s, &mvx_stride, &mvy_stride);
    mvx_stride >>= is_luma;
    mvy_stride *= mvx_stride;
318

319 320
    for (b_y = 0; b_y < h - 1; b_y++) {
        for (b_x = 0; b_x < w; b_x++) {
321
            int x;
322 323
            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];
324 325
            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]);
326 327 328 329
            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;

330 331
            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];
332

333 334
            if (!(top_damage || bottom_damage))
                continue; // both undamaged
335

336 337 338 339
            if ((!top_intra) && (!bottom_intra) &&
                FFABS(top_mv[0] - bottom_mv[0]) +
                FFABS(top_mv[1] + bottom_mv[1]) < 2)
                continue;
340

341 342
            for (x = 0; x < 8; x++) {
                int a, b, c, d;
343

344 345 346
                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];
347

348 349 350 351
                d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
                d = FFMAX(d, 0);
                if (b < 0)
                    d = -d;
352

353 354
                if (d == 0)
                    continue;
355

356 357
                if (!(top_damage && bottom_damage))
                    d = d * 16 / 9;
358

359 360 361 362 363
                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)];
364
                }
365 366 367 368 369
                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)];
370 371 372 373 374 375
                }
            }
        }
    }
}

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

388 389 390 391 392
    if (s->last_pic.f && s->last_pic.f->data[0])
        mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
    if (s->next_pic.f && s->next_pic.f->data[0])
        mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);

393
    set_mv_strides(s, &mot_step, &mot_stride);
394

395
    num_avail = 0;
396 397
    if (s->last_pic.motion_val[0])
        ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0);
398
    for (i = 0; i < mb_width * mb_height; i++) {
399 400 401
        const int mb_xy = s->mb_index2xy[i];
        int f = 0;
        int error = s->error_status_table[mb_xy];
402

403
        if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
404 405 406
            f = MV_FROZEN; // intra // FIXME check
        if (!(error & ER_MV_ERROR))
            f = MV_FROZEN; // inter with undamaged MV
407

408 409
        fixed[mb_xy] = f;
        if (f == MV_FROZEN)
410
            num_avail++;
411
        else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
412 413 414
            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;
415 416 417
            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];
418
        }
419
    }
420

421 422
    if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
        num_avail <= mb_width / 2) {
423
        for (mb_y = 0; mb_y < mb_height; mb_y++) {
424 425
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                const int mb_xy = mb_x + mb_y * s->mb_stride;
426
                int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
427

428
                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
429 430 431
                    continue;
                if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
                    continue;
432

433 434
                s->mv[0][0][0] = 0;
                s->mv[0][0][1] = 0;
435 436
                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
                             mb_x, mb_y, 0, 0);
437 438 439 440
            }
        }
        return;
    }
441

442
    for (depth = 0; ; depth++) {
443 444
        int changed, pass, none_left;

445 446 447
        none_left = 1;
        changed   = 1;
        for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
448
            int mb_x, mb_y;
449 450 451
            int score_sum = 0;

            changed = 0;
452
            for (mb_y = 0; mb_y < mb_height; mb_y++) {
453 454 455 456 457
                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;
458
                    int j;
459 460 461
                    int best_score         = 256 * 256 * 256 * 64;
                    int best_pred          = 0;
                    const int mot_index    = (mb_x + mb_y * mot_stride) * mot_step;
462
                    int prev_x = 0, prev_y = 0, prev_ref = 0;
463

464 465
                    if ((mb_x ^ mb_y ^ pass) & 1)
                        continue;
466

467 468
                    if (fixed[mb_xy] == MV_FROZEN)
                        continue;
469 470
                    av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
                    av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
471

472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
                    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] =
500
                            s->cur_pic.motion_val[0][mot_index - mot_step][0];
501
                        mv_predictor[pred_count][1] =
502
                            s->cur_pic.motion_val[0][mot_index - mot_step][1];
503
                        ref[pred_count] =
504
                            s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
505 506
                        pred_count++;
                    }
507 508
                    if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                        mv_predictor[pred_count][0] =
509
                            s->cur_pic.motion_val[0][mot_index + mot_step][0];
510
                        mv_predictor[pred_count][1] =
511
                            s->cur_pic.motion_val[0][mot_index + mot_step][1];
512
                        ref[pred_count] =
513
                            s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
514 515
                        pred_count++;
                    }
516 517
                    if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                        mv_predictor[pred_count][0] =
518
                            s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
519
                        mv_predictor[pred_count][1] =
520
                            s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
521
                        ref[pred_count] =
522
                            s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
523 524
                        pred_count++;
                    }
525 526
                    if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
                        mv_predictor[pred_count][0] =
527
                            s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
528
                        mv_predictor[pred_count][1] =
529
                            s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
530
                        ref[pred_count] =
531
                            s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
532 533
                        pred_count++;
                    }
534 535
                    if (pred_count == 0)
                        continue;
536

537 538
                    if (pred_count > 1) {
                        int sum_x = 0, sum_y = 0, sum_r = 0;
539
                        int max_x, max_y, min_x, min_y, max_r, min_r;
540

541 542 543 544 545
                        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])
546
                                goto skip_mean_and_median;
547
                        }
548

549
                        /* mean */
550 551 552
                        mv_predictor[pred_count][0] = sum_x / j;
                        mv_predictor[pred_count][1] = sum_y / j;
                                 ref[pred_count]    = sum_r / j;
553

554
                        /* median */
555 556 557 558 559
                        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;
560
                        }
561 562 563 564 565 566 567
                        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]);
568
                        }
569 570 571 572 573 574 575 576
                        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;
577
                        }
578
                        pred_count += 2;
579
                    }
580

581
skip_mean_and_median:
582 583 584
                    /* zero MV */
                    pred_count++;

585 586 587
                    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];
588

589
                    /* last MV */
590 591 592
                    mv_predictor[pred_count][0] = prev_x;
                    mv_predictor[pred_count][1] = prev_y;
                             ref[pred_count]    = prev_ref;
593 594
                    pred_count++;

595
                    for (j = 0; j < pred_count; j++) {
596
                        int *linesize = s->cur_pic.f->linesize;
597
                        int score = 0;
598
                        uint8_t *src = s->cur_pic.f->data[0] +
599
                                       mb_x * 16 + mb_y * 16 * linesize[0];
600

601
                        s->cur_pic.motion_val[0][mot_index][0] =
602
                            s->mv[0][0][0] = mv_predictor[j][0];
603
                        s->cur_pic.motion_val[0][mot_index][1] =
604
                            s->mv[0][0][1] = mv_predictor[j][1];
605

606 607
                        // predictor intra or otherwise not available
                        if (ref[j] < 0)
608 609
                            continue;

610 611
                        s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
                                     MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
612

613
                        if (mb_x > 0 && fixed[mb_xy - 1]) {
614
                            int k;
615
                            for (k = 0; k < 16; k++)
616 617
                                score += FFABS(src[k * linesize[0] - 1] -
                                               src[k * linesize[0]]);
618
                        }
619
                        if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
620
                            int k;
621
                            for (k = 0; k < 16; k++)
622 623
                                score += FFABS(src[k * linesize[0] + 15] -
                                               src[k * linesize[0] + 16]);
624
                        }
625
                        if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
626
                            int k;
627
                            for (k = 0; k < 16; k++)
628
                                score += FFABS(src[k - linesize[0]] - src[k]);
629
                        }
630
                        if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {
631
                            int k;
632
                            for (k = 0; k < 16; k++)
633 634
                                score += FFABS(src[k + linesize[0] * 15] -
                                               src[k + linesize[0] * 16]);
635
                        }
636

637 638 639
                        if (score <= best_score) { // <= will favor the last MV
                            best_score = score;
                            best_pred  = j;
640 641
                        }
                    }
642 643 644
                    score_sum += best_score;
                    s->mv[0][0][0] = mv_predictor[best_pred][0];
                    s->mv[0][0][1] = mv_predictor[best_pred][1];
645

646 647
                    for (i = 0; i < mot_step; i++)
                        for (j = 0; j < mot_step; j++) {
648 649
                            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];
650
                        }
651

652 653
                    s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
654

655

656 657
                    if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
                        fixed[mb_xy] = MV_CHANGED;
658
                        changed++;
659 660
                    } else
                        fixed[mb_xy] = MV_UNCHANGED;
661 662 663
                }
            }
        }
664

665
        if (none_left)
666
            return;
667

668
        for (i = 0; i < mb_width * mb_height; i++) {
669 670 671
            int mb_xy = s->mb_index2xy[i];
            if (fixed[mb_xy])
                fixed[mb_xy] = MV_FROZEN;
672 673 674
        }
    }
}
675

676
static int is_intra_more_likely(ERContext *s)
677
{
678
    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
679

680
    if (!s->last_pic.f || !s->last_pic.f->data[0])
681
        return 1; // no previous frame available -> use spatial prediction
682

683 684 685
    if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
        return 0;

686 687 688 689 690
    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)))
691 692
            undamaged_count++;
    }
693

694 695
    if (undamaged_count < 5)
        return 0; // almost all MBs damaged -> use temporal prediction
696

697
    // prevent dsp.sad() check, that requires access to the image
698 699
    if (CONFIG_XVMC    &&
        s->avctx->hwaccel && s->avctx->hwaccel->decode_mb &&
700
        s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I)
701
        return 1;
702

703 704
    skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
    is_intra_likely = 0;
705

706 707 708
    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++) {
709
            int error;
710
            const int mb_xy = mb_x + mb_y * s->mb_stride;
711

712 713 714
            error = s->error_status_table[mb_xy];
            if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
                continue; // skip damaged
715 716

            j++;
717 718 719
            // skip a few to speed things up
            if ((j % skip_amount) != 0)
                continue;
720

721 722 723
            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] +
724
                                       mb_x * 16 + mb_y * 16 * linesize[0];
725
                uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
726
                                       mb_x * 16 + mb_y * 16 * linesize[0];
727

728
                if (s->avctx->codec_id == AV_CODEC_ID_H264) {
729 730
                    // FIXME
                } else {
731
                    ff_thread_await_progress(s->last_pic.tf, mb_y, 0);
732
                }
733 734
                is_intra_likely += s->mecc.sad[0](NULL, last_mb_ptr, mb_ptr,
                                                  linesize[0], 16);
735
                // FIXME need await_progress() here
736 737 738
                is_intra_likely -= s->mecc.sad[0](NULL, last_mb_ptr,
                                                  last_mb_ptr + linesize[0] * 16,
                                                  linesize[0], 16);
739
            } else {
740
                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
741 742 743 744 745 746
                   is_intra_likely++;
                else
                   is_intra_likely--;
            }
        }
    }
747
//      av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
748
    return is_intra_likely > 0;
749 750
}

751
void ff_er_frame_start(ERContext *s)
752
{
753
    if (!s->avctx->error_concealment)
754
        return;
755

756 757 758 759 760
    if (!s->mecc_inited) {
        ff_me_cmp_init(&s->mecc, s->avctx);
        s->mecc_inited = 1;
    }

761 762 763
    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;
764
    s->error_occurred = 0;
765 766
}

767 768
static int er_supported(ERContext *s)
{
769
    if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice           ||
770
#if FF_API_CAP_VDPAU
771
       s->avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU          ||
772
#endif
773 774
       !s->cur_pic.f                                                  ||
       s->cur_pic.field_picture
775 776 777 778 779
    )
        return 0;
    return 1;
}

780
/**
781
 * Add a slice.
782 783 784 785
 * @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
786
 */
787
void ff_er_add_slice(ERContext *s, int startx, int starty,
788 789 790 791 792 793 794 795
                     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;

796
    if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice)
797 798
        return;

799 800 801
    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
802 803
        return;
    }
804

805
    if (!s->avctx->error_concealment)
806
        return;
807 808

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

822
    if (status & ER_MB_ERROR) {
823
        s->error_occurred = 1;
824
        avpriv_atomic_int_set(&s->error_count, INT_MAX);
825
    }
826

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

836
    if (end_i == s->mb_num)
837
        avpriv_atomic_int_set(&s->error_count, INT_MAX);
838
    else {
839 840 841
        s->error_status_table[end_xy] &= mask;
        s->error_status_table[end_xy] |= status;
    }
842

843
    s->error_status_table[start_xy] |= VP_START;
844

845
    if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
846
        er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
847
        int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
848

849
        prev_status &= ~ VP_START;
850 851
        if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
            s->error_occurred = 1;
852
            avpriv_atomic_int_set(&s->error_count, INT_MAX);
853
        }
854
    }
855 856
}

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

    /* We do not support ER of field pictures yet,
     * though it should not crash if enabled. */
869
    if (!s->avctx->error_concealment || s->error_count == 0            ||
870
        s->avctx->lowres                                               ||
871
        !er_supported(s)                                               ||
872 873 874
        s->error_count == 3 * s->mb_width *
                          (s->avctx->skip_top + s->avctx->skip_bottom)) {
        return;
875
    }
876
    linesize = s->cur_pic.f->linesize;
877 878 879 880 881 882 883 884
    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
885
        && (FFALIGN(s->avctx->height, 16)&16)
886 887 888 889 890 891
        && 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;
    }

892 893 894 895
    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) {
896
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
897
            memset(&s->last_pic, 0, sizeof(s->last_pic));
898 899
        }
    }
900 901 902 903
    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) {
904
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
905
            memset(&s->next_pic, 0, sizeof(s->next_pic));
906 907
        }
    }
908

909
    if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
        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;
        }
929
    }
930

931 932 933 934
    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];
935 936

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

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

947 948 949
        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];
950

951 952 953 954
            if (error & (1 << error_type))
                end_ok = 1;
            if (error & (8 << error_type))
                end_ok = 1;
955

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

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

969 970 971
        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];
972

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

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

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

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

1014
#if 1
1015
    /* backward mark errors */
1016 1017 1018 1019 1020
    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];
1021

1022
            if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1023
                distance++;
1024 1025 1026 1027 1028 1029 1030 1031 1032
            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;
1033 1034
            }

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

    /* forward mark errors */
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
    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;
1052 1053
        }
    }
1054
#if 1
1055
    /* handle not partitioned case */
1056 1057 1058
    if (!s->partitioned_frame) {
        for (i = 0; i < s->mb_num; i++) {
            const int mb_xy = s->mb_index2xy[i];
1059
            int error = s->error_status_table[mb_xy];
1060 1061 1062
            if (error & ER_MB_ERROR)
                error |= ER_MB_ERROR;
            s->error_status_table[mb_xy] = error;
1063 1064
        }
    }
1065
#endif
1066

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

1081
    is_intra_likely = is_intra_more_likely(s);
1082 1083

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

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

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

1105
    /* handle inter blocks with damaged AC */
1106 1107 1108
    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;
1109 1110
            const int mb_type = s->cur_pic.mb_type[mb_xy];
            const int dir     = !(s->last_pic.f && s->last_pic.f->data[0]);
1111 1112
            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
            int mv_type;
1113

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

            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;
1125
                int j;
1126
                mv_type = MV_TYPE_8X8;
1127
                for (j = 0; j < 4; j++) {
1128 1129
                    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];
1130
                }
1131
            } else {
1132
                mv_type     = MV_TYPE_16X16;
1133 1134
                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];
1135
            }
1136

1137
            s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1138
                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1139 1140 1141 1142
        }
    }

    /* guess MVs */
1143
    if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1144 1145 1146 1147
        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;
1148
                const int mb_type = s->cur_pic.mb_type[mb_xy];
1149
                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1150

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

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

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

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

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

1172 1173 1174 1175
                    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;
1176 1177 1178 1179 1180
                } 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;
1181
                }
1182

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

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

1202
            // error = s->error_status_table[mb_xy];
1203

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

1209 1210 1211
            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];
1212

1213 1214 1215 1216
            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++) {
1217
                    int x;
1218 1219
                    for (x = 0; x < 8; x++)
                       dc += dest_y[x + (n & 1) * 8 +
1220
                             (y + (n >> 1) * 8) * linesize[0]];
1221
                }
1222
                dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1223 1224
            }

1225 1226 1227
            if (!s->cur_pic.f->data[2])
                continue;

1228 1229
            dcu = dcv = 0;
            for (y = 0; y < 8; y++) {
1230
                int x;
1231
                for (x = 0; x < 8; x++) {
1232 1233
                    dcu += dest_cb[x + y * linesize[1]];
                    dcv += dest_cr[x + y * linesize[2]];
1234 1235
                }
            }
1236 1237
            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;
1238 1239
        }
    }
1240
#if 1
1241
    /* guess DC for damaged blocks */
1242 1243 1244
    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);
1245
#endif
1246

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

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

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

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

1265 1266 1267
            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];
1268 1269
            if (!s->cur_pic.f->data[2])
                dest_cb = dest_cr = NULL;
1270

1271 1272 1273
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
        }
    }
1274
#endif
1275

1276
    if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1277
        /* filter horizontal block boundaries */
1278
        h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1279
                       s->mb_height * 2, linesize[0], 1);
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 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294

        if (s->cur_pic.f->data[2]) {
            h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
                        s->mb_height, linesize[1], 0);
            h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
                        s->mb_height, linesize[2], 0);
            v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
                        s->mb_height, linesize[1], 0);
            v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
                        s->mb_height, linesize[2], 0);
        }
1295 1296
    }

Ivan Kalvachev's avatar
Ivan Kalvachev committed
1297
ec_clean:
1298
    /* clean a few tables */
1299 1300 1301
    for (i = 0; i < s->mb_num; i++) {
        const int mb_xy = s->mb_index2xy[i];
        int       error = s->error_status_table[mb_xy];
1302

1303
        if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1304 1305
            (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
            s->mbskip_table[mb_xy] = 0;
1306
        }
1307 1308
        if (s->mbintra_table)
            s->mbintra_table[mb_xy] = 1;
1309
    }
1310

1311 1312 1313 1314 1315 1316 1317
    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;
    }

1318 1319 1320
    memset(&s->cur_pic, 0, sizeof(ERPicture));
    memset(&s->last_pic, 0, sizeof(ERPicture));
    memset(&s->next_pic, 0, sizeof(ERPicture));
1321
}