// vps的格式需要参考官方文档 Void TEncCavlc::codeVPS( TComVPS* pcVPS ) { // 编码vps的id WRITE_CODE( pcVPS->getVPSId(), 4, "vps_video_parameter_set_id" ); // 保留位,指定为3 WRITE_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 set for( UInt i = 0; i <= pcVPS->getMaxNuhReservedZeroLayerId(); i ++ ) { // Only applicable for version 1 pcVPS->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 1 pcVPS->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的id WRITE_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的id WRITE_UVLC( pcPPS->getPPSId(), "pps_pic_parameter_set_id" ); // SPS的id WRITE_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 address Int maxSliceSegmentAddress = pcSlice->getPic()->getNumCUsInFrame(); Int bitsSliceSegmentAddress = 0; while(maxSliceSegmentAddress>(1<<bitsSliceSegmentAddress)) { bitsSliceSegmentAddress++; } Int ctuAddress; if (pcSlice->isNextSlice()) { // Calculate slice address ctuAddress = (pcSlice->getSliceCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()); } else { // Calculate slice address ctuAddress = (pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()); } //write slice address Int sliceSegmentAddress = pcSlice->getPic()->getPicSym()->getCUOrderMap(ctuAddress); // 该片是否为帧中的第一个片 WRITE_FLAG( sliceSegmentAddress==0, "first_slice_segment_in_pic_flag" ); if ( pcSlice->getRapPicFlag() ) { #if SETTING_NO_OUT_PIC_PRIOR WRITE_FLAG( pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag" ); #else WRITE_FLAG( 0, "no_output_of_prior_pics_flag" ); #endif } // pps的id WRITE_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 present assert (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 picture if (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 LSB if( (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()) { // 是否启用时域MVP WRITE_FLAG( pcSlice->getEnableTMVPFlag() ? 1 : 0, "slice_temporal_mvp_enable_flag" ); } } if(pcSlice->getSPS()->getUseSAO()) { if (pcSlice->getSPS()->getUseSAO()) { // 是否启用SAO WRITE_FLAG( pcSlice->getSaoEnabledFlag(), "slice_sao_luma_flag" ); WRITE_FLAG( pcSlice->getSaoEnabledFlagChroma(), "slice_sao_chroma_flag" ); } } //check if numrefidxes match the defaults. If not, override if (!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"); } }