HM编码器代码阅读(23)——参数集的熵编码

来源:互联网 发布:c语言教学视频哪个好 编辑:程序博客网 时间:2024/06/05 02:57
在HEVC中,各种参数集以及控制信息等使用CAVLC编码,片头部也是使用cavlc进行编码,而帧或者片中的数据(连同CU的语法元素等)使用的是CABAC进行熵编码。

下面介绍一下各种参数集的熵编码。
在TEncGOP::compressGOP函数(图像组编码函数)中可以看到,在调用compressSlice对片编码之后,调用了m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice )设置CAVLC编码器为当前的熵编码器,然后调用encodeVPS,encodeSPS,encodePPS分别对视频参数集、序列参数集、图像参数集进行熵编码。当然只有在视频序列的开头才会调用encodeVPS,encodeSPS,encodePPS。然后调用codeSliceHeader对片的头部进行编码。

vps的格式(部分参数)
vps_video_parameter_set_id:其他语法元素所参考的VPS编号;
vps_reserved_three_2bits:保留位,指定为3;
vps_max_layers_minus1:保留,值为0,用于未来的3D和可分级扩展标准使用;
vps_max_sub_layers_minus1:这个值表示比特流中可以支持最大数目的时域子层数目减1,取值范围为0到6,也就是最大可以支持7个子层;
vps_temporal_id_nesting_flag:当前一个参数vps_max_sub_layers_minus1为0(即不支持时域子层)时,这个参数应该为1;vps_max_sub_layers_minus1非0时,指定是否对编码视频序列的帧间预测添加限制。用于子层切换过程中。
vps_reserved_0xffff_16bits:两个字节的保留位,全部为1;
vps_sub_layer_ordering_info_present_flag:为1,vps_max_dec_pic_buffering_minus1[i],vps_max_num_reorder_pics[i]和vps_max_latency_increase_plus1[i]适用于vps_max_sub_layers_minus1+ 1个子层;为0,这些参数适用于所有子层;
vps_max_dec_pic_buffering_minus1:指定所需的最大解码图像缓存的数量;
vps_max_num_reorder_pics和vps_max_latency_increase_plus1:指定按照解码顺序在某一帧之后,而显示顺序在某一帧之前的帧的最大数量;
vps_max_layer_id:CVS中所有NAL单元的最大允许的nuh_layer_id值;
vps_num_layer_sets_minus1:由VPS指定的图层组的数量-1;当前标准中指定为0;
layer_id_included_flag[][]:表示nuh_layer_id与layerSetLayerIdList[]的包含关系;
vps_timing_info_present_flag:标识该VPS是否包含几个时间相关参数;
vps_extension_flag:标识该VPS是否包含扩展信息。

下面是encodeVPS,encodeSPS,encodePPS三个函数的定义:
// vps的格式需要参考官方文档Void TEncCavlc::codeVPS( TComVPS* pcVPS ){// 编码vps的idWRITE_CODE( pcVPS->getVPSId(),                    4,        "vps_video_parameter_set_id" );// 保留位,指定为3WRITE_CODE( 3,                                    2,        "vps_reserved_three_2bits" );// 保留的6个0比特WRITE_CODE( 0,                                    6,        "vps_reserved_zero_6bits" );// 时域层的数量WRITE_CODE( pcVPS->getMaxTLayers() - 1,           3,        "vps_max_sub_layers_minus1" );// 时域层嵌套标志WRITE_FLAG( pcVPS->getTemporalNestingFlag(),                "vps_temporal_id_nesting_flag" );assert (pcVPS->getMaxTLayers()>1||pcVPS->getTemporalNestingFlag());// 保留的16个比特(值都是0xffff)WRITE_CODE( 0xffff,                              16,        "vps_reserved_ffff_16bits" );// 对Profile Tier Level的信息进行编码codePTL( pcVPS->getPTL(), true, pcVPS->getMaxTLayers() - 1 );const Bool subLayerOrderingInfoPresentFlag = 1;// 时域层排序信息存在的标志?WRITE_FLAG(subLayerOrderingInfoPresentFlag,              "vps_sub_layer_ordering_info_present_flag");// 写入每个时域层的信息for(UInt i=0; i <= pcVPS->getMaxTLayers()-1; i++){// 解码缓冲区的数量WRITE_UVLC( pcVPS->getMaxDecPicBuffering(i) - 1,       "vps_max_dec_pic_buffering_minus1[i]" );// 重排图像的数量(指定按照解码顺序在某一帧之后,而显示顺序在某一帧之前的帧的最大数量)WRITE_UVLC( pcVPS->getNumReorderPics(i),               "vps_num_reorder_pics[i]" );WRITE_UVLC( pcVPS->getMaxLatencyIncrease(i),           "vps_max_latency_increase_plus1[i]" );if (!subLayerOrderingInfoPresentFlag){break;}}assert( pcVPS->getNumHrdParameters() <= MAX_VPS_NUM_HRD_PARAMETERS );assert( pcVPS->getMaxNuhReservedZeroLayerId() < MAX_VPS_NUH_RESERVED_ZERO_LAYER_ID_PLUS1 );WRITE_CODE( pcVPS->getMaxNuhReservedZeroLayerId(), 6,     "vps_max_nuh_reserved_zero_layer_id" );pcVPS->setMaxOpSets(1);// 操作集的数量?WRITE_UVLC( pcVPS->getMaxOpSets() - 1,                    "vps_max_op_sets_minus1" );for( UInt opsIdx = 1; opsIdx <= ( pcVPS->getMaxOpSets() - 1 ); opsIdx ++ ){// Operation point setfor( UInt i = 0; i <= pcVPS->getMaxNuhReservedZeroLayerId(); i ++ ){// Only applicable for version 1pcVPS->setLayerIdIncludedFlag( true, opsIdx, i );WRITE_FLAG( pcVPS->getLayerIdIncludedFlag( opsIdx, i ) ? 1 : 0, "layer_id_included_flag[opsIdx][i]" );}}// 计时或者时域方面的信息TimingInfo *timingInfo = pcVPS->getTimingInfo();// 时域信息存在的标志WRITE_FLAG(timingInfo->getTimingInfoPresentFlag(),          "vps_timing_info_present_flag");// 写入计时或者时域信息if(timingInfo->getTimingInfoPresentFlag()){WRITE_CODE(timingInfo->getNumUnitsInTick(), 32,           "vps_num_units_in_tick");WRITE_CODE(timingInfo->getTimeScale(),      32,           "vps_time_scale");WRITE_FLAG(timingInfo->getPocProportionalToTimingFlag(),  "vps_poc_proportional_to_timing_flag");if(timingInfo->getPocProportionalToTimingFlag()){WRITE_UVLC(timingInfo->getNumTicksPocDiffOneMinus1(),   "vps_num_ticks_poc_diff_one_minus1");}pcVPS->setNumHrdParameters( 0 );WRITE_UVLC( pcVPS->getNumHrdParameters(),                 "vps_num_hrd_parameters" );if( pcVPS->getNumHrdParameters() > 0 ){pcVPS->createHrdParamBuffer();}for( UInt i = 0; i < pcVPS->getNumHrdParameters(); i ++ ){// Only applicable for version 1pcVPS->setHrdOpSetIdx( 0, i );WRITE_UVLC( pcVPS->getHrdOpSetIdx( i ),                "hrd_op_set_idx" );if( i > 0 ){WRITE_FLAG( pcVPS->getCprmsPresentFlag( i ) ? 1 : 0, "cprms_present_flag[i]" );}// 编码HRD(参考解码器)的参数codeHrdParameters(pcVPS->getHrdParameters(i), pcVPS->getCprmsPresentFlag( i ), pcVPS->getMaxTLayers() - 1);}}// 扩展标志WRITE_FLAG( 0,                     "vps_extension_flag" );//future extensions here..return;}
// sps的格式需要参考官方文档Void TEncCavlc::codeSPS( TComSPS* pcSPS ){#if ENC_DEC_TRACE  xTraceSPSHeader (pcSPS);#endif// sps的idWRITE_CODE( pcSPS->getVPSId (),          4,       "sps_video_parameter_set_id" );// 时域层WRITE_CODE( pcSPS->getMaxTLayers() - 1,  3,       "sps_max_sub_layers_minus1" );// 时域层嵌套标志WRITE_FLAG( pcSPS->getTemporalIdNestingFlag() ? 1 : 0,                             "sps_temporal_id_nesting_flag" );// Profile,Tier,Level的参数codePTL(pcSPS->getPTL(), 1, pcSPS->getMaxTLayers() - 1);WRITE_UVLC( pcSPS->getSPSId (),                   "sps_seq_parameter_set_id" );// 视频采样格式WRITE_UVLC( pcSPS->getChromaFormatIdc (),         "chroma_format_idc" );assert(pcSPS->getChromaFormatIdc () == 1);// in the first version chroma_format_idc can only be equal to 1 (4:2:0)if( pcSPS->getChromaFormatIdc () == 3 ){WRITE_FLAG( 0,                                  "separate_colour_plane_flag");}// 帧的亮度分量的宽高WRITE_UVLC( pcSPS->getPicWidthInLumaSamples (),   "pic_width_in_luma_samples" );WRITE_UVLC( pcSPS->getPicHeightInLumaSamples(),   "pic_height_in_luma_samples" );Window conf = pcSPS->getConformanceWindow();// 是否启用一致性窗口WRITE_FLAG( conf.getWindowEnabledFlag(),          "conformance_window_flag" );if (conf.getWindowEnabledFlag()){WRITE_UVLC( conf.getWindowLeftOffset()   / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_left_offset" );WRITE_UVLC( conf.getWindowRightOffset()  / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_right_offset" );WRITE_UVLC( conf.getWindowTopOffset()    / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_top_offset" );WRITE_UVLC( conf.getWindowBottomOffset() / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_bottom_offset" );}// 深度信息WRITE_UVLC( pcSPS->getBitDepthY() - 8,             "bit_depth_luma_minus8" );WRITE_UVLC( pcSPS->getBitDepthC() - 8,             "bit_depth_chroma_minus8" );// 存储poc需要的比特数WRITE_UVLC( pcSPS->getBitsForPOC()-4,                 "log2_max_pic_order_cnt_lsb_minus4" );const Bool subLayerOrderingInfoPresentFlag = 1;WRITE_FLAG(subLayerOrderingInfoPresentFlag,       "sps_sub_layer_ordering_info_present_flag");for(UInt i=0; i <= pcSPS->getMaxTLayers()-1; i++){WRITE_UVLC( pcSPS->getMaxDecPicBuffering(i) - 1,       "sps_max_dec_pic_buffering_minus1[i]" );WRITE_UVLC( pcSPS->getNumReorderPics(i),               "sps_num_reorder_pics[i]" );WRITE_UVLC( pcSPS->getMaxLatencyIncrease(i),           "sps_max_latency_increase_plus1[i]" );if (!subLayerOrderingInfoPresentFlag){break;}}assert( pcSPS->getMaxCUWidth() == pcSPS->getMaxCUHeight() );WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 3,                                "log2_min_coding_block_size_minus3" );WRITE_UVLC( pcSPS->getLog2DiffMaxMinCodingBlockSize(),                             "log2_diff_max_min_coding_block_size" );WRITE_UVLC( pcSPS->getQuadtreeTULog2MinSize() - 2,                                 "log2_min_transform_block_size_minus2" );WRITE_UVLC( pcSPS->getQuadtreeTULog2MaxSize() - pcSPS->getQuadtreeTULog2MinSize(), "log2_diff_max_min_transform_block_size" );WRITE_UVLC( pcSPS->getQuadtreeTUMaxDepthInter() - 1,                               "max_transform_hierarchy_depth_inter" );WRITE_UVLC( pcSPS->getQuadtreeTUMaxDepthIntra() - 1,                               "max_transform_hierarchy_depth_intra" );WRITE_FLAG( pcSPS->getScalingListFlag() ? 1 : 0,                                   "scaling_list_enabled_flag" ); if(pcSPS->getScalingListFlag()){WRITE_FLAG( pcSPS->getScalingListPresentFlag() ? 1 : 0,                          "sps_scaling_list_data_present_flag" ); if(pcSPS->getScalingListPresentFlag()){codeScalingList( m_pcSlice->getScalingList() );}}WRITE_FLAG( pcSPS->getUseAMP() ? 1 : 0,                                            "amp_enabled_flag" );WRITE_FLAG( pcSPS->getUseSAO() ? 1 : 0,                                            "sample_adaptive_offset_enabled_flag");WRITE_FLAG( pcSPS->getUsePCM() ? 1 : 0,                                            "pcm_enabled_flag");if( pcSPS->getUsePCM() ){WRITE_CODE( pcSPS->getPCMBitDepthLuma() - 1, 4,                                  "pcm_sample_bit_depth_luma_minus1" );WRITE_CODE( pcSPS->getPCMBitDepthChroma() - 1, 4,                                "pcm_sample_bit_depth_chroma_minus1" );WRITE_UVLC( pcSPS->getPCMLog2MinSize() - 3,                                      "log2_min_pcm_luma_coding_block_size_minus3" );WRITE_UVLC( pcSPS->getPCMLog2MaxSize() - pcSPS->getPCMLog2MinSize(),             "log2_diff_max_min_pcm_luma_coding_block_size" );WRITE_FLAG( pcSPS->getPCMFilterDisableFlag()?1 : 0,                              "pcm_loop_filter_disable_flag");}assert( pcSPS->getMaxTLayers() > 0 );         TComRPSList* rpsList = pcSPS->getRPSList();TComReferencePictureSet*      rps;WRITE_UVLC(rpsList->getNumberOfReferencePictureSets(), "num_short_term_ref_pic_sets" );for(Int i=0; i < rpsList->getNumberOfReferencePictureSets(); i++){rps = rpsList->getReferencePictureSet(i);codeShortTermRefPicSet(pcSPS,rps,false, i);}WRITE_FLAG( pcSPS->getLongTermRefsPresent() ? 1 : 0,         "long_term_ref_pics_present_flag" );if (pcSPS->getLongTermRefsPresent()) {WRITE_UVLC(pcSPS->getNumLongTermRefPicSPS(), "num_long_term_ref_pic_sps" );for (UInt k = 0; k < pcSPS->getNumLongTermRefPicSPS(); k++){WRITE_CODE( pcSPS->getLtRefPicPocLsbSps(k), pcSPS->getBitsForPOC(), "lt_ref_pic_poc_lsb_sps");WRITE_FLAG( pcSPS->getUsedByCurrPicLtSPSFlag(k), "used_by_curr_pic_lt_sps_flag");}}WRITE_FLAG( pcSPS->getTMVPFlagsPresent()  ? 1 : 0,           "sps_temporal_mvp_enable_flag" );WRITE_FLAG( pcSPS->getUseStrongIntraSmoothing(),             "sps_strong_intra_smoothing_enable_flag" );WRITE_FLAG( pcSPS->getVuiParametersPresentFlag(),             "vui_parameters_present_flag" );if (pcSPS->getVuiParametersPresentFlag()){codeVUI(pcSPS->getVuiParameters(), pcSPS);}WRITE_FLAG( 0, "sps_extension_flag" );}
// pps的格式要参考官方文档Void TEncCavlc::codePPS( TComPPS* pcPPS ){#if ENC_DEC_TRACE  xTracePPSHeader (pcPPS);#endif// PPS的idWRITE_UVLC( pcPPS->getPPSId(),                             "pps_pic_parameter_set_id" );// SPS的idWRITE_UVLC( pcPPS->getSPSId(),                             "pps_seq_parameter_set_id" );// 是否使用了依赖性片片段WRITE_FLAG( pcPPS->getDependentSliceSegmentsEnabledFlag()    ? 1 : 0, "dependent_slice_segments_enabled_flag" );// OutputFlag存在的标志WRITE_FLAG( pcPPS->getOutputFlagPresentFlag() ? 1 : 0,     "output_flag_present_flag" );// slice头部额外的比特数WRITE_CODE( pcPPS->getNumExtraSliceHeaderBits(), 3,        "num_extra_slice_header_bits");// 整数符号是否隐藏(往下不一一细讲,总之就是对一堆参数进行编码)WRITE_FLAG( pcPPS->getSignHideFlag(), "sign_data_hiding_flag" );WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0,   "cabac_init_present_flag" );WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1,     "num_ref_idx_l0_default_active_minus1");WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1,     "num_ref_idx_l1_default_active_minus1");WRITE_SVLC( pcPPS->getPicInitQPMinus26(),                  "init_qp_minus26");WRITE_FLAG( pcPPS->getConstrainedIntraPred() ? 1 : 0,      "constrained_intra_pred_flag" );WRITE_FLAG( pcPPS->getUseTransformSkip() ? 1 : 0,  "transform_skip_enabled_flag" ); WRITE_FLAG( pcPPS->getUseDQP() ? 1 : 0, "cu_qp_delta_enabled_flag" );if ( pcPPS->getUseDQP() ){WRITE_UVLC( pcPPS->getMaxCuDQPDepth(), "diff_cu_qp_delta_depth" );}WRITE_SVLC( pcPPS->getChromaCbQpOffset(),                   "pps_cb_qp_offset" );WRITE_SVLC( pcPPS->getChromaCrQpOffset(),                   "pps_cr_qp_offset" );WRITE_FLAG( pcPPS->getSliceChromaQpFlag() ? 1 : 0,          "pps_slice_chroma_qp_offsets_present_flag" );WRITE_FLAG( pcPPS->getUseWP() ? 1 : 0,  "weighted_pred_flag" );   // Use of Weighting Prediction (P_SLICE)WRITE_FLAG( pcPPS->getWPBiPred() ? 1 : 0, "weighted_bipred_flag" );  // Use of Weighting Bi-Prediction (B_SLICE)WRITE_FLAG( pcPPS->getTransquantBypassEnableFlag() ? 1 : 0, "transquant_bypass_enable_flag" );WRITE_FLAG( pcPPS->getTilesEnabledFlag()             ? 1 : 0, "tiles_enabled_flag" );WRITE_FLAG( pcPPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "entropy_coding_sync_enabled_flag" );if( pcPPS->getTilesEnabledFlag() ){WRITE_UVLC( pcPPS->getNumTileColumnsMinus1(),                                    "num_tile_columns_minus1" );WRITE_UVLC( pcPPS->getTileNumRowsMinus1(),                                       "num_tile_rows_minus1" );WRITE_FLAG( pcPPS->getTileUniformSpacingFlag(),                                  "uniform_spacing_flag" );if( !pcPPS->getTileUniformSpacingFlag() ){for(UInt i=0; i<pcPPS->getNumTileColumnsMinus1(); i++){WRITE_UVLC( pcPPS->getTileColumnWidth(i)-1,                                  "column_width_minus1" );}for(UInt i=0; i<pcPPS->getTileNumRowsMinus1(); i++){WRITE_UVLC( pcPPS->getTileRowHeight(i)-1,                                    "row_height_minus1" );}}if(pcPPS->getNumTileColumnsMinus1() !=0 || pcPPS->getTileNumRowsMinus1() !=0){WRITE_FLAG( pcPPS->getLoopFilterAcrossTilesEnabledFlag()?1 : 0,          "loop_filter_across_tiles_enabled_flag");}}WRITE_FLAG( pcPPS->getLoopFilterAcrossSlicesEnabledFlag()?1 : 0,        "loop_filter_across_slices_enabled_flag");WRITE_FLAG( pcPPS->getDeblockingFilterControlPresentFlag()?1 : 0,       "deblocking_filter_control_present_flag");if(pcPPS->getDeblockingFilterControlPresentFlag()){WRITE_FLAG( pcPPS->getDeblockingFilterOverrideEnabledFlag() ? 1 : 0,  "deblocking_filter_override_enabled_flag" ); WRITE_FLAG( pcPPS->getPicDisableDeblockingFilterFlag() ? 1 : 0,       "pps_disable_deblocking_filter_flag" );if(!pcPPS->getPicDisableDeblockingFilterFlag()){WRITE_SVLC( pcPPS->getDeblockingFilterBetaOffsetDiv2(),             "pps_beta_offset_div2" );WRITE_SVLC( pcPPS->getDeblockingFilterTcOffsetDiv2(),               "pps_tc_offset_div2" );}}WRITE_FLAG( pcPPS->getScalingListPresentFlag() ? 1 : 0,                          "pps_scaling_list_data_present_flag" ); if( pcPPS->getScalingListPresentFlag() ){codeScalingList( m_pcSlice->getScalingList() );}WRITE_FLAG( pcPPS->getListsModificationPresentFlag(), "lists_modification_present_flag");WRITE_UVLC( pcPPS->getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2");WRITE_FLAG( pcPPS->getSliceHeaderExtensionPresentFlag() ? 1 : 0, "slice_segment_header_extension_present_flag");WRITE_FLAG( 0, "pps_extension_flag" );}
// 对片头进行编码Void TEncCavlc::codeSliceHeader         ( TComSlice* pcSlice ){#if ENC_DEC_TRACE  xTraceSliceHeader (pcSlice);#endif//calculate number of bits required for slice addressInt maxSliceSegmentAddress = pcSlice->getPic()->getNumCUsInFrame();Int bitsSliceSegmentAddress = 0;while(maxSliceSegmentAddress>(1<<bitsSliceSegmentAddress)) {bitsSliceSegmentAddress++;}Int ctuAddress;if (pcSlice->isNextSlice()){// Calculate slice addressctuAddress = (pcSlice->getSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU());}else{// Calculate slice addressctuAddress = (pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU());}//write slice addressInt sliceSegmentAddress = pcSlice->getPic()->getPicSym()->getCUOrderMap(ctuAddress);// 该片是否为帧中的第一个片WRITE_FLAG( sliceSegmentAddress==0, "first_slice_segment_in_pic_flag" );if ( pcSlice->getRapPicFlag() ){#if SETTING_NO_OUT_PIC_PRIORWRITE_FLAG( pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag" );#elseWRITE_FLAG( 0, "no_output_of_prior_pics_flag" );#endif}// pps的idWRITE_UVLC( pcSlice->getPPS()->getPPSId(), "slice_pic_parameter_set_id" );pcSlice->setDependentSliceSegmentFlag(!pcSlice->isNextSlice());if ( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() && (sliceSegmentAddress!=0) ){// 依赖性的片是否存在的标志WRITE_FLAG( pcSlice->getDependentSliceSegmentFlag() ? 1 : 0, "dependent_slice_segment_flag" );}if(sliceSegmentAddress>0){// 片的地址WRITE_CODE( sliceSegmentAddress, bitsSliceSegmentAddress, "slice_segment_address" );}if ( !pcSlice->getDependentSliceSegmentFlag() ){for (Int i = 0; i < pcSlice->getPPS()->getNumExtraSliceHeaderBits(); i++){assert(!!"slice_reserved_undetermined_flag[]");WRITE_FLAG(0, "slice_reserved_undetermined_flag[]");}// 片的类型WRITE_UVLC( pcSlice->getSliceType(),       "slice_type" );if( pcSlice->getPPS()->getOutputFlagPresentFlag() ){// 帧输出的标志WRITE_FLAG( pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag" );}// in the first version chroma_format_idc is equal to one, thus colour_plane_id will not be presentassert (pcSlice->getSPS()->getChromaFormatIdc() == 1 );// if( separate_colour_plane_flag  ==  1 )//   colour_plane_id                                      u(2)if( !pcSlice->getIdrPicFlag() ){Int picOrderCntLSB = (pcSlice->getPOC()-pcSlice->getLastIDR()+(1<<pcSlice->getSPS()->getBitsForPOC())) & ((1<<pcSlice->getSPS()->getBitsForPOC())-1);// 用于存储poc的比特数WRITE_CODE( picOrderCntLSB, pcSlice->getSPS()->getBitsForPOC(), "pic_order_cnt_lsb");TComReferencePictureSet* rps = pcSlice->getRPS();// check for bitstream restriction stating that:// If the current picture is a BLA or CRA picture, the value of NumPocTotalCurr shall be equal to 0.// Ideally this process should not be repeated for each slice in a pictureif (pcSlice->isIRAP()){for (Int picIdx = 0; picIdx < rps->getNumberOfPictures(); picIdx++){assert (!rps->getUsed(picIdx));}}if(pcSlice->getRPSidx() < 0){// 短期参考图像集的标志WRITE_FLAG( 0, "short_term_ref_pic_set_sps_flag");// 编码短期参考图像集codeShortTermRefPicSet(pcSlice->getSPS(), rps, true, pcSlice->getSPS()->getRPSList()->getNumberOfReferencePictureSets());}else{WRITE_FLAG( 1, "short_term_ref_pic_set_sps_flag");Int numBits = 0;while ((1 << numBits) < pcSlice->getSPS()->getRPSList()->getNumberOfReferencePictureSets()){numBits++;}if (numBits > 0){// 参考图像集的索引WRITE_CODE( pcSlice->getRPSidx(), numBits, "short_term_ref_pic_set_idx" );          }}if(pcSlice->getSPS()->getLongTermRefsPresent()){Int numLtrpInSH = rps->getNumberOfLongtermPictures();Int ltrpInSPS[MAX_NUM_REF_PICS];Int numLtrpInSPS = 0;UInt ltrpIndex;Int counter = 0;for(Int k = rps->getNumberOfPictures()-1; k > rps->getNumberOfPictures()-rps->getNumberOfLongtermPictures()-1; k--) {if (findMatchingLTRP(pcSlice, <rpIndex, rps->getPOC(k), rps->getUsed(k))) {ltrpInSPS[numLtrpInSPS] = ltrpIndex;numLtrpInSPS++;}else{counter++;}}numLtrpInSH -= numLtrpInSPS;Int bitsForLtrpInSPS = 0;while (pcSlice->getSPS()->getNumLongTermRefPicSPS() > (1 << bitsForLtrpInSPS)){bitsForLtrpInSPS++;}if (pcSlice->getSPS()->getNumLongTermRefPicSPS() > 0) {WRITE_UVLC( numLtrpInSPS, "num_long_term_sps");}// 长期参考帧的数量WRITE_UVLC( numLtrpInSH, "num_long_term_pics");// Note that the LSBs of the LT ref. pic. POCs must be sorted before.// Not sorted here because LT ref indices will be used in setRefPicList()Int prevDeltaMSB = 0, prevLSB = 0;Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();for(Int i=rps->getNumberOfPictures()-1 ; i > offset-1; i--){if (counter < numLtrpInSPS){if (bitsForLtrpInSPS > 0){WRITE_CODE( ltrpInSPS[counter], bitsForLtrpInSPS, "lt_idx_sps[i]");              }}else {WRITE_CODE( rps->getPocLSBLT(i), pcSlice->getSPS()->getBitsForPOC(), "poc_lsb_lt");WRITE_FLAG( rps->getUsed(i), "used_by_curr_pic_lt_flag"); }WRITE_FLAG( rps->getDeltaPocMSBPresentFlag(i), "delta_poc_msb_present_flag");if(rps->getDeltaPocMSBPresentFlag(i)){Bool deltaFlag = false;//  First LTRP from SPS                 ||  First LTRP from SH                              || curr LSB            != prev LSBif( (i == rps->getNumberOfPictures()-1) || (i == rps->getNumberOfPictures()-1-numLtrpInSPS) || (rps->getPocLSBLT(i) != prevLSB) ){deltaFlag = true;}if(deltaFlag){WRITE_UVLC( rps->getDeltaPocMSBCycleLT(i), "delta_poc_msb_cycle_lt[i]" );}else{              Int differenceInDeltaMSB = rps->getDeltaPocMSBCycleLT(i) - prevDeltaMSB;assert(differenceInDeltaMSB >= 0);WRITE_UVLC( differenceInDeltaMSB, "delta_poc_msb_cycle_lt[i]" );}prevLSB = rps->getPocLSBLT(i);prevDeltaMSB = rps->getDeltaPocMSBCycleLT(i);}}}if (pcSlice->getSPS()->getTMVPFlagsPresent()){// 是否启用时域MVPWRITE_FLAG( pcSlice->getEnableTMVPFlag() ? 1 : 0, "slice_temporal_mvp_enable_flag" );}}if(pcSlice->getSPS()->getUseSAO()){if (pcSlice->getSPS()->getUseSAO()){// 是否启用SAOWRITE_FLAG( pcSlice->getSaoEnabledFlag(), "slice_sao_luma_flag" );WRITE_FLAG( pcSlice->getSaoEnabledFlagChroma(), "slice_sao_chroma_flag" );}}//check if numrefidxes match the defaults. If not, overrideif (!pcSlice->isIntra()){Bool overrideFlag = (pcSlice->getNumRefIdx( REF_PIC_LIST_0 )!=pcSlice->getPPS()->getNumRefIdxL0DefaultActive()||(pcSlice->isInterB()&&pcSlice->getNumRefIdx( REF_PIC_LIST_1 )!=pcSlice->getPPS()->getNumRefIdxL1DefaultActive()));// 参考帧的数量WRITE_FLAG( overrideFlag ? 1 : 0,                               "num_ref_idx_active_override_flag");if (overrideFlag) {// 参考帧的数量WRITE_UVLC( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - 1,      "num_ref_idx_l0_active_minus1" );if (pcSlice->isInterB()){// 参考帧的数量WRITE_UVLC( pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - 1,    "num_ref_idx_l1_active_minus1" );}else{pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0);}}}else{pcSlice->setNumRefIdx(REF_PIC_LIST_0, 0);pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0);}if( pcSlice->getPPS()->getListsModificationPresentFlag() && pcSlice->getNumRpsCurrTempList() > 1){TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();if(!pcSlice->isIntra()){WRITE_FLAG(pcSlice->getRefPicListModification()->getRefPicListModificationFlagL0() ? 1 : 0,       "ref_pic_list_modification_flag_l0" );if (pcSlice->getRefPicListModification()->getRefPicListModificationFlagL0()){Int numRpsCurrTempList0 = pcSlice->getNumRpsCurrTempList();if (numRpsCurrTempList0 > 1){Int length = 1;numRpsCurrTempList0 --;while ( numRpsCurrTempList0 >>= 1) {length ++;}for(Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); i++){// 参考帧索引WRITE_CODE( refPicListModification->getRefPicSetIdxL0(i), length, "list_entry_l0");}}}}if(pcSlice->isInterB()){    WRITE_FLAG(pcSlice->getRefPicListModification()->getRefPicListModificationFlagL1() ? 1 : 0,       "ref_pic_list_modification_flag_l1" );if (pcSlice->getRefPicListModification()->getRefPicListModificationFlagL1()){Int numRpsCurrTempList1 = pcSlice->getNumRpsCurrTempList();if ( numRpsCurrTempList1 > 1 ){Int length = 1;numRpsCurrTempList1 --;while ( numRpsCurrTempList1 >>= 1){length ++;}for(Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); i++){// 参考帧的索引WRITE_CODE( refPicListModification->getRefPicSetIdxL1(i), length, "list_entry_l1");}}}}}if (pcSlice->isInterB()){// list1中MVD是否为0的标志?WRITE_FLAG( pcSlice->getMvdL1ZeroFlag() ? 1 : 0,   "mvd_l1_zero_flag");}if(!pcSlice->isIntra()){if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag()){SliceType sliceType   = pcSlice->getSliceType();Int  encCABACTableIdx = pcSlice->getPPS()->getEncCABACTableIdx();Bool encCabacInitFlag = (sliceType!=encCABACTableIdx && encCABACTableIdx!=I_SLICE) ? true : false;pcSlice->setCabacInitFlag( encCabacInitFlag );// CABAC初始化的标志WRITE_FLAG( encCabacInitFlag?1:0, "cabac_init_flag" );}}if ( pcSlice->getEnableTMVPFlag() ){if ( pcSlice->getSliceType() == B_SLICE ){// 是否使用了混合列表WRITE_FLAG( pcSlice->getColFromL0Flag(), "collocated_from_l0_flag" );}if ( pcSlice->getSliceType() != I_SLICE &&((pcSlice->getColFromL0Flag()==1 && pcSlice->getNumRefIdx(REF_PIC_LIST_0)>1)||(pcSlice->getColFromL0Flag()==0  && pcSlice->getNumRefIdx(REF_PIC_LIST_1)>1))){// 混合参考列表的索引?WRITE_UVLC( pcSlice->getColRefIdx(), "collocated_ref_idx" );}}if ( (pcSlice->getPPS()->getUseWP() && pcSlice->getSliceType()==P_SLICE) || (pcSlice->getPPS()->getWPBiPred() && pcSlice->getSliceType()==B_SLICE) ){// 带权预测的一些信息xCodePredWeightTable( pcSlice );}assert(pcSlice->getMaxNumMergeCand()<=MRG_MAX_NUM_CANDS);if (!pcSlice->isIntra()){// merge模式的候选者的数量WRITE_UVLC(MRG_MAX_NUM_CANDS - pcSlice->getMaxNumMergeCand(), "five_minus_max_num_merge_cand");}Int iCode = pcSlice->getSliceQp() - ( pcSlice->getPPS()->getPicInitQPMinus26() + 26 );// 量化步长WRITE_SVLC( iCode, "slice_qp_delta" ); if (pcSlice->getPPS()->getSliceChromaQpFlag()){iCode = pcSlice->getSliceQpDeltaCb();WRITE_SVLC( iCode, "slice_qp_delta_cb" );iCode = pcSlice->getSliceQpDeltaCr();WRITE_SVLC( iCode, "slice_qp_delta_cr" );}if (pcSlice->getPPS()->getDeblockingFilterControlPresentFlag()){if (pcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() ){// 去方块滤波覆盖的标记?WRITE_FLAG(pcSlice->getDeblockingFilterOverrideFlag(), "deblocking_filter_override_flag");}if (pcSlice->getDeblockingFilterOverrideFlag()){// 是否启用去方块滤波WRITE_FLAG(pcSlice->getDeblockingFilterDisable(), "slice_disable_deblocking_filter_flag");if(!pcSlice->getDeblockingFilterDisable()){WRITE_SVLC (pcSlice->getDeblockingFilterBetaOffsetDiv2(), "slice_beta_offset_div2");WRITE_SVLC (pcSlice->getDeblockingFilterTcOffsetDiv2(),   "slice_tc_offset_div2");}}}Bool isSAOEnabled = (!pcSlice->getSPS()->getUseSAO())?(false):(pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma());Bool isDBFEnabled = (!pcSlice->getDeblockingFilterDisable());if(pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag() && ( isSAOEnabled || isDBFEnabled )){// 环路滤波是否跨越片的边界WRITE_FLAG(pcSlice->getLFCrossSliceBoundaryFlag()?1:0, "slice_loop_filter_across_slices_enabled_flag");}}if(pcSlice->getPPS()->getSliceHeaderExtensionPresentFlag()){// 片头扩展长度WRITE_UVLC(0,"slice_header_extension_length");}}





0 0