vc1.c 155 KB
Newer Older
1
/*
2
 * VC-1 and WMV3 decoder
3
 * Copyright (c) 2006-2007 Konstantin Shishkov
4
 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
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 23
 */

/**
24
 * @file libavcodec/vc1.c
25
 * VC-1 and WMV3 decoder
26 27
 *
 */
28
#include "internal.h"
29 30 31
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
Kostya Shishkov's avatar
Kostya Shishkov committed
32
#include "vc1.h"
33
#include "vc1data.h"
34
#include "vc1acdata.h"
35
#include "msmpeg4data.h"
36
#include "unary.h"
Kostya Shishkov's avatar
Kostya Shishkov committed
37
#include "simple_idct.h"
38
#include "mathops.h"
39
#include "vdpau_internal.h"
anonymous's avatar
anonymous committed
40

41 42 43
#undef NDEBUG
#include <assert.h>

anonymous's avatar
anonymous committed
44 45
#define MB_INTRA_VLC_BITS 9
#define DC_VLC_BITS 9
46
#define AC_VLC_BITS 9
anonymous's avatar
anonymous committed
47
static const uint16_t table_mb_intra[64][2];
48 49


50 51 52 53 54 55
static const uint16_t vlc_offs[] = {
       0,   520,   552,   616,  1128,  1160, 1224, 1740, 1772, 1836, 1900, 2436,
    2986,  3050,  3610,  4154,  4218,  4746, 5326, 5390, 5902, 6554, 7658, 8620,
    9262, 10202, 10756, 11310, 12228, 15078
};

anonymous's avatar
anonymous committed
56
/**
57 58
 * Init VC-1 specific tables and VC1Context members
 * @param v The VC1Context to initialize
anonymous's avatar
anonymous committed
59 60
 * @return Status
 */
61
static int vc1_init_common(VC1Context *v)
62 63
{
    static int done = 0;
64
    int i = 0;
65
    static VLC_TYPE vlc_table[15078][2];
66 67

    v->hrd_rate = v->hrd_buffer = NULL;
anonymous's avatar
Fixes:  
anonymous committed
68 69

    /* VLC tables */
70 71
    if(!done)
    {
72
        INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
73
                 ff_vc1_bfraction_bits, 1, 1,
74 75
                 ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS);
        INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
76
                 ff_vc1_norm2_bits, 1, 1,
77 78
                 ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS);
        INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
79
                 ff_vc1_norm6_bits, 1, 1,
80 81
                 ff_vc1_norm6_codes, 2, 2, 556);
        INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
82
                 ff_vc1_imode_bits, 1, 1,
83
                 ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS);
anonymous's avatar
Fixes:  
anonymous committed
84 85
        for (i=0; i<3; i++)
        {
86 87
            ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i*3+0]];
            ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i*3+1] - vlc_offs[i*3+0];
88 89
            init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
                     ff_vc1_ttmb_bits[i], 1, 1,
90 91 92
                     ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
            ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i*3+1]];
            ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i*3+2] - vlc_offs[i*3+1];
93 94
            init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
                     ff_vc1_ttblk_bits[i], 1, 1,
95 96 97
                     ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
            ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i*3+2]];
            ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i*3+3] - vlc_offs[i*3+2];
98 99
            init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
                     ff_vc1_subblkpat_bits[i], 1, 1,
100
                     ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
anonymous's avatar
Fixes:  
anonymous committed
101 102
        }
        for(i=0; i<4; i++)
103
        {
104 105
            ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i*3+9]];
            ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i*3+10] - vlc_offs[i*3+9];
106 107
            init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
                     ff_vc1_4mv_block_pattern_bits[i], 1, 1,
108 109 110
                     ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
            ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i*3+10]];
            ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i*3+11] - vlc_offs[i*3+10];
111 112
            init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
                     ff_vc1_cbpcy_p_bits[i], 1, 1,
113 114 115
                     ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
            ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i*3+11]];
            ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i*3+12] - vlc_offs[i*3+11];
116 117
            init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
                     ff_vc1_mv_diff_bits[i], 1, 1,
118
                     ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
119
        }
120 121 122
        for(i=0; i<8; i++){
            ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i+21]];
            ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i+22] - vlc_offs[i+21];
123
            init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i],
124
                     &vc1_ac_tables[i][0][1], 8, 4,
125 126 127
                     &vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC);
        }
        //FIXME: switching to INIT_VLC_STATIC() results in incorrect decoding
128 129
        init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
                 &ff_msmp4_mb_i_table[0][1], 4, 2,
130
                 &ff_msmp4_mb_i_table[0][0], 4, 2, INIT_VLC_USE_STATIC);
131
        done = 1;
132 133
    }

anonymous's avatar
Fixes:  
anonymous committed
134 135 136 137
    /* Other defaults */
    v->pq = -1;
    v->mvrange = 0; /* 7.1.1.18, p80 */

138 139 140
    return 0;
}

141
/***********************************************************************/
anonymous's avatar
anonymous committed
142
/**
143
 * @defgroup vc1bitplane VC-1 Bitplane decoding
144 145 146 147
 * @see 8.7, p56
 * @{
 */

148
/**
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
 * Imode types
 * @{
 */
enum Imode {
    IMODE_RAW,
    IMODE_NORM2,
    IMODE_DIFF2,
    IMODE_NORM6,
    IMODE_DIFF6,
    IMODE_ROWSKIP,
    IMODE_COLSKIP
};
/** @} */ //imode defines

/** Decode rows by checking if they are skipped
 * @param plane Buffer to store decoded bits
 * @param[in] width Width of this buffer
 * @param[in] height Height of this buffer
 * @param[in] stride of this buffer
 */
static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
    int x, y;
171

172
    for (y=0; y<height; y++){
173
        if (!get_bits1(gb)) //rowskip
174 175 176
            memset(plane, 0, width);
        else
            for (x=0; x<width; x++)
177
                plane[x] = get_bits1(gb);
178
        plane += stride;
179
    }
180
}
181

182 183 184 185 186
/** Decode columns by checking if they are skipped
 * @param plane Buffer to store decoded bits
 * @param[in] width Width of this buffer
 * @param[in] height Height of this buffer
 * @param[in] stride of this buffer
187
 * @todo FIXME: Optimize
188 189 190
 */
static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
    int x, y;
191

192
    for (x=0; x<width; x++){
193
        if (!get_bits1(gb)) //colskip
194 195 196 197
            for (y=0; y<height; y++)
                plane[y*stride] = 0;
        else
            for (y=0; y<height; y++)
198
                plane[y*stride] = get_bits1(gb);
199
        plane ++;
200 201 202
    }
}

203
/** Decode a bitplane's bits
204 205
 * @param data bitplane where to store the decode bits
 * @param[out] raw_flag pointer to the flag indicating that this bitplane is not coded explicitly
206
 * @param v VC-1 context for bit reading and logging
anonymous's avatar
anonymous committed
207
 * @return Status
208
 * @todo FIXME: Optimize
anonymous's avatar
anonymous committed
209
 */
210
static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
211
{
212
    GetBitContext *gb = &v->s.gb;
213

214
    int imode, x, y, code, offset;
215 216
    uint8_t invert, *planep = data;
    int width, height, stride;
217

218 219 220
    width = v->s.mb_width;
    height = v->s.mb_height;
    stride = v->s.mb_stride;
221
    invert = get_bits1(gb);
222
    imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
223

224
    *raw_flag = 0;
225
    switch (imode)
226
    {
227 228
    case IMODE_RAW:
        //Data is actually read in the MB layer (same for all tests == "raw")
229
        *raw_flag = 1; //invert ignored
230 231 232
        return invert;
    case IMODE_DIFF2:
    case IMODE_NORM2:
233
        if ((height * width) & 1)
234
        {
235
            *planep++ = get_bits1(gb);
236
            offset = 1;
237
        }
238 239
        else offset = 0;
        // decode bitplane as one long line
240
        for (y = offset; y < height * width; y += 2) {
241
            code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
242 243
            *planep++ = code & 1;
            offset++;
244
            if(offset == width) {
245
                offset = 0;
246
                planep += stride - width;
247
            }
248 249
            *planep++ = code >> 1;
            offset++;
250
            if(offset == width) {
251
                offset = 0;
252
                planep += stride - width;
253
            }
254 255 256 257
        }
        break;
    case IMODE_DIFF6:
    case IMODE_NORM6:
258 259 260
        if(!(height % 3) && (width % 3)) { // use 2x3 decoding
            for(y = 0; y < height; y+= 3) {
                for(x = width & 1; x < width; x += 2) {
261
                    code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
262 263 264 265 266 267
                    if(code < 0){
                        av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
                        return -1;
                    }
                    planep[x + 0] = (code >> 0) & 1;
                    planep[x + 1] = (code >> 1) & 1;
268 269 270 271
                    planep[x + 0 + stride] = (code >> 2) & 1;
                    planep[x + 1 + stride] = (code >> 3) & 1;
                    planep[x + 0 + stride * 2] = (code >> 4) & 1;
                    planep[x + 1 + stride * 2] = (code >> 5) & 1;
272
                }
273
                planep += stride * 3;
274
            }
275
            if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb);
276
        } else { // 3x2
277
            planep += (height & 1) * stride;
278 279
            for(y = height & 1; y < height; y += 2) {
                for(x = width % 3; x < width; x += 3) {
280
                    code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
281 282 283 284 285 286 287
                    if(code < 0){
                        av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
                        return -1;
                    }
                    planep[x + 0] = (code >> 0) & 1;
                    planep[x + 1] = (code >> 1) & 1;
                    planep[x + 2] = (code >> 2) & 1;
288 289 290
                    planep[x + 0 + stride] = (code >> 3) & 1;
                    planep[x + 1 + stride] = (code >> 4) & 1;
                    planep[x + 2 + stride] = (code >> 5) & 1;
291
                }
292
                planep += stride * 2;
293
            }
294 295 296
            x = width % 3;
            if(x) decode_colskip(data  ,             x, height    , stride, &v->s.gb);
            if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb);
297 298 299
        }
        break;
    case IMODE_ROWSKIP:
300
        decode_rowskip(data, width, height, stride, &v->s.gb);
301 302
        break;
    case IMODE_COLSKIP:
303
        decode_colskip(data, width, height, stride, &v->s.gb);
304 305 306 307 308 309 310
        break;
    default: break;
    }

    /* Applying diff operator */
    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
    {
311
        planep = data;
312
        planep[0] ^= invert;
313
        for (x=1; x<width; x++)
314
            planep[x] ^= planep[x-1];
315
        for (y=1; y<height; y++)
316
        {
317 318 319
            planep += stride;
            planep[0] ^= planep[-stride];
            for (x=1; x<width; x++)
320
            {
321 322
                if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;
                else                                 planep[x] ^= planep[x-1];
323 324 325
            }
        }
    }
326
    else if (invert)
327
    {
328 329
        planep = data;
        for (x=0; x<stride*height; x++) planep[x] = !planep[x]; //FIXME stride
330
    }
331 332
    return (imode<<1) + invert;
}
333

334
/** @} */ //Bitplane group
335

336 337 338 339
static void vc1_loop_filter_iblk(MpegEncContext *s, int pq)
{
    int i, j;
    if(!s->first_slice_line)
340 341
        s->dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
    s->dsp.vc1_v_loop_filter16(s->dest[0] + 8*s->linesize, s->linesize, pq);
342
    for(i = !s->mb_x*8; i < 16; i += 8)
343
        s->dsp.vc1_h_loop_filter16(s->dest[0] + i, s->linesize, pq);
344 345
    for(j = 0; j < 2; j++){
        if(!s->first_slice_line)
346
            s->dsp.vc1_v_loop_filter8(s->dest[j+1], s->uvlinesize, pq);
347
        if(s->mb_x)
348
            s->dsp.vc1_h_loop_filter8(s->dest[j+1], s->uvlinesize, pq);
349 350 351
    }
}

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
/***********************************************************************/
/** VOP Dquant decoding
 * @param v VC-1 Context
 */
static int vop_dquant_decoding(VC1Context *v)
{
    GetBitContext *gb = &v->s.gb;
    int pqdiff;

    //variable size
    if (v->dquant == 2)
    {
        pqdiff = get_bits(gb, 3);
        if (pqdiff == 7) v->altpq = get_bits(gb, 5);
        else v->altpq = v->pq + pqdiff + 1;
    }
    else
369
    {
370
        v->dquantfrm = get_bits1(gb);
371
        if ( v->dquantfrm )
372
        {
373 374
            v->dqprofile = get_bits(gb, 2);
            switch (v->dqprofile)
375
            {
376 377 378 379 380
            case DQPROFILE_SINGLE_EDGE:
            case DQPROFILE_DOUBLE_EDGES:
                v->dqsbedge = get_bits(gb, 2);
                break;
            case DQPROFILE_ALL_MBS:
381
                v->dqbilevel = get_bits1(gb);
382 383
                if(!v->dqbilevel)
                    v->halfpq = 0;
384
            default: break; //Forbidden ?
Ivan Kalvachev's avatar
Ivan Kalvachev committed
385
            }
386
            if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
387
            {
388 389 390
                pqdiff = get_bits(gb, 3);
                if (pqdiff == 7) v->altpq = get_bits(gb, 5);
                else v->altpq = v->pq + pqdiff + 1;
391 392 393
            }
        }
    }
394 395
    return 0;
}
396

397 398 399 400 401 402 403 404
/** Put block onto picture
 */
static void vc1_put_block(VC1Context *v, DCTELEM block[6][64])
{
    uint8_t *Y;
    int ys, us, vs;
    DSPContext *dsp = &v->s.dsp;

Kostya Shishkov's avatar
Kostya Shishkov committed
405 406 407 408 409 410 411 412
    if(v->rangeredfrm) {
        int i, j, k;
        for(k = 0; k < 6; k++)
            for(j = 0; j < 8; j++)
                for(i = 0; i < 8; i++)
                    block[k][i + j*8] = ((block[k][i + j*8] - 128) << 1) + 128;

    }
413 414 415 416 417 418 419 420 421 422 423
    ys = v->s.current_picture.linesize[0];
    us = v->s.current_picture.linesize[1];
    vs = v->s.current_picture.linesize[2];
    Y = v->s.dest[0];

    dsp->put_pixels_clamped(block[0], Y, ys);
    dsp->put_pixels_clamped(block[1], Y + 8, ys);
    Y += ys * 8;
    dsp->put_pixels_clamped(block[2], Y, ys);
    dsp->put_pixels_clamped(block[3], Y + 8, ys);

Kostya Shishkov's avatar
Kostya Shishkov committed
424 425 426 427
    if(!(v->s.flags & CODEC_FLAG_GRAY)) {
        dsp->put_pixels_clamped(block[4], v->s.dest[1], us);
        dsp->put_pixels_clamped(block[5], v->s.dest[2], vs);
    }
428 429 430 431 432
}

/** Do motion compensation over 1 macroblock
 * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
 */
433
static void vc1_mc_1mv(VC1Context *v, int dir)
434 435 436 437
{
    MpegEncContext *s = &v->s;
    DSPContext *dsp = &v->s.dsp;
    uint8_t *srcY, *srcU, *srcV;
438
    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
439 440 441

    if(!v->s.last_picture.data[0])return;

442 443 444 445
    mx = s->mv[dir][0][0];
    my = s->mv[dir][0][1];

    // store motion vectors for further use in B frames
446
    if(s->pict_type == FF_P_TYPE) {
447 448 449
        s->current_picture.motion_val[1][s->block_index[0]][0] = mx;
        s->current_picture.motion_val[1][s->block_index[0]][1] = my;
    }
450 451
    uvmx = (mx + ((mx & 3) == 3)) >> 1;
    uvmy = (my + ((my & 3) == 3)) >> 1;
452 453 454 455
    if(v->fastuvmc) {
        uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
        uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
    }
456 457 458 459 460 461 462 463 464
    if(!dir) {
        srcY = s->last_picture.data[0];
        srcU = s->last_picture.data[1];
        srcV = s->last_picture.data[2];
    } else {
        srcY = s->next_picture.data[0];
        srcU = s->next_picture.data[1];
        srcV = s->next_picture.data[2];
    }
465

466 467 468 469 470
    src_x = s->mb_x * 16 + (mx >> 2);
    src_y = s->mb_y * 16 + (my >> 2);
    uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
    uvsrc_y = s->mb_y * 8 + (uvmy >> 2);

Kostya Shishkov's avatar
Kostya Shishkov committed
471 472 473 474 475 476 477 478 479 480 481
    if(v->profile != PROFILE_ADVANCED){
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
    }else{
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
        src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
        uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
    }
482 483 484 485 486

    srcY += src_y * s->linesize + src_x;
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;

Kostya Shishkov's avatar
Kostya Shishkov committed
487 488 489 490 491 492
    /* for grayscale we should not try to read from unknown area */
    if(s->flags & CODEC_FLAG_GRAY) {
        srcU = s->edge_emu_buffer + 18 * s->linesize;
        srcV = s->edge_emu_buffer + 18 * s->linesize;
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
493
    if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
494 495 496
       || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3
       || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){
        uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
497

498 499 500
        srcY -= s->mspel * (1 + s->linesize);
        ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
                            src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
501 502 503 504 505 506 507
        srcY = s->edge_emu_buffer;
        ff_emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8+1, 8+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        srcU = uvbuf;
        srcV = uvbuf + 16;
Kostya Shishkov's avatar
Kostya Shishkov committed
508 509 510 511 512 513
        /* if we deal with range reduction we need to scale source blocks */
        if(v->rangeredfrm) {
            int i, j;
            uint8_t *src, *src2;

            src = srcY;
514 515
            for(j = 0; j < 17 + s->mspel*2; j++) {
                for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
Kostya Shishkov's avatar
Kostya Shishkov committed
516 517 518 519 520 521 522 523 524 525 526 527
                src += s->linesize;
            }
            src = srcU; src2 = srcV;
            for(j = 0; j < 9; j++) {
                for(i = 0; i < 9; i++) {
                    src[i] = ((src[i] - 128) >> 1) + 128;
                    src2[i] = ((src2[i] - 128) >> 1) + 128;
                }
                src += s->uvlinesize;
                src2 += s->uvlinesize;
            }
        }
528 529 530 531 532 533
        /* if we deal with intensity compensation we need to scale source blocks */
        if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
            int i, j;
            uint8_t *src, *src2;

            src = srcY;
534 535
            for(j = 0; j < 17 + s->mspel*2; j++) {
                for(i = 0; i < 17 + s->mspel*2; i++) src[i] = v->luty[src[i]];
536 537 538 539 540 541 542 543 544 545 546 547
                src += s->linesize;
            }
            src = srcU; src2 = srcV;
            for(j = 0; j < 9; j++) {
                for(i = 0; i < 9; i++) {
                    src[i] = v->lutuv[src[i]];
                    src2[i] = v->lutuv[src2[i]];
                }
                src += s->uvlinesize;
                src2 += s->uvlinesize;
            }
        }
548
        srcY += s->mspel * (1 + s->linesize);
549 550
    }

551 552 553 554 555 556 557
    if(s->mspel) {
        dxy = ((my & 3) << 2) | (mx & 3);
        dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0]    , srcY    , s->linesize, v->rnd);
        dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
        srcY += s->linesize * 8;
        dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
        dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
558 559
    } else { // hpel mc - always used for luma
        dxy = (my & 2) | ((mx & 2) >> 1);
560

561 562 563 564 565
        if(!v->rnd)
            dsp->put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
        else
            dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
566 567

    if(s->flags & CODEC_FLAG_GRAY) return;
Kostya Shishkov's avatar
Kostya Shishkov committed
568
    /* Chroma MC always uses qpel bilinear */
569 570 571 572 573 574
    uvmx = (uvmx&3)<<1;
    uvmy = (uvmy&3)<<1;
    if(!v->rnd){
        dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
        dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
    }else{
575 576
        dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
        dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
577
    }
578 579
}

Kostya Shishkov's avatar
Kostya Shishkov committed
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
/** Do motion compensation for 4-MV macroblock - luminance block
 */
static void vc1_mc_4mv_luma(VC1Context *v, int n)
{
    MpegEncContext *s = &v->s;
    DSPContext *dsp = &v->s.dsp;
    uint8_t *srcY;
    int dxy, mx, my, src_x, src_y;
    int off;

    if(!v->s.last_picture.data[0])return;
    mx = s->mv[0][n][0];
    my = s->mv[0][n][1];
    srcY = s->last_picture.data[0];

    off = s->linesize * 4 * (n&2) + (n&1) * 8;

    src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2);
    src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2);

Kostya Shishkov's avatar
Kostya Shishkov committed
600 601 602 603 604 605 606
    if(v->profile != PROFILE_ADVANCED){
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
    }else{
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
        src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
607 608 609

    srcY += src_y * s->linesize + src_x;

610
    if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
611 612
       || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2
       || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 8 - s->mspel*2){
613 614 615
        srcY -= s->mspel * (1 + s->linesize);
        ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, 9+s->mspel*2,
                            src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
Kostya Shishkov's avatar
Kostya Shishkov committed
616
        srcY = s->edge_emu_buffer;
Kostya Shishkov's avatar
Kostya Shishkov committed
617 618 619 620 621 622
        /* if we deal with range reduction we need to scale source blocks */
        if(v->rangeredfrm) {
            int i, j;
            uint8_t *src;

            src = srcY;
623 624
            for(j = 0; j < 9 + s->mspel*2; j++) {
                for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
Kostya Shishkov's avatar
Kostya Shishkov committed
625 626 627
                src += s->linesize;
            }
        }
628 629 630 631 632 633 634 635 636 637 638
        /* if we deal with intensity compensation we need to scale source blocks */
        if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
            int i, j;
            uint8_t *src;

            src = srcY;
            for(j = 0; j < 9 + s->mspel*2; j++) {
                for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]];
                src += s->linesize;
            }
        }
639
        srcY += s->mspel * (1 + s->linesize);
Kostya Shishkov's avatar
Kostya Shishkov committed
640 641
    }

642 643 644
    if(s->mspel) {
        dxy = ((my & 3) << 2) | (mx & 3);
        dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, v->rnd);
645 646
    } else { // hpel mc - always used for luma
        dxy = (my & 2) | ((mx & 2) >> 1);
647 648 649 650
        if(!v->rnd)
            dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
        else
            dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
Kostya Shishkov's avatar
Kostya Shishkov committed
651 652 653 654 655
    }
}

static inline int median4(int a, int b, int c, int d)
{
656
    if(a < b) {
657 658
        if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
        else      return (FFMIN(b, c) + FFMAX(a, d)) / 2;
659
    } else {
660 661
        if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
        else      return (FFMIN(a, c) + FFMAX(b, d)) / 2;
662
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
663 664 665 666 667 668 669 670 671 672
}


/** Do motion compensation for 4-MV macroblock - both chroma blocks
 */
static void vc1_mc_4mv_chroma(VC1Context *v)
{
    MpegEncContext *s = &v->s;
    DSPContext *dsp = &v->s.dsp;
    uint8_t *srcU, *srcV;
673
    int uvmx, uvmy, uvsrc_x, uvsrc_y;
Kostya Shishkov's avatar
Kostya Shishkov committed
674 675 676 677 678
    int i, idx, tx = 0, ty = 0;
    int mvx[4], mvy[4], intra[4];
    static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};

    if(!v->s.last_picture.data[0])return;
Kostya Shishkov's avatar
Kostya Shishkov committed
679
    if(s->flags & CODEC_FLAG_GRAY) return;
Kostya Shishkov's avatar
Kostya Shishkov committed
680 681 682 683 684 685 686 687

    for(i = 0; i < 4; i++) {
        mvx[i] = s->mv[0][i][0];
        mvy[i] = s->mv[0][i][1];
        intra[i] = v->mb_type[0][s->block_index[i]];
    }

    /* calculate chroma MV vector from four luma MVs */
688
    idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0];
Kostya Shishkov's avatar
Kostya Shishkov committed
689 690 691 692 693 694 695
    if(!idx) { // all blocks are inter
        tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
        ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
    } else if(count[idx] == 1) { // 3 inter blocks
        switch(idx) {
        case 0x1:
            tx = mid_pred(mvx[1], mvx[2], mvx[3]);
696
            ty = mid_pred(mvy[1], mvy[2], mvy[3]);
Kostya Shishkov's avatar
Kostya Shishkov committed
697 698 699
            break;
        case 0x2:
            tx = mid_pred(mvx[0], mvx[2], mvx[3]);
700
            ty = mid_pred(mvy[0], mvy[2], mvy[3]);
Kostya Shishkov's avatar
Kostya Shishkov committed
701 702 703
            break;
        case 0x4:
            tx = mid_pred(mvx[0], mvx[1], mvx[3]);
704
            ty = mid_pred(mvy[0], mvy[1], mvy[3]);
Kostya Shishkov's avatar
Kostya Shishkov committed
705 706 707
            break;
        case 0x8:
            tx = mid_pred(mvx[0], mvx[1], mvx[2]);
708
            ty = mid_pred(mvy[0], mvy[1], mvy[2]);
Kostya Shishkov's avatar
Kostya Shishkov committed
709 710 711 712 713 714
            break;
        }
    } else if(count[idx] == 2) {
        int t1 = 0, t2 = 0;
        for(i=0; i<3;i++) if(!intra[i]) {t1 = i; break;}
        for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;}
715 716
        tx = (mvx[t1] + mvx[t2]) / 2;
        ty = (mvy[t1] + mvy[t2]) / 2;
717 718 719
    } else {
        s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
        s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
Kostya Shishkov's avatar
Kostya Shishkov committed
720
        return; //no need to do MC for inter blocks
721
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
722

723 724
    s->current_picture.motion_val[1][s->block_index[0]][0] = tx;
    s->current_picture.motion_val[1][s->block_index[0]][1] = ty;
Kostya Shishkov's avatar
Kostya Shishkov committed
725 726
    uvmx = (tx + ((tx&3) == 3)) >> 1;
    uvmy = (ty + ((ty&3) == 3)) >> 1;
727 728 729 730
    if(v->fastuvmc) {
        uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
        uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
731 732 733 734

    uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
    uvsrc_y = s->mb_y * 8 + (uvmy >> 2);

Kostya Shishkov's avatar
Kostya Shishkov committed
735 736 737 738 739 740 741
    if(v->profile != PROFILE_ADVANCED){
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
    }else{
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
        uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
    }
742

Kostya Shishkov's avatar
Kostya Shishkov committed
743 744
    srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
    srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
745 746
    if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
       || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
Kostya Shishkov's avatar
Kostya Shishkov committed
747
       || (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){
Kostya Shishkov's avatar
Kostya Shishkov committed
748 749 750 751 752 753
        ff_emulated_edge_mc(s->edge_emu_buffer     , srcU, s->uvlinesize, 8+1, 8+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        ff_emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        srcU = s->edge_emu_buffer;
        srcV = s->edge_emu_buffer + 16;
Kostya Shishkov's avatar
Kostya Shishkov committed
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769

        /* if we deal with range reduction we need to scale source blocks */
        if(v->rangeredfrm) {
            int i, j;
            uint8_t *src, *src2;

            src = srcU; src2 = srcV;
            for(j = 0; j < 9; j++) {
                for(i = 0; i < 9; i++) {
                    src[i] = ((src[i] - 128) >> 1) + 128;
                    src2[i] = ((src2[i] - 128) >> 1) + 128;
                }
                src += s->uvlinesize;
                src2 += s->uvlinesize;
            }
        }
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
        /* if we deal with intensity compensation we need to scale source blocks */
        if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
            int i, j;
            uint8_t *src, *src2;

            src = srcU; src2 = srcV;
            for(j = 0; j < 9; j++) {
                for(i = 0; i < 9; i++) {
                    src[i] = v->lutuv[src[i]];
                    src2[i] = v->lutuv[src2[i]];
                }
                src += s->uvlinesize;
                src2 += s->uvlinesize;
            }
        }
Kostya Shishkov's avatar
Kostya Shishkov committed
785 786
    }

Kostya Shishkov's avatar
Kostya Shishkov committed
787
    /* Chroma MC always uses qpel bilinear */
788 789 790 791 792 793
    uvmx = (uvmx&3)<<1;
    uvmy = (uvmy&3)<<1;
    if(!v->rnd){
        dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
        dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
    }else{
794 795
        dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
        dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
796
    }
Kostya Shishkov's avatar
Kostya Shishkov committed
797 798
}

799 800
static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb);

801
/**
anonymous's avatar
anonymous committed
802 803 804 805 806 807
 * Decode Simple/Main Profiles sequence header
 * @see Figure 7-8, p16-17
 * @param avctx Codec context
 * @param gb GetBit context initialized from Codec context extra_data
 * @return Status
 */
808 809
static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
{
810
    VC1Context *v = avctx->priv_data;
811

812
    av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
813
    v->profile = get_bits(gb, 2);
814
    if (v->profile == PROFILE_COMPLEX)
815
    {
816
        av_log(avctx, AV_LOG_ERROR, "WMV3 Complex Profile is not fully supported\n");
817
    }
818

819
    if (v->profile == PROFILE_ADVANCED)
820
    {
821 822
        v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz;
        v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
823
        return decode_sequence_header_adv(v, gb);
824 825 826
    }
    else
    {
Stefan Gehrer's avatar
Stefan Gehrer committed
827 828
        v->zz_8x4 = wmv2_scantableA;
        v->zz_4x8 = wmv2_scantableB;