Mercurial > hg > forks > libbpg
comparison jctvc/TLibEncoder/TEncCavlc.cpp @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:772086c29cc7 |
---|---|
1 /* The copyright in this software is being made available under the BSD | |
2 * License, included below. This software may be subject to other third party | |
3 * and contributor rights, including patent rights, and no such rights are | |
4 * granted under this license. | |
5 * | |
6 * Copyright (c) 2010-2014, ITU/ISO/IEC | |
7 * All rights reserved. | |
8 * | |
9 * Redistribution and use in source and binary forms, with or without | |
10 * modification, are permitted provided that the following conditions are met: | |
11 * | |
12 * * Redistributions of source code must retain the above copyright notice, | |
13 * this list of conditions and the following disclaimer. | |
14 * * Redistributions in binary form must reproduce the above copyright notice, | |
15 * this list of conditions and the following disclaimer in the documentation | |
16 * and/or other materials provided with the distribution. | |
17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may | |
18 * be used to endorse or promote products derived from this software without | |
19 * specific prior written permission. | |
20 * | |
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS | |
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
31 * THE POSSIBILITY OF SUCH DAMAGE. | |
32 */ | |
33 | |
34 /** \file TEncCavlc.cpp | |
35 \brief CAVLC encoder class | |
36 */ | |
37 | |
38 #include "../TLibCommon/CommonDef.h" | |
39 #include "TEncCavlc.h" | |
40 #include "SEIwrite.h" | |
41 | |
42 //! \ingroup TLibEncoder | |
43 //! \{ | |
44 | |
45 #define SRPS_IN_SLICE 1 | |
46 | |
47 #if ENC_DEC_TRACE | |
48 | |
49 Void xTraceSPSHeader (TComSPS *pSPS) | |
50 { | |
51 fprintf( g_hTrace, "=========== Sequence Parameter Set ID: %d ===========\n", pSPS->getSPSId() ); | |
52 } | |
53 | |
54 Void xTracePPSHeader (TComPPS *pPPS) | |
55 { | |
56 fprintf( g_hTrace, "=========== Picture Parameter Set ID: %d ===========\n", pPPS->getPPSId() ); | |
57 } | |
58 | |
59 Void xTraceSliceHeader (TComSlice *pSlice) | |
60 { | |
61 fprintf( g_hTrace, "=========== Slice ===========\n"); | |
62 } | |
63 | |
64 #endif | |
65 | |
66 | |
67 | |
68 // ==================================================================================================================== | |
69 // Constructor / destructor / create / destroy | |
70 // ==================================================================================================================== | |
71 | |
72 TEncCavlc::TEncCavlc() | |
73 { | |
74 m_pcBitIf = NULL; | |
75 } | |
76 | |
77 TEncCavlc::~TEncCavlc() | |
78 { | |
79 } | |
80 | |
81 | |
82 // ==================================================================================================================== | |
83 // Public member functions | |
84 // ==================================================================================================================== | |
85 | |
86 Void TEncCavlc::resetEntropy() | |
87 { | |
88 } | |
89 | |
90 | |
91 Void TEncCavlc::codeDFFlag(UInt uiCode, const Char *pSymbolName) | |
92 { | |
93 WRITE_FLAG(uiCode, pSymbolName); | |
94 } | |
95 Void TEncCavlc::codeDFSvlc(Int iCode, const Char *pSymbolName) | |
96 { | |
97 WRITE_SVLC(iCode, pSymbolName); | |
98 } | |
99 | |
100 Void TEncCavlc::codeShortTermRefPicSet( TComSPS* pcSPS, TComReferencePictureSet* rps, Bool calledFromSliceHeader, Int idx) | |
101 { | |
102 #if PRINT_RPS_INFO | |
103 Int lastBits = getNumberOfWrittenBits(); | |
104 #endif | |
105 if (idx > 0) | |
106 { | |
107 WRITE_FLAG( rps->getInterRPSPrediction(), "inter_ref_pic_set_prediction_flag" ); // inter_RPS_prediction_flag | |
108 } | |
109 if (rps->getInterRPSPrediction()) | |
110 { | |
111 Int deltaRPS = rps->getDeltaRPS(); | |
112 if(calledFromSliceHeader) | |
113 { | |
114 WRITE_UVLC( rps->getDeltaRIdxMinus1(), "delta_idx_minus1" ); // delta index of the Reference Picture Set used for prediction minus 1 | |
115 } | |
116 | |
117 WRITE_CODE( (deltaRPS >=0 ? 0: 1), 1, "delta_rps_sign" ); //delta_rps_sign | |
118 WRITE_UVLC( abs(deltaRPS) - 1, "abs_delta_rps_minus1"); // absolute delta RPS minus 1 | |
119 | |
120 for(Int j=0; j < rps->getNumRefIdc(); j++) | |
121 { | |
122 Int refIdc = rps->getRefIdc(j); | |
123 WRITE_CODE( (refIdc==1? 1: 0), 1, "used_by_curr_pic_flag" ); //first bit is "1" if Idc is 1 | |
124 if (refIdc != 1) | |
125 { | |
126 WRITE_CODE( refIdc>>1, 1, "use_delta_flag" ); //second bit is "1" if Idc is 2, "0" otherwise. | |
127 } | |
128 } | |
129 } | |
130 else | |
131 { | |
132 WRITE_UVLC( rps->getNumberOfNegativePictures(), "num_negative_pics" ); | |
133 WRITE_UVLC( rps->getNumberOfPositivePictures(), "num_positive_pics" ); | |
134 Int prev = 0; | |
135 for(Int j=0 ; j < rps->getNumberOfNegativePictures(); j++) | |
136 { | |
137 WRITE_UVLC( prev-rps->getDeltaPOC(j)-1, "delta_poc_s0_minus1" ); | |
138 prev = rps->getDeltaPOC(j); | |
139 WRITE_FLAG( rps->getUsed(j), "used_by_curr_pic_s0_flag"); | |
140 } | |
141 prev = 0; | |
142 for(Int j=rps->getNumberOfNegativePictures(); j < rps->getNumberOfNegativePictures()+rps->getNumberOfPositivePictures(); j++) | |
143 { | |
144 WRITE_UVLC( rps->getDeltaPOC(j)-prev-1, "delta_poc_s1_minus1" ); | |
145 prev = rps->getDeltaPOC(j); | |
146 WRITE_FLAG( rps->getUsed(j), "used_by_curr_pic_s1_flag" ); | |
147 } | |
148 } | |
149 | |
150 #if PRINT_RPS_INFO | |
151 printf("irps=%d (%2d bits) ", rps->getInterRPSPrediction(), getNumberOfWrittenBits() - lastBits); | |
152 rps->printDeltaPOC(); | |
153 #endif | |
154 } | |
155 | |
156 | |
157 Void TEncCavlc::codePPS( TComPPS* pcPPS ) | |
158 { | |
159 #if ENC_DEC_TRACE | |
160 xTracePPSHeader (pcPPS); | |
161 #endif | |
162 | |
163 const UInt numberValidComponents = getNumberValidComponents(pcPPS->getSPS()->getChromaFormatIdc()); | |
164 | |
165 WRITE_UVLC( pcPPS->getPPSId(), "pps_pic_parameter_set_id" ); | |
166 WRITE_UVLC( pcPPS->getSPSId(), "pps_seq_parameter_set_id" ); | |
167 WRITE_FLAG( pcPPS->getDependentSliceSegmentsEnabledFlag() ? 1 : 0, "dependent_slice_segments_enabled_flag" ); | |
168 WRITE_FLAG( pcPPS->getOutputFlagPresentFlag() ? 1 : 0, "output_flag_present_flag" ); | |
169 WRITE_CODE( pcPPS->getNumExtraSliceHeaderBits(), 3, "num_extra_slice_header_bits"); | |
170 WRITE_FLAG( pcPPS->getSignHideFlag(), "sign_data_hiding_flag" ); | |
171 WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0, "cabac_init_present_flag" ); | |
172 WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1, "num_ref_idx_l0_default_active_minus1"); | |
173 WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1, "num_ref_idx_l1_default_active_minus1"); | |
174 | |
175 WRITE_SVLC( pcPPS->getPicInitQPMinus26(), "init_qp_minus26"); | |
176 WRITE_FLAG( pcPPS->getConstrainedIntraPred() ? 1 : 0, "constrained_intra_pred_flag" ); | |
177 WRITE_FLAG( pcPPS->getUseTransformSkip() ? 1 : 0, "transform_skip_enabled_flag" ); | |
178 WRITE_FLAG( pcPPS->getUseDQP() ? 1 : 0, "cu_qp_delta_enabled_flag" ); | |
179 if ( pcPPS->getUseDQP() ) | |
180 { | |
181 WRITE_UVLC( pcPPS->getMaxCuDQPDepth(), "diff_cu_qp_delta_depth" ); | |
182 } | |
183 | |
184 WRITE_SVLC( COMPONENT_Cb<numberValidComponents ? (pcPPS->getQpOffset(COMPONENT_Cb)) : 0, "pps_cb_qp_offset" ); | |
185 WRITE_SVLC( COMPONENT_Cr<numberValidComponents ? (pcPPS->getQpOffset(COMPONENT_Cr)) : 0, "pps_cr_qp_offset" ); | |
186 | |
187 assert(numberValidComponents <= 3); // if more than 3 components (eg 4:4:4:4), then additional offsets will have to go in extension area... | |
188 | |
189 WRITE_FLAG( pcPPS->getSliceChromaQpFlag() ? 1 : 0, "pps_slice_chroma_qp_offsets_present_flag" ); | |
190 | |
191 WRITE_FLAG( pcPPS->getUseWP() ? 1 : 0, "weighted_pred_flag" ); // Use of Weighting Prediction (P_SLICE) | |
192 WRITE_FLAG( pcPPS->getWPBiPred() ? 1 : 0, "weighted_bipred_flag" ); // Use of Weighting Bi-Prediction (B_SLICE) | |
193 WRITE_FLAG( pcPPS->getTransquantBypassEnableFlag() ? 1 : 0, "transquant_bypass_enable_flag" ); | |
194 WRITE_FLAG( pcPPS->getTilesEnabledFlag() ? 1 : 0, "tiles_enabled_flag" ); | |
195 WRITE_FLAG( pcPPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "entropy_coding_sync_enabled_flag" ); | |
196 if( pcPPS->getTilesEnabledFlag() ) | |
197 { | |
198 WRITE_UVLC( pcPPS->getNumTileColumnsMinus1(), "num_tile_columns_minus1" ); | |
199 WRITE_UVLC( pcPPS->getNumTileRowsMinus1(), "num_tile_rows_minus1" ); | |
200 WRITE_FLAG( pcPPS->getTileUniformSpacingFlag(), "uniform_spacing_flag" ); | |
201 if( !pcPPS->getTileUniformSpacingFlag() ) | |
202 { | |
203 for(UInt i=0; i<pcPPS->getNumTileColumnsMinus1(); i++) | |
204 { | |
205 WRITE_UVLC( pcPPS->getTileColumnWidth(i)-1, "column_width_minus1" ); | |
206 } | |
207 for(UInt i=0; i<pcPPS->getNumTileRowsMinus1(); i++) | |
208 { | |
209 WRITE_UVLC( pcPPS->getTileRowHeight(i)-1, "row_height_minus1" ); | |
210 } | |
211 } | |
212 if(pcPPS->getNumTileColumnsMinus1() !=0 || pcPPS->getNumTileRowsMinus1() !=0) | |
213 { | |
214 WRITE_FLAG( pcPPS->getLoopFilterAcrossTilesEnabledFlag()?1 : 0, "loop_filter_across_tiles_enabled_flag"); | |
215 } | |
216 } | |
217 WRITE_FLAG( pcPPS->getLoopFilterAcrossSlicesEnabledFlag()?1 : 0, "loop_filter_across_slices_enabled_flag"); | |
218 WRITE_FLAG( pcPPS->getDeblockingFilterControlPresentFlag()?1 : 0, "deblocking_filter_control_present_flag"); | |
219 if(pcPPS->getDeblockingFilterControlPresentFlag()) | |
220 { | |
221 WRITE_FLAG( pcPPS->getDeblockingFilterOverrideEnabledFlag() ? 1 : 0, "deblocking_filter_override_enabled_flag" ); | |
222 WRITE_FLAG( pcPPS->getPicDisableDeblockingFilterFlag() ? 1 : 0, "pps_disable_deblocking_filter_flag" ); | |
223 if(!pcPPS->getPicDisableDeblockingFilterFlag()) | |
224 { | |
225 WRITE_SVLC( pcPPS->getDeblockingFilterBetaOffsetDiv2(), "pps_beta_offset_div2" ); | |
226 WRITE_SVLC( pcPPS->getDeblockingFilterTcOffsetDiv2(), "pps_tc_offset_div2" ); | |
227 } | |
228 } | |
229 WRITE_FLAG( pcPPS->getScalingListPresentFlag() ? 1 : 0, "pps_scaling_list_data_present_flag" ); | |
230 if( pcPPS->getScalingListPresentFlag() ) | |
231 { | |
232 codeScalingList( m_pcSlice->getScalingList() ); | |
233 } | |
234 WRITE_FLAG( pcPPS->getListsModificationPresentFlag(), "lists_modification_present_flag"); | |
235 WRITE_UVLC( pcPPS->getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2"); | |
236 WRITE_FLAG( pcPPS->getSliceHeaderExtensionPresentFlag() ? 1 : 0, "slice_segment_header_extension_present_flag"); | |
237 | |
238 Bool pps_extension_present_flag=false; | |
239 Bool pps_extension_flags[NUM_PPS_EXTENSION_FLAGS]={false}; | |
240 | |
241 pps_extension_flags[PPS_EXT__REXT] = ( | |
242 ( pcPPS->getUseTransformSkip() && (pcPPS->getTransformSkipLog2MaxSize() != 2)) | |
243 || pcPPS->getUseCrossComponentPrediction() | |
244 || ( pcPPS->getChromaQpAdjTableSize() > 0 ) | |
245 || ( pcPPS->getSaoOffsetBitShift(CHANNEL_TYPE_LUMA) !=0 ) || ( pcPPS->getSaoOffsetBitShift(CHANNEL_TYPE_CHROMA) !=0 ) | |
246 ) | |
247 ; | |
248 | |
249 // Other PPS extension flags checked here. | |
250 | |
251 for(Int i=0; i<NUM_PPS_EXTENSION_FLAGS; i++) | |
252 { | |
253 pps_extension_present_flag|=pps_extension_flags[i]; | |
254 } | |
255 | |
256 WRITE_FLAG( (pps_extension_present_flag?1:0), "pps_extension_present_flag" ); | |
257 | |
258 if (pps_extension_present_flag) | |
259 { | |
260 for(Int i=0; i<NUM_PPS_EXTENSION_FLAGS; i++) | |
261 { | |
262 WRITE_FLAG( pps_extension_flags[i]?1:0, "pps_extension_flag[]" ); | |
263 } | |
264 | |
265 for(Int i=0; i<NUM_PPS_EXTENSION_FLAGS; i++) // loop used so that the order is determined by the enum. | |
266 { | |
267 if (pps_extension_flags[i]) | |
268 { | |
269 switch (PPSExtensionFlagIndex(i)) | |
270 { | |
271 case PPS_EXT__REXT: | |
272 | |
273 if (pcPPS->getUseTransformSkip()) | |
274 { | |
275 WRITE_UVLC( pcPPS->getTransformSkipLog2MaxSize()-2, "log2_transform_skip_max_size_minus2"); | |
276 } | |
277 | |
278 WRITE_FLAG((pcPPS->getUseCrossComponentPrediction() ? 1 : 0), "cross_component_prediction_flag" ); | |
279 | |
280 WRITE_FLAG(UInt(pcPPS->getChromaQpAdjTableSize() > 0), "chroma_qp_adjustment_enabled_flag" ); | |
281 if (pcPPS->getChromaQpAdjTableSize() > 0) | |
282 { | |
283 WRITE_UVLC(pcPPS->getMaxCuChromaQpAdjDepth(), "diff_cu_chroma_qp_adjustment_depth"); | |
284 WRITE_UVLC(pcPPS->getChromaQpAdjTableSize() - 1, "chroma_qp_adjustment_table_size_minus1"); | |
285 /* skip zero index */ | |
286 for (Int chromaQpAdjustmentIndex = 1; chromaQpAdjustmentIndex <= pcPPS->getChromaQpAdjTableSize(); chromaQpAdjustmentIndex++) | |
287 { | |
288 WRITE_SVLC(pcPPS->getChromaQpAdjTableAt(chromaQpAdjustmentIndex).u.comp.CbOffset, "cb_qp_adjustnemt[i]"); | |
289 WRITE_SVLC(pcPPS->getChromaQpAdjTableAt(chromaQpAdjustmentIndex).u.comp.CrOffset, "cr_qp_adjustnemt[i]"); | |
290 } | |
291 } | |
292 | |
293 WRITE_UVLC( pcPPS->getSaoOffsetBitShift(CHANNEL_TYPE_LUMA), "sao_luma_bit_shift" ); | |
294 WRITE_UVLC( pcPPS->getSaoOffsetBitShift(CHANNEL_TYPE_CHROMA), "sao_chroma_bit_shift" ); | |
295 break; | |
296 default: | |
297 assert(pps_extension_flags[i]==false); // Should never get here with an active PPS extension flag. | |
298 break; | |
299 } // switch | |
300 } // if flag present | |
301 } // loop over PPS flags | |
302 } // pps_extension_present_flag is non-zero | |
303 } | |
304 | |
305 Void TEncCavlc::codeVUI( TComVUI *pcVUI, TComSPS* pcSPS ) | |
306 { | |
307 #if ENC_DEC_TRACE | |
308 fprintf( g_hTrace, "----------- vui_parameters -----------\n"); | |
309 #endif | |
310 WRITE_FLAG(pcVUI->getAspectRatioInfoPresentFlag(), "aspect_ratio_info_present_flag"); | |
311 if (pcVUI->getAspectRatioInfoPresentFlag()) | |
312 { | |
313 WRITE_CODE(pcVUI->getAspectRatioIdc(), 8, "aspect_ratio_idc" ); | |
314 if (pcVUI->getAspectRatioIdc() == 255) | |
315 { | |
316 WRITE_CODE(pcVUI->getSarWidth(), 16, "sar_width"); | |
317 WRITE_CODE(pcVUI->getSarHeight(), 16, "sar_height"); | |
318 } | |
319 } | |
320 WRITE_FLAG(pcVUI->getOverscanInfoPresentFlag(), "overscan_info_present_flag"); | |
321 if (pcVUI->getOverscanInfoPresentFlag()) | |
322 { | |
323 WRITE_FLAG(pcVUI->getOverscanAppropriateFlag(), "overscan_appropriate_flag"); | |
324 } | |
325 WRITE_FLAG(pcVUI->getVideoSignalTypePresentFlag(), "video_signal_type_present_flag"); | |
326 if (pcVUI->getVideoSignalTypePresentFlag()) | |
327 { | |
328 WRITE_CODE(pcVUI->getVideoFormat(), 3, "video_format"); | |
329 WRITE_FLAG(pcVUI->getVideoFullRangeFlag(), "video_full_range_flag"); | |
330 WRITE_FLAG(pcVUI->getColourDescriptionPresentFlag(), "colour_description_present_flag"); | |
331 if (pcVUI->getColourDescriptionPresentFlag()) | |
332 { | |
333 WRITE_CODE(pcVUI->getColourPrimaries(), 8, "colour_primaries"); | |
334 WRITE_CODE(pcVUI->getTransferCharacteristics(), 8, "transfer_characteristics"); | |
335 WRITE_CODE(pcVUI->getMatrixCoefficients(), 8, "matrix_coefficients"); | |
336 } | |
337 } | |
338 | |
339 WRITE_FLAG(pcVUI->getChromaLocInfoPresentFlag(), "chroma_loc_info_present_flag"); | |
340 if (pcVUI->getChromaLocInfoPresentFlag()) | |
341 { | |
342 WRITE_UVLC(pcVUI->getChromaSampleLocTypeTopField(), "chroma_sample_loc_type_top_field"); | |
343 WRITE_UVLC(pcVUI->getChromaSampleLocTypeBottomField(), "chroma_sample_loc_type_bottom_field"); | |
344 } | |
345 | |
346 WRITE_FLAG(pcVUI->getNeutralChromaIndicationFlag(), "neutral_chroma_indication_flag"); | |
347 WRITE_FLAG(pcVUI->getFieldSeqFlag(), "field_seq_flag"); | |
348 WRITE_FLAG(pcVUI->getFrameFieldInfoPresentFlag(), "frame_field_info_present_flag"); | |
349 | |
350 Window defaultDisplayWindow = pcVUI->getDefaultDisplayWindow(); | |
351 WRITE_FLAG(defaultDisplayWindow.getWindowEnabledFlag(), "default_display_window_flag"); | |
352 if( defaultDisplayWindow.getWindowEnabledFlag() ) | |
353 { | |
354 WRITE_UVLC(defaultDisplayWindow.getWindowLeftOffset() / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc()), "def_disp_win_left_offset"); | |
355 WRITE_UVLC(defaultDisplayWindow.getWindowRightOffset() / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc()), "def_disp_win_right_offset"); | |
356 WRITE_UVLC(defaultDisplayWindow.getWindowTopOffset() / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc()), "def_disp_win_top_offset"); | |
357 WRITE_UVLC(defaultDisplayWindow.getWindowBottomOffset()/ TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc()), "def_disp_win_bottom_offset"); | |
358 } | |
359 TimingInfo *timingInfo = pcVUI->getTimingInfo(); | |
360 WRITE_FLAG(timingInfo->getTimingInfoPresentFlag(), "vui_timing_info_present_flag"); | |
361 if(timingInfo->getTimingInfoPresentFlag()) | |
362 { | |
363 WRITE_CODE(timingInfo->getNumUnitsInTick(), 32, "vui_num_units_in_tick"); | |
364 WRITE_CODE(timingInfo->getTimeScale(), 32, "vui_time_scale"); | |
365 WRITE_FLAG(timingInfo->getPocProportionalToTimingFlag(), "vui_poc_proportional_to_timing_flag"); | |
366 if(timingInfo->getPocProportionalToTimingFlag()) | |
367 { | |
368 WRITE_UVLC(timingInfo->getNumTicksPocDiffOneMinus1(), "vui_num_ticks_poc_diff_one_minus1"); | |
369 } | |
370 WRITE_FLAG(pcVUI->getHrdParametersPresentFlag(), "hrd_parameters_present_flag"); | |
371 if( pcVUI->getHrdParametersPresentFlag() ) | |
372 { | |
373 codeHrdParameters(pcVUI->getHrdParameters(), 1, pcSPS->getMaxTLayers() - 1 ); | |
374 } | |
375 } | |
376 | |
377 WRITE_FLAG(pcVUI->getBitstreamRestrictionFlag(), "bitstream_restriction_flag"); | |
378 if (pcVUI->getBitstreamRestrictionFlag()) | |
379 { | |
380 WRITE_FLAG(pcVUI->getTilesFixedStructureFlag(), "tiles_fixed_structure_flag"); | |
381 WRITE_FLAG(pcVUI->getMotionVectorsOverPicBoundariesFlag(), "motion_vectors_over_pic_boundaries_flag"); | |
382 WRITE_FLAG(pcVUI->getRestrictedRefPicListsFlag(), "restricted_ref_pic_lists_flag"); | |
383 WRITE_UVLC(pcVUI->getMinSpatialSegmentationIdc(), "min_spatial_segmentation_idc"); | |
384 WRITE_UVLC(pcVUI->getMaxBytesPerPicDenom(), "max_bytes_per_pic_denom"); | |
385 WRITE_UVLC(pcVUI->getMaxBitsPerMinCuDenom(), "max_bits_per_mincu_denom"); | |
386 WRITE_UVLC(pcVUI->getLog2MaxMvLengthHorizontal(), "log2_max_mv_length_horizontal"); | |
387 WRITE_UVLC(pcVUI->getLog2MaxMvLengthVertical(), "log2_max_mv_length_vertical"); | |
388 } | |
389 } | |
390 | |
391 Void TEncCavlc::codeHrdParameters( TComHRD *hrd, Bool commonInfPresentFlag, UInt maxNumSubLayersMinus1 ) | |
392 { | |
393 if( commonInfPresentFlag ) | |
394 { | |
395 WRITE_FLAG( hrd->getNalHrdParametersPresentFlag() ? 1 : 0 , "nal_hrd_parameters_present_flag" ); | |
396 WRITE_FLAG( hrd->getVclHrdParametersPresentFlag() ? 1 : 0 , "vcl_hrd_parameters_present_flag" ); | |
397 if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) | |
398 { | |
399 WRITE_FLAG( hrd->getSubPicCpbParamsPresentFlag() ? 1 : 0, "sub_pic_cpb_params_present_flag" ); | |
400 if( hrd->getSubPicCpbParamsPresentFlag() ) | |
401 { | |
402 WRITE_CODE( hrd->getTickDivisorMinus2(), 8, "tick_divisor_minus2" ); | |
403 WRITE_CODE( hrd->getDuCpbRemovalDelayLengthMinus1(), 5, "du_cpb_removal_delay_length_minus1" ); | |
404 WRITE_FLAG( hrd->getSubPicCpbParamsInPicTimingSEIFlag() ? 1 : 0, "sub_pic_cpb_params_in_pic_timing_sei_flag" ); | |
405 WRITE_CODE( hrd->getDpbOutputDelayDuLengthMinus1(), 5, "dpb_output_delay_du_length_minus1" ); | |
406 } | |
407 WRITE_CODE( hrd->getBitRateScale(), 4, "bit_rate_scale" ); | |
408 WRITE_CODE( hrd->getCpbSizeScale(), 4, "cpb_size_scale" ); | |
409 if( hrd->getSubPicCpbParamsPresentFlag() ) | |
410 { | |
411 WRITE_CODE( hrd->getDuCpbSizeScale(), 4, "du_cpb_size_scale" ); | |
412 } | |
413 WRITE_CODE( hrd->getInitialCpbRemovalDelayLengthMinus1(), 5, "initial_cpb_removal_delay_length_minus1" ); | |
414 WRITE_CODE( hrd->getCpbRemovalDelayLengthMinus1(), 5, "au_cpb_removal_delay_length_minus1" ); | |
415 WRITE_CODE( hrd->getDpbOutputDelayLengthMinus1(), 5, "dpb_output_delay_length_minus1" ); | |
416 } | |
417 } | |
418 Int i, j, nalOrVcl; | |
419 for( i = 0; i <= maxNumSubLayersMinus1; i ++ ) | |
420 { | |
421 WRITE_FLAG( hrd->getFixedPicRateFlag( i ) ? 1 : 0, "fixed_pic_rate_general_flag"); | |
422 if( !hrd->getFixedPicRateFlag( i ) ) | |
423 { | |
424 WRITE_FLAG( hrd->getFixedPicRateWithinCvsFlag( i ) ? 1 : 0, "fixed_pic_rate_within_cvs_flag"); | |
425 } | |
426 else | |
427 { | |
428 hrd->setFixedPicRateWithinCvsFlag( i, true ); | |
429 } | |
430 if( hrd->getFixedPicRateWithinCvsFlag( i ) ) | |
431 { | |
432 WRITE_UVLC( hrd->getPicDurationInTcMinus1( i ), "elemental_duration_in_tc_minus1"); | |
433 } | |
434 else | |
435 { | |
436 WRITE_FLAG( hrd->getLowDelayHrdFlag( i ) ? 1 : 0, "low_delay_hrd_flag"); | |
437 } | |
438 if (!hrd->getLowDelayHrdFlag( i )) | |
439 { | |
440 WRITE_UVLC( hrd->getCpbCntMinus1( i ), "cpb_cnt_minus1"); | |
441 } | |
442 | |
443 for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ ) | |
444 { | |
445 if( ( ( nalOrVcl == 0 ) && ( hrd->getNalHrdParametersPresentFlag() ) ) || | |
446 ( ( nalOrVcl == 1 ) && ( hrd->getVclHrdParametersPresentFlag() ) ) ) | |
447 { | |
448 for( j = 0; j <= ( hrd->getCpbCntMinus1( i ) ); j ++ ) | |
449 { | |
450 WRITE_UVLC( hrd->getBitRateValueMinus1( i, j, nalOrVcl ), "bit_rate_value_minus1"); | |
451 WRITE_UVLC( hrd->getCpbSizeValueMinus1( i, j, nalOrVcl ), "cpb_size_value_minus1"); | |
452 if( hrd->getSubPicCpbParamsPresentFlag() ) | |
453 { | |
454 WRITE_UVLC( hrd->getDuCpbSizeValueMinus1( i, j, nalOrVcl ), "cpb_size_du_value_minus1"); | |
455 WRITE_UVLC( hrd->getDuBitRateValueMinus1( i, j, nalOrVcl ), "bit_rate_du_value_minus1"); | |
456 } | |
457 WRITE_FLAG( hrd->getCbrFlag( i, j, nalOrVcl ) ? 1 : 0, "cbr_flag"); | |
458 } | |
459 } | |
460 } | |
461 } | |
462 } | |
463 | |
464 Void TEncCavlc::codeSPS( TComSPS* pcSPS ) | |
465 { | |
466 | |
467 const ChromaFormat format = pcSPS->getChromaFormatIdc(); | |
468 const Bool chromaEnabled = isChromaEnabled(format); | |
469 | |
470 #if ENC_DEC_TRACE | |
471 xTraceSPSHeader (pcSPS); | |
472 #endif | |
473 WRITE_CODE( pcSPS->getVPSId (), 4, "sps_video_parameter_set_id" ); | |
474 WRITE_CODE( pcSPS->getMaxTLayers() - 1, 3, "sps_max_sub_layers_minus1" ); | |
475 WRITE_FLAG( pcSPS->getTemporalIdNestingFlag() ? 1 : 0, "sps_temporal_id_nesting_flag" ); | |
476 codePTL(pcSPS->getPTL(), 1, pcSPS->getMaxTLayers() - 1); | |
477 WRITE_UVLC( pcSPS->getSPSId (), "sps_seq_parameter_set_id" ); | |
478 WRITE_UVLC( Int(pcSPS->getChromaFormatIdc ()), "chroma_format_idc" ); | |
479 if( format == CHROMA_444 ) | |
480 { | |
481 WRITE_FLAG( 0, "separate_colour_plane_flag"); | |
482 } | |
483 | |
484 WRITE_UVLC( pcSPS->getPicWidthInLumaSamples (), "pic_width_in_luma_samples" ); | |
485 WRITE_UVLC( pcSPS->getPicHeightInLumaSamples(), "pic_height_in_luma_samples" ); | |
486 Window conf = pcSPS->getConformanceWindow(); | |
487 | |
488 WRITE_FLAG( conf.getWindowEnabledFlag(), "conformance_window_flag" ); | |
489 if (conf.getWindowEnabledFlag()) | |
490 { | |
491 WRITE_UVLC( conf.getWindowLeftOffset() / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_left_offset" ); | |
492 WRITE_UVLC( conf.getWindowRightOffset() / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_right_offset" ); | |
493 WRITE_UVLC( conf.getWindowTopOffset() / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_top_offset" ); | |
494 WRITE_UVLC( conf.getWindowBottomOffset() / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_bottom_offset" ); | |
495 } | |
496 | |
497 WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8, "bit_depth_luma_minus8" ); | |
498 | |
499 WRITE_UVLC( chromaEnabled ? (pcSPS->getBitDepth(CHANNEL_TYPE_CHROMA) - 8):0, "bit_depth_chroma_minus8" ); | |
500 | |
501 WRITE_UVLC( pcSPS->getBitsForPOC()-4, "log2_max_pic_order_cnt_lsb_minus4" ); | |
502 | |
503 const Bool subLayerOrderingInfoPresentFlag = 1; | |
504 WRITE_FLAG(subLayerOrderingInfoPresentFlag, "sps_sub_layer_ordering_info_present_flag"); | |
505 for(UInt i=0; i <= pcSPS->getMaxTLayers()-1; i++) | |
506 { | |
507 WRITE_UVLC( pcSPS->getMaxDecPicBuffering(i) - 1, "sps_max_dec_pic_buffering_minus1[i]" ); | |
508 WRITE_UVLC( pcSPS->getNumReorderPics(i), "sps_num_reorder_pics[i]" ); | |
509 WRITE_UVLC( pcSPS->getMaxLatencyIncrease(i), "sps_max_latency_increase_plus1[i]" ); | |
510 if (!subLayerOrderingInfoPresentFlag) | |
511 { | |
512 break; | |
513 } | |
514 } | |
515 assert( pcSPS->getMaxCUWidth() == pcSPS->getMaxCUHeight() ); | |
516 | |
517 WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 3, "log2_min_coding_block_size_minus3" ); | |
518 WRITE_UVLC( pcSPS->getLog2DiffMaxMinCodingBlockSize(), "log2_diff_max_min_coding_block_size" ); | |
519 WRITE_UVLC( pcSPS->getQuadtreeTULog2MinSize() - 2, "log2_min_transform_block_size_minus2" ); | |
520 WRITE_UVLC( pcSPS->getQuadtreeTULog2MaxSize() - pcSPS->getQuadtreeTULog2MinSize(), "log2_diff_max_min_transform_block_size" ); | |
521 WRITE_UVLC( pcSPS->getQuadtreeTUMaxDepthInter() - 1, "max_transform_hierarchy_depth_inter" ); | |
522 WRITE_UVLC( pcSPS->getQuadtreeTUMaxDepthIntra() - 1, "max_transform_hierarchy_depth_intra" ); | |
523 WRITE_FLAG( pcSPS->getScalingListFlag() ? 1 : 0, "scaling_list_enabled_flag" ); | |
524 if(pcSPS->getScalingListFlag()) | |
525 { | |
526 WRITE_FLAG( pcSPS->getScalingListPresentFlag() ? 1 : 0, "sps_scaling_list_data_present_flag" ); | |
527 if(pcSPS->getScalingListPresentFlag()) | |
528 { | |
529 codeScalingList( m_pcSlice->getScalingList() ); | |
530 } | |
531 } | |
532 WRITE_FLAG( pcSPS->getUseAMP() ? 1 : 0, "amp_enabled_flag" ); | |
533 WRITE_FLAG( pcSPS->getUseSAO() ? 1 : 0, "sample_adaptive_offset_enabled_flag"); | |
534 | |
535 WRITE_FLAG( pcSPS->getUsePCM() ? 1 : 0, "pcm_enabled_flag"); | |
536 if( pcSPS->getUsePCM() ) | |
537 { | |
538 WRITE_CODE( pcSPS->getPCMBitDepth(CHANNEL_TYPE_LUMA) - 1, 4, "pcm_sample_bit_depth_luma_minus1" ); | |
539 WRITE_CODE( chromaEnabled ? (pcSPS->getPCMBitDepth(CHANNEL_TYPE_CHROMA) - 1) : 0, 4, "pcm_sample_bit_depth_chroma_minus1" ); | |
540 WRITE_UVLC( pcSPS->getPCMLog2MinSize() - 3, "log2_min_pcm_luma_coding_block_size_minus3" ); | |
541 WRITE_UVLC( pcSPS->getPCMLog2MaxSize() - pcSPS->getPCMLog2MinSize(), "log2_diff_max_min_pcm_luma_coding_block_size" ); | |
542 WRITE_FLAG( pcSPS->getPCMFilterDisableFlag()?1 : 0, "pcm_loop_filter_disable_flag"); | |
543 } | |
544 | |
545 assert( pcSPS->getMaxTLayers() > 0 ); | |
546 | |
547 TComRPSList* rpsList = pcSPS->getRPSList(); | |
548 TComReferencePictureSet* rps; | |
549 | |
550 #if SRPS_IN_SLICE | |
551 WRITE_UVLC(0, "num_short_term_ref_pic_sets" ); | |
552 #else | |
553 WRITE_UVLC(rpsList->getNumberOfReferencePictureSets(), "num_short_term_ref_pic_sets" ); | |
554 for(Int i=0; i < rpsList->getNumberOfReferencePictureSets(); i++) | |
555 { | |
556 rps = rpsList->getReferencePictureSet(i); | |
557 codeShortTermRefPicSet(pcSPS,rps,false, i); | |
558 } | |
559 #endif | |
560 WRITE_FLAG( pcSPS->getLongTermRefsPresent() ? 1 : 0, "long_term_ref_pics_present_flag" ); | |
561 if (pcSPS->getLongTermRefsPresent()) | |
562 { | |
563 WRITE_UVLC(pcSPS->getNumLongTermRefPicSPS(), "num_long_term_ref_pic_sps" ); | |
564 for (UInt k = 0; k < pcSPS->getNumLongTermRefPicSPS(); k++) | |
565 { | |
566 WRITE_CODE( pcSPS->getLtRefPicPocLsbSps(k), pcSPS->getBitsForPOC(), "lt_ref_pic_poc_lsb_sps"); | |
567 WRITE_FLAG( pcSPS->getUsedByCurrPicLtSPSFlag(k), "used_by_curr_pic_lt_sps_flag"); | |
568 } | |
569 } | |
570 WRITE_FLAG( pcSPS->getTMVPFlagsPresent() ? 1 : 0, "sps_temporal_mvp_enable_flag" ); | |
571 | |
572 WRITE_FLAG( pcSPS->getUseStrongIntraSmoothing(), "sps_strong_intra_smoothing_enable_flag" ); | |
573 | |
574 WRITE_FLAG( pcSPS->getVuiParametersPresentFlag(), "vui_parameters_present_flag" ); | |
575 if (pcSPS->getVuiParametersPresentFlag()) | |
576 { | |
577 codeVUI(pcSPS->getVuiParameters(), pcSPS); | |
578 } | |
579 | |
580 Bool sps_extension_present_flag=false; | |
581 Bool sps_extension_flags[NUM_SPS_EXTENSION_FLAGS]={false}; | |
582 | |
583 sps_extension_flags[SPS_EXT__REXT] = ( | |
584 pcSPS->getUseResidualRotation() | |
585 || pcSPS->getUseSingleSignificanceMapContext() | |
586 || pcSPS->getUseResidualDPCM(RDPCM_SIGNAL_IMPLICIT) | |
587 || pcSPS->getUseResidualDPCM(RDPCM_SIGNAL_EXPLICIT) | |
588 || pcSPS->getUseExtendedPrecision() | |
589 || pcSPS->getDisableIntraReferenceSmoothing() | |
590 || pcSPS->getUseHighPrecisionPredictionWeighting() | |
591 || pcSPS->getUseGolombRiceParameterAdaptation() | |
592 || pcSPS->getAlignCABACBeforeBypass() | |
593 ); | |
594 | |
595 // Other SPS extension flags checked here. | |
596 | |
597 for(Int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) | |
598 { | |
599 sps_extension_present_flag|=sps_extension_flags[i]; | |
600 } | |
601 | |
602 WRITE_FLAG( (sps_extension_present_flag?1:0), "sps_extension_present_flag" ); | |
603 | |
604 if (sps_extension_present_flag) | |
605 { | |
606 for(Int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) | |
607 { | |
608 WRITE_FLAG( sps_extension_flags[i]?1:0, "sps_extension_flag[]" ); | |
609 } | |
610 | |
611 for(Int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) // loop used so that the order is determined by the enum. | |
612 { | |
613 if (sps_extension_flags[i]) | |
614 { | |
615 switch (SPSExtensionFlagIndex(i)) | |
616 { | |
617 case SPS_EXT__REXT: | |
618 | |
619 WRITE_FLAG( (pcSPS->getUseResidualRotation() ? 1 : 0), "transform_skip_rotation_enabled_flag"); | |
620 WRITE_FLAG( (pcSPS->getUseSingleSignificanceMapContext() ? 1 : 0), "transform_skip_context_enabled_flag"); | |
621 WRITE_FLAG( (pcSPS->getUseResidualDPCM(RDPCM_SIGNAL_IMPLICIT) ? 1 : 0), "residual_dpcm_implicit_enabled_flag" ); | |
622 WRITE_FLAG( (pcSPS->getUseResidualDPCM(RDPCM_SIGNAL_EXPLICIT) ? 1 : 0), "residual_dpcm_explicit_enabled_flag" ); | |
623 WRITE_FLAG( (pcSPS->getUseExtendedPrecision() ? 1 : 0), "extended_precision_processing_flag" ); | |
624 WRITE_FLAG( (pcSPS->getDisableIntraReferenceSmoothing() ? 1 : 0), "intra_smoothing_disabled_flag" ); | |
625 WRITE_FLAG( (pcSPS->getUseHighPrecisionPredictionWeighting() ? 1 : 0), "high_precision_prediction_weighting_flag" ); | |
626 WRITE_FLAG( (pcSPS->getUseGolombRiceParameterAdaptation() ? 1 : 0), "golomb_rice_parameter_adaptation_flag" ); | |
627 WRITE_FLAG( (pcSPS->getAlignCABACBeforeBypass() ? 1 : 0), "cabac_bypass_alignment_enabled_flag" ); | |
628 break; | |
629 default: | |
630 assert(sps_extension_flags[i]==false); // Should never get here with an active SPS extension flag. | |
631 break; | |
632 } | |
633 } | |
634 } | |
635 } | |
636 } | |
637 | |
638 Void TEncCavlc::codeVPS( TComVPS* pcVPS ) | |
639 { | |
640 WRITE_CODE( pcVPS->getVPSId(), 4, "vps_video_parameter_set_id" ); | |
641 WRITE_CODE( 3, 2, "vps_reserved_three_2bits" ); | |
642 WRITE_CODE( 0, 6, "vps_reserved_zero_6bits" ); | |
643 WRITE_CODE( pcVPS->getMaxTLayers() - 1, 3, "vps_max_sub_layers_minus1" ); | |
644 WRITE_FLAG( pcVPS->getTemporalNestingFlag(), "vps_temporal_id_nesting_flag" ); | |
645 assert (pcVPS->getMaxTLayers()>1||pcVPS->getTemporalNestingFlag()); | |
646 WRITE_CODE( 0xffff, 16, "vps_reserved_ffff_16bits" ); | |
647 codePTL( pcVPS->getPTL(), true, pcVPS->getMaxTLayers() - 1 ); | |
648 const Bool subLayerOrderingInfoPresentFlag = 1; | |
649 WRITE_FLAG(subLayerOrderingInfoPresentFlag, "vps_sub_layer_ordering_info_present_flag"); | |
650 for(UInt i=0; i <= pcVPS->getMaxTLayers()-1; i++) | |
651 { | |
652 WRITE_UVLC( pcVPS->getMaxDecPicBuffering(i) - 1, "vps_max_dec_pic_buffering_minus1[i]" ); | |
653 WRITE_UVLC( pcVPS->getNumReorderPics(i), "vps_num_reorder_pics[i]" ); | |
654 WRITE_UVLC( pcVPS->getMaxLatencyIncrease(i), "vps_max_latency_increase_plus1[i]" ); | |
655 if (!subLayerOrderingInfoPresentFlag) | |
656 { | |
657 break; | |
658 } | |
659 } | |
660 | |
661 assert( pcVPS->getNumHrdParameters() <= MAX_VPS_NUM_HRD_PARAMETERS ); | |
662 assert( pcVPS->getMaxNuhReservedZeroLayerId() < MAX_VPS_NUH_RESERVED_ZERO_LAYER_ID_PLUS1 ); | |
663 WRITE_CODE( pcVPS->getMaxNuhReservedZeroLayerId(), 6, "vps_max_nuh_reserved_zero_layer_id" ); | |
664 pcVPS->setMaxOpSets(1); | |
665 WRITE_UVLC( pcVPS->getMaxOpSets() - 1, "vps_max_op_sets_minus1" ); | |
666 for( UInt opsIdx = 1; opsIdx <= ( pcVPS->getMaxOpSets() - 1 ); opsIdx ++ ) | |
667 { | |
668 // Operation point set | |
669 for( UInt i = 0; i <= pcVPS->getMaxNuhReservedZeroLayerId(); i ++ ) | |
670 { | |
671 // Only applicable for version 1 | |
672 pcVPS->setLayerIdIncludedFlag( true, opsIdx, i ); | |
673 WRITE_FLAG( pcVPS->getLayerIdIncludedFlag( opsIdx, i ) ? 1 : 0, "layer_id_included_flag[opsIdx][i]" ); | |
674 } | |
675 } | |
676 TimingInfo *timingInfo = pcVPS->getTimingInfo(); | |
677 WRITE_FLAG(timingInfo->getTimingInfoPresentFlag(), "vps_timing_info_present_flag"); | |
678 if(timingInfo->getTimingInfoPresentFlag()) | |
679 { | |
680 WRITE_CODE(timingInfo->getNumUnitsInTick(), 32, "vps_num_units_in_tick"); | |
681 WRITE_CODE(timingInfo->getTimeScale(), 32, "vps_time_scale"); | |
682 WRITE_FLAG(timingInfo->getPocProportionalToTimingFlag(), "vps_poc_proportional_to_timing_flag"); | |
683 if(timingInfo->getPocProportionalToTimingFlag()) | |
684 { | |
685 WRITE_UVLC(timingInfo->getNumTicksPocDiffOneMinus1(), "vps_num_ticks_poc_diff_one_minus1"); | |
686 } | |
687 pcVPS->setNumHrdParameters( 0 ); | |
688 WRITE_UVLC( pcVPS->getNumHrdParameters(), "vps_num_hrd_parameters" ); | |
689 | |
690 if( pcVPS->getNumHrdParameters() > 0 ) | |
691 { | |
692 pcVPS->createHrdParamBuffer(); | |
693 } | |
694 for( UInt i = 0; i < pcVPS->getNumHrdParameters(); i ++ ) | |
695 { | |
696 // Only applicable for version 1 | |
697 pcVPS->setHrdOpSetIdx( 0, i ); | |
698 WRITE_UVLC( pcVPS->getHrdOpSetIdx( i ), "hrd_op_set_idx" ); | |
699 if( i > 0 ) | |
700 { | |
701 WRITE_FLAG( pcVPS->getCprmsPresentFlag( i ) ? 1 : 0, "cprms_present_flag[i]" ); | |
702 } | |
703 codeHrdParameters(pcVPS->getHrdParameters(i), pcVPS->getCprmsPresentFlag( i ), pcVPS->getMaxTLayers() - 1); | |
704 } | |
705 } | |
706 WRITE_FLAG( 0, "vps_extension_flag" ); | |
707 | |
708 //future extensions here.. | |
709 | |
710 return; | |
711 } | |
712 | |
713 Void TEncCavlc::codeSliceHeader ( TComSlice* pcSlice ) | |
714 { | |
715 #if ENC_DEC_TRACE | |
716 xTraceSliceHeader (pcSlice); | |
717 #endif | |
718 | |
719 const ChromaFormat format = pcSlice->getSPS()->getChromaFormatIdc(); | |
720 const UInt numberValidComponents = getNumberValidComponents(format); | |
721 const Bool chromaEnabled = isChromaEnabled(format); | |
722 | |
723 //calculate number of bits required for slice address | |
724 Int maxSliceSegmentAddress = pcSlice->getPic()->getNumberOfCtusInFrame(); | |
725 Int bitsSliceSegmentAddress = 0; | |
726 while(maxSliceSegmentAddress>(1<<bitsSliceSegmentAddress)) | |
727 { | |
728 bitsSliceSegmentAddress++; | |
729 } | |
730 const Int ctuTsAddress = pcSlice->getSliceSegmentCurStartCtuTsAddr(); | |
731 | |
732 //write slice address | |
733 const Int sliceSegmentRsAddress = pcSlice->getPic()->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddress); | |
734 | |
735 WRITE_FLAG( sliceSegmentRsAddress==0, "first_slice_segment_in_pic_flag" ); | |
736 if ( pcSlice->getRapPicFlag() ) | |
737 { | |
738 WRITE_FLAG( pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag" ); | |
739 } | |
740 WRITE_UVLC( pcSlice->getPPS()->getPPSId(), "slice_pic_parameter_set_id" ); | |
741 if ( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() && (sliceSegmentRsAddress!=0) ) | |
742 { | |
743 WRITE_FLAG( pcSlice->getDependentSliceSegmentFlag() ? 1 : 0, "dependent_slice_segment_flag" ); | |
744 } | |
745 if(sliceSegmentRsAddress>0) | |
746 { | |
747 WRITE_CODE( sliceSegmentRsAddress, bitsSliceSegmentAddress, "slice_segment_address" ); | |
748 } | |
749 if ( !pcSlice->getDependentSliceSegmentFlag() ) | |
750 { | |
751 for (Int i = 0; i < pcSlice->getPPS()->getNumExtraSliceHeaderBits(); i++) | |
752 { | |
753 assert(!!"slice_reserved_undetermined_flag[]"); | |
754 WRITE_FLAG(0, "slice_reserved_undetermined_flag[]"); | |
755 } | |
756 | |
757 WRITE_UVLC( pcSlice->getSliceType(), "slice_type" ); | |
758 | |
759 if( pcSlice->getPPS()->getOutputFlagPresentFlag() ) | |
760 { | |
761 WRITE_FLAG( pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag" ); | |
762 } | |
763 | |
764 if( !pcSlice->getIdrPicFlag() ) | |
765 { | |
766 Int picOrderCntLSB = (pcSlice->getPOC()-pcSlice->getLastIDR()+(1<<pcSlice->getSPS()->getBitsForPOC())) & ((1<<pcSlice->getSPS()->getBitsForPOC())-1); | |
767 WRITE_CODE( picOrderCntLSB, pcSlice->getSPS()->getBitsForPOC(), "pic_order_cnt_lsb"); | |
768 TComReferencePictureSet* rps = pcSlice->getRPS(); | |
769 | |
770 // check for bitstream restriction stating that: | |
771 // If the current picture is a BLA or CRA picture, the value of NumPocTotalCurr shall be equal to 0. | |
772 // Ideally this process should not be repeated for each slice in a picture | |
773 if (pcSlice->isIRAP()) | |
774 { | |
775 for (Int picIdx = 0; picIdx < rps->getNumberOfPictures(); picIdx++) | |
776 { | |
777 assert (!rps->getUsed(picIdx)); | |
778 } | |
779 } | |
780 | |
781 #if SRPS_IN_SLICE | |
782 { | |
783 WRITE_FLAG( 0, "short_term_ref_pic_set_sps_flag"); | |
784 codeShortTermRefPicSet(pcSlice->getSPS(), rps, true, 0); | |
785 } | |
786 #else | |
787 if(pcSlice->getRPSidx() < 0) | |
788 { | |
789 WRITE_FLAG( 0, "short_term_ref_pic_set_sps_flag"); | |
790 codeShortTermRefPicSet(pcSlice->getSPS(), rps, true, pcSlice->getSPS()->getRPSList()->getNumberOfReferencePictureSets()); | |
791 } | |
792 else | |
793 { | |
794 WRITE_FLAG( 1, "short_term_ref_pic_set_sps_flag"); | |
795 Int numBits = 0; | |
796 while ((1 << numBits) < pcSlice->getSPS()->getRPSList()->getNumberOfReferencePictureSets()) | |
797 { | |
798 numBits++; | |
799 } | |
800 if (numBits > 0) | |
801 { | |
802 WRITE_CODE( pcSlice->getRPSidx(), numBits, "short_term_ref_pic_set_idx" ); | |
803 } | |
804 } | |
805 #endif | |
806 if(pcSlice->getSPS()->getLongTermRefsPresent()) | |
807 { | |
808 Int numLtrpInSH = rps->getNumberOfLongtermPictures(); | |
809 Int ltrpInSPS[MAX_NUM_REF_PICS]; | |
810 Int numLtrpInSPS = 0; | |
811 UInt ltrpIndex; | |
812 Int counter = 0; | |
813 for(Int k = rps->getNumberOfPictures()-1; k > rps->getNumberOfPictures()-rps->getNumberOfLongtermPictures()-1; k--) | |
814 { | |
815 if (findMatchingLTRP(pcSlice, <rpIndex, rps->getPOC(k), rps->getUsed(k))) | |
816 { | |
817 ltrpInSPS[numLtrpInSPS] = ltrpIndex; | |
818 numLtrpInSPS++; | |
819 } | |
820 else | |
821 { | |
822 counter++; | |
823 } | |
824 } | |
825 numLtrpInSH -= numLtrpInSPS; | |
826 | |
827 Int bitsForLtrpInSPS = 0; | |
828 while (pcSlice->getSPS()->getNumLongTermRefPicSPS() > (1 << bitsForLtrpInSPS)) | |
829 { | |
830 bitsForLtrpInSPS++; | |
831 } | |
832 if (pcSlice->getSPS()->getNumLongTermRefPicSPS() > 0) | |
833 { | |
834 WRITE_UVLC( numLtrpInSPS, "num_long_term_sps"); | |
835 } | |
836 WRITE_UVLC( numLtrpInSH, "num_long_term_pics"); | |
837 // Note that the LSBs of the LT ref. pic. POCs must be sorted before. | |
838 // Not sorted here because LT ref indices will be used in setRefPicList() | |
839 Int prevDeltaMSB = 0, prevLSB = 0; | |
840 Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures(); | |
841 for(Int i=rps->getNumberOfPictures()-1 ; i > offset-1; i--) | |
842 { | |
843 if (counter < numLtrpInSPS) | |
844 { | |
845 if (bitsForLtrpInSPS > 0) | |
846 { | |
847 WRITE_CODE( ltrpInSPS[counter], bitsForLtrpInSPS, "lt_idx_sps[i]"); | |
848 } | |
849 } | |
850 else | |
851 { | |
852 WRITE_CODE( rps->getPocLSBLT(i), pcSlice->getSPS()->getBitsForPOC(), "poc_lsb_lt"); | |
853 WRITE_FLAG( rps->getUsed(i), "used_by_curr_pic_lt_flag"); | |
854 } | |
855 WRITE_FLAG( rps->getDeltaPocMSBPresentFlag(i), "delta_poc_msb_present_flag"); | |
856 | |
857 if(rps->getDeltaPocMSBPresentFlag(i)) | |
858 { | |
859 Bool deltaFlag = false; | |
860 // First LTRP from SPS || First LTRP from SH || curr LSB != prev LSB | |
861 if( (i == rps->getNumberOfPictures()-1) || (i == rps->getNumberOfPictures()-1-numLtrpInSPS) || (rps->getPocLSBLT(i) != prevLSB) ) | |
862 { | |
863 deltaFlag = true; | |
864 } | |
865 if(deltaFlag) | |
866 { | |
867 WRITE_UVLC( rps->getDeltaPocMSBCycleLT(i), "delta_poc_msb_cycle_lt[i]" ); | |
868 } | |
869 else | |
870 { | |
871 Int differenceInDeltaMSB = rps->getDeltaPocMSBCycleLT(i) - prevDeltaMSB; | |
872 assert(differenceInDeltaMSB >= 0); | |
873 WRITE_UVLC( differenceInDeltaMSB, "delta_poc_msb_cycle_lt[i]" ); | |
874 } | |
875 prevLSB = rps->getPocLSBLT(i); | |
876 prevDeltaMSB = rps->getDeltaPocMSBCycleLT(i); | |
877 } | |
878 } | |
879 } | |
880 if (pcSlice->getSPS()->getTMVPFlagsPresent()) | |
881 { | |
882 WRITE_FLAG( pcSlice->getEnableTMVPFlag() ? 1 : 0, "slice_temporal_mvp_enable_flag" ); | |
883 } | |
884 } | |
885 if(pcSlice->getSPS()->getUseSAO()) | |
886 { | |
887 WRITE_FLAG( pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA), "slice_sao_luma_flag" ); | |
888 if (chromaEnabled) WRITE_FLAG( pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA), "slice_sao_chroma_flag" ); | |
889 } | |
890 | |
891 //check if numrefidxes match the defaults. If not, override | |
892 | |
893 if (!pcSlice->isIntra()) | |
894 { | |
895 Bool overrideFlag = (pcSlice->getNumRefIdx( REF_PIC_LIST_0 )!=pcSlice->getPPS()->getNumRefIdxL0DefaultActive()||(pcSlice->isInterB()&&pcSlice->getNumRefIdx( REF_PIC_LIST_1 )!=pcSlice->getPPS()->getNumRefIdxL1DefaultActive())); | |
896 WRITE_FLAG( overrideFlag ? 1 : 0, "num_ref_idx_active_override_flag"); | |
897 if (overrideFlag) | |
898 { | |
899 WRITE_UVLC( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - 1, "num_ref_idx_l0_active_minus1" ); | |
900 if (pcSlice->isInterB()) | |
901 { | |
902 WRITE_UVLC( pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - 1, "num_ref_idx_l1_active_minus1" ); | |
903 } | |
904 else | |
905 { | |
906 pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0); | |
907 } | |
908 } | |
909 } | |
910 else | |
911 { | |
912 pcSlice->setNumRefIdx(REF_PIC_LIST_0, 0); | |
913 pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0); | |
914 } | |
915 | |
916 if( pcSlice->getPPS()->getListsModificationPresentFlag() && pcSlice->getNumRpsCurrTempList() > 1) | |
917 { | |
918 TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification(); | |
919 if(!pcSlice->isIntra()) | |
920 { | |
921 WRITE_FLAG(pcSlice->getRefPicListModification()->getRefPicListModificationFlagL0() ? 1 : 0, "ref_pic_list_modification_flag_l0" ); | |
922 if (pcSlice->getRefPicListModification()->getRefPicListModificationFlagL0()) | |
923 { | |
924 Int numRpsCurrTempList0 = pcSlice->getNumRpsCurrTempList(); | |
925 if (numRpsCurrTempList0 > 1) | |
926 { | |
927 Int length = 1; | |
928 numRpsCurrTempList0 --; | |
929 while ( numRpsCurrTempList0 >>= 1) | |
930 { | |
931 length ++; | |
932 } | |
933 for(Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); i++) | |
934 { | |
935 WRITE_CODE( refPicListModification->getRefPicSetIdxL0(i), length, "list_entry_l0"); | |
936 } | |
937 } | |
938 } | |
939 } | |
940 if(pcSlice->isInterB()) | |
941 { | |
942 WRITE_FLAG(pcSlice->getRefPicListModification()->getRefPicListModificationFlagL1() ? 1 : 0, "ref_pic_list_modification_flag_l1" ); | |
943 if (pcSlice->getRefPicListModification()->getRefPicListModificationFlagL1()) | |
944 { | |
945 Int numRpsCurrTempList1 = pcSlice->getNumRpsCurrTempList(); | |
946 if ( numRpsCurrTempList1 > 1 ) | |
947 { | |
948 Int length = 1; | |
949 numRpsCurrTempList1 --; | |
950 while ( numRpsCurrTempList1 >>= 1) | |
951 { | |
952 length ++; | |
953 } | |
954 for(Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); i++) | |
955 { | |
956 WRITE_CODE( refPicListModification->getRefPicSetIdxL1(i), length, "list_entry_l1"); | |
957 } | |
958 } | |
959 } | |
960 } | |
961 } | |
962 | |
963 if (pcSlice->isInterB()) | |
964 { | |
965 WRITE_FLAG( pcSlice->getMvdL1ZeroFlag() ? 1 : 0, "mvd_l1_zero_flag"); | |
966 } | |
967 | |
968 if(!pcSlice->isIntra()) | |
969 { | |
970 if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag()) | |
971 { | |
972 SliceType sliceType = pcSlice->getSliceType(); | |
973 Int encCABACTableIdx = pcSlice->getPPS()->getEncCABACTableIdx(); | |
974 Bool encCabacInitFlag = (sliceType!=encCABACTableIdx && encCABACTableIdx!=I_SLICE) ? true : false; | |
975 pcSlice->setCabacInitFlag( encCabacInitFlag ); | |
976 WRITE_FLAG( encCabacInitFlag?1:0, "cabac_init_flag" ); | |
977 } | |
978 } | |
979 | |
980 if ( pcSlice->getEnableTMVPFlag() ) | |
981 { | |
982 if ( pcSlice->getSliceType() == B_SLICE ) | |
983 { | |
984 WRITE_FLAG( pcSlice->getColFromL0Flag(), "collocated_from_l0_flag" ); | |
985 } | |
986 | |
987 if ( pcSlice->getSliceType() != I_SLICE && | |
988 ((pcSlice->getColFromL0Flag()==1 && pcSlice->getNumRefIdx(REF_PIC_LIST_0)>1)|| | |
989 (pcSlice->getColFromL0Flag()==0 && pcSlice->getNumRefIdx(REF_PIC_LIST_1)>1))) | |
990 { | |
991 WRITE_UVLC( pcSlice->getColRefIdx(), "collocated_ref_idx" ); | |
992 } | |
993 } | |
994 if ( (pcSlice->getPPS()->getUseWP() && pcSlice->getSliceType()==P_SLICE) || (pcSlice->getPPS()->getWPBiPred() && pcSlice->getSliceType()==B_SLICE) ) | |
995 { | |
996 xCodePredWeightTable( pcSlice ); | |
997 } | |
998 assert(pcSlice->getMaxNumMergeCand()<=MRG_MAX_NUM_CANDS); | |
999 if (!pcSlice->isIntra()) | |
1000 { | |
1001 WRITE_UVLC(MRG_MAX_NUM_CANDS - pcSlice->getMaxNumMergeCand(), "five_minus_max_num_merge_cand"); | |
1002 } | |
1003 Int iCode = pcSlice->getSliceQp() - ( pcSlice->getPPS()->getPicInitQPMinus26() + 26 ); | |
1004 WRITE_SVLC( iCode, "slice_qp_delta" ); | |
1005 if (pcSlice->getPPS()->getSliceChromaQpFlag()) | |
1006 { | |
1007 if (numberValidComponents > COMPONENT_Cb) { WRITE_SVLC( pcSlice->getSliceChromaQpDelta(COMPONENT_Cb), "slice_qp_delta_cb" ); } | |
1008 if (numberValidComponents > COMPONENT_Cr) { WRITE_SVLC( pcSlice->getSliceChromaQpDelta(COMPONENT_Cr), "slice_qp_delta_cr" ); } | |
1009 assert(numberValidComponents <= COMPONENT_Cr+1); | |
1010 } | |
1011 | |
1012 if (pcSlice->getPPS()->getChromaQpAdjTableSize() > 0) | |
1013 { | |
1014 WRITE_FLAG(pcSlice->getUseChromaQpAdj(), "slice_chroma_qp_adjustment_enabled_flag"); | |
1015 } | |
1016 | |
1017 if (pcSlice->getPPS()->getDeblockingFilterControlPresentFlag()) | |
1018 { | |
1019 if (pcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() ) | |
1020 { | |
1021 WRITE_FLAG(pcSlice->getDeblockingFilterOverrideFlag(), "deblocking_filter_override_flag"); | |
1022 } | |
1023 if (pcSlice->getDeblockingFilterOverrideFlag()) | |
1024 { | |
1025 WRITE_FLAG(pcSlice->getDeblockingFilterDisable(), "slice_disable_deblocking_filter_flag"); | |
1026 if(!pcSlice->getDeblockingFilterDisable()) | |
1027 { | |
1028 WRITE_SVLC (pcSlice->getDeblockingFilterBetaOffsetDiv2(), "slice_beta_offset_div2"); | |
1029 WRITE_SVLC (pcSlice->getDeblockingFilterTcOffsetDiv2(), "slice_tc_offset_div2"); | |
1030 } | |
1031 } | |
1032 } | |
1033 | |
1034 Bool isSAOEnabled = pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA) || (chromaEnabled && pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA))); | |
1035 Bool isDBFEnabled = (!pcSlice->getDeblockingFilterDisable()); | |
1036 | |
1037 if(pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag() && ( isSAOEnabled || isDBFEnabled )) | |
1038 { | |
1039 WRITE_FLAG(pcSlice->getLFCrossSliceBoundaryFlag()?1:0, "slice_loop_filter_across_slices_enabled_flag"); | |
1040 } | |
1041 } | |
1042 if(pcSlice->getPPS()->getSliceHeaderExtensionPresentFlag()) | |
1043 { | |
1044 WRITE_UVLC(0,"slice_header_extension_length"); | |
1045 } | |
1046 } | |
1047 | |
1048 Void TEncCavlc::codePTL( TComPTL* pcPTL, Bool profilePresentFlag, Int maxNumSubLayersMinus1) | |
1049 { | |
1050 if(profilePresentFlag) | |
1051 { | |
1052 codeProfileTier(pcPTL->getGeneralPTL()); // general_... | |
1053 } | |
1054 WRITE_CODE( Int(pcPTL->getGeneralPTL()->getLevelIdc()), 8, "general_level_idc" ); | |
1055 | |
1056 for (Int i = 0; i < maxNumSubLayersMinus1; i++) | |
1057 { | |
1058 if(profilePresentFlag) | |
1059 { | |
1060 WRITE_FLAG( pcPTL->getSubLayerProfilePresentFlag(i), "sub_layer_profile_present_flag[i]" ); | |
1061 } | |
1062 | |
1063 WRITE_FLAG( pcPTL->getSubLayerLevelPresentFlag(i), "sub_layer_level_present_flag[i]" ); | |
1064 } | |
1065 | |
1066 if (maxNumSubLayersMinus1 > 0) | |
1067 { | |
1068 for (Int i = maxNumSubLayersMinus1; i < 8; i++) | |
1069 { | |
1070 WRITE_CODE(0, 2, "reserved_zero_2bits"); | |
1071 } | |
1072 } | |
1073 | |
1074 for(Int i = 0; i < maxNumSubLayersMinus1; i++) | |
1075 { | |
1076 if( profilePresentFlag && pcPTL->getSubLayerProfilePresentFlag(i) ) | |
1077 { | |
1078 codeProfileTier(pcPTL->getSubLayerPTL(i)); // sub_layer_... | |
1079 } | |
1080 if( pcPTL->getSubLayerLevelPresentFlag(i) ) | |
1081 { | |
1082 WRITE_CODE( Int(pcPTL->getSubLayerPTL(i)->getLevelIdc()), 8, "sub_layer_level_idc[i]" ); | |
1083 } | |
1084 } | |
1085 } | |
1086 Void TEncCavlc::codeProfileTier( ProfileTierLevel* ptl ) | |
1087 { | |
1088 WRITE_CODE( ptl->getProfileSpace(), 2 , "XXX_profile_space[]"); | |
1089 WRITE_FLAG( ptl->getTierFlag()==Level::HIGH, "XXX_tier_flag[]" ); | |
1090 WRITE_CODE( Int(ptl->getProfileIdc()), 5 , "XXX_profile_idc[]" ); | |
1091 for(Int j = 0; j < 32; j++) | |
1092 { | |
1093 WRITE_FLAG( ptl->getProfileCompatibilityFlag(j), "XXX_profile_compatibility_flag[][j]"); | |
1094 } | |
1095 | |
1096 WRITE_FLAG(ptl->getProgressiveSourceFlag(), "general_progressive_source_flag"); | |
1097 WRITE_FLAG(ptl->getInterlacedSourceFlag(), "general_interlaced_source_flag"); | |
1098 WRITE_FLAG(ptl->getNonPackedConstraintFlag(), "general_non_packed_constraint_flag"); | |
1099 WRITE_FLAG(ptl->getFrameOnlyConstraintFlag(), "general_frame_only_constraint_flag"); | |
1100 | |
1101 if (ptl->getProfileIdc() == Profile::MAINREXT || ptl->getProfileIdc() == Profile::HIGHTHROUGHPUTREXT ) | |
1102 { | |
1103 const UInt bitDepthConstraint=ptl->getBitDepthConstraint(); | |
1104 WRITE_FLAG(bitDepthConstraint<=12, "general_max_12bit_constraint_flag"); | |
1105 WRITE_FLAG(bitDepthConstraint<=10, "general_max_10bit_constraint_flag"); | |
1106 WRITE_FLAG(bitDepthConstraint<= 8, "general_max_8bit_constraint_flag"); | |
1107 const ChromaFormat chromaFmtConstraint=ptl->getChromaFormatConstraint(); | |
1108 WRITE_FLAG(chromaFmtConstraint==CHROMA_422||chromaFmtConstraint==CHROMA_420||chromaFmtConstraint==CHROMA_400, "general_max_422chroma_constraint_flag"); | |
1109 WRITE_FLAG(chromaFmtConstraint==CHROMA_420||chromaFmtConstraint==CHROMA_400, "general_max_420chroma_constraint_flag"); | |
1110 WRITE_FLAG(chromaFmtConstraint==CHROMA_400, "general_max_monochrome_constraint_flag"); | |
1111 WRITE_FLAG(ptl->getIntraConstraintFlag(), "general_intra_constraint_flag"); | |
1112 WRITE_FLAG(0, "general_one_picture_only_constraint_flag"); | |
1113 WRITE_FLAG(ptl->getLowerBitRateConstraintFlag(), "general_lower_bit_rate_constraint_flag"); | |
1114 WRITE_CODE(0 , 16, "XXX_reserved_zero_35bits[0..15]"); | |
1115 WRITE_CODE(0 , 16, "XXX_reserved_zero_35bits[16..31]"); | |
1116 WRITE_CODE(0 , 3, "XXX_reserved_zero_35bits[32..34]"); | |
1117 } | |
1118 else | |
1119 { | |
1120 WRITE_CODE(0x0000 , 16, "XXX_reserved_zero_44bits[0..15]"); | |
1121 WRITE_CODE(0x0000 , 16, "XXX_reserved_zero_44bits[16..31]"); | |
1122 WRITE_CODE(0x000 , 12, "XXX_reserved_zero_44bits[32..43]"); | |
1123 } | |
1124 } | |
1125 | |
1126 /** | |
1127 - write tiles and wavefront substreams sizes for the slice header. | |
1128 . | |
1129 \param pcSlice Where we find the substream size information. | |
1130 */ | |
1131 Void TEncCavlc::codeTilesWPPEntryPoint( TComSlice* pSlice ) | |
1132 { | |
1133 if (!pSlice->getPPS()->getTilesEnabledFlag() && !pSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) | |
1134 { | |
1135 return; | |
1136 } | |
1137 UInt maxOffset = 0; | |
1138 for(Int idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++) | |
1139 { | |
1140 UInt offset=pSlice->getSubstreamSize(idx); | |
1141 if ( offset > maxOffset ) | |
1142 { | |
1143 maxOffset = offset; | |
1144 } | |
1145 } | |
1146 | |
1147 // Determine number of bits "offsetLenMinus1+1" required for entry point information | |
1148 UInt offsetLenMinus1 = 0; | |
1149 while (maxOffset >= (1u << (offsetLenMinus1 + 1))) | |
1150 { | |
1151 offsetLenMinus1++; | |
1152 assert(offsetLenMinus1 + 1 < 32); | |
1153 } | |
1154 | |
1155 WRITE_UVLC(pSlice->getNumberOfSubstreamSizes(), "num_entry_point_offsets"); | |
1156 if (pSlice->getNumberOfSubstreamSizes()>0) | |
1157 { | |
1158 WRITE_UVLC(offsetLenMinus1, "offset_len_minus1"); | |
1159 | |
1160 for (UInt idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++) | |
1161 { | |
1162 WRITE_CODE(pSlice->getSubstreamSize(idx)-1, offsetLenMinus1+1, "entry_point_offset_minus1"); | |
1163 } | |
1164 } | |
1165 } | |
1166 | |
1167 Void TEncCavlc::codeTerminatingBit ( UInt uilsLast ) | |
1168 { | |
1169 } | |
1170 | |
1171 Void TEncCavlc::codeSliceFinish () | |
1172 { | |
1173 } | |
1174 | |
1175 Void TEncCavlc::codeMVPIdx ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
1176 { | |
1177 assert(0); | |
1178 } | |
1179 | |
1180 Void TEncCavlc::codePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) | |
1181 { | |
1182 assert(0); | |
1183 } | |
1184 | |
1185 Void TEncCavlc::codePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1186 { | |
1187 assert(0); | |
1188 } | |
1189 | |
1190 Void TEncCavlc::codeMergeFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1191 { | |
1192 assert(0); | |
1193 } | |
1194 | |
1195 Void TEncCavlc::codeMergeIndex ( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1196 { | |
1197 assert(0); | |
1198 } | |
1199 | |
1200 Void TEncCavlc::codeInterModeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiEncMode ) | |
1201 { | |
1202 assert(0); | |
1203 } | |
1204 | |
1205 Void TEncCavlc::codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1206 { | |
1207 assert(0); | |
1208 } | |
1209 | |
1210 Void TEncCavlc::codeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1211 { | |
1212 assert(0); | |
1213 } | |
1214 | |
1215 Void TEncCavlc::codeSplitFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) | |
1216 { | |
1217 assert(0); | |
1218 } | |
1219 | |
1220 Void TEncCavlc::codeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx ) | |
1221 { | |
1222 assert(0); | |
1223 } | |
1224 | |
1225 Void TEncCavlc::codeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel ) | |
1226 { | |
1227 assert(0); | |
1228 } | |
1229 | |
1230 Void TEncCavlc::codeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1231 { | |
1232 assert(0); | |
1233 } | |
1234 | |
1235 Void TEncCavlc::codeQtCbfZero( TComTU &rTu, const ChannelType chType ) | |
1236 { | |
1237 assert(0); | |
1238 } | |
1239 Void TEncCavlc::codeQtRootCbfZero( TComDataCU* pcCU ) | |
1240 { | |
1241 assert(0); | |
1242 } | |
1243 | |
1244 Void TEncCavlc::codeTransformSkipFlags (TComTU &rTu, ComponentID component ) | |
1245 { | |
1246 assert(0); | |
1247 } | |
1248 | |
1249 /** Code I_PCM information. | |
1250 * \param pcCU pointer to CU | |
1251 * \param uiAbsPartIdx CU index | |
1252 * \returns Void | |
1253 */ | |
1254 Void TEncCavlc::codeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1255 { | |
1256 assert(0); | |
1257 } | |
1258 | |
1259 Void TEncCavlc::codeIntraDirLumaAng( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool isMultiple) | |
1260 { | |
1261 assert(0); | |
1262 } | |
1263 | |
1264 Void TEncCavlc::codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1265 { | |
1266 assert(0); | |
1267 } | |
1268 | |
1269 Void TEncCavlc::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1270 { | |
1271 assert(0); | |
1272 } | |
1273 | |
1274 Void TEncCavlc::codeRefFrmIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
1275 { | |
1276 assert(0); | |
1277 } | |
1278 | |
1279 Void TEncCavlc::codeMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) | |
1280 { | |
1281 assert(0); | |
1282 } | |
1283 | |
1284 Void TEncCavlc::codeCrossComponentPrediction( TComTU& /*rTu*/, ComponentID /*compID*/ ) | |
1285 { | |
1286 assert(0); | |
1287 } | |
1288 | |
1289 Void TEncCavlc::codeDeltaQP( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1290 { | |
1291 Int iDQp = pcCU->getQP( uiAbsPartIdx ) - pcCU->getRefQP( uiAbsPartIdx ); | |
1292 | |
1293 Int qpBdOffsetY = pcCU->getSlice()->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA); | |
1294 iDQp = (iDQp + 78 + qpBdOffsetY + (qpBdOffsetY/2)) % (52 + qpBdOffsetY) - 26 - (qpBdOffsetY/2); | |
1295 | |
1296 xWriteSvlc( iDQp ); | |
1297 | |
1298 return; | |
1299 } | |
1300 | |
1301 Void TEncCavlc::codeChromaQpAdjustment( TComDataCU* pcCU, UInt uiAbsPartIdx ) | |
1302 { | |
1303 assert(0); | |
1304 } | |
1305 | |
1306 Void TEncCavlc::codeCoeffNxN ( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID ) | |
1307 { | |
1308 assert(0); | |
1309 } | |
1310 | |
1311 Void TEncCavlc::estBit( estBitsSbacStruct* pcEstBitsCabac, Int width, Int height, ChannelType chType ) | |
1312 { | |
1313 // printf("error : no VLC mode support in this version\n"); | |
1314 return; | |
1315 } | |
1316 | |
1317 // ==================================================================================================================== | |
1318 // Protected member functions | |
1319 // ==================================================================================================================== | |
1320 | |
1321 /** code explicit wp tables | |
1322 * \param TComSlice* pcSlice | |
1323 * \returns Void | |
1324 */ | |
1325 Void TEncCavlc::xCodePredWeightTable( TComSlice* pcSlice ) | |
1326 { | |
1327 WPScalingParam *wp; | |
1328 const ChromaFormat format = pcSlice->getPic()->getChromaFormat(); | |
1329 const UInt numberValidComponents = getNumberValidComponents(format); | |
1330 const Bool bChroma = isChromaEnabled(format); | |
1331 const Int iNbRef = (pcSlice->getSliceType() == B_SLICE ) ? (2) : (1); | |
1332 Bool bDenomCoded = false; | |
1333 UInt uiMode = 0; | |
1334 UInt uiTotalSignalledWeightFlags = 0; | |
1335 | |
1336 if ( (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred()) ) | |
1337 { | |
1338 uiMode = 1; // explicit | |
1339 } | |
1340 if(uiMode == 1) | |
1341 { | |
1342 for ( Int iNumRef=0 ; iNumRef<iNbRef ; iNumRef++ ) | |
1343 { | |
1344 RefPicList eRefPicList = ( iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); | |
1345 | |
1346 // NOTE: wp[].uiLog2WeightDenom and wp[].bPresentFlag are actually per-channel-type settings. | |
1347 | |
1348 for ( Int iRefIdx=0 ; iRefIdx<pcSlice->getNumRefIdx(eRefPicList) ; iRefIdx++ ) | |
1349 { | |
1350 pcSlice->getWpScaling(eRefPicList, iRefIdx, wp); | |
1351 if ( !bDenomCoded ) | |
1352 { | |
1353 Int iDeltaDenom; | |
1354 WRITE_UVLC( wp[COMPONENT_Y].uiLog2WeightDenom, "luma_log2_weight_denom" ); // ue(v): luma_log2_weight_denom | |
1355 | |
1356 if( bChroma ) | |
1357 { | |
1358 assert(wp[COMPONENT_Cb].uiLog2WeightDenom == wp[COMPONENT_Cr].uiLog2WeightDenom); // check the channel-type settings are consistent across components. | |
1359 iDeltaDenom = (wp[COMPONENT_Cb].uiLog2WeightDenom - wp[COMPONENT_Y].uiLog2WeightDenom); | |
1360 WRITE_SVLC( iDeltaDenom, "delta_chroma_log2_weight_denom" ); // se(v): delta_chroma_log2_weight_denom | |
1361 } | |
1362 bDenomCoded = true; | |
1363 } | |
1364 WRITE_FLAG( wp[COMPONENT_Y].bPresentFlag, "luma_weight_lX_flag" ); // u(1): luma_weight_lX_flag | |
1365 uiTotalSignalledWeightFlags += wp[COMPONENT_Y].bPresentFlag; | |
1366 } | |
1367 if (bChroma) | |
1368 { | |
1369 for ( Int iRefIdx=0 ; iRefIdx<pcSlice->getNumRefIdx(eRefPicList) ; iRefIdx++ ) | |
1370 { | |
1371 pcSlice->getWpScaling(eRefPicList, iRefIdx, wp); | |
1372 assert(wp[COMPONENT_Cb].bPresentFlag == wp[COMPONENT_Cr].bPresentFlag); // check the channel-type settings are consistent across components. | |
1373 WRITE_FLAG( wp[COMPONENT_Cb].bPresentFlag, "chroma_weight_lX_flag" ); // u(1): chroma_weight_lX_flag | |
1374 uiTotalSignalledWeightFlags += 2*wp[COMPONENT_Cb].bPresentFlag; | |
1375 } | |
1376 } | |
1377 | |
1378 for ( Int iRefIdx=0 ; iRefIdx<pcSlice->getNumRefIdx(eRefPicList) ; iRefIdx++ ) | |
1379 { | |
1380 pcSlice->getWpScaling(eRefPicList, iRefIdx, wp); | |
1381 if ( wp[COMPONENT_Y].bPresentFlag ) | |
1382 { | |
1383 Int iDeltaWeight = (wp[COMPONENT_Y].iWeight - (1<<wp[COMPONENT_Y].uiLog2WeightDenom)); | |
1384 WRITE_SVLC( iDeltaWeight, "delta_luma_weight_lX" ); // se(v): delta_luma_weight_lX | |
1385 WRITE_SVLC( wp[COMPONENT_Y].iOffset, "luma_offset_lX" ); // se(v): luma_offset_lX | |
1386 } | |
1387 | |
1388 if ( bChroma ) | |
1389 { | |
1390 if ( wp[COMPONENT_Cb].bPresentFlag ) | |
1391 { | |
1392 for ( Int j = COMPONENT_Cb ; j < numberValidComponents ; j++ ) | |
1393 { | |
1394 assert(wp[COMPONENT_Cb].uiLog2WeightDenom == wp[COMPONENT_Cr].uiLog2WeightDenom); | |
1395 Int iDeltaWeight = (wp[j].iWeight - (1<<wp[COMPONENT_Cb].uiLog2WeightDenom)); | |
1396 WRITE_SVLC( iDeltaWeight, "delta_chroma_weight_lX" ); // se(v): delta_chroma_weight_lX | |
1397 | |
1398 Int range=pcSlice->getSPS()->getUseHighPrecisionPredictionWeighting() ? (1<<g_bitDepth[CHANNEL_TYPE_CHROMA])/2 : 128; | |
1399 Int pred = ( range - ( ( range*wp[j].iWeight)>>(wp[j].uiLog2WeightDenom) ) ); | |
1400 Int iDeltaChroma = (wp[j].iOffset - pred); | |
1401 WRITE_SVLC( iDeltaChroma, "delta_chroma_offset_lX" ); // se(v): delta_chroma_offset_lX | |
1402 } | |
1403 } | |
1404 } | |
1405 } | |
1406 } | |
1407 assert(uiTotalSignalledWeightFlags<=24); | |
1408 } | |
1409 } | |
1410 | |
1411 /** code quantization matrix | |
1412 * \param scalingList quantization matrix information | |
1413 */ | |
1414 Void TEncCavlc::codeScalingList( TComScalingList* scalingList ) | |
1415 { | |
1416 UInt listId,sizeId; | |
1417 Bool scalingListPredModeFlag; | |
1418 | |
1419 //for each size | |
1420 for(sizeId = 0; sizeId < SCALING_LIST_SIZE_NUM; sizeId++) | |
1421 { | |
1422 Int predListStep = (sizeId == SCALING_LIST_32x32? (SCALING_LIST_NUM/NUMBER_OF_PREDICTION_MODES) : 1); // if 32x32, skip over chroma entries. | |
1423 | |
1424 for(listId = 0; listId < SCALING_LIST_NUM; listId+=predListStep) | |
1425 { | |
1426 scalingListPredModeFlag = scalingList->checkPredMode( sizeId, listId ); | |
1427 WRITE_FLAG( scalingListPredModeFlag, "scaling_list_pred_mode_flag" ); | |
1428 if(!scalingListPredModeFlag)// Copy Mode | |
1429 { | |
1430 if (sizeId == SCALING_LIST_32x32) | |
1431 { | |
1432 // adjust the code, to cope with the missing chroma entries | |
1433 WRITE_UVLC( ((Int)listId - (Int)scalingList->getRefMatrixId (sizeId,listId)) / (SCALING_LIST_NUM/NUMBER_OF_PREDICTION_MODES), "scaling_list_pred_matrix_id_delta"); | |
1434 } | |
1435 else | |
1436 { | |
1437 WRITE_UVLC( (Int)listId - (Int)scalingList->getRefMatrixId (sizeId,listId), "scaling_list_pred_matrix_id_delta"); | |
1438 } | |
1439 } | |
1440 else// DPCM Mode | |
1441 { | |
1442 xCodeScalingList(scalingList, sizeId, listId); | |
1443 } | |
1444 } | |
1445 } | |
1446 return; | |
1447 } | |
1448 /** code DPCM | |
1449 * \param scalingList quantization matrix information | |
1450 * \param sizeIdc size index | |
1451 * \param listIdc list index | |
1452 */ | |
1453 Void TEncCavlc::xCodeScalingList(TComScalingList* scalingList, UInt sizeId, UInt listId) | |
1454 { | |
1455 Int coefNum = min(MAX_MATRIX_COEF_NUM,(Int)g_scalingListSize[sizeId]); | |
1456 UInt* scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][sizeId==0 ? 2 : 3][sizeId==0 ? 2 : 3]; | |
1457 Int nextCoef = SCALING_LIST_START_VALUE; | |
1458 Int data; | |
1459 Int *src = scalingList->getScalingListAddress(sizeId, listId); | |
1460 if( sizeId > SCALING_LIST_8x8 ) | |
1461 { | |
1462 WRITE_SVLC( scalingList->getScalingListDC(sizeId,listId) - 8, "scaling_list_dc_coef_minus8"); | |
1463 nextCoef = scalingList->getScalingListDC(sizeId,listId); | |
1464 } | |
1465 for(Int i=0;i<coefNum;i++) | |
1466 { | |
1467 data = src[scan[i]] - nextCoef; | |
1468 nextCoef = src[scan[i]]; | |
1469 if(data > 127) | |
1470 { | |
1471 data = data - 256; | |
1472 } | |
1473 if(data < -128) | |
1474 { | |
1475 data = data + 256; | |
1476 } | |
1477 | |
1478 WRITE_SVLC( data, "scaling_list_delta_coef"); | |
1479 } | |
1480 } | |
1481 Bool TEncCavlc::findMatchingLTRP ( TComSlice* pcSlice, UInt *ltrpsIndex, Int ltrpPOC, Bool usedFlag ) | |
1482 { | |
1483 // Bool state = true, state2 = false; | |
1484 Int lsb = ltrpPOC & ((1<<pcSlice->getSPS()->getBitsForPOC())-1); | |
1485 for (Int k = 0; k < pcSlice->getSPS()->getNumLongTermRefPicSPS(); k++) | |
1486 { | |
1487 if ( (lsb == pcSlice->getSPS()->getLtRefPicPocLsbSps(k)) && (usedFlag == pcSlice->getSPS()->getUsedByCurrPicLtSPSFlag(k)) ) | |
1488 { | |
1489 *ltrpsIndex = k; | |
1490 return true; | |
1491 } | |
1492 } | |
1493 return false; | |
1494 } | |
1495 Bool TComScalingList::checkPredMode(UInt sizeId, UInt listId) | |
1496 { | |
1497 Int predListStep = (sizeId == SCALING_LIST_32x32? (SCALING_LIST_NUM/NUMBER_OF_PREDICTION_MODES) : 1); // if 32x32, skip over chroma entries. | |
1498 | |
1499 for(Int predListIdx = (Int)listId ; predListIdx >= 0; predListIdx-=predListStep) | |
1500 { | |
1501 if( !memcmp(getScalingListAddress(sizeId,listId),((listId == predListIdx) ? | |
1502 getScalingListDefaultAddress(sizeId, predListIdx): getScalingListAddress(sizeId, predListIdx)),sizeof(Int)*min(MAX_MATRIX_COEF_NUM,(Int)g_scalingListSize[sizeId])) // check value of matrix | |
1503 && ((sizeId < SCALING_LIST_16x16) || (getScalingListDC(sizeId,listId) == getScalingListDC(sizeId,predListIdx)))) // check DC value | |
1504 { | |
1505 setRefMatrixId(sizeId, listId, predListIdx); | |
1506 return false; | |
1507 } | |
1508 } | |
1509 return true; | |
1510 } | |
1511 | |
1512 Void TEncCavlc::codeExplicitRdpcmMode( TComTU &rTu, const ComponentID compID ) | |
1513 { | |
1514 assert(0); | |
1515 } | |
1516 | |
1517 //! \} |