📄 vc1.c
字号:
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 + -