vp8.c 63 KB
Newer Older
David Conrad's avatar
David Conrad committed
1 2 3 4 5
/**
 * VP8 compatible video decoder
 *
 * Copyright (C) 2010 David Conrad
 * Copyright (C) 2010 Ronald S. Bultje
6
 * Copyright (C) 2010 Jason Garrett-Glaser
David Conrad's avatar
David Conrad committed
7
 *
8
 * This file is part of Libav.
David Conrad's avatar
David Conrad committed
9
 *
10
 * Libav is free software; you can redistribute it and/or
David Conrad's avatar
David Conrad committed
11 12 13 14
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
15
 * Libav is distributed in the hope that it will be useful,
David Conrad's avatar
David Conrad committed
16 17 18 19 20
 * 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
21
 * License along with Libav; if not, write to the Free Software
David Conrad's avatar
David Conrad committed
22 23 24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

25
#include "libavutil/imgutils.h"
David Conrad's avatar
David Conrad committed
26
#include "avcodec.h"
27
#include "vp8.h"
David Conrad's avatar
David Conrad committed
28 29
#include "vp8data.h"
#include "rectangle.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
30
#include "thread.h"
David Conrad's avatar
David Conrad committed
31

32 33 34 35
#if ARCH_ARM
#   include "arm/vp8.h"
#endif

David Conrad's avatar
David Conrad committed
36 37 38 39 40
static void vp8_decode_flush(AVCodecContext *avctx)
{
    VP8Context *s = avctx->priv_data;
    int i;

Ronald S. Bultje's avatar
Ronald S. Bultje committed
41 42 43 44 45
    if (!avctx->is_copy) {
        for (i = 0; i < 5; i++)
            if (s->frames[i].data[0])
                ff_thread_release_buffer(avctx, &s->frames[i]);
    }
David Conrad's avatar
David Conrad committed
46 47 48
    memset(s->framep, 0, sizeof(s->framep));

    av_freep(&s->macroblocks_base);
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
49
    av_freep(&s->filter_strength);
50
    av_freep(&s->intra4x4_pred_mode_top);
David Conrad's avatar
David Conrad committed
51 52
    av_freep(&s->top_nnz);
    av_freep(&s->edge_emu_buffer);
53
    av_freep(&s->top_border);
54
    av_freep(&s->segmentation_map);
David Conrad's avatar
David Conrad committed
55 56 57 58 59 60

    s->macroblocks        = NULL;
}

static int update_dimensions(VP8Context *s, int width, int height)
{
Ronald S. Bultje's avatar
Ronald S. Bultje committed
61 62 63 64
    if (width  != s->avctx->width ||
        height != s->avctx->height) {
        if (av_image_check_size(width, height, 0, s->avctx))
            return AVERROR_INVALIDDATA;
David Conrad's avatar
David Conrad committed
65

Ronald S. Bultje's avatar
Ronald S. Bultje committed
66
        vp8_decode_flush(s->avctx);
David Conrad's avatar
David Conrad committed
67

Ronald S. Bultje's avatar
Ronald S. Bultje committed
68 69
        avcodec_set_dimensions(s->avctx, width, height);
    }
David Conrad's avatar
David Conrad committed
70 71 72 73

    s->mb_width  = (s->avctx->coded_width +15) / 16;
    s->mb_height = (s->avctx->coded_height+15) / 16;

Pascal Massimino's avatar
Pascal Massimino committed
74 75
    s->macroblocks_base        = av_mallocz((s->mb_width+s->mb_height*2+1)*sizeof(*s->macroblocks));
    s->filter_strength         = av_mallocz(s->mb_width*sizeof(*s->filter_strength));
76
    s->intra4x4_pred_mode_top  = av_mallocz(s->mb_width*4);
David Conrad's avatar
David Conrad committed
77
    s->top_nnz                 = av_mallocz(s->mb_width*sizeof(*s->top_nnz));
78
    s->top_border              = av_mallocz((s->mb_width+1)*sizeof(*s->top_border));
Pascal Massimino's avatar
Pascal Massimino committed
79
    s->segmentation_map        = av_mallocz(s->mb_width*s->mb_height);
David Conrad's avatar
David Conrad committed
80

81
    if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_top ||
82
        !s->top_nnz || !s->top_border || !s->segmentation_map)
David Conrad's avatar
David Conrad committed
83 84
        return AVERROR(ENOMEM);

85
    s->macroblocks        = s->macroblocks_base + 1;
David Conrad's avatar
David Conrad committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

    return 0;
}

static void parse_segment_info(VP8Context *s)
{
    VP56RangeCoder *c = &s->c;
    int i;

    s->segmentation.update_map = vp8_rac_get(c);

    if (vp8_rac_get(c)) { // update segment feature data
        s->segmentation.absolute_vals = vp8_rac_get(c);

        for (i = 0; i < 4; i++)
            s->segmentation.base_quant[i]   = vp8_rac_get_sint(c, 7);

        for (i = 0; i < 4; i++)
            s->segmentation.filter_level[i] = vp8_rac_get_sint(c, 6);
    }
    if (s->segmentation.update_map)
        for (i = 0; i < 3; i++)
            s->prob->segmentid[i] = vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
}

static void update_lf_deltas(VP8Context *s)
{
    VP56RangeCoder *c = &s->c;
    int i;

    for (i = 0; i < 4; i++)
        s->lf_delta.ref[i]  = vp8_rac_get_sint(c, 6);

119
    for (i = MODE_I4x4; i <= VP8_MVMODE_SPLIT; i++)
David Conrad's avatar
David Conrad committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
        s->lf_delta.mode[i] = vp8_rac_get_sint(c, 6);
}

static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
{
    const uint8_t *sizes = buf;
    int i;

    s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);

    buf      += 3*(s->num_coeff_partitions-1);
    buf_size -= 3*(s->num_coeff_partitions-1);
    if (buf_size < 0)
        return -1;

    for (i = 0; i < s->num_coeff_partitions-1; i++) {
136
        int size = AV_RL24(sizes + 3*i);
David Conrad's avatar
David Conrad committed
137 138 139
        if (buf_size - size < 0)
            return -1;

140
        ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
David Conrad's avatar
David Conrad committed
141 142 143
        buf      += size;
        buf_size -= size;
    }
144
    ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
David Conrad's avatar
David Conrad committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

    return 0;
}

static void get_quants(VP8Context *s)
{
    VP56RangeCoder *c = &s->c;
    int i, base_qi;

    int yac_qi     = vp8_rac_get_uint(c, 7);
    int ydc_delta  = vp8_rac_get_sint(c, 4);
    int y2dc_delta = vp8_rac_get_sint(c, 4);
    int y2ac_delta = vp8_rac_get_sint(c, 4);
    int uvdc_delta = vp8_rac_get_sint(c, 4);
    int uvac_delta = vp8_rac_get_sint(c, 4);

    for (i = 0; i < 4; i++) {
        if (s->segmentation.enabled) {
            base_qi = s->segmentation.base_quant[i];
            if (!s->segmentation.absolute_vals)
                base_qi += yac_qi;
        } else
            base_qi = yac_qi;

169 170 171 172 173 174
        s->qmat[i].luma_qmul[0]    =       vp8_dc_qlookup[av_clip_uintp2(base_qi + ydc_delta , 7)];
        s->qmat[i].luma_qmul[1]    =       vp8_ac_qlookup[av_clip_uintp2(base_qi             , 7)];
        s->qmat[i].luma_dc_qmul[0] =   2 * vp8_dc_qlookup[av_clip_uintp2(base_qi + y2dc_delta, 7)];
        s->qmat[i].luma_dc_qmul[1] = 155 * vp8_ac_qlookup[av_clip_uintp2(base_qi + y2ac_delta, 7)] / 100;
        s->qmat[i].chroma_qmul[0]  =       vp8_dc_qlookup[av_clip_uintp2(base_qi + uvdc_delta, 7)];
        s->qmat[i].chroma_qmul[1]  =       vp8_ac_qlookup[av_clip_uintp2(base_qi + uvac_delta, 7)];
175 176 177

        s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
        s->qmat[i].chroma_qmul[0]  = FFMIN(s->qmat[i].chroma_qmul[0], 132);
David Conrad's avatar
David Conrad committed
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    }
}

/**
 * Determine which buffers golden and altref should be updated with after this frame.
 * The spec isn't clear here, so I'm going by my understanding of what libvpx does
 *
 * Intra frames update all 3 references
 * Inter frames update VP56_FRAME_PREVIOUS if the update_last flag is set
 * If the update (golden|altref) flag is set, it's updated with the current frame
 *      if update_last is set, and VP56_FRAME_PREVIOUS otherwise.
 * If the flag is not set, the number read means:
 *      0: no update
 *      1: VP56_FRAME_PREVIOUS
 *      2: update golden with altref, or update altref with golden
 */
static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
{
    VP56RangeCoder *c = &s->c;

    if (update)
        return VP56_FRAME_CURRENT;

    switch (vp8_rac_get_uint(c, 2)) {
    case 1:
        return VP56_FRAME_PREVIOUS;
    case 2:
        return (ref == VP56_FRAME_GOLDEN) ? VP56_FRAME_GOLDEN2 : VP56_FRAME_GOLDEN;
    }
    return VP56_FRAME_NONE;
}

static void update_refs(VP8Context *s)
{
    VP56RangeCoder *c = &s->c;

    int update_golden = vp8_rac_get(c);
    int update_altref = vp8_rac_get(c);

    s->update_golden = ref_to_update(s, update_golden, VP56_FRAME_GOLDEN);
    s->update_altref = ref_to_update(s, update_altref, VP56_FRAME_GOLDEN2);
}

static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
{
    VP56RangeCoder *c = &s->c;
224
    int header_size, hscale, vscale, i, j, k, l, m, ret;
David Conrad's avatar
David Conrad committed
225 226 227 228 229 230
    int width  = s->avctx->width;
    int height = s->avctx->height;

    s->keyframe  = !(buf[0] & 1);
    s->profile   =  (buf[0]>>1) & 7;
    s->invisible = !(buf[0] & 0x10);
231
    header_size  = AV_RL24(buf) >> 5;
David Conrad's avatar
David Conrad committed
232 233 234
    buf      += 3;
    buf_size -= 3;

David Conrad's avatar
David Conrad committed
235 236 237 238 239 240 241
    if (s->profile > 3)
        av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);

    if (!s->profile)
        memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
    else    // profile 1-3 use bilinear, 4+ aren't defined so whatever
        memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab, sizeof(s->put_pixels_tab));
David Conrad's avatar
David Conrad committed
242 243 244 245 246 247 248

    if (header_size > buf_size - 7*s->keyframe) {
        av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
        return AVERROR_INVALIDDATA;
    }

    if (s->keyframe) {
249 250
        if (AV_RL24(buf) != 0x2a019d) {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid start code 0x%x\n", AV_RL24(buf));
David Conrad's avatar
David Conrad committed
251 252 253 254 255 256 257 258 259
            return AVERROR_INVALIDDATA;
        }
        width  = AV_RL16(buf+3) & 0x3fff;
        height = AV_RL16(buf+5) & 0x3fff;
        hscale = buf[4] >> 6;
        vscale = buf[6] >> 6;
        buf      += 7;
        buf_size -= 7;

260 261 262
        if (hscale || vscale)
            av_log_missing_feature(s->avctx, "Upscaling", 1);

David Conrad's avatar
David Conrad committed
263
        s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
264 265 266 267
        for (i = 0; i < 4; i++)
            for (j = 0; j < 16; j++)
                memcpy(s->prob->token[i][j], vp8_token_default_probs[i][vp8_coeff_band[j]],
                       sizeof(s->prob->token[i][j]));
David Conrad's avatar
David Conrad committed
268 269 270 271 272 273 274 275 276 277 278 279
        memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter, sizeof(s->prob->pred16x16));
        memcpy(s->prob->pred8x8c , vp8_pred8x8c_prob_inter , sizeof(s->prob->pred8x8c));
        memcpy(s->prob->mvc      , vp8_mv_default_prob     , sizeof(s->prob->mvc));
        memset(&s->segmentation, 0, sizeof(s->segmentation));
    }

    if (!s->macroblocks_base || /* first frame */
        width != s->avctx->width || height != s->avctx->height) {
        if ((ret = update_dimensions(s, width, height) < 0))
            return ret;
    }

280
    ff_vp56_init_range_decoder(c, buf, header_size);
David Conrad's avatar
David Conrad committed
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
    buf      += header_size;
    buf_size -= header_size;

    if (s->keyframe) {
        if (vp8_rac_get(c))
            av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
        vp8_rac_get(c); // whether we can skip clamping in dsp functions
    }

    if ((s->segmentation.enabled = vp8_rac_get(c)))
        parse_segment_info(s);
    else
        s->segmentation.update_map = 0; // FIXME: move this to some init function?

    s->filter.simple    = vp8_rac_get(c);
    s->filter.level     = vp8_rac_get_uint(c, 6);
    s->filter.sharpness = vp8_rac_get_uint(c, 3);

    if ((s->lf_delta.enabled = vp8_rac_get(c)))
        if (vp8_rac_get(c))
            update_lf_deltas(s);

    if (setup_partitions(s, buf, buf_size)) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
        return AVERROR_INVALIDDATA;
    }

    get_quants(s);

    if (!s->keyframe) {
        update_refs(s);
        s->sign_bias[VP56_FRAME_GOLDEN]               = vp8_rac_get(c);
        s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
    }

    // if we aren't saving this frame's probabilities for future frames,
    // make a copy of the current probabilities
    if (!(s->update_probabilities = vp8_rac_get(c)))
        s->prob[1] = s->prob[0];

    s->update_last = s->keyframe || vp8_rac_get(c);

    for (i = 0; i < 4; i++)
        for (j = 0; j < 8; j++)
            for (k = 0; k < 3; k++)
                for (l = 0; l < NUM_DCT_TOKENS-1; l++)
327 328
                    if (vp56_rac_get_prob_branchy(c, vp8_token_update_probs[i][j][k][l])) {
                        int prob = vp8_rac_get_uint(c, 8);
329 330
                        for (m = 0; vp8_coeff_band_indexes[j][m] >= 0; m++)
                            s->prob->token[i][vp8_coeff_band_indexes[j][m]][k][l] = prob;
331
                    }
David Conrad's avatar
David Conrad committed
332 333

    if ((s->mbskip_enabled = vp8_rac_get(c)))
334
        s->prob->mbskip = vp8_rac_get_uint(c, 8);
David Conrad's avatar
David Conrad committed
335 336

    if (!s->keyframe) {
337 338 339
        s->prob->intra  = vp8_rac_get_uint(c, 8);
        s->prob->last   = vp8_rac_get_uint(c, 8);
        s->prob->golden = vp8_rac_get_uint(c, 8);
David Conrad's avatar
David Conrad committed
340 341 342 343 344 345 346 347 348 349 350

        if (vp8_rac_get(c))
            for (i = 0; i < 4; i++)
                s->prob->pred16x16[i] = vp8_rac_get_uint(c, 8);
        if (vp8_rac_get(c))
            for (i = 0; i < 3; i++)
                s->prob->pred8x8c[i]  = vp8_rac_get_uint(c, 8);

        // 17.2 MV probability update
        for (i = 0; i < 2; i++)
            for (j = 0; j < 19; j++)
351
                if (vp56_rac_get_prob_branchy(c, vp8_mv_update_prob[i][j]))
David Conrad's avatar
David Conrad committed
352 353 354 355 356 357
                    s->prob->mvc[i][j] = vp8_rac_get_nn(c);
    }

    return 0;
}

Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
358
static av_always_inline void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)
David Conrad's avatar
David Conrad committed
359
{
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
360 361
    dst->x = av_clip(src->x, s->mv_min.x, s->mv_max.x);
    dst->y = av_clip(src->y, s->mv_min.y, s->mv_max.y);
David Conrad's avatar
David Conrad committed
362 363 364 365 366 367 368
}

/**
 * Motion vector coding, 17.1.
 */
static int read_mv_component(VP56RangeCoder *c, const uint8_t *p)
{
369
    int bit, x = 0;
David Conrad's avatar
David Conrad committed
370

371
    if (vp56_rac_get_prob_branchy(c, p[0])) {
David Conrad's avatar
David Conrad committed
372 373 374 375 376 377 378 379
        int i;

        for (i = 0; i < 3; i++)
            x += vp56_rac_get_prob(c, p[9 + i]) << i;
        for (i = 9; i > 3; i--)
            x += vp56_rac_get_prob(c, p[9 + i]) << i;
        if (!(x & 0xFFF0) || vp56_rac_get_prob(c, p[12]))
            x += 8;
380 381 382 383 384 385 386 387 388 389 390
    } else {
        // small_mvtree
        const uint8_t *ps = p+2;
        bit = vp56_rac_get_prob(c, *ps);
        ps += 1 + 3*bit;
        x  += 4*bit;
        bit = vp56_rac_get_prob(c, *ps);
        ps += 1 + bit;
        x  += 2*bit;
        x  += vp56_rac_get_prob(c, *ps);
    }
David Conrad's avatar
David Conrad committed
391 392 393 394

    return (x && vp56_rac_get_prob(c, p[1])) ? -x : x;
}

395 396
static av_always_inline
const uint8_t *get_submv_prob(uint32_t left, uint32_t top)
David Conrad's avatar
David Conrad committed
397
{
398 399 400
    if (left == top)
        return vp8_submv_prob[4-!!left];
    if (!top)
David Conrad's avatar
David Conrad committed
401
        return vp8_submv_prob[2];
402
    return vp8_submv_prob[1-!!left];
David Conrad's avatar
David Conrad committed
403 404 405 406
}

/**
 * Split motion vector prediction, 16.4.
407
 * @returns the number of motion vectors parsed (2, 4 or 16)
David Conrad's avatar
David Conrad committed
408
 */
409 410
static av_always_inline
int decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb)
David Conrad's avatar
David Conrad committed
411
{
412 413
    int part_idx;
    int n, num;
414
    VP8Macroblock *top_mb  = &mb[2];
415 416 417
    VP8Macroblock *left_mb = &mb[-1];
    const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning],
                  *mbsplits_top = vp8_mbsplits[top_mb->partitioning],
418
                  *mbsplits_cur, *firstidx;
419 420 421
    VP56mv *top_mv  = top_mb->bmv;
    VP56mv *left_mv = left_mb->bmv;
    VP56mv *cur_mv  = mb->bmv;
David Conrad's avatar
David Conrad committed
422

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
    if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[0])) {
        if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[1])) {
            part_idx = VP8_SPLITMVMODE_16x8 + vp56_rac_get_prob(c, vp8_mbsplit_prob[2]);
        } else {
            part_idx = VP8_SPLITMVMODE_8x8;
        }
    } else {
        part_idx = VP8_SPLITMVMODE_4x4;
    }

    num = vp8_mbsplit_count[part_idx];
    mbsplits_cur = vp8_mbsplits[part_idx],
    firstidx = vp8_mbfirstidx[part_idx];
    mb->partitioning = part_idx;

David Conrad's avatar
David Conrad committed
438
    for (n = 0; n < num; n++) {
439
        int k = firstidx[n];
440
        uint32_t left, above;
441 442
        const uint8_t *submv_prob;

443 444 445 446 447 448 449 450
        if (!(k & 3))
            left = AV_RN32A(&left_mv[mbsplits_left[k + 3]]);
        else
            left  = AV_RN32A(&cur_mv[mbsplits_cur[k - 1]]);
        if (k <= 3)
            above = AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
        else
            above = AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
451 452

        submv_prob = get_submv_prob(left, above);
David Conrad's avatar
David Conrad committed
453

454 455 456 457 458 459 460 461 462 463 464 465
        if (vp56_rac_get_prob_branchy(c, submv_prob[0])) {
            if (vp56_rac_get_prob_branchy(c, submv_prob[1])) {
                if (vp56_rac_get_prob_branchy(c, submv_prob[2])) {
                    mb->bmv[n].y = mb->mv.y + read_mv_component(c, s->prob->mvc[0]);
                    mb->bmv[n].x = mb->mv.x + read_mv_component(c, s->prob->mvc[1]);
                } else {
                    AV_ZERO32(&mb->bmv[n]);
                }
            } else {
                AV_WN32A(&mb->bmv[n], above);
            }
        } else {
466
            AV_WN32A(&mb->bmv[n], left);
David Conrad's avatar
David Conrad committed
467 468
        }
    }
469 470

    return num;
David Conrad's avatar
David Conrad committed
471 472
}

473 474 475 476 477 478 479
static av_always_inline
void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y)
{
    VP8Macroblock *mb_edge[3] = { mb + 2 /* top */,
                                  mb - 1 /* left */,
                                  mb + 1 /* top-left */ };
    enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
480
    enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
481 482
    int idx = CNT_ZERO;
    int cur_sign_bias = s->sign_bias[mb->ref_frame];
483
    int8_t *sign_bias = s->sign_bias;
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
    VP56mv near_mv[4];
    uint8_t cnt[4] = { 0 };
    VP56RangeCoder *c = &s->c;

    AV_ZERO32(&near_mv[0]);
    AV_ZERO32(&near_mv[1]);

    /* Process MB on top, left and top-left */
    #define MV_EDGE_CHECK(n)\
    {\
        VP8Macroblock *edge = mb_edge[n];\
        int edge_ref = edge->ref_frame;\
        if (edge_ref != VP56_FRAME_CURRENT) {\
            uint32_t mv = AV_RN32A(&edge->mv);\
            if (mv) {\
                if (cur_sign_bias != sign_bias[edge_ref]) {\
                    /* SWAR negate of the values in mv. */\
                    mv = ~mv;\
                    mv = ((mv&0x7fff7fff) + 0x00010001) ^ (mv&0x80008000);\
                }\
                if (!n || mv != AV_RN32A(&near_mv[idx]))\
                    AV_WN32A(&near_mv[++idx], mv);\
                cnt[idx]      += 1 + (n != 2);\
            } else\
                cnt[CNT_ZERO] += 1 + (n != 2);\
        }\
    }

    MV_EDGE_CHECK(0)
    MV_EDGE_CHECK(1)
    MV_EDGE_CHECK(2)

    mb->partitioning = VP8_SPLITMVMODE_NONE;
    if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_ZERO]][0])) {
        mb->mode = VP8_MVMODE_MV;

        /* If we have three distinct MVs, merge first and last if they're the same */
521
        if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) == AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
522 523 524 525 526 527 528 529 530 531 532 533
            cnt[CNT_NEAREST] += 1;

        /* Swap near and nearest if necessary */
        if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
            FFSWAP(uint8_t,     cnt[CNT_NEAREST],     cnt[CNT_NEAR]);
            FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
        }

        if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
            if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {

                /* Choose the best mv out of 0,0 and the nearest mv */
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
534
                clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
535 536 537
                cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode    == VP8_MVMODE_SPLIT) +
                                    (mb_edge[VP8_EDGE_TOP]->mode     == VP8_MVMODE_SPLIT)) * 2 +
                                    (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
538 539 540 541 542 543 544 545 546 547

                if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) {
                    mb->mode = VP8_MVMODE_SPLIT;
                    mb->mv = mb->bmv[decode_splitmvs(s, c, mb) - 1];
                } else {
                    mb->mv.y += read_mv_component(c, s->prob->mvc[0]);
                    mb->mv.x += read_mv_component(c, s->prob->mvc[1]);
                    mb->bmv[0] = mb->mv;
                }
            } else {
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
548
                clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);
549 550 551
                mb->bmv[0] = mb->mv;
            }
        } else {
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
552
            clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);
553 554 555 556 557 558 559 560 561
            mb->bmv[0] = mb->mv;
        }
    } else {
        mb->mode = VP8_MVMODE_ZERO;
        AV_ZERO32(&mb->mv);
        mb->bmv[0] = mb->mv;
    }
}

562
static av_always_inline
563 564
void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c,
                           int mb_x, int keyframe)
David Conrad's avatar
David Conrad committed
565
{
566
    uint8_t *intra4x4 = s->intra4x4_pred_mode_mb;
567
    if (keyframe) {
568 569 570
        int x, y;
        uint8_t* const top = s->intra4x4_pred_mode_top + 4 * mb_x;
        uint8_t* const left = s->intra4x4_pred_mode_left;
571 572
        for (y = 0; y < 4; y++) {
            for (x = 0; x < 4; x++) {
573 574 575 576 577
                const uint8_t *ctx;
                ctx = vp8_pred4x4_prob_intra[top[x]][left[y]];
                *intra4x4 = vp8_rac_get_tree(c, vp8_pred4x4_tree, ctx);
                left[y] = top[x] = *intra4x4;
                intra4x4++;
David Conrad's avatar
David Conrad committed
578 579
            }
        }
580
    } else {
581
        int i;
582 583
        for (i = 0; i < 16; i++)
            intra4x4[i] = vp8_rac_get_tree(c, vp8_pred4x4_tree, vp8_pred4x4_prob_inter);
David Conrad's avatar
David Conrad committed
584 585 586
    }
}

587
static av_always_inline
Ronald S. Bultje's avatar
Ronald S. Bultje committed
588
void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref)
David Conrad's avatar
David Conrad committed
589 590 591 592
{
    VP56RangeCoder *c = &s->c;

    if (s->segmentation.update_map)
593
        *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
594 595
    else
        *segment = ref ? *ref : *segment;
596
    s->segment = *segment;
David Conrad's avatar
David Conrad committed
597

598
    mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
David Conrad's avatar
David Conrad committed
599 600 601 602 603

    if (s->keyframe) {
        mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra, vp8_pred16x16_prob_intra);

        if (mb->mode == MODE_I4x4) {
604 605 606 607 608 609
            decode_intra4x4_modes(s, c, mb_x, 1);
        } else {
            const uint32_t modes = vp8_pred4x4_mode[mb->mode] * 0x01010101u;
            AV_WN32A(s->intra4x4_pred_mode_top + 4 * mb_x, modes);
            AV_WN32A(s->intra4x4_pred_mode_left, modes);
        }
David Conrad's avatar
David Conrad committed
610 611 612

        s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, vp8_pred8x8c_prob_intra);
        mb->ref_frame = VP56_FRAME_CURRENT;
613
    } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {
David Conrad's avatar
David Conrad committed
614
        // inter MB, 16.2
615 616
        if (vp56_rac_get_prob_branchy(c, s->prob->last))
            mb->ref_frame = vp56_rac_get_prob(c, s->prob->golden) ?
David Conrad's avatar
David Conrad committed
617 618 619
                VP56_FRAME_GOLDEN2 /* altref */ : VP56_FRAME_GOLDEN;
        else
            mb->ref_frame = VP56_FRAME_PREVIOUS;
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
620
        s->ref_count[mb->ref_frame-1]++;
David Conrad's avatar
David Conrad committed
621 622

        // motion vectors, 16.3
623
        decode_mvs(s, mb, mb_x, mb_y);
David Conrad's avatar
David Conrad committed
624 625 626 627
    } else {
        // intra MB, 16.1
        mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);

628
        if (mb->mode == MODE_I4x4)
629
            decode_intra4x4_modes(s, c, mb_x, 0);
David Conrad's avatar
David Conrad committed
630 631 632

        s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, s->prob->pred8x8c);
        mb->ref_frame = VP56_FRAME_CURRENT;
633
        mb->partitioning = VP8_SPLITMVMODE_NONE;
634
        AV_ZERO32(&mb->bmv[0]);
David Conrad's avatar
David Conrad committed
635 636 637
    }
}

638
#ifndef decode_block_coeffs_internal
David Conrad's avatar
David Conrad committed
639
/**
640 641 642
 * @param c arithmetic bitstream reader context
 * @param block destination for block coefficients
 * @param probs probabilities to use when reading trees from the bitstream
David Conrad's avatar
David Conrad committed
643 644 645
 * @param i initial coeff index, 0 unless a separate DC block is coded
 * @param zero_nhood the initial prediction context for number of surrounding
 *                   all-zero blocks (only left/top, so 0-2)
646
 * @param qmul array holding the dc/ac dequant factor at position 0/1
David Conrad's avatar
David Conrad committed
647 648 649
 * @return 0 if no coeffs were decoded
 *         otherwise, the index of the last coeff decoded plus one
 */
650
static int decode_block_coeffs_internal(VP56RangeCoder *c, DCTELEM block[16],
651
                                        uint8_t probs[16][3][NUM_DCT_TOKENS-1],
652
                                        int i, uint8_t *token_prob, int16_t qmul[2])
David Conrad's avatar
David Conrad committed
653
{
654
    goto skip_eob;
655
    do {
656
        int coeff;
657
        if (!vp56_rac_get_prob_branchy(c, token_prob[0]))   // DCT_EOB
658
            return i;
David Conrad's avatar
David Conrad committed
659

660 661
skip_eob:
        if (!vp56_rac_get_prob_branchy(c, token_prob[1])) { // DCT_0
662
            if (++i == 16)
663
                return i; // invalid input; blocks should end with EOB
664
            token_prob = probs[i][0];
665
            goto skip_eob;
666 667 668 669
        }

        if (!vp56_rac_get_prob_branchy(c, token_prob[2])) { // DCT_1
            coeff = 1;
670
            token_prob = probs[i+1][1];
671 672
        } else {
            if (!vp56_rac_get_prob_branchy(c, token_prob[3])) { // DCT 2,3,4
673
                coeff = vp56_rac_get_prob_branchy(c, token_prob[4]);
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
                if (coeff)
                    coeff += vp56_rac_get_prob(c, token_prob[5]);
                coeff += 2;
            } else {
                // DCT_CAT*
                if (!vp56_rac_get_prob_branchy(c, token_prob[6])) {
                    if (!vp56_rac_get_prob_branchy(c, token_prob[7])) { // DCT_CAT1
                        coeff  = 5 + vp56_rac_get_prob(c, vp8_dct_cat1_prob[0]);
                    } else {                                    // DCT_CAT2
                        coeff  = 7;
                        coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[0]) << 1;
                        coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[1]);
                    }
                } else {    // DCT_CAT3 and up
                    int a = vp56_rac_get_prob(c, token_prob[8]);
                    int b = vp56_rac_get_prob(c, token_prob[9+a]);
                    int cat = (a<<1) + b;
                    coeff  = 3 + (8<<cat);
692
                    coeff += vp8_rac_get_coeff(c, ff_vp8_dct_cat_prob[cat]);
693 694
                }
            }
695
            token_prob = probs[i+1][2];
696 697
        }
        block[zigzag_scan[i]] = (vp8_rac_get(c) ? -coeff : coeff) * qmul[!!i];
698
    } while (++i < 16);
699

700
    return i;
David Conrad's avatar
David Conrad committed
701
}
702
#endif
David Conrad's avatar
David Conrad committed
703

704 705
static av_always_inline
int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16],
706
                        uint8_t probs[16][3][NUM_DCT_TOKENS-1],
707 708 709 710 711 712 713 714
                        int i, int zero_nhood, int16_t qmul[2])
{
    uint8_t *token_prob = probs[i][zero_nhood];
    if (!vp56_rac_get_prob_branchy(c, token_prob[0]))   // DCT_EOB
        return 0;
    return decode_block_coeffs_internal(c, block, probs, i, token_prob, qmul);
}

715 716 717
static av_always_inline
void decode_mb_coeffs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
                      uint8_t t_nnz[9], uint8_t l_nnz[9])
David Conrad's avatar
David Conrad committed
718 719 720
{
    int i, x, y, luma_start = 0, luma_ctx = 3;
    int nnz_pred, nnz, nnz_total = 0;
721
    int segment = s->segment;
722
    int block_dc = 0;
David Conrad's avatar
David Conrad committed
723 724 725 726 727

    if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
        nnz_pred = t_nnz[8] + l_nnz[8];

        // decode DC values and do hadamard
728
        nnz = decode_block_coeffs(c, s->block_dc, s->prob->token[1], 0, nnz_pred,
David Conrad's avatar
David Conrad committed
729 730
                                  s->qmat[segment].luma_dc_qmul);
        l_nnz[8] = t_nnz[8] = !!nnz;
731 732 733 734 735 736 737 738
        if (nnz) {
            nnz_total += nnz;
            block_dc = 1;
            if (nnz == 1)
                s->vp8dsp.vp8_luma_dc_wht_dc(s->block, s->block_dc);
            else
                s->vp8dsp.vp8_luma_dc_wht(s->block, s->block_dc);
        }
David Conrad's avatar
David Conrad committed
739 740 741 742 743 744 745
        luma_start = 1;
        luma_ctx = 0;
    }

    // luma blocks
    for (y = 0; y < 4; y++)
        for (x = 0; x < 4; x++) {
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
746
            nnz_pred = l_nnz[y] + t_nnz[x];
David Conrad's avatar
David Conrad committed
747
            nnz = decode_block_coeffs(c, s->block[y][x], s->prob->token[luma_ctx], luma_start,
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
748
                                      nnz_pred, s->qmat[segment].luma_qmul);
749 750
            // nnz+block_dc may be one more than the actual last index, but we don't care
            s->non_zero_count_cache[y][x] = nnz + block_dc;
David Conrad's avatar
David Conrad committed
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
            t_nnz[x] = l_nnz[y] = !!nnz;
            nnz_total += nnz;
        }

    // chroma blocks
    // TODO: what to do about dimensions? 2nd dim for luma is x,
    // but for chroma it's (y<<1)|x
    for (i = 4; i < 6; i++)
        for (y = 0; y < 2; y++)
            for (x = 0; x < 2; x++) {
                nnz_pred = l_nnz[i+2*y] + t_nnz[i+2*x];
                nnz = decode_block_coeffs(c, s->block[i][(y<<1)+x], s->prob->token[2], 0,
                                          nnz_pred, s->qmat[segment].chroma_qmul);
                s->non_zero_count_cache[i][(y<<1)+x] = nnz;
                t_nnz[i+2*x] = l_nnz[i+2*y] = !!nnz;
                nnz_total += nnz;
            }

    // if there were no coded coeffs despite the macroblock not being marked skip,
    // we MUST not do the inner loop filter and should not do IDCT
    // Since skip isn't used for bitstream prediction, just manually set it.
    if (!nnz_total)
        mb->skip = 1;
}

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
static av_always_inline
void backup_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr,
                      int linesize, int uvlinesize, int simple)
{
    AV_COPY128(top_border, src_y + 15*linesize);
    if (!simple) {
        AV_COPY64(top_border+16, src_cb + 7*uvlinesize);
        AV_COPY64(top_border+24, src_cr + 7*uvlinesize);
    }
}

static av_always_inline
void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr,
                    int linesize, int uvlinesize, int mb_x, int mb_y, int mb_width,
                    int simple, int xchg)
{
    uint8_t *top_border_m1 = top_border-32;     // for TL prediction
    src_y  -=   linesize;
    src_cb -= uvlinesize;
    src_cr -= uvlinesize;

Måns Rullgård's avatar
Måns Rullgård committed
797 798 799 800
#define XCHG(a,b,xchg) do {                     \
        if (xchg) AV_SWAP64(b,a);               \
        else      AV_COPY64(b,a);               \
    } while (0)
801 802 803 804

    XCHG(top_border_m1+8, src_y-8, xchg);
    XCHG(top_border,      src_y,   xchg);
    XCHG(top_border+8,    src_y+8, 1);
805
    if (mb_x < mb_width-1)
806
        XCHG(top_border+32, src_y+16, 1);
807

808 809 810 811 812 813 814 815 816 817
    // only copy chroma for normal loop filter
    // or to initialize the top row to 127
    if (!simple || !mb_y) {
        XCHG(top_border_m1+16, src_cb-8, xchg);
        XCHG(top_border_m1+24, src_cr-8, xchg);
        XCHG(top_border+16,    src_cb, 1);
        XCHG(top_border+24,    src_cr, 1);
    }
}

818
static av_always_inline
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
int check_dc_pred8x8_mode(int mode, int mb_x, int mb_y)
{
    if (!mb_x) {
        return mb_y ? TOP_DC_PRED8x8 : DC_128_PRED8x8;
    } else {
        return mb_y ? mode : LEFT_DC_PRED8x8;
    }
}

static av_always_inline
int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y)
{
    if (!mb_x) {
        return mb_y ? VERT_PRED8x8 : DC_129_PRED8x8;
    } else {
        return mb_y ? mode : HOR_PRED8x8;
    }
}

static av_always_inline
int check_intra_pred8x8_mode(int mode, int mb_x, int mb_y)
David Conrad's avatar
David Conrad committed
840 841
{
    if (mode == DC_PRED8x8) {
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
        return check_dc_pred8x8_mode(mode, mb_x, mb_y);
    } else {
        return mode;
    }
}

static av_always_inline
int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y)
{
    switch (mode) {
    case DC_PRED8x8:
        return check_dc_pred8x8_mode(mode, mb_x, mb_y);
    case VERT_PRED8x8:
        return !mb_y ? DC_127_PRED8x8 : mode;
    case HOR_PRED8x8:
        return !mb_x ? DC_129_PRED8x8 : mode;
    case PLANE_PRED8x8 /*TM*/:
        return check_tm_pred8x8_mode(mode, mb_x, mb_y);
    }
    return mode;
}

static av_always_inline
int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y)
{
    if (!mb_x) {
        return mb_y ? VERT_VP8_PRED : DC_129_PRED;
    } else {
        return mb_y ? mode : HOR_VP8_PRED;
    }
}

static av_always_inline
int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y, int *copy_buf)
{
    switch (mode) {
    case VERT_PRED:
        if (!mb_x && mb_y) {
            *copy_buf = 1;
            return mode;
        }
        /* fall-through */
    case DIAG_DOWN_LEFT_PRED:
    case VERT_LEFT_PRED:
        return !mb_y ? DC_127_PRED : mode;
    case HOR_PRED:
        if (!mb_y) {
            *copy_buf = 1;
            return mode;
891
        }
892 893 894 895 896 897 898 899 900 901 902 903
        /* fall-through */
    case HOR_UP_PRED:
        return !mb_x ? DC_129_PRED : mode;
    case TM_VP8_PRED:
        return check_tm_pred4x4_mode(mode, mb_x, mb_y);
    case DC_PRED: // 4x4 DC doesn't use the same "H.264-style" exceptions as 16x16/8x8 DC
    case DIAG_DOWN_RIGHT_PRED:
    case VERT_RIGHT_PRED:
    case HOR_DOWN_PRED:
        if (!mb_y || !mb_x)
            *copy_buf = 1;
        return mode;
David Conrad's avatar
David Conrad committed
904 905 906 907
    }
    return mode;
}

908 909
static av_always_inline
void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
910
                   int mb_x, int mb_y)
David Conrad's avatar
David Conrad committed
911
{
912
    AVCodecContext *avctx = s->avctx;
David Conrad's avatar
David Conrad committed
913 914
    int x, y, mode, nnz, tr;

915 916
    // for the first row, we need to run xchg_mb_border to init the top edge to 127
    // otherwise, skip it if we aren't going to deblock
917
    if (!(avctx->flags & CODEC_FLAG_EMU_EDGE && !mb_y) && (s->deblock_filter || !mb_y))
918 919 920 921
        xchg_mb_border(s->top_border[mb_x+1], dst[0], dst[1], dst[2],
                       s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
                       s->filter.simple, 1);

David Conrad's avatar
David Conrad committed
922
    if (mb->mode < MODE_I4x4) {
923 924 925 926 927
        if (avctx->flags & CODEC_FLAG_EMU_EDGE) { // tested
            mode = check_intra_pred8x8_mode_emuedge(mb->mode, mb_x, mb_y);
        } else {
            mode = check_intra_pred8x8_mode(mb->mode, mb_x, mb_y);
        }
David Conrad's avatar
David Conrad committed
928 929 930
        s->hpc.pred16x16[mode](dst[0], s->linesize);
    } else {
        uint8_t *ptr = dst[0];
931
        uint8_t *intra4x4 = s->intra4x4_pred_mode_mb;
932
        uint8_t tr_top[4] = { 127, 127, 127, 127 };
David Conrad's avatar
David Conrad committed
933 934 935 936 937 938 939

        // all blocks on the right edge of the macroblock use bottom edge
        // the top macroblock for their topright edge
        uint8_t *tr_right = ptr - s->linesize + 16;

        // if we're on the right edge of the frame, said edge is extended
        // from the top macroblock
940 941
        if (!(!mb_y && avctx->flags & CODEC_FLAG_EMU_EDGE) &&
            mb_x == s->mb_width-1) {
David Conrad's avatar
David Conrad committed
942 943 944 945
            tr = tr_right[-1]*0x01010101;
            tr_right = (uint8_t *)&tr;
        }

946 947 948
        if (mb->skip)
            AV_ZERO128(s->non_zero_count_cache);

David Conrad's avatar
David Conrad committed
949 950 951
        for (y = 0; y < 4; y++) {
            uint8_t *topright = ptr + 4 - s->linesize;
            for (x = 0; x < 4; x++) {
952 953 954 955 956 957 958
                int copy = 0, linesize = s->linesize;
                uint8_t *dst = ptr+4*x;
                DECLARE_ALIGNED(4, uint8_t, copy_dst)[5*8];

                if ((y == 0 || x == 3) && mb_y == 0 && avctx->flags & CODEC_FLAG_EMU_EDGE) {
                    topright = tr_top;
                } else if (x == 3)
David Conrad's avatar
David Conrad committed
959 960
                    topright = tr_right;

961 962 963 964 965 966 967
                if (avctx->flags & CODEC_FLAG_EMU_EDGE) { // mb_x+x or mb_y+y is a hack but works
                    mode = check_intra_pred4x4_mode_emuedge(intra4x4[x], mb_x + x, mb_y + y, &copy);
                    if (copy) {
                        dst = copy_dst + 12;
                        linesize = 8;
                        if (!(mb_y + y)) {
                            copy_dst[3] = 127U;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
968
                            AV_WN32A(copy_dst+4, 127U * 0x01010101U);
969
                        } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
970
                            AV_COPY32(copy_dst+4, ptr+4*x-s->linesize);
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
                            if (!(mb_x + x)) {
                                copy_dst[3] = 129U;
                            } else {
                                copy_dst[3] = ptr[4*x-s->linesize-1];
                            }
                        }
                        if (!(mb_x + x)) {
                            copy_dst[11] =
                            copy_dst[19] =
                            copy_dst[27] =
                            copy_dst[35] = 129U;
                        } else {
                            copy_dst[11] = ptr[4*x              -1];
                            copy_dst[19] = ptr[4*x+s->linesize  -1];
                            copy_dst[27] = ptr[4*x+s->linesize*2-1];
                            copy_dst[35] = ptr[4*x+s->linesize*3-1];
                        }
                    }
                } else {
                    mode = intra4x4[x];
                }
                s->hpc.pred4x4[mode](dst, topright, linesize);
                if (copy) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
994 995 996 997
                    AV_COPY32(ptr+4*x              , copy_dst+12);
                    AV_COPY32(ptr+4*x+s->linesize  , copy_dst+20);
                    AV_COPY32(ptr+4*x+s->linesize*2, copy_dst+28);
                    AV_COPY32(ptr+4*x+s->linesize*3, copy_dst+36);
998
                }
David Conrad's avatar
David Conrad committed
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010

                nnz = s->non_zero_count_cache[y][x];
                if (nnz) {
                    if (nnz == 1)
                        s->vp8dsp.vp8_idct_dc_add(ptr+4*x, s->block[y][x], s->linesize);
                    else
                        s->vp8dsp.vp8_idct_add(ptr+4*x, s->block[y][x], s->linesize);
                }
                topright += 4;
            }

            ptr   += 4*s->linesize;
1011
            intra4x4 += 4;
David Conrad's avatar
David Conrad committed
1012 1013 1014
        }
    }

1015 1016 1017 1018 1019
    if (avctx->flags & CODEC_FLAG_EMU_EDGE) {
        mode = check_intra_pred8x8_mode_emuedge(s->chroma_pred_mode, mb_x, mb_y);
    } else {
        mode = check_intra_pred8x8_mode(s->chroma_pred_mode, mb_x, mb_y);
    }
David Conrad's avatar
David Conrad committed
1020 1021
    s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
    s->hpc.pred8x8[mode](dst[2], s->uvlinesize);
1022

1023
    if (!(avctx->flags & CODEC_FLAG_EMU_EDGE && !mb_y) && (s->deblock_filter || !mb_y))
1024 1025 1026
        xchg_mb_border(s->top_border[mb_x+1], dst[0], dst[1], dst[2],
                       s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
                       s->filter.simple, 0);
David Conrad's avatar
David Conrad committed
1027 1028
}

1029 1030 1031 1032 1033 1034 1035
static const uint8_t subpel_idx[3][8] = {
    { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
                                // also function pointer index
    { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
    { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
};

David Conrad's avatar
David Conrad committed
1036 1037 1038 1039 1040 1041
/**
 * Generic MC function.
 *
 * @param s VP8 decoding context
 * @param luma 1 for luma (Y) planes, 0 for chroma (Cb/Cr) planes
 * @param dst target buffer for block data at block position
1042
 * @param ref reference picture buffer at origin (0, 0)
David Conrad's avatar
David Conrad committed
1043 1044 1045 1046 1047 1048 1049 1050
 * @param mv motion vector (relative to block position) to get pixel data from
 * @param x_off horizontal position of block from origin (0, 0)
 * @param y_off vertical position of block from origin (0, 0)
 * @param block_w width of block (16, 8 or 4)
 * @param block_h height of block (always same as block_w)
 * @param width width of src/dst plane data
 * @param height height of src/dst plane data
 * @param linesize size of a single line of plane data, including padding
1051
 * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
David Conrad's avatar
David Conrad committed
1052
 */
1053
static av_always_inline
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1054
void vp8_mc_luma(VP8Context *s, uint8_t *dst, AVFrame *ref, const VP56mv *mv,
1055 1056 1057
                 int x_off, int y_off, int block_w, int block_h,
                 int width, int height, int linesize,
                 vp8_mc_func mc_func[3][3])
David Conrad's avatar
David Conrad committed
1058
{
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1059 1060
    uint8_t *src = ref->data[0];

1061
    if (AV_RN32A(mv)) {
1062 1063 1064 1065 1066 1067

        int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx];
        int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my];

        x_off += mv->x >> 2;
        y_off += mv->y >> 2;
1068 1069

        // edge emulation
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1070
        ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 4, 0);
1071
        src += y_off * linesize + x_off;
1072 1073
        if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
            y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
1074
            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
1075 1076
                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
                                    x_off - mx_idx, y_off - my_idx, width, height);
1077
            src = s->edge_emu_buffer + mx_idx + linesize * my_idx;
1078 1079
        }
        mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1080 1081
    } else {
        ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
1082
        mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1083
    }
David Conrad's avatar
David Conrad committed
1084 1085
}

1086
static av_always_inline
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1087 1088
void vp8_mc_chroma(VP8Context *s, uint8_t *dst1, uint8_t *dst2, AVFrame *ref,
                   const VP56mv *mv, int x_off, int y_off,
1089 1090 1091
                   int block_w, int block_h, int width, int height, int linesize,
                   vp8_mc_func mc_func[3][3])
{
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1092 1093
    uint8_t *src1 = ref->data[1], *src2 = ref->data[2];

1094 1095 1096 1097 1098 1099