Skip to content
Snippets Groups Projects
vc1.c 148 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kostya Shishkov's avatar
    Kostya Shishkov committed
        DSPContext *dsp = &v->s.dsp;
        uint8_t *srcU, *srcV;
        int uvdxy, uvmx, uvmy, uvsrc_x, uvsrc_y;
        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;
    
        if(s->flags & CODEC_FLAG_GRAY) return;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
    
        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 */
    
        idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0];
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        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]);
    
                ty = mid_pred(mvy[1], mvy[2], mvy[3]);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                break;
            case 0x2:
                tx = mid_pred(mvx[0], mvx[2], mvx[3]);
    
                ty = mid_pred(mvy[0], mvy[2], mvy[3]);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                break;
            case 0x4:
                tx = mid_pred(mvx[0], mvx[1], mvx[3]);
    
                ty = mid_pred(mvy[0], mvy[1], mvy[3]);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                break;
            case 0x8:
                tx = mid_pred(mvx[0], mvx[1], mvx[2]);
    
                ty = mid_pred(mvy[0], mvy[1], mvy[2]);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                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;}
    
            tx = (mvx[t1] + mvx[t2]) / 2;
            ty = (mvy[t1] + mvy[t2]) / 2;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        } else
            return; //no need to do MC for inter blocks
    
    
        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
        uvmx = (tx + ((tx&3) == 3)) >> 1;
        uvmy = (ty + ((ty&3) == 3)) >> 1;
    
        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
    
        uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
        uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
    
    
        uvsrc_x = clip(uvsrc_x,  -8, s->mb_width  *  8);
        uvsrc_y = clip(uvsrc_y,  -8, s->mb_height *  8);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
        srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
    
        if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
           || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
    
           || (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
            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;
    
    
            /* 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;
                }
            }
    
            /* 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
        /* Chroma MC always uses qpel bilinear */
    
        uvdxy = ((uvmy & 3) << 2) | (uvmx & 3);
    
        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{
            dsp->put_no_rnd_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
            dsp->put_no_rnd_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
        }
    
    static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb);
    
    
     * 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
     */
    
    static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
    {
    
        VC1Context *v = avctx->priv_data;
    
        av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
    
            av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden (and WMV3 Complex Profile is unsupported)\n");
    
        if (v->profile == PROFILE_ADVANCED)
    
            return decode_sequence_header_adv(v, gb);
    
        }
        else
        {
            v->res_sm = get_bits(gb, 2); //reserved
            if (v->res_sm)
            {
                av_log(avctx, AV_LOG_ERROR,
                       "Reserved RES_SM=%i is forbidden\n", v->res_sm);
    
            }
        }
    
        // (fps-2)/4 (->30)
        v->frmrtq_postproc = get_bits(gb, 3); //common
        // (bitrate-32kbps)/64kbps
        v->bitrtq_postproc = get_bits(gb, 5); //common
    
        v->s.loop_filter = get_bits(gb, 1); //common
    
        if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE)
        {
            av_log(avctx, AV_LOG_ERROR,
                   "LOOPFILTER shell not be enabled in simple profile\n");
        }
    
        v->res_x8 = get_bits(gb, 1); //reserved
        if (v->res_x8)
    
            av_log(avctx, AV_LOG_ERROR,
                   "1 for reserved RES_X8 is forbidden\n");
            //return -1;
        }
        v->multires = get_bits(gb, 1);
        v->res_fasttx = get_bits(gb, 1);
        if (!v->res_fasttx)
        {
            av_log(avctx, AV_LOG_ERROR,
                   "0 for reserved RES_FASTTX is forbidden\n");
            //return -1;
    
        }
    
        v->fastuvmc =  get_bits(gb, 1); //common
        if (!v->profile && !v->fastuvmc)
        {
            av_log(avctx, AV_LOG_ERROR,
                   "FASTUVMC unavailable in Simple Profile\n");
            return -1;
        }
        v->extended_mv =  get_bits(gb, 1); //common
        if (!v->profile && v->extended_mv)
        {
            av_log(avctx, AV_LOG_ERROR,
                   "Extended MVs unavailable in Simple Profile\n");
            return -1;
        }
        v->dquant =  get_bits(gb, 2); //common
        v->vstransform =  get_bits(gb, 1); //common
    
        v->res_transtab = get_bits(gb, 1);
        if (v->res_transtab)
    
            av_log(avctx, AV_LOG_ERROR,
                   "1 for reserved RES_TRANSTAB is forbidden\n");
            return -1;
    
        v->s.resync_marker = get_bits(gb, 1);
        v->rangered = get_bits(gb, 1);
        if (v->rangered && v->profile == PROFILE_SIMPLE)
    
            av_log(avctx, AV_LOG_INFO,
                   "RANGERED should be set to 0 in simple profile\n");
    
    anonymous's avatar
    anonymous committed
        v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common
    
        v->finterpflag = get_bits(gb, 1); //common
        v->res_rtm_flag = get_bits(gb, 1); //reserved
        if (!v->res_rtm_flag)
    
    //            av_log(avctx, AV_LOG_ERROR,
    //                   "0 for reserved RES_RTM_FLAG is forbidden\n");
    
            av_log(avctx, AV_LOG_ERROR,
                   "Old WMV3 version detected, only I-frames will be decoded\n");
            //return -1;
        }
        av_log(avctx, AV_LOG_DEBUG,
    
                   "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
    
                   "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
    
                   "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
                   "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
                   v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
    
                   v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
    
    anonymous's avatar
    anonymous committed
                   v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
    
    static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
    {
        v->res_rtm_flag = 1;
        v->level = get_bits(gb, 3);
        if(v->level >= 5)
        {
            av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
        }
        v->chromaformat = get_bits(gb, 2);
        if (v->chromaformat != 1)
        {
            av_log(v->s.avctx, AV_LOG_ERROR,
                   "Only 4:2:0 chroma format supported\n");
            return -1;
        }
    
        // (fps-2)/4 (->30)
        v->frmrtq_postproc = get_bits(gb, 3); //common
        // (bitrate-32kbps)/64kbps
        v->bitrtq_postproc = get_bits(gb, 5); //common
        v->postprocflag = get_bits(gb, 1); //common
    
        v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
        v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
        v->broadcast = get_bits1(gb);
        v->interlace = get_bits1(gb);
    
        if(v->interlace){
            av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced mode not supported (yet)\n");
            return -1;
        }
    
        v->tfcntrflag = get_bits1(gb);
        v->finterpflag = get_bits1(gb);
        get_bits1(gb); // reserved
    
    
        av_log(v->s.avctx, AV_LOG_DEBUG,
                   "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
                   "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
                   "TFCTRflag=%i, FINTERPflag=%i\n",
                   v->level, v->frmrtq_postproc, v->bitrtq_postproc,
                   v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
                   v->tfcntrflag, v->finterpflag
                   );
    
    
        v->psf = get_bits1(gb);
        if(v->psf) { //PsF, 6.1.13
            av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
            return -1;
        }
        if(get_bits1(gb)) { //Display Info - decoding is not affected by it
            int w, h, ar = 0;
            av_log(v->s.avctx, AV_LOG_INFO, "Display extended info:\n");
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
            w = get_bits(gb, 14) + 1;
            h = get_bits(gb, 14) + 1;
    
            av_log(v->s.avctx, AV_LOG_INFO, "Display dimensions: %ix%i\n", w, h);
            //TODO: store aspect ratio in AVCodecContext
            if(get_bits1(gb))
                ar = get_bits(gb, 4);
            if(ar == 15) {
                w = get_bits(gb, 8);
                h = get_bits(gb, 8);
            }
    
            if(get_bits1(gb)){ //framerate stuff
                if(get_bits1(gb)) {
                    get_bits(gb, 16);
                } else {
                    get_bits(gb, 8);
                    get_bits(gb, 4);
                }
            }
    
            if(get_bits1(gb)){
                v->color_prim = get_bits(gb, 8);
                v->transfer_char = get_bits(gb, 8);
                v->matrix_coef = get_bits(gb, 8);
            }
        }
    
        v->hrd_param_flag = get_bits1(gb);
        if(v->hrd_param_flag) {
            int i;
            v->hrd_num_leaky_buckets = get_bits(gb, 5);
            get_bits(gb, 4); //bitrate exponent
            get_bits(gb, 4); //buffer size exponent
            for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
                get_bits(gb, 16); //hrd_rate[n]
                get_bits(gb, 16); //hrd_buffer[n]
            }
        }
        return 0;
    }
    
    static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
    {
        VC1Context *v = avctx->priv_data;
    
        int i, blink, refdist;
    
    
        av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
    
        blink = get_bits1(gb); // broken link
    
        avctx->max_b_frames = 1 - get_bits1(gb); // 'closed entry' also signalize possible B-frames
    
        refdist = get_bits1(gb); // refdist flag
    
        v->s.loop_filter = get_bits1(gb);
        v->fastuvmc = get_bits1(gb);
        v->extended_mv = get_bits1(gb);
        v->dquant = get_bits(gb, 2);
        v->vstransform = get_bits1(gb);
        v->overlap = get_bits1(gb);
        v->quantizer_mode = get_bits(gb, 2);
    
        if(v->hrd_param_flag){
            for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
                get_bits(gb, 8); //hrd_full[n]
            }
        }
    
        if(get_bits1(gb)){
            avctx->coded_width = (get_bits(gb, 12)+1)<<1;
            avctx->coded_height = (get_bits(gb, 12)+1)<<1;
        }
        if(v->extended_mv)
            v->extended_dmv = get_bits1(gb);
        if(get_bits1(gb)) {
            av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
            skip_bits(gb, 3); // Y range, ignored for now
        }
        if(get_bits1(gb)) {
            av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");
            skip_bits(gb, 3); // UV range, ignored for now
        }
    
    
        av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
            "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
            "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
            "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
            blink, 1 - avctx->max_b_frames, v->panscanflag, refdist, v->s.loop_filter,
            v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
    
    
    static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
    
        int pqindex, lowquant, status;
    
        if(v->finterpflag) v->interpfrm = get_bits(gb, 1);
        skip_bits(gb, 2); //framecnt unused
        v->rangeredfrm = 0;
        if (v->rangered) v->rangeredfrm = get_bits(gb, 1);
        v->s.pict_type = get_bits(gb, 1);
        if (v->s.avctx->max_b_frames) {
            if (!v->s.pict_type) {
                if (get_bits(gb, 1)) v->s.pict_type = I_TYPE;
                else v->s.pict_type = B_TYPE;
            } else v->s.pict_type = P_TYPE;
        } else v->s.pict_type = v->s.pict_type ? P_TYPE : I_TYPE;
    
    
        v->bi_type = 0;
    
        if(v->s.pict_type == B_TYPE) {
            v->bfraction = get_vlc2(gb, vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
            v->bfraction = vc1_bfraction_lut[v->bfraction];
    
            if(v->bfraction == 0) {
    
        if(v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
            get_bits(gb, 7); // skip buffer fullness
    
        /* calculate RND */
    
        if(v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
    
            v->rnd = 1;
        if(v->s.pict_type == P_TYPE)
            v->rnd ^= 1;
    
    
        /* Quantizer stuff */
        pqindex = get_bits(gb, 5);
        if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
            v->pq = pquant_table[0][pqindex];
        else
    
        v->pquantizer = 1;
    
        if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
            v->pquantizer = pqindex < 9;
    
        if (v->quantizer_mode == QUANT_NON_UNIFORM)
            v->pquantizer = 0;
    
        v->pqindex = pqindex;
        if (pqindex < 9) v->halfpq = get_bits(gb, 1);
        else v->halfpq = 0;
        if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
            v->pquantizer = get_bits(gb, 1);
        v->dquantfrm = 0;
    
        if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3);
        v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
        v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
        v->range_x = 1 << (v->k_x - 1);
        v->range_y = 1 << (v->k_y - 1);
        if (v->profile == PROFILE_ADVANCED)
        {
            if (v->postprocflag) v->postproc = get_bits(gb, 1);
        }
        else
            if (v->multires && v->s.pict_type != B_TYPE) v->respic = get_bits(gb, 2);
    
    
    //av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
    //        (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
    
    
        if(v->s.pict_type == I_TYPE || v->s.pict_type == P_TYPE) v->use_ic = 0;
    
    
        switch(v->s.pict_type) {
        case P_TYPE:
            if (v->pq < 5) v->tt_index = 0;
            else if(v->pq < 13) v->tt_index = 1;
            else v->tt_index = 2;
    
            lowquant = (v->pq > 12) ? 0 : 1;
            v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)];
            if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
            {
    
                int scale, shift, i;
                v->mv_mode2 = mv_pmode_table2[lowquant][get_prefix(gb, 1, 3)];
    
                v->lumscale = get_bits(gb, 6);
                v->lumshift = get_bits(gb, 6);
    
                /* fill lookup tables for intensity compensation */
                if(!v->lumscale) {
                    scale = -64;
                    shift = (255 - v->lumshift * 2) << 6;
                    if(v->lumshift > 31)
                        shift += 128 << 6;
                } else {
                    scale = v->lumscale + 32;
                    if(v->lumshift > 31)
                        shift = (v->lumshift - 64) << 6;
                    else
                        shift = v->lumshift << 6;
                }
                for(i = 0; i < 256; i++) {
                    v->luty[i] = clip_uint8((scale * i + shift + 32) >> 6);
                    v->lutuv[i] = clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
                }
    
            }
            if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
    
            else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
                if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
                    v->s.quarter_sample = 0;
                else
                    v->s.quarter_sample = 1;
            } else
    
            v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
    
    
            if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
                     v->mv_mode2 == MV_PMODE_MIXED_MV)
                    || v->mv_mode == MV_PMODE_MIXED_MV)
            {
    
                status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
    
                if (status < 0) return -1;
                av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
                       "Imode: %i, Invert: %i\n", status>>1, status&1);
    
            } else {
                v->mv_type_is_raw = 0;
                memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
    
            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
    
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
    
            /* Hopefully this is correct for P frames */
            v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
            v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
    
            if (v->dquant)
            {
                av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
                vop_dquant_decoding(v);
            }
    
            v->ttfrm = 0; //FIXME Is that so ?
            if (v->vstransform)
            {
                v->ttmbf = get_bits(gb, 1);
                if (v->ttmbf)
                {
    
                    v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)];
    
            if (v->pq < 5) v->tt_index = 0;
            else if(v->pq < 13) v->tt_index = 1;
            else v->tt_index = 2;
    
            lowquant = (v->pq > 12) ? 0 : 1;
            v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
            v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
    
    
            status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
    
            v->s.mv_table_index = get_bits(gb, 2);
            v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
    
            if (v->dquant)
            {
                av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
                vop_dquant_decoding(v);
            }
    
            v->ttfrm = 0;
            if (v->vstransform)
            {
                v->ttmbf = get_bits(gb, 1);
                if (v->ttmbf)
                {
                    v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)];
                }
            } else {
                v->ttmbf = 1;
                v->ttfrm = TT_8X8;
            }
    
    
        /* AC Syntax */
        v->c_ac_table_index = decode012(gb);
        if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
    
            v->y_ac_table_index = decode012(gb);
    
        /* DC Syntax */
        v->s.dc_table_index = get_bits(gb, 1);
    
    
        if(v->s.pict_type == BI_TYPE) {
            v->s.pict_type = B_TYPE;
            v->bi_type = 1;
        }
    
    static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
    {
        int fcm;
        int pqindex, lowquant;
        int status;
    
        v->p_frame_skipped = 0;
    
        if(v->interlace)
            fcm = decode012(gb);
        switch(get_prefix(gb, 0, 4)) {
        case 0:
            v->s.pict_type = P_TYPE;
            break;
        case 1:
            v->s.pict_type = B_TYPE;
    
        case 2:
            v->s.pict_type = I_TYPE;
            break;
        case 3:
            v->s.pict_type = BI_TYPE;
    
        case 4:
            v->s.pict_type = P_TYPE; // skipped pic
            v->p_frame_skipped = 1;
            return 0;
        }
        if(v->tfcntrflag)
            get_bits(gb, 8);
        if(v->broadcast) {
            if(!v->interlace || v->panscanflag) {
                get_bits(gb, 2);
            } else {
                get_bits1(gb);
                get_bits1(gb);
            }
        }
        if(v->panscanflag) {
            //...
        }
        v->rnd = get_bits1(gb);
        if(v->interlace)
            v->uvsamp = get_bits1(gb);
        if(v->finterpflag) v->interpfrm = get_bits(gb, 1);
    
        if(v->s.pict_type == B_TYPE) {
            v->bfraction = get_vlc2(gb, vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
            v->bfraction = vc1_bfraction_lut[v->bfraction];
            if(v->bfraction == 0) {
                v->s.pict_type = BI_TYPE; /* XXX: should not happen here */
            }
        }
    
        pqindex = get_bits(gb, 5);
        v->pqindex = pqindex;
        if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
            v->pq = pquant_table[0][pqindex];
        else
            v->pq = pquant_table[1][pqindex];
    
        v->pquantizer = 1;
        if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
            v->pquantizer = pqindex < 9;
        if (v->quantizer_mode == QUANT_NON_UNIFORM)
            v->pquantizer = 0;
        v->pqindex = pqindex;
        if (pqindex < 9) v->halfpq = get_bits(gb, 1);
        else v->halfpq = 0;
        if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
            v->pquantizer = get_bits(gb, 1);
    
        switch(v->s.pict_type) {
        case I_TYPE:
    
            status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "
                    "Imode: %i, Invert: %i\n", status>>1, status&1);
            v->condover = CONDOVER_NONE;
            if(v->overlap && v->pq <= 8) {
                v->condover = decode012(gb);
                if(v->condover == CONDOVER_SELECT) {
                    status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);
                    if (status < 0) return -1;
                    av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: "
                            "Imode: %i, Invert: %i\n", status>>1, status&1);
                }
            }
            break;
        case P_TYPE:
            if(v->postprocflag)
                v->postproc = get_bits1(gb);
            if (v->extended_mv) v->mvrange = get_prefix(gb, 0, 3);
            else v->mvrange = 0;
            v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
            v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
            v->range_x = 1 << (v->k_x - 1);
            v->range_y = 1 << (v->k_y - 1);
    
            if (v->pq < 5) v->tt_index = 0;
            else if(v->pq < 13) v->tt_index = 1;
            else v->tt_index = 2;
    
            lowquant = (v->pq > 12) ? 0 : 1;
            v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)];
            if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
            {
                int scale, shift, i;
                v->mv_mode2 = mv_pmode_table2[lowquant][get_prefix(gb, 1, 3)];
                v->lumscale = get_bits(gb, 6);
                v->lumshift = get_bits(gb, 6);
                /* fill lookup tables for intensity compensation */
                if(!v->lumscale) {
                    scale = -64;
                    shift = (255 - v->lumshift * 2) << 6;
                    if(v->lumshift > 31)
                        shift += 128 << 6;
                } else {
                    scale = v->lumscale + 32;
                    if(v->lumshift > 31)
                        shift = (v->lumshift - 64) << 6;
                    else
                        shift = v->lumshift << 6;
                }
                for(i = 0; i < 256; i++) {
                    v->luty[i] = clip_uint8((scale * i + shift + 32) >> 6);
                    v->lutuv[i] = clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
                }
            }
            if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
                v->s.quarter_sample = 0;
            else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
                if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
                    v->s.quarter_sample = 0;
                else
                    v->s.quarter_sample = 1;
            } else
                v->s.quarter_sample = 1;
            v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
    
            if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
                     v->mv_mode2 == MV_PMODE_MIXED_MV)
                    || v->mv_mode == MV_PMODE_MIXED_MV)
            {
                status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
                if (status < 0) return -1;
                av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
                       "Imode: %i, Invert: %i\n", status>>1, status&1);
            } else {
                v->mv_type_is_raw = 0;
                memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
            }
            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
    
            /* Hopefully this is correct for P frames */
            v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
            v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
            if (v->dquant)
            {
                av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
                vop_dquant_decoding(v);
            }
    
            v->ttfrm = 0; //FIXME Is that so ?
            if (v->vstransform)
            {
                v->ttmbf = get_bits(gb, 1);
                if (v->ttmbf)
                {
                    v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)];
                }
            } else {
                v->ttmbf = 1;
                v->ttfrm = TT_8X8;
            }
            break;
    
        case B_TYPE:
            if(v->postprocflag)
                v->postproc = get_bits1(gb);
            if (v->extended_mv) v->mvrange = get_prefix(gb, 0, 3);
            else v->mvrange = 0;
            v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
            v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
            v->range_x = 1 << (v->k_x - 1);
            v->range_y = 1 << (v->k_y - 1);
    
            if (v->pq < 5) v->tt_index = 0;
            else if(v->pq < 13) v->tt_index = 1;
            else v->tt_index = 2;
    
            lowquant = (v->pq > 12) ? 0 : 1;
            v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
            v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
            v->s.mspel = v->s.quarter_sample;
    
            status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
            if (status < 0) return -1;
            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
                   "Imode: %i, Invert: %i\n", status>>1, status&1);
    
            v->s.mv_table_index = get_bits(gb, 2);
            v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
    
            if (v->dquant)
            {
                av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
                vop_dquant_decoding(v);
            }
    
            v->ttfrm = 0;
            if (v->vstransform)
            {
                v->ttmbf = get_bits(gb, 1);
                if (v->ttmbf)
                {
                    v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)];
                }
            } else {
                v->ttmbf = 1;
                v->ttfrm = TT_8X8;
            }
            break;
    
        }
    
        /* AC Syntax */
        v->c_ac_table_index = decode012(gb);
        if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
        {
            v->y_ac_table_index = decode012(gb);
        }
        /* DC Syntax */
        v->s.dc_table_index = get_bits(gb, 1);
        if (v->s.pict_type == I_TYPE && v->dquant) {
            av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
            vop_dquant_decoding(v);
        }
    
    
        v->bi_type = 0;
        if(v->s.pict_type == BI_TYPE) {
            v->s.pict_type = B_TYPE;
            v->bi_type = 1;
        }
    
    /***********************************************************************/
    /**
    
     * @defgroup block VC-1 Block-level functions
     * @see 7.1.4, p91 and 8.1.1.7, p(1)04
    
    /**
     * @def GET_MQUANT
     * @brief Get macroblock-level quantizer scale
    
    #define GET_MQUANT()                                           \
      if (v->dquantfrm)                                            \
      {                                                            \
    
        if (v->dqprofile == DQPROFILE_ALL_MBS)                     \
        {                                                          \
          if (v->dqbilevel)                                        \
          {                                                        \
    
            mquant = (get_bits(gb, 1)) ? v->altpq : v->pq;         \
    
          }                                                        \
          else                                                     \
          {                                                        \
            mqdiff = get_bits(gb, 3);                              \
            if (mqdiff != 7) mquant = v->pq + mqdiff;              \
            else mquant = get_bits(gb, 5);                         \
          }                                                        \
        }                                                          \
    
        if(v->dqprofile == DQPROFILE_SINGLE_EDGE)                  \
            edges = 1 << v->dqsbedge;                              \
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        else if(v->dqprofile == DQPROFILE_DOUBLE_EDGES)            \
    
            edges = (3 << v->dqsbedge) % 15;                       \
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        else if(v->dqprofile == DQPROFILE_FOUR_EDGES)              \
    
            edges = 15;                                            \
        if((edges&1) && !s->mb_x)                                  \
            mquant = v->altpq;                                     \
    
        if((edges&2) && s->first_slice_line)                       \
    
            mquant = v->altpq;                                     \
        if((edges&4) && s->mb_x == (s->mb_width - 1))              \
            mquant = v->altpq;                                     \
        if((edges&8) && s->mb_y == (s->mb_height - 1))             \
            mquant = v->altpq;                                     \
    
    /**
     * @def GET_MVDATA(_dmv_x, _dmv_y)
     * @brief Get MV differentials
     * @see MVDATA decoding from 8.3.5.2, p(1)20
     * @param _dmv_x Horizontal differential for decoded MV
     * @param _dmv_y Vertical differential for decoded MV
    
    #define GET_MVDATA(_dmv_x, _dmv_y)                                  \
      index = 1 + get_vlc2(gb, vc1_mv_diff_vlc[s->mv_table_index].table,\
                           VC1_MV_DIFF_VLC_BITS, 2);                    \
      if (index > 36)                                                   \
      {                                                                 \
        mb_has_coeffs = 1;                                              \
        index -= 37;                                                    \
      }                                                                 \
      else mb_has_coeffs = 0;                                           \
      s->mb_intra = 0;                                                  \
      if (!index) { _dmv_x = _dmv_y = 0; }                              \
      else if (index == 35)                                             \
      {                                                                 \
    
        _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample);          \
        _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample);          \
    
      }                                                                 \
      else if (index == 36)                                             \
      {                                                                 \
        _dmv_x = 0;                                                     \
        _dmv_y = 0;                                                     \
        s->mb_intra = 1;                                                \
      }                                                                 \
      else                                                              \
      {                                                                 \
        index1 = index%6;                                               \
    
        if (!s->quarter_sample && index1 == 5) val = 1;                 \
        else                                   val = 0;                 \
    
        if(size_table[index1] - val > 0)                                \
            val = get_bits(gb, size_table[index1] - val);               \
        else                                   val = 0;                 \
    
        sign = 0 - (val&1);                                             \
        _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \
                                                                        \
        index1 = index/6;                                               \
    
        if (!s->quarter_sample && index1 == 5) val = 1;                 \
        else                                   val = 0;                 \
    
        if(size_table[index1] - val > 0)                                \
            val = get_bits(gb, size_table[index1] - val);               \
        else                                   val = 0;                 \
    
        sign = 0 - (val&1);                                             \
        _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \
      }
    
    /** Predict and set motion vector
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
    static inline void vc1_pred_mv(MpegEncContext *s, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra)
    
    anonymous's avatar
    anonymous committed
    {
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        int xy, wrap, off = 0;
    
    anonymous's avatar
    anonymous committed
    
    
        /* scale MV difference to be quad-pel */
    
        dmv_x <<= 1 - s->quarter_sample;
        dmv_y <<= 1 - s->quarter_sample;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        xy = s->block_index[n];
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        if(s->mb_intra){
            s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
            s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
            if(mv1) { /* duplicate motion data for 1-MV block */
                s->current_picture.motion_val[0][xy + 1][0] = 0;
                s->current_picture.motion_val[0][xy + 1][1] = 0;
                s->current_picture.motion_val[0][xy + wrap][0] = 0;
                s->current_picture.motion_val[0][xy + wrap][1] = 0;
                s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
                s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
            }
            return;
        }
    
        C = s->current_picture.motion_val[0][xy - 1];
        A = s->current_picture.motion_val[0][xy - wrap];
        if(mv1)
            off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
        else {
            //in 4-MV mode different blocks have different B predictor position
            switch(n){
            case 0:
                off = (s->mb_x > 0) ? -1 : 1;
                break;
            case 1:
                off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
                break;
            case 2:
                off = 1;
                break;
            case 3:
                off = -1;
            }
        }
        B = s->current_picture.motion_val[0][xy - wrap + off];
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        if(!s->first_slice_line || (n==2 || n==3)) { // predictor A is not out of bounds
    
            if(s->mb_width == 1) {
                px = A[0];
                py = A[1];
            } else {
                px = mid_pred(A[0], B[0], C[0]);
                py = mid_pred(A[1], B[1], C[1]);