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

📄 vc9.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
    {    case P_TYPE: status = decode_p_picture_secondary_header(v); break;    case B_TYPE: status = decode_b_picture_secondary_header(v); break;    case BI_TYPE:    case I_TYPE: status = decode_i_picture_secondary_header(v); break;    }    if (status<0) return FRAME_SKIPPED;    /* 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 = decode012(gb);    return 0;}#endif/** @} */ //End for adv_frame_hdr/***********************************************************************//** * @defgroup block VC9 Block-level functions * @see 7.1.4, p91 and 8.1.1.7, p(1)04 * @todo TODO: Integrate to MpegEncContext facilities * @{ *//** * @def GET_MQUANT * @brief Get macroblock-level quantizer scale * @warning XXX: qdiff to the frame quant, not previous quant ? * @fixme XXX: Don't know how to initialize mquant otherwise in last case */#define GET_MQUANT()                                           \  if (v->dquantfrm)                                            \  {                                                            \    if (v->dqprofile == DQPROFILE_ALL_MBS)                     \    {                                                          \      if (v->dqbilevel)                                        \      {                                                        \        mquant = (get_bits(gb, 1)) ? v->pq : v->altpq;         \      }                                                        \      else                                                     \      {                                                        \        mqdiff = get_bits(gb, 3);                              \        if (mqdiff != 7) mquant = v->pq + mqdiff;              \        else mquant = get_bits(gb, 5);                         \      }                                                        \    }                                                          \    else mquant = v->pq;                                       \  }/** * @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 * @todo TODO: Use MpegEncContext arrays to store them */#define GET_MVDATA(_dmv_x, _dmv_y)                                  \  index = 1 + get_vlc2(gb, vc9_mv_diff_vlc[s->mv_table_index].table,\                       VC9_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);                                  \    _dmv_y = get_bits(gb, v->k_y);                                  \    s->mb_intra = 1;                                                \  }                                                                 \  else                                                              \  {                                                                 \    index1 = index%6;                                               \    if (s->mspel && index1 == 5) val = 1;                           \    else                         val = 0;                           \    val = get_bits(gb, size_table[index1] - val);                   \    sign = 0 - (val&1);                                             \    _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \                                                                    \    index1 = index/6;                                               \    if (s->mspel && index1 == 5) val = 1;                           \    else                          val = 0;                          \    val = get_bits(gb, size_table[index1] - val);                   \    sign = 0 - (val&1);                                             \    _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \  }/** Get predicted DC value * prediction dir: left=0, top=1 * @param s MpegEncContext * @param[in] n block index in the current MB * @param dc_val_ptr Pointer to DC predictor * @param dir_ptr Prediction direction for use in AC prediction * @todo TODO: Actually do it the VC9 way * @todo TODO: Handle properly edges */static inline int vc9_pred_dc(MpegEncContext *s, int n,                              uint16_t **dc_val_ptr, int *dir_ptr){    int a, b, c, wrap, pred, scale;    int16_t *dc_val;    static const uint16_t dcpred[31] = {        1024,  512,  341,  256,  205,  171,  146,  128,         114,  102,   93,   85,   79,   73,   68,   64,          60,   57,   54,   51,   49,   47,   45,   43,          41,   39,   38,   37,   35,   34,   33    };    /* find prediction - wmv3_dc_scale always used here in fact */    if (n < 4)     scale = s->y_dc_scale;    else           scale = s->c_dc_scale;    wrap = s->block_wrap[n];    dc_val= s->dc_val[0] + s->block_index[n];    /* B C     * A X     */    a = dc_val[ - 1];    b = dc_val[ - 1 - wrap];    c = dc_val[ - wrap];    /* XXX: Rule B is used only for I and BI frames in S/M/C profile     *      with overlap filtering off     */    if ((s->pict_type == I_TYPE || s->pict_type == BI_TYPE) &&        1 /* XXX: overlap filtering off */)    {        /* Set outer values */        if (s->first_slice_line && n!=2) b=c=dcpred[scale];        if (s->mb_x == 0) b=a=dcpred[scale];    }    else    {        /* Set outer values */        if (s->first_slice_line && n!=2) b=c=0;        if (s->mb_x == 0) b=a=0;        /* XXX: Rule A needs to know if blocks are inter or intra :/ */        if (0)        {            /* update predictor */            *dc_val_ptr = &dc_val[0];            dir_ptr = 0;            return a;        }    }    if (abs(a - b) <= abs(b - c)) {        pred = c;        *dir_ptr = 1;    } else {        pred = a;        *dir_ptr = 0;    }    /* update predictor */    *dc_val_ptr = &dc_val[0];    return pred;}/** Decode one block, inter or intra * @param v The VC9 context * @param block 8x8 DCT block * @param n Block index in the current MB (<4=>luma) * @param coded If the block is coded * @param mquant Quantizer step for the current block * @see Inter TT: Table 21, p73 + p91-85 * @see Intra TT: Table 20, p72 + p(1)05-(1)07 * @todo TODO: Process the blocks * @todo TODO: Use M$ MPEG-4 cbp prediction */static int vc9_decode_block(VC9Context *v, DCTELEM block[64], int n, int coded, int mquant){    GetBitContext *gb = &v->s.gb;    MpegEncContext *s = &v->s;    int ttblk; /* Transform Type per Block */    int subblkpat; /* Sub-block Transform Type Pattern */    int dc_pred_dir; /* Direction of the DC prediction used */    int run_diff, i;    /* XXX: Guard against dumb values of mquant */    mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );    /* Set DC scale - y and c use the same */    s->y_dc_scale = s->y_dc_scale_table[mquant];    s->c_dc_scale = s->c_dc_scale_table[mquant];    if (s->mb_intra)    {        int dcdiff;        uint16_t *dc_val;        /* Get DC differential */        if (n < 4) {            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);        } else {            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);        }        if (dcdiff < 0){            av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");            return -1;        }        if (dcdiff)        {            if (dcdiff == 119 /* ESC index value */)            {                /* TODO: Optimize */                if (mquant == 1) dcdiff = get_bits(gb, 10);                else if (mquant == 2) dcdiff = get_bits(gb, 9);                else dcdiff = get_bits(gb, 8);            }            else            {                if (mquant == 1)                  dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;                else if (mquant == 2)                  dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;            }            if (get_bits(gb, 1))              dcdiff = -dcdiff;        }        /* Prediction */        dcdiff += vc9_pred_dc(s, n, &dc_val, &dc_pred_dir);        *dc_val = dcdiff;        /* Store the quantized DC coeff, used for prediction */        if (n < 4) {            block[0] = dcdiff * s->y_dc_scale;        } else {            block[0] = dcdiff * s->c_dc_scale;        }        if (block[0] < 0) {#if TRACE            //av_log(s->avctx, AV_LOG_ERROR, "DC=%i<0\n", dcdiff);#endif            //return -1;        }        /* Skip ? */        run_diff = 0;        i = 0;        if (!coded) {            goto not_coded;        }    }    else    {        mquant = v->pq;        /* Get TTBLK */        if (v->ttmb < 8) /* per block */            ttblk = get_vlc2(gb, vc9_ttblk_vlc[v->tt_index].table, VC9_TTBLK_VLC_BITS, 2);        else /* Per frame */          ttblk = 0; //FIXME, depends on ttfrm        /* Get SUBBLKPAT */        if (ttblk == v->ttblk4x4) /* 4x4 transform for that qp value */            subblkpat = 1+get_vlc2(gb, vc9_subblkpat_vlc[v->tt_index].table,                                   VC9_SUBBLKPAT_VLC_BITS, 2);        else /* All others: 8x8, 4x8, 8x4 */            subblkpat = decode012(gb);    }    //TODO AC Decoding    i = 63; //XXX: nothing done yet not_coded:    if (s->mb_intra) {        mpeg4_pred_ac(s, block, n, dc_pred_dir);        if (s->ac_pred) {            i = 63; /* XXX: not optimal */        }    }    if(i>0) i=63; //FIXME/XXX optimize    s->block_last_index[n] = i;    return 0;}/** @} */ //End for group block/***********************************************************************//** * @defgroup std_mb VC9 Macroblock-level functions in Simple/Main Profiles * @see 7.1.4, p91 and 8.1.1.7, p(1)04 * @todo TODO: Integrate to MpegEncContext facilities * @{ */static inline int vc9_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr){    int xy, wrap, pred, a, b, c;    xy = s->block_index[n];    wrap = s->b8_stride;    /* B C     * A X     */    a = s->coded_block[xy - 1       ];    b = s->coded_block[xy - 1 - wrap];    c = s->coded_block[xy     - wrap];    if (b == c) {        pred = a;    } else {        pred = c;    }    /* store value */    *coded_block_ptr = &s->coded_block[xy];    return pred;}/** Decode one I-frame MB (in Simple/Main profile) * @todo TODO: Extend to AP */static int vc9_decode_i_mb(VC9Context *v, DCTELEM block[6][64]){    int i, cbp, val;    uint8_t *coded_val;//    uint32_t * const mb_type_ptr= &v->s.current_picture.mb_type[ v->s.mb_x + v->s.mb_y*v->s.mb_stride ];    v->s.mb_intra = 1;    cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);    if (cbp < 0) return -1;    v->s.ac_pred = get_bits(&v->s.gb, 1);    for (i=0; i<6; i++)    {        val = ((cbp >> (5 - i)) & 1);        if (i < 4) {            int pred = vc9_coded_block_pred(&v->s, i, &coded_val);            val = val ^ pred;            *coded_val = val;        }        cbp |= val << (5 - i);        if (vc9_decode_block(v, block[i], i, val, v->pq) < 0) //FIXME Should be mquant        {            av_log(v->s.avctx, AV_LOG_ERROR,                   "\nerror while decoding block: %d x %d (%d)\n", v->s.mb_x, v->s.mb_y, i);            return -1;        }    }    return 0;}/** Decode one P-frame MB (in Simple/Main profile) * @todo TODO: Extend to AP * @fixme FIXME: DC value for inter blocks not set */static int vc9_decode_p_mb(VC9Context *v, DCTELEM block[6][64]){    MpegEncContext *s = &v->s;    GetBitContext *gb = &s->gb;    int i, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */    int cbp; /* cbp decoding stuff */    int hybrid_pred; /* Prediction types */    int mv_mode_bit = 0;    int mqdiff, mquant; /* MB quantization */    int ttmb; /* MB Transform type */    int status;    uint8_t *coded_val;    static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },      offset_table[6] = { 0, 1, 3, 7, 15, 31 };    int mb_has_coeffs = 1; /* last_flag */    int dmv_x, dmv_y; /* Differential MV components */    int index, index1; /* LUT indices */    int val, sign; /* temp values */    mquant = v->pq; /* Loosy initialization */    if (v->mv_type_mb_plane.is_raw)        v->mv_type_mb_plane.data[mb_offset] = get_bits(gb, 1);    if (v->skip_mb_plane.is_raw)        v->skip_mb_plane.data[mb_offset] = get_bits(gb, 1);    if (!mv_mode_bit) /* 1MV mode */    {        if (!v->skip_mb_plane.data[mb_offset])        {            GET_MVDATA(dmv_x, dmv_y);            /* hybrid mv pred, 8.3.5.3.4 */            if (v->mv_mode == MV_PMODE_1MV ||                v->mv_mode == MV_PMODE_MIXED_MV)                hybrid_pred = get_bits(gb, 1);            /* FIXME Set DC val for inter block ? */            if (s->mb_intra && !mb_has_coeffs)            {                GET_MQUANT();                s->ac_pred = get_bits(gb, 1);                /* XXX: how to handle cbp ? */                cbp = 0;                for (i=0; i<6; i++)                {                     s->coded_block[s->block_index[i]] = 0;                     vc9_decode_block(v, block[i], i, 0, mquant);                }            

⌨️ 快捷键说明

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