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

📄 vc1.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (v->extended_mv) v->mvrange = get_unary(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 = &ff_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_bits1(gb);            if (v->ttmbf)            {                v->ttfrm = ff_vc1_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_bits1(gb);    if ((v->s.pict_type == I_TYPE || v->s.pict_type == BI_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;    }    return 0;}/***********************************************************************//** * @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)                                            \  {                                                            \    int edges = 0;                                             \    if (v->dqprofile == DQPROFILE_ALL_MBS)                     \    {                                                          \      if (v->dqbilevel)                                        \      {                                                        \        mquant = (get_bits1(gb)) ? 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;                              \    else if(v->dqprofile == DQPROFILE_DOUBLE_EDGES)            \        edges = (3 << v->dqsbedge) % 15;                       \    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, ff_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 */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){    int xy, wrap, off = 0;    int16_t *A, *B, *C;    int px, py;    int sum;    /* scale MV difference to be quad-pel */    dmv_x <<= 1 - s->quarter_sample;    dmv_y <<= 1 - s->quarter_sample;    wrap = s->b8_stride;    xy = s->block_index[n];    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;        s->current_picture.motion_val[1][xy][0] = 0;        s->current_picture.motion_val[1][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;            s->current_picture.motion_val[1][xy + 1][0] = 0;            s->current_picture.motion_val[1][xy + 1][1] = 0;            s->current_picture.motion_val[1][xy + wrap][0] = 0;            s->current_picture.motion_val[1][xy + wrap][1] = 0;            s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;            s->current_picture.motion_val[1][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];    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]);        }    } else if(s->mb_x || (n==1 || n==3)) { // predictor C is not out of bounds        px = C[0];        py = C[1];    } else {        px = py = 0;    }    /* Pullback MV as specified in 8.3.5.3.4 */    {        int qx, qy, X, Y;        qx = (s->mb_x << 6) + ((n==1 || n==3) ? 32 : 0);        qy = (s->mb_y << 6) + ((n==2 || n==3) ? 32 : 0);        X = (s->mb_width << 6) - 4;        Y = (s->mb_height << 6) - 4;        if(mv1) {            if(qx + px < -60) px = -60 - qx;            if(qy + py < -60) py = -60 - qy;        } else {            if(qx + px < -28) px = -28 - qx;            if(qy + py < -28) py = -28 - qy;        }        if(qx + px > X) px = X - qx;        if(qy + py > Y) py = Y - qy;    }    /* Calculate hybrid prediction as specified in 8.3.5.3.5 */    if((!s->first_slice_line || (n==2 || n==3)) && (s->mb_x || (n==1 || n==3))) {        if(is_intra[xy - wrap])            sum = FFABS(px) + FFABS(py);        else            sum = FFABS(px - A[0]) + FFABS(py - A[1]);        if(sum > 32) {            if(get_bits1(&s->gb)) {                px = A[0];                py = A[1];            } else {                px = C[0];                py = C[1];            }        } else {            if(is_intra[xy - 1])                sum = FFABS(px) + FFABS(py);            else                sum = FFABS(px - C[0]) + FFABS(py - C[1]);            if(sum > 32) {                if(get_bits1(&s->gb)) {                    px = A[0];                    py = A[1];                } else {                    px = C[0];                    py = C[1];                }            }        }    }    /* store MV using signed modulus of MV range defined in 4.11 */    s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;    s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;    if(mv1) { /* duplicate motion data for 1-MV block */        s->current_picture.motion_val[0][xy + 1][0] = s->current_picture.motion_val[0][xy][0];        s->current_picture.motion_val[0][xy + 1][1] = s->current_picture.motion_val[0][xy][1];        s->current_picture.motion_val[0][xy + wrap][0] = s->current_picture.motion_val[0][xy][0];        s->current_picture.motion_val[0][xy + wrap][1] = s->current_picture.motion_val[0][xy][1];        s->current_picture.motion_val[0][xy + wrap + 1][0] = s->current_picture.motion_val[0][xy][0];        s->current_picture.motion_val[0][xy + wrap + 1][1] = s->current_picture.motion_val[0][xy][1];    }}/** Motion compensation for direct or interpolated blocks in B-frames */static void vc1_interp_mc(VC1Context *v){    MpegEncContext *s = &v->s;    DSPContext *dsp = &v->s.dsp;    uint8_t *srcY, *srcU, *srcV;    int dxy, uvdxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;    if(!v->s.next_picture.data[0])return;    mx = s->mv[1][0][0];    my = s->mv[1][0][1];    uvmx = (mx + ((mx & 3) == 3)) >> 1;    uvmy = (my + ((my & 3) == 3)) >> 1;    if(v->fastuvmc) {        uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));        uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));    }    srcY = s->next_picture.data[0];    srcU = s->next_picture.data[1];    srcV = s->next_picture.data[2];    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);    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);    }    srcY += src_y * s->linesize + src_x;    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;    /* 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;    }    if(v->rangeredfrm       || (unsigned)src_x > s->h_edge_pos - (mx&3) - 16       || (unsigned)src_y > s->v_edge_pos - (my&3) - 16){        uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;        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);        srcY = s->edge_emu_buffer;        ff_emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8+1, 8

⌨️ 快捷键说明

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