/src/vvenc/source/Lib/EncoderLib/VLCWriter.cpp
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | |
43 | | |
44 | | /** \file VLCWriter.cpp |
45 | | * \brief Writer for high level syntax |
46 | | */ |
47 | | |
48 | | #include "VLCWriter.h" |
49 | | #include "SEIwrite.h" |
50 | | #include "CommonLib/CommonDef.h" |
51 | | #include "CommonLib/Unit.h" |
52 | | #include "CommonLib/Picture.h" // th remove this |
53 | | #include "CommonLib/dtrace_next.h" |
54 | | |
55 | | //! \ingroup EncoderLib |
56 | | //! \{ |
57 | | |
58 | | namespace vvenc { |
59 | | |
60 | | #if ENABLE_TRACING |
61 | | |
62 | | void VLCWriter::xWriteSCodeTr (int value, uint32_t length, const char *pSymbolName) |
63 | | { |
64 | | xWriteSCode (value,length); |
65 | | if( g_HLSTraceEnable ) |
66 | | { |
67 | | if( length<10 ) |
68 | | { |
69 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value ); |
70 | | } |
71 | | else |
72 | | { |
73 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value ); |
74 | | } |
75 | | } |
76 | | } |
77 | | |
78 | | void VLCWriter::xWriteCodeTr (uint32_t value, uint32_t length, const char *pSymbolName) |
79 | | { |
80 | | xWriteCode (value,length); |
81 | | |
82 | | if( g_HLSTraceEnable ) |
83 | | { |
84 | | if( length < 10 ) |
85 | | { |
86 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value ); |
87 | | } |
88 | | else |
89 | | { |
90 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value ); |
91 | | } |
92 | | } |
93 | | } |
94 | | |
95 | | void VLCWriter::xWriteUvlcTr (uint32_t value, const char *pSymbolName) |
96 | | { |
97 | | xWriteUvlc (value); |
98 | | if( g_HLSTraceEnable ) |
99 | | { |
100 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %d\n", pSymbolName, value ); |
101 | | } |
102 | | } |
103 | | |
104 | | void VLCWriter::xWriteSvlcTr (int value, const char *pSymbolName) |
105 | | { |
106 | | xWriteSvlc(value); |
107 | | if( g_HLSTraceEnable ) |
108 | | { |
109 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, value ); |
110 | | } |
111 | | } |
112 | | |
113 | | void VLCWriter::xWriteFlagTr(bool flag, const char *pSymbolName) |
114 | | { |
115 | | xWriteFlag(flag); |
116 | | if( g_HLSTraceEnable ) |
117 | | { |
118 | | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", pSymbolName, flag?1:0 ); |
119 | | } |
120 | | } |
121 | | |
122 | | bool g_HLSTraceEnable = true; |
123 | | |
124 | | #endif |
125 | | |
126 | | void VLCWriter::xWriteSCode ( int code, uint32_t length ) |
127 | 0 | { |
128 | 0 | assert ( length > 0 && length<=32 ); |
129 | 0 | assert( length==32 || (code>=-(1<<(length-1)) && code<(1<<(length-1))) ); |
130 | 0 | m_pcBitIf->write( length==32 ? uint32_t(code) : ( uint32_t(code)&((1<<length)-1) ), length ); |
131 | 0 | } |
132 | | |
133 | | void VLCWriter::xWriteCode ( uint32_t uiCode, uint32_t uiLength ) |
134 | 0 | { |
135 | 0 | CHECK( uiLength == 0, "Code of length '0' not supported" ); |
136 | 0 | m_pcBitIf->write( uiCode, uiLength ); |
137 | 0 | } |
138 | | |
139 | | void VLCWriter::xWriteUvlc ( uint32_t uiCode ) |
140 | 0 | { |
141 | 0 | uint32_t uiLength = 1; |
142 | 0 | uint32_t uiTemp = ++uiCode; |
143 | |
|
144 | 0 | CHECK( !uiTemp, "Integer overflow" ); |
145 | |
|
146 | 0 | while( 1 != uiTemp ) |
147 | 0 | { |
148 | 0 | uiTemp >>= 1; |
149 | 0 | uiLength += 2; |
150 | 0 | } |
151 | | // Take care of cases where uiLength > 32 |
152 | 0 | m_pcBitIf->write( 0, uiLength >> 1); |
153 | 0 | m_pcBitIf->write( uiCode, (uiLength+1) >> 1); |
154 | 0 | } |
155 | | |
156 | | void VLCWriter::xWriteSvlc ( int iCode ) |
157 | 0 | { |
158 | 0 | uint32_t uiCode = uint32_t( iCode <= 0 ? (-iCode)<<1 : (iCode<<1)-1); |
159 | 0 | xWriteUvlc( uiCode ); |
160 | 0 | } |
161 | | |
162 | | void VLCWriter::xWriteFlag( bool flag ) |
163 | 0 | { |
164 | 0 | m_pcBitIf->write( flag?1:0, 1 ); |
165 | 0 | } |
166 | | |
167 | | void VLCWriter::xWriteRbspTrailingBits() |
168 | 0 | { |
169 | 0 | WRITE_FLAG( 1, "rbsp_stop_one_bit"); |
170 | 0 | int cnt = 0; |
171 | 0 | while (m_pcBitIf->getNumBitsUntilByteAligned()) |
172 | 0 | { |
173 | 0 | WRITE_FLAG( 0, "rbsp_alignment_zero_bit"); |
174 | 0 | cnt++; |
175 | 0 | } |
176 | 0 | CHECK(cnt>=8, "More than '8' alignment bytes read"); |
177 | 0 | } |
178 | | |
179 | | void HLSWriter::codeAUD(const int audIrapOrGdrAuFlag, const int pictureType) |
180 | 0 | { |
181 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Access Unit Delimiter ===========\n" ); |
182 | |
|
183 | 0 | CHECK(pictureType >= 3, "Invalid picture type"); |
184 | 0 | WRITE_FLAG(audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag"); |
185 | 0 | WRITE_CODE(pictureType, 3, "pic_type"); |
186 | 0 | xWriteRbspTrailingBits(); |
187 | 0 | } |
188 | | |
189 | | void HLSWriter::xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount, const bool isForbiddenZeroDeltaPoc, int rplIdx ) |
190 | 0 | { |
191 | 0 | uint32_t numRefPic = rpl->numberOfShorttermPictures + rpl->numberOfLongtermPictures + rpl->numberOfInterLayerPictures; |
192 | 0 | WRITE_UVLC(numRefPic, "num_ref_entries[ listIdx ][ rplsIdx ]"); |
193 | |
|
194 | 0 | if (isLongTermPresent && numRefPic > 0 && rplIdx != -1) |
195 | 0 | { |
196 | 0 | WRITE_FLAG(rpl->ltrpInSliceHeader, "ltrp_in_slice_header_flag[ listIdx ][ rplsIdx ]"); |
197 | 0 | } |
198 | 0 | int prevDelta = MAX_INT; |
199 | 0 | int deltaValue = 0; |
200 | 0 | bool firstSTRP = true; |
201 | 0 | for (int ii = 0; ii < numRefPic; ii++) |
202 | 0 | { |
203 | 0 | if( rpl->interLayerPresent ) |
204 | 0 | { |
205 | 0 | WRITE_FLAG( rpl->isInterLayerRefPic[ii], "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" ); |
206 | |
|
207 | 0 | if( rpl->isInterLayerRefPic[ii] ) |
208 | 0 | { |
209 | 0 | CHECK( rpl->interLayerRefPicIdx[ii] < 0, "Wrong inter-layer reference index" ); |
210 | 0 | WRITE_UVLC( rpl->interLayerRefPicIdx[ii], "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" ); |
211 | 0 | } |
212 | 0 | } |
213 | | |
214 | 0 | if( !rpl->isInterLayerRefPic[ii] ) |
215 | 0 | { |
216 | 0 | if (isLongTermPresent) |
217 | 0 | { |
218 | 0 | WRITE_FLAG(!rpl->isLongtermRefPic[ii], "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]"); |
219 | 0 | } |
220 | 0 | if (!rpl->isLongtermRefPic[ii]) |
221 | 0 | { |
222 | 0 | if (firstSTRP) |
223 | 0 | { |
224 | 0 | firstSTRP = false; |
225 | 0 | deltaValue = prevDelta = rpl->refPicIdentifier[ii]; |
226 | 0 | } |
227 | 0 | else |
228 | 0 | { |
229 | 0 | deltaValue = rpl->refPicIdentifier[ii] - prevDelta; |
230 | 0 | prevDelta = rpl->refPicIdentifier[ii]; |
231 | 0 | } |
232 | 0 | unsigned int absDeltaValue = (deltaValue < 0) ? 0 - deltaValue : deltaValue; |
233 | 0 | if( isForbiddenZeroDeltaPoc || ii == 0 ) |
234 | 0 | { |
235 | 0 | CHECK( !absDeltaValue, "Zero delta POC is not used without WP" ); |
236 | 0 | WRITE_UVLC( absDeltaValue - 1, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]" ); |
237 | 0 | } |
238 | 0 | else |
239 | 0 | WRITE_UVLC(absDeltaValue, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]"); |
240 | 0 | if (absDeltaValue > 0) |
241 | 0 | { |
242 | 0 | WRITE_FLAG((deltaValue < 0), "strp_entry_sign_flag[ listIdx ][ rplsIdx ][ i ]"); //0 means negative delta POC : 1 means positive |
243 | 0 | } |
244 | 0 | } |
245 | 0 | else if (!rpl->ltrpInSliceHeader) |
246 | 0 | { |
247 | 0 | WRITE_CODE(rpl->refPicIdentifier[ii], ltLsbBitsCount, "poc_lsb_lt[listIdx][rplsIdx][i]"); |
248 | 0 | } |
249 | 0 | } |
250 | 0 | } |
251 | 0 | } |
252 | | |
253 | | void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS ) |
254 | 0 | { |
255 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set ===========\n" ); |
256 | |
|
257 | 0 | WRITE_CODE( pcPPS->ppsId, 6, "pps_pic_parameter_set_id" ); |
258 | 0 | WRITE_CODE( pcPPS->spsId, 4, "pps_seq_parameter_set_id" ); |
259 | |
|
260 | 0 | WRITE_FLAG( pcPPS->mixedNaluTypesInPic, "pps_mixed_nalu_types_in_pic_flag" ); |
261 | |
|
262 | 0 | WRITE_UVLC( pcPPS->picWidthInLumaSamples, "pic_width_in_luma_samples" ); |
263 | 0 | WRITE_UVLC( pcPPS->picHeightInLumaSamples, "pic_height_in_luma_samples" ); |
264 | |
|
265 | 0 | if( pcPPS->picWidthInLumaSamples == pcSPS->maxPicWidthInLumaSamples && pcPPS->picHeightInLumaSamples == pcSPS->maxPicHeightInLumaSamples ) |
266 | 0 | { |
267 | 0 | WRITE_FLAG( 0, "pps_conformance_window_flag" ); |
268 | 0 | } |
269 | 0 | else |
270 | 0 | { |
271 | 0 | const Window& conf = pcPPS->conformanceWindow; |
272 | 0 | WRITE_FLAG( conf.enabledFlag, "pps_conformance_window_flag" ); |
273 | 0 | if( conf.enabledFlag ) |
274 | 0 | { |
275 | 0 | WRITE_UVLC( conf.winLeftOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "conf_win_left_offset" ); |
276 | 0 | WRITE_UVLC( conf.winRightOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "conf_win_right_offset" ); |
277 | 0 | WRITE_UVLC( conf.winTopOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "conf_win_top_offset" ); |
278 | 0 | WRITE_UVLC( conf.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "conf_win_bottom_offset" ); |
279 | 0 | } |
280 | 0 | } |
281 | |
|
282 | 0 | const Window& scWnd = pcPPS->scalingWindow; |
283 | 0 | WRITE_FLAG( scWnd.enabledFlag, "pps_scaling_window_flag" ); |
284 | 0 | if( scWnd.enabledFlag ) |
285 | 0 | { |
286 | 0 | WRITE_UVLC( scWnd.winLeftOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "pps_scaling_win_left_offset" ); |
287 | 0 | WRITE_UVLC( scWnd.winRightOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "pps_scaling_win_right_offset" ); |
288 | 0 | WRITE_UVLC( scWnd.winTopOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "pps_scaling_win_top_offset" ); |
289 | 0 | WRITE_UVLC( scWnd.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "pps_scaling_win_bottom_offset" ); |
290 | 0 | } |
291 | |
|
292 | 0 | WRITE_FLAG( pcPPS->outputFlagPresent, "pps_output_flag_present_flag" ); |
293 | 0 | WRITE_FLAG( pcPPS->noPicPartition, "pps_no_pic_partition_flag" ); |
294 | 0 | WRITE_FLAG( pcPPS->subPicIdMappingInPps, "pps_subpic_id_mapping_in_pps_flag" ); |
295 | 0 | if( pcPPS->subPicIdMappingInPps ) |
296 | 0 | { |
297 | 0 | if( pcPPS->noPicPartition ) |
298 | 0 | { |
299 | 0 | WRITE_UVLC( pcPPS->numSubPics - 1, "pps_num_subpics_minus1" ); |
300 | 0 | } |
301 | 0 | WRITE_UVLC( pcPPS->subPicIdLen - 1, "pps_subpic_id_len_minus1" ); |
302 | |
|
303 | 0 | CHECK((1 << pcPPS->subPicIdLen) < pcPPS->numSubPics, "pps_subpic_id_len exceeds valid range"); |
304 | 0 | for( int picIdx = 0; picIdx < pcPPS->numSubPics; picIdx++ ) |
305 | 0 | { |
306 | 0 | WRITE_CODE( pcPPS->subPicId[picIdx], pcPPS->subPicIdLen, "pps_subpic_id[i]" ); |
307 | 0 | } |
308 | 0 | } |
309 | | |
310 | 0 | if( !pcPPS->noPicPartition ) |
311 | 0 | { |
312 | 0 | WRITE_CODE( pcPPS->log2CtuSize - 5, 2, "pps_log2_ctu_size_minus5" ); |
313 | 0 | WRITE_UVLC( pcPPS->numExpTileCols - 1, "pps_num_exp_tile_columns_minus1" ); |
314 | 0 | WRITE_UVLC( pcPPS->numExpTileRows - 1, "pps_num_exp_tile_rows_minus1" ); |
315 | |
|
316 | 0 | for( int colIdx = 0; colIdx < pcPPS->numExpTileCols; colIdx++ ) |
317 | 0 | { |
318 | 0 | WRITE_UVLC( pcPPS->tileColWidth[ colIdx ] - 1, "pps_tile_column_width_minus1[i]" ); |
319 | 0 | } |
320 | 0 | for( int rowIdx = 0; rowIdx < pcPPS->numExpTileRows; rowIdx++ ) |
321 | 0 | { |
322 | 0 | WRITE_UVLC( pcPPS->tileRowHeight[ rowIdx ] - 1, "pps_tile_row_height_minus1[i]" ); |
323 | 0 | } |
324 | |
|
325 | 0 | if( pcPPS->numTileCols * pcPPS->numTileRows > 1 ) |
326 | 0 | { |
327 | 0 | WRITE_FLAG( pcPPS->loopFilterAcrossTilesEnabled, "pps_loop_filter_across_tiles_enabled_flag" ); |
328 | 0 | WRITE_FLAG( pcPPS->rectSlice ? 1 : 0, "pps_rect_slice_flag" ); |
329 | 0 | } |
330 | 0 | if( pcPPS->rectSlice ) |
331 | 0 | { |
332 | 0 | WRITE_FLAG( pcPPS->singleSlicePerSubPic ? 1 : 0, "pps_single_slice_per_subpic_flag" ); |
333 | 0 | } |
334 | 0 | if( pcPPS->rectSlice & !pcPPS->singleSlicePerSubPic ) |
335 | 0 | { |
336 | 0 | CHECK( pcPPS->numSlicesInPic > 1, "currently only one slice supported" ); |
337 | 0 | WRITE_UVLC( pcPPS->numSlicesInPic - 1, "pps_num_slices_in_pic_minus1" ); |
338 | 0 | } |
339 | | |
340 | 0 | if( pcPPS->rectSlice == 0 || pcPPS->singleSlicePerSubPic || pcPPS->numSlicesInPic > 1 ) |
341 | 0 | { |
342 | 0 | WRITE_FLAG( pcPPS->loopFilterAcrossSlicesEnabled, "pps_loop_filter_across_slices_enabled_flag" ); |
343 | 0 | } |
344 | 0 | } |
345 | | |
346 | 0 | WRITE_FLAG( pcPPS->cabacInitPresent, "pps_cabac_init_present_flag" ); |
347 | 0 | WRITE_UVLC( pcPPS->numRefIdxL0DefaultActive-1, "pps_num_ref_idx_l0_default_active_minus1"); |
348 | 0 | WRITE_UVLC( pcPPS->numRefIdxL1DefaultActive-1, "pps_num_ref_idx_l1_default_active_minus1"); |
349 | 0 | WRITE_FLAG( pcPPS->rpl1IdxPresent, "pps_rpl1_idx_present_flag"); |
350 | |
|
351 | 0 | WRITE_FLAG( pcPPS->weightPred, "pps_weighted_pred_flag" ); // Use of Weighting Prediction (P_SLICE) |
352 | 0 | WRITE_FLAG( pcPPS->weightedBiPred, "pps_weighted_bipred_flag" ); // Use of Weighting Bi-Prediction (B_SLICE) |
353 | 0 | WRITE_FLAG( pcPPS->wrapAroundEnabled, "pps_ref_wraparound_enabled_flag" ); |
354 | 0 | if( pcPPS->wrapAroundEnabled ) |
355 | 0 | { |
356 | 0 | WRITE_UVLC(pcPPS->picWidthMinusWrapAroundOffset, "pps_pic_width_minus_wraparound_offset"); |
357 | 0 | } |
358 | |
|
359 | 0 | WRITE_SVLC( pcPPS->picInitQPMinus26, "pps_init_qp_minus26"); |
360 | 0 | WRITE_FLAG( pcPPS->useDQP, "pps_cu_qp_delta_enabled_flag" ); |
361 | 0 | WRITE_FLAG (pcPPS->usePPSChromaTool, "pps_chroma_tool_offsets_present_flag"); |
362 | 0 | if (pcPPS->usePPSChromaTool) |
363 | 0 | { |
364 | 0 | WRITE_SVLC( pcPPS->chromaQpOffset[COMP_Cb], "pps_cb_qp_offset" ); |
365 | 0 | WRITE_SVLC( pcPPS->chromaQpOffset[COMP_Cr], "pps_cr_qp_offset" ); |
366 | 0 | WRITE_FLAG( pcPPS->jointCbCrQpOffsetPresent, "pps_joint_cbcr_qp_offset_present_flag"); |
367 | 0 | if (pcPPS->jointCbCrQpOffsetPresent) |
368 | 0 | { |
369 | 0 | WRITE_SVLC(pcPPS->chromaQpOffset[COMP_JOINT_CbCr],"pps_joint_cbcr_qp_offset_value"); |
370 | 0 | } |
371 | |
|
372 | 0 | WRITE_FLAG( pcPPS->sliceChromaQpFlag, "pps_slice_chroma_qp_offsets_present_flag" ); |
373 | |
|
374 | 0 | bool cuChromaQpOffsetEnabled = pcPPS->chromaQpOffsetListLen>0; |
375 | 0 | WRITE_FLAG(cuChromaQpOffsetEnabled, "pps_cu_chroma_qp_offset_list_enabled_flag" ); |
376 | 0 | if( cuChromaQpOffsetEnabled ) |
377 | 0 | { |
378 | 0 | WRITE_UVLC(pcPPS->chromaQpOffsetListLen - 1, "pps_chroma_qp_offset_list_len_minus1"); |
379 | | /* skip zero index */ |
380 | 0 | for (int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx < pcPPS->chromaQpOffsetListLen; cuChromaQpOffsetIdx++) |
381 | 0 | { |
382 | 0 | WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CbOffset, "pps_cb_qp_offset_list[i]"); |
383 | 0 | WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CrOffset, "pps_cr_qp_offset_list[i]"); |
384 | 0 | if (pcPPS->jointCbCrQpOffsetPresent) |
385 | 0 | { |
386 | 0 | WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1).u.comp.JointCbCrOffset, "pps_joint_cbcr_qp_offset_list[i]"); |
387 | 0 | } |
388 | 0 | } |
389 | 0 | } |
390 | 0 | } |
391 | 0 | WRITE_FLAG( pcPPS->deblockingFilterControlPresent, "pps_deblocking_filter_control_present_flag"); |
392 | 0 | if(pcPPS->deblockingFilterControlPresent) |
393 | 0 | { |
394 | 0 | WRITE_FLAG( pcPPS->deblockingFilterOverrideEnabled, "pps_deblocking_filter_override_enabled_flag" ); |
395 | 0 | WRITE_FLAG( pcPPS->deblockingFilterDisabled, "pps_deblocking_filter_disabled_flag" ); |
396 | 0 | if (!pcPPS->noPicPartition && pcPPS->deblockingFilterOverrideEnabled) |
397 | 0 | { |
398 | 0 | WRITE_FLAG(pcPPS->dbfInfoInPh, "pps_dbf_info_in_ph_flag"); |
399 | 0 | } |
400 | |
|
401 | 0 | if(!pcPPS->deblockingFilterDisabled ) |
402 | 0 | { |
403 | 0 | WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Y], "pps_beta_offset_div2" ); |
404 | 0 | WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Y], "pps_tc_offset_div2" ); |
405 | 0 | if( pcPPS->usePPSChromaTool ) |
406 | 0 | { |
407 | 0 | WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Cb], "pps_cb_beta_offset_div2" ); |
408 | 0 | WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Cb], "pps_cb_tc_offset_div2" ); |
409 | 0 | WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Cr], "pps_cr_beta_offset_div2" ); |
410 | 0 | WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Cr], "pps_cr_tc_offset_div2" ); |
411 | 0 | } |
412 | 0 | } |
413 | 0 | } |
414 | 0 | if ( !pcPPS->noPicPartition ) |
415 | 0 | { |
416 | 0 | WRITE_FLAG(pcPPS->rplInfoInPh, "pps_rpl_info_in_ph_flag"); |
417 | 0 | WRITE_FLAG(pcPPS->saoInfoInPh, "pps_sao_info_in_ph_flag"); |
418 | 0 | WRITE_FLAG(pcPPS->alfInfoInPh, "pps_alf_info_in_ph_flag"); |
419 | 0 | if( (pcPPS->weightPred || pcPPS->weightedBiPred) && pcPPS->rplInfoInPh) |
420 | 0 | { |
421 | 0 | WRITE_FLAG(pcPPS->wpInfoInPh, "pps_wp_info_in_ph_flag"); |
422 | 0 | } |
423 | 0 | WRITE_FLAG(pcPPS->qpDeltaInfoInPh, "pps_qp_delta_info_in_ph_flag"); |
424 | 0 | } |
425 | |
|
426 | 0 | WRITE_FLAG( pcPPS->pictureHeaderExtensionPresent, "pps_picture_header_extension_present_flag"); |
427 | 0 | WRITE_FLAG( pcPPS->sliceHeaderExtensionPresent, "pps_slice_header_extension_present_flag"); |
428 | |
|
429 | 0 | WRITE_FLAG( false, "pps_extension_present_flag" ); |
430 | |
|
431 | 0 | xWriteRbspTrailingBits(); |
432 | 0 | } |
433 | | |
434 | | void HLSWriter::codeAPS( const APS* pcAPS ) |
435 | 0 | { |
436 | 0 | DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set ===========\n"); |
437 | |
|
438 | 0 | WRITE_CODE(pcAPS->apsType, 3, "aps_params_type"); |
439 | 0 | WRITE_CODE(pcAPS->apsId, 5, "adaptation_parameter_set_id"); |
440 | 0 | WRITE_FLAG(pcAPS->chromaPresent, "aps_chroma_present_flag"); |
441 | |
|
442 | 0 | if (pcAPS->apsType == ALF_APS) |
443 | 0 | { |
444 | 0 | codeAlfAps(pcAPS); |
445 | 0 | } |
446 | 0 | else if (pcAPS->apsType == LMCS_APS) |
447 | 0 | { |
448 | 0 | codeLmcsAps (pcAPS ); |
449 | 0 | } |
450 | 0 | else if( pcAPS->apsType == SCALING_LIST_APS ) |
451 | 0 | { |
452 | 0 | THROW("no support"); |
453 | 0 | } |
454 | 0 | else |
455 | 0 | { |
456 | 0 | THROW("invalid APS Type"); |
457 | 0 | } |
458 | 0 | WRITE_FLAG(0, "aps_extension_flag"); |
459 | 0 | xWriteRbspTrailingBits(); |
460 | 0 | } |
461 | | |
462 | | void HLSWriter::codeAlfAps( const APS* pcAPS ) |
463 | 0 | { |
464 | 0 | const AlfParam& param = pcAPS->alfParam; |
465 | |
|
466 | 0 | WRITE_FLAG(param.newFilterFlag[CH_L], "alf_luma_new_filter"); |
467 | 0 | const CcAlfFilterParam& paramCcAlf = pcAPS->ccAlfParam; |
468 | 0 | if (pcAPS->chromaPresent) |
469 | 0 | { |
470 | 0 | WRITE_FLAG(param.newFilterFlag[CH_C], "alf_chroma_new_filter"); |
471 | 0 | WRITE_FLAG(paramCcAlf.newCcAlfFilter[COMP_Cb - 1], "alf_cc_cb_filter_signal_flag"); |
472 | 0 | WRITE_FLAG(paramCcAlf.newCcAlfFilter[COMP_Cr - 1], "alf_cc_cr_filter_signal_flag"); |
473 | 0 | } |
474 | |
|
475 | 0 | if (param.newFilterFlag[CH_L]) |
476 | 0 | { |
477 | 0 | WRITE_FLAG( param.nonLinearFlag[CH_L], "alf_luma_clip" ); |
478 | |
|
479 | 0 | WRITE_UVLC(param.numLumaFilters - 1, "alf_luma_num_filters_signalled_minus1"); |
480 | 0 | if (param.numLumaFilters > 1) |
481 | 0 | { |
482 | 0 | const int len = ceilLog2( param.numLumaFilters); |
483 | 0 | for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++) |
484 | 0 | { |
485 | 0 | WRITE_CODE(param.filterCoeffDeltaIdx[i], len, "alf_luma_coeff_delta_idx" ); |
486 | 0 | } |
487 | 0 | } |
488 | 0 | alfFilter(param, false, 0); |
489 | 0 | } |
490 | |
|
491 | 0 | if (param.newFilterFlag[CH_C]) |
492 | 0 | { |
493 | 0 | WRITE_FLAG(param.nonLinearFlag[CH_C], "alf_nonlinear_enable_flag_chroma"); |
494 | 0 | if( VVENC_MAX_NUM_ALF_ALTERNATIVES_CHROMA > 1 ) |
495 | 0 | { |
496 | 0 | WRITE_UVLC( param.numAlternativesChroma - 1, "alf_chroma_num_alts_minus1" ); |
497 | 0 | } |
498 | 0 | for( int altIdx=0; altIdx < param.numAlternativesChroma; ++altIdx ) |
499 | 0 | { |
500 | 0 | alfFilter(param, true, altIdx); |
501 | 0 | } |
502 | 0 | } |
503 | |
|
504 | 0 | for (int ccIdx = 0; ccIdx < 2; ccIdx++) |
505 | 0 | { |
506 | 0 | if (paramCcAlf.newCcAlfFilter[ccIdx]) |
507 | 0 | { |
508 | 0 | const int filterCount = paramCcAlf.ccAlfFilterCount[ccIdx]; |
509 | 0 | CHECK(filterCount > MAX_NUM_CC_ALF_FILTERS, "CC ALF Filter count is too large"); |
510 | 0 | CHECK(filterCount == 0, "CC ALF Filter count is too small"); |
511 | |
|
512 | 0 | WRITE_UVLC(filterCount - 1, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1"); |
513 | |
|
514 | 0 | for (int filterIdx = 0; filterIdx < filterCount; filterIdx++) |
515 | 0 | { |
516 | 0 | AlfFilterShape alfShape(size_CC_ALF); |
517 | |
|
518 | 0 | const short *coeff = paramCcAlf.ccAlfCoeff[ccIdx][filterIdx]; |
519 | | // Filter coefficients |
520 | 0 | for (int i = 0; i < alfShape.numCoeff - 1; i++) |
521 | 0 | { |
522 | 0 | if (coeff[i] == 0) |
523 | 0 | { |
524 | 0 | WRITE_CODE(0, CCALF_BITS_PER_COEFF_LEVEL, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs"); |
525 | 0 | } |
526 | 0 | else |
527 | 0 | { |
528 | 0 | WRITE_CODE(1 + floorLog2(abs(coeff[i])), CCALF_BITS_PER_COEFF_LEVEL, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs"); |
529 | 0 | WRITE_FLAG(coeff[i] < 0 ? 1 : 0, ccIdx == 0 ? "alf_cc_cb_coeff_sign" : "alf_cc_cr_coeff_sign"); |
530 | 0 | } |
531 | 0 | } |
532 | |
|
533 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "%s coeff filterIdx %d: ", ccIdx == 0 ? "Cb" : "Cr", filterIdx); |
534 | 0 | for (int i = 0; i < alfShape.numCoeff; i++) |
535 | 0 | { |
536 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "%d ", coeff[i]); |
537 | 0 | } |
538 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "\n"); |
539 | 0 | } |
540 | 0 | } |
541 | 0 | } |
542 | 0 | } |
543 | | |
544 | | void HLSWriter::codeLmcsAps( const APS* aps ) |
545 | 0 | { |
546 | 0 | const LmcsParam& param = aps->lmcsParam; |
547 | 0 | WRITE_UVLC(param.reshaperModelMinBinIdx, "lmcs_min_bin_idx"); |
548 | 0 | WRITE_UVLC(PIC_CODE_CW_BINS - 1 - param.reshaperModelMaxBinIdx, "lmcs_delta_max_bin_idx"); |
549 | 0 | assert(param.maxNbitsNeededDeltaCW > 0); |
550 | 0 | WRITE_UVLC(param.maxNbitsNeededDeltaCW - 1, "lmcs_delta_cw_prec_minus1"); |
551 | |
|
552 | 0 | for (int i = param.reshaperModelMinBinIdx; i <= param.reshaperModelMaxBinIdx; i++) |
553 | 0 | { |
554 | 0 | int deltaCW = param.reshaperModelBinCWDelta[i]; |
555 | 0 | int signCW = (deltaCW < 0) ? 1 : 0; |
556 | 0 | int absCW = (deltaCW < 0) ? (-deltaCW) : deltaCW; |
557 | 0 | WRITE_CODE(absCW, param.maxNbitsNeededDeltaCW, "lmcs_delta_abs_cw[ i ]"); |
558 | 0 | if (absCW > 0) |
559 | 0 | { |
560 | 0 | WRITE_FLAG(signCW, "lmcs_delta_sign_cw_flag[ i ]"); |
561 | 0 | } |
562 | 0 | } |
563 | 0 | int deltaCRS = aps->chromaPresent ? param.chrResScalingOffset : 0; |
564 | 0 | int signCRS = (deltaCRS < 0) ? 1 : 0; |
565 | 0 | int absCRS = (deltaCRS < 0) ? (-deltaCRS) : deltaCRS; |
566 | 0 | if (aps->chromaPresent) |
567 | 0 | { |
568 | 0 | WRITE_CODE(absCRS, 3, "lmcs_delta_abs_crs"); |
569 | 0 | } |
570 | 0 | if (absCRS > 0) |
571 | 0 | { |
572 | 0 | WRITE_FLAG(signCRS, "lmcs_delta_sign_crs_val_flag"); |
573 | 0 | } |
574 | 0 | } |
575 | | |
576 | | void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS ) |
577 | 0 | { |
578 | | #if ENABLE_TRACING |
579 | | DTRACE( g_trace_ctx, D_HEADER, "----------- vui_parameters -----------\n"); |
580 | | #endif |
581 | |
|
582 | 0 | WRITE_FLAG(pcVUI->progressiveSourceFlag, "vui_general_progressive_source_flag" ); |
583 | 0 | WRITE_FLAG(pcVUI->interlacedSourceFlag, "vui_general_interlaced_source_flag" ); |
584 | 0 | WRITE_FLAG(pcVUI->nonPackedFlag, "vui_non_packed_constraint_flag"); |
585 | 0 | WRITE_FLAG(pcVUI->nonProjectedFlag, "vui_non_projected_constraint_flag"); |
586 | 0 | WRITE_FLAG(pcVUI->aspectRatioInfoPresent, "aspect_ratio_info_present_flag"); |
587 | 0 | if (pcVUI->aspectRatioInfoPresent) |
588 | 0 | { |
589 | 0 | WRITE_FLAG(pcVUI->aspectRatioConstantFlag, "vui_aspect_ratio_constant_flag"); |
590 | 0 | WRITE_CODE(pcVUI->aspectRatioIdc, 8, "aspect_ratio_idc" ); |
591 | 0 | if (pcVUI->aspectRatioIdc == 255) |
592 | 0 | { |
593 | 0 | WRITE_CODE(pcVUI->sarWidth, 16, "sar_width"); |
594 | 0 | WRITE_CODE(pcVUI->sarHeight, 16, "sar_height"); |
595 | 0 | } |
596 | 0 | } |
597 | 0 | WRITE_FLAG(pcVUI->overscanInfoPresent, "vui_overscan_info_present_flag"); |
598 | 0 | if (pcVUI->overscanInfoPresent) |
599 | 0 | { |
600 | 0 | WRITE_FLAG(pcVUI->overscanAppropriateFlag, "vui_overscan_appropriate_flag"); |
601 | 0 | } |
602 | 0 | WRITE_FLAG(pcVUI->colourDescriptionPresent, "colour_description_present_flag"); |
603 | 0 | if (pcVUI->colourDescriptionPresent) |
604 | 0 | { |
605 | 0 | WRITE_CODE(pcVUI->colourPrimaries, 8, "colour_primaries"); |
606 | 0 | WRITE_CODE(pcVUI->transferCharacteristics, 8, "transfer_characteristics"); |
607 | 0 | WRITE_CODE(pcVUI->matrixCoefficients, 8, "matrix_coeffs"); |
608 | 0 | WRITE_FLAG(pcVUI->videoFullRangeFlag, "vui_video_full_range_flag"); |
609 | 0 | } |
610 | 0 | WRITE_FLAG(pcVUI->chromaLocInfoPresent, "chroma_loc_info_present_flag"); |
611 | 0 | if (pcVUI->chromaLocInfoPresent) |
612 | 0 | { |
613 | 0 | if(pcVUI->progressiveSourceFlag && !pcVUI->interlacedSourceFlag) |
614 | 0 | { |
615 | 0 | WRITE_UVLC(pcVUI->chromaSampleLocType, "chroma_sample_loc_type"); |
616 | 0 | } |
617 | 0 | else |
618 | 0 | { |
619 | 0 | WRITE_UVLC(pcVUI->chromaSampleLocTypeTopField, "chroma_sample_loc_type_top_field"); |
620 | 0 | WRITE_UVLC(pcVUI->chromaSampleLocTypeBottomField, "chroma_sample_loc_type_bottom_field"); |
621 | 0 | } |
622 | 0 | } |
623 | |
|
624 | 0 | if(!isByteAligned()) |
625 | 0 | { |
626 | 0 | WRITE_FLAG(1, "vui_payload_bit_equal_to_one"); |
627 | 0 | while(!isByteAligned()) |
628 | 0 | { |
629 | 0 | WRITE_FLAG(0, "vui_payload_bit_equal_to_zero"); |
630 | 0 | } |
631 | 0 | } |
632 | 0 | } |
633 | | |
634 | | void HLSWriter::codeGeneralHrdparameters(const GeneralHrdParams * hrd) |
635 | 0 | { |
636 | 0 | WRITE_CODE(hrd->numUnitsInTick, 32, "num_units_in_tick"); |
637 | 0 | WRITE_CODE(hrd->timeScale, 32, "time_scale"); |
638 | 0 | WRITE_FLAG(hrd->generalNalHrdParamsPresent, "general_nal_hrd_parameters_present_flag"); |
639 | 0 | WRITE_FLAG(hrd->generalVclHrdParamsPresent, "general_vcl_hrd_parameters_present_flag"); |
640 | 0 | if( hrd->generalNalHrdParamsPresent || hrd->generalVclHrdParamsPresent ) |
641 | 0 | { |
642 | 0 | WRITE_FLAG(hrd->generalSamePicTimingInAllOlsFlag, "general_same_pic_timing_in_all_ols_flag"); |
643 | 0 | WRITE_FLAG(hrd->generalDecodingUnitHrdParamsPresent, "general_decoding_unit_hrd_params_present_flag"); |
644 | 0 | if (hrd->generalDecodingUnitHrdParamsPresent) |
645 | 0 | { |
646 | 0 | WRITE_CODE(hrd->tickDivisorMinus2, 8, "tick_divisor_minus2"); |
647 | 0 | } |
648 | 0 | WRITE_CODE(hrd->bitRateScale, 4, "bit_rate_scale"); |
649 | 0 | WRITE_CODE(hrd->cpbSizeScale, 4, "cpb_size_scale"); |
650 | 0 | if (hrd->generalDecodingUnitHrdParamsPresent) |
651 | 0 | { |
652 | 0 | WRITE_CODE(hrd->cpbSizeDuScale, 4, "cpb_size_du_scale"); |
653 | 0 | } |
654 | 0 | WRITE_UVLC(hrd->hrdCpbCntMinus1, "hrd_cpb_cnt_minus1"); |
655 | 0 | } |
656 | 0 | } |
657 | | |
658 | | void HLSWriter::codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const OlsHrdParams *olsHrd, const uint32_t firstSubLayer, const uint32_t maxNumSubLayersMinus1) |
659 | 0 | { |
660 | 0 | for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ ) |
661 | 0 | { |
662 | 0 | const OlsHrdParams *hrd = &(olsHrd[i]); |
663 | 0 | WRITE_FLAG(hrd->fixedPicRateGeneralFlag, "fixed_pic_rate_general_flag"); |
664 | |
|
665 | 0 | if (!hrd->fixedPicRateGeneralFlag) |
666 | 0 | { |
667 | 0 | WRITE_FLAG(hrd->fixedPicRateWithinCvsFlag, "fixed_pic_rate_within_cvs_flag"); |
668 | 0 | } |
669 | 0 | if (hrd->fixedPicRateWithinCvsFlag) |
670 | 0 | { |
671 | 0 | WRITE_UVLC(hrd->elementDurationInTcMinus1, "elemental_duration_in_tc_minus1"); |
672 | 0 | } |
673 | 0 | else if ( (generalHrd->generalNalHrdParamsPresent || generalHrd->generalVclHrdParamsPresent) &&generalHrd->hrdCpbCntMinus1 == 0) |
674 | 0 | { |
675 | 0 | WRITE_FLAG(hrd->lowDelayHrdFlag, "low_delay_hrd_flag"); |
676 | 0 | } |
677 | |
|
678 | 0 | for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ ) |
679 | 0 | { |
680 | 0 | if (((nalOrVcl == 0) && (generalHrd->generalNalHrdParamsPresent)) || ((nalOrVcl == 1) && (generalHrd->generalVclHrdParamsPresent))) |
681 | 0 | { |
682 | 0 | for (int j = 0; j <= (generalHrd->hrdCpbCntMinus1); j++) |
683 | 0 | { |
684 | 0 | WRITE_UVLC(hrd->bitRateValueMinus1[j][nalOrVcl], "bit_rate_value_minus1"); |
685 | 0 | WRITE_UVLC(hrd->cpbSizeValueMinus1[j][nalOrVcl], "cpb_size_value_minus1"); |
686 | 0 | if (generalHrd->generalDecodingUnitHrdParamsPresent) |
687 | 0 | { |
688 | 0 | WRITE_UVLC(hrd->duCpbSizeValueMinus1[j][nalOrVcl], "cpb_size_du_value_minus1"); |
689 | 0 | WRITE_UVLC(hrd->duBitRateValueMinus1[j][nalOrVcl], "bit_rate_du_value_minus1"); |
690 | 0 | } |
691 | 0 | WRITE_FLAG(hrd->cbrFlag[j][nalOrVcl], "cbr_flag"); |
692 | 0 | } |
693 | 0 | } |
694 | 0 | } |
695 | 0 | } |
696 | 0 | } |
697 | | |
698 | | void HLSWriter::dpb_parameters(int maxSubLayersMinus1, bool subLayerInfoFlag, const SPS *pcSPS) |
699 | 0 | { |
700 | 0 | for (uint32_t i = (subLayerInfoFlag ? 0 : maxSubLayersMinus1); i <= maxSubLayersMinus1; i++) |
701 | 0 | { |
702 | 0 | WRITE_UVLC(pcSPS->maxDecPicBuffering[i] - 1, "dpb_max_dec_pic_buffering_minus1[i]"); |
703 | 0 | WRITE_UVLC(pcSPS->numReorderPics[i], "dpb_max_num_reorder_pics[i]"); |
704 | 0 | WRITE_UVLC(pcSPS->maxLatencyIncreasePlus1[i], "dpb_max_latency_increase_plus1[i]"); |
705 | 0 | } |
706 | 0 | } |
707 | | |
708 | | void HLSWriter::codeSPS( const SPS* pcSPS ) |
709 | 0 | { |
710 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Sequence Parameter Set ===========\n" ); |
711 | |
|
712 | 0 | WRITE_CODE( pcSPS->spsId, 4, "sps_seq_parameter_set_id" ); |
713 | 0 | WRITE_CODE( pcSPS->vpsId, 4, "sps_video_parameter_set_id" ); |
714 | 0 | CHECK(pcSPS->maxTLayers == 0, "Maximum number of temporal sub-layers is '0'"); |
715 | |
|
716 | 0 | WRITE_CODE(pcSPS->maxTLayers - 1, 3, "sps_max_sub_layers_minus1"); |
717 | 0 | WRITE_CODE( int(pcSPS->chromaFormatIdc), 2, "sps_chroma_format_idc" ); |
718 | 0 | WRITE_CODE(floorLog2(pcSPS->CTUSize) - 5, 2, "sps_log2_ctu_size_minus5"); |
719 | 0 | WRITE_FLAG(pcSPS->ptlDpbHrdParamsPresent, "sps_ptl_dpb_hrd_params_present_flag"); |
720 | |
|
721 | 0 | if (pcSPS->ptlDpbHrdParamsPresent) |
722 | 0 | { |
723 | 0 | codeProfileTierLevel( &pcSPS->profileTierLevel, true, pcSPS->maxTLayers - 1 ); |
724 | 0 | } |
725 | |
|
726 | 0 | WRITE_FLAG(pcSPS->GDR, "sps_gdr_enabled_flag"); |
727 | 0 | WRITE_FLAG( pcSPS->rprEnabled, "sps_ref_pic_resampling_enabled_flag" ); |
728 | 0 | if( pcSPS->rprEnabled ) |
729 | 0 | { |
730 | 0 | WRITE_FLAG(pcSPS->resChangeInClvsEnabled, "sps_res_change_in_clvs_allowed_flag"); |
731 | 0 | } |
732 | 0 | WRITE_UVLC( pcSPS->maxPicWidthInLumaSamples, "sps_pic_width_max_in_luma_samples" ); |
733 | 0 | WRITE_UVLC( pcSPS->maxPicHeightInLumaSamples, "sps_pic_height_max_in_luma_samples" ); |
734 | |
|
735 | 0 | const Window& conf = pcSPS->conformanceWindow; |
736 | 0 | WRITE_FLAG( conf.enabledFlag, "sps_conformance_window_flag" ); |
737 | 0 | if (conf.enabledFlag) |
738 | 0 | { |
739 | 0 | WRITE_UVLC( conf.winLeftOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "sps_conf_win_left_offset" ); |
740 | 0 | WRITE_UVLC( conf.winRightOffset / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "sps_conf_win_right_offset" ); |
741 | 0 | WRITE_UVLC( conf.winTopOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "sps_conf_win_top_offset" ); |
742 | 0 | WRITE_UVLC( conf.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "sps_conf_win_bottom_offset" ); |
743 | 0 | } |
744 | |
|
745 | 0 | WRITE_FLAG(pcSPS->subPicInfoPresent, "sps_subpic_info_present_flag"); |
746 | |
|
747 | 0 | if (pcSPS->subPicInfoPresent) |
748 | 0 | { |
749 | 0 | THROW("no suppport"); |
750 | 0 | } |
751 | | |
752 | 0 | WRITE_UVLC( pcSPS->bitDepths[ CH_L ] - 8, "sps_bitdepth_minus8" ); |
753 | 0 | WRITE_FLAG( pcSPS->entropyCodingSyncEnabled, "sps_entropy_coding_sync_enabled_flag" ); |
754 | 0 | WRITE_FLAG( pcSPS->entryPointsPresent, "sps_entry_point_offsets_present_flag" ); |
755 | 0 | WRITE_CODE( pcSPS->bitsForPOC-4, 4, "sps_log2_max_pic_order_cnt_lsb_minus4" ); |
756 | 0 | WRITE_FLAG( pcSPS->pocMsbFlag, "sps_poc_msb_flag"); |
757 | |
|
758 | 0 | if (pcSPS->pocMsbFlag) |
759 | 0 | { |
760 | 0 | WRITE_UVLC(pcSPS->pocMsbLen - 1, "sps_poc_msb_len_minus1"); |
761 | 0 | } |
762 | |
|
763 | 0 | WRITE_CODE(0, 2, "sps_num_extra_ph_bits_bytes"); |
764 | 0 | WRITE_CODE(0, 2, "sps_num_extra_sh_bits_bytes"); |
765 | |
|
766 | 0 | if (pcSPS->ptlDpbHrdParamsPresent) |
767 | 0 | { |
768 | 0 | if (pcSPS->maxTLayers > 1) |
769 | 0 | { |
770 | 0 | WRITE_FLAG(pcSPS->subLayerDpbParams, "sps_sublayer_dpb_params_flag"); |
771 | 0 | } |
772 | 0 | dpb_parameters(pcSPS->maxTLayers - 1, pcSPS->subLayerDpbParams, pcSPS); |
773 | 0 | } |
774 | |
|
775 | 0 | WRITE_UVLC(pcSPS->log2MinCodingBlockSize - 2, "log2_min_luma_coding_block_size_minus2"); |
776 | 0 | WRITE_FLAG(pcSPS->partitionOverrideEnabled, "sps_partition_constraints_override_enabled_flag"); |
777 | 0 | WRITE_UVLC(Log2(pcSPS->minQTSize[0]) - pcSPS->log2MinCodingBlockSize, "sps_log2_diff_min_qt_min_cb_intra_slice_luma"); |
778 | 0 | WRITE_UVLC(pcSPS->maxMTTDepth[0], "sps_max_mtt_hierarchy_depth_intra_slice_luma"); |
779 | 0 | if (pcSPS->maxMTTDepth[0] != 0) |
780 | 0 | { |
781 | 0 | WRITE_UVLC(Log2(pcSPS->maxBTSize[0]) - Log2(pcSPS->minQTSize[0]), "sps_log2_diff_max_bt_min_qt_intra_slice_luma"); |
782 | 0 | WRITE_UVLC(Log2(pcSPS->maxTTSize[0]) - Log2(pcSPS->minQTSize[0]), "sps_log2_diff_max_tt_min_qt_intra_slice_luma"); |
783 | 0 | } |
784 | 0 | if( pcSPS->chromaFormatIdc != CHROMA_400 ) |
785 | 0 | { |
786 | 0 | WRITE_FLAG(pcSPS->dualITree, "sps_qtbtt_dual_tree_intra_flag"); |
787 | 0 | } |
788 | 0 | if (pcSPS->dualITree) |
789 | 0 | { |
790 | 0 | WRITE_UVLC(Log2(pcSPS->minQTSize[2]) - pcSPS->log2MinCodingBlockSize, "sps_log2_diff_min_qt_min_cb_intra_slice_chroma"); |
791 | 0 | WRITE_UVLC(pcSPS->maxMTTDepth[2], "sps_max_mtt_hierarchy_depth_intra_slice_chroma"); |
792 | 0 | if (pcSPS->maxMTTDepth[2] != 0) |
793 | 0 | { |
794 | 0 | WRITE_UVLC(Log2(pcSPS->maxBTSize[2]) - Log2(pcSPS->minQTSize[2]), "sps_log2_diff_max_bt_min_qt_intra_slice_chroma"); |
795 | 0 | WRITE_UVLC(Log2(pcSPS->maxTTSize[2]) - Log2(pcSPS->minQTSize[2]), "sps_log2_diff_max_tt_min_qt_intra_slice_chroma"); |
796 | 0 | } |
797 | 0 | } |
798 | |
|
799 | 0 | WRITE_UVLC(Log2(pcSPS->minQTSize[1]) - pcSPS->log2MinCodingBlockSize, "sps_log2_diff_min_qt_min_cb_inter_slice"); |
800 | 0 | WRITE_UVLC(pcSPS->maxMTTDepth[1], "sps_max_mtt_hierarchy_depth_inter_slice"); |
801 | 0 | if (pcSPS->maxMTTDepth[1] != 0) |
802 | 0 | { |
803 | 0 | WRITE_UVLC(Log2(pcSPS->maxBTSize[1]) - Log2(pcSPS->minQTSize[1]), "sps_log2_diff_max_bt_min_qt_inter_slice"); |
804 | 0 | WRITE_UVLC(Log2(pcSPS->maxTTSize[1]) - Log2(pcSPS->minQTSize[1]), "sps_log2_diff_max_tt_min_qt_inter_slice"); |
805 | 0 | } |
806 | |
|
807 | 0 | if (pcSPS->CTUSize > 32) |
808 | 0 | { |
809 | 0 | WRITE_FLAG( (pcSPS->log2MaxTbSize - 5) != 0, "sps_max_luma_transform_size_64_flag" ); |
810 | 0 | } |
811 | 0 | WRITE_FLAG(pcSPS->transformSkip, "sps_transform_skip_enabled_flag"); |
812 | 0 | if (pcSPS->transformSkip) |
813 | 0 | { |
814 | 0 | WRITE_UVLC(pcSPS->log2MaxTransformSkipBlockSize - 2, "sps_log2_transform_skip_max_size_minus2"); |
815 | 0 | WRITE_FLAG(pcSPS->BDPCM, "sps_bdpcm_enabled_flag"); |
816 | 0 | } |
817 | 0 | WRITE_FLAG( pcSPS->MTS, "sps_mts_enabled_flag" ); |
818 | 0 | if ( pcSPS->MTS ) |
819 | 0 | { |
820 | 0 | WRITE_FLAG( pcSPS->MTSIntra, "sps_explicit_mts_intra_enabled_flag" ); |
821 | 0 | WRITE_FLAG( pcSPS->MTSInter, "sps_explicit_mts_inter_enabled_flag" ); |
822 | 0 | } |
823 | 0 | WRITE_FLAG( pcSPS->LFNST, "sps_lfnst_enabled_flag"); |
824 | |
|
825 | 0 | if (pcSPS->chromaFormatIdc != CHROMA_400) |
826 | 0 | { |
827 | 0 | WRITE_FLAG(pcSPS->jointCbCr, "sps_joint_cbcr_enabled_flag"); |
828 | |
|
829 | 0 | const ChromaQpMappingTable& chromaQpMappingTable = pcSPS->chromaQpMappingTable; |
830 | 0 | WRITE_FLAG(chromaQpMappingTable.m_sameCQPTableForAllChromaFlag, "same_qp_table_for_chroma"); |
831 | 0 | int numQpTables = chromaQpMappingTable.m_sameCQPTableForAllChromaFlag ? 1 : (pcSPS->jointCbCr ? 3 : 2); |
832 | 0 | CHECK(numQpTables != chromaQpMappingTable.m_numQpTables, " numQpTables does not match at encoder side "); |
833 | 0 | for (int i = 0; i < numQpTables; i++) |
834 | 0 | { |
835 | 0 | WRITE_SVLC(chromaQpMappingTable.m_qpTableStartMinus26[i], "sps_qp_table_starts_minus26"); |
836 | 0 | WRITE_UVLC(chromaQpMappingTable.m_numPtsInCQPTableMinus1[i], "sps_num_points_in_qp_table_minus1"); |
837 | |
|
838 | 0 | for (int j = 0; j <= chromaQpMappingTable.m_numPtsInCQPTableMinus1[i]; j++) |
839 | 0 | { |
840 | 0 | WRITE_UVLC(chromaQpMappingTable.m_deltaQpInValMinus1[i][j], "sps_delta_qp_in_val_minus1"); |
841 | 0 | WRITE_UVLC(chromaQpMappingTable.m_deltaQpOutVal[i][j] ^ chromaQpMappingTable.m_deltaQpInValMinus1[i][j], "sps_delta_qp_diff_val"); |
842 | 0 | } |
843 | 0 | } |
844 | 0 | } |
845 | | |
846 | 0 | WRITE_FLAG( pcSPS->saoEnabled, "sps_sao_enabled_flag"); |
847 | 0 | WRITE_FLAG( pcSPS->alfEnabled, "sps_alf_enabled_flag" ); |
848 | 0 | if (pcSPS->alfEnabled && pcSPS->chromaFormatIdc != CHROMA_400) |
849 | 0 | { |
850 | 0 | WRITE_FLAG( pcSPS->ccalfEnabled, "sps_ccalf_enabled_flag" ); |
851 | 0 | } |
852 | 0 | WRITE_FLAG(pcSPS->lumaReshapeEnable, "sps_lmcs_enable_flag"); |
853 | 0 | WRITE_FLAG( pcSPS->weightPred, "sps_weighted_pred_flag" ); // Use of Weighting Prediction (P_SLICE) |
854 | 0 | WRITE_FLAG( pcSPS->weightedBiPred, "sps_weighted_bipred_flag" ); // Use of Weighting Bi-Prediction (B_SLICE) |
855 | 0 | WRITE_FLAG( pcSPS->longTermRefsPresent, "sps_long_term_ref_pics_flag" ); |
856 | 0 | if( pcSPS->vpsId > 0 ) |
857 | 0 | { |
858 | 0 | WRITE_FLAG( pcSPS->interLayerPresent, "sps_inter_layer_ref_pics_present_flag" ); |
859 | 0 | } |
860 | 0 | WRITE_FLAG( pcSPS->idrRefParamList, "sps_idr_rpl_present_flag" ); |
861 | 0 | WRITE_FLAG( pcSPS->rpl1CopyFromRpl0, "sps_rpl1_copy_from_rpl0_flag"); |
862 | | |
863 | | //Write candidate for List0 |
864 | 0 | uint32_t numberOfRPL = (uint32_t)pcSPS->getNumRPL(0); |
865 | 0 | WRITE_UVLC(numberOfRPL, "sps_num_ref_pic_lists_in_sps[0]"); |
866 | 0 | for (int ii = 0; ii < numberOfRPL; ii++) |
867 | 0 | { |
868 | 0 | xCodeRefPicList( &pcSPS->rplList[0][ii], pcSPS->longTermRefsPresent, pcSPS->bitsForPOC, !pcSPS->weightPred && !pcSPS->weightedBiPred, ii ); |
869 | 0 | } |
870 | | |
871 | | //Write candidate for List1 |
872 | 0 | if (!pcSPS->rpl1CopyFromRpl0) |
873 | 0 | { |
874 | 0 | numberOfRPL = (uint32_t)pcSPS->getNumRPL(1); |
875 | 0 | WRITE_UVLC(numberOfRPL, "sps_num_ref_pic_lists_in_sps[1]"); |
876 | 0 | for (int ii = 0; ii < numberOfRPL; ii++) |
877 | 0 | { |
878 | 0 | xCodeRefPicList( &pcSPS->rplList[1][ii], pcSPS->longTermRefsPresent, pcSPS->bitsForPOC, !pcSPS->weightPred && !pcSPS->weightedBiPred, ii ); |
879 | 0 | } |
880 | 0 | } |
881 | |
|
882 | 0 | WRITE_FLAG( pcSPS->wrapAroundEnabled, "sps_ref_wraparound_enabled_flag" ); |
883 | |
|
884 | 0 | WRITE_FLAG( pcSPS->temporalMVPEnabled, "sps_temporal_mvp_enabled_flag" ); |
885 | |
|
886 | 0 | if ( pcSPS->temporalMVPEnabled ) |
887 | 0 | { |
888 | 0 | WRITE_FLAG( pcSPS->SbtMvp, "sps_sbtmvp_enabled_flag"); |
889 | 0 | } |
890 | |
|
891 | 0 | WRITE_FLAG( pcSPS->AMVR, "sps_amvr_enabled_flag" ); |
892 | |
|
893 | 0 | WRITE_FLAG( pcSPS->BDOF, "sps_bdof_enabled_flag" ); |
894 | 0 | if (pcSPS->BDOF) |
895 | 0 | { |
896 | 0 | WRITE_FLAG(pcSPS->BdofPresent, "sps_bdof_pic_present_flag"); |
897 | 0 | } |
898 | 0 | WRITE_FLAG( pcSPS->SMVD, "sps_smvd_enabled_flag" ); |
899 | 0 | WRITE_FLAG( pcSPS->DMVR, "sps_dmvr_enabled_flag" ); |
900 | 0 | if (pcSPS->DMVR) |
901 | 0 | { |
902 | 0 | WRITE_FLAG(pcSPS->DmvrPresent, "sps_dmvr_pic_present_flag"); |
903 | 0 | } |
904 | 0 | WRITE_FLAG(pcSPS->MMVD, "sps_mmvd_enabled_flag"); |
905 | 0 | if ( pcSPS->MMVD ) |
906 | 0 | { |
907 | 0 | WRITE_FLAG( pcSPS->fpelMmvd, "sps_fpel_mmvd_enabled_flag" ); |
908 | 0 | } |
909 | 0 | WRITE_UVLC(MRG_MAX_NUM_CANDS - pcSPS->maxNumMergeCand, "sps_six_minus_max_num_merge_cand"); |
910 | 0 | WRITE_FLAG( pcSPS->SBT, "sps_sbt_enabled_flag" ); |
911 | 0 | WRITE_FLAG( pcSPS->Affine, "sps_affine_enabled_flag" ); |
912 | 0 | if ( pcSPS->Affine ) |
913 | 0 | { |
914 | 0 | WRITE_UVLC(AFFINE_MRG_MAX_NUM_CANDS - pcSPS->maxNumAffineMergeCand, "five_minus_max_num_subblock_merge_cand"); |
915 | 0 | WRITE_FLAG( pcSPS->AffineType, "sps_affine_type_flag" ); |
916 | 0 | if (pcSPS->AMVR ) |
917 | 0 | { |
918 | 0 | WRITE_FLAG( pcSPS->AffineAmvr, "sps_affine_amvr_enabled_flag" ); |
919 | 0 | } |
920 | |
|
921 | 0 | WRITE_FLAG( pcSPS->PROF, "sps_affine_prof_enabled_flag" ); |
922 | 0 | if (pcSPS->PROF) |
923 | 0 | { |
924 | 0 | WRITE_FLAG(pcSPS->ProfPresent, "sps_prof_pic_present_flag" ); |
925 | 0 | } |
926 | 0 | } |
927 | |
|
928 | 0 | WRITE_FLAG(pcSPS->BCW, "sps_bcw_enabled_flag"); |
929 | |
|
930 | 0 | WRITE_FLAG( pcSPS->CIIP, "sps_ciip_enabled_flag" ); |
931 | |
|
932 | 0 | if (pcSPS->maxNumMergeCand >= 2) |
933 | 0 | { |
934 | 0 | WRITE_FLAG(pcSPS->GEO, "sps_gpm_enabled_flag"); |
935 | 0 | if (pcSPS->GEO && pcSPS->maxNumMergeCand >= 3) |
936 | 0 | { |
937 | 0 | WRITE_UVLC(pcSPS->maxNumMergeCand - pcSPS->maxNumGeoCand, "sps_max_num_merge_cand_minus_max_num_gpm_cand"); |
938 | 0 | } |
939 | 0 | } |
940 | |
|
941 | 0 | WRITE_UVLC(pcSPS->log2ParallelMergeLevelMinus2, "sps_log2_parallel_merge_level_minus2"); |
942 | 0 | WRITE_FLAG( pcSPS->ISP, "sps_isp_enabled_flag"); |
943 | 0 | WRITE_FLAG( pcSPS->MRL, "sps_mrl_enabled_flag"); |
944 | 0 | WRITE_FLAG( pcSPS->MIP, "sps_mip_enabled_flag"); |
945 | 0 | if( pcSPS->chromaFormatIdc != CHROMA_400) |
946 | 0 | { |
947 | 0 | WRITE_FLAG( pcSPS->LMChroma, "sps_cclm_enabled_flag" ); |
948 | 0 | } |
949 | 0 | if ( pcSPS->chromaFormatIdc == CHROMA_420 ) |
950 | 0 | { |
951 | 0 | WRITE_FLAG( pcSPS->horCollocatedChroma, "sps_chroma_horizontal_collocated_flag" ); |
952 | 0 | WRITE_FLAG( pcSPS->verCollocatedChroma, "sps_chroma_vertical_collocated_flag" ); |
953 | 0 | } |
954 | |
|
955 | 0 | WRITE_FLAG(pcSPS->PLT, "sps_palette_enabled_flag" ); |
956 | |
|
957 | 0 | if (pcSPS->chromaFormatIdc == CHROMA_444) |
958 | 0 | { |
959 | 0 | WRITE_FLAG(pcSPS->PLT, "sps_plt_enabled_flag" ); |
960 | 0 | } |
961 | 0 | if (pcSPS->chromaFormatIdc == CHROMA_444 && pcSPS->log2MaxTbSize != 6) |
962 | 0 | { |
963 | 0 | WRITE_FLAG(pcSPS->useColorTrans, "sps_act_enabled_flag"); |
964 | 0 | } |
965 | 0 | if (pcSPS->transformSkip || pcSPS->PLT) |
966 | 0 | { |
967 | 0 | WRITE_UVLC(pcSPS->internalMinusInputBitDepth[CH_L], "sps_internal_bit_depth_minus_input_bit_depth"); |
968 | 0 | } |
969 | |
|
970 | 0 | WRITE_FLAG(pcSPS->IBC, "sps_ibc_enabled_flag"); |
971 | 0 | if( pcSPS->IBC ) |
972 | 0 | { |
973 | 0 | WRITE_UVLC(IBC_MRG_MAX_NUM_CANDS - pcSPS->maxNumIBCMergeCand, "six_minus_max_num_ibc_merge_cand"); |
974 | 0 | } |
975 | |
|
976 | 0 | WRITE_FLAG( pcSPS->LADF, "sps_ladf_enabled_flag" ); |
977 | 0 | if ( pcSPS->LADF ) |
978 | 0 | { |
979 | 0 | THROW("no support"); |
980 | 0 | } |
981 | | |
982 | 0 | WRITE_FLAG( pcSPS->scalingListEnabled, "sps_explicit_scaling_list_enabled_flag" ); |
983 | 0 | if (pcSPS->LFNST && pcSPS->scalingListEnabled ) |
984 | 0 | { |
985 | 0 | WRITE_FLAG(pcSPS->disableScalingMatrixForLfnstBlks, "sps_scaling_matrix_for_lfnst_disabled_flag"); |
986 | 0 | } |
987 | 0 | if (pcSPS->useColorTrans && pcSPS->scalingListEnabled) |
988 | 0 | { |
989 | 0 | WRITE_FLAG(pcSPS->scalingMatrixAlternativeColourSpaceDisabled, "sps_scaling_matrix_for_alternative_colour_space_disabled_flag"); |
990 | 0 | } |
991 | 0 | if (pcSPS->scalingMatrixAlternativeColourSpaceDisabled) |
992 | 0 | { |
993 | 0 | WRITE_FLAG(pcSPS->scalingMatrixDesignatedColourSpace, "sps_scaling_matrix_designated_colour_space_flag"); |
994 | 0 | } |
995 | 0 | WRITE_FLAG(pcSPS->depQuantEnabled, "sps_dep_quant_enabled_flag"); |
996 | 0 | WRITE_FLAG(pcSPS->signDataHidingEnabled, "sps_sign_data_hiding_enabled_flag"); |
997 | |
|
998 | 0 | WRITE_FLAG( pcSPS->virtualBoundariesEnabled, "sps_virtual_boundaries_enabled_flag" ); |
999 | 0 | if( pcSPS->virtualBoundariesEnabled ) |
1000 | 0 | { |
1001 | 0 | WRITE_CODE( pcSPS->numVerVirtualBoundaries, 2, "sps_num_ver_virtual_boundaries"); |
1002 | 0 | for( unsigned i = 0; i < pcSPS->numVerVirtualBoundaries; i++ ) |
1003 | 0 | { |
1004 | 0 | WRITE_UVLC((pcSPS->virtualBoundariesPosX[i]>>3), "sps_virtual_boundaries_pos_x"); |
1005 | 0 | } |
1006 | 0 | WRITE_CODE(pcSPS->numHorVirtualBoundaries, 2, "sps_num_hor_virtual_boundaries"); |
1007 | 0 | for( unsigned i = 0; i < pcSPS->numHorVirtualBoundaries; i++ ) |
1008 | 0 | { |
1009 | 0 | WRITE_UVLC((pcSPS->virtualBoundariesPosY[i]>>3), "sps_virtual_boundaries_pos_y"); |
1010 | 0 | } |
1011 | 0 | } |
1012 | |
|
1013 | 0 | if (pcSPS->ptlDpbHrdParamsPresent) |
1014 | 0 | { |
1015 | 0 | WRITE_FLAG(pcSPS->hrdParametersPresent, "sps_timing_hrd_params_present_flag"); |
1016 | |
|
1017 | 0 | if( pcSPS->hrdParametersPresent ) |
1018 | 0 | { |
1019 | 0 | codeGeneralHrdparameters(&pcSPS->generalHrdParams); |
1020 | 0 | if ((pcSPS->maxTLayers - 1) > 0) |
1021 | 0 | { |
1022 | 0 | WRITE_FLAG(pcSPS->subLayerParametersPresent, "sps_sublayer_cpb_params_present_flag"); |
1023 | 0 | } |
1024 | 0 | uint32_t firstSubLayer = pcSPS->subLayerParametersPresent ? 0 : (pcSPS->maxTLayers - 1); |
1025 | 0 | codeOlsHrdParameters(&pcSPS->generalHrdParams, pcSPS->olsHrdParams, firstSubLayer, pcSPS->maxTLayers - 1); |
1026 | 0 | } |
1027 | 0 | } |
1028 | |
|
1029 | 0 | WRITE_FLAG(pcSPS->fieldSeqFlag, "sps_field_seq_flag"); |
1030 | |
|
1031 | 0 | WRITE_FLAG( pcSPS->vuiParametersPresent, "sps_vui_parameters_present_flag" ); |
1032 | 0 | if (pcSPS->vuiParametersPresent) |
1033 | 0 | { |
1034 | 0 | OutputBitstream *bs = m_pcBitIf; // save the original ono |
1035 | 0 | OutputBitstream bs_count; |
1036 | 0 | setBitstream(&bs_count); |
1037 | | #if ENABLE_TRACING |
1038 | | bool traceEnable = g_HLSTraceEnable; |
1039 | | g_HLSTraceEnable = false; |
1040 | | #endif |
1041 | 0 | codeVUI(&pcSPS->vuiParameters, pcSPS); |
1042 | | #if ENABLE_TRACING |
1043 | | g_HLSTraceEnable = traceEnable; |
1044 | | #endif |
1045 | 0 | unsigned vui_payload_data_num_bits = bs_count.getNumberOfWrittenBits(); |
1046 | 0 | CHECK( vui_payload_data_num_bits % 8 != 0, "Invalid number of VUI payload data bits" ); |
1047 | 0 | setBitstream(bs); |
1048 | 0 | WRITE_UVLC((vui_payload_data_num_bits >> 3) - 1, "sps_vui_payload_size_minus1"); |
1049 | 0 | while (!isByteAligned()) |
1050 | 0 | { |
1051 | 0 | WRITE_FLAG(0, "sps_vui_alignment_zero_bit"); |
1052 | 0 | } |
1053 | 0 | codeVUI(&pcSPS->vuiParameters, pcSPS); |
1054 | 0 | } |
1055 | | |
1056 | 0 | bool sps_extension_present_flag=false; |
1057 | 0 | bool sps_extension_flags[NUM_SPS_EXTENSION_FLAGS]={false}; |
1058 | |
|
1059 | 0 | for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) |
1060 | 0 | { |
1061 | 0 | sps_extension_present_flag|=sps_extension_flags[i]; |
1062 | 0 | } |
1063 | |
|
1064 | 0 | WRITE_FLAG( sps_extension_present_flag, "sps_extension_present_flag" ); |
1065 | |
|
1066 | 0 | if (sps_extension_present_flag) |
1067 | 0 | { |
1068 | | #if ENABLE_TRACING |
1069 | | static const char *syntaxStrings[]={ "sps_range_extension_flag", |
1070 | | "sps_multilayer_extension_flag", |
1071 | | "sps_extension_6bits[0]", |
1072 | | "sps_extension_6bits[1]", |
1073 | | "sps_extension_6bits[2]", |
1074 | | "sps_extension_6bits[3]", |
1075 | | "sps_extension_6bits[4]", |
1076 | | "sps_extension_6bits[5]" }; |
1077 | | #endif |
1078 | |
|
1079 | 0 | for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) |
1080 | 0 | { |
1081 | 0 | WRITE_FLAG( sps_extension_flags[i], syntaxStrings[i] ); |
1082 | 0 | } |
1083 | |
|
1084 | 0 | for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) // loop used so that the order is determined by the enum. |
1085 | 0 | { |
1086 | 0 | if (sps_extension_flags[i]) |
1087 | 0 | { |
1088 | | #if 0 // TODO: enable when applicable |
1089 | | switch (SPSExtensionFlagIndex(i)) |
1090 | | { |
1091 | | default: |
1092 | | CHECK(sps_extension_flags[i]!=false, "Unknown PPS extension signalled"); // Should never get here with an active SPS extension flag. |
1093 | | break; |
1094 | | } |
1095 | | #endif |
1096 | 0 | } |
1097 | 0 | } |
1098 | 0 | } |
1099 | 0 | xWriteRbspTrailingBits(); |
1100 | 0 | } |
1101 | | |
1102 | | void HLSWriter::codeDCI( const DCI* dci ) |
1103 | 0 | { |
1104 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Decoding Parameter Set ===========\n" ); |
1105 | |
|
1106 | 0 | WRITE_CODE( 0, 4, "dci_reserved_zero_5bits" ); |
1107 | 0 | uint32_t numPTLs = (uint32_t) dci->profileTierLevel.size(); |
1108 | 0 | CHECK (numPTLs<1, "At least one PTL must be available in DPS"); |
1109 | |
|
1110 | 0 | WRITE_CODE( numPTLs - 1, 4, "dci_num_ptls_minus1" ); |
1111 | |
|
1112 | 0 | for (int i=0; i< numPTLs; i++) |
1113 | 0 | { |
1114 | 0 | codeProfileTierLevel( &dci->profileTierLevel[i], true, 0 ); |
1115 | 0 | } |
1116 | 0 | WRITE_FLAG( 0, "dci_extension_flag" ); |
1117 | 0 | xWriteRbspTrailingBits(); |
1118 | 0 | } |
1119 | | |
1120 | | void HLSWriter::codeVPS(const VPS* pcVPS) |
1121 | 0 | { |
1122 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Video Parameter Set ===========\n" ); |
1123 | |
|
1124 | 0 | WRITE_CODE(pcVPS->vpsId, 4, "vps_video_parameter_set_id"); |
1125 | 0 | WRITE_CODE(pcVPS->maxLayers - 1, 6, "vps_max_layers_minus1"); |
1126 | 0 | WRITE_CODE(pcVPS->maxSubLayers - 1, 3, "vps_max_sublayers_minus1"); |
1127 | 0 | if (pcVPS->maxLayers > 1 && pcVPS->maxSubLayers > 1) |
1128 | 0 | { |
1129 | 0 | WRITE_FLAG(pcVPS->defaultPtlDpbHrdMaxTidFlag, "vps_default_ptl_dpb_hrd_max_tid_flag"); |
1130 | 0 | } |
1131 | 0 | if (pcVPS->maxLayers > 1) |
1132 | 0 | { |
1133 | 0 | WRITE_FLAG(pcVPS->allIndependentLayers, "vps_all_independent_layers_flag"); |
1134 | 0 | } |
1135 | 0 | for (uint32_t i = 0; i < pcVPS->maxLayers; i++) |
1136 | 0 | { |
1137 | 0 | WRITE_CODE(pcVPS->layerId[i], 6, "vps_layer_id"); |
1138 | 0 | if (i > 0 && !pcVPS->allIndependentLayers) |
1139 | 0 | { |
1140 | 0 | WRITE_FLAG(pcVPS->independentLayer[i], "vps_independent_layer_flag"); |
1141 | 0 | if (!pcVPS->independentLayer[i]) |
1142 | 0 | { |
1143 | 0 | bool presentFlag = false; |
1144 | 0 | for (int j = 0; j < i; j++) |
1145 | 0 | { |
1146 | 0 | presentFlag |= ((pcVPS->maxTidIlRefPicsPlus1[i][j] != VVENC_MAX_TLAYER) && pcVPS->directRefLayer[i][j]); |
1147 | 0 | } |
1148 | 0 | WRITE_FLAG(presentFlag, "max_tid_ref_present_flag[ i ]"); |
1149 | 0 | for (int j = 0; j < i; j++) |
1150 | 0 | { |
1151 | 0 | WRITE_FLAG(pcVPS->directRefLayer[i][j], "vps_direct_ref_layer_flag"); |
1152 | 0 | if (presentFlag && pcVPS->directRefLayer[i][j]) |
1153 | 0 | { |
1154 | 0 | WRITE_CODE(pcVPS->maxTidIlRefPicsPlus1[i][j], 3, "max_tid_il_ref_pics_plus1[ i ][ j ]"); |
1155 | 0 | } |
1156 | 0 | } |
1157 | 0 | } |
1158 | 0 | } |
1159 | 0 | } |
1160 | 0 | if( pcVPS->maxLayers > 1 ) |
1161 | 0 | { |
1162 | 0 | if (pcVPS->allIndependentLayers) |
1163 | 0 | { |
1164 | 0 | WRITE_FLAG(pcVPS->eachLayerIsAnOls, "vps_each_layer_is_an_ols_flag"); |
1165 | 0 | } |
1166 | 0 | if (!pcVPS->eachLayerIsAnOls) |
1167 | 0 | { |
1168 | 0 | if (!pcVPS->allIndependentLayers) |
1169 | 0 | { |
1170 | 0 | WRITE_CODE(pcVPS->olsModeIdc, 2, "vps_ols_mode_idc"); |
1171 | 0 | } |
1172 | 0 | if (pcVPS->olsModeIdc == 2) |
1173 | 0 | { |
1174 | 0 | WRITE_CODE(pcVPS->numOutputLayerSets - 2, 8, "vps_num_output_layer_sets_minus2"); |
1175 | 0 | for (uint32_t i = 1; i < pcVPS->numOutputLayerSets; i++) |
1176 | 0 | { |
1177 | 0 | for (uint32_t j = 0; j < pcVPS->maxLayers; j++) |
1178 | 0 | { |
1179 | 0 | WRITE_FLAG(pcVPS->olsOutputLayer[i][j], "vps_ols_output_layer_flag"); |
1180 | 0 | } |
1181 | 0 | } |
1182 | 0 | } |
1183 | 0 | } |
1184 | 0 | CHECK(pcVPS->numPtls - 1 >= pcVPS->totalNumOLSs, "vps_num_ptls_minus1 shall be less than TotalNumOlss"); |
1185 | 0 | WRITE_CODE(pcVPS->numPtls - 1, 8, "vps_num_ptls_minus1"); |
1186 | 0 | } |
1187 | | |
1188 | 0 | int totalNumOlss = pcVPS->totalNumOLSs; |
1189 | 0 | for (int i = 0; i < pcVPS->numPtls; i++) |
1190 | 0 | { |
1191 | 0 | if(i > 0) |
1192 | 0 | { |
1193 | 0 | WRITE_FLAG(pcVPS->ptPresent[i], "vps_ptl_present_flag"); |
1194 | 0 | } |
1195 | 0 | if(!pcVPS->allLayersSameNumSubLayers) |
1196 | 0 | { |
1197 | 0 | WRITE_CODE(pcVPS->ptlMaxTemporalId[i] ,3, "vps_ptl_max_temporal_id"); |
1198 | 0 | } |
1199 | 0 | } |
1200 | 0 | int cnt = 0; |
1201 | 0 | while (m_pcBitIf->getNumBitsUntilByteAligned()) |
1202 | 0 | { |
1203 | 0 | WRITE_FLAG( 0, "vps_ptl_reserved_zero_bit"); |
1204 | 0 | cnt++; |
1205 | 0 | } |
1206 | 0 | CHECK(cnt>=8, "More than '8' alignment bytes written"); |
1207 | 0 | for (int i = 0; i < pcVPS->numPtls; i++) |
1208 | 0 | { |
1209 | 0 | codeProfileTierLevel(&pcVPS->profileTierLevel[i], pcVPS->ptPresent[i], pcVPS->ptlMaxTemporalId[i] - 1); |
1210 | 0 | } |
1211 | 0 | for (int i = 0; i < totalNumOlss; i++) |
1212 | 0 | { |
1213 | 0 | if(pcVPS->numPtls > 1 && pcVPS->numPtls != pcVPS->totalNumOLSs) |
1214 | 0 | WRITE_CODE(pcVPS->olsPtlIdx[i], 8, "vps_ols_ptl_idx"); |
1215 | 0 | } |
1216 | 0 | if( !pcVPS->allIndependentLayers ) |
1217 | 0 | { |
1218 | 0 | WRITE_UVLC( pcVPS->numDpbParams, "vps_num_dpb_params" ); |
1219 | 0 | } |
1220 | |
|
1221 | 0 | if( pcVPS->numDpbParams > 0 && pcVPS->maxSubLayers > 1 ) |
1222 | 0 | { |
1223 | 0 | WRITE_FLAG( pcVPS->sublayerDpbParamsPresent, "vps_sublayer_dpb_params_present_flag" ); |
1224 | 0 | } |
1225 | |
|
1226 | 0 | for( int i = 0; i < pcVPS->numDpbParams; i++ ) |
1227 | 0 | { |
1228 | 0 | if( !pcVPS->allLayersSameNumSubLayers ) |
1229 | 0 | { |
1230 | 0 | WRITE_CODE( pcVPS->dpbMaxTemporalId[i], 3, "vps_dpb_max_temporal_id[i]" ); |
1231 | 0 | } |
1232 | 0 | if( pcVPS->maxSubLayers == 1 ) |
1233 | 0 | { |
1234 | 0 | CHECK( pcVPS->dpbMaxTemporalId[i] != 0, "When vps_max_sublayers_minus1 is equal to 0, the value of dpb_max_temporal_id[ i ] is inferred to be equal to 0" ); |
1235 | 0 | } |
1236 | 0 | else |
1237 | 0 | { |
1238 | 0 | if( pcVPS->defaultPtlDpbHrdMaxTidFlag ) |
1239 | 0 | { |
1240 | 0 | CHECK( pcVPS->dpbMaxTemporalId[i] != pcVPS->maxSubLayers - 1, "When vps_max_sublayers_minus1 is greater than 0 and vps_all_layers_same_num_sublayers_flag is equal to 1, the value of dpb_max_temporal_id[ i ] is inferred to be equal to vps_max_sublayers_minus1" ); |
1241 | 0 | } |
1242 | 0 | else |
1243 | 0 | { |
1244 | 0 | WRITE_CODE( pcVPS->dpbMaxTemporalId[i], 3, "vps_dpb_max_temporal_id[i]" ); |
1245 | 0 | } |
1246 | 0 | } |
1247 | | |
1248 | 0 | for( int j = ( pcVPS->sublayerDpbParamsPresent ? 0 : pcVPS->dpbMaxTemporalId[i] ); j <= pcVPS->dpbMaxTemporalId[i]; j++ ) |
1249 | 0 | { |
1250 | 0 | WRITE_UVLC( pcVPS->dpbParameters[i].maxDecPicBuffering[j], "max_dec_pic_buffering_minus1[i]" ); |
1251 | 0 | WRITE_UVLC( pcVPS->dpbParameters[i].numReorderPics[j], "max_num_reorder_pics[i]" ); |
1252 | 0 | WRITE_UVLC( pcVPS->dpbParameters[i].maxLatencyIncreasePlus1[j], "max_latency_increase_plus1[i]" ); |
1253 | 0 | } |
1254 | 0 | } |
1255 | | |
1256 | 0 | for( int i = 0; i < pcVPS->totalNumOLSs; i++ ) |
1257 | 0 | { |
1258 | 0 | if( pcVPS->numLayersInOls[i] > 1 ) |
1259 | 0 | { |
1260 | 0 | WRITE_UVLC( pcVPS->olsDpbPicSize[i].width, "vps_ols_dpb_pic_width[i]" ); |
1261 | 0 | WRITE_UVLC( pcVPS->olsDpbPicSize[i].height, "vps_ols_dpb_pic_height[i]" ); |
1262 | 0 | WRITE_CODE( pcVPS->olsDpbChromaFormatIdc[i], 2, "vps_ols_dpb_chroma_format[i]"); |
1263 | 0 | WRITE_UVLC( pcVPS->olsDpbBitDepthMinus8[i], "vps_ols_dpb_bitdepth_minus8[i]"); |
1264 | 0 | if( pcVPS->numDpbParams > 1 && (pcVPS->numDpbParams != pcVPS->numMultiLayeredOlss) ) |
1265 | 0 | { |
1266 | 0 | WRITE_UVLC( pcVPS->olsDpbParamsIdx[i], "vps_ols_dpb_params_idx[i]" ); |
1267 | 0 | } |
1268 | 0 | } |
1269 | 0 | } |
1270 | | |
1271 | |
|
1272 | 0 | if (!pcVPS->eachLayerIsAnOls) |
1273 | 0 | { |
1274 | 0 | WRITE_FLAG(pcVPS->generalHrdParamsPresent, "vps_general_hrd_params_present_flag"); |
1275 | 0 | } |
1276 | 0 | if (pcVPS->generalHrdParamsPresent) |
1277 | 0 | { |
1278 | 0 | codeGeneralHrdparameters(&pcVPS->generalHrdParams); |
1279 | 0 | if ((pcVPS->maxSubLayers-1) > 0) |
1280 | 0 | { |
1281 | 0 | WRITE_FLAG(pcVPS->sublayerCpbParamsPresent, "vps_sublayer_cpb_params_present_flag"); |
1282 | 0 | } |
1283 | 0 | WRITE_UVLC(pcVPS->numOlsHrdParamsMinus1, "vps_num_ols_hrd_params_minus1"); |
1284 | 0 | for (int i = 0; i <= pcVPS->numOlsHrdParamsMinus1; i++) |
1285 | 0 | { |
1286 | 0 | if (!pcVPS->defaultPtlDpbHrdMaxTidFlag) |
1287 | 0 | { |
1288 | 0 | WRITE_CODE(pcVPS->hrdMaxTid[i], 3, "vps_hrd_vps_max_tid[i]"); |
1289 | 0 | } |
1290 | 0 | uint32_t firstSublayer = pcVPS->sublayerCpbParamsPresent ? 0 : pcVPS->hrdMaxTid[i]; |
1291 | 0 | codeOlsHrdParameters(&pcVPS->generalHrdParams, &pcVPS->olsHrdParams[i], firstSublayer, pcVPS->hrdMaxTid[i]); |
1292 | 0 | } |
1293 | 0 | if ((pcVPS->numOlsHrdParamsMinus1 > 0) && ((pcVPS->numOlsHrdParamsMinus1 + 1) != pcVPS->numMultiLayeredOlss)) |
1294 | 0 | { |
1295 | 0 | for (int i = 0; i < pcVPS->numMultiLayeredOlss; i++) |
1296 | 0 | { |
1297 | 0 | WRITE_UVLC(pcVPS->olsHrdIdx[i], "vps_ols_hrd_idx[i]"); |
1298 | 0 | } |
1299 | 0 | } |
1300 | 0 | } |
1301 | 0 | WRITE_FLAG(0, "vps_extension_flag"); |
1302 | | |
1303 | | //future extensions here.. |
1304 | 0 | xWriteRbspTrailingBits(); |
1305 | 0 | } |
1306 | | |
1307 | | void HLSWriter::codePictureHeader( const PicHeader* picHeader, bool writeRbspTrailingBits ) |
1308 | 0 | { |
1309 | 0 | const PPS* pps = NULL; |
1310 | 0 | const SPS* sps = NULL; |
1311 | |
|
1312 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Header ===========\n" ); |
1313 | |
|
1314 | 0 | CodingStructure& cs = *picHeader->pic->cs; |
1315 | 0 | WRITE_FLAG(picHeader->gdrOrIrapPic, "ph_gdr_or_irap_pic_flag"); |
1316 | 0 | WRITE_FLAG(picHeader->nonRefPic, "ph_non_ref_pic_flag"); |
1317 | 0 | if (picHeader->gdrOrIrapPic) |
1318 | 0 | { |
1319 | 0 | WRITE_FLAG(picHeader->gdrPic, "ph_gdr_pic_flag"); |
1320 | 0 | } |
1321 | | // Q0781, two-flags |
1322 | 0 | WRITE_FLAG(picHeader->picInterSliceAllowed, "ph_inter_slice_allowed_flag"); |
1323 | 0 | if (picHeader->picInterSliceAllowed) |
1324 | 0 | { |
1325 | 0 | WRITE_FLAG(picHeader->picIntraSliceAllowed, "ph_intra_slice_allowed_flag"); |
1326 | 0 | } |
1327 | | // parameter sets |
1328 | 0 | WRITE_UVLC(picHeader->ppsId, "ph_pic_parameter_set_id"); |
1329 | 0 | pps = cs.slice->pps; |
1330 | 0 | CHECK(pps == 0, "Invalid PPS"); |
1331 | 0 | sps = cs.slice->sps; |
1332 | 0 | CHECK(sps == 0, "Invalid SPS"); |
1333 | 0 | int pocBits = cs.slice->sps->bitsForPOC; |
1334 | 0 | int pocMask = (1 << pocBits) - 1; |
1335 | 0 | WRITE_CODE(cs.slice->poc & pocMask, pocBits, "ph_pic_order_cnt_lsb"); |
1336 | 0 | if( picHeader->gdrPic ) |
1337 | 0 | { |
1338 | 0 | WRITE_UVLC(picHeader->recoveryPocCnt, "ph_recovery_poc_cnt"); |
1339 | 0 | } |
1340 | | |
1341 | | // PH extra bits are not written in the reference encoder |
1342 | | // as these bits are reserved for future extensions |
1343 | | // for( i = 0; i < NumExtraPhBits; i++ ) |
1344 | | // ph_extra_bit[ i ] |
1345 | |
|
1346 | 0 | if (sps->pocMsbFlag) |
1347 | 0 | { |
1348 | 0 | WRITE_FLAG(picHeader->pocMsbPresent, "ph_poc_msb_present_flag"); |
1349 | 0 | if (picHeader->pocMsbPresent) |
1350 | 0 | { |
1351 | 0 | WRITE_CODE(picHeader->pocMsbVal, sps->pocMsbLen, "ph_poc_msb_val"); |
1352 | 0 | } |
1353 | 0 | } |
1354 | | |
1355 | | // alf enable flags and aps IDs |
1356 | 0 | if( sps->alfEnabled) |
1357 | 0 | { |
1358 | 0 | if (pps->alfInfoInPh) |
1359 | 0 | { |
1360 | 0 | WRITE_FLAG(picHeader->alfEnabled[COMP_Y], "ph_alf_enabled_flag"); |
1361 | 0 | if (picHeader->alfEnabled[COMP_Y]) |
1362 | 0 | { |
1363 | 0 | WRITE_CODE(picHeader->numAlfAps, 3, "ph_num_alf_aps_ids_luma"); |
1364 | 0 | for (int i = 0; i < picHeader->numAlfAps; i++) |
1365 | 0 | { |
1366 | 0 | WRITE_CODE(picHeader->alfApsId[i], 3, "ph_alf_aps_id_luma"); |
1367 | 0 | } |
1368 | |
|
1369 | 0 | const int alfChromaIdc = picHeader->alfEnabled[COMP_Cb] + picHeader->alfEnabled[COMP_Cr] * 2 ; |
1370 | 0 | if (sps->chromaFormatIdc != CHROMA_400) |
1371 | 0 | { |
1372 | 0 | WRITE_CODE(picHeader->alfEnabled[COMP_Cb], 1, "ph_alf_cb_enabled_flag"); |
1373 | 0 | WRITE_CODE(picHeader->alfEnabled[COMP_Cr], 1, "ph_alf_cr_enabled_flag"); |
1374 | 0 | } |
1375 | 0 | if (alfChromaIdc) |
1376 | 0 | { |
1377 | 0 | WRITE_CODE(picHeader->alfChromaApsId, 3, "ph_alf_aps_id_chroma"); |
1378 | 0 | } |
1379 | 0 | if (sps->ccalfEnabled) |
1380 | 0 | { |
1381 | 0 | WRITE_FLAG(picHeader->ccalfEnabled[COMP_Cb], "ph_cc_alf_cb_enabled_flag"); |
1382 | 0 | if (picHeader->ccalfEnabled[COMP_Cb]) |
1383 | 0 | { |
1384 | 0 | WRITE_CODE(picHeader->ccalfCbApsId, 3, "ph_cc_alf_cb_aps_id"); |
1385 | 0 | } |
1386 | 0 | WRITE_FLAG(picHeader->ccalfEnabled[COMP_Cr], "ph_cc_alf_cr_enabled_flag"); |
1387 | 0 | if (picHeader->ccalfEnabled[COMP_Cr]) |
1388 | 0 | { |
1389 | 0 | WRITE_CODE(picHeader->ccalfCrApsId, 3, "ph_cc_alf_cr_aps_id"); |
1390 | 0 | } |
1391 | 0 | } |
1392 | 0 | } |
1393 | 0 | } |
1394 | 0 | } |
1395 | | |
1396 | | // luma mapping / chroma scaling controls |
1397 | 0 | if (sps->lumaReshapeEnable) |
1398 | 0 | { |
1399 | 0 | WRITE_FLAG(picHeader->lmcsEnabled, "ph_lmcs_enabled_flag"); |
1400 | 0 | if (picHeader->lmcsEnabled) |
1401 | 0 | { |
1402 | 0 | WRITE_CODE(picHeader->lmcsApsId, 2, "ph_lmcs_aps_id"); |
1403 | 0 | if (sps->chromaFormatIdc != CHROMA_400) |
1404 | 0 | { |
1405 | 0 | WRITE_FLAG(picHeader->lmcsChromaResidualScale, "ph_chroma_residual_scale_flag"); |
1406 | 0 | } |
1407 | 0 | } |
1408 | 0 | } |
1409 | | |
1410 | | // quantization scaling lists |
1411 | 0 | if( sps->scalingListEnabled ) |
1412 | 0 | { |
1413 | 0 | WRITE_FLAG( picHeader->explicitScalingListEnabled, "ph_scaling_list_present_flag" ); |
1414 | 0 | if( picHeader->explicitScalingListEnabled ) |
1415 | 0 | { |
1416 | 0 | WRITE_CODE( picHeader->scalingListApsId, 3, "ph_scaling_list_aps_id" ); |
1417 | 0 | } |
1418 | 0 | } |
1419 | | |
1420 | | // virtual boundaries |
1421 | 0 | if( sps->virtualBoundariesEnabled && !sps->virtualBoundariesPresent ) |
1422 | 0 | { |
1423 | 0 | WRITE_FLAG( picHeader->virtualBoundariesEnabled, "ph_loop_filter_across_virtual_boundaries_disabled_present_flag" ); |
1424 | 0 | if( picHeader->virtualBoundariesEnabled ) |
1425 | 0 | { |
1426 | 0 | WRITE_CODE(picHeader->numVerVirtualBoundaries, 2, "ph_num_ver_virtual_boundaries"); |
1427 | 0 | for( unsigned i = 0; i < picHeader->numVerVirtualBoundaries; i++ ) |
1428 | 0 | { |
1429 | 0 | WRITE_UVLC(picHeader->virtualBoundariesPosX[i] >> 3, "ph_virtual_boundaries_pos_x"); |
1430 | 0 | } |
1431 | 0 | WRITE_CODE(picHeader->numHorVirtualBoundaries, 2, "ph_num_hor_virtual_boundaries"); |
1432 | 0 | for( unsigned i = 0; i < picHeader->numHorVirtualBoundaries; i++ ) |
1433 | 0 | { |
1434 | 0 | WRITE_UVLC(picHeader->virtualBoundariesPosY[i]>>3, "ph_virtual_boundaries_pos_y"); |
1435 | 0 | } |
1436 | 0 | } |
1437 | 0 | } |
1438 | | |
1439 | | // picture output flag |
1440 | 0 | if( pps->outputFlagPresent && !picHeader->nonRefPic) |
1441 | 0 | { |
1442 | 0 | WRITE_FLAG( picHeader->picOutputFlag, "ph_pic_output_flag" ); |
1443 | 0 | } |
1444 | | |
1445 | | // reference picture lists |
1446 | 0 | if (pps->rplInfoInPh) |
1447 | 0 | { |
1448 | | // List0 and List1 |
1449 | 0 | for(int listIdx = 0; listIdx < 2; listIdx++) |
1450 | 0 | { |
1451 | 0 | if(sps->getNumRPL(listIdx) > 0 && |
1452 | 0 | (listIdx == 0 || (listIdx == 1 && pps->rpl1IdxPresent))) |
1453 | 0 | { |
1454 | 0 | WRITE_FLAG(picHeader->rplIdx[listIdx] != -1 ? 1 : 0, "pic_rpl_sps_flag[i]"); |
1455 | 0 | } |
1456 | 0 | else if(sps->getNumRPL(listIdx) == 0) |
1457 | 0 | { |
1458 | 0 | CHECK(picHeader->rplIdx[listIdx] != -1, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected"); |
1459 | 0 | } |
1460 | 0 | else if(listIdx == 1) |
1461 | 0 | { |
1462 | 0 | auto rplsSpsFlag0 = picHeader->rplIdx[0] != -1 ? 1 : 0; |
1463 | 0 | auto rplsSpsFlag1 = picHeader->rplIdx[1] != -1 ? 1 : 0; |
1464 | 0 | CHECK(rplsSpsFlag1 != rplsSpsFlag0, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected"); |
1465 | 0 | } |
1466 | | |
1467 | 0 | if(picHeader->rplIdx[listIdx] != -1) |
1468 | 0 | { |
1469 | 0 | if(sps->getNumRPL(listIdx) > 1 && |
1470 | 0 | (listIdx == 0 || (listIdx == 1 && pps->rpl1IdxPresent))) |
1471 | 0 | { |
1472 | 0 | int numBits = ceilLog2(sps->getNumRPL( listIdx )); |
1473 | 0 | WRITE_CODE(picHeader->rplIdx[listIdx], numBits, "pic_rpl_idx[i]"); |
1474 | 0 | } |
1475 | 0 | else if(sps->getNumRPL(listIdx) == 1) |
1476 | 0 | { |
1477 | 0 | CHECK(picHeader->rplIdx[listIdx] != 0, "RPL1Idx is not signalled but it is not equal to 0"); |
1478 | 0 | } |
1479 | 0 | else |
1480 | 0 | { |
1481 | 0 | CHECK(picHeader->rplIdx[1] != picHeader->rplIdx[0], "RPL1Idx is not signalled but it is not the same as RPL0Idx"); |
1482 | 0 | } |
1483 | 0 | } |
1484 | | // explicit RPL in picture header |
1485 | 0 | else |
1486 | 0 | { |
1487 | 0 | xCodeRefPicList( picHeader->pRPL[listIdx], sps->longTermRefsPresent, sps->bitsForPOC, !(sps->weightPred||sps->weightedBiPred), -1 ); |
1488 | 0 | } |
1489 | | |
1490 | | // POC MSB cycle signalling for LTRP |
1491 | 0 | if (picHeader->pRPL[listIdx]->numberOfLongtermPictures) |
1492 | 0 | { |
1493 | 0 | for (int i = 0; i < picHeader->pRPL[listIdx]->numberOfLongtermPictures + picHeader->pRPL[listIdx]->numberOfShorttermPictures; i++) |
1494 | 0 | { |
1495 | 0 | if (picHeader->pRPL[listIdx]->isLongtermRefPic[i]) |
1496 | 0 | { |
1497 | 0 | if (picHeader->pRPL[listIdx]->ltrpInSliceHeader) |
1498 | 0 | { |
1499 | 0 | WRITE_CODE(picHeader->pRPL[listIdx]->refPicIdentifier[i], sps->bitsForPOC, |
1500 | 0 | "pic_poc_lsb_lt[listIdx][rplsIdx][j]"); |
1501 | 0 | } |
1502 | 0 | WRITE_FLAG(picHeader->pRPL[listIdx]->deltaPocMSBPresent[i], "pic_delta_poc_msb_present_flag[i][j]"); |
1503 | 0 | if (picHeader->pRPL[listIdx]->deltaPocMSBPresent[i]) |
1504 | 0 | { |
1505 | 0 | WRITE_UVLC(picHeader->pRPL[listIdx]->deltaPocMSBCycleLT[i], "pic_delta_poc_msb_cycle_lt[i][j]"); |
1506 | 0 | } |
1507 | 0 | } |
1508 | 0 | } |
1509 | 0 | } |
1510 | 0 | } |
1511 | 0 | } |
1512 | | |
1513 | | // partitioning constraint overrides |
1514 | 0 | if (sps->partitionOverrideEnabled ) |
1515 | 0 | { |
1516 | 0 | WRITE_FLAG(picHeader->splitConsOverride, "partition_constraints_override_flag"); |
1517 | 0 | } |
1518 | | |
1519 | | // Q0781, two-flags |
1520 | 0 | if (picHeader->picIntraSliceAllowed) |
1521 | 0 | { |
1522 | 0 | if (picHeader->splitConsOverride) |
1523 | 0 | { |
1524 | 0 | WRITE_UVLC(floorLog2(picHeader->minQTSize[0]) - sps->log2MinCodingBlockSize, "pic_log2_diff_min_qt_min_cb_intra_slice_luma"); |
1525 | 0 | WRITE_UVLC(picHeader->maxMTTDepth[0], "ph_max_mtt_hierarchy_depth_intra_slice_luma"); |
1526 | 0 | if (picHeader->maxMTTDepth[0] != 0) |
1527 | 0 | { |
1528 | 0 | WRITE_UVLC(floorLog2(picHeader->maxBTSize[0]) - floorLog2(picHeader->minQTSize[0]), "ph_log2_diff_max_bt_min_qt_intra_slice_luma"); |
1529 | 0 | WRITE_UVLC(floorLog2(picHeader->maxTTSize[0]) - floorLog2(picHeader->minQTSize[0]), "ph_log2_diff_max_tt_min_qt_intra_slice_luma"); |
1530 | 0 | } |
1531 | |
|
1532 | 0 | if (sps->dualITree) |
1533 | 0 | { |
1534 | 0 | WRITE_UVLC(floorLog2(picHeader->minQTSize[2]) - sps->log2MinCodingBlockSize, "ph_log2_diff_min_qt_min_cb_intra_slice_chroma"); |
1535 | 0 | WRITE_UVLC(picHeader->maxMTTDepth[2], "ph_max_mtt_hierarchy_depth_intra_slice_chroma"); |
1536 | 0 | if (picHeader->maxMTTDepth[2] != 0) |
1537 | 0 | { |
1538 | 0 | WRITE_UVLC(floorLog2(picHeader->maxBTSize[2]) - floorLog2(picHeader->minQTSize[2]), "ph_log2_diff_max_bt_min_qt_intra_slice_chroma"); |
1539 | 0 | WRITE_UVLC(floorLog2(picHeader->maxTTSize[2]) - floorLog2(picHeader->minQTSize[2]), "ph_log2_diff_max_tt_min_qt_intra_slice_chroma"); |
1540 | 0 | } |
1541 | 0 | } |
1542 | 0 | } |
1543 | 0 | } |
1544 | 0 | if (picHeader->picIntraSliceAllowed ) |
1545 | 0 | { |
1546 | | // delta quantization and chrom and chroma offset |
1547 | 0 | if (pps->useDQP) |
1548 | 0 | { |
1549 | 0 | WRITE_UVLC( picHeader->cuQpDeltaSubdivIntra, "ph_cu_qp_delta_subdiv_intra_slice" ); |
1550 | 0 | } |
1551 | 0 | if (pps->chromaQpOffsetListLen ) |
1552 | 0 | { |
1553 | 0 | WRITE_UVLC( picHeader->cuChromaQpOffsetSubdivIntra, "ph_cu_chroma_qp_offset_subdiv_intra_slice" ); |
1554 | 0 | } |
1555 | 0 | } |
1556 | |
|
1557 | 0 | if (picHeader->picInterSliceAllowed ) |
1558 | 0 | { |
1559 | 0 | if (picHeader->splitConsOverride ) |
1560 | 0 | { |
1561 | 0 | WRITE_UVLC(floorLog2(picHeader->minQTSize[1]) - sps->log2MinCodingBlockSize, "ph_log2_diff_min_qt_min_cb_inter_slice"); |
1562 | 0 | WRITE_UVLC(picHeader->maxMTTDepth[1], "ph_max_mtt_hierarchy_depth_inter_slice"); |
1563 | 0 | if (picHeader->maxMTTDepth[1] != 0) |
1564 | 0 | { |
1565 | 0 | WRITE_UVLC(floorLog2(picHeader->maxBTSize[1]) - floorLog2(picHeader->minQTSize[1]), "ph_log2_diff_max_bt_min_qt_inter_slice"); |
1566 | 0 | WRITE_UVLC(floorLog2(picHeader->maxTTSize[1]) - floorLog2(picHeader->minQTSize[1]), "ph_log2_diff_max_tt_min_qt_inter_slice"); |
1567 | 0 | } |
1568 | 0 | } |
1569 | | |
1570 | | // delta quantization and chrom and chroma offset |
1571 | 0 | if (pps->useDQP) |
1572 | 0 | { |
1573 | 0 | WRITE_UVLC(picHeader->cuQpDeltaSubdivInter, "ph_cu_qp_delta_subdiv_inter_slice"); |
1574 | 0 | } |
1575 | |
|
1576 | 0 | if (pps->chromaQpOffsetListLen ) |
1577 | 0 | { |
1578 | 0 | WRITE_UVLC(picHeader->cuChromaQpOffsetSubdivInter, "ph_cu_chroma_qp_offset_subdiv_inter_slice"); |
1579 | 0 | } |
1580 | | |
1581 | | // temporal motion vector prediction |
1582 | 0 | if (sps->temporalMVPEnabled) |
1583 | 0 | { |
1584 | 0 | WRITE_FLAG( picHeader->enableTMVP, "ph_temporal_mvp_enabled_flag" ); |
1585 | 0 | if (picHeader->enableTMVP && pps->rplInfoInPh) |
1586 | 0 | { |
1587 | 0 | if (picHeader->pRPL[1]->getNumRefEntries() > 0) |
1588 | 0 | { |
1589 | 0 | WRITE_CODE(picHeader->picColFromL0, 1, "ph_collocated_from_l0_flag"); |
1590 | 0 | } |
1591 | 0 | if ((picHeader->picColFromL0 && picHeader->pRPL[0]->getNumRefEntries() > 1) || |
1592 | 0 | (!picHeader->picColFromL0 && picHeader->pRPL[1]->getNumRefEntries() > 1)) |
1593 | 0 | { |
1594 | 0 | WRITE_UVLC(picHeader->colRefIdx, "ph_collocated_ref_idx"); |
1595 | 0 | } |
1596 | 0 | } |
1597 | 0 | } |
1598 | | |
1599 | | // full-pel MMVD flag |
1600 | 0 | if (sps->fpelMmvd ) |
1601 | 0 | { |
1602 | 0 | WRITE_FLAG( picHeader->disFracMMVD, "ph_fpel_mmvd_enabled_flag" ); |
1603 | 0 | } |
1604 | | // mvd L1 zero flag |
1605 | 0 | if (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0) |
1606 | 0 | { |
1607 | 0 | WRITE_FLAG(picHeader->mvdL1Zero, "ph_mvd_l1_zero_flag"); |
1608 | 0 | } |
1609 | | |
1610 | | // picture level BDOF disable flags |
1611 | 0 | if (sps->BdofPresent && (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0)) |
1612 | 0 | { |
1613 | 0 | WRITE_FLAG(picHeader->disBdofFlag, "ph_disable_bdof_flag"); |
1614 | 0 | } |
1615 | | |
1616 | | // picture level DMVR disable flags |
1617 | 0 | if (sps->DmvrPresent && (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0)) |
1618 | 0 | { |
1619 | 0 | WRITE_FLAG(picHeader->disDmvrFlag, "ph_disable_dmvr_flag"); |
1620 | 0 | } |
1621 | | |
1622 | | // picture level PROF disable flags |
1623 | 0 | if (sps->ProfPresent) |
1624 | 0 | { |
1625 | 0 | WRITE_FLAG(picHeader->disProfFlag, "ph_disable_prof_flag"); |
1626 | 0 | } |
1627 | |
|
1628 | 0 | if ((pps->weightPred || pps->weightedBiPred) && pps->wpInfoInPh ) |
1629 | 0 | { |
1630 | 0 | xCodePredWeightTable(picHeader, pps, sps); |
1631 | 0 | } |
1632 | 0 | } |
1633 | |
|
1634 | 0 | if (pps->qpDeltaInfoInPh) |
1635 | 0 | { |
1636 | 0 | WRITE_SVLC(picHeader->qpDelta, "ph_qp_delta"); |
1637 | 0 | } |
1638 | | |
1639 | | // joint Cb/Cr sign flag |
1640 | 0 | if (sps->jointCbCr ) |
1641 | 0 | { |
1642 | 0 | WRITE_FLAG( picHeader->jointCbCrSign, "ph_joint_cbcr_sign_flag" ); |
1643 | 0 | } |
1644 | | |
1645 | | // sao enable flags |
1646 | 0 | if(sps->saoEnabled) |
1647 | 0 | { |
1648 | 0 | if (pps->saoInfoInPh) |
1649 | 0 | { |
1650 | 0 | WRITE_FLAG(picHeader->saoEnabled[CH_L], "ph_sao_luma_enabled_flag"); |
1651 | 0 | if (sps->chromaFormatIdc != CHROMA_400) |
1652 | 0 | { |
1653 | 0 | WRITE_FLAG(picHeader->saoEnabled[CH_C], "ph_sao_chroma_enabled_flag"); |
1654 | 0 | } |
1655 | 0 | } |
1656 | 0 | } |
1657 | | |
1658 | | // deblocking filter controls |
1659 | 0 | if (pps->deblockingFilterControlPresent ) |
1660 | 0 | { |
1661 | 0 | if(pps->deblockingFilterOverrideEnabled) |
1662 | 0 | { |
1663 | 0 | if (pps->dbfInfoInPh) |
1664 | 0 | { |
1665 | 0 | WRITE_FLAG ( picHeader->deblockingFilterOverride, "ph_deblocking_filter_override_flag" ); |
1666 | | |
1667 | 0 | if(picHeader->deblockingFilterOverride) |
1668 | 0 | { |
1669 | 0 | WRITE_FLAG( picHeader->deblockingFilterDisable, "ph_deblocking_filter_disabled_flag" ); |
1670 | 0 | if( !picHeader->deblockingFilterDisable ) |
1671 | 0 | { |
1672 | 0 | WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Y], "ph_beta_offset_div2" ); |
1673 | 0 | WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Y], "ph_tc_offset_div2" ); |
1674 | 0 | if( pps->usePPSChromaTool ) |
1675 | 0 | { |
1676 | 0 | WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Cb], "ph_cb_beta_offset_div2" ); |
1677 | 0 | WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Cb], "ph_cb_tc_offset_div2" ); |
1678 | 0 | WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Cr], "ph_cr_beta_offset_div2" ); |
1679 | 0 | WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Cr], "ph_cr_tc_offset_div2" ); |
1680 | 0 | } |
1681 | 0 | } |
1682 | 0 | } |
1683 | 0 | } |
1684 | 0 | } |
1685 | 0 | } |
1686 | | |
1687 | | // picture header extension |
1688 | 0 | if(pps->pictureHeaderExtensionPresent) |
1689 | 0 | { |
1690 | 0 | WRITE_UVLC(0,"ph_extension_length"); |
1691 | 0 | } |
1692 | |
|
1693 | 0 | if ( writeRbspTrailingBits ) |
1694 | 0 | { |
1695 | 0 | xWriteRbspTrailingBits(); |
1696 | 0 | } |
1697 | 0 | } |
1698 | | |
1699 | | |
1700 | | void HLSWriter::codeSliceHeader( const Slice* slice ) |
1701 | 0 | { |
1702 | 0 | DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" ); |
1703 | |
|
1704 | 0 | CodingStructure& cs = *slice->pic->cs; |
1705 | 0 | const PicHeader *picHeader = cs.picHeader; |
1706 | 0 | const ChromaFormat format = slice->sps->chromaFormatIdc; |
1707 | 0 | const uint32_t numberValidComponents = getNumberValidComponents(format); |
1708 | 0 | const bool chromaEnabled = isChromaEnabled(format); |
1709 | |
|
1710 | 0 | WRITE_FLAG(slice->pictureHeaderInSliceHeader, "sh_picture_header_in_slice_header_flag"); |
1711 | 0 | if(slice->pictureHeaderInSliceHeader) |
1712 | 0 | { |
1713 | 0 | codePictureHeader(picHeader, false); |
1714 | 0 | } |
1715 | |
|
1716 | 0 | if (slice->sps->subPicInfoPresent) |
1717 | 0 | { |
1718 | 0 | uint32_t bitsSubPicId; |
1719 | 0 | if (slice->sps->subPicIdMappingExplicitlySignalled) |
1720 | 0 | { |
1721 | 0 | bitsSubPicId = slice->sps->subPicIdLen; |
1722 | 0 | } |
1723 | 0 | else if (slice->pps->subPicIdMappingInPps) |
1724 | 0 | { |
1725 | 0 | bitsSubPicId = slice->pps->subPicIdLen; |
1726 | 0 | } |
1727 | 0 | else |
1728 | 0 | { |
1729 | 0 | bitsSubPicId = ceilLog2(slice->sps->numSubPics); |
1730 | 0 | } |
1731 | 0 | WRITE_CODE(slice->sliceSubPicId, bitsSubPicId, "sh_subpic_id"); |
1732 | 0 | } |
1733 | |
|
1734 | 0 | if (!slice->pps->rectSlice) |
1735 | 0 | { |
1736 | 0 | THROW("no suppport"); |
1737 | 0 | } |
1738 | 0 | else |
1739 | 0 | { |
1740 | | // slice address is the index of the slice within the current sub-picture |
1741 | 0 | uint32_t currSubPicIdx = slice->pps->getSubPicIdxFromSubPicId( slice->sliceSubPicId ); |
1742 | 0 | SubPic currSubPic = slice->pps->subPics[currSubPicIdx]; |
1743 | 0 | if( currSubPic.numSlicesInSubPic > 1 ) |
1744 | 0 | { |
1745 | 0 | int numSlicesInPreviousSubPics = 0; |
1746 | 0 | for(int sp = 0; sp < currSubPicIdx; sp++) |
1747 | 0 | { |
1748 | 0 | numSlicesInPreviousSubPics += slice->pps->subPics[sp].numSlicesInSubPic; |
1749 | 0 | } |
1750 | 0 | int bitsSliceAddress = ceilLog2(currSubPic.numSlicesInSubPic); |
1751 | 0 | WRITE_CODE( slice->sliceMap.sliceID - numSlicesInPreviousSubPics, bitsSliceAddress, "sh_slice_address"); |
1752 | 0 | } |
1753 | 0 | } |
1754 | | |
1755 | 0 | if (picHeader->picInterSliceAllowed) |
1756 | 0 | { |
1757 | 0 | WRITE_UVLC(slice->sliceType, "sh_slice_type"); |
1758 | 0 | } |
1759 | 0 | if (picHeader->gdrOrIrapPic) //th check this |
1760 | 0 | { |
1761 | 0 | WRITE_FLAG(picHeader->noOutputOfPriorPics, "sh_no_output_of_prior_pics_flag"); |
1762 | 0 | } |
1763 | |
|
1764 | 0 | if (!picHeader->picIntraSliceAllowed ) |
1765 | 0 | { |
1766 | 0 | CHECK(slice->sliceType == VVENC_I_SLICE, "when pic_intra_slice_allowed_flag = 0, no I_Slice is allowed"); |
1767 | 0 | } |
1768 | | |
1769 | 0 | if (slice->sps->alfEnabled && !slice->pps->alfInfoInPh) |
1770 | 0 | { |
1771 | 0 | const int alfEnabled = slice->alfEnabled[COMP_Y]; |
1772 | 0 | WRITE_FLAG(alfEnabled, "sh_alf_enabled_flag"); |
1773 | |
|
1774 | 0 | if (alfEnabled) |
1775 | 0 | { |
1776 | 0 | WRITE_CODE(slice->numAps, 3, "sh_num_alf_aps_ids_luma"); |
1777 | 0 | for (int i = 0; i < slice->numAps; i++) |
1778 | 0 | { |
1779 | 0 | WRITE_CODE(slice->lumaApsId[i], 3, "sh_alf_aps_id_luma"); |
1780 | 0 | } |
1781 | |
|
1782 | 0 | const int alfChromaIdc = slice->alfEnabled[COMP_Cb] + slice->alfEnabled[COMP_Cr] * 2; |
1783 | 0 | if (chromaEnabled) |
1784 | 0 | { |
1785 | 0 | WRITE_FLAG(slice->alfEnabled[COMP_Cb], "sh_alf_cb_enabled_flag"); |
1786 | 0 | WRITE_FLAG(slice->alfEnabled[COMP_Cr], "sh_alf_cr_enabled_flag"); |
1787 | 0 | } |
1788 | 0 | if (alfChromaIdc) |
1789 | 0 | { |
1790 | 0 | WRITE_CODE(slice->chromaApsId, 3, "sh_alf_aps_id_chroma"); |
1791 | 0 | } |
1792 | |
|
1793 | 0 | if (slice->sps->ccalfEnabled) |
1794 | 0 | { |
1795 | 0 | WRITE_FLAG(slice->ccAlfCbEnabled, "sh_cc_alf_cb_enabled_flag"); |
1796 | 0 | if( slice->ccAlfCbEnabled ) |
1797 | 0 | { |
1798 | | // write CC ALF Cb APS ID |
1799 | 0 | WRITE_CODE(slice->ccAlfCbApsId, 3, "sh_cc_alf_cb_aps_id"); |
1800 | 0 | } |
1801 | | // Cr |
1802 | 0 | WRITE_FLAG(slice->ccAlfCrEnabled, "sh_cc_alf_cr_enabled_flag"); |
1803 | 0 | if( slice->ccAlfCrEnabled ) |
1804 | 0 | { |
1805 | | // write CC ALF Cr APS ID |
1806 | 0 | WRITE_CODE(slice->ccAlfCrApsId, 3, "sh_cc_alf_cr_aps_id"); |
1807 | 0 | } |
1808 | 0 | } |
1809 | 0 | } |
1810 | 0 | } |
1811 | |
|
1812 | 0 | if (picHeader->lmcsEnabled && !slice->pictureHeaderInSliceHeader) |
1813 | 0 | { |
1814 | 0 | WRITE_FLAG( slice->lmcsEnabled, "sh_lmcs_enabled_flag"); |
1815 | 0 | } |
1816 | 0 | if (picHeader->explicitScalingListEnabled && !slice->pictureHeaderInSliceHeader) |
1817 | 0 | { |
1818 | 0 | WRITE_FLAG(slice->explicitScalingListUsed, "sh_explicit_scaling_list_used_flag"); |
1819 | 0 | } |
1820 | |
|
1821 | 0 | if( !slice->pps->rplInfoInPh && (!slice->getIdrPicFlag() || slice->sps->idrRefParamList)) |
1822 | 0 | { |
1823 | 0 | int numRPL0 = slice->sps->getNumRPL(0); |
1824 | | //Write L0 related syntax elements |
1825 | 0 | if (numRPL0 > 0) |
1826 | 0 | { |
1827 | 0 | WRITE_FLAG(slice->rplIdx[0] != -1, "ref_pic_list_sps_flag[0]"); |
1828 | 0 | } |
1829 | 0 | if (slice->rplIdx[0] != -1) |
1830 | 0 | { |
1831 | 0 | if (numRPL0 > 1) |
1832 | 0 | { |
1833 | 0 | int numBits = 0; |
1834 | 0 | while ((1 << numBits) < numRPL0) |
1835 | 0 | { |
1836 | 0 | numBits++; |
1837 | 0 | } |
1838 | 0 | WRITE_CODE(slice->rplIdx[0], numBits, "ref_pic_list_idx[0]"); |
1839 | 0 | } |
1840 | 0 | } |
1841 | 0 | else |
1842 | 0 | { //write local RPL0 |
1843 | 0 | xCodeRefPicList( slice->rpl[0], slice->sps->longTermRefsPresent, slice->sps->bitsForPOC, !slice->sps->weightPred && !slice->sps->weightedBiPred, -1 ); |
1844 | 0 | } |
1845 | | //Deal POC Msb cycle signalling for LTRP |
1846 | 0 | if (slice->rpl[0]->numberOfLongtermPictures) |
1847 | 0 | { |
1848 | 0 | for (int i = 0; i < slice->rpl[0]->numberOfLongtermPictures + slice->rpl[0]->numberOfShorttermPictures; i++) |
1849 | 0 | { |
1850 | 0 | if (slice->rpl[0]->isLongtermRefPic[i]) |
1851 | 0 | { |
1852 | 0 | if (slice->rpl[0]->ltrpInSliceHeader) |
1853 | 0 | { |
1854 | 0 | WRITE_CODE(slice->rpl[0]->refPicIdentifier[i], slice->sps->bitsForPOC, "slice_poc_lsb_lt[listIdx][rplsIdx][j]"); |
1855 | 0 | } |
1856 | 0 | WRITE_FLAG(slice->rpl[0]->deltaPocMSBPresent[i], "delta_poc_msb_present_flag[i][j]"); |
1857 | 0 | if (slice->rpl[0]->deltaPocMSBPresent[i]) |
1858 | 0 | { |
1859 | 0 | WRITE_UVLC(slice->rpl[0]->deltaPocMSBCycleLT[i], "delta_poc_msb_cycle_lt[i][j]"); |
1860 | 0 | } |
1861 | 0 | } |
1862 | 0 | } |
1863 | 0 | } |
1864 | | |
1865 | | //Write L1 related syntax elements |
1866 | 0 | if (slice->sps->getNumRPL(1) > 1 && slice->pps->rpl1IdxPresent) |
1867 | 0 | { |
1868 | 0 | WRITE_FLAG(slice->rplIdx[1] != -1 ? 1 : 0, "ref_pic_list_sps_flag[1]"); |
1869 | 0 | } |
1870 | 0 | else if (slice->sps->getNumRPL(1) == 0) |
1871 | 0 | { |
1872 | 0 | CHECK(slice->rplIdx[1] != -1, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected"); |
1873 | 0 | } |
1874 | 0 | else |
1875 | 0 | { |
1876 | 0 | auto rplsSpsFlag0 = slice->rplIdx[0] != -1 ? 1 : 0; |
1877 | 0 | auto rplsSpsFlag1 = slice->rplIdx[1] != -1 ? 1 : 0; |
1878 | 0 | CHECK(rplsSpsFlag1 != rplsSpsFlag0, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected"); |
1879 | 0 | } |
1880 | | |
1881 | 0 | if (slice->rplIdx[1] != -1) |
1882 | 0 | { |
1883 | 0 | if (slice->sps->getNumRPL(1) > 1 && slice->pps->rpl1IdxPresent) |
1884 | 0 | { |
1885 | 0 | int numBits = 0; |
1886 | 0 | while ((1 << numBits) < slice->sps->getNumRPL(1)) |
1887 | 0 | { |
1888 | 0 | numBits++; |
1889 | 0 | } |
1890 | 0 | WRITE_CODE(slice->rplIdx[1], numBits, "ref_pic_list_idx[1]"); |
1891 | 0 | } |
1892 | 0 | else if (slice->sps->getNumRPL(1) == 1) |
1893 | 0 | { |
1894 | 0 | CHECK(slice->rplIdx[1] != 0, "RPL1Idx is not signalled but it is not equal to 0"); |
1895 | 0 | } |
1896 | 0 | else |
1897 | 0 | { |
1898 | 0 | CHECK(slice->rplIdx[1] != slice->rplIdx[0], "RPL1Idx is not signalled but it is not the same as RPL0Idx"); |
1899 | 0 | } |
1900 | 0 | } |
1901 | 0 | else |
1902 | 0 | { //write local RPL1 |
1903 | 0 | xCodeRefPicList( slice->rpl[1], slice->sps->longTermRefsPresent, slice->sps->bitsForPOC, !(slice->sps->weightPred || slice->sps->weightedBiPred), -1 ); |
1904 | 0 | } |
1905 | | //Deal POC Msb cycle signalling for LTRP |
1906 | 0 | if (slice->rpl[1]->numberOfLongtermPictures) |
1907 | 0 | { |
1908 | 0 | for (int i = 0; i < slice->rpl[1]->numberOfLongtermPictures + slice->rpl[1]->numberOfShorttermPictures; i++) |
1909 | 0 | { |
1910 | 0 | if (slice->rpl[1]->isLongtermRefPic[i]) |
1911 | 0 | { |
1912 | 0 | if (slice->rpl[1]->ltrpInSliceHeader) |
1913 | 0 | { |
1914 | 0 | WRITE_CODE(slice->rpl[1]->refPicIdentifier[i], slice->sps->bitsForPOC, |
1915 | 0 | "slice_poc_lsb_lt[listIdx][rplsIdx][j]"); |
1916 | 0 | } |
1917 | 0 | WRITE_FLAG(slice->rpl[1]->deltaPocMSBPresent[i], "delta_poc_msb_present_flag[i][j]"); |
1918 | 0 | if (slice->rpl[1]->deltaPocMSBPresent[i]) |
1919 | 0 | { |
1920 | 0 | WRITE_UVLC(slice->rpl[1]->deltaPocMSBCycleLT[i], "delta_poc_msb_cycle_lt[i][j]"); |
1921 | 0 | } |
1922 | 0 | } |
1923 | 0 | } |
1924 | 0 | } |
1925 | 0 | } |
1926 | | |
1927 | | //check if numrefidxes match the defaults. If not, override |
1928 | | |
1929 | 0 | if ((!slice->isIntra() && slice->rpl[0]->getNumRefEntries() > 1) || |
1930 | 0 | (slice->isInterB() && slice->rpl[1]->getNumRefEntries() > 1) ) |
1931 | 0 | { |
1932 | 0 | int defaultL0 = std::min<int>(slice->rpl[0]->getNumRefEntries(), slice->pps->numRefIdxL0DefaultActive); |
1933 | 0 | int defaultL1 = slice->isInterB() ? std::min<int>(slice->rpl[1]->getNumRefEntries(), slice->pps->numRefIdxL1DefaultActive) : 0; |
1934 | 0 | bool overrideFlag = ( slice->numRefIdx[ REF_PIC_LIST_0 ] != defaultL0 || ( slice->isInterB() && slice->numRefIdx[ REF_PIC_LIST_1 ] != defaultL1 ) ); |
1935 | 0 | WRITE_FLAG( overrideFlag ? 1 : 0, "num_ref_idx_active_override_flag" ); |
1936 | 0 | if( overrideFlag ) |
1937 | 0 | { |
1938 | 0 | if(slice->rpl[0]->getNumRefEntries() > 1) |
1939 | 0 | { |
1940 | 0 | WRITE_UVLC( slice->numRefIdx[ REF_PIC_LIST_0 ] - 1, "num_ref_idx_l0_active_minus1" ); |
1941 | 0 | } |
1942 | |
|
1943 | 0 | if( slice->isInterB() && slice->rpl[1]->getNumRefEntries() > 1) |
1944 | 0 | { |
1945 | 0 | WRITE_UVLC( slice->numRefIdx[ REF_PIC_LIST_1 ] - 1, "num_ref_idx_l1_active_minus1" ); |
1946 | 0 | } |
1947 | 0 | } |
1948 | 0 | } |
1949 | |
|
1950 | 0 | if( !slice->isIntra() ) |
1951 | 0 | { |
1952 | 0 | if( !slice->isIntra() && slice->pps->cabacInitPresent ) |
1953 | 0 | { |
1954 | 0 | const SliceType encCABACTableIdx = slice->encCABACTableIdx; |
1955 | 0 | bool encCabacInitFlag = ( slice->sliceType != encCABACTableIdx && encCABACTableIdx != VVENC_I_SLICE ) ? true : false; |
1956 | 0 | WRITE_FLAG( encCabacInitFlag ? 1 : 0, "sh_cabac_init_flag" ); |
1957 | 0 | } |
1958 | 0 | } |
1959 | |
|
1960 | 0 | if( slice->picHeader->enableTMVP && !slice->pps->rplInfoInPh) |
1961 | 0 | { |
1962 | 0 | if(!slice->pps->rplInfoInPh) |
1963 | 0 | { |
1964 | 0 | if (slice->sliceType == VVENC_B_SLICE) |
1965 | 0 | { |
1966 | 0 | WRITE_FLAG(slice->colFromL0Flag, "sh_collocated_from_l0_flag"); |
1967 | 0 | } |
1968 | 0 | } |
1969 | |
|
1970 | 0 | if( slice->sliceType != VVENC_I_SLICE && |
1971 | 0 | ( ( slice->colFromL0Flag == 1 && slice->numRefIdx[ REF_PIC_LIST_0 ] > 1 ) || |
1972 | 0 | ( slice->colFromL0Flag == 0 && slice->numRefIdx[ REF_PIC_LIST_1 ] > 1 ) ) ) |
1973 | 0 | { |
1974 | 0 | WRITE_UVLC( slice->colRefIdx, "sh_collocated_ref_idx" ); |
1975 | 0 | } |
1976 | 0 | } |
1977 | |
|
1978 | 0 | if( ( slice->pps->weightPred && slice->sliceType == VVENC_P_SLICE ) || ( slice->pps->weightedBiPred && slice->sliceType == VVENC_B_SLICE ) ) |
1979 | 0 | { |
1980 | 0 | if( !slice->pps->wpInfoInPh ) |
1981 | 0 | { |
1982 | 0 | xCodePredWeightTable( slice ); |
1983 | 0 | } |
1984 | 0 | } |
1985 | |
|
1986 | 0 | if (!slice->pps->qpDeltaInfoInPh) |
1987 | 0 | { |
1988 | 0 | WRITE_SVLC(slice->sliceQp - (slice->pps->picInitQPMinus26 + 26), "slice_qp_delta"); |
1989 | 0 | } |
1990 | 0 | if (slice->pps->sliceChromaQpFlag) |
1991 | 0 | { |
1992 | 0 | if (numberValidComponents > COMP_Cb) |
1993 | 0 | { |
1994 | 0 | WRITE_SVLC( slice->sliceChromaQpDelta[COMP_Cb], "sh_cb_qp_offset" ); |
1995 | 0 | } |
1996 | 0 | if (numberValidComponents > COMP_Cr) |
1997 | 0 | { |
1998 | 0 | WRITE_SVLC( slice->sliceChromaQpDelta[COMP_Cr], "sh_cr_qp_offset" ); |
1999 | 0 | if (slice->sps->jointCbCr) |
2000 | 0 | { |
2001 | 0 | WRITE_SVLC( slice->sliceChromaQpDelta[COMP_JOINT_CbCr], "sh_joint_cbcr_qp_offset"); |
2002 | 0 | } |
2003 | 0 | } |
2004 | 0 | CHECK(numberValidComponents < COMP_Cr+1, "Too many valid components"); |
2005 | 0 | } |
2006 | | |
2007 | 0 | if (slice->pps->chromaQpOffsetListLen>0) |
2008 | 0 | { |
2009 | 0 | WRITE_FLAG(slice->chromaQpAdjEnabled, "sh_cu_chroma_qp_offset_enabled_flag"); |
2010 | 0 | } |
2011 | |
|
2012 | 0 | if( slice->sps->saoEnabled && !slice->pps->saoInfoInPh ) |
2013 | 0 | { |
2014 | 0 | WRITE_FLAG( slice->saoEnabled[CH_L], "sh_sao_luma_flag" ); |
2015 | 0 | if( chromaEnabled ) |
2016 | 0 | { |
2017 | 0 | WRITE_FLAG( slice->saoEnabled[CH_C], "sh_sao_chroma_flag" ); |
2018 | 0 | } |
2019 | 0 | } |
2020 | | |
2021 | |
|
2022 | 0 | if (slice->pps->deblockingFilterControlPresent && !slice->pps->dbfInfoInPh) |
2023 | 0 | { |
2024 | 0 | if (slice->pps->deblockingFilterOverrideEnabled ) |
2025 | 0 | { |
2026 | 0 | WRITE_FLAG(slice->deblockingFilterOverride, "sh_deblocking_params_present_flag"); |
2027 | 0 | } |
2028 | 0 | if (slice->deblockingFilterOverride) |
2029 | 0 | { |
2030 | 0 | if (!slice->pps->deblockingFilterDisabled) |
2031 | 0 | { |
2032 | 0 | WRITE_FLAG(slice->deblockingFilterDisable, "sh_deblocking_filter_disabled_flag"); |
2033 | 0 | } |
2034 | 0 | if(!slice->deblockingFilterDisable) |
2035 | 0 | { |
2036 | 0 | WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Y], "slice_beta_offset_div2"); |
2037 | 0 | WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Y], "slice_tc_offset_div2"); |
2038 | 0 | if( slice->pps->usePPSChromaTool ) |
2039 | 0 | { |
2040 | 0 | WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Cb], "slice_cb_beta_offset_div2"); |
2041 | 0 | WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Cb], "slice_cb_tc_offset_div2"); |
2042 | 0 | WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Cr], "slice_cr_beta_offset_div2"); |
2043 | 0 | WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Cr], "slice_cr_tc_offset_div2"); |
2044 | 0 | } |
2045 | 0 | } |
2046 | 0 | } |
2047 | 0 | } |
2048 | | |
2049 | | // dependent quantization |
2050 | 0 | if( slice->sps->depQuantEnabled ) |
2051 | 0 | { |
2052 | 0 | WRITE_FLAG(slice->depQuantEnabled, "sh_dep_quant_used_flag"); |
2053 | 0 | } |
2054 | | |
2055 | | // sign data hiding |
2056 | 0 | if( slice->sps->signDataHidingEnabled && !slice->depQuantEnabled ) |
2057 | 0 | { |
2058 | 0 | WRITE_FLAG(slice->signDataHidingEnabled, "sh_sign_data_hiding_used_flag" ); |
2059 | 0 | } |
2060 | 0 | if( slice->sps->transformSkip && !slice->depQuantEnabled && !slice->signDataHidingEnabled ) |
2061 | 0 | { |
2062 | 0 | WRITE_FLAG(slice->tsResidualCodingDisabled, "sh_ts_residual_coding_disabled_flag"); |
2063 | 0 | } |
2064 | |
|
2065 | 0 | if(slice->pps->sliceHeaderExtensionPresent) |
2066 | 0 | { |
2067 | 0 | WRITE_UVLC(0,"slice_header_extension_length"); |
2068 | 0 | } |
2069 | 0 | } |
2070 | | |
2071 | | void HLSWriter::codeConstraintInfo ( const ConstraintInfo* cinfo ) |
2072 | 0 | { |
2073 | 0 | WRITE_FLAG(cinfo->gciPresent, "gci_present_flag"); |
2074 | 0 | if (cinfo->gciPresent) |
2075 | 0 | { |
2076 | 0 | WRITE_FLAG(cinfo->intraOnlyConstraintFlag, "gci_intra_only_constraint_flag"); |
2077 | 0 | WRITE_FLAG(cinfo->allLayersIndependentConstraintFlag, "gci_all_layers_independent_constraint_flag"); |
2078 | 0 | WRITE_FLAG(cinfo->onePictureOnlyConstraintFlag, "gci_one_au_only_constraint_flag"); |
2079 | | |
2080 | | /* picture format */ |
2081 | 0 | WRITE_CODE(16 - cinfo->maxBitDepthConstraintIdc, 4, "gci_sixteen_minus_max_bitdepth_constraint_idc"); |
2082 | 0 | WRITE_CODE(3 - cinfo->maxChromaFormatConstraintIdc, 2, "gci_three_minus_max_chroma_format_constraint_idc"); |
2083 | | |
2084 | | /* NAL unit type related */ |
2085 | 0 | WRITE_FLAG(cinfo->noMixedNaluTypesInPicConstraintFlag, "gci_no_mixed_nalu_types_in_pic_constraint_flag"); |
2086 | 0 | WRITE_FLAG(cinfo->noTrailConstraintFlag, "gci_no_trail_constraint_flag"); |
2087 | 0 | WRITE_FLAG(cinfo->noStsaConstraintFlag, "gci_no_stsa_constraint_flag"); |
2088 | 0 | WRITE_FLAG(cinfo->noRaslConstraintFlag, "gci_no_rasl_constraint_flag"); |
2089 | 0 | WRITE_FLAG(cinfo->noRadlConstraintFlag, "gci_no_radl_constraint_flag"); |
2090 | 0 | WRITE_FLAG(cinfo->noIdrConstraintFlag, "gci_no_idr_constraint_flag"); |
2091 | 0 | WRITE_FLAG(cinfo->noCraConstraintFlag, "gci_no_cra_constraint_flag"); |
2092 | 0 | WRITE_FLAG(cinfo->noGdrConstraintFlag, "gci_no_gdr_constraint_flag"); |
2093 | 0 | WRITE_FLAG(cinfo->noApsConstraintFlag, "gci_no_aps_constraint_flag"); |
2094 | 0 | WRITE_FLAG(cinfo->noIdrRplConstraintFlag, "gci_no_idr_rpl_constraint_flag"); |
2095 | | |
2096 | | /* tile, slice, subpicture partitioning */ |
2097 | 0 | WRITE_FLAG(cinfo->oneTilePerPicConstraintFlag, "gci_one_tile_per_pic_constraint_flag"); |
2098 | 0 | WRITE_FLAG(cinfo->picHeaderInSliceHeaderConstraintFlag, "gci_pic_header_in_slice_header_constraint_flag"); |
2099 | 0 | WRITE_FLAG(cinfo->oneSlicePerPicConstraintFlag, "gci_one_slice_per_pic_constraint_flag"); |
2100 | 0 | WRITE_FLAG(cinfo->noRectSliceConstraintFlag, "gci_no_rectangular_slice_constraint_flag"); |
2101 | 0 | WRITE_FLAG(cinfo->oneSlicePerSubpicConstraintFlag, "gci_one_slice_per_subpic_constraint_flag"); |
2102 | 0 | WRITE_FLAG(cinfo->noSubpicInfoConstraintFlag, "gci_no_subpic_info_constraint_flag"); |
2103 | | |
2104 | | |
2105 | | /* CTU and block partitioning */ |
2106 | 0 | WRITE_CODE(3 - (cinfo->maxLog2CtuSizeConstraintIdc - 5), 2, "gci_three_minus_max_log2_ctu_size_constraint_idc"); |
2107 | 0 | WRITE_FLAG(cinfo->noPartitionConstraintsOverrideConstraintFlag, "gci_no_partition_constraints_override_constraint_flag"); |
2108 | 0 | WRITE_FLAG(cinfo->noMttConstraintFlag, "gci_no_mtt_constraint_flag"); |
2109 | 0 | WRITE_FLAG(cinfo->noQtbttDualTreeIntraConstraintFlag, "gci_no_qtbtt_dual_tree_intra_constraint_flag"); |
2110 | | |
2111 | | /* intra */ |
2112 | 0 | WRITE_FLAG(cinfo->noPaletteConstraintFlag, "gci_no_palette_constraint_flag"); |
2113 | 0 | WRITE_FLAG(cinfo->noIbcConstraintFlag, "gci_no_ibc_constraint_flag"); |
2114 | 0 | WRITE_FLAG(cinfo->noIspConstraintFlag, "gci_no_isp_constraint_flag"); |
2115 | 0 | WRITE_FLAG(cinfo->noMrlConstraintFlag, "gci_no_mrl_constraint_flag"); |
2116 | 0 | WRITE_FLAG(cinfo->noMipConstraintFlag, "gci_no_mip_constraint_flag"); |
2117 | 0 | WRITE_FLAG(cinfo->noCclmConstraintFlag, "gci_no_cclm_constraint_flag"); |
2118 | | |
2119 | | /* inter */ |
2120 | 0 | WRITE_FLAG(cinfo->noRprConstraintFlag, "gci_no_ref_pic_resampling_constraint_flag"); |
2121 | 0 | WRITE_FLAG(cinfo->noResChangeInClvsConstraintFlag, "gci_no_res_change_in_clvs_constraint_flag"); |
2122 | 0 | WRITE_FLAG(cinfo->noWeightedPredictionConstraintFlag, "gci_no_weighted_prediction_constraint_flag"); |
2123 | 0 | WRITE_FLAG(cinfo->noRefWraparoundConstraintFlag, "gci_no_ref_wraparound_constraint_flag"); |
2124 | 0 | WRITE_FLAG(cinfo->noTemporalMvpConstraintFlag, "gci_no_temporal_mvp_constraint_flag"); |
2125 | 0 | WRITE_FLAG(cinfo->noSbtmvpConstraintFlag, "gci_no_sbtmvp_constraint_flag"); |
2126 | 0 | WRITE_FLAG(cinfo->noAmvrConstraintFlag, "gci_no_amvr_constraint_flag"); |
2127 | 0 | WRITE_FLAG(cinfo->noBdofConstraintFlag, "gci_no_bdof_constraint_flag"); |
2128 | 0 | WRITE_FLAG(cinfo->noSmvdConstraintFlag, "gci_no_smvd_constraint_flag"); |
2129 | 0 | WRITE_FLAG(cinfo->noDmvrConstraintFlag, "gci_no_dmvr_constraint_flag"); |
2130 | 0 | WRITE_FLAG(cinfo->noMmvdConstraintFlag, "gci_no_mmvd_constraint_flag"); |
2131 | 0 | WRITE_FLAG(cinfo->noAffineMotionConstraintFlag, "gci_no_affine_motion_constraint_flag"); |
2132 | 0 | WRITE_FLAG(cinfo->noProfConstraintFlag, "gci_no_prof_constraint_flag"); |
2133 | 0 | WRITE_FLAG(cinfo->noBcwConstraintFlag, "gci_no_bcw_constraint_flag"); |
2134 | 0 | WRITE_FLAG(cinfo->noCiipConstraintFlag, "gci_no_ciip_constraint_flag"); |
2135 | 0 | WRITE_FLAG(cinfo->noGeoConstraintFlag, "gci_no_gpm_constraint_flag"); |
2136 | | |
2137 | | /* transform, quantization, residual */ |
2138 | 0 | WRITE_FLAG(cinfo->noLumaTransformSize64ConstraintFlag, "gci_no_luma_transform_size_64_constraint_flag"); |
2139 | 0 | WRITE_FLAG(cinfo->noTransformSkipConstraintFlag, "gci_no_transform_skip_constraint_flag"); |
2140 | 0 | WRITE_FLAG(cinfo->noBDPCMConstraintFlag, "gci_no_bdpcm_constraint_flag"); |
2141 | 0 | WRITE_FLAG(cinfo->noMtsConstraintFlag, "gci_no_mts_constraint_flag"); |
2142 | 0 | WRITE_FLAG(cinfo->noLfnstConstraintFlag, "gci_no_lfnst_constraint_flag"); |
2143 | 0 | WRITE_FLAG(cinfo->noJointCbCrConstraintFlag, "gci_no_joint_cbcr_constraint_flag"); |
2144 | 0 | WRITE_FLAG(cinfo->noSbtConstraintFlag, "gci_no_sbt_constraint_flag"); |
2145 | 0 | WRITE_FLAG(cinfo->noActConstraintFlag, "gci_no_act_constraint_flag"); |
2146 | 0 | WRITE_FLAG(cinfo->noExplicitScaleListConstraintFlag, "gci_no_explicit_scaling_list_constraint_flag"); |
2147 | 0 | WRITE_FLAG(cinfo->noDepQuantConstraintFlag, "gci_no_dep_quant_constraint_flag"); |
2148 | 0 | WRITE_FLAG(cinfo->noSignDataHidingConstraintFlag, "gci_no_sign_data_hiding_constraint_flag"); |
2149 | 0 | WRITE_FLAG(cinfo->noQpDeltaConstraintFlag, "gci_no_qp_delta_constraint_flag"); |
2150 | 0 | WRITE_FLAG(cinfo->noChromaQpOffsetConstraintFlag, "gci_no_chroma_qp_offset_constraint_flag"); |
2151 | | |
2152 | | /* loop filter */ |
2153 | 0 | WRITE_FLAG(cinfo->noSaoConstraintFlag, "gci_no_sao_constraint_flag"); |
2154 | 0 | WRITE_FLAG(cinfo->noAlfConstraintFlag, "gci_no_alf_constraint_flag"); |
2155 | 0 | WRITE_FLAG(cinfo->noCCAlfConstraintFlag, "gci_no_ccalf_constraint_flag"); |
2156 | 0 | WRITE_FLAG(cinfo->noLmcsConstraintFlag, "gci_no_lmcs_constraint_flag"); |
2157 | 0 | WRITE_FLAG(cinfo->noLadfConstraintFlag, "gci_no_ladf_constraint_flag"); |
2158 | 0 | WRITE_FLAG(cinfo->noVirtualBoundaryConstraintFlag, "gci_no_virtual_boundaries_constraint_flag"); |
2159 | | |
2160 | | //The value of gci_num_reserved_bits shall be equal to 0 in bitstreams conforming to this version of this Specification. |
2161 | | //Other values of gci_num_reserved_bits are reserved for future use by ITU-T | ISO/IEC. |
2162 | 0 | WRITE_CODE(0, 8, "gci_num_reserved_bits"); |
2163 | 0 | } |
2164 | |
|
2165 | 0 | while (!isByteAligned()) |
2166 | 0 | { |
2167 | 0 | WRITE_FLAG(0, "gci_alignment_zero_bit"); |
2168 | 0 | } |
2169 | 0 | } |
2170 | | |
2171 | | |
2172 | | void HLSWriter::codeProfileTierLevel ( const ProfileTierLevel* ptl, bool profileTierPresent, int maxNumSubLayersMinus1 ) |
2173 | 0 | { |
2174 | 0 | if(profileTierPresent) |
2175 | 0 | { |
2176 | 0 | WRITE_CODE( (uint32_t)ptl->profileIdc, 7 , "general_profile_idc" ); |
2177 | 0 | WRITE_FLAG( ptl->tierFlag==vvencTier::VVENC_TIER_HIGH, "general_tier_flag" ); |
2178 | 0 | } |
2179 | |
|
2180 | 0 | WRITE_CODE( (uint32_t)ptl->levelIdc, 8 , "general_level_idc"); |
2181 | 0 | WRITE_FLAG( ptl->frameOnlyConstraintFlag, "ptl_frame_only_constraint_flag" ); |
2182 | 0 | WRITE_FLAG( ptl->multiLayerEnabledFlag, "ptl_multilayer_enabled_flag" ); |
2183 | 0 | if(profileTierPresent) |
2184 | 0 | { |
2185 | 0 | codeConstraintInfo( &ptl->constraintInfo ); |
2186 | 0 | } |
2187 | |
|
2188 | 0 | for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--) |
2189 | 0 | { |
2190 | 0 | WRITE_FLAG( ptl->subLayerLevelPresent[i], "sub_layer_level_present_flag[i]" ); |
2191 | 0 | } |
2192 | |
|
2193 | 0 | while (!isByteAligned()) |
2194 | 0 | { |
2195 | 0 | WRITE_FLAG(0, "ptl_reserved_zero_bit"); |
2196 | 0 | } |
2197 | |
|
2198 | 0 | for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--) |
2199 | 0 | { |
2200 | 0 | if( ptl->subLayerLevelPresent[i] ) |
2201 | 0 | { |
2202 | 0 | WRITE_CODE( (uint32_t)ptl->subLayerLevelIdc[i], 8, "sub_layer_level_idc[i]" ); |
2203 | 0 | } |
2204 | 0 | } |
2205 | |
|
2206 | 0 | if (profileTierPresent) |
2207 | 0 | { |
2208 | 0 | WRITE_CODE(ptl->numSubProfile, 8, "ptl_num_sub_profiles"); |
2209 | 0 | for (int i = 0; i < ptl->numSubProfile; i++) |
2210 | 0 | { |
2211 | 0 | WRITE_CODE(ptl->subProfileIdc[i], 32, "general_sub_profile_idc[i]"); |
2212 | 0 | } |
2213 | 0 | } |
2214 | 0 | } |
2215 | | |
2216 | | |
2217 | | /** |
2218 | | * Write tiles and wavefront substreams sizes for the slice header (entry points). |
2219 | | * |
2220 | | * \param pSlice Slice structure that contains the substream size information. |
2221 | | */ |
2222 | | void HLSWriter::codeTilesWPPEntryPoint( Slice* pSlice ) |
2223 | 0 | { |
2224 | 0 | int numEntryPoints = pSlice->getNumEntryPoints( *pSlice->sps, *pSlice->pps ); |
2225 | 0 | if( numEntryPoints == 0 ) |
2226 | 0 | { |
2227 | 0 | return; |
2228 | 0 | } |
2229 | | |
2230 | 0 | uint32_t maxOffset = 0; |
2231 | 0 | for(int idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++) |
2232 | 0 | { |
2233 | 0 | uint32_t offset=pSlice->getSubstreamSize(idx); |
2234 | 0 | if ( offset > maxOffset ) |
2235 | 0 | { |
2236 | 0 | maxOffset = offset; |
2237 | 0 | } |
2238 | 0 | } |
2239 | | |
2240 | | // Determine number of bits "offsetLenMinus1+1" required for entry point information |
2241 | 0 | uint32_t offsetLenMinus1 = 0; |
2242 | 0 | while (maxOffset >= (1u << (offsetLenMinus1 + 1))) |
2243 | 0 | { |
2244 | 0 | offsetLenMinus1++; |
2245 | 0 | CHECK(offsetLenMinus1 + 1 >= 32, "Invalid offset length minus 1"); |
2246 | 0 | } |
2247 | | |
2248 | 0 | if (pSlice->getNumberOfSubstreamSizes()>0) |
2249 | 0 | { |
2250 | 0 | WRITE_UVLC(offsetLenMinus1, "sh_entry_offset_len_minus1"); |
2251 | |
|
2252 | 0 | for (uint32_t idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++) |
2253 | 0 | { |
2254 | 0 | WRITE_CODE(pSlice->getSubstreamSize(idx)-1, offsetLenMinus1+1, "sh_entry_point_offset_minus1"); |
2255 | 0 | } |
2256 | 0 | } |
2257 | 0 | } |
2258 | | |
2259 | | |
2260 | | // ==================================================================================================================== |
2261 | | // Protected member functions |
2262 | | // ==================================================================================================================== |
2263 | | |
2264 | | //! Code weighted prediction tables |
2265 | | void HLSWriter::xCodePredWeightTable( const Slice* slice ) |
2266 | 0 | { |
2267 | 0 | WPScalingParam *wp; |
2268 | 0 | const ChromaFormat format = slice->sps->chromaFormatIdc; |
2269 | 0 | const uint32_t numberValidComponents = getNumberValidComponents(format); |
2270 | 0 | const bool bChroma = isChromaEnabled(format); |
2271 | 0 | const int iNbRef = (slice->sliceType == VVENC_B_SLICE ) ? (2) : (1); |
2272 | 0 | bool bDenomCoded = false; |
2273 | 0 | uint32_t uiTotalSignalledWeightFlags = 0; |
2274 | |
|
2275 | 0 | if ( (slice->sliceType==VVENC_P_SLICE && slice->pps->weightPred) || (slice->sliceType==VVENC_B_SLICE && slice->pps->weightedBiPred) ) |
2276 | 0 | { |
2277 | 0 | for ( int iNumRef=0 ; iNumRef<iNbRef ; iNumRef++ ) // loop over l0 and l1 syntax elements |
2278 | 0 | { |
2279 | 0 | RefPicList refPicList = ( iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
2280 | | |
2281 | | // NOTE: wp[].log2WeightDenom and wp[].presentFlag are actually per-channel-type settings. |
2282 | |
|
2283 | 0 | for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ ) |
2284 | 0 | { |
2285 | 0 | slice->getWpScaling(refPicList, iRefIdx, wp); |
2286 | 0 | if ( !bDenomCoded ) |
2287 | 0 | { |
2288 | 0 | int iDeltaDenom; |
2289 | 0 | WRITE_UVLC( wp[COMP_Y].log2WeightDenom, "luma_log2_weight_denom" ); |
2290 | |
|
2291 | 0 | if( bChroma ) |
2292 | 0 | { |
2293 | 0 | CHECK( wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported" ); |
2294 | 0 | iDeltaDenom = (wp[COMP_Cb].log2WeightDenom - wp[COMP_Y].log2WeightDenom); |
2295 | 0 | WRITE_SVLC( iDeltaDenom, "delta_chroma_log2_weight_denom" ); |
2296 | 0 | } |
2297 | 0 | bDenomCoded = true; |
2298 | 0 | } |
2299 | 0 | WRITE_FLAG( wp[COMP_Y].presentFlag, iNumRef==0?"luma_weight_l0_flag[i]":"luma_weight_l1_flag[i]" ); |
2300 | 0 | uiTotalSignalledWeightFlags += wp[COMP_Y].presentFlag; |
2301 | 0 | } |
2302 | 0 | if (bChroma) |
2303 | 0 | { |
2304 | 0 | for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ ) |
2305 | 0 | { |
2306 | 0 | slice->getWpScaling( refPicList, iRefIdx, wp ); |
2307 | 0 | CHECK( wp[COMP_Cb].presentFlag != wp[COMP_Cr].presentFlag, "Inconsistent settings for chroma channels" ); |
2308 | 0 | WRITE_FLAG( wp[COMP_Cb].presentFlag, iNumRef==0?"chroma_weight_l0_flag[i]":"chroma_weight_l1_flag[i]" ); |
2309 | 0 | uiTotalSignalledWeightFlags += 2*wp[COMP_Cb].presentFlag; |
2310 | 0 | } |
2311 | 0 | } |
2312 | | |
2313 | 0 | for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ ) |
2314 | 0 | { |
2315 | 0 | slice->getWpScaling(refPicList, iRefIdx, wp); |
2316 | 0 | if ( wp[COMP_Y].presentFlag ) |
2317 | 0 | { |
2318 | 0 | int iDeltaWeight = (wp[COMP_Y].iWeight - (1<<wp[COMP_Y].log2WeightDenom)); |
2319 | 0 | WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_luma_weight_l0[i]":"delta_luma_weight_l1[i]" ); |
2320 | 0 | WRITE_SVLC( wp[COMP_Y].iOffset, iNumRef==0?"luma_offset_l0[i]":"luma_offset_l1[i]" ); |
2321 | 0 | } |
2322 | |
|
2323 | 0 | if ( bChroma ) |
2324 | 0 | { |
2325 | 0 | if ( wp[COMP_Cb].presentFlag ) |
2326 | 0 | { |
2327 | 0 | for ( int j = COMP_Cb ; j < numberValidComponents ; j++ ) |
2328 | 0 | { |
2329 | 0 | CHECK(wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported"); |
2330 | 0 | int iDeltaWeight = (wp[j].iWeight - (1<<wp[COMP_Cb].log2WeightDenom)); |
2331 | 0 | WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_chroma_weight_l0[i]":"delta_chroma_weight_l1[i]" ); |
2332 | |
|
2333 | 0 | int range=128; |
2334 | 0 | int pred = ( range - ( ( range*wp[j].iWeight)>>(wp[j].log2WeightDenom) ) ); |
2335 | 0 | int iDeltaChroma = (wp[j].iOffset - pred); |
2336 | 0 | WRITE_SVLC( iDeltaChroma, iNumRef==0?"delta_chroma_offset_l0[i]":"delta_chroma_offset_l1[i]" ); |
2337 | 0 | } |
2338 | 0 | } |
2339 | 0 | } |
2340 | 0 | } |
2341 | 0 | } |
2342 | 0 | CHECK(uiTotalSignalledWeightFlags>24, "Too many signalled weight flags"); |
2343 | 0 | } |
2344 | 0 | } |
2345 | | |
2346 | | |
2347 | | void HLSWriter::xCodePredWeightTable( const PicHeader *picHeader, const PPS *pps, const SPS *sps ) |
2348 | 0 | { |
2349 | 0 | WPScalingParam *wp; |
2350 | 0 | const ChromaFormat format = sps->chromaFormatIdc; |
2351 | 0 | const uint32_t numberValidComponents = getNumberValidComponents(format); |
2352 | 0 | const bool bChroma = isChromaEnabled(format); |
2353 | 0 | bool bDenomCoded = false; |
2354 | 0 | uint32_t uiTotalSignalledWeightFlags = 0; |
2355 | 0 | uint32_t numLxWeights = picHeader->numL0Weights; |
2356 | 0 | bool moreSyntaxToBeParsed = true; |
2357 | 0 | for (int iNumRef = 0; iNumRef < NUM_REF_PIC_LIST_01 && moreSyntaxToBeParsed; iNumRef++) // loop over l0 and l1 syntax elements |
2358 | 0 | { |
2359 | 0 | RefPicList refPicList = ( iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
2360 | | |
2361 | | // NOTE: wp[].log2WeightDenom and wp[].presentFlag are actually per-channel-type settings. |
2362 | |
|
2363 | 0 | for ( int iRefIdx=0 ; iRefIdx<numLxWeights ; iRefIdx++ ) |
2364 | 0 | { |
2365 | 0 | picHeader->getWpScaling(refPicList, iRefIdx, wp); |
2366 | 0 | if ( !bDenomCoded ) |
2367 | 0 | { |
2368 | 0 | int iDeltaDenom; |
2369 | 0 | WRITE_UVLC( wp[COMP_Y].log2WeightDenom, "luma_log2_weight_denom" ); |
2370 | |
|
2371 | 0 | if( bChroma ) |
2372 | 0 | { |
2373 | 0 | CHECK( wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported" ); |
2374 | 0 | iDeltaDenom = (wp[COMP_Cb].log2WeightDenom - wp[COMP_Y].log2WeightDenom); |
2375 | 0 | WRITE_SVLC( iDeltaDenom, "delta_chroma_log2_weight_denom" ); |
2376 | 0 | } |
2377 | 0 | bDenomCoded = true; |
2378 | 0 | } |
2379 | 0 | WRITE_FLAG( wp[COMP_Y].presentFlag, iNumRef==0?"luma_weight_l0_flag[i]":"luma_weight_l1_flag[i]" ); |
2380 | 0 | uiTotalSignalledWeightFlags += wp[COMP_Y].presentFlag; |
2381 | 0 | } |
2382 | 0 | if (bChroma) |
2383 | 0 | { |
2384 | 0 | for ( int iRefIdx=0 ; iRefIdx<numLxWeights; iRefIdx++ ) |
2385 | 0 | { |
2386 | 0 | picHeader->getWpScaling( refPicList, iRefIdx, wp ); |
2387 | 0 | CHECK( wp[COMP_Cb].presentFlag != wp[COMP_Cr].presentFlag, "Inconsistent settings for chroma channels" ); |
2388 | 0 | WRITE_FLAG( wp[COMP_Cb].presentFlag, iNumRef==0?"chroma_weight_l0_flag[i]":"chroma_weight_l1_flag[i]" ); |
2389 | 0 | uiTotalSignalledWeightFlags += 2*wp[COMP_Cb].presentFlag; |
2390 | 0 | } |
2391 | 0 | } |
2392 | | |
2393 | 0 | for ( int iRefIdx=0 ; iRefIdx<numLxWeights; iRefIdx++ ) |
2394 | 0 | { |
2395 | 0 | picHeader->getWpScaling(refPicList, iRefIdx, wp); |
2396 | 0 | if ( wp[COMP_Y].presentFlag ) |
2397 | 0 | { |
2398 | 0 | int iDeltaWeight = (wp[COMP_Y].iWeight - (1<<wp[COMP_Y].log2WeightDenom)); |
2399 | 0 | WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_luma_weight_l0[i]":"delta_luma_weight_l1[i]" ); |
2400 | 0 | WRITE_SVLC( wp[COMP_Y].iOffset, iNumRef==0?"luma_offset_l0[i]":"luma_offset_l1[i]" ); |
2401 | 0 | } |
2402 | |
|
2403 | 0 | if ( bChroma ) |
2404 | 0 | { |
2405 | 0 | if ( wp[COMP_Cb].presentFlag ) |
2406 | 0 | { |
2407 | 0 | for ( int j = COMP_Cb ; j < numberValidComponents ; j++ ) |
2408 | 0 | { |
2409 | 0 | CHECK(wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported"); |
2410 | 0 | int iDeltaWeight = (wp[j].iWeight - (1<<wp[COMP_Cb].log2WeightDenom)); |
2411 | 0 | WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_chroma_weight_l0[i]":"delta_chroma_weight_l1[i]" ); |
2412 | |
|
2413 | 0 | int range=128; |
2414 | 0 | int pred = ( range - ( ( range*wp[j].iWeight)>>(wp[j].log2WeightDenom) ) ); |
2415 | 0 | int iDeltaChroma = (wp[j].iOffset - pred); |
2416 | 0 | WRITE_SVLC( iDeltaChroma, iNumRef==0?"delta_chroma_offset_l0[i]":"delta_chroma_offset_l1[i]" ); |
2417 | 0 | } |
2418 | 0 | } |
2419 | 0 | } |
2420 | 0 | } |
2421 | 0 | if (iNumRef == 0 ) |
2422 | 0 | { |
2423 | 0 | numLxWeights = picHeader->numL1Weights; |
2424 | 0 | if (pps->weightedBiPred == 0) |
2425 | 0 | { |
2426 | 0 | numLxWeights = 0; |
2427 | 0 | } |
2428 | 0 | else if (picHeader->pRPL[1]->getNumRefEntries() > 0) |
2429 | 0 | { |
2430 | 0 | WRITE_UVLC(numLxWeights, "num_l1_weights"); |
2431 | 0 | } |
2432 | 0 | moreSyntaxToBeParsed = (numLxWeights == 0) ? false : true; |
2433 | 0 | } |
2434 | 0 | } |
2435 | 0 | CHECK(uiTotalSignalledWeightFlags>24, "Too many signalled weight flags"); |
2436 | 0 | } |
2437 | | |
2438 | | void HLSWriter::alfFilter( const AlfParam& alfParam, const bool isChroma, const int altIdx ) |
2439 | 0 | { |
2440 | 0 | AlfFilterShape alfShape(isChroma ? 5 : 7); |
2441 | 0 | const short* coeff = isChroma ? alfParam.chromaCoeff[altIdx] : alfParam.lumaCoeff; |
2442 | 0 | const short* clipp = isChroma ? alfParam.chromaClipp[altIdx] : alfParam.lumaClipp; |
2443 | 0 | const int numFilters = isChroma ? 1 : alfParam.numLumaFilters; |
2444 | | |
2445 | | // vlc for all |
2446 | | |
2447 | | // Filter coefficients |
2448 | 0 | for( int ind = 0; ind < numFilters; ++ind ) |
2449 | 0 | { |
2450 | 0 | for( int i = 0; i < alfShape.numCoeff - 1; i++ ) |
2451 | 0 | { |
2452 | 0 | WRITE_UVLC( abs(coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ]), isChroma ? "alf_chroma_coeff_abs" : "alf_luma_coeff_abs" ); //alf_coeff_chroma[i], alf_coeff_luma_delta[i][j] |
2453 | 0 | if( abs( coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ] ) != 0 ) |
2454 | 0 | { |
2455 | 0 | WRITE_FLAG( ( coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ] < 0 ) ? 1 : 0, isChroma ? "alf_chroma_coeff_sign" : "alf_luma_coeff_sign" ); |
2456 | 0 | } |
2457 | 0 | } |
2458 | 0 | } |
2459 | | |
2460 | | // Clipping values coding |
2461 | 0 | if( alfParam.nonLinearFlag[isChroma] ) |
2462 | 0 | { |
2463 | 0 | for (int ind = 0; ind < numFilters; ++ind) |
2464 | 0 | { |
2465 | 0 | for (int i = 0; i < alfShape.numCoeff - 1; i++) |
2466 | 0 | { |
2467 | 0 | WRITE_CODE(clipp[ind* MAX_NUM_ALF_LUMA_COEFF + i], 2, isChroma ? "alf_chroma_clip_idx" : "alf_luma_clip_idx"); |
2468 | 0 | } |
2469 | 0 | } |
2470 | 0 | } |
2471 | 0 | } |
2472 | | |
2473 | | } // namespace vvenc |
2474 | | |
2475 | | //! \} |
2476 | | |