📄 umc_h264_bs.cpp
字号:
// ---------------------------------------------------------------------------void CH264pBs::PutTR(const Ipp32u tr){ PutBits(tr, FIELDLEN_TR);} // CH264pBs::PutTR()// ---------------------------------------------------------------------------// CH264pBs::PutDQUANT()// ---------------------------------------------------------------------------void CH264pBs::PutDQUANT ( const Ipp32u quant, const Ipp32u quant_prev ){ Ipp32s dquant; // compute dquant dquant=quant-quant_prev; // Get dquant between (QP_RANGE-1) to (-QP_RANGE) (25 to -26 for JVT) if (dquant >= H264_QP_RANGE) dquant = dquant - H264_QP_MAX; else if (dquant < -H264_QP_RANGE) dquant = dquant + H264_QP_MAX; PutVLCCode(SIGNED_VLC_CODE(dquant));} // CH264pbs::PutDQUANT()// ---------------------------------------------------------------------------// CH264pBs::PutPQUANT()// ---------------------------------------------------------------------------void CH264pBs::PutPQUANT(const Ipp32u pquant){ PutBits(pquant, FIELDLEN_PQUANT);} // CH264pbs::PutPQUANT()// ---------------------------------------------------------------------------// CH264pBs::PutDBQ()// ---------------------------------------------------------------------------void CH264pBs::PutDBQ(const Ipp32u dbq){ PutBits(dbq, FIELDLEN_DBQUANT);} // CH264pbs::PutDBQ()// ---------------------------------------------------------------------------// CH264pBs::PutSliceHeader()// ---------------------------------------------------------------------------Status CH264pBs::PutSliceHeader(H264SliceHeader const slice_hdr, H264PicParamSet const pic_parms, H264SeqParamSet const seq_parms, EnumPicClass const ePictureClass){ Status ps = UMC_OK; // Write first_mb_in_slice PutVLCCode(slice_hdr.first_mb_in_slice); // Write slice_type_idc PutVLCCode(slice_hdr.slice_type); // Write pic_parameter_set_id PutVLCCode(slice_hdr.pic_parameter_set_id); // Write frame_num (modulo MAX_FN) using log2_max_frame_num bits PutBits(slice_hdr.frame_num, seq_parms.log2_max_frame_num); // Only write field values if not frame only... if (!seq_parms.frame_mbs_only_flag) { // Write field_pic_flag PutBits(slice_hdr.field_pic_flag, 1); // Write bottom_field_flag if (slice_hdr.field_pic_flag == 1) { PutBits(slice_hdr.bottom_field_flag, 1); } } if (ePictureClass == IDR_PIC) { PutVLCCode(slice_hdr.idr_pic_id); } // Write pic_order_cnt info if (seq_parms.pic_order_cnt_type == 0) { PutBits(slice_hdr.pic_order_cnt_lsb, seq_parms.log2_max_pic_order_cnt_lsb); if ((pic_parms.pic_order_present_flag == 1) && (!slice_hdr.field_pic_flag)) { PutVLCCode(SIGNED_VLC_CODE(slice_hdr.delta_pic_order_cnt_bottom)); } } // Handle Redundant Slice Flag if (pic_parms.redundant_pic_cnt_present_flag) { PutVLCCode(slice_hdr.redundant_pic_cnt); } // Write direct_spatial_mv_pred_flag if this is a BPREDSLICE if (slice_hdr.slice_type == BPREDSLICE) { PutBits(slice_hdr.direct_spatial_mv_pred_flag, 1); } if ((slice_hdr.slice_type == BPREDSLICE) || (slice_hdr.slice_type == S_PREDSLICE) || (slice_hdr.slice_type == PREDSLICE)) { // Write num_ref_idx_active_override_flag PutBits(slice_hdr.num_ref_idx_active_override_flag, 1); if (slice_hdr.num_ref_idx_active_override_flag) { PutVLCCode(slice_hdr.num_ref_idx_l0_active - 1); if (slice_hdr.slice_type == BPREDSLICE) { PutVLCCode(slice_hdr.num_ref_idx_l1_active - 1); } } } // ref_pic_list_reordering() default settings if ((slice_hdr.slice_type != INTRASLICE) && (slice_hdr.slice_type != S_INTRASLICE)) { // ref_pic_list_reordering_flag_l0 PutBits(0,1); // More data would be inserted here if the above flag is 1 if (slice_hdr.slice_type == BPREDSLICE) { // ref_pic_list_reordering_flag_l1 PutBits(0,1); // More data would be inserted here if the above flag is 1 } } if ((pic_parms.weighted_pred_flag && (slice_hdr.slice_type == PREDSLICE || slice_hdr.slice_type == S_PREDSLICE)) || ((pic_parms.weighted_bipred_idc == 1) && slice_hdr.slice_type == BPREDSLICE)) { // Add support for pred_weight_table() ??? } // Write appropriate bits for dec_ref_pic_marking() // Note! Currently there are no structure members for these syntax elements, // so the default bits are just written directly. This need to be updated // when appropriate structures are implemented. TODO - VSI if (ePictureClass == IDR_PIC) { // no_output_of_prior_pics_flag PutBits(0, 1); // long_term_reference_flag PutBits(0, 1); } else if (ePictureClass == REFERENCE_PIC) { // adaptive_ref_pic_marking_mode_flag PutBits(slice_hdr.adaptive_ref_pic_marking_mode_flag, 1); // Other things would be written here if memory management control // were to be implemented, changing the value of the adaptive_ref_pic_marking_mode_flag // written above to 1. } if (pic_parms.entropy_coding_mode && slice_hdr.slice_type != INTRASLICE && slice_hdr.slice_type != S_INTRASLICE) { PutVLCCode(slice_hdr.cabac_init_idc); } // Write slice_qp_delta PutVLCCode(SIGNED_VLC_CODE(slice_hdr.slice_qp_delta)); // No sp_for_switch_flag or slice_qp_s_delta are written because we don't // support SI and SP slices if ((slice_hdr.slice_type == S_PREDSLICE) || (slice_hdr.slice_type == S_INTRASLICE)) { if (slice_hdr.slice_type == S_PREDSLICE) PutBits(slice_hdr.sp_for_switch_flag, 1); // Write slice_qp_s_delta PutVLCCode(SIGNED_VLC_CODE(slice_hdr.slice_qs_delta)); } // Write Filter Parameters if (pic_parms.deblocking_filter_variables_present_flag) { // Write disable_deblocking_filter_idc PutVLCCode(slice_hdr.disable_deblocking_filter_idc); if (slice_hdr.disable_deblocking_filter_idc != 1) { // Write slice_alpha_c0_offset_div2 PutVLCCode(SIGNED_VLC_CODE(slice_hdr.slice_alpha_c0_offset>>1)); // Write slice_beta_offset_div2 PutVLCCode(SIGNED_VLC_CODE(slice_hdr.slice_beta_offset>>1)); } else { // If the filter is disabled, both offsets are -51 } } else { // If no parms are written, then the filter is ON } if (pic_parms.num_slice_groups > 1) { // Write slice_group_change_cycle } return ps;} // CH264pBs::PutSliceHeader()// Encoder Lookup tables for encoding coeff_tokentypedef struct { Ipp8u code; Ipp8u len;} struct_CodeEntry;static const struct_CodeEntry EncTotalCoeff[4][17][4] ={ { // Num-VLC0 // 0 1 2 3 <-- Trailing Ones { { 1, 1},{ 0, 0},{ 0, 0},{ 0, 0} }, // 0 Total_Coeffs { { 5, 6},{ 1, 2},{ 0, 0},{ 0, 0} }, // 1 Total_Coeffs { { 7, 8},{ 4, 6},{ 1, 3},{ 0, 0} }, // 2 Total_Coeffs { { 7, 9},{ 6, 8},{ 5, 7},{ 3, 5} }, // 3 Total_Coeffs { { 7,10},{ 6, 9},{ 5, 8},{ 3, 6} }, // 4 Total_Coeffs { { 7,11},{ 6,10},{ 5, 9},{ 4, 7} }, // 5 Total_Coeffs { {15,13},{ 6,11},{ 5,10},{ 4, 8} }, // 6 Total_Coeffs { {11,13},{14,13},{ 5,11},{ 4, 9} }, // 7 Total_Coeffs { { 8,13},{10,13},{13,13},{ 4,10} }, // 8 Total_Coeffs { {15,14},{14,14},{ 9,13},{ 4,11} }, // 9 Total_Coeffs { {11,14},{10,14},{13,14},{12,13} }, // 10 Total_Coeffs { {15,15},{14,15},{ 9,14},{12,14} }, // 11 Total_Coeffs { {11,15},{10,15},{13,15},{ 8,14} }, // 12 Total_Coeffs { {15,16},{ 1,15},{ 9,15},{12,15} }, // 13 Total_Coeffs { {11,16},{14,16},{13,16},{ 8,15} }, // 14 Total_Coeffs { { 7,16},{10,16},{ 9,16},{12,16} }, // 15 Total_Coeffs { { 4,16},{ 6,16},{ 5,16},{ 8,16} } // 16 Total_Coeffs }, { // Num-VLC1 // 0 1 2 3 <-- Trailing Ones { { 3, 2},{ 0, 0},{ 0, 0},{ 0, 0} }, // 0 Total_Coeffs { {11, 6},{ 2, 2},{ 0, 0},{ 0, 0} }, // 1 Total_Coeffs { { 7, 6},{ 7, 5},{ 3, 3},{ 0, 0} }, // 2 Total_Coeffs { { 7, 7},{10, 6},{ 9, 6},{ 5, 4} }, // 3 Total_Coeffs { { 7, 8},{ 6, 6},{ 5, 6},{ 4, 4} }, // 4 Total_Coeffs { { 4, 8},{ 6, 7},{ 5, 7},{ 6, 5} }, // 5 Total_Coeffs { { 7, 9},{ 6, 8},{ 5, 8},{ 8, 6} }, // 6 Total_Coeffs { {15,11},{ 6, 9},{ 5, 9},{ 4, 6} }, // 7 Total_Coeffs { {11,11},{14,11},{13,11},{ 4, 7} }, // 8 Total_Coeffs { {15,12},{10,11},{ 9,11},{ 4, 9} }, // 9 Total_Coeffs { {11,12},{14,12},{13,12},{12,11} }, // 10 Total_Coeffs { { 8,12},{10,12},{ 9,12},{ 8,11} }, // 11 Total_Coeffs { {15,13},{14,13},{13,13},{12,12} }, // 12 Total_Coeffs { {11,13},{10,13},{ 9,13},{12,13} }, // 13 Total_Coeffs { { 7,13},{11,14},{ 6,13},{ 8,13} }, // 14 Total_Coeffs { { 9,14},{ 8,14},{10,14},{ 1,13} }, // 15 Total_Coeffs { { 7,14},{ 6,14},{ 5,14},{ 4,14} } // 16 Total_Coeffs }, { // Num-VLC2 // 0 1 2 3 <-- Trailing Ones { {15, 4},{ 0, 0},{ 0, 0},{ 0, 0} }, // 0 Total_Coeffs { {15, 6},{14, 4},{ 0, 0},{ 0, 0} }, // 1 Total_Coeffs { {11, 6},{15, 5},{13, 4},{ 0, 0} }, // 2 Total_Coeffs { { 8, 6},{12, 5},{14, 5},{12, 4} }, // 3 Total_Coeffs { {15, 7},{10, 5},{11, 5},{11, 4} }, // 4 Total_Coeffs { {11, 7},{ 8, 5},{ 9, 5},{10, 4} }, // 5 Total_Coeffs { { 9, 7},{14, 6},{13, 6},{ 9, 4} }, // 6 Total_Coeffs { { 8, 7},{10, 6},{ 9, 6},{ 8, 4} }, // 7 Total_Coeffs { {15, 8},{14, 7},{13, 7},{13, 5} }, // 8 Total_Coeffs { {11, 8},{14, 8},{10, 7},{12, 6} }, // 9 Total_Coeffs { {15, 9},{10, 8},{13, 8},{12, 7} }, // 10 Total_Coeffs { {11, 9},{14, 9},{ 9, 8},{12, 8} }, // 11 Total_Coeffs { { 8, 9},{10, 9},{13, 9},{ 8, 8} }, // 12 Total_Coeffs { {13,10},{ 7, 9},{ 9, 9},{12, 9} }, // 13 Total_Coeffs { { 9,10},{12,10},{11,10},{10,10} }, // 14 Total_Coeffs { { 5,10},{ 8,10},{ 7,10},{ 6,10} }, // 15 Total_Coeffs { { 1,10},{ 4,10},{ 3,10},{ 2,10} } // 16 Total_Coeffs }, { // Num-VLC_ChromaDC // 0 1 2 3 <-- Trailing Ones { { 1, 2},{ 0, 0},{ 0, 0},{ 0, 0} }, // 0 Total_Coeffs { { 7, 6},{ 1, 1},{ 0, 0},{ 0, 0} }, // 1 Total_Coeffs { { 4, 6},{ 6, 6},{ 1, 3},{ 0, 0} }, // 2 Total_Coeffs { { 3, 6},{ 3, 7},{ 2, 7},{ 5, 6} }, // 3 Total_Coeffs { { 2, 6},{ 3, 8},{ 2, 8},{ 0, 7} }, // 4 Total_Coeffs { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, // Not used... { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} }, { { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} } }};Status CH264pBs::PutNumCoeffAndTrailingOnes( Ipp32u N, // N, obtained from num coeffs of above/left blocks bool bChromaDC, // True if this is a Chroma DC coeff block (2x2) Ipp32u uNumCoeff, // Number of non-trailing one coeffs to follow (0-4 or 0-16) Ipp32u uNumTrailingOnes, // Number of trailing ones (0-3) Ipp32u TrOneSigns // Signs of the trailing ones, packed into 3 LSBs, (1==neg)){ Ipp32s uVLCSelect; Status ps = UMC_OK; if (bChromaDC) { uVLCSelect = 3; } else { if (N < 2) { uVLCSelect = 0; } else if (N < 4) { uVLCSelect = 1; } else if (N < 8) { uVLCSelect = 2; } else { // N > 7 uVLCSelect = -1; // escape to Fixed Length code } } if (uVLCSelect >= 0) { // Write coeff_token from Look-up table PutBits(EncTotalCoeff[uVLCSelect][uNumCoeff][uNumTrailingOnes].code, EncTotalCoeff[uVLCSelect][uNumCoeff][uNumTrailingOnes].len); } else { if (uNumCoeff == 0) { PutBits(3, 6); } else { // // xxxxyy -> xxxx = uNumCoeff-l , yy = uNumTrailingOnes PutBits((((uNumCoeff-1)<<2)|uNumTrailingOnes), 6); } } // Write signs of NumTrailingOnes PutBits(TrOneSigns, uNumTrailingOnes); return ps;}Status CH264pBs::PutLevels( Ipp16s* iLevels, // Array of Levels to write Ipp32u uNumLevels, // Total Number of coeffs to write (0-4 or 0-16) Ipp32u uTrailingOnes // Trailing Ones){ Ipp32s uVLCSelect = 0; Status ps = UMC_OK; Ipp32s vlc_inc_tab[7] = {0, 3, 6, 12, 24, 48, 0x8000}; Ipp32s escape_tab[7] = {16, 16, 31, 61, 121, 241, 481}; Ipp32u cnt; Ipp32u level_adj = 0; // Used to flag that the next level // is decreased in magnitude by 1 when coded. // Fixup first coeff level if Trailing Ones < 3 if (uTrailingOnes < 3) { level_adj = 1; // Subtracted from the level when coded if ((uTrailingOnes + uNumLevels) > 10) uVLCSelect = 1; // Start with different table } for (cnt = 0; cnt < uNumLevels; cnt++) { Ipp32s L = ABS(iLevels[cnt]); Ipp32u sign = (L != iLevels[cnt]); L -= level_adj; if (L >= escape_tab[uVLCSelect]) { // 28-bit escape // Catch cases where the level is too large to write to the BS PutBits(1, 16); // PutBits maxes out at 24 bits PutBits(((L-escape_tab[uVLCSelect])<<1)+sign, 12); } else if (uVLCSelect) { // VLC Level 1-6 Ipp32u N= uVLCSelect - 1; PutBits(1, ((L-1)>>(N))+1);// PutBits((((L-1)%(1<<N))<<1)+sign, uVLCSelect); PutBits((((L-1)&((1<<N)-1))<<1)+sign, uVLCSelect); } else { // VLC Level 0 if (L < 8) { PutBits(1,sign+((L-1)<<1)+1); // Start with a 0 if negative } else { // L 8-15 PutBits(16+((L&7)<<1)+sign,19); // 19 bit escape } } L += level_adj; // Restore the true level for the following calculations // Adjust the VLC table depending on the current table and // the Level just coded. if (!uVLCSelect && (L > 3)) uVLCSelect = 2; else if (L > vlc_inc_tab[uVLCSelect]) uVLCSelect++; level_adj = 0; // Clear this now that it's served its purpose } return ps;}// Note, the following 2 tables are indexed by TotalZeros & TotalCoeff-1static const struct_CodeEntry EncTotalZeros2x2[4][3] = { // 0 1 2 <- (TotalCoeff-1) { {1,1},{1,1},{1,1} }, // 0 TotalZeros { {1,2},{1,2},{0,1} }, // 1 TotalZeros { {1,3},{0,2},{0,0} }, // 2 TotalZeros { {0,3},{0,0},{0,0} } // 3 TotalZeros};static const struct_CodeEntry EncTotalZeros4x4[16][15] = { // 0/7 1/8 2/9 3/10 4/11 5/12 6/13 14 <- (TotalCoeff-1) { {1,1},{7,3},{5,4},{3,5},{5,4},{1,6},{1,6}, {1,6},{1,6},{1,5},{0,4},{0,4},{0,3},{0,2},{0,1} }, // 0 TotalZeros { {3,3},{6,3},{7,3},{7,3},{4,4},{1,5},{1,5}, {1,4},{0,6},{0,5},{1,4},{1,4},{1,3},{1,2},{1,1} }, // 1 TotalZeros { {2,3},{5,3},{6,3},{5,4},{3,4},{7,3},{5,3}, {1,5},{1,4},{1,3},{1,3},{1,2},{1,1},{1,1},{0,0} }, // 2 TotalZeros { {3,4},{4,3},{5,3},{4,4},{7,3},{6,3},{4,3}, {3,3},{3,2},{3,2},{2,3},{1,1},{1,2},{0,0},{0,0} }, // 3 TotalZeros { {2,4},{3,3},{4,4},{6,3},{6,3},{5,3},{3,3},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -