⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vc9.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (v->profile < PROFILE_ADVANCED)#endif    {        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");            //return -1;        }#if TRACE        av_log(avctx, AV_LOG_INFO,               "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"               "LoopFilter=%i, MultiRes=%i, FastUVMV=%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,               v->rangered, v->vstransform, v->overlap, v->s.resync_marker,               v->dquant, v->quantizer_mode, avctx->max_b_frames               );        return 0;#endif    }#if HAS_ADVANCED_PROFILE    else return decode_advanced_sequence_header(avctx, gb);#endif}#if HAS_ADVANCED_PROFILE/** Entry point decoding (Advanced Profile) * @param avctx Codec context * @param gb GetBit context initialized from avctx->extra_data * @return Status */static int advanced_entry_point_process(AVCodecContext *avctx, GetBitContext *gb){    VC9Context *v = avctx->priv_data;    int i;    if (v->profile != PROFILE_ADVANCED)    {        av_log(avctx, AV_LOG_ERROR,               "Entry point are only defined in Advanced Profile!\n");        return -1; //Only for advanced profile!    }    if (v->hrd_param_flag)    {        //Update buffer fullness        av_log(avctx, AV_LOG_DEBUG, "Buffer fullness update\n");        assert(v->hrd_num_leaky_buckets > 0);        for (i=0; i<v->hrd_num_leaky_buckets; i++)            v->hrd_fullness[i] = get_bits(gb, 8);    }    if ((v->range_mapy_flag = get_bits(gb, 1)))    {        //RANGE_MAPY        av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPY\n");        v->range_mapy = get_bits(gb, 3);    }    if ((v->range_mapuv_flag = get_bits(gb, 1)))    {        //RANGE_MAPUV        av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPUV\n");        v->range_mapuv = get_bits(gb, 3);    }    if (v->panscanflag)    {        //NUMPANSCANWIN        v->numpanscanwin = get_bits(gb, 3);        av_log(avctx, AV_LOG_DEBUG, "NUMPANSCANWIN: %u\n", v->numpanscanwin);    }    return 0;}#endif/***********************************************************************//** * @defgroup bitplane VC9 Bitplane decoding * @see 8.7, p56 * @{ *//** @addtogroup bitplane * Imode types * @{ */#define IMODE_RAW     0#define IMODE_NORM2   1#define IMODE_DIFF2   2#define IMODE_NORM6   3#define IMODE_DIFF6   4#define IMODE_ROWSKIP 5#define IMODE_COLSKIP 6/** @} */ //imode defines/** Allocate the buffer from a bitplane, given its dimensions * @param bp Bitplane which buffer is to allocate * @param[in] width Width of the buffer * @param[in] height Height of the buffer * @return Status * @todo TODO: Take into account stride * @todo TODO: Allow use of external buffers ? */static int alloc_bitplane(BitPlane *bp, int width, int height){    if (!bp || bp->width<0 || bp->height<0) return -1;    bp->data = (uint8_t*)av_malloc(width*height);    if (!bp->data) return -1;    bp->width = bp->stride = width;    bp->height = height;    return 0;}/** Free the bitplane's buffer * @param bp Bitplane which buffer is to free */static void free_bitplane(BitPlane *bp){    bp->width = bp->stride = bp->height = 0;    if (bp->data) av_freep(&bp->data);}/** 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;    for (y=0; y<height; y++){        if (!get_bits(gb, 1)) //rowskip            memset(plane, 0, width);        else            for (x=0; x<width; x++)                plane[x] = get_bits(gb, 1);        plane += stride;    }}/** 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 * @fixme FIXME: Optimize */static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){    int x, y;    for (x=0; x<width; x++){        if (!get_bits(gb, 1)) //colskip            for (y=0; y<height; y++)                plane[y*stride] = 0;        else            for (y=0; y<height; y++)                plane[y*stride] = get_bits(gb, 1);        plane ++;    }}/** Decode a bitplane's bits * @param bp Bitplane where to store the decode bits * @param v VC9 context for bit reading and logging * @return Status * @fixme FIXME: Optimize * @todo TODO: Decide if a struct is needed */static int bitplane_decoding(BitPlane *bp, VC9Context *v){    GetBitContext *gb = &v->s.gb;    int imode, x, y, code, use_vertical_tile, tile_w, tile_h, offset;    uint8_t invert, *planep = bp->data;    invert = get_bits(gb, 1);    imode = get_vlc2(gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2);    bp->is_raw = 0;    switch (imode)    {    case IMODE_RAW:        //Data is actually read in the MB layer (same for all tests == "raw")        bp->is_raw = 1; //invert ignored        return invert;    case IMODE_DIFF2:    case IMODE_NORM2:        if ((bp->height*bp->width) & 1)        {            *(++planep) = get_bits(gb, 1);            offset = x = 1;        }        else offset = x = 0;        for (y=0; y<bp->height; y++)        {            for(; x<bp->width; x+=2)            {                code = get_vlc2(gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);                *(++planep) = code&1; //lsb => left                *(++planep) = (code>>1)&1; //msb => right            }            planep += bp->stride-bp->width;            if ((bp->width-offset)&1) //Odd number previously processed            {                code = get_vlc2(gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);                *planep = code&1;                planep += bp->stride-bp->width;                *planep = (code>>1)&1; //msb => right                offset = x = 1;            }            else            {                offset = x = 0;                planep += bp->stride-bp->width;            }        }        break;    case IMODE_DIFF6:    case IMODE_NORM6:        use_vertical_tile=  bp->height%3==0 &&  bp->width%3!=0;        tile_w= use_vertical_tile ? 2 : 3;        tile_h= use_vertical_tile ? 3 : 2;        for(y=  bp->height%tile_h; y< bp->height; y+=tile_h){            for(x=  bp->width%tile_w; x< bp->width; x+=tile_w){                code = get_vlc2(gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2);                if(code<0){                    av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");                    return -1;                }                //FIXME following is a pure guess and probably wrong                //FIXME A bitplane (0 | !0), so could the shifts be avoided ?                planep[x     + 0*bp->stride]= (code>>0)&1;                planep[x + 1 + 0*bp->stride]= (code>>1)&1;                //FIXME Does branch prediction help here?                if(use_vertical_tile){                    planep[x + 0 + 1*bp->stride]= (code>>2)&1;                    planep[x + 1 + 1*bp->stride]= (code>>3)&1;                    planep[x + 0 + 2*bp->stride]= (code>>4)&1;                    planep[x + 1 + 2*bp->stride]= (code>>5)&1;                }else{                    planep[x + 2 + 0*bp->stride]= (code>>2)&1;                    planep[x + 0 + 1*bp->stride]= (code>>3)&1;                    planep[x + 1 + 1*bp->stride]= (code>>4)&1;                    planep[x + 2 + 1*bp->stride]= (code>>5)&1;                }            }        }        x=  bp->width % tile_w;        decode_colskip(bp->data  ,             x, bp->height         , bp->stride, &v->s.gb);        decode_rowskip(bp->data+x, bp->width - x, bp->height % tile_h, bp->stride, &v->s.gb);        break;    case IMODE_ROWSKIP:        decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);        break;    case IMODE_COLSKIP:        decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);        break;    default: break;    }    /* Applying diff operator */    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)    {        planep = bp->data;        planep[0] ^= invert;        for (x=1; x<bp->width; x++)            planep[x] ^= planep[x-1];        for (y=1; y<bp->height; y++)        {            planep += bp->stride;            planep[0] ^= planep[-bp->stride];            for (x=1; x<bp->width; x++)            {                if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;                else                                     planep[x] ^= planep[x-1];            }        }    }    else if (invert)    {        planep = bp->data;        for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride    }    return (imode<<1) + invert;}/** @} */ //Bitplane group/***********************************************************************//** VOP Dquant decoding * @param v VC9 Context */static int vop_dquant_decoding(VC9Context *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    {        v->dquantfrm = get_bits(gb, 1);        if ( v->dquantfrm )        {            v->dqprofile = get_bits(gb, 2);            switch (v->dqprofile)            {            case DQPROFILE_SINGLE_EDGE:            case DQPROFILE_DOUBLE_EDGES:                v->dqsbedge = get_bits(gb, 2);                break;            case DQPROFILE_ALL_MBS:                v->dqbilevel = get_bits(gb, 1);            default: break; //Forbidden ?            }            if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)            {                pqdiff = get_bits(gb, 3);                if (pqdiff == 7) v->altpq = get_bits(gb, 5);                else v->altpq = v->pq + pqdiff + 1;            }        }    }    return 0;}/***********************************************************************//** * @defgroup all_frame_hdr All VC9 profiles frame header * @brief Part of the frame header decoding from all profiles * @warning Only pro/epilog differs between Simple/Main and Advanced => check caller * @{ *//** B and BI frame header decoding, primary part * @see Tables 11+12, p62-65 * @param v VC9 context * @return Status * @warning Also handles BI frames */static int decode_b_picture_primary_header(VC9Context *v){    GetBitContext *gb = &v->s.gb;    int pqindex;    /* Prolog common to all frametypes should be done in caller */    if (v->profile == PROFILE_SIMPLE)    {        av_log(v->s.avctx, AV_LOG_ERROR, "Found a B frame while in Simple Profile!\n");        return FRAME_SKIPPED;    }    v->bfraction = vc9_bfraction_lut[get_vlc2(gb, vc9_bfraction_vlc.table,                                              VC9_BFRACTION_VLC_BITS, 2)];    if (v->bfraction < -1)    {        av_log(v->s.avctx, AV_LOG_ERROR, "Invalid BFRaction\n");        return FRAME_SKIPPED;    }    else if (!v->bfraction)    {        /* We actually have a BI frame */        v->s.pict_type = BI_TYPE;        v->buffer_fullness = get_bits(gb, 7);    }    /* Read the quantization stuff */    pqindex = get_bits(gb, 5);    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)        v->pq = pquant_table[0][pqindex];    else    {        v->pq = pquant_table[v->quantizer_mode-1][pqindex];    }    if (pqindex < 9) v->halfpq = get_bits(gb, 1);    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)        v->pquantizer = get_bits(gb, 1);#if HAS_ADVANCED_PROFILE    if (v->profile == PROFILE_ADVANCED)    {        if (v->postprocflag) v->postproc = get_bits(gb, 2);        if (v->extended_mv == 1 && v->s.pict_type != BI_TYPE)            v->mvrange = get_prefix(gb, 0, 3);    }#endif    else    {        if (v->extended_mv == 1)            v->mvrange = get_prefix(gb, 0, 3);    }    /* Read the MV mode */    if (v->s.pict_type != BI_TYPE)    {        v->mv_mode = get_bits(gb, 1);        if (v->pq < 13)        {            if (!v->mv_mode)            {                v->mv_mode = get_bits(gb, 2);                if (v->mv_mode)                av_log(v->s.avctx, AV_LOG_ERROR,                       "mv_mode for lowquant B frame was %i\n", v->mv_mode);            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -