/work/vvdec/source/Lib/DecoderLib/HLSyntaxReader.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) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC 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 | | /** \file HLSyntaxReader.cpp |
44 | | * \brief Reader for high level syntax |
45 | | */ |
46 | | |
47 | | //! \ingroup DecoderLib |
48 | | //! \{ |
49 | | |
50 | | #include "HLSyntaxReader.h" |
51 | | |
52 | | #include "CommonLib/CommonDef.h" |
53 | | #include "CommonLib/Rom.h" |
54 | | #include "CommonLib/dtrace_next.h" |
55 | | #include "CommonLib/AdaptiveLoopFilter.h" |
56 | | |
57 | | #include "ParameterSetManager.h" |
58 | | |
59 | 582 | #define CHECK_CONSTRAINT( cond, msg ) CHECK( cond, msg ) |
60 | | |
61 | | namespace vvdec |
62 | | { |
63 | | |
64 | | void AUDReader::parseAccessUnitDelimiter( InputBitstream* bs, uint32_t &picType ) |
65 | 4 | { |
66 | 4 | setBitstream( bs ); |
67 | | |
68 | | #if ENABLE_TRACING |
69 | | xTraceAccessUnitDelimiter(); |
70 | | #endif |
71 | | |
72 | 4 | X_READ_FLAG( aud_irap_or_gdr_au_flag ); |
73 | 4 | (void)aud_irap_or_gdr_au_flag; |
74 | | |
75 | 4 | X_READ_CODE_NO_RANGE( aud_pic_type, 3 ); |
76 | 4 | picType = aud_pic_type; |
77 | | |
78 | 4 | xReadRbspTrailingBits(); |
79 | 4 | } |
80 | | |
81 | | void FDReader::parseFillerData( InputBitstream* bs, uint32_t &fdSize ) |
82 | 0 | { |
83 | 0 | setBitstream( bs ); |
84 | | #if ENABLE_TRACING |
85 | | DTRACE( g_trace_ctx, D_HEADER, "=========== Filler Data ===========\n" ); |
86 | | #endif |
87 | 0 | fdSize = 0; |
88 | 0 | while( m_pcBitstream->getNumBitsLeft() > 8 ) |
89 | 0 | { |
90 | 0 | X_READ_CODE_NO_RANGE( fd_ff_byte, 8 ); |
91 | 0 | CHECK_WARN( fd_ff_byte != 0xff, "Invalid fillter data not '0xff'" ); |
92 | 0 | fdSize++; |
93 | 0 | } |
94 | 0 | xReadRbspTrailingBits(); |
95 | 0 | } |
96 | | |
97 | | |
98 | | // ==================================================================================================================== |
99 | | // Public member functions |
100 | | // ==================================================================================================================== |
101 | | |
102 | | void HLSyntaxReader::copyRefPicList( const SPS* sps, const ReferencePictureList* source_rpl, ReferencePictureList* dest_rp ) |
103 | 0 | { |
104 | 0 | memcpy( dest_rp, source_rpl, sizeof( ReferencePictureList ) ); |
105 | |
|
106 | 0 | if( !sps->getLongTermRefsPresent() ) |
107 | 0 | { |
108 | 0 | dest_rp->setNumberOfLongtermPictures( 0 ); |
109 | 0 | } |
110 | 0 | } |
111 | | |
112 | | void HLSyntaxReader::parseRefPicList( ReferencePictureList* rpl, int rplIdx, const SPS* sps ) |
113 | 0 | { |
114 | 0 | X_READ_UVLC_idx( num_ref_entries, "[ listIdx ][ rplsIdx ]", 0, MAX_NUM_REF_PICS ); |
115 | | // The value of num_ref_entries[ listIdx ][ rplsIdx ] shall be in the range of 0 to MaxDpbSize + 13, inclusive, |
116 | | // where MaxDpbSize is as specified in clause A.4.2. |
117 | |
|
118 | 0 | if( sps->getLongTermRefsPresent() && num_ref_entries > 0 && rplIdx != -1 ) // rplsIdx == -1 means it's called from parsePicOrSliceHeader |
119 | 0 | { |
120 | 0 | X_READ_FLAG_idx( ltrp_in_header_flag, "[ listIdx ][ rplsIdx ]" ); |
121 | 0 | rpl->setLtrpInSliceHeaderFlag( ltrp_in_header_flag ); |
122 | 0 | } |
123 | 0 | else if( sps->getLongTermRefsPresent() ) |
124 | 0 | { |
125 | | // When sps_long_term_ref_pics_flag is equal to 1 and rplsIdx is equal to sps_num_ref_pic_lists[ listIdx ], |
126 | | // the value of ltrp_in_header_flag[ listIdx ][ rplsIdx ] is inferred to be equal to 1. |
127 | 0 | rpl->setLtrpInSliceHeaderFlag( 1 ); |
128 | 0 | } |
129 | |
|
130 | 0 | uint32_t numStrp = 0; |
131 | 0 | uint32_t numLtrp = 0; |
132 | 0 | uint32_t numIlrp = 0; |
133 | |
|
134 | 0 | rpl->setInterLayerPresentFlag( sps->getInterLayerPresentFlag() ); |
135 | |
|
136 | 0 | int prevDelta = 0; |
137 | 0 | for( unsigned ii = 0; ii < num_ref_entries; ii++ ) |
138 | 0 | { |
139 | 0 | if( rpl->getInterLayerPresentFlag() ) |
140 | 0 | { |
141 | 0 | X_READ_FLAG_idx( inter_layer_ref_pic_flag, "[ listIdx ][ rplsIdx ][ i ]" ); |
142 | 0 | if( inter_layer_ref_pic_flag ) |
143 | 0 | { |
144 | 0 | X_READ_UVLC_idx( ilrp_idx, "[ listIdx ][ rplsIdx ][ i ]", 0, MAX_VPS_LAYERS ); |
145 | | // The value of ilrp_idx[ listIdx ][ rplsIdx ][ i ] shall be in the range of 0 to NumDirectRefLayers[ GeneralLayerIdx[ nuh_layer_id ] ] − 1, inclusive. |
146 | 0 | rpl->setRefPicIdentifier( ii, 0, true, true, ilrp_idx ); |
147 | 0 | numIlrp++; |
148 | |
|
149 | 0 | continue; |
150 | 0 | } |
151 | 0 | } |
152 | | |
153 | | // if( !inter_layer_ref_pic_flag ) // implicit due to previous `continue` |
154 | 0 | { |
155 | 0 | bool isLongTerm = false; |
156 | 0 | if( sps->getLongTermRefsPresent() ) |
157 | 0 | { |
158 | 0 | X_READ_FLAG_idx( st_ref_pic_flag, "[ listIdx ][ rplsIdx ][ i ]" ); |
159 | 0 | isLongTerm = !st_ref_pic_flag; |
160 | 0 | } |
161 | |
|
162 | 0 | if( !isLongTerm ) |
163 | 0 | { |
164 | 0 | X_READ_UVLC_idx( abs_delta_poc_st, "[ listIdx ][ rplsIdx ][ i ]", 0, ( 1 << 15 ) - 1 ); |
165 | 0 | int deltaPocSt = abs_delta_poc_st; |
166 | 0 | if( ( !sps->getUseWP() && !sps->getUseWPBiPred() ) || ii == 0 ) |
167 | 0 | { |
168 | 0 | deltaPocSt++; |
169 | 0 | } |
170 | |
|
171 | 0 | if( deltaPocSt > 0 ) |
172 | 0 | { |
173 | 0 | X_READ_FLAG_idx( strp_entry_sign_flag, "[ listIdx ][ rplsIdx ][ i ]" ); |
174 | 0 | if( strp_entry_sign_flag ) |
175 | 0 | { |
176 | 0 | deltaPocSt = -deltaPocSt; |
177 | 0 | } |
178 | 0 | } |
179 | |
|
180 | 0 | deltaPocSt += prevDelta; |
181 | 0 | prevDelta = deltaPocSt; |
182 | 0 | rpl->setRefPicIdentifier( ii, deltaPocSt, false, false, 0 ); |
183 | 0 | numStrp++; |
184 | 0 | } |
185 | 0 | else |
186 | 0 | { |
187 | 0 | if( !rpl->getLtrpInSliceHeaderFlag() ) |
188 | 0 | { |
189 | 0 | X_READ_CODE_NO_RANGE_idx( rpls_poc_lsb_lt, "[ listIdx ][ rplsIdx ][ j++ ]", sps->getBitsForPOC() ); |
190 | 0 | rpl->setRefPicIdentifier( ii, rpls_poc_lsb_lt, true, false, 0 ); |
191 | 0 | } |
192 | 0 | else |
193 | 0 | { |
194 | 0 | rpl->setRefPicIdentifier( ii, 0, true, false, 0 ); |
195 | 0 | } |
196 | 0 | numLtrp++; |
197 | 0 | } |
198 | 0 | } |
199 | 0 | } |
200 | 0 | rpl->setNumberOfShorttermPictures( numStrp ); |
201 | 0 | rpl->setNumberOfLongtermPictures( numLtrp ); |
202 | 0 | rpl->setNumberOfInterLayerPictures( numIlrp ); |
203 | 0 | } |
204 | | |
205 | | void HLSyntaxReader::parsePPS( PPS* pcPPS, const ParameterSetManager* parameterSetManager ) |
206 | 2 | { |
207 | | #if ENABLE_TRACING |
208 | | xTracePPSHeader(); |
209 | | #endif |
210 | | |
211 | 2 | X_READ_CODE_NO_RANGE( pps_pic_parameter_set_id, 6 ); |
212 | 2 | pcPPS->setPPSId( pps_pic_parameter_set_id ); |
213 | | |
214 | 2 | X_READ_CODE( pps_seq_parameter_set_id, 4, 0, 15 ); |
215 | 2 | const SPS* sps = parameterSetManager->getSPS( pps_seq_parameter_set_id ); |
216 | 2 | CHECK( !sps, "SPS with id " << pps_seq_parameter_set_id << " missing." ); |
217 | 2 | pcPPS->setSPSId( pps_seq_parameter_set_id ); |
218 | | |
219 | 2 | const int SubWidthC = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() ); |
220 | 2 | const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() ); |
221 | | |
222 | 2 | X_READ_FLAG( pps_mixed_nalu_types_in_pic_flag ); |
223 | 2 | pcPPS->setMixedNaluTypesInPicFlag( pps_mixed_nalu_types_in_pic_flag == 1 ); |
224 | | |
225 | 2 | const int CtbSizeY = sps->getCTUSize(); |
226 | 2 | const int MinCbSizeY = 1 << sps->getLog2MinCodingBlockSize(); |
227 | | |
228 | 2 | X_READ_UVLC( pps_pic_width_in_luma_samples, 1, sps->getMaxPicWidthInLumaSamples() ); |
229 | 2 | CHECK( pps_pic_width_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_width_in_luma_samples not a multiple of 8 or MinCbSizeY" ); |
230 | 2 | CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_width_in_luma_samples != sps->getMaxPicWidthInLumaSamples(), |
231 | 2 | "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_width_in_luma_samples shall be equal" |
232 | 2 | " to sps_pic_width_max_in_luma_samples." ) |
233 | 2 | CHECK( sps->getUseWrapAround() && CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1, |
234 | 2 | "When sps_ref_wraparound_enabled_flag is equal to 1, the value of ( CtbSizeY / MinCbSizeY + 1 ) shall be less than or" |
235 | 2 | " equal to the value of ( pps_pic_width_in_luma_samples / MinCbSizeY − 1 )." ); |
236 | 2 | pcPPS->setPicWidthInLumaSamples( pps_pic_width_in_luma_samples ); |
237 | | |
238 | 2 | X_READ_UVLC( pps_pic_height_in_luma_samples, 1, sps->getMaxPicHeightInLumaSamples() ); |
239 | 2 | CHECK( pps_pic_height_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_height_in_luma_samples not a multiple of 8 or MinCbSizeY" ); |
240 | 2 | CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_height_in_luma_samples != sps->getMaxPicHeightInLumaSamples(), |
241 | 2 | "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_height_in_luma_samples shall be equal" |
242 | 2 | " to sps_pic_height_max_in_luma_samples." ) |
243 | 2 | pcPPS->setPicHeightInLumaSamples( pps_pic_height_in_luma_samples ); |
244 | | |
245 | 2 | const unsigned PicWidthInCtbsY = ( pps_pic_width_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY; (void) PicWidthInCtbsY; |
246 | 2 | const unsigned PicHeightInCtbsY = ( pps_pic_height_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY; (void) PicHeightInCtbsY; |
247 | 2 | const unsigned PicSizeInCtbsY = PicWidthInCtbsY * PicHeightInCtbsY; (void) PicSizeInCtbsY; |
248 | 2 | const unsigned PicWidthInMinCbsY = pps_pic_width_in_luma_samples / MinCbSizeY; (void) PicWidthInMinCbsY; |
249 | 2 | const unsigned PicHeightInMinCbsY = pps_pic_height_in_luma_samples / MinCbSizeY; (void) PicHeightInMinCbsY; |
250 | 2 | const unsigned PicSizeInMinCbsY = PicWidthInMinCbsY * PicHeightInMinCbsY; (void) PicSizeInMinCbsY; |
251 | 2 | const unsigned PicSizeInSamplesY = pps_pic_width_in_luma_samples * pps_pic_height_in_luma_samples; (void) PicSizeInSamplesY; |
252 | 2 | const unsigned PicWidthInSamplesC = pps_pic_width_in_luma_samples / SubWidthC; (void) PicWidthInSamplesC; |
253 | 2 | const unsigned PicHeightInSamplesC = pps_pic_height_in_luma_samples / SubHeightC; (void) PicHeightInSamplesC; |
254 | | |
255 | 2 | X_READ_FLAG( pps_conformance_window_flag ); |
256 | 2 | CHECK( pps_conformance_window_flag != 0 && pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples() |
257 | 2 | && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples(), |
258 | 2 | "pps_conformance_window_flag shall be equal to 0" ) |
259 | 2 | pcPPS->setConformanceWindowPresentFlag( pps_conformance_window_flag ); |
260 | | |
261 | 2 | if( pps_conformance_window_flag != 0 ) |
262 | 0 | { |
263 | 0 | X_READ_UVLC_NO_RANGE( pps_conf_win_left_offset ); |
264 | 0 | X_READ_UVLC_NO_RANGE( pps_conf_win_right_offset ); |
265 | 0 | X_READ_UVLC_NO_RANGE( pps_conf_win_top_offset ); |
266 | 0 | X_READ_UVLC_NO_RANGE( pps_conf_win_bottom_offset ); |
267 | |
|
268 | 0 | CHECK( SubWidthC * ( pps_conf_win_left_offset + pps_conf_win_right_offset ) >= pps_pic_width_in_luma_samples, |
269 | 0 | "pps_conf_win_left_offset + pps_conf_win_right_offset too large" ); |
270 | 0 | CHECK( SubHeightC * ( pps_conf_win_top_offset + pps_conf_win_bottom_offset ) >= pps_pic_height_in_luma_samples, |
271 | 0 | "pps_conf_win_top_offset + pps_conf_win_bottom_offset too large" ); |
272 | |
|
273 | 0 | Window& conf = pcPPS->getConformanceWindow(); |
274 | 0 | conf.setWindowLeftOffset( pps_conf_win_left_offset ); |
275 | 0 | conf.setWindowRightOffset( pps_conf_win_right_offset ); |
276 | 0 | conf.setWindowTopOffset( pps_conf_win_top_offset ); |
277 | 0 | conf.setWindowBottomOffset( pps_conf_win_bottom_offset ); |
278 | 0 | } |
279 | | |
280 | 2 | X_READ_FLAG_CHECK( pps_scaling_window_explicit_signalling_flag, |
281 | 2 | !sps->getRprEnabledFlag() && pps_scaling_window_explicit_signalling_flag != 0, |
282 | 2 | "When sps_ref_pic_resampling_enabled_flag is equal to 0, the value of pps_scaling_window_explicit_signalling_flag shall be equal to 0" ); |
283 | | |
284 | 2 | if( pps_scaling_window_explicit_signalling_flag != 0 ) |
285 | 0 | { |
286 | 0 | X_READ_SVLC_NO_RANGE( pps_scaling_win_left_offset ); |
287 | 0 | X_READ_SVLC_NO_RANGE( pps_scaling_win_right_offset ); |
288 | 0 | X_READ_SVLC_NO_RANGE( pps_scaling_win_top_offset ); |
289 | 0 | X_READ_SVLC_NO_RANGE( pps_scaling_win_bottom_offset ); |
290 | |
|
291 | 0 | CHECK( SubWidthC * pps_scaling_win_left_offset < -(int) pps_pic_width_in_luma_samples * 15 |
292 | 0 | || SubWidthC * pps_scaling_win_left_offset >= (int) pps_pic_width_in_luma_samples, |
293 | 0 | "pps_scaling_win_left_offset (" << pps_scaling_win_left_offset << ") out of bounds" ); |
294 | 0 | CHECK( SubWidthC * pps_scaling_win_right_offset < -(int) pps_pic_width_in_luma_samples * 15 |
295 | 0 | || SubWidthC * pps_scaling_win_right_offset >= (int) pps_pic_width_in_luma_samples, |
296 | 0 | "pps_scaling_win_right_offset (" << pps_scaling_win_right_offset << ") out of bounds" ); |
297 | 0 | CHECK( SubHeightC * pps_scaling_win_top_offset < -(int) pps_pic_height_in_luma_samples * 15 |
298 | 0 | || SubHeightC * pps_scaling_win_top_offset >= (int) pps_pic_height_in_luma_samples, |
299 | 0 | "pps_scaling_win_top_offset (" << pps_scaling_win_top_offset << ") out of bounds" ); |
300 | 0 | CHECK( SubHeightC * pps_scaling_win_bottom_offset < -(int) pps_pic_height_in_luma_samples * 15 |
301 | 0 | || SubHeightC * pps_scaling_win_bottom_offset >= (int) pps_pic_height_in_luma_samples, |
302 | 0 | "pps_scaling_win_bottom_offset (" << pps_scaling_win_bottom_offset << ") out of bounds" ); |
303 | |
|
304 | 0 | CHECK( SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) < -(int) pps_pic_width_in_luma_samples * 15 |
305 | 0 | || SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) >= (int) pps_pic_width_in_luma_samples, |
306 | 0 | "SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be greater than or equal to" |
307 | 0 | " -pps_pic_width_in_luma_samples * 15 and less than pps_pic_width_in_luma_samples." |
308 | 0 | " (pps_scaling_win_left_offset + pps_scaling_win_right_offset = " |
309 | 0 | << pps_scaling_win_left_offset + pps_scaling_win_right_offset << ")" ); |
310 | |
|
311 | 0 | CHECK( SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) < -(int) pps_pic_height_in_luma_samples * 15 |
312 | 0 | || SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) >= (int) pps_pic_height_in_luma_samples, |
313 | 0 | "SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be greater than or equal to" |
314 | 0 | " -pps_pic_height_in_luma_samples * 15 and less than pps_pic_height_in_luma_samples." |
315 | 0 | " (pps_scaling_win_top_offset + pps_scaling_win_bottom_offset = " |
316 | 0 | << pps_scaling_win_top_offset + pps_scaling_win_bottom_offset << ")" ) |
317 | | |
318 | | #if 0 |
319 | | // these checks need to be moved to the creation of ref pic lists |
320 | | // |
321 | | const int CurrPicScalWinWidthL = pps_pic_width_in_luma_samples - SubWidthC * ( pps_scaling_win_right_offset + pps_scaling_win_left_offset ); |
322 | | const int CurrPicScalWinHeightL = pps_pic_height_in_luma_samples - SubHeightC * ( pps_scaling_win_bottom_offset + pps_scaling_win_top_offset ); |
323 | | CHECK( CurrPicScalWinWidthL * 2 < refPicScalWinWidthL, |
324 | | "Requirement of bitstream conformance: CurrPicScalWinWidthL * 2 is greater than or equal to refPicScalWinWidthL." ); |
325 | | CHECK( CurrPicScalWinHeightL * 2 < refPicScalWinHeightL, |
326 | | "Requirement of bitstream conformance: CurrPicScalWinHeightL * 2 is greater than or equal to refPicScalWinHeightL." ); |
327 | | CHECK( CurrPicScalWinWidthL > refPicScalWinWidthL * 8, |
328 | | "Requirement of bitstream conformance: CurrPicScalWinWidthL is less than or equal to refPicScalWinWidthL * 8." ); |
329 | | CHECK( CurrPicScalWinHeightL > refPicScalWinHeightL * 8, |
330 | | "Requirement of bitstream conformance: CurrPicScalWinHeightL is less than or equal to refPicScalWinHeightL * 8." ); |
331 | | CHECK( CurrPicScalWinWidthL * sps->getMaxPicWidthInLumaSamples() < refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - std::max( 8, MinCbSizeY ) ), |
332 | | "Requirement of bitstream conformance: CurrPicScalWinWidthL * sps_pic_width_max_in_luma_samples is greater than or equal to" |
333 | | " refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - Max( 8, MinCbSizeY ) )." ); |
334 | | CHECK( CurrPicScalWinHeightL * sps->getMaxPicHeightInLumaSamples() < refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - std::max( 8, MinCbSizeY ) ), |
335 | | "Requirement of bitstream conformance: CurrPicScalWinHeightL * sps_pic_height_max_in_luma_samples is greater than or equal to" |
336 | | " refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - Max( 8, MinCbSizeY ) )." ); |
337 | | #endif |
338 | | |
339 | 0 | Window& scalingWindow = pcPPS->getScalingWindow(); |
340 | 0 | scalingWindow.setWindowLeftOffset( pps_scaling_win_left_offset ); |
341 | 0 | scalingWindow.setWindowRightOffset( pps_scaling_win_right_offset ); |
342 | 0 | scalingWindow.setWindowTopOffset( pps_scaling_win_top_offset ); |
343 | 0 | scalingWindow.setWindowBottomOffset( pps_scaling_win_bottom_offset ); |
344 | 0 | } |
345 | 2 | else |
346 | 2 | { |
347 | 2 | pcPPS->setScalingWindow( pcPPS->getConformanceWindow() ); |
348 | 2 | } |
349 | | |
350 | 2 | X_READ_FLAG( pps_output_flag_present_flag ); |
351 | 2 | pcPPS->setOutputFlagPresentFlag( pps_output_flag_present_flag ); |
352 | | |
353 | 2 | X_READ_FLAG_CHECK( pps_no_pic_partition_flag, |
354 | 2 | ( sps->getNumSubPics() > 1 || pps_mixed_nalu_types_in_pic_flag == 1 ) && pps_no_pic_partition_flag != 0, |
355 | 2 | "When sps_num_subpics_minus1 is greater than 0 or pps_mixed_nalu_types_in_pic_flag is equal to 1, the value of pps_no_pic_partition_flag " |
356 | 2 | "shall be equal to 0." ); |
357 | 2 | pcPPS->setNoPicPartitionFlag( pps_no_pic_partition_flag ); |
358 | | |
359 | 2 | X_READ_FLAG( pps_subpic_id_mapping_present_flag ); |
360 | 2 | CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 0 || sps->getSubPicIdMappingPresentFlag() == 1 ) && pps_subpic_id_mapping_present_flag != 0, |
361 | 2 | "If sps_subpic_id_mapping_explicitly_signalled_flag is 0 or sps_subpic_id_mapping_present_flag is equal to 1, the value of" |
362 | 2 | " pps_subpic_id_mapping_present_flag shall be equal to 0." ); |
363 | 2 | CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 1 && sps->getSubPicIdMappingPresentFlag() == 0 ) && pps_subpic_id_mapping_present_flag != 1, |
364 | 2 | "Otherwise (sps_subpic_id_mapping_explicitly_signalled_flag is equal to 1 and sps_subpic_id_mapping_present_flag is equal to 0), the value of" |
365 | 2 | " pps_subpic_id_mapping_present_flag shall be equal to 1." ); |
366 | 2 | pcPPS->setSubPicIdMappingPresentFlag( pps_subpic_id_mapping_present_flag ); |
367 | | |
368 | 2 | if( pps_subpic_id_mapping_present_flag ) |
369 | 0 | { |
370 | 0 | if( !pps_no_pic_partition_flag ) |
371 | 0 | { |
372 | 0 | X_READ_UVLC( pps_num_subpics_minus1, 0, MAX_NUM_SUB_PICS - 1 ); |
373 | 0 | CHECK( pps_num_subpics_minus1 != sps->getNumSubPics() - 1, "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" ); |
374 | 0 | pcPPS->setNumSubPics( pps_num_subpics_minus1 + 1 ); |
375 | 0 | } |
376 | 0 | else |
377 | 0 | { |
378 | | // When pps_no_pic_partition_flag is equal to 1, the value of pps_num_subpics_minus1 is inferred to be equal to 0. |
379 | 0 | pcPPS->setNumSubPics( 1 ); |
380 | 0 | } |
381 | | |
382 | 0 | X_READ_UVLC( pps_subpic_id_len_minus1, 0, 15 ); |
383 | 0 | CHECK( pps_subpic_id_len_minus1 != sps->getSubPicIdLen() - 1, "pps_subpic_id_len_minus1 shall be equal to sps_subpic_id_len_minus1" ); |
384 | 0 | CHECK( ( 1 << ( pps_subpic_id_len_minus1 + 1 ) ) < pcPPS->getNumSubPics(), "pps_subpic_id_len too short" ); |
385 | 0 | pcPPS->setSubPicIdLen( pps_subpic_id_len_minus1 + 1 ); |
386 | |
|
387 | 0 | for( int picIdx = 0; picIdx < pcPPS->getNumSubPics(); picIdx++ ) |
388 | 0 | { |
389 | 0 | X_READ_CODE_NO_RANGE_idx( pps_subpic_id, "[i]", pcPPS->getSubPicIdLen() ); |
390 | 0 | pcPPS->setSubPicId( picIdx, pps_subpic_id ); |
391 | 0 | } |
392 | 0 | } |
393 | 2 | else |
394 | 2 | { |
395 | 2 | for( int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++ ) |
396 | 0 | { |
397 | 0 | pcPPS->setSubPicId( picIdx, sps->getSubPicIdMappingExplicitlySignalledFlag() ? sps->getSubPicId( picIdx ) : picIdx ); |
398 | 0 | } |
399 | 2 | } |
400 | 2 | for( int i = 0; i < pcPPS->getNumSubPics(); ++i ) |
401 | 0 | { |
402 | 0 | for( int j = 0; j < i; ++j ) |
403 | 0 | { |
404 | 0 | CHECK( pcPPS->getSubPicId( i ) == pcPPS->getSubPicId( j ), |
405 | 0 | "It is a requirement of bitstream conformance that, for any two different values of i and j in the range of" |
406 | 0 | " 0 to sps_num_subpics_minus1, inclusive, SubpicIdVal[ i ] shall not be equal to SubpicIdVal[ j ]." ) |
407 | 0 | } |
408 | 0 | } |
409 | | |
410 | 2 | pcPPS->resetTileSliceInfo(); |
411 | | |
412 | 2 | if( !pps_no_pic_partition_flag ) |
413 | 0 | { |
414 | | // CTU size - required to match size in SPS |
415 | 0 | X_READ_CODE( pps_log2_ctu_size_minus5, 2, 0,2 ); |
416 | 0 | CHECK( pps_log2_ctu_size_minus5 != getLog2( sps->getCTUSize() ) - 5, "pps_log2_ctu_size_minus5 shall be equal to sps_log2_ctu_size_minus5" ); |
417 | 0 | pcPPS->setLog2CtuSize( pps_log2_ctu_size_minus5 + 5 ); |
418 | | |
419 | | // number of explicit tile columns/rows |
420 | |
|
421 | 0 | X_READ_UVLC( pps_num_exp_tile_columns_minus1, 0, PicWidthInCtbsY - 1 ); |
422 | 0 | pcPPS->setNumExpTileColumns( pps_num_exp_tile_columns_minus1 + 1 ); |
423 | |
|
424 | 0 | X_READ_UVLC( pps_num_exp_tile_rows_minus1, 0, PicHeightInCtbsY - 1 ); |
425 | 0 | pcPPS->setNumExpTileRows( pps_num_exp_tile_rows_minus1 + 1 ); |
426 | 0 | CHECK( pcPPS->getNumExpTileColumns() > MAX_TILE_COLS, "Number of explicit tile columns exceeds valid range" ); |
427 | | |
428 | | // tile sizes |
429 | 0 | for( int colIdx = 0; colIdx < pcPPS->getNumExpTileColumns(); colIdx++ ) |
430 | 0 | { |
431 | 0 | X_READ_UVLC_idx( pps_tile_column_width_minus1, "[i]", 0, PicWidthInCtbsY - 1 ); |
432 | 0 | pcPPS->addTileColumnWidth( pps_tile_column_width_minus1 + 1 ); |
433 | 0 | } |
434 | 0 | for( int rowIdx = 0; rowIdx < pcPPS->getNumExpTileRows(); rowIdx++ ) |
435 | 0 | { |
436 | 0 | X_READ_UVLC_idx( pps_tile_row_height_minus1, "[i]", 0, PicHeightInCtbsY - 1 ); |
437 | 0 | pcPPS->addTileRowHeight( pps_tile_row_height_minus1 + 1 ); |
438 | 0 | } |
439 | 0 | pcPPS->initTiles(); |
440 | | |
441 | | // rectangular slice signalling |
442 | 0 | if( pcPPS->getNumTiles() > 1 ) |
443 | 0 | { |
444 | 0 | X_READ_FLAG( pps_loop_filter_across_tiles_enabled_flag ); |
445 | 0 | pcPPS->setLoopFilterAcrossTilesEnabledFlag( pps_loop_filter_across_tiles_enabled_flag ); |
446 | 0 | X_READ_FLAG( pps_rect_slice_flag ); |
447 | 0 | CHECK( ( sps->getSubPicInfoPresentFlag() || pps_mixed_nalu_types_in_pic_flag ) && pps_rect_slice_flag != 1, |
448 | 0 | "When sps_subpic_info_present_flag is equal to 1 or pps_mixed_nalu_types_in_pic_flag is equal to 1," |
449 | 0 | " the value of pps_rect_slice_flag shall be equal to 1." ); |
450 | 0 | pcPPS->setRectSliceFlag( pps_rect_slice_flag ); |
451 | 0 | } |
452 | 0 | else |
453 | 0 | { |
454 | 0 | pcPPS->setLoopFilterAcrossTilesEnabledFlag( false ); |
455 | 0 | pcPPS->setRectSliceFlag( true ); |
456 | 0 | } |
457 | | |
458 | 0 | if( pcPPS->getRectSliceFlag() ) |
459 | 0 | { |
460 | 0 | X_READ_FLAG( pps_single_slice_per_subpic_flag ); |
461 | 0 | pcPPS->setSingleSlicePerSubPicFlag( pps_single_slice_per_subpic_flag ); |
462 | 0 | } |
463 | |
|
464 | 0 | if( pcPPS->getRectSliceFlag() && !pcPPS->getSingleSlicePerSubPicFlag() ) |
465 | 0 | { |
466 | 0 | X_READ_UVLC( pps_num_slices_in_pic_minus1, 0, MAX_SLICES - 1 /* TODO: should be MaxSlicesPerAU -1 */ ); |
467 | 0 | pcPPS->setNumSlicesInPic( pps_num_slices_in_pic_minus1 + 1 ); |
468 | |
|
469 | 0 | if( pps_num_slices_in_pic_minus1 > 1 ) |
470 | 0 | { |
471 | 0 | X_READ_FLAG( pps_tile_idx_delta_present_flag ); |
472 | 0 | pcPPS->setTileIdxDeltaPresentFlag( pps_tile_idx_delta_present_flag ); |
473 | 0 | } |
474 | 0 | pcPPS->initRectSlices(); |
475 | |
|
476 | 0 | int32_t tileIdx = 0; |
477 | | // read rectangular slice parameters |
478 | 0 | for( int sliceIdx = 0; sliceIdx < pcPPS->getNumSlicesInPic() - 1; sliceIdx++ ) |
479 | 0 | { |
480 | 0 | pcPPS->setSliceTileIdx( sliceIdx, tileIdx ); // this is SliceTopLeftTileIdx[ i ] |
481 | | |
482 | | // complete tiles within a single slice |
483 | 0 | if( tileIdx % pcPPS->getNumTileColumns() != pcPPS->getNumTileColumns() - 1 ) |
484 | 0 | { |
485 | 0 | X_READ_UVLC_idx( pps_slice_width_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileColumns() - 1 ); |
486 | 0 | pcPPS->setSliceWidthInTiles( sliceIdx, pps_slice_width_in_tiles_minus1 + 1 ); |
487 | 0 | } |
488 | 0 | else |
489 | 0 | { |
490 | 0 | pcPPS->setSliceWidthInTiles( sliceIdx, 1 ); |
491 | 0 | } |
492 | |
|
493 | 0 | if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1 |
494 | 0 | && ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) ) |
495 | 0 | { |
496 | 0 | X_READ_UVLC_idx( pps_slice_height_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileRows() - 1 ); |
497 | 0 | pcPPS->setSliceHeightInTiles( sliceIdx, pps_slice_height_in_tiles_minus1 + 1 ); |
498 | 0 | } |
499 | 0 | else |
500 | 0 | { |
501 | 0 | if( tileIdx / pcPPS->getNumTileColumns() == pcPPS->getNumTileRows() - 1 ) |
502 | 0 | { |
503 | 0 | pcPPS->setSliceHeightInTiles( sliceIdx, 1 ); |
504 | 0 | } |
505 | 0 | else |
506 | 0 | { |
507 | 0 | pcPPS->setSliceHeightInTiles( sliceIdx, pcPPS->getSliceHeightInTiles( sliceIdx - 1 ) ); |
508 | 0 | } |
509 | 0 | } |
510 | | |
511 | | // multiple slices within a single tile special case |
512 | 0 | if( pcPPS->getSliceWidthInTiles( sliceIdx ) == 1 && pcPPS->getSliceHeightInTiles( sliceIdx ) == 1 ) |
513 | 0 | { |
514 | 0 | if( pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) > 1 ) |
515 | 0 | { |
516 | 0 | X_READ_UVLC_idx( pps_num_exp_slices_in_tile, "[i]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 ); |
517 | 0 | if( pps_num_exp_slices_in_tile == 0 ) |
518 | 0 | { |
519 | 0 | pcPPS->setNumSlicesInTile( sliceIdx, 1 ); |
520 | 0 | pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) ); |
521 | 0 | } |
522 | 0 | else // ( pps_num_exp_slices_in_tile > 0 ) |
523 | 0 | { |
524 | 0 | uint32_t remTileRowHeight = pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ); |
525 | 0 | uint32_t lastExpSliceHeightInCtus = 0; |
526 | |
|
527 | 0 | int j = 0; |
528 | 0 | for( ; j < pps_num_exp_slices_in_tile; j++ ) |
529 | 0 | { |
530 | 0 | X_READ_UVLC_idx( pps_exp_slice_height_in_ctus_minus1, "[i][j]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 ); |
531 | 0 | pcPPS->setSliceHeightInCtu( sliceIdx + j, pps_exp_slice_height_in_ctus_minus1 + 1 ); |
532 | 0 | remTileRowHeight -= ( pps_exp_slice_height_in_ctus_minus1 + 1 ); |
533 | |
|
534 | 0 | lastExpSliceHeightInCtus = pps_exp_slice_height_in_ctus_minus1 + 1; |
535 | 0 | } |
536 | |
|
537 | 0 | uint32_t uniformSliceHeight = lastExpSliceHeightInCtus; |
538 | 0 | while( remTileRowHeight >= uniformSliceHeight ) |
539 | 0 | { |
540 | 0 | pcPPS->setSliceHeightInCtu( sliceIdx + j, uniformSliceHeight ); |
541 | 0 | remTileRowHeight -= uniformSliceHeight; |
542 | 0 | j++; |
543 | 0 | } |
544 | 0 | if( remTileRowHeight > 0 ) |
545 | 0 | { |
546 | 0 | pcPPS->setSliceHeightInCtu( sliceIdx + j, remTileRowHeight ); |
547 | 0 | j++; |
548 | 0 | } |
549 | 0 | for( int k = 0; k < j; k++ ) |
550 | 0 | { |
551 | 0 | pcPPS->setNumSlicesInTile( sliceIdx + k, j ); |
552 | 0 | pcPPS->setSliceWidthInTiles( sliceIdx + k, 1 ); |
553 | 0 | pcPPS->setSliceHeightInTiles( sliceIdx + k, 1 ); |
554 | 0 | pcPPS->setSliceTileIdx( sliceIdx + k, tileIdx ); |
555 | 0 | } |
556 | 0 | sliceIdx += ( j - 1 ); |
557 | 0 | } // ( pps_num_exp_slices_in_tile > 0 ) |
558 | 0 | } |
559 | 0 | else // ( pps->getTileRowHeight( tileIdx / pps->getNumTileColumns() ) <= 1 ) |
560 | 0 | { |
561 | 0 | pcPPS->setNumSlicesInTile( sliceIdx, 1 ); |
562 | 0 | pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) ); |
563 | 0 | } |
564 | 0 | } // ( pps->getSliceWidthInTiles(sliceIdx) == 1 && pps->getSliceHeightInTiles(sliceIdx) == 1 ) |
565 | | |
566 | | // tile index offset to start of next slice |
567 | 0 | if( sliceIdx < pps_num_slices_in_pic_minus1 ) |
568 | 0 | { |
569 | 0 | if( pcPPS->getTileIdxDeltaPresentFlag() ) |
570 | 0 | { |
571 | 0 | X_READ_SVLC_idx( pps_tile_idx_delta_val, "[i]", -(int) pcPPS->getNumTiles() + 1, (int) pcPPS->getNumTiles() - 1 ); |
572 | 0 | CHECK( pps_tile_idx_delta_val == 0, "When present, the value of pps_tile_idx_delta_val[ i ] shall not be equal to 0." ); |
573 | | |
574 | | // TODO: When pps_rect_slice_flag is equal to 1, it is a requirement of bitstrream conformance that, for any two slices, with picture- |
575 | | // level slice indices idxA and idxB, that belong to the same picture and different subpictures, when |
576 | | // SubpicIdxForSlice[idxA] is less than SubpicIdxForSlice[idxB], the value of idxA shall be less than idxB. |
577 | | // CHECK( pps->getRectSliceFlag() && /* TODO */ ) |
578 | |
|
579 | 0 | tileIdx += pps_tile_idx_delta_val; |
580 | 0 | CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." ); |
581 | 0 | } |
582 | 0 | else |
583 | 0 | { |
584 | 0 | tileIdx += pcPPS->getSliceWidthInTiles( sliceIdx ); |
585 | 0 | if( tileIdx % pcPPS->getNumTileColumns() == 0 ) |
586 | 0 | { |
587 | 0 | tileIdx += ( pcPPS->getSliceHeightInTiles( sliceIdx ) - 1 ) * pcPPS->getNumTileColumns(); |
588 | 0 | } |
589 | 0 | } |
590 | 0 | } |
591 | | // TODO: hier? |
592 | 0 | CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." ); |
593 | |
|
594 | 0 | } // for( int i = 0; i < pps->getNumSlicesInPic()-1; i++ ) |
595 | 0 | pcPPS->setSliceTileIdx( pcPPS->getNumSlicesInPic() - 1, tileIdx ); |
596 | |
|
597 | 0 | } // if( pps->getRectSliceFlag() && !pps->getSingleSlicePerSubPicFlag() ) |
598 | | |
599 | 0 | if( !pcPPS->getRectSliceFlag() || pcPPS->getSingleSlicePerSubPicFlag() || pcPPS->getNumSlicesInPic() > 1 ) |
600 | 0 | { |
601 | 0 | X_READ_FLAG( pps_loop_filter_across_slices_enabled_flag ); |
602 | 0 | pcPPS->setLoopFilterAcrossSlicesEnabledFlag( pps_loop_filter_across_slices_enabled_flag ); |
603 | 0 | } |
604 | 0 | else |
605 | 0 | { |
606 | 0 | pcPPS->setLoopFilterAcrossSlicesEnabledFlag( false ); |
607 | 0 | } |
608 | 0 | } |
609 | 2 | else // if( !pps_no_pic_partition_flag ) |
610 | 2 | { |
611 | | // When pps_no_pic_partition_flag is equal to 1, the value of pps_single_slice_per_subpic_flag is inferred to be equal to 1. |
612 | 2 | pcPPS->setSingleSlicePerSubPicFlag( 1 ); |
613 | 2 | } |
614 | | |
615 | 2 | X_READ_FLAG( pps_cabac_init_present_flag ); |
616 | 2 | pcPPS->setCabacInitPresentFlag( pps_cabac_init_present_flag ); |
617 | | |
618 | 2 | { |
619 | 2 | X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[0]", 0, 14 ); |
620 | 2 | pcPPS->setNumRefIdxL0DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 ); |
621 | 2 | } |
622 | 2 | { |
623 | 2 | X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[1]", 0, 14 ); |
624 | 2 | pcPPS->setNumRefIdxL1DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 ); |
625 | 2 | } |
626 | | |
627 | 2 | X_READ_FLAG( pps_rpl1_idx_present_flag ); |
628 | 2 | pcPPS->setRpl1IdxPresentFlag( pps_rpl1_idx_present_flag ); |
629 | | |
630 | 2 | X_READ_FLAG_CHECK( pps_weighted_pred_flag, |
631 | 2 | sps->getUseWP() == 0 && pps_weighted_pred_flag != 0, |
632 | 2 | "sps_weighted_pred_flag is equal to 0, the value of pps_weighted_pred_flag shall be equal to 0." ); |
633 | 2 | pcPPS->setUseWP( pps_weighted_pred_flag ); |
634 | | |
635 | 2 | X_READ_FLAG_CHECK( pps_weighted_bipred_flag, |
636 | 2 | sps->getUseWPBiPred() == 0 && pps_weighted_bipred_flag != 0, |
637 | 2 | "When sps_weighted_bipred_flag is equal to 0, the value of pps_weighted_bipred_flag shall be equal to 0." ); |
638 | 2 | pcPPS->setWPBiPred( pps_weighted_bipred_flag ); |
639 | | |
640 | 2 | X_READ_FLAG_CHECK( pps_ref_wraparound_enabled_flag, |
641 | 2 | ( sps->getUseWrapAround() == 0 || CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1 ) |
642 | 2 | && pps_ref_wraparound_enabled_flag != 0, |
643 | 2 | "When sps_ref_wraparound_enabled_flag is equal to 0 or the value of CtbSizeY / MinCbSizeY + 1 is greater than" |
644 | 2 | " pps_pic_width_in_luma_samples / MinCbSizeY − 1, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." ); |
645 | 2 | pcPPS->setUseWrapAround( pps_ref_wraparound_enabled_flag ); |
646 | | |
647 | 2 | if( pps_ref_wraparound_enabled_flag ) |
648 | 0 | { |
649 | 0 | X_READ_UVLC( pps_pic_width_minus_wraparound_offset, 0, ( pps_pic_width_in_luma_samples / MinCbSizeY ) - ( CtbSizeY / MinCbSizeY ) - 2 ); |
650 | 0 | pcPPS->setPicWidthMinusWrapAroundOffset( pps_pic_width_minus_wraparound_offset ); |
651 | 0 | } |
652 | | |
653 | 2 | X_READ_SVLC( pps_init_qp_minus26, -( 26 + sps->getQpBDOffset() ), 37 ); |
654 | 2 | pcPPS->setPicInitQPMinus26( pps_init_qp_minus26 ); |
655 | | |
656 | 2 | X_READ_FLAG( pps_cu_qp_delta_enabled_flag ); |
657 | 2 | pcPPS->setUseDQP( pps_cu_qp_delta_enabled_flag ); |
658 | | |
659 | 2 | X_READ_FLAG_CHECK( pps_chroma_tool_offsets_present_flag, |
660 | 2 | sps->getChromaFormatIdc() == 0 && pps_chroma_tool_offsets_present_flag != 0, |
661 | 2 | "When sps_chroma_format_idc is equal to 0, the value of pps_chroma_tool_offsets_present_flag shall be equal to 0." ); |
662 | 2 | pcPPS->setPPSChromaToolFlag( pps_chroma_tool_offsets_present_flag ); |
663 | | |
664 | 2 | if( pps_chroma_tool_offsets_present_flag ) |
665 | 0 | { |
666 | 0 | X_READ_SVLC( pps_cb_qp_offset, -12, 12 ); |
667 | 0 | pcPPS->setQpOffset( COMPONENT_Cb, pps_cb_qp_offset ); |
668 | |
|
669 | 0 | X_READ_SVLC( pps_cr_qp_offset, -12, 12 ); |
670 | 0 | pcPPS->setQpOffset( COMPONENT_Cr, pps_cr_qp_offset ); |
671 | |
|
672 | 0 | X_READ_FLAG_CHECK( pps_joint_cbcr_qp_offset_present_flag, |
673 | 0 | ( sps->getChromaFormatIdc() == 0 || sps->getJointCbCrEnabledFlag() == 0 ) && pps_joint_cbcr_qp_offset_present_flag != 0, |
674 | 0 | "When sps_chroma_format_idc is equal to 0 or sps_joint_cbcr_enabled_flag is equal to 0, the value of" |
675 | 0 | " pps_joint_cbcr_qp_offset_present_flag shall be equal to 0." ); |
676 | 0 | pcPPS->setJointCbCrQpOffsetPresentFlag( pps_joint_cbcr_qp_offset_present_flag ); |
677 | |
|
678 | 0 | if( pps_joint_cbcr_qp_offset_present_flag ) |
679 | 0 | { |
680 | 0 | X_READ_SVLC( pps_joint_cbcr_qp_offset_value, -12, 12 ); |
681 | 0 | pcPPS->setQpOffset( JOINT_CbCr, pps_joint_cbcr_qp_offset_value ); |
682 | 0 | } |
683 | 0 | else |
684 | 0 | { |
685 | 0 | pcPPS->setQpOffset( JOINT_CbCr, 0 ); |
686 | 0 | } |
687 | |
|
688 | 0 | X_READ_FLAG( pps_slice_chroma_qp_offsets_present_flag ); |
689 | 0 | pcPPS->setSliceChromaQpFlag( pps_slice_chroma_qp_offsets_present_flag ); |
690 | |
|
691 | 0 | X_READ_FLAG( pps_cu_chroma_qp_offset_list_enabled_flag ); |
692 | 0 | if( !pps_cu_chroma_qp_offset_list_enabled_flag ) |
693 | 0 | { |
694 | 0 | pcPPS->clearChromaQpOffsetList(); |
695 | 0 | } |
696 | 0 | else |
697 | 0 | { |
698 | 0 | X_READ_UVLC( pps_chroma_qp_offset_list_len_minus1, 0, MAX_QP_OFFSET_LIST_SIZE - 1 ); |
699 | |
|
700 | 0 | for( int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx <= pps_chroma_qp_offset_list_len_minus1; cuChromaQpOffsetIdx++ ) |
701 | 0 | { |
702 | 0 | X_READ_SVLC_idx( pps_cb_qp_offset_list, "[i]", -12, 12 ); |
703 | 0 | X_READ_SVLC_idx( pps_cr_qp_offset_list, "[i]", -12, 12 ); |
704 | 0 | int jointCbCrOffset = 0; |
705 | 0 | if( pps_joint_cbcr_qp_offset_present_flag ) |
706 | 0 | { |
707 | 0 | X_READ_SVLC_idx( pps_joint_cbcr_qp_offset_list, "[i]", -12, 12 ); |
708 | 0 | jointCbCrOffset = pps_joint_cbcr_qp_offset_list; |
709 | 0 | } |
710 | | // table uses +1 for index (see comment inside the function) |
711 | 0 | pcPPS->setChromaQpOffsetListEntry( cuChromaQpOffsetIdx + 1, pps_cb_qp_offset_list, pps_cr_qp_offset_list, jointCbCrOffset ); |
712 | 0 | } |
713 | 0 | CHECK( pcPPS->getChromaQpOffsetListLen() != pps_chroma_qp_offset_list_len_minus1 + 1, "Invalid chroma QP offset list length" ); |
714 | 0 | } |
715 | 0 | } |
716 | 2 | else |
717 | 2 | { |
718 | 2 | pcPPS->setQpOffset( COMPONENT_Cb, 0 ); |
719 | 2 | pcPPS->setQpOffset( COMPONENT_Cr, 0 ); |
720 | 2 | pcPPS->setJointCbCrQpOffsetPresentFlag( 0 ); |
721 | 2 | pcPPS->setSliceChromaQpFlag( 0 ); |
722 | 2 | pcPPS->clearChromaQpOffsetList(); |
723 | 2 | } |
724 | | |
725 | 2 | X_READ_FLAG( pps_deblocking_filter_control_present_flag ); |
726 | 2 | pcPPS->setDeblockingFilterControlPresentFlag( pps_deblocking_filter_control_present_flag ); |
727 | | |
728 | 2 | if( pps_deblocking_filter_control_present_flag ) |
729 | 0 | { |
730 | 0 | X_READ_FLAG( pps_deblocking_filter_override_enabled_flag ); |
731 | 0 | pcPPS->setDeblockingFilterOverrideEnabledFlag( pps_deblocking_filter_override_enabled_flag ); |
732 | |
|
733 | 0 | X_READ_FLAG( pps_deblocking_filter_disabled_flag ); |
734 | 0 | pcPPS->setPPSDeblockingFilterDisabledFlag( pps_deblocking_filter_disabled_flag ); |
735 | |
|
736 | 0 | if( !pps_no_pic_partition_flag && pps_deblocking_filter_override_enabled_flag ) |
737 | 0 | { |
738 | 0 | X_READ_FLAG( pps_dbf_info_in_ph_flag ); |
739 | 0 | pcPPS->setDbfInfoInPhFlag( pps_dbf_info_in_ph_flag ); |
740 | 0 | } |
741 | |
|
742 | 0 | if( !pps_deblocking_filter_disabled_flag ) |
743 | 0 | { |
744 | 0 | X_READ_SVLC( pps_luma_beta_offset_div2, -12, 12 ); |
745 | 0 | pcPPS->setDeblockingFilterBetaOffsetDiv2( pps_luma_beta_offset_div2 ); |
746 | |
|
747 | 0 | X_READ_SVLC( pps_luma_tc_offset_div2, -12, 12 ); |
748 | 0 | pcPPS->setDeblockingFilterTcOffsetDiv2( pps_luma_tc_offset_div2 ); |
749 | |
|
750 | 0 | if( pps_chroma_tool_offsets_present_flag ) |
751 | 0 | { |
752 | 0 | X_READ_SVLC( pps_cb_beta_offset_div2, -12, 12 ); |
753 | 0 | pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_cb_beta_offset_div2 ); |
754 | |
|
755 | 0 | X_READ_SVLC( pps_cb_tc_offset_div2, -12, 12 ); |
756 | 0 | pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_cb_tc_offset_div2 ); |
757 | |
|
758 | 0 | X_READ_SVLC( pps_cr_beta_offset_div2, -12, 12 ); |
759 | 0 | pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_cr_beta_offset_div2 ); |
760 | |
|
761 | 0 | X_READ_SVLC( pps_cr_tc_offset_div2, -12, 12 ); |
762 | 0 | pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_cr_tc_offset_div2 ); |
763 | 0 | } |
764 | 0 | else |
765 | 0 | { |
766 | 0 | pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_luma_beta_offset_div2 ); |
767 | 0 | pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_luma_tc_offset_div2 ); |
768 | 0 | pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_luma_beta_offset_div2 ); |
769 | 0 | pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_luma_tc_offset_div2 ); |
770 | 0 | } |
771 | 0 | } |
772 | 0 | } |
773 | | |
774 | 2 | if( !pps_no_pic_partition_flag ) |
775 | 0 | { |
776 | 0 | X_READ_FLAG( pps_rpl_info_in_ph_flag ); |
777 | 0 | pcPPS->setRplInfoInPhFlag( pps_rpl_info_in_ph_flag ); |
778 | |
|
779 | 0 | X_READ_FLAG( pps_sao_info_in_ph_flag ); |
780 | 0 | pcPPS->setSaoInfoInPhFlag( pps_sao_info_in_ph_flag ); |
781 | |
|
782 | 0 | X_READ_FLAG( pps_alf_info_in_ph_flag ); |
783 | 0 | pcPPS->setAlfInfoInPhFlag( pps_alf_info_in_ph_flag ); |
784 | |
|
785 | 0 | if( ( pps_weighted_pred_flag || pps_weighted_bipred_flag ) && pps_rpl_info_in_ph_flag ) |
786 | 0 | { |
787 | 0 | X_READ_FLAG( pps_wp_info_in_ph_flag ); |
788 | 0 | pcPPS->setWpInfoInPhFlag( pps_wp_info_in_ph_flag ); |
789 | 0 | } |
790 | |
|
791 | 0 | X_READ_FLAG( pps_qp_delta_info_in_ph_flag ); |
792 | 0 | pcPPS->setQpDeltaInfoInPhFlag( pps_qp_delta_info_in_ph_flag ); |
793 | 0 | } |
794 | | |
795 | 2 | X_READ_FLAG( pps_picture_header_extension_present_flag ); |
796 | 2 | pcPPS->setPictureHeaderExtensionPresentFlag( pps_picture_header_extension_present_flag ); |
797 | | |
798 | 2 | X_READ_FLAG( pps_slice_header_extension_present_flag ); |
799 | 2 | pcPPS->setSliceHeaderExtensionPresentFlag( pps_slice_header_extension_present_flag ); |
800 | | |
801 | 2 | X_READ_FLAG( pps_extension_flag ); |
802 | 2 | if( pps_extension_flag ) |
803 | 0 | { |
804 | 0 | while( xMoreRbspData() ) |
805 | 0 | { |
806 | 0 | X_READ_FLAG( pps_extension_data_flag ); |
807 | 0 | (void) pps_extension_data_flag; |
808 | 0 | } |
809 | 0 | } |
810 | | |
811 | 2 | xReadRbspTrailingBits(); |
812 | | |
813 | | // ================================ |
814 | | // PPS READING DONE |
815 | | // ================================ |
816 | | |
817 | 2 | if( pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples() && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples() ) |
818 | 0 | { |
819 | 0 | CHECK( pcPPS->getConformanceWindowPresentFlag(), |
820 | 0 | "When pps_pic_width_in_luma_samples is equal to sps_pic_width_max_in_luma_samples and " |
821 | 0 | "pps_pic_height_in_luma_samples is equal to sps_pic_height_max_in_luma_samples, the value of " |
822 | 0 | "pps_conformance_window_flag shall be equal to 0" ); |
823 | |
|
824 | 0 | pcPPS->setConformanceWindow( sps->getConformanceWindow() ); |
825 | |
|
826 | 0 | if( !pcPPS->getScalingWindow().getWindowEnabledFlag() ) |
827 | 0 | { |
828 | 0 | pcPPS->setScalingWindow( pcPPS->getConformanceWindow() ); |
829 | 0 | } |
830 | 0 | } |
831 | | |
832 | 2 | pcPPS->finalizePPSPartitioning( sps ); |
833 | | |
834 | | // set wraparound offset from PPS and SPS info |
835 | 2 | int minCbSizeY = ( 1 << sps->getLog2MinCodingBlockSize() ); |
836 | 2 | CHECK( !sps->getUseWrapAround() && pcPPS->getUseWrapAround(), |
837 | 2 | "When sps_ref_wraparound_enabled_flag is equal to 0, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." ); |
838 | 2 | CHECK( sps->getCTUSize() / minCbSizeY + 1 > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - 1 && pcPPS->getUseWrapAround(), |
839 | 2 | "When the value of CtbSizeY / MinCbSizeY + 1 is greater than pic_width_in_luma_samples / MinCbSizeY - 1, the value of " |
840 | 2 | "pps_ref_wraparound_enabled_flag shall be equal to 0." ); |
841 | 2 | if( pcPPS->getUseWrapAround() ) |
842 | 0 | { |
843 | 0 | CHECK( pcPPS->getPicWidthMinusWrapAroundOffset() > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - sps->getCTUSize() / minCbSizeY - 2, |
844 | 0 | "pps_pic_width_minus_wraparound_ofsfet shall be less than or equal to pps_pic_width_in_luma_samples/MinCbSizeY - CtbSizeY/MinCbSizeY-2" ); |
845 | 0 | pcPPS->setWrapAroundOffset( minCbSizeY * ( pcPPS->getPicWidthInLumaSamples() / minCbSizeY - pcPPS->getPicWidthMinusWrapAroundOffset() ) ); |
846 | 0 | } |
847 | 2 | else |
848 | 2 | { |
849 | 2 | pcPPS->setWrapAroundOffset( 0 ); |
850 | 2 | } |
851 | | |
852 | 2 | pcPPS->pcv = std::make_unique<PreCalcValues>( *sps, *pcPPS ); |
853 | 2 | } |
854 | | |
855 | | bool HLSyntaxReader::parseAPS( APS* aps ) |
856 | 132 | { |
857 | | #if ENABLE_TRACING |
858 | | xTraceAPSHeader(); |
859 | | #endif |
860 | | |
861 | 132 | X_READ_CODE_NO_RANGE( aps_params_type, 3 ); |
862 | | // if not in supported range, this APS is ignored `switch() -> default` |
863 | 132 | aps->setAPSType( aps_params_type ); |
864 | | |
865 | 132 | X_READ_CODE_NO_RANGE( adaptation_parameter_set_id, 5 ); |
866 | | // range check happens later in the `switch( aps_params_type )` |
867 | 132 | aps->setAPSId( adaptation_parameter_set_id ); |
868 | | |
869 | 132 | X_READ_FLAG( aps_chroma_present_flag ); |
870 | 132 | aps->chromaPresentFlag = aps_chroma_present_flag; |
871 | | |
872 | 132 | switch( aps_params_type ) |
873 | 132 | { |
874 | 64 | case ALF_APS: |
875 | 64 | CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for ALF_APS" ); |
876 | 62 | parseAlfAps( aps ); |
877 | 62 | break; |
878 | 16 | case LMCS_APS: |
879 | 16 | CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 3, "adaptation_parameter_set_id for LMCS_APS," ); |
880 | 16 | parseLmcsAps( aps ); |
881 | 16 | break; |
882 | 48 | case SCALING_LIST_APS: |
883 | 48 | CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for SCALING_APS" ); |
884 | 46 | parseScalingListAps( aps ); |
885 | 46 | break; |
886 | 4 | default: |
887 | 4 | WARN( "unknown APS type (" << aps_params_type << ")" ); |
888 | 4 | return false; |
889 | 132 | } |
890 | | |
891 | 44 | X_READ_FLAG( aps_extension_flag ); |
892 | 44 | if( aps_extension_flag ) |
893 | 32 | { |
894 | 2.75k | while( xMoreRbspData() ) |
895 | 2.72k | { |
896 | 2.72k | X_READ_FLAG( aps_extension_data_flag ); |
897 | 2.72k | (void) aps_extension_data_flag; |
898 | 2.72k | } |
899 | 32 | } |
900 | 44 | xReadRbspTrailingBits(); |
901 | | |
902 | 44 | return true; |
903 | 132 | } |
904 | | |
905 | | void HLSyntaxReader::parseAlfAps( APS* aps ) |
906 | 62 | { |
907 | 62 | AlfSliceParam& param = aps->getAlfAPSParam(); |
908 | 62 | param.reset(); |
909 | | |
910 | 62 | X_READ_FLAG( alf_luma_new_filter ); // standard: alf_luma_filter_signal_flag |
911 | 62 | param.newFilterFlag[CHANNEL_TYPE_LUMA] = alf_luma_new_filter; |
912 | | |
913 | 62 | CcAlfFilterParam& ccAlfParam = aps->getCcAlfAPSParam(); |
914 | 62 | ccAlfParam.reset(); |
915 | 62 | if( aps->chromaPresentFlag ) |
916 | 36 | { |
917 | 36 | X_READ_FLAG( alf_chroma_new_filter ); // standard: alf_chroma_filter_signal_flag |
918 | 36 | param.newFilterFlag[CHANNEL_TYPE_CHROMA] = alf_chroma_new_filter; |
919 | | |
920 | 36 | X_READ_FLAG( alf_cc_cb_filter_signal_flag ); |
921 | 36 | ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = alf_cc_cb_filter_signal_flag; |
922 | | |
923 | 36 | X_READ_FLAG( alf_cc_cr_filter_signal_flag ); |
924 | 36 | ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = alf_cc_cr_filter_signal_flag; |
925 | 36 | } |
926 | 62 | CHECK( param.newFilterFlag[CHANNEL_TYPE_LUMA] == 0 && param.newFilterFlag[CHANNEL_TYPE_CHROMA] == 0 |
927 | 62 | && ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] == 0 && ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] == 0, |
928 | 62 | "bitstream conformance error: one of alf_luma_filter_signal_flag, alf_chroma_filter_signal_flag, " |
929 | 62 | "alf_cross_component_cb_filter_signal_flag, and alf_cross_component_cr_filter_signal_flag shall be nonzero" ); |
930 | | |
931 | | // The variable NumAlfFilters specifying the number of different adaptive loop filters is set equal to 25. |
932 | 60 | static constexpr int NumAlfFilters = MAX_NUM_ALF_CLASSES; |
933 | | |
934 | 60 | if( alf_luma_new_filter ) |
935 | 34 | { |
936 | 34 | X_READ_FLAG( alf_luma_clip ); |
937 | 34 | param.nonLinearFlagLuma = alf_luma_clip; |
938 | | |
939 | 34 | X_READ_UVLC( alf_luma_num_filters_signalled_minus1, 0, NumAlfFilters - 1 ); |
940 | 34 | param.numLumaFilters = alf_luma_num_filters_signalled_minus1 + 1; |
941 | | |
942 | 34 | if( alf_luma_num_filters_signalled_minus1 > 0 ) |
943 | 14 | { |
944 | 14 | const int length = (int) ceil( log2( alf_luma_num_filters_signalled_minus1 + 1 ) ); |
945 | 244 | for( int filtIdx = 0; filtIdx < NumAlfFilters; filtIdx++ ) |
946 | 230 | { |
947 | 230 | X_READ_CODE( alf_luma_coeff_delta_idx, length, 0, alf_luma_num_filters_signalled_minus1 ); |
948 | 230 | param.filterCoeffDeltaIdx[filtIdx] = alf_luma_coeff_delta_idx; |
949 | 230 | } |
950 | 14 | } |
951 | | |
952 | 34 | alfFilterCoeffs( param, false, 0 ); |
953 | 34 | } |
954 | | |
955 | 60 | if( param.newFilterFlag[CHANNEL_TYPE_CHROMA] ) |
956 | 10 | { |
957 | 10 | X_READ_FLAG( alf_nonlinear_enable_flag_chroma ); |
958 | 10 | param.nonLinearFlagChroma = alf_nonlinear_enable_flag_chroma; |
959 | | |
960 | 10 | X_READ_UVLC( alf_chroma_num_alts_minus1, 0, MAX_NUM_ALF_ALTERNATIVES_CHROMA - 1 ); |
961 | 10 | param.numAlternativesChroma = alf_chroma_num_alts_minus1 + 1; |
962 | | |
963 | 30 | for( int altIdx = 0; altIdx <= alf_chroma_num_alts_minus1; ++altIdx ) |
964 | 20 | { |
965 | 20 | alfFilterCoeffs( param, true, altIdx ); |
966 | 20 | } |
967 | 10 | } |
968 | | |
969 | 124 | for( int ccIdx = 0; ccIdx < 2; ccIdx++ ) |
970 | 70 | { |
971 | 70 | if( ccAlfParam.newCcAlfFilter[ccIdx] ) |
972 | 22 | { |
973 | 22 | uint32_t code; |
974 | 22 | READ_UVLC( code, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" ); |
975 | 22 | CHECK_READ_RANGE( code, 0, 3, ( ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" ) ) |
976 | | |
977 | 16 | ccAlfParam.ccAlfFilterCount[ccIdx] = code + 1; |
978 | | |
979 | 42 | for( int filterIdx = 0; filterIdx < ccAlfParam.ccAlfFilterCount[ccIdx]; filterIdx++ ) |
980 | 26 | { |
981 | 26 | ccAlfParam.ccAlfFilterIdxEnabled[ccIdx][filterIdx] = true; |
982 | | |
983 | 26 | const int numCoeff = g_alfNumCoeff[CC_ALF]; |
984 | | |
985 | 26 | short* coeff = ccAlfParam.ccAlfCoeff[ccIdx][filterIdx]; |
986 | | // Filter coefficients |
987 | 194 | for( int i = 0; i < numCoeff - 1; i++ ) |
988 | 168 | { |
989 | 168 | READ_CODE( 3, code, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs" ); |
990 | 168 | if( code ) |
991 | 74 | { |
992 | 74 | coeff[i] = 1 << ( code - 1 ); |
993 | | |
994 | 74 | READ_FLAG( code, ccIdx == 0 ? "alf_cc_cb_coeff_sign" : "alf_cc_cr_coeff_sign" ); |
995 | 74 | coeff[i] *= 1 - 2 * code; |
996 | 74 | } |
997 | 94 | else |
998 | 94 | { |
999 | 94 | coeff[i] = 0; |
1000 | 94 | } |
1001 | 168 | } |
1002 | | |
1003 | 26 | DTRACE( g_trace_ctx, D_SYNTAX, "%s coeff filterIdx %d: ", ccIdx == 0 ? "Cb" : "Cr", filterIdx ); |
1004 | 186 | for( int i = 0; i < numCoeff; i++ ) |
1005 | 160 | { |
1006 | 160 | DTRACE( g_trace_ctx, D_SYNTAX, "%d ", coeff[i] ); |
1007 | 160 | } |
1008 | 26 | DTRACE( g_trace_ctx, D_SYNTAX, "\n" ); |
1009 | 26 | } |
1010 | 16 | } |
1011 | 70 | } |
1012 | 60 | } |
1013 | | |
1014 | | void HLSyntaxReader::parseLmcsAps( APS* aps ) |
1015 | 16 | { |
1016 | 16 | SliceReshapeInfo& info = aps->getReshaperAPSInfo(); |
1017 | 16 | info.reset(); |
1018 | | |
1019 | 16 | X_READ_UVLC( lmcs_min_bin_idx, 0, 15 ); |
1020 | 16 | info.reshaperModelMinBinIdx = lmcs_min_bin_idx; |
1021 | | |
1022 | 16 | X_READ_UVLC( lmcs_delta_max_bin_idx, 0, 15 ); |
1023 | 16 | info.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1 - lmcs_delta_max_bin_idx; |
1024 | 16 | CHECK( info.reshaperModelMaxBinIdx < lmcs_min_bin_idx, "The value of LmcsMaxBinIdx shall be greater than or equal to lmcs_min_bin_idx." ); |
1025 | | |
1026 | 16 | X_READ_UVLC( lmcs_delta_cw_prec_minus1, 0, 14 ); |
1027 | 16 | info.maxNbitsNeededDeltaCW = lmcs_delta_cw_prec_minus1 + 1; |
1028 | | |
1029 | 16 | CHECK( info.maxNbitsNeededDeltaCW == 0, "wrong" ); |
1030 | | |
1031 | 166 | for( uint32_t i = info.reshaperModelMinBinIdx; i <= info.reshaperModelMaxBinIdx; i++ ) |
1032 | 150 | { |
1033 | 150 | X_READ_CODE_NO_RANGE_idx( lmcs_delta_abs_cw, "[ i ]", info.maxNbitsNeededDeltaCW ); |
1034 | 150 | info.reshaperModelBinCWDelta[i] = lmcs_delta_abs_cw; |
1035 | 150 | if( lmcs_delta_abs_cw ) |
1036 | 96 | { |
1037 | 96 | X_READ_FLAG_idx( lmcs_delta_sign_cw_flag, "[ i ]" ); |
1038 | 96 | info.reshaperModelBinCWDelta[i] *= 1 - 2 * lmcs_delta_sign_cw_flag; |
1039 | 96 | } |
1040 | | // lmcsCW[i] range is checked in Reshape::constructReshaper() |
1041 | 150 | } |
1042 | | |
1043 | 16 | if( aps->chromaPresentFlag ) |
1044 | 8 | { |
1045 | 8 | X_READ_CODE_NO_RANGE( lmcs_delta_abs_crs, 3 ); |
1046 | 8 | info.chrResScalingOffset = lmcs_delta_abs_crs; |
1047 | 8 | if( lmcs_delta_abs_crs > 0 ) |
1048 | 6 | { |
1049 | 6 | X_READ_FLAG( lmcs_delta_sign_crs_flag ); |
1050 | 6 | info.chrResScalingOffset *= ( 1 - 2 * lmcs_delta_sign_crs_flag ); |
1051 | 6 | } |
1052 | | // lmcsDeltaCrs range is checked in Reshape::constructReshaper() |
1053 | 8 | } |
1054 | 16 | } |
1055 | | |
1056 | | void HLSyntaxReader::parseScalingListAps( APS* aps ) |
1057 | 46 | { |
1058 | 46 | ScalingList& info = aps->getScalingList(); |
1059 | 46 | parseScalingList( &info, aps->chromaPresentFlag ); |
1060 | 46 | } |
1061 | | |
1062 | | static const int SARFixedRatios[][2] = |
1063 | | { |
1064 | | { 1, 1 }, |
1065 | | { 12, 11 }, |
1066 | | { 10, 11 }, |
1067 | | { 16, 11 }, |
1068 | | { 40, 33 }, |
1069 | | { 24, 11 }, |
1070 | | { 20, 11 }, |
1071 | | { 32, 11 }, |
1072 | | { 80, 33 }, |
1073 | | { 18, 11 }, |
1074 | | { 15, 11 }, |
1075 | | { 64, 33 }, |
1076 | | { 160, 99 }, |
1077 | | { 4, 3 }, |
1078 | | { 3, 2 }, |
1079 | | { 2, 1 }, |
1080 | | }; |
1081 | | |
1082 | | void HLSyntaxReader::parseVUI( VUI* pcVUI, unsigned vuiPayloadSize ) |
1083 | 0 | { |
1084 | | #if ENABLE_TRACING |
1085 | | DTRACE( g_trace_ctx, D_HEADER, "----------- vui_parameters -----------\n"); |
1086 | | #endif |
1087 | 0 | InputBitstream *bs = getBitstream(); |
1088 | 0 | auto substream = bs->extractSubstream( vuiPayloadSize * 8 ); |
1089 | 0 | setBitstream( substream.get() ); |
1090 | |
|
1091 | 0 | X_READ_FLAG( vui_general_progressive_source_flag ); |
1092 | 0 | pcVUI->setProgressiveSourceFlag( vui_general_progressive_source_flag ); |
1093 | |
|
1094 | 0 | X_READ_FLAG( vui_general_interlaced_source_flag ); |
1095 | 0 | pcVUI->setInterlacedSourceFlag( vui_general_interlaced_source_flag ); |
1096 | |
|
1097 | 0 | X_READ_FLAG( vui_non_packed_constraint_flag ); |
1098 | 0 | pcVUI->setNonPackedFlag( vui_non_packed_constraint_flag ); |
1099 | |
|
1100 | 0 | X_READ_FLAG( vui_non_projected_constraint_flag ); |
1101 | 0 | pcVUI->setNonProjectedFlag( vui_non_projected_constraint_flag ); |
1102 | |
|
1103 | 0 | X_READ_FLAG( vui_aspect_ratio_info_present_flag ); |
1104 | 0 | pcVUI->setAspectRatioInfoPresentFlag( vui_aspect_ratio_info_present_flag ); |
1105 | |
|
1106 | 0 | if( vui_aspect_ratio_info_present_flag ) |
1107 | 0 | { |
1108 | 0 | X_READ_FLAG( vui_aspect_ratio_constant_flag ); |
1109 | 0 | pcVUI->setAspectRatioConstantFlag( vui_aspect_ratio_constant_flag ); |
1110 | |
|
1111 | 0 | X_READ_CODE_NO_RANGE( vui_aspect_ratio_idc, 8 ); |
1112 | 0 | pcVUI->setAspectRatioIdc( vui_aspect_ratio_idc ); |
1113 | |
|
1114 | 0 | if( pcVUI->getAspectRatioIdc() == 255 ) |
1115 | 0 | { |
1116 | 0 | X_READ_CODE_NO_RANGE( vui_sar_width, 16 ); |
1117 | 0 | pcVUI->setSarWidth( vui_sar_width ); |
1118 | |
|
1119 | 0 | X_READ_CODE_NO_RANGE( vui_sar_height, 16 ); |
1120 | 0 | pcVUI->setSarHeight( vui_sar_height ); |
1121 | 0 | } |
1122 | 0 | else if (pcVUI->getAspectRatioIdc() > 0 && (size_t)pcVUI->getAspectRatioIdc() <= sizeof(SARFixedRatios) / sizeof(SARFixedRatios[0])) |
1123 | 0 | { |
1124 | 0 | pcVUI->setSarWidth( SARFixedRatios[pcVUI->getAspectRatioIdc() - 1][0] ); |
1125 | 0 | pcVUI->setSarHeight( SARFixedRatios[pcVUI->getAspectRatioIdc() - 1][1] ); |
1126 | 0 | } |
1127 | 0 | } |
1128 | |
|
1129 | 0 | X_READ_FLAG( vui_overscan_info_present_flag ); |
1130 | 0 | pcVUI->setOverscanInfoPresentFlag( vui_overscan_info_present_flag ); |
1131 | |
|
1132 | 0 | if( vui_overscan_info_present_flag ) |
1133 | 0 | { |
1134 | 0 | X_READ_FLAG( vui_overscan_appropriate_flag ); |
1135 | 0 | pcVUI->setOverscanAppropriateFlag( vui_overscan_appropriate_flag ); |
1136 | 0 | } |
1137 | |
|
1138 | 0 | X_READ_FLAG( vui_colour_description_present_flag ); |
1139 | 0 | pcVUI->setColourDescriptionPresentFlag( vui_colour_description_present_flag ); |
1140 | |
|
1141 | 0 | if( vui_colour_description_present_flag ) |
1142 | 0 | { |
1143 | 0 | X_READ_CODE_NO_RANGE( vui_colour_primaries, 8 ); |
1144 | 0 | pcVUI->setColourPrimaries( vui_colour_primaries ); |
1145 | |
|
1146 | 0 | X_READ_CODE_NO_RANGE( vui_transfer_characteristics, 8 ); |
1147 | 0 | pcVUI->setTransferCharacteristics( vui_transfer_characteristics ); |
1148 | |
|
1149 | 0 | X_READ_CODE_NO_RANGE( vui_matrix_coeffs, 8 ); |
1150 | 0 | pcVUI->setMatrixCoefficients( vui_matrix_coeffs ); |
1151 | |
|
1152 | 0 | X_READ_FLAG( vui_video_full_range_flag ); |
1153 | 0 | pcVUI->setVideoFullRangeFlag( vui_video_full_range_flag ); |
1154 | 0 | } |
1155 | |
|
1156 | 0 | X_READ_FLAG( vui_chroma_loc_info_present_flag ); |
1157 | 0 | pcVUI->setChromaLocInfoPresentFlag( vui_chroma_loc_info_present_flag ); |
1158 | |
|
1159 | 0 | if( vui_chroma_loc_info_present_flag ) |
1160 | 0 | { |
1161 | 0 | if( vui_general_progressive_source_flag && !vui_general_interlaced_source_flag ) |
1162 | 0 | { |
1163 | 0 | X_READ_UVLC( vui_chroma_sample_loc_type_frame, 0, 6 ); |
1164 | 0 | pcVUI->setChromaSampleLocType( vui_chroma_sample_loc_type_frame ); |
1165 | 0 | } |
1166 | 0 | else |
1167 | 0 | { |
1168 | 0 | X_READ_UVLC( vui_chroma_sample_loc_type_top_field, 0, 6 ); |
1169 | 0 | pcVUI->setChromaSampleLocTypeTopField( vui_chroma_sample_loc_type_top_field ); |
1170 | |
|
1171 | 0 | X_READ_UVLC( vui_chroma_sample_loc_type_bottom_field, 0, 6 ); |
1172 | 0 | pcVUI->setChromaSampleLocTypeBottomField( vui_chroma_sample_loc_type_bottom_field ); |
1173 | 0 | } |
1174 | 0 | } |
1175 | |
|
1176 | 0 | int payloadBitsRem = getBitstream()->getNumBitsLeft(); |
1177 | 0 | if( payloadBitsRem ) //Corresponds to more_data_in_payload() |
1178 | 0 | { |
1179 | 0 | while( payloadBitsRem > 9 ) //payload_extension_present() |
1180 | 0 | { |
1181 | 0 | X_READ_FLAG( vui_reserved_payload_extension_data ); |
1182 | 0 | (void) vui_reserved_payload_extension_data; |
1183 | 0 | payloadBitsRem--; |
1184 | 0 | } |
1185 | 0 | int finalBits = getBitstream()->peekBits( payloadBitsRem ); |
1186 | 0 | int numFinalZeroBits = 0; |
1187 | 0 | int mask = 0xff; |
1188 | 0 | while( finalBits & (mask >> numFinalZeroBits) ) |
1189 | 0 | { |
1190 | 0 | numFinalZeroBits++; |
1191 | 0 | } |
1192 | 0 | while( payloadBitsRem > 9-numFinalZeroBits ) //payload_extension_present() |
1193 | 0 | { |
1194 | 0 | X_READ_FLAG( vui_reserved_payload_extension_data ); |
1195 | 0 | (void) vui_reserved_payload_extension_data; |
1196 | 0 | payloadBitsRem--; |
1197 | 0 | } |
1198 | 0 | X_READ_FLAG_CHECK( vui_payload_bit_equal_to_one, vui_payload_bit_equal_to_one != 1, "vui_payload_bit_equal_to_one not equal to 1" ); |
1199 | 0 | (void)vui_payload_bit_equal_to_one; |
1200 | 0 | payloadBitsRem--; |
1201 | 0 | while( payloadBitsRem ) |
1202 | 0 | { |
1203 | 0 | X_READ_FLAG_CHECK( vui_payload_bit_equal_to_zero, vui_payload_bit_equal_to_zero != 0, "vui_payload_bit_equal_to_zero not equal to 0" ); |
1204 | 0 | (void)vui_payload_bit_equal_to_zero; |
1205 | 0 | payloadBitsRem--; |
1206 | 0 | } |
1207 | 0 | } |
1208 | 0 | setBitstream( bs ); |
1209 | 0 | } |
1210 | | |
1211 | | void HLSyntaxReader::parseGeneralHrdParameters( GeneralHrdParams *hrd ) |
1212 | 0 | { |
1213 | 0 | X_READ_CODE_NO_RANGE( num_units_in_tick, 32 ); |
1214 | 0 | CHECK( num_units_in_tick <= 0, "num_units_in_tick shall be greater than 0" ); |
1215 | 0 | hrd->setNumUnitsInTick( num_units_in_tick ); |
1216 | |
|
1217 | 0 | X_READ_CODE_NO_RANGE( time_scale, 32 ); |
1218 | 0 | CHECK( time_scale <= 0, "The value of time_scale shall be greater than 0." ); |
1219 | 0 | hrd->setTimeScale( time_scale ); |
1220 | |
|
1221 | 0 | X_READ_FLAG( general_nal_hrd_params_present_flag ); |
1222 | 0 | hrd->setGeneralNalHrdParamsPresentFlag( general_nal_hrd_params_present_flag ); |
1223 | |
|
1224 | 0 | X_READ_FLAG( general_vcl_hrd_params_present_flag ); |
1225 | 0 | hrd->setGeneralVclHrdParamsPresentFlag( general_vcl_hrd_params_present_flag ); |
1226 | |
|
1227 | 0 | if( general_nal_hrd_params_present_flag || general_vcl_hrd_params_present_flag ) |
1228 | 0 | { |
1229 | 0 | X_READ_FLAG( general_same_pic_timing_in_all_ols_flag ); |
1230 | 0 | hrd->setGeneralSamePicTimingInAllOlsFlag( general_same_pic_timing_in_all_ols_flag ); |
1231 | |
|
1232 | 0 | X_READ_FLAG( general_du_hrd_params_present_flag ); |
1233 | 0 | hrd->setGeneralDuHrdParamsPresentFlag( general_du_hrd_params_present_flag ); |
1234 | |
|
1235 | 0 | if( general_du_hrd_params_present_flag ) |
1236 | 0 | { |
1237 | 0 | X_READ_CODE_NO_RANGE( tick_divisor_minus2, 8 ); |
1238 | 0 | hrd->setTickDivisorMinus2( tick_divisor_minus2 ); |
1239 | 0 | } |
1240 | |
|
1241 | 0 | X_READ_CODE_NO_RANGE( bit_rate_scale, 4 ); |
1242 | 0 | hrd->setBitRateScale( bit_rate_scale ); |
1243 | |
|
1244 | 0 | X_READ_CODE_NO_RANGE( cpb_size_scale, 4 ); |
1245 | 0 | hrd->setCpbSizeScale( cpb_size_scale ); |
1246 | |
|
1247 | 0 | if( general_du_hrd_params_present_flag ) |
1248 | 0 | { |
1249 | 0 | X_READ_CODE_NO_RANGE( cpb_size_du_scale, 4 ); |
1250 | 0 | hrd->setCpbSizeDuScale( cpb_size_du_scale ); |
1251 | 0 | } |
1252 | |
|
1253 | 0 | X_READ_UVLC( hrd_cpb_cnt_minus1, 0, MAX_CPB_CNT - 1 ); |
1254 | 0 | hrd->setHrdCpbCntMinus1( hrd_cpb_cnt_minus1 ); |
1255 | 0 | } |
1256 | 0 | } |
1257 | | |
1258 | | void HLSyntaxReader::parseOlsHrdParameters( GeneralHrdParams * generalHrd, std::vector<OlsHrdParams>& olsHrd, uint32_t firstSubLayer, uint32_t maxNumSubLayersMinus1 ) |
1259 | 0 | { |
1260 | 0 | olsHrd.resize( maxNumSubLayersMinus1 + 1 ); |
1261 | |
|
1262 | 0 | for( unsigned i = firstSubLayer; i <= maxNumSubLayersMinus1; i++ ) |
1263 | 0 | { |
1264 | 0 | OlsHrdParams& hrd = olsHrd[i]; |
1265 | |
|
1266 | 0 | X_READ_FLAG( fixed_pic_rate_general_flag ); |
1267 | 0 | hrd.setFixedPicRateGeneralFlag( fixed_pic_rate_general_flag ); |
1268 | | |
1269 | | // When fixed_pic_rate_general_flag[ i ] is equal to 1, the value of fixed_pic_rate_within_cvs_flag[ i ] is inferred to be equal to 1. |
1270 | 0 | hrd.setFixedPicRateWithinCvsFlag( fixed_pic_rate_general_flag ); |
1271 | 0 | if( !fixed_pic_rate_general_flag ) |
1272 | 0 | { |
1273 | 0 | X_READ_FLAG( fixed_pic_rate_within_cvs_flag ); |
1274 | 0 | hrd.setFixedPicRateWithinCvsFlag( fixed_pic_rate_within_cvs_flag ); |
1275 | 0 | } |
1276 | | |
1277 | | // TODO: It is a requirement of bitstream conformance that when general_nal_hrd_params_present_flag and |
1278 | | // general_vcl_hrd_params_present_flag are both equal to 0, there shall be at least one value of |
1279 | | // fixed_pic_rate_within_cvs_flag[ i ] equal to 1 for i in the range of 0 to MaxSubLayersVal − 1, inclusive. |
1280 | |
|
1281 | 0 | hrd.setLowDelayHrdFlag( false ); // Inferred to be 0 when not present |
1282 | |
|
1283 | 0 | if( hrd.getFixedPicRateWithinCvsFlag() ) |
1284 | 0 | { |
1285 | 0 | X_READ_UVLC( elemental_duration_in_tc_minus1, 0, 2047 ); |
1286 | 0 | hrd.setElementDurationInTcMinus1( elemental_duration_in_tc_minus1 ); |
1287 | 0 | } |
1288 | 0 | else if( ( generalHrd->getGeneralNalHrdParamsPresentFlag() || generalHrd->getGeneralVclHrdParamsPresentFlag() ) |
1289 | 0 | && generalHrd->getHrdCpbCntMinus1() == 0 ) |
1290 | 0 | { |
1291 | 0 | X_READ_FLAG( low_delay_hrd_flag ); |
1292 | 0 | hrd.setLowDelayHrdFlag( low_delay_hrd_flag ); |
1293 | 0 | } |
1294 | |
|
1295 | 0 | using NalOrVcl = enum { NAL = 0, VCL = 1 }; |
1296 | 0 | for( NalOrVcl nalOrVcl: { NAL, VCL } ) |
1297 | 0 | { |
1298 | 0 | if( ( nalOrVcl == NAL && generalHrd->getGeneralNalHrdParamsPresentFlag() ) || // |
1299 | 0 | ( nalOrVcl == VCL && generalHrd->getGeneralVclHrdParamsPresentFlag() ) ) |
1300 | 0 | { |
1301 | 0 | for( int j = 0; j <= generalHrd->getHrdCpbCntMinus1(); j++ ) |
1302 | 0 | { |
1303 | 0 | CHECK( generalHrd->getHrdCpbCntMinus1() >= MAX_CPB_CNT, "hrd_cpb_cnt_minus1 out of bounds" ); |
1304 | |
|
1305 | 0 | X_READ_UVLC_NO_RANGE( bit_rate_value_minus1 ); |
1306 | 0 | CHECK( j > 0 && bit_rate_value_minus1 <= hrd.getBitRateValueMinus1( j - 1, nalOrVcl ), |
1307 | 0 | "For any j greater than 0 and any particular value of i, bit_rate_value_minus1[ i ][ j ]" |
1308 | 0 | " shall be greater than bit_rate_value_minus1[ i ][ j − 1 ]." ); |
1309 | 0 | hrd.setBitRateValueMinus1( j, nalOrVcl, bit_rate_value_minus1 ); |
1310 | |
|
1311 | 0 | X_READ_UVLC( cpb_size_value_minus1, 0, ( 1ull << 32 ) - 2 ); |
1312 | 0 | CHECK( j > 0 && cpb_size_value_minus1 > hrd.getCpbSizeValueMinus1( j - 1, nalOrVcl ), |
1313 | 0 | "For any j greater than 0 and any particular value of i, cpb_size_value_minus1[ i ][ j ]" |
1314 | 0 | " shall be less than or equal to cpb_size_value_minus1[ i ][ j − 1 ]." ); |
1315 | 0 | hrd.setCpbSizeValueMinus1( j, nalOrVcl, cpb_size_value_minus1 ); |
1316 | |
|
1317 | 0 | if( generalHrd->getGeneralDuHrdParamsPresentFlag() ) |
1318 | 0 | { |
1319 | 0 | X_READ_UVLC( cpb_size_du_value_minus1, 0, ( 1ull << 32 ) - 2 ); |
1320 | 0 | CHECK( j > 0 && cpb_size_du_value_minus1 > hrd.getDuCpbSizeValueMinus1( j - 1, nalOrVcl ), |
1321 | 0 | "For any j greater than 0 and any particular value of i, cpb_size_du_value_minus1[ i ][ j ]" |
1322 | 0 | " shall be less than or equal to cpb_size_du_value_minus1[ i ][ j − 1 ]." ) |
1323 | 0 | hrd.setDuCpbSizeValueMinus1( j, nalOrVcl, cpb_size_du_value_minus1 ); |
1324 | |
|
1325 | 0 | X_READ_UVLC( bit_rate_du_value_minus1, 0, ( 1ull << 32 ) - 2 ); |
1326 | 0 | CHECK( j > 0 && bit_rate_du_value_minus1 <= hrd.getDuBitRateValueMinus1( j - 1, nalOrVcl ), |
1327 | 0 | "For any j greater than 0 and any particular value of i, bit_rate_du_value_minus1[ i ][ j ]" |
1328 | 0 | " shall be greater than bit_rate_du_value_minus1[ i ][ j − 1 ]" ) |
1329 | 0 | hrd.setDuBitRateValueMinus1( j, nalOrVcl, bit_rate_du_value_minus1 ); |
1330 | 0 | } |
1331 | 0 | X_READ_FLAG( cbr_flag ); |
1332 | 0 | hrd.setCbrFlag( j, nalOrVcl, cbr_flag ); |
1333 | 0 | } |
1334 | 0 | } |
1335 | 0 | } |
1336 | 0 | } |
1337 | | |
1338 | 0 | for( int i = 0; i < firstSubLayer; i++ ) |
1339 | 0 | { |
1340 | 0 | OlsHrdParams* hrdHighestTLayer = &( olsHrd[maxNumSubLayersMinus1] ); |
1341 | 0 | OlsHrdParams* hrdTemp = &( olsHrd[i] ); |
1342 | 0 | bool tempFlag = hrdHighestTLayer->getFixedPicRateGeneralFlag(); |
1343 | 0 | hrdTemp->setFixedPicRateGeneralFlag( tempFlag ); |
1344 | 0 | tempFlag = hrdHighestTLayer->getFixedPicRateWithinCvsFlag(); |
1345 | 0 | hrdTemp->setFixedPicRateWithinCvsFlag( tempFlag ); |
1346 | 0 | uint32_t tempElementDurationInTcMinus1 = hrdHighestTLayer->getElementDurationInTcMinus1(); |
1347 | 0 | hrdTemp->setElementDurationInTcMinus1( tempElementDurationInTcMinus1 ); |
1348 | 0 | for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl++ ) |
1349 | 0 | { |
1350 | 0 | if( ( nalOrVcl == 0 && generalHrd->getGeneralNalHrdParamsPresentFlag() ) || ( nalOrVcl == 1 && generalHrd->getGeneralVclHrdParamsPresentFlag() ) ) |
1351 | 0 | { |
1352 | 0 | for( int j = 0; j <= (generalHrd->getHrdCpbCntMinus1()); j++ ) |
1353 | 0 | { |
1354 | 0 | uint32_t bitRate = hrdHighestTLayer->getBitRateValueMinus1( j, nalOrVcl ); |
1355 | 0 | hrdTemp->setBitRateValueMinus1( j, nalOrVcl, bitRate ); |
1356 | 0 | uint32_t cpbSize = hrdHighestTLayer->getCpbSizeValueMinus1( j, nalOrVcl ); |
1357 | 0 | hrdTemp->setCpbSizeValueMinus1( j, nalOrVcl, cpbSize ); |
1358 | 0 | if( generalHrd->getGeneralDuHrdParamsPresentFlag() ) |
1359 | 0 | { |
1360 | 0 | uint32_t bitRateDu = hrdHighestTLayer->getDuBitRateValueMinus1( j, nalOrVcl ); |
1361 | 0 | hrdTemp->setDuBitRateValueMinus1(j, nalOrVcl, bitRateDu); |
1362 | 0 | uint32_t cpbSizeDu = hrdHighestTLayer->getDuCpbSizeValueMinus1( j, nalOrVcl ); |
1363 | 0 | hrdTemp->setDuCpbSizeValueMinus1( j, nalOrVcl, cpbSizeDu ); |
1364 | 0 | } |
1365 | 0 | bool flag = hrdHighestTLayer->getCbrFlag( j, nalOrVcl ); |
1366 | 0 | hrdTemp->setCbrFlag( j, nalOrVcl, flag ); |
1367 | 0 | } |
1368 | 0 | } |
1369 | 0 | } |
1370 | 0 | } |
1371 | 0 | } |
1372 | | |
1373 | | void HLSyntaxReader::dpb_parameters( int maxSubLayersMinus1, bool subLayerInfoFlag, SPS *pcSPS ) |
1374 | 6 | { |
1375 | 6 | CHECK( maxSubLayersMinus1 >= MAX_TLAYER, "maxSubLayersMinus1 out of bounds" ); |
1376 | 16 | for( int i = ( subLayerInfoFlag ? 0 : maxSubLayersMinus1 ); i <= maxSubLayersMinus1; i++ ) |
1377 | 12 | { |
1378 | 12 | X_READ_UVLC_NO_RANGE_idx( dpb_max_dec_pic_buffering_minus1, "[i]" ); |
1379 | 12 | CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getMaxDecPicBuffering( i - 1 ) - 1, |
1380 | 12 | "When i is greater than 0, dpb_max_dec_pic_buffering_minus1[ i ] shall be greater than or equal to dpb_max_dec_pic_buffering_minus1[ i − 1 ]." ); |
1381 | 10 | pcSPS->setMaxDecPicBuffering( dpb_max_dec_pic_buffering_minus1 + 1, i ); |
1382 | | |
1383 | 10 | X_READ_UVLC_idx( dpb_max_num_reorder_pics, "[i]", 0, dpb_max_dec_pic_buffering_minus1 ); |
1384 | 10 | CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getNumReorderPics( i - 1 ), |
1385 | 10 | "When i is greater than 0, dpb_max_num_reorder_pics[ i ] shall be greater than or equal to dpb_max_num_reorder_pics[ i − 1 ]." ); |
1386 | 10 | pcSPS->setNumReorderPics( dpb_max_num_reorder_pics, i ); |
1387 | | |
1388 | 10 | X_READ_UVLC_idx( dpb_max_latency_increase_plus1, "[i]", 0, ( uint64_t( 1 ) << 32 ) - 2 ); |
1389 | 10 | pcSPS->setMaxLatencyIncreasePlus1( dpb_max_latency_increase_plus1, i ); |
1390 | 10 | } |
1391 | 6 | } |
1392 | | |
1393 | | void HLSyntaxReader::parseExtraPHBitsStruct( SPS *sps, int numBytes ) |
1394 | 16 | { |
1395 | 16 | std::vector<bool> presentFlags; |
1396 | 16 | presentFlags.resize ( 8 * numBytes ); |
1397 | | |
1398 | 208 | for( int i = 0; i < 8 * numBytes; i++ ) |
1399 | 192 | { |
1400 | 192 | X_READ_FLAG_idx( sps_extra_ph_bit_present_flag, "[i]" ); |
1401 | 192 | presentFlags[i] = sps_extra_ph_bit_present_flag; |
1402 | 192 | } |
1403 | | |
1404 | 16 | sps->setExtraPHBitPresentFlags( std::move( presentFlags ) ); |
1405 | 16 | } |
1406 | | |
1407 | | void HLSyntaxReader::parseExtraSHBitsStruct( SPS *sps, int numBytes ) |
1408 | 16 | { |
1409 | 16 | std::vector<bool> presentFlags; |
1410 | 16 | presentFlags.resize ( 8 * numBytes ); |
1411 | | |
1412 | 192 | for( int i = 0; i < 8 * numBytes; i++ ) |
1413 | 176 | { |
1414 | 176 | X_READ_FLAG_idx( sps_extra_sh_bit_present_flag, "[i]" ); |
1415 | 176 | presentFlags[i] = sps_extra_sh_bit_present_flag; |
1416 | 176 | } |
1417 | | |
1418 | 16 | sps->setExtraSHBitPresentFlags( std::move( presentFlags ) ); |
1419 | 16 | } |
1420 | | |
1421 | | void HLSyntaxReader::parseSPS( SPS* sps, const ParameterSetManager* parameterSetManager ) |
1422 | 108 | { |
1423 | | #if ENABLE_TRACING |
1424 | | xTraceSPSHeader (); |
1425 | | #endif |
1426 | | |
1427 | 108 | X_READ_CODE_NO_RANGE( sps_seq_parameter_set_id, 4 ); |
1428 | 108 | sps->setSPSId( sps_seq_parameter_set_id ); |
1429 | | |
1430 | 108 | X_READ_CODE_NO_RANGE( sps_video_parameter_set_id, 4 ); |
1431 | 108 | (void) sps_video_parameter_set_id; // sps->setVPSId( sps_video_parameter_set_id ); // TODO: change to support VPS |
1432 | 108 | const VPS* vps = nullptr; |
1433 | | #if 0 |
1434 | | if( sps_video_parameter_set_id > 0 && parameterSetManager->getVPS( sps_video_parameter_set_id ) ) |
1435 | | { |
1436 | | vps = parameterSetManager->getVPS( sps_video_parameter_set_id ); |
1437 | | } |
1438 | | #endif |
1439 | | |
1440 | 108 | X_READ_CODE( sps_max_sublayers_minus1, 3, 0, 6 ); |
1441 | 108 | CHECK( vps && sps_video_parameter_set_id > vps->getMaxSubLayers(), |
1442 | 108 | "If sps_video_parameter_set_id is greater than 0, the value of sps_max_sublayers_minus1 shall be in the range of 0 to vps_max_sublayers_minus1, " |
1443 | 108 | "inclusive." ) |
1444 | 108 | sps->setMaxTLayers( sps_max_sublayers_minus1 + 1 ); |
1445 | | |
1446 | 108 | X_READ_CODE_NO_RANGE( sps_chroma_format_idc, 2 ); |
1447 | | // it is a requirement of bitstream conformance that the value of sps_chroma_format_idc shall |
1448 | | // be less than or equal to the value of vps_ols_dpb_chroma_format[ i ]. |
1449 | 108 | sps->setChromaFormatIdc( ChromaFormat( sps_chroma_format_idc ) ); |
1450 | | |
1451 | 108 | X_READ_CODE( sps_log2_ctu_size_minus5, 2, 0, 2 ); |
1452 | 108 | sps->setCTUSize( 1 << ( sps_log2_ctu_size_minus5 + 5 ) ); |
1453 | | |
1454 | 108 | const int CtbLog2SizeY = sps_log2_ctu_size_minus5 + 5; |
1455 | 108 | const int CtbSizeY = 1 << CtbLog2SizeY; |
1456 | 108 | sps->setMaxCUWidth( sps->getCTUSize() ); |
1457 | 108 | sps->setMaxCUHeight( sps->getCTUSize() ); |
1458 | | |
1459 | 108 | X_READ_FLAG( sps_ptl_dpb_hrd_params_present_flag ); |
1460 | 108 | CHECK( sps_video_parameter_set_id == 0 && !sps_ptl_dpb_hrd_params_present_flag, |
1461 | 108 | "When sps_video_parameter_set_id is equal to 0, the value of sps_ptl_dpb_hrd_params_present_flag shall be equal to 1" ); |
1462 | 108 | sps->setPtlDpbHrdParamsPresentFlag( sps_ptl_dpb_hrd_params_present_flag ); |
1463 | | |
1464 | 108 | if( sps_ptl_dpb_hrd_params_present_flag ) |
1465 | 52 | { |
1466 | 52 | parseProfileTierLevel( sps->getProfileTierLevel(), true, sps->getMaxTLayers() - 1 ); |
1467 | 52 | } |
1468 | | |
1469 | 108 | const ProfileTierLevel* ptl = sps->getProfileTierLevel(); |
1470 | 108 | const ConstraintInfo* gci = ptl->getConstraintInfo(); |
1471 | | |
1472 | 108 | X_READ_FLAG( sps_gdr_enabled_flag ); |
1473 | 108 | CHECK_CONSTRAINT( gci->getNoGdrConstraintFlag() && sps_gdr_enabled_flag, |
1474 | 106 | "When gci_no_gdr_constraint_flag equal to 1 , the value of sps_gdr_enabled_flag shall be equal to 0" ); |
1475 | 106 | sps->setGDREnabledFlag( sps_gdr_enabled_flag ); |
1476 | | |
1477 | 106 | X_READ_FLAG( sps_ref_pic_resampling_enabled_flag ); |
1478 | 106 | CHECK_CONSTRAINT( gci->getNoRprConstraintFlag() && sps_ref_pic_resampling_enabled_flag, |
1479 | 104 | "When gci_no_ref_pic_resampling_constraint_flag is equal to 1, sps_ref_pic_resampling_enabled_flag shall be equal to 0" ); |
1480 | 104 | sps->setRprEnabledFlag( sps_ref_pic_resampling_enabled_flag ); |
1481 | | |
1482 | 104 | if( sps_ref_pic_resampling_enabled_flag ) |
1483 | 4 | { |
1484 | 4 | X_READ_FLAG( sps_res_change_in_clvs_allowed_flag ); |
1485 | 4 | CHECK_CONSTRAINT( gci->getNoResChangeInClvsConstraintFlag() && sps_res_change_in_clvs_allowed_flag, |
1486 | 4 | "When no_res_change_in_clvs_constraint_flag is equal to 1, res_change_in_clvs_allowed_flag shall be equal to 0" ); |
1487 | 4 | sps->setResChangeInClvsEnabledFlag( sps_res_change_in_clvs_allowed_flag ); |
1488 | 4 | } |
1489 | | |
1490 | 104 | X_READ_UVLC_NO_RANGE( sps_pic_width_max_in_luma_samples ); |
1491 | 104 | sps->setMaxPicWidthInLumaSamples( sps_pic_width_max_in_luma_samples ); |
1492 | | |
1493 | 104 | X_READ_UVLC_NO_RANGE( sps_pic_height_max_in_luma_samples ); |
1494 | 104 | sps->setMaxPicHeightInLumaSamples( sps_pic_height_max_in_luma_samples ); |
1495 | | |
1496 | 104 | const int SubWidthC = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() ); |
1497 | 104 | const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() ); |
1498 | | |
1499 | 104 | X_READ_FLAG( sps_conformance_window_flag ); |
1500 | 104 | sps->setConformanceWindowPresentFlag( sps_conformance_window_flag ); |
1501 | | |
1502 | 104 | if( sps_conformance_window_flag ) |
1503 | 24 | { |
1504 | 24 | X_READ_UVLC_NO_RANGE( sps_conf_win_left_offset ); |
1505 | 24 | X_READ_UVLC_NO_RANGE( sps_conf_win_right_offset ); |
1506 | 24 | X_READ_UVLC_NO_RANGE( sps_conf_win_top_offset ); |
1507 | 24 | X_READ_UVLC_NO_RANGE( sps_conf_win_bottom_offset ); |
1508 | | |
1509 | 24 | CHECK( SubWidthC * ( sps_conf_win_left_offset + sps_conf_win_right_offset ) > sps_pic_width_max_in_luma_samples, |
1510 | 24 | "The value of SubWidthC * ( sps_conf_win_left_offset + sps_conf_win_right_offset ) shall be less than sps_pic_width_max_in_luma_samples." ); |
1511 | 24 | CHECK( SubHeightC * ( sps_conf_win_top_offset + sps_conf_win_bottom_offset ) > sps_pic_height_max_in_luma_samples, |
1512 | 24 | "The value of SubHeightC * ( sps_conf_win_top_offset + sps_conf_win_bottom_offset ) shall be less than sps_pic_height_max_in_luma_samples." ); |
1513 | | |
1514 | 18 | Window& conf = sps->getConformanceWindow(); |
1515 | 18 | conf.setWindowLeftOffset( sps_conf_win_left_offset ); |
1516 | 18 | conf.setWindowRightOffset( sps_conf_win_right_offset ); |
1517 | 18 | conf.setWindowTopOffset( sps_conf_win_top_offset ); |
1518 | 18 | conf.setWindowBottomOffset( sps_conf_win_bottom_offset ); |
1519 | 18 | } |
1520 | 98 | X_READ_FLAG( sps_subpic_info_present_flag ); |
1521 | 98 | CHECK( sps->getResChangeInClvsEnabledFlag() && sps_subpic_info_present_flag, |
1522 | 98 | "When sps_res_change_in_clvs_allowed_flag is equal to 1, the value of sps_subpic_info_present_flag shall be equal to 0." ) |
1523 | 96 | CHECK_CONSTRAINT( gci->getNoSubpicInfoConstraintFlag() && sps_subpic_info_present_flag, |
1524 | 96 | "When gci_no_subpic_info_constraint_flag is equal to 1, the value of subpic_info_present_flag shall be equal to 0" ); |
1525 | 96 | sps->setSubPicInfoPresentFlag( sps_subpic_info_present_flag ); |
1526 | | |
1527 | | |
1528 | 96 | if( sps_subpic_info_present_flag ) |
1529 | 38 | { |
1530 | 38 | X_READ_UVLC_NO_RANGE( sps_num_subpics_minus1 ); |
1531 | 38 | CHECK( sps_num_subpics_minus1 + 1 > ( ( sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY ) |
1532 | 38 | * ( ( sps_pic_height_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY ), |
1533 | 38 | "Invalid sps_num_subpics_minus1 value" ); |
1534 | 36 | sps->setNumSubPics( sps_num_subpics_minus1 + 1 ); |
1535 | | |
1536 | 36 | if( sps_num_subpics_minus1 == 0 ) |
1537 | 8 | { |
1538 | 8 | sps->setSubPicCtuTopLeftX( 0, 0 ); |
1539 | 8 | sps->setSubPicCtuTopLeftY( 0, 0 ); |
1540 | 8 | sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) ); |
1541 | 8 | sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) ); |
1542 | 8 | sps->setIndependentSubPicsFlag( 1 ); |
1543 | 8 | sps->setSubPicSameSizeFlag( 0 ); |
1544 | 8 | sps->setSubPicTreatedAsPicFlag( 0, 1 ); |
1545 | 8 | sps->setLoopFilterAcrossSubpicEnabledFlag( 0, 0 ); |
1546 | 8 | } |
1547 | 28 | else // ( sps_num_subpics_minus1 > 0 ) |
1548 | 28 | { |
1549 | 28 | X_READ_FLAG( sps_independent_subpics_flag ); |
1550 | 28 | sps->setIndependentSubPicsFlag( sps_independent_subpics_flag ); |
1551 | | |
1552 | 28 | X_READ_FLAG( sps_subpic_same_size_flag ); |
1553 | 28 | sps->setSubPicSameSizeFlag( sps_subpic_same_size_flag ); |
1554 | | |
1555 | 28 | const uint32_t tmpWidthVal = ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize(); |
1556 | 28 | const uint32_t tmpHeightVal = ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize(); |
1557 | | |
1558 | 28 | const int ceilLog2tmpWidth = (int) ceil( log2( tmpWidthVal ) ); |
1559 | 28 | const int ceilLog2tmpHeight = (int) ceil( log2( tmpHeightVal ) ); |
1560 | 116 | for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ ) |
1561 | 98 | { |
1562 | 98 | if( !sps_subpic_same_size_flag || picIdx == 0 ) |
1563 | 80 | { |
1564 | 80 | if( picIdx > 0 && sps_pic_width_max_in_luma_samples > CtbSizeY ) |
1565 | 10 | { |
1566 | 10 | X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_x, "[ i ]", ceilLog2tmpWidth ); |
1567 | 10 | sps->setSubPicCtuTopLeftX( picIdx, sps_subpic_ctu_top_left_x ); |
1568 | 10 | } |
1569 | 70 | else |
1570 | 70 | { |
1571 | 70 | sps->setSubPicCtuTopLeftX( picIdx, 0 ); |
1572 | 70 | } |
1573 | | |
1574 | 80 | if( picIdx > 0 && sps_pic_height_max_in_luma_samples > CtbSizeY ) |
1575 | 42 | { |
1576 | 42 | X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_y, "[ i ]", ceilLog2tmpHeight ); |
1577 | 42 | sps->setSubPicCtuTopLeftY( picIdx, sps_subpic_ctu_top_left_y ); |
1578 | 42 | } |
1579 | 38 | else |
1580 | 38 | { |
1581 | 38 | sps->setSubPicCtuTopLeftY( picIdx, 0 ); |
1582 | 38 | } |
1583 | | |
1584 | 80 | if( picIdx < sps_num_subpics_minus1 && sps_pic_width_max_in_luma_samples > CtbSizeY ) |
1585 | 20 | { |
1586 | 20 | X_READ_CODE_NO_RANGE_idx( sps_subpic_width_minus1, "[ i ]", ceilLog2tmpWidth ); |
1587 | 20 | sps->setSubPicWidth( picIdx, sps_subpic_width_minus1 + 1 ); |
1588 | 20 | } |
1589 | 60 | else |
1590 | 60 | { |
1591 | | // If sps_subpic_same_size_flag is equal to 0 or i is equal to 0, the value of sps_subpic_width_minus1[ i ] is inferred |
1592 | | // to be equal to tmpWidthVal - sps_subpic_ctu_top_left_x[ i ] - 1. |
1593 | 60 | sps->setSubPicWidth( picIdx, tmpWidthVal - sps->getSubPicCtuTopLeftX( picIdx ) ); |
1594 | 60 | } |
1595 | | |
1596 | 80 | if( picIdx < sps_num_subpics_minus1 && sps_pic_height_max_in_luma_samples > CtbSizeY ) |
1597 | 44 | { |
1598 | 44 | X_READ_CODE_NO_RANGE_idx( sps_subpic_height_minus1, "[ i ]", ceilLog2tmpHeight ); |
1599 | 44 | sps->setSubPicHeight( picIdx, sps_subpic_height_minus1 + 1 ); |
1600 | 44 | } |
1601 | 36 | else |
1602 | 36 | { |
1603 | | // If sps_subpic_same_size_flag is equal to 0 or i is equal to 0, the value of sps_subpic_height_minus1[ i ] is inferred |
1604 | | // to be equal to tmpHeightVal - sps_subpic_ctu_top_left_y[ i ] − 1. |
1605 | 36 | sps->setSubPicHeight( picIdx, tmpHeightVal - sps->getSubPicCtuTopLeftY( picIdx ) ); |
1606 | 36 | } |
1607 | 80 | } |
1608 | 18 | else // ( sps_subpic_same_size_flag && picIdx != 0 ) |
1609 | 18 | { |
1610 | 18 | const int numSubpicCols = tmpWidthVal / sps->getSubPicWidth( 0 ); |
1611 | | |
1612 | | // const int numSubpicCols = tmpWidthVal / ( sps->getSubPicWidth( 0 ) + 1 ); |
1613 | 18 | CHECK( sps_subpic_same_size_flag && numSubpicCols * tmpHeightVal / sps->getSubPicHeight( 0 ) - 1 != sps_num_subpics_minus1, |
1614 | 18 | "When sps_subpic_same_size_flag is equal to 1, the value of numSubpicCols * tmpHeightVal / ( sps_subpic_height_minus1[ 0 ] + 1 ) − 1" |
1615 | 18 | " shall be equal to sps_num_subpics_minus1." ) |
1616 | 14 | CHECK( sps_subpic_same_size_flag && tmpWidthVal % sps->getSubPicWidth( 0 ) != 0, |
1617 | 14 | "When sps_subpic_same_size_flag is equal to 1, the value of tmpWidthVal % ( sps_subpic_width_minus1[ 0 ] + 1 ) shall" |
1618 | 14 | " be equal to 0." ); |
1619 | 12 | CHECK( sps_subpic_same_size_flag && tmpHeightVal % sps->getSubPicHeight( 0 ) != 0, |
1620 | 12 | "When sps_subpic_same_size_flag is equal to 1, the value of tmpHeightVal % ( sps_subpic_height_minus1[ 0 ] + 1 ) shall" |
1621 | 12 | " be equal to 0." ) |
1622 | | |
1623 | | // Otherwise, the value of sps_subpic_ctu_top_left_x[ i ] is inferred to be equal to ( i % numSubpicCols ) * ( sps_subpic_width_minus1[ 0 ] + 1 ). |
1624 | | // Otherwise, the value of sps_subpic_ctu_top_left_y[ i ] is inferred to be equal to ( i / numSubpicCols ) * ( sps_subpic_height_minus1[ 0 ] + 1 ). |
1625 | 12 | sps->setSubPicCtuTopLeftX( picIdx, ( picIdx % numSubpicCols ) * sps->getSubPicWidth( 0 ) ); |
1626 | 12 | sps->setSubPicCtuTopLeftY( picIdx, ( picIdx / numSubpicCols ) * sps->getSubPicHeight( 0 ) ); |
1627 | | // Otherwise, the value of sps_subpic_width_minus1[ i ] is inferred to be equal to sps_subpic_width_minus1[ 0 ]. |
1628 | | // Otherwise, the value of sps_subpic_height_minus1[ i ] is inferred to be equal to sps_subpic_height_minus1[ 0 ]. |
1629 | 12 | sps->setSubPicWidth( picIdx, sps->getSubPicWidth( 0 ) ); |
1630 | 12 | sps->setSubPicHeight( picIdx, sps->getSubPicHeight( 0 ) ); |
1631 | 12 | } |
1632 | | |
1633 | | // TODO: It is a requirement of bitstream conformance that the shapes of the subpictures shall be such that each subpicture, when |
1634 | | // decoded, shall have its entire left boundary and entire top boundary consisting of picture boundaries or consisting of |
1635 | | // boundaries of previously decoded subpictures. |
1636 | | // For each subpicture with subpicture index i in the range of 0 to sps_num_subpics_minus1, inclusive, it is a requirement |
1637 | | // of bitstream conformance that all of the following conditions are true: |
1638 | | // - The value of ( sps_subpic_ctu_top_left_x[ i ] * CtbSizeY ) shall be less than ( sps_pic_width_max_in_luma_samples - sps_conf_win_right_offset * SubWidthC ). |
1639 | | // - The value of ( ( sps_subpic_ctu_top_left_x[ i ] + sps_subpic_width_minus1[ i ] + 1 ) * CtbSizeY ) shall be greater than ( sps_conf_win_left_offset * SubWidthC ). |
1640 | | // - The value of ( sps_subpic_ctu_top_left_y[ i ] * CtbSizeY ) shall be less than ( sps_pic_height_max_in_luma_samples - sps_conf_win_bottom_offset * SubHeightC ). |
1641 | | // - The value of ( ( sps_subpic_ctu_top_left_y[ i ] + sps_subpic_height_minus1[ i ] + 1 ) * CtbSizeY ) shall be greater than ( sps_conf_win_top_offset * SubHeightC ). |
1642 | | |
1643 | 92 | Window& conf = sps->getConformanceWindow(); |
1644 | 92 | CHECK( sps->getSubPicCtuTopLeftX( picIdx ) * CtbSizeY >= sps->getMaxPicWidthInLumaSamples() - conf.getWindowRightOffset() * SubWidthC, |
1645 | 92 | "The value of ( sps_subpic_ctu_top_left_x[ i ] * CtbSizeY )" |
1646 | 92 | " shall be less than ( sps_pic_width_max_in_luma_samples - sps_conf_win_right_offset * SubWidthC )." ); |
1647 | 88 | CHECK( ( sps->getSubPicCtuTopLeftX( picIdx ) + sps->getSubPicWidth( picIdx ) ) * CtbSizeY <= conf.getWindowLeftOffset() * SubWidthC, |
1648 | 88 | "The value of ( ( sps_subpic_ctu_top_left_x[ i ] + sps_subpic_width_minus1[ i ] + 1 ) * CtbSizeY )" |
1649 | 88 | " shall be greater than ( sps_conf_win_left_offset * SubWidthC )." ); |
1650 | 88 | CHECK( sps->getSubPicCtuTopLeftY( picIdx ) * CtbSizeY >= sps->getMaxPicHeightInLumaSamples() - conf.getWindowBottomOffset() * SubHeightC, |
1651 | 88 | "The value of ( sps_subpic_ctu_top_left_y[ i ] * CtbSizeY )" |
1652 | 88 | " shall be less than ( sps_pic_height_max_in_luma_samples - sps_conf_win_bottom_offset * SubHeightC )." ); |
1653 | 88 | CHECK( ( sps->getSubPicCtuTopLeftY( picIdx ) + sps->getSubPicHeight( picIdx ) ) * CtbSizeY <= conf.getWindowTopOffset() * SubHeightC, |
1654 | 88 | "The value of ( ( sps_subpic_ctu_top_left_y[ i ] + sps_subpic_height_minus1[ i ] + 1 ) * CtbSizeY )" |
1655 | 88 | " shall be greater than ( sps_conf_win_top_offset * SubHeightC )." ); |
1656 | | |
1657 | 88 | if( !sps_independent_subpics_flag ) |
1658 | 62 | { |
1659 | 62 | X_READ_FLAG_idx( sps_subpic_treated_as_pic_flag, "[ i ]" ); |
1660 | 62 | sps->setSubPicTreatedAsPicFlag( picIdx, sps_subpic_treated_as_pic_flag ); |
1661 | | |
1662 | 62 | X_READ_FLAG_idx( sps_loop_filter_across_subpic_enabled_flag, "[ i ]" ); |
1663 | 62 | sps->setLoopFilterAcrossSubpicEnabledFlag( picIdx, sps_loop_filter_across_subpic_enabled_flag ); |
1664 | 62 | } |
1665 | 26 | else |
1666 | 26 | { |
1667 | | // should be set as default |
1668 | 26 | sps->setSubPicTreatedAsPicFlag( picIdx, 1 ); |
1669 | 26 | } |
1670 | 88 | } // for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ ) |
1671 | 28 | } |
1672 | | |
1673 | | |
1674 | 26 | X_READ_UVLC( sps_subpic_id_len_minus1, 0, 15 ); |
1675 | 26 | CHECK( 1 << ( sps_subpic_id_len_minus1 + 1 ) < sps_num_subpics_minus1 + 1, |
1676 | 26 | "The value of 1 << ( sps_subpic_id_len_minus1 + 1 ) shall be greater than or equal to sps_num_subpics_minus1 + 1" ); |
1677 | 24 | sps->setSubPicIdLen( sps_subpic_id_len_minus1 + 1 ); |
1678 | | |
1679 | 24 | X_READ_FLAG( sps_subpic_id_mapping_explicitly_signalled_flag ); |
1680 | 24 | sps->setSubPicIdMappingExplicitlySignalledFlag( sps_subpic_id_mapping_explicitly_signalled_flag ); |
1681 | | |
1682 | 24 | if( sps_subpic_id_mapping_explicitly_signalled_flag ) |
1683 | 10 | { |
1684 | 10 | X_READ_FLAG( sps_subpic_id_mapping_present_flag ); |
1685 | 10 | sps->setSubPicIdMappingPresentFlag( sps_subpic_id_mapping_present_flag ); |
1686 | | |
1687 | 10 | if( sps_subpic_id_mapping_present_flag ) |
1688 | 8 | { |
1689 | 30 | for( int picIdx = 0; picIdx <= sps_num_subpics_minus1; picIdx++ ) |
1690 | 22 | { |
1691 | 22 | X_READ_CODE_NO_RANGE_idx( sps_subpic_id, "[ i ]", sps->getSubPicIdLen() ); |
1692 | 22 | sps->setSubPicId( picIdx, sps_subpic_id ); |
1693 | 22 | } |
1694 | 8 | } |
1695 | 10 | } |
1696 | 24 | } // sps_subpic_info_present_flag |
1697 | 58 | else // ( !sps_subpic_info_present_flag ) |
1698 | 58 | { |
1699 | 58 | sps->setSubPicIdMappingExplicitlySignalledFlag( 0 ); |
1700 | 58 | sps->setNumSubPics( 1 ); |
1701 | 58 | sps->setSubPicCtuTopLeftX( 0, 0 ); |
1702 | 58 | sps->setSubPicCtuTopLeftY( 0, 0 ); |
1703 | 58 | sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) ); |
1704 | 58 | sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) ); |
1705 | 58 | sps->setSubPicTreatedAsPicFlag( 0, true ); |
1706 | 58 | sps->setLoopFilterAcrossSubpicEnabledFlag( 0, false ); |
1707 | 58 | } |
1708 | | |
1709 | 82 | if( !sps->getSubPicIdMappingExplicitlySignalledFlag() || !sps->getSubPicIdMappingPresentFlag() ) |
1710 | 34 | { |
1711 | 86 | for( int picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ ) |
1712 | 52 | { |
1713 | 52 | sps->setSubPicId( picIdx, picIdx ); |
1714 | 52 | } |
1715 | 34 | } |
1716 | | |
1717 | 82 | X_READ_UVLC( sps_bitdepth_minus8, 0, 8 ); |
1718 | 82 | const Profile::Name profile = sps->getProfileTierLevel()->getProfileIdc(); |
1719 | 82 | if( profile != Profile::NONE ) |
1720 | 6 | { |
1721 | 6 | CHECK( sps_bitdepth_minus8 + 8 > ProfileFeatures::getProfileFeatures( profile )->maxBitDepth, |
1722 | 6 | "sps_bitdepth_minus8 exceeds range supported by signalled profile" ); |
1723 | 4 | } |
1724 | 80 | sps->setBitDepth( 8 + sps_bitdepth_minus8 ); |
1725 | 80 | sps->setQpBDOffset( 6 * sps_bitdepth_minus8 ); |
1726 | 80 | const int BitDepth = 8 + sps_bitdepth_minus8; |
1727 | 80 | const int QpBdOffset = 6 * sps_bitdepth_minus8; |
1728 | | |
1729 | 80 | X_READ_FLAG( sps_entropy_coding_sync_enabled_flag ); |
1730 | 80 | sps->setEntropyCodingSyncEnabledFlag( sps_entropy_coding_sync_enabled_flag ); |
1731 | | |
1732 | 80 | X_READ_FLAG( sps_entry_point_offsets_present_flag ); |
1733 | 80 | sps->setEntryPointsPresentFlag( sps_entry_point_offsets_present_flag ); |
1734 | | |
1735 | 80 | X_READ_CODE( sps_log2_max_pic_order_cnt_lsb_minus4, 4, 0, 12 ); |
1736 | 80 | sps->setBitsForPOC( sps_log2_max_pic_order_cnt_lsb_minus4 + 4 ); |
1737 | | |
1738 | 80 | X_READ_FLAG( sps_poc_msb_cycle_flag ); |
1739 | 80 | sps->setPocMsbFlag( sps_poc_msb_cycle_flag ); |
1740 | | |
1741 | 80 | if( sps_poc_msb_cycle_flag ) |
1742 | 16 | { |
1743 | 16 | X_READ_UVLC( sps_poc_msb_cycle_len_minus1, 0, 32 - sps_log2_max_pic_order_cnt_lsb_minus4 - 5 ); |
1744 | 16 | sps->setPocMsbLen( sps_poc_msb_cycle_len_minus1 + 1 ); |
1745 | 16 | } |
1746 | | |
1747 | | // extra bits are for future extensions, we will read, but ignore them, |
1748 | | // unless a meaning is specified in the spec |
1749 | 80 | X_READ_CODE( sps_num_extra_ph_bytes, 2, 0, 2 ); |
1750 | 80 | sps->setNumExtraPHBitsBytes( sps_num_extra_ph_bytes ); |
1751 | 80 | if( sps_num_extra_ph_bytes ) |
1752 | 16 | { |
1753 | 16 | parseExtraPHBitsStruct( sps, sps_num_extra_ph_bytes ); |
1754 | 16 | } |
1755 | | |
1756 | 80 | X_READ_CODE( sps_num_extra_sh_bytes, 2, 0, 2 ); |
1757 | 80 | sps->setNumExtraSHBitsBytes( sps_num_extra_sh_bytes ); |
1758 | 80 | if( sps_num_extra_sh_bytes ) |
1759 | 16 | { |
1760 | 16 | parseExtraSHBitsStruct( sps, sps_num_extra_sh_bytes ); |
1761 | 16 | } |
1762 | | |
1763 | 80 | if( sps_ptl_dpb_hrd_params_present_flag ) |
1764 | 6 | { |
1765 | 6 | if( sps_max_sublayers_minus1 > 0 ) |
1766 | 6 | { |
1767 | 6 | X_READ_FLAG( sps_sublayer_dpb_params_flag ); |
1768 | 6 | sps->setSubLayerDpbParamsFlag( sps_sublayer_dpb_params_flag ); |
1769 | 6 | } |
1770 | 6 | dpb_parameters( sps_max_sublayers_minus1, sps->getSubLayerDpbParamsFlag(), sps ); |
1771 | 6 | } |
1772 | | |
1773 | 80 | X_READ_UVLC( sps_log2_min_luma_coding_block_size_minus2, 0, std::min( 4u, sps_log2_ctu_size_minus5 + 3 ) ); |
1774 | 80 | sps->setLog2MinCodingBlockSize( sps_log2_min_luma_coding_block_size_minus2 + 2 ); |
1775 | | |
1776 | 80 | const int MinCbLog2SizeY = sps_log2_min_luma_coding_block_size_minus2 + 2; |
1777 | 80 | const int MinCbSizeY = 1 << MinCbLog2SizeY; |
1778 | 80 | const int VSize = std::min( 64, CtbSizeY ); |
1779 | 80 | CHECK( MinCbSizeY > VSize, "The value of MinCbSizeY shall be less than or equal to VSize." ) |
1780 | 80 | CHECK( MinCbLog2SizeY > CtbLog2SizeY, "Invalid log2_min_luma_coding_block_size_minus2 signalled" ); |
1781 | | |
1782 | | // postponed checks for sps_pic_{width,height}_max_in_luma_samples, |
1783 | 80 | CHECK( sps_pic_width_max_in_luma_samples == 0 || sps_pic_width_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ), |
1784 | 80 | "sps_pic_width_max_in_luma_samples shall not be equal to 0 and shall be an integer multiple of Max( 8, MinCbSizeY )" ); |
1785 | 68 | CHECK( sps_pic_height_max_in_luma_samples == 0 || sps_pic_height_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ), |
1786 | 68 | "sps_pic_height_max_in_luma_samples shall not be equal to 0 and shall be an integer multiple of Max( 8, MinCbSizeY )" ); |
1787 | | |
1788 | 66 | const int minCuSize = 1 << sps->getLog2MinCodingBlockSize(); |
1789 | 66 | CHECK( ( sps->getMaxPicWidthInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" ); |
1790 | 66 | CHECK( ( sps->getMaxPicHeightInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" ); |
1791 | | |
1792 | 66 | X_READ_FLAG( sps_partition_constraints_override_enabled_flag ); |
1793 | 66 | sps->setSplitConsOverrideEnabledFlag( sps_partition_constraints_override_enabled_flag ); |
1794 | | |
1795 | 66 | X_READ_UVLC( sps_log2_diff_min_qt_min_cb_intra_slice_luma, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY ); |
1796 | 66 | const unsigned MinQtLog2SizeIntraY = sps_log2_diff_min_qt_min_cb_intra_slice_luma + MinCbLog2SizeY; |
1797 | | |
1798 | 66 | X_READ_UVLC( sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
1799 | | |
1800 | 66 | PartitionConstraints minQT = { 1u << MinQtLog2SizeIntraY, 0, 0 }; |
1801 | 66 | PartitionConstraints maxBTD = { sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 0 }; |
1802 | 66 | PartitionConstraints maxTTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 }; |
1803 | 66 | PartitionConstraints maxBTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 }; |
1804 | | |
1805 | 66 | int spsLog2DiffMinQtMinCbIntraSliceLuma = 0; |
1806 | 66 | if( sps_max_mtt_hierarchy_depth_intra_slice_luma != 0 ) |
1807 | 0 | { |
1808 | 0 | X_READ_UVLC( sps_log2_diff_max_bt_min_qt_intra_slice_luma, 0, CtbLog2SizeY - MinQtLog2SizeIntraY ); |
1809 | 0 | maxBTSize[0] <<= sps_log2_diff_max_bt_min_qt_intra_slice_luma; |
1810 | 0 | spsLog2DiffMinQtMinCbIntraSliceLuma = sps_log2_diff_max_bt_min_qt_intra_slice_luma; |
1811 | |
|
1812 | 0 | X_READ_UVLC( sps_log2_diff_max_tt_min_qt_intra_slice_luma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY ); |
1813 | 0 | maxTTSize[0] <<= sps_log2_diff_max_tt_min_qt_intra_slice_luma; |
1814 | 0 | } |
1815 | 66 | CHECK( maxTTSize[0] > 64, "The value of sps_log2_diff_max_tt_min_qt_intra_slice_luma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraY" ); |
1816 | | |
1817 | 66 | if( sps_chroma_format_idc != CHROMA_400 ) |
1818 | 0 | { |
1819 | 0 | X_READ_FLAG( sps_qtbtt_dual_tree_intra_flag ); |
1820 | 0 | sps->setUseDualITree( sps_qtbtt_dual_tree_intra_flag ); |
1821 | |
|
1822 | 0 | (void)spsLog2DiffMinQtMinCbIntraSliceLuma; |
1823 | | // this breaks the testset (TREE_C_HHI_3.bit) although specified in the spec |
1824 | | // CHECK( spsLog2DiffMinQtMinCbIntraSliceLuma > std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY && sps_qtbtt_dual_tree_intra_flag, |
1825 | | // "When sps_log2_diff_max_bt_min_qt_intra_slice_luma is greater than Min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY, the value of " |
1826 | | // "sps_qtbtt_dual_tree_intra_flag shall be equal to 0." ) |
1827 | 0 | } |
1828 | | |
1829 | | |
1830 | 66 | if( sps->getUseDualITree() ) |
1831 | 0 | { |
1832 | 0 | X_READ_UVLC( sps_log2_diff_min_qt_min_cb_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY ); |
1833 | 0 | const int MinQtLog2SizeIntraC = sps_log2_diff_min_qt_min_cb_intra_slice_chroma + MinCbLog2SizeY; |
1834 | |
|
1835 | 0 | X_READ_UVLC( sps_max_mtt_hierarchy_depth_intra_slice_chroma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
1836 | 0 | maxBTD[2] = sps_max_mtt_hierarchy_depth_intra_slice_chroma; |
1837 | |
|
1838 | 0 | minQT[2] = 1 << MinQtLog2SizeIntraC; |
1839 | 0 | maxTTSize[2] = maxBTSize[2] = minQT[2]; |
1840 | 0 | if( sps_max_mtt_hierarchy_depth_intra_slice_chroma != 0 ) |
1841 | 0 | { |
1842 | 0 | X_READ_UVLC( sps_log2_diff_max_bt_min_qt_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraC ); |
1843 | 0 | maxBTSize[2] <<= sps_log2_diff_max_bt_min_qt_intra_slice_chroma; |
1844 | |
|
1845 | 0 | X_READ_UVLC( sps_log2_diff_max_tt_min_qt_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraC ); |
1846 | 0 | maxTTSize[2] <<= sps_log2_diff_max_tt_min_qt_intra_slice_chroma; |
1847 | |
|
1848 | 0 | CHECK( maxTTSize[2] > 64, "The value of sps_log2_diff_max_tt_min_qt_intra_slice_chroma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraChroma" ); |
1849 | 0 | CHECK( maxBTSize[2] > 64, "The value of sps_log2_diff_max_bt_min_qt_intra_slice_chroma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraChroma" ); |
1850 | 0 | } |
1851 | 0 | } |
1852 | | // minQT[2] = 1 << MinQtLog2SizeIntraC; // THIS WAS MISSING? -> only read for dual tree |
1853 | | |
1854 | 66 | X_READ_UVLC( sps_log2_diff_min_qt_min_cb_inter_slice, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY ); |
1855 | 66 | const int MinQtLog2SizeInterY = sps_log2_diff_min_qt_min_cb_inter_slice + MinCbLog2SizeY; |
1856 | | |
1857 | 66 | X_READ_UVLC( sps_max_mtt_hierarchy_depth_inter_slice, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
1858 | 66 | maxBTD[1] = sps_max_mtt_hierarchy_depth_inter_slice; |
1859 | | |
1860 | 66 | minQT[1] = 1 << MinQtLog2SizeInterY; |
1861 | 66 | maxTTSize[1] = maxBTSize[1] = minQT[1]; |
1862 | 66 | if( sps_max_mtt_hierarchy_depth_inter_slice != 0 ) |
1863 | 0 | { |
1864 | 0 | X_READ_UVLC( sps_log2_diff_max_bt_min_qt_inter_slice, 0, CtbLog2SizeY - MinQtLog2SizeInterY ); |
1865 | 0 | maxBTSize[1] <<= sps_log2_diff_max_bt_min_qt_inter_slice; |
1866 | |
|
1867 | 0 | X_READ_UVLC( sps_log2_diff_max_tt_min_qt_inter_slice, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeInterY ); |
1868 | 0 | maxTTSize[1] <<= sps_log2_diff_max_tt_min_qt_inter_slice; |
1869 | 0 | } |
1870 | | |
1871 | 66 | sps->setMinQTSizes( minQT ); |
1872 | 66 | sps->setMaxMTTHierarchyDepths( maxBTD ); |
1873 | 66 | sps->setMaxBTSizes( maxBTSize ); |
1874 | 66 | sps->setMaxTTSizes( maxTTSize ); |
1875 | | |
1876 | 66 | if( CtbSizeY > 32 ) |
1877 | 0 | { |
1878 | 0 | X_READ_FLAG( sps_max_luma_transform_size_64_flag ); |
1879 | 0 | sps->setLog2MaxTbSize( 5 + sps_max_luma_transform_size_64_flag ); |
1880 | 0 | } |
1881 | 66 | else |
1882 | 66 | { |
1883 | 66 | sps->setLog2MaxTbSize( 5 ); |
1884 | 66 | } |
1885 | | |
1886 | 66 | X_READ_FLAG( sps_transform_skip_enabled_flag ); |
1887 | 66 | sps->setTransformSkipEnabledFlag( sps_transform_skip_enabled_flag ); |
1888 | | |
1889 | 66 | if( sps_transform_skip_enabled_flag ) |
1890 | 0 | { |
1891 | 0 | X_READ_UVLC( sps_log2_transform_skip_max_size_minus2, 0, 3 ); |
1892 | 0 | sps->setLog2MaxTransformSkipBlockSize( sps_log2_transform_skip_max_size_minus2 + 2 ); |
1893 | |
|
1894 | 0 | X_READ_FLAG( sps_bdpcm_enabled_flag ); |
1895 | 0 | sps->setBDPCMEnabledFlag( sps_bdpcm_enabled_flag ); |
1896 | 0 | } |
1897 | | |
1898 | 66 | X_READ_FLAG( sps_mts_enabled_flag ); |
1899 | 66 | sps->setUseMTS( sps_mts_enabled_flag ); |
1900 | | |
1901 | 66 | if( sps_mts_enabled_flag ) |
1902 | 0 | { |
1903 | 0 | X_READ_FLAG( sps_explicit_mts_intra_enabled_flag ); |
1904 | 0 | sps->setUseIntraMTS( sps_explicit_mts_intra_enabled_flag ); |
1905 | |
|
1906 | 0 | X_READ_FLAG( sps_explicit_mts_inter_enabled_flag ); |
1907 | 0 | sps->setUseInterMTS( sps_explicit_mts_inter_enabled_flag ); |
1908 | 0 | } |
1909 | | |
1910 | 66 | X_READ_FLAG( sps_lfnst_enabled_flag ); |
1911 | 66 | sps->setUseLFNST( sps_lfnst_enabled_flag ); |
1912 | | |
1913 | 66 | if( sps_chroma_format_idc != CHROMA_400 ) |
1914 | 0 | { |
1915 | 0 | X_READ_FLAG( sps_joint_cbcr_enabled_flag ); |
1916 | 0 | sps->setJointCbCrEnabledFlag( sps_joint_cbcr_enabled_flag ); |
1917 | |
|
1918 | 0 | X_READ_FLAG( sps_same_qp_table_for_chroma_flag ); |
1919 | 0 | ChromaQpMappingTableParams chromaQpMappingTableParams; |
1920 | 0 | chromaQpMappingTableParams.setSameCQPTableForAllChromaFlag( sps_same_qp_table_for_chroma_flag ); |
1921 | |
|
1922 | 0 | const int numQpTables = sps_same_qp_table_for_chroma_flag ? 1 : ( sps_joint_cbcr_enabled_flag ? 3 : 2 ); |
1923 | 0 | chromaQpMappingTableParams.setNumQpTables( numQpTables ); |
1924 | |
|
1925 | 0 | for( int i = 0; i < numQpTables; i++ ) |
1926 | 0 | { |
1927 | 0 | X_READ_SVLC( sps_qp_table_start_minus26, -26 - QpBdOffset, 36 ); |
1928 | 0 | chromaQpMappingTableParams.setQpTableStartMinus26( i, sps_qp_table_start_minus26 ); |
1929 | |
|
1930 | 0 | X_READ_UVLC( sps_num_points_in_qp_table_minus1, 0, (unsigned) ( 36 - sps_qp_table_start_minus26 ) ); // cast after subtraction to prevent conversion of sps_qp_table_start_minus26 to unsigned |
1931 | 0 | chromaQpMappingTableParams.setNumPtsInCQPTableMinus1( i, sps_num_points_in_qp_table_minus1 ); |
1932 | |
|
1933 | 0 | std::vector<int> deltaQpInValMinus1( sps_num_points_in_qp_table_minus1 + 1 ); |
1934 | 0 | std::vector<int> deltaQpOutVal( sps_num_points_in_qp_table_minus1 + 1 ); |
1935 | 0 | for( unsigned j = 0; j <= sps_num_points_in_qp_table_minus1; j++ ) |
1936 | 0 | { |
1937 | 0 | X_READ_UVLC_NO_RANGE( sps_delta_qp_in_val_minus1 ); // checked later in ChromaQpMappingTable::deriveChromaQPMappingTables() |
1938 | 0 | deltaQpInValMinus1[j] = sps_delta_qp_in_val_minus1; |
1939 | |
|
1940 | 0 | X_READ_UVLC_NO_RANGE( sps_delta_qp_diff_val ); // checked later in ChromaQpMappingTable::deriveChromaQPMappingTables() |
1941 | 0 | deltaQpOutVal[j] = sps_delta_qp_diff_val ^ deltaQpInValMinus1[j]; |
1942 | 0 | } |
1943 | 0 | chromaQpMappingTableParams.setDeltaQpInValMinus1( i, deltaQpInValMinus1 ); |
1944 | 0 | chromaQpMappingTableParams.setDeltaQpOutVal( i, deltaQpOutVal ); |
1945 | 0 | } |
1946 | 0 | chromaQpMappingTableParams.m_qpBdOffset = sps->getQpBDOffset(); |
1947 | 0 | sps->setChromaQpMappingTableFromParams( std::move( chromaQpMappingTableParams ) ); |
1948 | 0 | sps->deriveChromaQPMappingTables(); |
1949 | 0 | } |
1950 | | |
1951 | | |
1952 | 66 | X_READ_FLAG( sps_sao_enabled_flag ); |
1953 | 66 | sps->setUseSAO( sps_sao_enabled_flag ); |
1954 | | |
1955 | 66 | X_READ_FLAG( sps_alf_enabled_flag ); |
1956 | 66 | sps->setUseALF( sps_alf_enabled_flag ); |
1957 | | |
1958 | 66 | if( sps_alf_enabled_flag && sps_chroma_format_idc != CHROMA_400 ) |
1959 | 0 | { |
1960 | 0 | X_READ_FLAG( sps_ccalf_enabled_flag ); |
1961 | 0 | sps->setUseCCALF( sps_ccalf_enabled_flag ); |
1962 | 0 | } |
1963 | 66 | else |
1964 | 66 | { |
1965 | 66 | sps->setUseCCALF( false ); |
1966 | 66 | } |
1967 | | |
1968 | 66 | X_READ_FLAG( sps_lmcs_enable_flag ); |
1969 | 66 | sps->setUseReshaper( sps_lmcs_enable_flag ); |
1970 | | |
1971 | 66 | X_READ_FLAG( sps_weighted_pred_flag ); |
1972 | 66 | sps->setUseWP( sps_weighted_pred_flag ); |
1973 | | |
1974 | 66 | X_READ_FLAG( sps_weighted_bipred_flag ); |
1975 | 66 | sps->setUseWPBiPred( sps_weighted_bipred_flag ); |
1976 | | |
1977 | 66 | X_READ_FLAG( sps_long_term_ref_pics_flag ); |
1978 | 66 | sps->setLongTermRefsPresent( sps_long_term_ref_pics_flag ); |
1979 | | |
1980 | 66 | if( sps_video_parameter_set_id > 0 ) |
1981 | 0 | { |
1982 | 0 | X_READ_FLAG( sps_inter_layer_prediction_enabled_flag ); |
1983 | 0 | sps->setInterLayerPresentFlag( sps_inter_layer_prediction_enabled_flag ); |
1984 | | // CHECK( vps->getIndependentLayerFlag( vps->getGeneralLayerIdx( nuh_layer_id ) ) == 1 && sps_inter_layer_prediction_enabled_flag != 0, |
1985 | | // "When vps_independent_layer_flag[ GeneralLayerIdx[ nuh_layer_id ] ] is equal to 1," |
1986 | | // " the value of sps_inter_layer_prediction_enabled_flag shall be equal to 0." ) |
1987 | 0 | } |
1988 | | |
1989 | 66 | X_READ_FLAG( sps_idr_rpl_present_flag ); |
1990 | 66 | CHECK_CONSTRAINT( gci->getNoIdrRplConstraintFlag() && sps_idr_rpl_present_flag, |
1991 | 66 | "When gci_no_idr_rpl_constraint_flag equal to 1, the value of sps_idr_rpl_present_flag shall be equal to 0" ); |
1992 | 66 | sps->setIDRRefParamListPresent( sps_idr_rpl_present_flag ); |
1993 | | |
1994 | 66 | X_READ_FLAG( sps_rpl1_same_as_rpl0_flag ); |
1995 | 66 | sps->setRPL1CopyFromRPL0Flag( sps_rpl1_same_as_rpl0_flag ); |
1996 | | |
1997 | 66 | for( unsigned i = 0; i < ( sps_rpl1_same_as_rpl0_flag ? 1 : 2 ); i++ ) |
1998 | 0 | { |
1999 | 0 | X_READ_UVLC_idx( sps_num_ref_pic_lists, "[i]", 0, 64 ); |
2000 | |
|
2001 | 0 | RPLList& rplList = sps->createRPLList( i, sps_num_ref_pic_lists ); |
2002 | 0 | for( unsigned j = 0; j < sps_num_ref_pic_lists; j++ ) |
2003 | 0 | { |
2004 | 0 | parseRefPicList( &rplList[j], j, sps ); |
2005 | 0 | } |
2006 | 0 | } |
2007 | 66 | if( sps_rpl1_same_as_rpl0_flag ) |
2008 | 0 | { |
2009 | 0 | const unsigned numberOfRPL = sps->getNumRPL( 0 ); |
2010 | 0 | const RPLList& rplListSource = sps->getRPLList( 0 ); |
2011 | 0 | RPLList& rplListDest = sps->createRPLList( 1, numberOfRPL ); |
2012 | 0 | for( unsigned j = 0; j < numberOfRPL; j++ ) |
2013 | 0 | { |
2014 | 0 | copyRefPicList( sps, &rplListSource[j], &rplListDest[j] ); |
2015 | 0 | } |
2016 | 0 | } |
2017 | | |
2018 | | |
2019 | 66 | X_READ_FLAG( sps_ref_wraparound_enabled_flag ); |
2020 | 66 | sps->setUseWrapAround( sps_ref_wraparound_enabled_flag ); |
2021 | 66 | for( int i = 0; i < sps->getNumSubPics(); ++i ) |
2022 | 0 | { |
2023 | 0 | CHECK( sps->getSubPicTreatedAsPicFlag( i ) == 1 && sps->getSubPicWidth( i ) != ( sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) >> CtbLog2SizeY |
2024 | 0 | && sps_ref_wraparound_enabled_flag != 0, |
2025 | 0 | "It is a requirement of bitstream conformance that, when there is one or more values of i in the range of 0 to sps_num_subpics_minus1, inclusive," |
2026 | 0 | " for which sps_subpic_treated_as_pic_flag[ i ] is equal to 1 and sps_subpic_width_minus1[ i ] plus 1 is not equal to" |
2027 | 0 | " ( sps_pic_width_max_in_luma_samples + CtbSizeY− 1 ) >> CtbLog2SizeY ), the value of sps_ref_wraparound_enabled_flag shall be equal to 0." ); |
2028 | 0 | } |
2029 | | |
2030 | 66 | X_READ_FLAG( sps_temporal_mvp_enabled_flag ); |
2031 | 66 | sps->setSPSTemporalMVPEnabledFlag( sps_temporal_mvp_enabled_flag ); |
2032 | | |
2033 | 66 | if( sps_temporal_mvp_enabled_flag ) |
2034 | 0 | { |
2035 | 0 | X_READ_FLAG( sps_sbtmvp_enabled_flag ); |
2036 | 0 | sps->setSBTMVPEnabledFlag( sps_sbtmvp_enabled_flag ); |
2037 | 0 | } |
2038 | | |
2039 | 66 | X_READ_FLAG( sps_amvr_enabled_flag ); |
2040 | 66 | sps->setAMVREnabledFlag( sps_amvr_enabled_flag ); |
2041 | | |
2042 | 66 | X_READ_FLAG( sps_bdof_enabled_flag ); |
2043 | 66 | sps->setUseBIO( sps_bdof_enabled_flag ); |
2044 | | |
2045 | 66 | if( sps_bdof_enabled_flag ) |
2046 | 0 | { |
2047 | 0 | X_READ_FLAG( sps_bdof_control_present_in_ph_flag ); |
2048 | 0 | sps->setBdofControlPresentInPhFlag( sps_bdof_control_present_in_ph_flag ); |
2049 | 0 | } |
2050 | | |
2051 | 66 | X_READ_FLAG( sps_smvd_enabled_flag ); |
2052 | 66 | sps->setUseSMVD( sps_smvd_enabled_flag ); |
2053 | | |
2054 | 66 | X_READ_FLAG( sps_dmvr_enabled_flag ); |
2055 | 66 | sps->setUseDMVR( sps_dmvr_enabled_flag ); |
2056 | | |
2057 | 66 | if( sps_dmvr_enabled_flag ) |
2058 | 0 | { |
2059 | 0 | X_READ_FLAG( sps_dmvr_control_present_in_ph_flag ); |
2060 | 0 | sps->setDmvrControlPresentInPhFlag( sps_dmvr_control_present_in_ph_flag ); |
2061 | 0 | } |
2062 | | |
2063 | 66 | X_READ_FLAG( sps_mmvd_enabled_flag ); |
2064 | 66 | sps->setUseMMVD( sps_mmvd_enabled_flag ); |
2065 | | |
2066 | 66 | if( sps->getUseMMVD() ) |
2067 | 0 | { |
2068 | 0 | X_READ_FLAG( sps_mmvd_fullpel_only_flag ); |
2069 | 0 | sps->setFpelMmvdEnabledFlag( sps_mmvd_fullpel_only_flag ); |
2070 | 0 | } |
2071 | | |
2072 | 66 | X_READ_UVLC( sps_six_minus_max_num_merge_cand, 0, 5 ); |
2073 | 66 | const unsigned MaxNumMergeCand = MRG_MAX_NUM_CANDS - sps_six_minus_max_num_merge_cand; |
2074 | 66 | sps->setMaxNumMergeCand( MaxNumMergeCand ); |
2075 | | |
2076 | 66 | X_READ_FLAG( sps_sbt_enabled_flag ); |
2077 | 66 | sps->setUseSBT( sps_sbt_enabled_flag ); |
2078 | | |
2079 | 66 | X_READ_FLAG( sps_affine_enabled_flag ); |
2080 | 66 | sps->setUseAffine( sps_affine_enabled_flag ); |
2081 | | |
2082 | 66 | if( sps_affine_enabled_flag ) |
2083 | 0 | { |
2084 | 0 | X_READ_UVLC( sps_five_minus_max_num_subblock_merge_cand, 0, 5 - sps->getSBTMVPEnabledFlag() ); |
2085 | 0 | sps->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - sps_five_minus_max_num_subblock_merge_cand ); |
2086 | |
|
2087 | 0 | X_READ_FLAG( sps_6param_affine_enabled_flag ); |
2088 | 0 | sps->setUseAffineType( sps_6param_affine_enabled_flag ); |
2089 | |
|
2090 | 0 | if( sps_amvr_enabled_flag ) |
2091 | 0 | { |
2092 | 0 | X_READ_FLAG( sps_affine_amvr_enabled_flag ); |
2093 | 0 | sps->setAffineAmvrEnabledFlag( sps_affine_amvr_enabled_flag ); |
2094 | 0 | } |
2095 | |
|
2096 | 0 | X_READ_FLAG( sps_affine_prof_enabled_flag ); |
2097 | 0 | sps->setUsePROF( sps_affine_prof_enabled_flag ); |
2098 | |
|
2099 | 0 | if( sps_affine_prof_enabled_flag ) |
2100 | 0 | { |
2101 | 0 | X_READ_FLAG( sps_prof_control_present_in_ph_flag ); |
2102 | 0 | sps->setProfControlPresentInPhFlag( sps_prof_control_present_in_ph_flag ); |
2103 | 0 | } |
2104 | 0 | } |
2105 | | |
2106 | 66 | X_READ_FLAG( sps_bcw_enabled_flag ); |
2107 | 66 | sps->setUseBcw( sps_bcw_enabled_flag ); |
2108 | | |
2109 | 66 | X_READ_FLAG( sps_ciip_enabled_flag ); |
2110 | 66 | sps->setUseCiip( sps_ciip_enabled_flag ); |
2111 | | |
2112 | 66 | if( MaxNumMergeCand >= 2 ) |
2113 | 0 | { |
2114 | 0 | X_READ_FLAG( sps_gpm_enabled_flag ); |
2115 | 0 | sps->setUseGeo( sps_gpm_enabled_flag ); |
2116 | |
|
2117 | 0 | if( sps_gpm_enabled_flag && MaxNumMergeCand >= 3 ) |
2118 | 0 | { |
2119 | 0 | X_READ_UVLC( sps_max_num_merge_cand_minus_max_num_gpm_cand, 0, MaxNumMergeCand - 2 ); |
2120 | 0 | sps->setMaxNumGeoCand( MaxNumMergeCand - sps_max_num_merge_cand_minus_max_num_gpm_cand ); |
2121 | 0 | } |
2122 | 0 | else if( sps_gpm_enabled_flag ) |
2123 | 0 | { |
2124 | 0 | sps->setMaxNumGeoCand( 2 ); |
2125 | 0 | } |
2126 | 0 | } |
2127 | | |
2128 | 66 | X_READ_UVLC( sps_log2_parallel_merge_level_minus2, 0, CtbLog2SizeY - 2 ); |
2129 | 66 | sps->setLog2ParallelMergeLevelMinus2( sps_log2_parallel_merge_level_minus2 ); |
2130 | | |
2131 | 66 | X_READ_FLAG( sps_isp_enabled_flag ); |
2132 | 66 | sps->setUseISP( sps_isp_enabled_flag ); |
2133 | | |
2134 | 66 | X_READ_FLAG( sps_mrl_enabled_flag ); |
2135 | 66 | sps->setUseMRL( sps_mrl_enabled_flag ); |
2136 | | |
2137 | 66 | X_READ_FLAG( sps_mip_enabled_flag ); |
2138 | 66 | sps->setUseMIP( sps_mip_enabled_flag ); |
2139 | | |
2140 | 66 | if( sps_chroma_format_idc != CHROMA_400 ) |
2141 | 0 | { |
2142 | 0 | X_READ_FLAG( sps_cclm_enabled_flag ); |
2143 | 0 | sps->setUseLMChroma( sps_cclm_enabled_flag ); |
2144 | 0 | } |
2145 | | |
2146 | 66 | if( sps_chroma_format_idc == CHROMA_420 ) |
2147 | 0 | { |
2148 | 0 | X_READ_FLAG( sps_chroma_horizontal_collocated_flag ); |
2149 | 0 | sps->setHorCollocatedChromaFlag( sps_chroma_horizontal_collocated_flag ); |
2150 | |
|
2151 | 0 | X_READ_FLAG( sps_chroma_vertical_collocated_flag ); |
2152 | 0 | sps->setVerCollocatedChromaFlag( sps_chroma_vertical_collocated_flag ); |
2153 | 0 | } |
2154 | | |
2155 | 66 | X_READ_FLAG( sps_palette_enabled_flag ); |
2156 | 66 | CHECK( sps_palette_enabled_flag, "palette mode is not yet supported" ); |
2157 | | |
2158 | 66 | if( sps_chroma_format_idc == CHROMA_444 && sps->getLog2MaxTbSize() != 6 ) |
2159 | 0 | { |
2160 | 0 | X_READ_FLAG( sps_act_enabled_flag ); |
2161 | 0 | sps->setUseColorTrans( sps_act_enabled_flag ); |
2162 | 0 | } |
2163 | | |
2164 | 66 | if( sps_transform_skip_enabled_flag || sps_palette_enabled_flag ) |
2165 | 0 | { |
2166 | 0 | X_READ_UVLC( sps_internal_bit_depth_minus_input_bit_depth, 0, 8 ); // Why is this called sps_min_qp_prime_ts in the standard? |
2167 | 0 | sps->setInternalMinusInputBitDepth( sps_internal_bit_depth_minus_input_bit_depth ); |
2168 | 0 | } |
2169 | | |
2170 | 66 | X_READ_FLAG( sps_ibc_enabled_flag ); |
2171 | 66 | sps->setIBCFlag( sps_ibc_enabled_flag ); |
2172 | | |
2173 | 66 | if( sps_ibc_enabled_flag ) |
2174 | 0 | { |
2175 | 0 | X_READ_UVLC( sps_six_minus_max_num_ibc_merge_cand, 0, 5 ); |
2176 | 0 | sps->setMaxNumIBCMergeCand( IBC_MRG_MAX_NUM_CANDS - sps_six_minus_max_num_ibc_merge_cand ); |
2177 | 0 | } |
2178 | | |
2179 | 66 | # if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET |
2180 | 66 | X_READ_FLAG( sps_ladf_enabled_flag ); |
2181 | 66 | sps->setLadfEnabled( sps_ladf_enabled_flag ); |
2182 | | |
2183 | 66 | if( sps->getLadfEnabled() ) |
2184 | 0 | { |
2185 | 0 | X_READ_CODE( sps_num_ladf_intervals_minus2, 2, 0, 3 ); |
2186 | 0 | sps->setLadfNumIntervals( sps_num_ladf_intervals_minus2 + 2 ); |
2187 | |
|
2188 | 0 | X_READ_SVLC( sps_ladf_lowest_interval_qp_offset, -63, 63 ); |
2189 | 0 | sps->setLadfQpOffset( sps_ladf_lowest_interval_qp_offset, 0 ); |
2190 | |
|
2191 | 0 | for( unsigned i = 0; i < sps_num_ladf_intervals_minus2 + 1; i++ ) |
2192 | 0 | { |
2193 | 0 | X_READ_SVLC_idx( sps_ladf_qp_offset, "[i]", -63, 63 ); |
2194 | 0 | sps->setLadfQpOffset( sps_ladf_qp_offset, i + 1 ); |
2195 | |
|
2196 | 0 | X_READ_UVLC_idx( sps_ladf_delta_threshold_minus1, "[i]", 0, ( 1 << BitDepth ) - 3 ); |
2197 | 0 | sps->setLadfIntervalLowerBound( sps->getLadfIntervalLowerBound( i ) + sps_ladf_delta_threshold_minus1 + 1, i + 1 ); |
2198 | 0 | } |
2199 | 0 | } |
2200 | 66 | #endif |
2201 | | |
2202 | 66 | X_READ_FLAG( sps_explicit_scaling_list_enabled_flag ); |
2203 | 66 | CHECK_CONSTRAINT( gci->getNoExplicitScaleListConstraintFlag() && sps_explicit_scaling_list_enabled_flag, |
2204 | 66 | "When gci_no_explicit_scaling_list_constraint_flag is equal to 1, sps_explicit_scaling_list_enabled_flag shall be equal to 0" ); |
2205 | 66 | sps->setScalingListFlag( sps_explicit_scaling_list_enabled_flag ); |
2206 | | |
2207 | 66 | if( sps_lfnst_enabled_flag && sps_explicit_scaling_list_enabled_flag ) |
2208 | 0 | { |
2209 | 0 | X_READ_FLAG( sps_scaling_matrix_for_lfnst_disabled_flag ); |
2210 | 0 | sps->setDisableScalingMatrixForLfnstBlks( sps_scaling_matrix_for_lfnst_disabled_flag ); |
2211 | 0 | } |
2212 | | |
2213 | 66 | if( sps->getUseColorTrans() && sps_explicit_scaling_list_enabled_flag ) |
2214 | 0 | { |
2215 | 0 | X_READ_FLAG( sps_scaling_matrix_for_alternative_colour_space_disabled_flag ); |
2216 | 0 | sps->setScalingMatrixForAlternativeColourSpaceDisabledFlag( sps_scaling_matrix_for_alternative_colour_space_disabled_flag ); |
2217 | |
|
2218 | 0 | if( sps_scaling_matrix_for_alternative_colour_space_disabled_flag ) |
2219 | 0 | { |
2220 | 0 | X_READ_FLAG( sps_scaling_matrix_designated_colour_space_flag ); |
2221 | 0 | sps->setScalingMatrixDesignatedColourSpaceFlag( sps_scaling_matrix_designated_colour_space_flag ); |
2222 | 0 | } |
2223 | 0 | } |
2224 | | |
2225 | 66 | X_READ_FLAG( sps_dep_quant_enabled_flag ); |
2226 | 66 | sps->setDepQuantEnabledFlag( sps_dep_quant_enabled_flag ); |
2227 | | |
2228 | 66 | X_READ_FLAG( sps_sign_data_hiding_enabled_flag ); |
2229 | 66 | sps->setSignDataHidingEnabledFlag( sps_sign_data_hiding_enabled_flag ); |
2230 | | |
2231 | 66 | X_READ_FLAG( sps_virtual_boundaries_enabled_flag ); |
2232 | 66 | CHECK_CONSTRAINT( gci->getNoVirtualBoundaryConstraintFlag() && sps_virtual_boundaries_enabled_flag, |
2233 | 66 | "When gci_no_virtual_boundaries_constraint_flag is equal to 1, sps_virtual_boundaries_enabled_flag shall be equal to 0" ); |
2234 | 66 | sps->setVirtualBoundariesEnabledFlag( sps_virtual_boundaries_enabled_flag ); |
2235 | | |
2236 | 66 | if( sps_virtual_boundaries_enabled_flag ) |
2237 | 0 | { |
2238 | 0 | X_READ_FLAG( sps_virtual_boundaries_present_flag ); |
2239 | 0 | sps->setVirtualBoundariesPresentFlag( sps_virtual_boundaries_present_flag ); |
2240 | |
|
2241 | 0 | if( sps_virtual_boundaries_present_flag ) |
2242 | 0 | { |
2243 | 0 | X_READ_UVLC( sps_num_ver_virtual_boundaries, 0, sps_pic_width_max_in_luma_samples <= 8 ? 0 : 3 ); |
2244 | 0 | sps->setNumVerVirtualBoundaries( sps_num_ver_virtual_boundaries ); |
2245 | |
|
2246 | 0 | for( unsigned i = 0; i < sps_num_ver_virtual_boundaries; i++ ) |
2247 | 0 | { |
2248 | 0 | X_READ_UVLC_idx( sps_virtual_boundary_pos_x_minus1, "[i]", 0, ( sps_pic_width_max_in_luma_samples + 7 ) / 8 - 2 ); |
2249 | 0 | sps->setVirtualBoundariesPosX( ( sps_virtual_boundary_pos_x_minus1 + 1 ) << 3, i ); |
2250 | 0 | } |
2251 | |
|
2252 | 0 | X_READ_UVLC_idx( sps_num_hor_virtual_boundaries, "[i]", 0, sps_pic_height_max_in_luma_samples <= 8 ? 0 : 3 ); |
2253 | 0 | sps->setNumHorVirtualBoundaries( sps_num_hor_virtual_boundaries ); |
2254 | |
|
2255 | 0 | for( unsigned i = 0; i <sps_num_hor_virtual_boundaries; i++ ) |
2256 | 0 | { |
2257 | 0 | X_READ_UVLC_idx( sps_virtual_boundary_pos_y_minus1, "[i]", 0, ( sps_pic_height_max_in_luma_samples + 7 ) / 8 - 2 ); |
2258 | 0 | sps->setVirtualBoundariesPosY( (sps_virtual_boundary_pos_y_minus1 + 1) << 3, i ); |
2259 | 0 | } |
2260 | 0 | } |
2261 | 0 | } |
2262 | | |
2263 | 66 | if( sps_ptl_dpb_hrd_params_present_flag ) |
2264 | 0 | { |
2265 | 0 | X_READ_FLAG( sps_timing_hrd_params_present_flag ); |
2266 | 0 | sps->setGeneralHrdParametersPresentFlag( sps_timing_hrd_params_present_flag ); |
2267 | |
|
2268 | 0 | if( sps_timing_hrd_params_present_flag ) |
2269 | 0 | { |
2270 | 0 | parseGeneralHrdParameters( sps->getGeneralHrdParameters() ); |
2271 | 0 | if( sps_max_sublayers_minus1 > 0 ) |
2272 | 0 | { |
2273 | 0 | X_READ_FLAG( sps_sublayer_cpb_params_present_flag ); |
2274 | 0 | sps->setSubLayerParametersPresentFlag( sps_sublayer_cpb_params_present_flag ); |
2275 | 0 | } |
2276 | |
|
2277 | 0 | uint32_t firstSubLayer = sps->getSubLayerParametersPresentFlag() ? 0 : sps_max_sublayers_minus1; |
2278 | 0 | parseOlsHrdParameters( sps->getGeneralHrdParameters(), sps->getOlsHrdParameters(), firstSubLayer, sps_max_sublayers_minus1 ); |
2279 | 0 | } |
2280 | 0 | } |
2281 | | |
2282 | 66 | X_READ_FLAG( sps_field_seq_flag ); |
2283 | 66 | sps->setFieldSeqFlag( sps_field_seq_flag ); |
2284 | | |
2285 | 66 | CHECK_CONSTRAINT( sps->getProfileTierLevel()->getFrameOnlyConstraintFlag() && sps_field_seq_flag, |
2286 | 66 | "When ptl_frame_only_constraint_flag equal to 1 , the value of sps_field_seq_flag shall be equal to 0" ); |
2287 | | |
2288 | 66 | X_READ_FLAG( sps_vui_parameters_present_flag ); |
2289 | 66 | sps->setVuiParametersPresentFlag( sps_vui_parameters_present_flag ); |
2290 | | |
2291 | 66 | if( sps_vui_parameters_present_flag ) |
2292 | 0 | { |
2293 | 0 | X_READ_UVLC( sps_vui_payload_size_minus1, 0, 1023 ); |
2294 | 0 | sps->setVuiPayloadSize( sps_vui_payload_size_minus1 + 1 ); |
2295 | |
|
2296 | 0 | while( !isByteAligned() ) |
2297 | 0 | { |
2298 | 0 | X_READ_FLAG( sps_vui_alignment_zero_bit ); |
2299 | 0 | CHECK( sps_vui_alignment_zero_bit, "sps_vui_alignment_zero_bit not equal to 0" ); |
2300 | 0 | } |
2301 | | |
2302 | 0 | parseVUI( sps->getVuiParameters(), sps->getVuiPayloadSize() ); |
2303 | 0 | } |
2304 | | |
2305 | 66 | X_READ_FLAG( sps_extension_present_flag ); |
2306 | 66 | if( sps_extension_present_flag ) |
2307 | 0 | { |
2308 | 0 | while( xMoreRbspData() ) |
2309 | 0 | { |
2310 | 0 | X_READ_FLAG( sps_extension_data_flag ); |
2311 | 0 | (void)sps_extension_data_flag; |
2312 | 0 | } |
2313 | 0 | } |
2314 | | |
2315 | 66 | xReadRbspTrailingBits(); |
2316 | 66 | } |
2317 | | |
2318 | | void HLSyntaxReader::parseDCI( DCI* dci ) |
2319 | 24 | { |
2320 | | #if ENABLE_TRACING |
2321 | | xTraceDCIHeader(); |
2322 | | #endif |
2323 | 24 | X_READ_CODE_NO_RANGE( dci_reserved_zero_4bits, 4 ); |
2324 | 24 | (void) dci_reserved_zero_4bits; |
2325 | | |
2326 | 24 | X_READ_CODE( dci_num_ptls_minus1, 4, 0, 15 ); |
2327 | 24 | CHECK_WARN( dci_num_ptls_minus1 == 15, "reserved dci_num_ptls_minus1==15 used" ); |
2328 | 24 | const int numPTLs = dci_num_ptls_minus1 + 1; |
2329 | | |
2330 | 24 | std::vector<ProfileTierLevel> ptls( numPTLs ); |
2331 | 62 | for( int i = 0; i < numPTLs; i++ ) |
2332 | 38 | { |
2333 | 38 | parseProfileTierLevel( &ptls[i], true, 0 ); |
2334 | 38 | } |
2335 | 24 | dci->setProfileTierLevel( std::move( ptls ) ); |
2336 | | |
2337 | 24 | X_READ_FLAG(dci_extension_flag ); |
2338 | 24 | if( dci_extension_flag ) |
2339 | 6 | { |
2340 | 832 | while( xMoreRbspData() ) |
2341 | 826 | { |
2342 | 826 | X_READ_FLAG( dci_extension_data_flag ); |
2343 | 826 | (void) dci_extension_data_flag; |
2344 | 826 | } |
2345 | 6 | } |
2346 | 24 | xReadRbspTrailingBits(); |
2347 | 24 | } |
2348 | | |
2349 | | #if 0 |
2350 | | // We don't parse the VPS, because the needed bounds checks in parseVPS() are not yet implemented, and we don't process it anyways |
2351 | | void HLSyntaxReader::parseVPS( VPS* pcVPS ) |
2352 | | { |
2353 | | #if ENABLE_TRACING |
2354 | | xTraceVPSHeader(); |
2355 | | #endif |
2356 | | uint32_t uiCode; |
2357 | | |
2358 | | //CHECK( true, "needs to be adjusted, e.g. sublayer and independent layer stuff -> see VTM-9.0" ); |
2359 | | |
2360 | | READ_CODE( 4, uiCode, "vps_video_parameter_set_id" ); pcVPS->setVPSId( uiCode ); |
2361 | | CHECK( uiCode == 0, "vps_video_parameter_set_id equal to zero is reserved and shall not be used in a bitstream" ); |
2362 | | |
2363 | | READ_CODE( 6, uiCode, "vps_max_layers_minus1" ); pcVPS->setMaxLayers( uiCode + 1 ); |
2364 | | CHECK( uiCode + 1 > MAX_VPS_LAYERS, "Signalled number of layers larger than MAX_VPS_LAYERS." ); |
2365 | | |
2366 | | if( pcVPS->getMaxLayers() - 1 == 0 ) |
2367 | | { |
2368 | | pcVPS->setEachLayerIsAnOlsFlag( 1 ); |
2369 | | } |
2370 | | READ_CODE( 3, uiCode, "vps_max_sublayers_minus1" ); pcVPS->setMaxSubLayers( uiCode + 1 ); |
2371 | | CHECK( uiCode + 1 > MAX_VPS_SUBLAYERS, "Signalled number of sublayers larger than MAX_VPS_SUBLAYERS." ); |
2372 | | |
2373 | | if( pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1 ) |
2374 | | { |
2375 | | READ_FLAG( uiCode, "vps_default_ptl_dpb_hrd_max_tid_flag" ); pcVPS->setAllLayersSameNumSublayersFlag( uiCode ); |
2376 | | } |
2377 | | else |
2378 | | { |
2379 | | pcVPS->setAllLayersSameNumSublayersFlag( 1 ); |
2380 | | } |
2381 | | if( pcVPS->getMaxLayers() > 1 ) |
2382 | | { |
2383 | | READ_FLAG( uiCode, "vps_all_independent_layers_flag" ); pcVPS->setAllIndependentLayersFlag( uiCode ); |
2384 | | if( pcVPS->getAllIndependentLayersFlag() == 0 ) |
2385 | | { |
2386 | | pcVPS->setEachLayerIsAnOlsFlag( 0 ); |
2387 | | } |
2388 | | } |
2389 | | for( uint32_t i = 0; i < pcVPS->getMaxLayers(); i++ ) |
2390 | | { |
2391 | | READ_CODE( 6, uiCode, "vps_layer_id[i]" ); pcVPS->setLayerId( i, uiCode ); |
2392 | | pcVPS->setGeneralLayerIdx( uiCode, i ); |
2393 | | |
2394 | | if( i > 0 && !pcVPS->getAllIndependentLayersFlag() ) |
2395 | | { |
2396 | | READ_FLAG( uiCode, "vps_independent_layer_flag[i]" ); pcVPS->setIndependentLayerFlag( i, uiCode ); |
2397 | | if( !pcVPS->getIndependentLayerFlag( i ) ) |
2398 | | { |
2399 | | READ_FLAG( uiCode, "vps_max_tid_ref_present_flag[i]" ); |
2400 | | bool vpsMaxTidRefPresentFlag = ( uiCode == 1 ); |
2401 | | |
2402 | | uint16_t sumUiCode = 0; |
2403 | | for( int j = 0, k = 0; j < i; j++ ) |
2404 | | { |
2405 | | READ_FLAG( uiCode, "vps_direct_ref_layer_flag[ i ][ j ]" ); pcVPS->setDirectRefLayerFlag( i, j, uiCode ); |
2406 | | if( uiCode ) |
2407 | | { |
2408 | | pcVPS->setInterLayerRefIdc( i, j, k ); |
2409 | | pcVPS->setDirectRefLayerIdx( i, k++, j ); |
2410 | | sumUiCode++; |
2411 | | if( vpsMaxTidRefPresentFlag ) |
2412 | | { |
2413 | | READ_CODE( 3, uiCode, "vps_max_tid_il_ref_pics_plus1[i][ j ]" ); |
2414 | | // pcVPS->setMaxTidIlRefPicsPlus1( i, uiCode ); |
2415 | | } |
2416 | | } |
2417 | | } |
2418 | | CHECK(sumUiCode == 0, "There has to be at least one value of j such that the value of vps_direct_dependency_flag[i][ j ] is equal to 1,when vps_independent_layer_flag[i] is equal to 0 " ); |
2419 | | // if( uiCode ) |
2420 | | // { |
2421 | | // READ_CODE( 3, uiCode, "max_tid_il_ref_pics_plus1[i]" ); pcVPS->setMaxTidIlRefPicsPlus1( i, uiCode ); |
2422 | | // } |
2423 | | // else |
2424 | | // { |
2425 | | // pcVPS->setMaxTidIlRefPicsPlus1( i, 7) ; |
2426 | | // } |
2427 | | } |
2428 | | } |
2429 | | } |
2430 | | |
2431 | | if( pcVPS->getMaxLayers() > 1 ) |
2432 | | { |
2433 | | if( pcVPS->getAllIndependentLayersFlag() ) |
2434 | | { |
2435 | | READ_FLAG( uiCode, "vps_each_layer_is_an_ols_flag" ); pcVPS->setEachLayerIsAnOlsFlag( uiCode ); |
2436 | | if( pcVPS->getEachLayerIsAnOlsFlag() == 0 ) |
2437 | | { |
2438 | | pcVPS->setOlsModeIdc( 2 ); |
2439 | | } |
2440 | | } |
2441 | | if( !pcVPS->getEachLayerIsAnOlsFlag() ) |
2442 | | { |
2443 | | if( !pcVPS->getAllIndependentLayersFlag() ) |
2444 | | { |
2445 | | READ_CODE( 2, uiCode, "vps_ols_mode_idc" ); pcVPS->setOlsModeIdc( uiCode ); |
2446 | | CHECK( uiCode > MAX_VPS_OLS_MODE_IDC, "ols_mode_idc shall be in the rage of 0 to 2" ); |
2447 | | } |
2448 | | if( pcVPS->getOlsModeIdc() == 2 ) |
2449 | | { |
2450 | | READ_CODE( 8, uiCode, "vps_num_output_layer_sets_minus2" ); pcVPS->setNumOutputLayerSets( uiCode + 2 ); |
2451 | | for( uint32_t i = 1; i <= pcVPS->getNumOutputLayerSets() - 1; i++ ) |
2452 | | { |
2453 | | for( uint32_t j = 0; j < pcVPS->getMaxLayers(); j++ ) |
2454 | | { |
2455 | | READ_FLAG( uiCode, "vps_ols_output_layer_flag[i][ j ]" ); pcVPS->setOlsOutputLayerFlag( i, j, uiCode ); |
2456 | | } |
2457 | | } |
2458 | | } |
2459 | | } |
2460 | | READ_CODE( 8, uiCode, "vps_num_ptls_minus1" ); pcVPS->setNumPtls( uiCode + 1 ); |
2461 | | } |
2462 | | else |
2463 | | { |
2464 | | pcVPS->setNumPtls( 1 ); |
2465 | | } |
2466 | | |
2467 | | pcVPS->deriveOutputLayerSets(); |
2468 | | CHECK( uiCode >= pcVPS->getTotalNumOLSs(), "The value of vps_num_ptls_minus1 shall be less than TotalNumOlss" ); |
2469 | | |
2470 | | std::vector<bool> isPTLReferred( pcVPS->getNumPtls(), false ); |
2471 | | for( int i = 0; i < pcVPS->getNumPtls(); i++ ) |
2472 | | { |
2473 | | if( i > 0 ) |
2474 | | { |
2475 | | READ_FLAG( uiCode, "pt_present_flag[i]" ); pcVPS->setPtPresentFlag( i, uiCode ); |
2476 | | } |
2477 | | else |
2478 | | { |
2479 | | pcVPS->setPtPresentFlag( 0, 1 ); |
2480 | | } |
2481 | | |
2482 | | if( !pcVPS->getAllLayersSameNumSublayersFlag() ) |
2483 | | { |
2484 | | READ_CODE( 3, uiCode, "ptl_max_tid[i]" ); pcVPS->setPtlMaxTemporalId( i, uiCode ); |
2485 | | } |
2486 | | else |
2487 | | { |
2488 | | pcVPS->setPtlMaxTemporalId( i, pcVPS->getMaxSubLayers() - 1 ); |
2489 | | } |
2490 | | } |
2491 | | int cnt = 0; |
2492 | | while( m_pcBitstream->getNumBitsUntilByteAligned() ) |
2493 | | { |
2494 | | READ_FLAG( uiCode, "vps_ptl_reserved_zero_bit" ); |
2495 | | CHECK( uiCode!=0, "Alignment bit is not '0'" ); |
2496 | | cnt++; |
2497 | | } |
2498 | | CHECK( cnt >= 8, "Read more than '8' alignment bits" ); |
2499 | | { |
2500 | | std::vector<ProfileTierLevel> ptls( pcVPS->getNumPtls() ); |
2501 | | for( int i = 0; i < pcVPS->getNumPtls(); i++ ) |
2502 | | { |
2503 | | parseProfileTierLevel( &ptls[i], pcVPS->getPtPresentFlag( i ), pcVPS->getPtlMaxTemporalId( i ) ); |
2504 | | } |
2505 | | pcVPS->setProfileTierLevel( std::move( ptls ) ); |
2506 | | } |
2507 | | for( int i = 0; i < pcVPS->getTotalNumOLSs(); i++ ) |
2508 | | { |
2509 | | if( pcVPS->getNumPtls() > 1 && pcVPS->getNumPtls() != pcVPS->getTotalNumOLSs() ) |
2510 | | { |
2511 | | READ_CODE( 8, uiCode, "vps_ols_ptl_idx[i]" ); pcVPS->setOlsPtlIdx( i, uiCode ); |
2512 | | } |
2513 | | else if( pcVPS->getNumPtls() == pcVPS->getTotalNumOLSs() ) |
2514 | | { |
2515 | | pcVPS->setOlsPtlIdx( i, i ); |
2516 | | } |
2517 | | else |
2518 | | { |
2519 | | pcVPS->setOlsPtlIdx( i, 0 ); |
2520 | | } |
2521 | | isPTLReferred[pcVPS->getOlsPtlIdx( i )] = true; |
2522 | | } |
2523 | | for( int i = 0; i < pcVPS->getNumPtls(); i++ ) |
2524 | | { |
2525 | | CHECK( !isPTLReferred[i],"Each profile_tier_level( ) syntax structure in the VPS shall be referred to by at least one value of vps_ols_ptl_idx[i] for i in the range of 0 to TotalNumOlss ? 1, inclusive" ); |
2526 | | } |
2527 | | |
2528 | | if( !pcVPS->getEachLayerIsAnOlsFlag() ) |
2529 | | { |
2530 | | READ_UVLC( uiCode, "vps_num_dpb_params_minus1" ); pcVPS->m_numDpbParams = uiCode + 1; |
2531 | | |
2532 | | CHECK( pcVPS->m_numDpbParams > pcVPS->getNumMultiLayeredOlss(), "The value of vps_num_dpb_params_minus1 shall be in the range of 0 to NumMultiLayerOlss - 1, inclusive" ); |
2533 | | std::vector<bool> isDPBParamReferred( pcVPS->m_numDpbParams, false ); |
2534 | | |
2535 | | if( pcVPS->m_numDpbParams > 0 && pcVPS->getMaxSubLayers() > 1 ) |
2536 | | { |
2537 | | READ_FLAG( uiCode, "vps_sublayer_dpb_params_present_flag" ); pcVPS->m_sublayerDpbParamsPresentFlag = uiCode; |
2538 | | } |
2539 | | |
2540 | | pcVPS->m_dpbParameters.resize( pcVPS->m_numDpbParams ); |
2541 | | |
2542 | | for( int i = 0; i < pcVPS->m_numDpbParams; i++ ) |
2543 | | { |
2544 | | if( !pcVPS->getAllLayersSameNumSublayersFlag() ) |
2545 | | { |
2546 | | READ_CODE( 3, uiCode, "vps_dpb_max_tid[i]" ); |
2547 | | pcVPS->m_dpbMaxTemporalId.push_back( uiCode ); |
2548 | | CHECK( uiCode > ( pcVPS->getMaxSubLayers() - 1 ), "The value of vps_dpb_max_tid[i] shall be in the range of 0 to vps_max_sublayers_minus1, inclusive." ) |
2549 | | } |
2550 | | else |
2551 | | { |
2552 | | pcVPS->m_dpbMaxTemporalId.push_back( pcVPS->getMaxSubLayers() - 1 ); |
2553 | | } |
2554 | | |
2555 | | for( int j = ( pcVPS->m_sublayerDpbParamsPresentFlag ? 0 : pcVPS->m_dpbMaxTemporalId[i] ); j <= pcVPS->m_dpbMaxTemporalId[i]; j++ ) |
2556 | | { |
2557 | | READ_UVLC( uiCode, "dpb_max_dec_pic_buffering_minus1[i]" ); pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[j] = uiCode + 1; |
2558 | | READ_UVLC( uiCode, "dpb_max_num_reorder_pics[i]" ); pcVPS->m_dpbParameters[i].m_numReorderPics[j] = uiCode; |
2559 | | READ_UVLC( uiCode, "dpb_max_latency_increase_plus1[i]" ); pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = uiCode; |
2560 | | } |
2561 | | |
2562 | | for( int j = ( pcVPS->m_sublayerDpbParamsPresentFlag ? pcVPS->m_dpbMaxTemporalId[i] : 0 ); j < pcVPS->m_dpbMaxTemporalId[i]; j++ ) |
2563 | | { |
2564 | | // When max_dec_pic_buffering_minus1[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ]. |
2565 | | pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[j] = pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[pcVPS->m_dpbMaxTemporalId[i]]; |
2566 | | |
2567 | | // When max_num_reorder_pics[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ]. |
2568 | | pcVPS->m_dpbParameters[i].m_numReorderPics[j] = pcVPS->m_dpbParameters[i].m_numReorderPics[pcVPS->m_dpbMaxTemporalId[i]]; |
2569 | | |
2570 | | // When max_latency_increase_plus1[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ]. |
2571 | | pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[pcVPS->m_dpbMaxTemporalId[i]]; |
2572 | | } |
2573 | | } |
2574 | | |
2575 | | for( int i = 0, j=0; i < pcVPS->getTotalNumOLSs(); i++ ) |
2576 | | { |
2577 | | if( pcVPS->m_numLayersInOls[i] > 1 ) |
2578 | | { |
2579 | | READ_UVLC( uiCode, "vps_ols_dpb_pic_width[i]" ); pcVPS->setOlsDpbPicWidth( i, uiCode ); |
2580 | | READ_UVLC( uiCode, "vps_ols_dpb_pic_height[i]" ); pcVPS->setOlsDpbPicHeight( i, uiCode ); |
2581 | | READ_CODE( 2, uiCode, "vps_ols_dpb_chroma_format[i]" ); pcVPS->setOlsDpbChromaFormatIdc( i, uiCode ); |
2582 | | READ_UVLC( uiCode, "vps_ols_dpb_bitdepth_minus8[i]" ); pcVPS->setOlsDpbBitDepthMinus8( i, uiCode ); |
2583 | | const Profile::Name profile = pcVPS->getProfileTierLevel( pcVPS->getOlsPtlIdx( i ) ).getProfileIdc(); |
2584 | | if( profile != Profile::NONE ) |
2585 | | { |
2586 | | CHECK( uiCode + 8 > ProfileFeatures::getProfileFeatures( profile )->maxBitDepth, |
2587 | | "vps_ols_dpb_bitdepth_minus8[ i ] exceeds range supported by signalled profile" ); |
2588 | | } |
2589 | | if( ( pcVPS->m_numDpbParams > 1 ) && ( pcVPS->m_numDpbParams != pcVPS->m_numMultiLayeredOlss) ) |
2590 | | { |
2591 | | READ_UVLC( uiCode, "vps_ols_dpb_params_idx[i]" ); pcVPS->setOlsDpbParamsIdx( i, uiCode ); |
2592 | | } |
2593 | | else if( pcVPS->m_numDpbParams == 1 ) |
2594 | | { |
2595 | | pcVPS->setOlsDpbParamsIdx( i, 0 ); |
2596 | | } |
2597 | | else |
2598 | | { |
2599 | | pcVPS->setOlsDpbParamsIdx( i, j ); |
2600 | | } |
2601 | | j += 1; |
2602 | | isDPBParamReferred[pcVPS->getOlsDpbParamsIdx( i )] = true; |
2603 | | } |
2604 | | } |
2605 | | for( int i = 0; i < pcVPS->m_numDpbParams; i++ ) |
2606 | | { |
2607 | | CHECK( !isDPBParamReferred[i], "Each dpb_parameters() syntax structure in the VPS shall be referred to by at least one value of vps_ols_dpb_params_idx[i] for i in the range of 0 to NumMultiLayerOlss - 1, inclusive" ); |
2608 | | } |
2609 | | } |
2610 | | |
2611 | | if( !pcVPS->getEachLayerIsAnOlsFlag() ) |
2612 | | { |
2613 | | READ_FLAG( uiCode, "vps_general_hrd_params_present_flag" ); pcVPS->setVPSGeneralHrdParamsPresentFlag( uiCode ); |
2614 | | } |
2615 | | if( pcVPS->getVPSGeneralHrdParamsPresentFlag() ) |
2616 | | { |
2617 | | parseGeneralHrdParameters( pcVPS->getGeneralHrdParameters() ); |
2618 | | if( ( pcVPS->getMaxSubLayers() - 1 ) > 0 ) |
2619 | | { |
2620 | | READ_FLAG( uiCode, "vps_sublayer_cpb_params_present_flag" ); pcVPS->setVPSSublayerCpbParamsPresentFlag( uiCode ); |
2621 | | } |
2622 | | else |
2623 | | { |
2624 | | pcVPS->setVPSSublayerCpbParamsPresentFlag( 0 ); |
2625 | | } |
2626 | | |
2627 | | READ_UVLC( uiCode, "vps_num_ols_hrd_params_minus1" ); pcVPS->setNumOlsHrdParamsMinus1( uiCode ); |
2628 | | CHECK( uiCode >= pcVPS->getNumMultiLayeredOlss(), "The value of vps_num_ols_hrd_params_minus1 shall be in the range of 0 to NumMultiLayerOlss - 1, inclusive" ); |
2629 | | std::vector<bool> isHRDParamReferred( uiCode + 1, false ); |
2630 | | pcVPS->m_olsHrdParams.clear(); |
2631 | | pcVPS->m_olsHrdParams.resize( pcVPS->getNumOlsHrdParamsMinus1() + 1, std::vector<OlsHrdParams>( pcVPS->getMaxSubLayers() ) ); |
2632 | | for( int i = 0; i <= pcVPS->getNumOlsHrdParamsMinus1(); i++ ) |
2633 | | { |
2634 | | if( !pcVPS->getAllLayersSameNumSublayersFlag() ) |
2635 | | { |
2636 | | READ_CODE( 3, uiCode, "vps_hrd_max_tid[i]" ); pcVPS->setHrdMaxTid(i, uiCode ); |
2637 | | CHECK( uiCode > ( pcVPS->getMaxSubLayers() - 1 ), "The value of vps_hrd_max_tid[i] shall be in the range of 0 to vps_max_sublayers_minus1, inclusive." ); |
2638 | | } |
2639 | | else |
2640 | | { |
2641 | | pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 ); |
2642 | | } |
2643 | | uint32_t firstSublayer = pcVPS->getVPSSublayerCpbParamsPresentFlag() ? 0 : pcVPS->getHrdMaxTid( i ); |
2644 | | parseOlsHrdParameters( pcVPS->getGeneralHrdParameters(), pcVPS->getOlsHrdParameters( i ), firstSublayer, pcVPS->getHrdMaxTid( i ) ); |
2645 | | } |
2646 | | for( int i = pcVPS->getNumOlsHrdParamsMinus1() + 1; i < pcVPS->getTotalNumOLSs(); i++ ) |
2647 | | { |
2648 | | pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 ); |
2649 | | } |
2650 | | for( int i = 0; i < pcVPS->m_numMultiLayeredOlss; i++ ) |
2651 | | { |
2652 | | if( ( ( pcVPS->getNumOlsHrdParamsMinus1() + 1 ) != pcVPS->m_numMultiLayeredOlss ) && ( pcVPS->getNumOlsHrdParamsMinus1() > 0 ) ) |
2653 | | { |
2654 | | READ_UVLC( uiCode, "vps_ols_hrd_idx[i]" ); pcVPS->setOlsHrdIdx( i, uiCode ); |
2655 | | CHECK( uiCode > pcVPS->getNumOlsHrdParamsMinus1(), "The value of ols_hrd_idx[[i] shall be in the range of 0 to num_ols_hrd_params_minus1, inclusive." ); |
2656 | | } |
2657 | | else if( pcVPS->getNumOlsHrdParamsMinus1() == 0 ) |
2658 | | { |
2659 | | pcVPS->setOlsHrdIdx( i, 0 ); |
2660 | | } |
2661 | | else |
2662 | | { |
2663 | | pcVPS->setOlsHrdIdx( i, i ); |
2664 | | } |
2665 | | isHRDParamReferred[pcVPS->getOlsHrdIdx( i )] = true; |
2666 | | } |
2667 | | for( int i = 0; i <= pcVPS->getNumOlsHrdParamsMinus1(); i++ ) |
2668 | | { |
2669 | | CHECK( !isHRDParamReferred[i], "Each ols_hrd_parameters( ) syntax structure in the VPS shall be referred to by at least one value of vps_ols_hrd_idx[i] for i in the range of 1 to NumMultiLayerOlss - 1, inclusive"); |
2670 | | } |
2671 | | } |
2672 | | else |
2673 | | { |
2674 | | for( int i = 0; i < pcVPS->getTotalNumOLSs(); i++ ) |
2675 | | { |
2676 | | pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 ); |
2677 | | } |
2678 | | } |
2679 | | |
2680 | | |
2681 | | READ_FLAG( uiCode, "vps_extension_flag" ); |
2682 | | if( uiCode ) |
2683 | | { |
2684 | | while( xMoreRbspData() ) |
2685 | | { |
2686 | | READ_FLAG( uiCode, "vps_extension_data_flag" ); |
2687 | | } |
2688 | | } |
2689 | | pcVPS->checkVPS(); |
2690 | | xReadRbspTrailingBits(); |
2691 | | } |
2692 | | #endif |
2693 | | |
2694 | | void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, const ParameterSetManager *parameterSetManager, bool readRbspTrailingBits ) |
2695 | 6 | { |
2696 | | #if ENABLE_TRACING |
2697 | | xTracePictureHeader(); |
2698 | | #endif |
2699 | | |
2700 | 6 | X_READ_FLAG( ph_gdr_or_irap_pic_flag ); |
2701 | 6 | picHeader->setGdrOrIrapPicFlag( ph_gdr_or_irap_pic_flag ); |
2702 | | |
2703 | 6 | X_READ_FLAG( ph_non_ref_pic_flag ); |
2704 | 6 | picHeader->setNonReferencePictureFlag( ph_non_ref_pic_flag ); |
2705 | | |
2706 | 6 | if( picHeader->getGdrOrIrapPicFlag() ) |
2707 | 2 | { |
2708 | 2 | X_READ_FLAG( ph_gdr_pic_flag ); |
2709 | 2 | picHeader->setGdrPicFlag( ph_gdr_pic_flag ); |
2710 | 2 | } |
2711 | | |
2712 | 6 | X_READ_FLAG( ph_inter_slice_allowed_flag ); |
2713 | 6 | picHeader->setPicInterSliceAllowedFlag( ph_inter_slice_allowed_flag ); |
2714 | | |
2715 | 6 | if( ph_inter_slice_allowed_flag ) |
2716 | 2 | { |
2717 | 2 | X_READ_FLAG( ph_intra_slice_allowed_flag ); |
2718 | 2 | picHeader->setPicIntraSliceAllowedFlag( ph_intra_slice_allowed_flag ); |
2719 | 2 | } |
2720 | 6 | CHECK( picHeader->getPicInterSliceAllowedFlag() == 0 && picHeader->getPicIntraSliceAllowedFlag() == 0, |
2721 | 6 | "Invalid picture without intra or inter slice" ); |
2722 | | |
2723 | | // parameter sets |
2724 | 6 | X_READ_UVLC( ph_pic_parameter_set_id, 0, 63 ); |
2725 | 6 | picHeader->setPPSId( ph_pic_parameter_set_id ); |
2726 | | |
2727 | 6 | const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() ); |
2728 | 6 | CHECK( !pps, "Invalid PPS" ); |
2729 | | |
2730 | 6 | picHeader->setSPSId( pps->getSPSId() ); |
2731 | 6 | const SPS* sps = parameterSetManager->getSPS( picHeader->getSPSId() ); |
2732 | 6 | CHECK( !sps, "Invalid SPS" ); |
2733 | | |
2734 | 6 | const unsigned CtbSizeY = sps->getCTUSize(); |
2735 | 6 | const unsigned CtbLog2SizeY = getLog2( CtbSizeY ); |
2736 | 6 | const unsigned MinCbLog2SizeY = sps->getLog2MinCodingBlockSize(); |
2737 | 6 | const unsigned MaxPicOrderCntLsb = 1 << sps->getBitsForPOC(); |
2738 | | |
2739 | 6 | X_READ_CODE_NO_RANGE( ph_pic_order_cnt_lsb, sps->getBitsForPOC() ); |
2740 | 6 | picHeader->setPocLsb( ph_pic_order_cnt_lsb ); |
2741 | | |
2742 | 6 | if( picHeader->getGdrPicFlag() ) |
2743 | 0 | { |
2744 | 0 | X_READ_UVLC( ph_recovery_poc_cnt, 0, MaxPicOrderCntLsb ); |
2745 | 0 | picHeader->setRecoveryPocCnt( ph_recovery_poc_cnt ); |
2746 | 0 | } |
2747 | 6 | else |
2748 | 6 | { |
2749 | 6 | picHeader->setRecoveryPocCnt( -1 ); |
2750 | 6 | } |
2751 | | |
2752 | 6 | const std::vector<bool>& phExtraBitsPresent = sps->getExtraPHBitPresentFlags(); |
2753 | 6 | for( int i = 0; i < sps->getNumExtraPHBitsBytes() * 8; i++ ) |
2754 | 0 | { |
2755 | | // extra bits are ignored (when present) |
2756 | 0 | if( phExtraBitsPresent[i] ) |
2757 | 0 | { |
2758 | 0 | X_READ_FLAG_idx( ph_extra_bit, "[i]" ); |
2759 | 0 | (void) ph_extra_bit; |
2760 | 0 | } |
2761 | 0 | } |
2762 | | |
2763 | 6 | if( sps->getPocMsbFlag() ) |
2764 | 0 | { |
2765 | 0 | X_READ_FLAG( ph_poc_msb_cycle_present_flag ); |
2766 | 0 | picHeader->setPocMsbPresentFlag( ph_poc_msb_cycle_present_flag ); |
2767 | |
|
2768 | 0 | if( ph_poc_msb_cycle_present_flag ) |
2769 | 0 | { |
2770 | 0 | X_READ_CODE_NO_RANGE( ph_poc_msb_cycle_val, sps->getPocMsbLen() ); |
2771 | 0 | picHeader->setPocMsbVal( ph_poc_msb_cycle_val ); |
2772 | 0 | } |
2773 | 0 | } |
2774 | | |
2775 | | // alf enable flags and aps IDs |
2776 | 6 | if( sps->getUseALF() && pps->getAlfInfoInPhFlag() ) |
2777 | 0 | { |
2778 | 0 | X_READ_FLAG( ph_alf_enabled_flag ); |
2779 | 0 | picHeader->setAlfEnabledFlag( COMPONENT_Y, ph_alf_enabled_flag ); |
2780 | |
|
2781 | 0 | if( ph_alf_enabled_flag ) |
2782 | 0 | { |
2783 | 0 | X_READ_CODE( ph_num_alf_aps_ids_luma, 3, 0, MAX_NUM_ALF_APS_IDS ); |
2784 | 0 | picHeader->setNumAlfAps( ph_num_alf_aps_ids_luma ); |
2785 | | |
2786 | | // auto* alfAPSs = parameterSetManager->getAlfAPSs(); |
2787 | |
|
2788 | 0 | AlfApsIdVec apsId( ph_num_alf_aps_ids_luma, -1 ); |
2789 | 0 | for( int i = 0; i < ph_num_alf_aps_ids_luma; i++ ) |
2790 | 0 | { |
2791 | 0 | X_READ_CODE_NO_RANGE_idx( ph_alf_aps_id_luma, "[i]", 3 ); |
2792 | 0 | apsId[i] = ph_alf_aps_id_luma; |
2793 | | |
2794 | | // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_luma ); |
2795 | | // CHECK( !alfAPS, "ALF APS with ph_alf_aps_id_luma == " << ph_alf_aps_id_luma << " not available."); |
2796 | | // CHECK( alfAPS->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_LUMA] != 1, |
2797 | | // "The value of alf_luma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS " |
2798 | | // " and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 1." ); |
2799 | | // /*CHECK( parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_luma )->getTemporalId() > todo: don't know curr temp ID |
2800 | | // "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id" |
2801 | | // " equal to ph_alf_aps_id_luma[ i ] shall be less than or equal to the TemporalId of the current picture." );*/ |
2802 | | // CHECK( sps->getChromaFormatIdc() == 0 && alfAPS->chromaPresentFlag != 0, |
2803 | | // "When sps_chroma_format_idc is equal to 0, the value of aps_chroma_present_flag of the APS NAL unit having aps_params_type" |
2804 | | // " equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 0." ); |
2805 | | // CHECK( sps->getUseCCALF() == 0 |
2806 | | // && ( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 0 || alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 0 ), |
2807 | | // "When sps_ccalf_enabled_flag is equal to 0, the values of alf_cc_cb_filter_signal_flag and alf_cc_cr_filter_signal_flag of the APS NAL unit " |
2808 | | // " having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 0." ); |
2809 | 0 | } |
2810 | 0 | picHeader->setAlfAPSIds( apsId ); |
2811 | |
|
2812 | 0 | if( sps->getChromaFormatIdc() != CHROMA_400 ) |
2813 | 0 | { |
2814 | 0 | X_READ_FLAG( ph_alf_cb_enabled_flag ); |
2815 | 0 | picHeader->setAlfEnabledFlag( COMPONENT_Cb, ph_alf_cb_enabled_flag ); |
2816 | |
|
2817 | 0 | X_READ_FLAG( ph_alf_cr_enabled_flag ); |
2818 | 0 | picHeader->setAlfEnabledFlag( COMPONENT_Cr, ph_alf_cr_enabled_flag ); |
2819 | 0 | } |
2820 | |
|
2821 | 0 | if( picHeader->getAlfEnabledFlag( COMPONENT_Cb ) || picHeader->getAlfEnabledFlag( COMPONENT_Cr ) ) |
2822 | 0 | { |
2823 | 0 | X_READ_CODE_NO_RANGE( ph_alf_aps_id_chroma, 3 ); |
2824 | 0 | picHeader->setAlfApsIdChroma( ph_alf_aps_id_chroma ); |
2825 | | |
2826 | | // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_chroma ); |
2827 | | // CHECK( !alfAPS, "ALF APS with ph_alf_aps_id_chroma == " << ph_alf_aps_id_chroma << " not available."); |
2828 | | |
2829 | | // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[CHANNEL_TYPE_CHROMA] != 1, |
2830 | | // "The value of alf_chroma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and" |
2831 | | // " aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be equal to 1." ); |
2832 | | // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and |
2833 | | // // aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be less than or equal to the TemporalId of the |
2834 | | // // current picture. |
2835 | | |
2836 | | // CHECK( sps->getUseCCALF() == 0 |
2837 | | // && ( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 0 || alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 0 ), |
2838 | | // "When sps_ccalf_enabled_flag is equal to 0, the values of alf_cc_cb_filter_signal_flag and alf_cc_cr_filter_signal_flag of the APS NAL unit " |
2839 | | // " having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be equal to 0." ); |
2840 | 0 | } |
2841 | |
|
2842 | 0 | if( sps->getUseCCALF() ) |
2843 | 0 | { |
2844 | 0 | X_READ_FLAG( ph_alf_cc_cb_enabled_flag ); |
2845 | 0 | picHeader->setCcAlfEnabledFlag( COMPONENT_Cb, ph_alf_cc_cb_enabled_flag ); |
2846 | |
|
2847 | 0 | if( ph_alf_cc_cb_enabled_flag ) |
2848 | 0 | { |
2849 | 0 | X_READ_CODE_NO_RANGE( ph_alf_cc_cb_aps_id, 3 ); |
2850 | 0 | picHeader->setCcAlfCbApsId( ph_alf_cc_cb_aps_id ); |
2851 | | |
2852 | | // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_cc_cb_aps_id ); |
2853 | | // CHECK( !alfAPS, "ALF APS with ph_alf_cc_cb_aps_id == " << ph_alf_cc_cb_aps_id << " not available."); |
2854 | | // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 1, |
2855 | | // "The value of alf_cc_cb_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and" |
2856 | | // " aps_adaptation_parameter_set_id equal to ph_alf_cc_cb_aps_id shall be equal to 1." ); |
2857 | | // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and |
2858 | | // // aps_adaptation_parameter_set_id equal to ph_alf_cc_cb_aps_id shall be less than or equal to the TemporalId of the |
2859 | | // // current picture. |
2860 | 0 | } |
2861 | |
|
2862 | 0 | X_READ_FLAG( ph_alf_cc_cr_enabled_flag ); |
2863 | 0 | picHeader->setCcAlfEnabledFlag( COMPONENT_Cr, ph_alf_cc_cr_enabled_flag ); |
2864 | |
|
2865 | 0 | if( ph_alf_cc_cr_enabled_flag ) |
2866 | 0 | { |
2867 | 0 | X_READ_CODE_NO_RANGE( ph_alf_cc_cr_aps_id, 3 ); |
2868 | 0 | picHeader->setCcAlfCrApsId( ph_alf_cc_cr_aps_id ); |
2869 | | |
2870 | | // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_cc_cr_aps_id ); |
2871 | | // CHECK( !alfAPS, "ALF APS with ph_alf_cc_cr_aps_id == " << ph_alf_cc_cr_aps_id << " not available." ); |
2872 | | // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 1, |
2873 | | // "The value of alf_cc_cr_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and" |
2874 | | // " aps_adaptation_parameter_set_id equal to ph_alf_cc_cr_aps_id shall be equal to 1." ); |
2875 | | // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and |
2876 | | // // aps_adaptation_parameter_set_id equal to ph_alf_cc_cr_aps_id shall be less than or equal to the TemporalId of the |
2877 | | // // current picture. |
2878 | 0 | } |
2879 | 0 | } |
2880 | 0 | } // if( ph_alf_enabled_flag ) |
2881 | 0 | } // if( sps->getUseALF() && pps->getAlfInfoInPhFlag() ) |
2882 | | |
2883 | | // luma mapping / chroma scaling controls |
2884 | 6 | if( sps->getUseReshaper() ) |
2885 | 0 | { |
2886 | 0 | X_READ_FLAG( ph_lmcs_enabled_flag ); |
2887 | 0 | picHeader->setLmcsEnabledFlag( ph_lmcs_enabled_flag ); |
2888 | |
|
2889 | 0 | if( ph_lmcs_enabled_flag ) |
2890 | 0 | { |
2891 | 0 | X_READ_CODE_NO_RANGE( ph_lmcs_aps_id, 2 ); |
2892 | 0 | picHeader->setLmcsAPSId( ph_lmcs_aps_id ); |
2893 | |
|
2894 | 0 | if( sps->getChromaFormatIdc() != CHROMA_400 ) |
2895 | 0 | { |
2896 | 0 | X_READ_FLAG( ph_chroma_residual_scale_flag ); |
2897 | 0 | picHeader->setLmcsChromaResidualScaleFlag( ph_chroma_residual_scale_flag ); |
2898 | 0 | } |
2899 | 0 | } |
2900 | 0 | } |
2901 | | |
2902 | | // quantization scaling lists |
2903 | 6 | if( sps->getScalingListFlag() ) |
2904 | 0 | { |
2905 | 0 | X_READ_FLAG( ph_explicit_scaling_list_enabled_flag ); |
2906 | 0 | picHeader->setExplicitScalingListEnabledFlag( ph_explicit_scaling_list_enabled_flag ); |
2907 | |
|
2908 | 0 | if( ph_explicit_scaling_list_enabled_flag ) |
2909 | 0 | { |
2910 | 0 | X_READ_CODE_NO_RANGE( ph_scaling_list_aps_id, 3 ); |
2911 | 0 | picHeader->setScalingListAPSId( ph_scaling_list_aps_id ); |
2912 | 0 | } |
2913 | 0 | } |
2914 | | |
2915 | | // virtual boundaries |
2916 | 6 | if( sps->getVirtualBoundariesEnabledFlag() && !sps->getVirtualBoundariesPresentFlag() ) |
2917 | 0 | { |
2918 | 0 | X_READ_FLAG( ph_virtual_boundaries_present_flag ); |
2919 | 0 | picHeader->setVirtualBoundariesPresentFlag( ph_virtual_boundaries_present_flag ); |
2920 | |
|
2921 | 0 | if( ph_virtual_boundaries_present_flag ) |
2922 | 0 | { |
2923 | 0 | X_READ_UVLC( ph_num_ver_virtual_boundaries, 0, pps->getPicWidthInLumaSamples() <= 8 ? 0 : 3 ); |
2924 | 0 | picHeader->setNumVerVirtualBoundaries( ph_num_ver_virtual_boundaries ); |
2925 | |
|
2926 | 0 | for( unsigned i = 0, prevBoundPos = 0; i < ph_num_ver_virtual_boundaries; i++ ) |
2927 | 0 | { |
2928 | 0 | X_READ_UVLC_idx( ph_virtual_boundary_pos_x_minus1, "[ i ]", 0, ( pps->getPicWidthInLumaSamples() + 7 ) / 8 - 2 ); |
2929 | |
|
2930 | 0 | const unsigned virtBoundPosX = ( ph_virtual_boundary_pos_x_minus1 + 1 ) << 3; |
2931 | 0 | CHECK( i > 0 && virtBoundPosX < prevBoundPos + CtbSizeY, |
2932 | 0 | "The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples." ); |
2933 | 0 | picHeader->setVirtualBoundariesPosX( virtBoundPosX, i ); |
2934 | |
|
2935 | 0 | prevBoundPos = virtBoundPosX; |
2936 | 0 | } |
2937 | | |
2938 | 0 | X_READ_UVLC( ph_num_hor_virtual_boundaries, 0, pps->getPicHeightInLumaSamples() <= 8 ? 0 : 3 ); |
2939 | 0 | picHeader->setNumHorVirtualBoundaries( ph_num_hor_virtual_boundaries ); |
2940 | |
|
2941 | 0 | for( unsigned i = 0, prevBoundPos = 0; i < ph_num_hor_virtual_boundaries; i++ ) |
2942 | 0 | { |
2943 | 0 | X_READ_UVLC_idx( ph_virtual_boundary_pos_y_minus1, "[ i ]", 0, ( pps->getPicHeightInLumaSamples() + 7 ) / 8 - 2 ); |
2944 | |
|
2945 | 0 | const unsigned virtBoundPosY = ( ph_virtual_boundary_pos_y_minus1 + 1 ) << 3; |
2946 | 0 | CHECK( i > 0 && virtBoundPosY < prevBoundPos + CtbSizeY, |
2947 | 0 | "The distance between any two horizontal virtual boundaries shall be greater than or equal to CtbSizeY luma samples." ); |
2948 | 0 | picHeader->setVirtualBoundariesPosY( virtBoundPosY, i ); |
2949 | |
|
2950 | 0 | prevBoundPos = virtBoundPosY; |
2951 | 0 | } |
2952 | 0 | CHECK( ph_num_ver_virtual_boundaries + ph_num_hor_virtual_boundaries <= 0, |
2953 | 0 | "When sps_virtual_boundaries_enabled_flag is equal to 1 and ph_virtual_boundaries_present_flag is equal to 1, the sum" |
2954 | 0 | " of ph_num_ver_virtual_boundaries and ph_num_hor_virtual_boundaries shall be greater than 0." ); |
2955 | 0 | } |
2956 | 0 | } |
2957 | 6 | else if( sps->getVirtualBoundariesPresentFlag() ) |
2958 | 0 | { |
2959 | 0 | picHeader->setVirtualBoundariesPresentFlag( true ); |
2960 | 0 | picHeader->setNumVerVirtualBoundaries( sps->getNumVerVirtualBoundaries() ); |
2961 | 0 | picHeader->setNumHorVirtualBoundaries( sps->getNumHorVirtualBoundaries() ); |
2962 | |
|
2963 | 0 | for( unsigned i = 0, prevBoundPosX = 0, prevBoundPosY = 0; i < 3; i++ ) |
2964 | 0 | { |
2965 | 0 | picHeader->setVirtualBoundariesPosX( sps->getVirtualBoundariesPosX( i ), i ); |
2966 | 0 | picHeader->setVirtualBoundariesPosY( sps->getVirtualBoundariesPosY( i ), i ); |
2967 | |
|
2968 | 0 | CHECK( i > 0 && i < picHeader->getNumVerVirtualBoundaries() && picHeader->getVirtualBoundariesPosX( i ) < prevBoundPosX + CtbSizeY, |
2969 | 0 | "The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples." ); |
2970 | 0 | CHECK( i > 0 && i < picHeader->getNumHorVirtualBoundaries() && picHeader->getVirtualBoundariesPosY( i ) < prevBoundPosY + CtbSizeY, |
2971 | 0 | "The distance between any two horizontal virtual boundaries shall be greater than or equal to CtbSizeY luma samples." ); |
2972 | |
|
2973 | 0 | prevBoundPosX = picHeader->getVirtualBoundariesPosX( i ); |
2974 | 0 | prevBoundPosY = picHeader->getVirtualBoundariesPosY( i ); |
2975 | 0 | } |
2976 | 0 | } |
2977 | | |
2978 | | // picture output flag |
2979 | 6 | if( pps->getOutputFlagPresentFlag() && !picHeader->getNonReferencePictureFlag() ) |
2980 | 0 | { |
2981 | 0 | X_READ_FLAG( ph_pic_output_flag ); |
2982 | 0 | picHeader->setPicOutputFlag( ph_pic_output_flag); |
2983 | 0 | } |
2984 | | |
2985 | | // reference picture lists |
2986 | 6 | if( pps->getRplInfoInPhFlag() ) |
2987 | 0 | { |
2988 | 0 | parsePicOrSliceHeaderRPL( picHeader, sps, pps ); |
2989 | 0 | } |
2990 | | |
2991 | | // partitioning constraint overrides |
2992 | 6 | if( sps->getSplitConsOverrideEnabledFlag() ) |
2993 | 0 | { |
2994 | 0 | X_READ_FLAG( ph_partition_constraints_override_flag ); |
2995 | 0 | picHeader->setSplitConsOverrideFlag( ph_partition_constraints_override_flag ); |
2996 | 0 | } |
2997 | | |
2998 | | // inherit constraint values from SPS |
2999 | 6 | PartitionConstraints minQT = sps->getMinQTSizes(); |
3000 | 6 | PartitionConstraints maxBTD = sps->getMaxMTTHierarchyDepths(); |
3001 | 6 | PartitionConstraints maxBTSize = sps->getMaxBTSizes(); |
3002 | 6 | PartitionConstraints maxTTSize = sps->getMaxTTSizes(); |
3003 | | |
3004 | 6 | if( picHeader->getPicIntraSliceAllowedFlag() ) |
3005 | 0 | { |
3006 | 0 | unsigned MinQtLog2SizeIntraY = getLog2( minQT[0] ); |
3007 | 0 | if( picHeader->getSplitConsOverrideFlag() ) |
3008 | 0 | { |
3009 | 0 | X_READ_UVLC( ph_log2_diff_min_qt_min_cb_intra_slice_luma, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY ); |
3010 | 0 | MinQtLog2SizeIntraY = ph_log2_diff_min_qt_min_cb_intra_slice_luma + MinCbLog2SizeY; |
3011 | 0 | minQT[0] = 1 << MinQtLog2SizeIntraY; |
3012 | |
|
3013 | 0 | X_READ_UVLC( ph_max_mtt_hierarchy_depth_intra_slice_luma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
3014 | 0 | maxBTD[0] = ph_max_mtt_hierarchy_depth_intra_slice_luma; |
3015 | | // TODO: When not present, the value of ph_max_mtt_hierarchy_depth_intra_slice_luma is inferred to be equal to sps_max_mtt_hierarchy_depth_intra_slice_luma. |
3016 | |
|
3017 | 0 | maxTTSize[0] = maxBTSize[0] = minQT[0]; |
3018 | 0 | if( maxBTD[0] != 0 ) |
3019 | 0 | { |
3020 | 0 | X_READ_UVLC( ph_log2_diff_max_bt_min_qt_intra_slice_luma, |
3021 | 0 | 0, ( sps->getUseDualITree() ? std::min( 6u, CtbLog2SizeY ) : CtbLog2SizeY ) - MinQtLog2SizeIntraY ); |
3022 | 0 | maxBTSize[0] <<= ph_log2_diff_max_bt_min_qt_intra_slice_luma; |
3023 | | // TODO: When not present, the value of ph_log2_diff_max_bt_min_qt_intra_slice_luma is inferred to be equal to |
3024 | | // sps_log2_diff_max_bt_min_qt_intra_slice_luma. |
3025 | |
|
3026 | 0 | X_READ_UVLC( ph_log2_diff_max_tt_min_qt_intra_slice_luma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraY ); |
3027 | 0 | maxTTSize[0] <<= ph_log2_diff_max_tt_min_qt_intra_slice_luma; |
3028 | | // TODO: When not present, the value of ph_log2_diff_max_tt_min_qt_intra_slice_luma is inferred to be equal to |
3029 | | // sps_log2_diff_max_tt_min_qt_intra_slice_luma. |
3030 | 0 | } |
3031 | 0 | if( sps->getUseDualITree() ) |
3032 | 0 | { |
3033 | 0 | X_READ_UVLC( ph_log2_diff_min_qt_min_cb_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY ); |
3034 | 0 | unsigned MinQtLog2SizeIntraC = ph_log2_diff_min_qt_min_cb_intra_slice_chroma + MinCbLog2SizeY; |
3035 | 0 | minQT[2] = 1 << MinQtLog2SizeIntraC; |
3036 | | // TODO: When not present, the value of ph_log2_diff_min_qt_min_cb_intra_slice_chroma is inferred to be equal to |
3037 | | // sps_log2_diff_min_qt_min_cb_intra_slice_chroma. |
3038 | |
|
3039 | 0 | X_READ_UVLC( ph_max_mtt_hierarchy_depth_intra_slice_chroma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
3040 | 0 | maxBTD[2] = ph_max_mtt_hierarchy_depth_intra_slice_chroma; |
3041 | | // TODO: When not present, the value of ph_max_mtt_hierarchy_depth_intra_slice_chroma is inferred to be equal to |
3042 | | // sps_max_mtt_hierarchy_depth_intra_slice_chroma. |
3043 | |
|
3044 | 0 | maxTTSize[2] = maxBTSize[2] = minQT[2]; |
3045 | 0 | if( ph_max_mtt_hierarchy_depth_intra_slice_chroma ) |
3046 | 0 | { |
3047 | 0 | X_READ_UVLC( ph_log2_diff_max_bt_min_qt_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraC ); |
3048 | 0 | maxBTSize[2] <<= ph_log2_diff_max_bt_min_qt_intra_slice_chroma; |
3049 | | // TODO: When not present, the value of ph_log2_diff_max_bt_min_qt_intra_slice_chroma is inferred to be equal to |
3050 | | // sps_log2_diff_max_bt_min_qt_intra_slice_chroma. |
3051 | |
|
3052 | 0 | X_READ_UVLC( ph_log2_diff_max_tt_min_qt_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraC ); |
3053 | 0 | maxTTSize[2] <<= ph_log2_diff_max_tt_min_qt_intra_slice_chroma; |
3054 | | // TODO: When not present, the value of ph_log2_diff_max_tt_min_qt_intra_slice_chroma is inferred to be equal to |
3055 | | // sps_log2_diff_max_tt_min_qt_intra_slice_chroma. |
3056 | 0 | } |
3057 | 0 | } // if( sps->getUseDualITree() ) |
3058 | 0 | } // if( picHeader->getSplitConsOverrideFlag() ) |
3059 | | |
3060 | | // delta quantization and chrom and chroma offset |
3061 | 0 | if( pps->getUseDQP() ) |
3062 | 0 | { |
3063 | 0 | X_READ_UVLC( ph_cu_qp_delta_subdiv_intra_slice, |
3064 | 0 | 0, 2 * ( CtbLog2SizeY - MinQtLog2SizeIntraY + maxBTD[0] /*ph_max_mtt_hierarchy_depth_intra_slice_luma*/ ) ); |
3065 | 0 | picHeader->setCuQpDeltaSubdivIntra( ph_cu_qp_delta_subdiv_intra_slice ); |
3066 | 0 | } |
3067 | |
|
3068 | 0 | if( pps->getCuChromaQpOffsetEnabledFlag() ) |
3069 | 0 | { |
3070 | 0 | X_READ_UVLC( ph_cu_chroma_qp_offset_subdiv_intra_slice, |
3071 | 0 | 0, 2 * ( CtbLog2SizeY - MinQtLog2SizeIntraY + maxBTD[0] /*ph_max_mtt_hierarchy_depth_intra_slice_luma*/ ) ); |
3072 | 0 | picHeader->setCuChromaQpOffsetSubdivIntra( ph_cu_chroma_qp_offset_subdiv_intra_slice ); |
3073 | 0 | } |
3074 | 0 | } // if( picHeader->getPicIntraSliceAllowedFlag() ) |
3075 | | |
3076 | 6 | if( ph_inter_slice_allowed_flag ) |
3077 | 0 | { |
3078 | 0 | unsigned MinQtLog2SizeInterY = MinCbLog2SizeY; |
3079 | 0 | if( picHeader->getSplitConsOverrideFlag() ) |
3080 | 0 | { |
3081 | 0 | X_READ_UVLC( ph_log2_diff_min_qt_min_cb_inter_slice, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY ); |
3082 | 0 | MinQtLog2SizeInterY += ph_log2_diff_min_qt_min_cb_inter_slice; |
3083 | 0 | minQT[1] = 1 << MinQtLog2SizeInterY; |
3084 | |
|
3085 | 0 | X_READ_UVLC( ph_max_mtt_hierarchy_depth_inter_slice, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) ); |
3086 | 0 | maxBTD[1] = ph_max_mtt_hierarchy_depth_inter_slice; |
3087 | |
|
3088 | 0 | maxTTSize[1] = maxBTSize[1] = minQT[1]; |
3089 | 0 | if( maxBTD[1] != 0 ) |
3090 | 0 | { |
3091 | 0 | X_READ_UVLC( ph_log2_diff_max_bt_min_qt_inter_slice, 0, CtbLog2SizeY - MinQtLog2SizeInterY ); |
3092 | 0 | maxBTSize[1] <<= ph_log2_diff_max_bt_min_qt_inter_slice; |
3093 | |
|
3094 | 0 | X_READ_UVLC( ph_log2_diff_max_tt_min_qt_inter_slice, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeInterY ); |
3095 | 0 | maxTTSize[1] <<= ph_log2_diff_max_tt_min_qt_inter_slice; |
3096 | 0 | } |
3097 | 0 | } |
3098 | | |
3099 | | // delta quantization and chrom and chroma offset |
3100 | 0 | if( pps->getUseDQP() ) |
3101 | 0 | { |
3102 | 0 | X_READ_UVLC( ph_cu_qp_delta_subdiv_inter_slice, 0, 2 * ( CtbLog2SizeY - MinQtLog2SizeInterY + maxBTD[1] /*ph_max_mtt_hierarchy_depth_inter_slice*/ ) ); |
3103 | 0 | picHeader->setCuQpDeltaSubdivInter( ph_cu_qp_delta_subdiv_inter_slice ); |
3104 | 0 | } |
3105 | |
|
3106 | 0 | if( pps->getCuChromaQpOffsetEnabledFlag() ) |
3107 | 0 | { |
3108 | 0 | X_READ_UVLC( ph_cu_chroma_qp_offset_subdiv_inter_slice, |
3109 | 0 | 0, 2 * ( CtbLog2SizeY - MinQtLog2SizeInterY + maxBTD[1] /*ph_max_mtt_hierarchy_depth_inter_slice*/ ) ); |
3110 | 0 | picHeader->setCuChromaQpOffsetSubdivInter( ph_cu_chroma_qp_offset_subdiv_inter_slice ); |
3111 | 0 | } |
3112 | | |
3113 | | // temporal motion vector prediction |
3114 | 0 | if( sps->getSPSTemporalMVPEnabledFlag() ) |
3115 | 0 | { |
3116 | 0 | X_READ_FLAG( ph_temporal_mvp_enabled_flag ); |
3117 | 0 | picHeader->setEnableTMVPFlag( ph_temporal_mvp_enabled_flag ); |
3118 | |
|
3119 | 0 | if( ph_temporal_mvp_enabled_flag && pps->getRplInfoInPhFlag() ) |
3120 | 0 | { |
3121 | 0 | if( picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 0 ) |
3122 | 0 | { |
3123 | 0 | X_READ_FLAG( ph_collocated_from_l0_flag ); |
3124 | 0 | picHeader->setPicColFromL0Flag( ph_collocated_from_l0_flag ); |
3125 | 0 | } |
3126 | 0 | else // ( num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] == 0 ) |
3127 | 0 | { |
3128 | | // When ph_temporal_mvp_enabled_flag and pps_rpl_info_in_ph_flag are both equal to 1 and num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] is equal to 0, the value |
3129 | | // of ph_collocated_from_l0_flag is inferred to be equal to 1. |
3130 | 0 | picHeader->setPicColFromL0Flag( 1 ); |
3131 | 0 | } |
3132 | |
|
3133 | 0 | if( ( picHeader->getPicColFromL0Flag() && picHeader->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() > 1 ) |
3134 | 0 | || ( !picHeader->getPicColFromL0Flag() && picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 1 ) ) |
3135 | 0 | { |
3136 | 0 | X_READ_UVLC_NO_RANGE( ph_collocated_ref_idx ); |
3137 | 0 | if( picHeader->getPicColFromL0Flag() ) |
3138 | 0 | { |
3139 | 0 | CHECK( ph_collocated_ref_idx > picHeader->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() - 1, |
3140 | 0 | "When ph_collocated_from_l0_flag is equal to 1, ph_collocated_ref_idx refers to an entry in RPL 0, and the value of ph_collocated_ref_idx" |
3141 | 0 | " shall be in the range of 0 to num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] − 1, inclusive." ) |
3142 | 0 | } |
3143 | 0 | else |
3144 | 0 | { |
3145 | 0 | CHECK( ph_collocated_ref_idx > picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() - 1, |
3146 | 0 | "When ph_collocated_from_l0_flag is equal to 0, ph_collocated_ref_idx refers to an entry in RPL 1, and the value of ph_collocated_ref_idx" |
3147 | 0 | " shall be in the range of 0 to num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] − 1, inclusive." ); |
3148 | 0 | } |
3149 | 0 | picHeader->setColRefIdx( ph_collocated_ref_idx ); |
3150 | 0 | } |
3151 | 0 | } |
3152 | 0 | } |
3153 | | |
3154 | | // merge candidate list size |
3155 | | // subblock merge candidate list size |
3156 | 0 | if( sps->getUseAffine() ) |
3157 | 0 | { |
3158 | 0 | picHeader->setMaxNumAffineMergeCand( sps->getMaxNumAffineMergeCand() ); |
3159 | 0 | } |
3160 | 0 | else |
3161 | 0 | { |
3162 | 0 | picHeader->setMaxNumAffineMergeCand( sps->getSBTMVPEnabledFlag() && picHeader->getEnableTMVPFlag() ); |
3163 | 0 | } |
3164 | | |
3165 | | // full-pel MMVD flag |
3166 | 0 | if( sps->getFpelMmvdEnabledFlag() ) |
3167 | 0 | { |
3168 | 0 | X_READ_FLAG( ph_fpel_mmvd_enabled_flag ); |
3169 | 0 | picHeader->setDisFracMMVD( ph_fpel_mmvd_enabled_flag ); |
3170 | 0 | } |
3171 | |
|
3172 | 0 | bool presenceFlag = 0; |
3173 | 0 | if( !pps->getRplInfoInPhFlag() ) // This condition is intentionally not merged into the next, to avoid possible interpretation of RplsIdx[ i ] not having |
3174 | 0 | { // a specified value. |
3175 | 0 | presenceFlag = 1; |
3176 | 0 | } |
3177 | 0 | else if( picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 0 ) |
3178 | 0 | { |
3179 | 0 | presenceFlag = 1; |
3180 | 0 | } |
3181 | | |
3182 | | // If sps_bdof_control_present_in_ph_flag is equal to 0, the value of ph_bdof_disabled_flag is inferred to be equal to 1 - sps_bdof_enabled_flag |
3183 | | // Otherwise (sps_bdof_control_present_in_ph_flag is equal to 1), the value of ph_bdof_disabled_flag is inferred to be equal to 1. |
3184 | 0 | picHeader->setDisBdofFlag( sps->getBdofControlPresentInPhFlag() == 0 ? 1 - sps->getUseBIO() : 1 ); |
3185 | | |
3186 | | // If sps_dmvr_control_present_in_ph_flag is equal to 0, the value of ph_dmvr_disabled_flag is inferred to be equal to 1 - sps_dmvr_enabled_flag. |
3187 | | // Otherwise (sps_dmvr_control_present_in_ph_flag is equal to 1), the value of ph_dmvr_disabled_flag is inferred to be equal to 1. |
3188 | 0 | picHeader->setDisDmvrFlag( sps->getDmvrControlPresentInPhFlag() == 0 ? 1 - sps->getUseDMVR() : 1 ); |
3189 | |
|
3190 | 0 | if( presenceFlag ) |
3191 | 0 | { |
3192 | | // mvd L1 zero flag |
3193 | 0 | X_READ_FLAG( ph_mvd_l1_zero_flag ); |
3194 | 0 | picHeader->setMvdL1ZeroFlag( ph_mvd_l1_zero_flag ); |
3195 | | |
3196 | | // picture level BDOF disable flags |
3197 | 0 | if( sps->getBdofControlPresentInPhFlag() ) |
3198 | 0 | { |
3199 | 0 | X_READ_FLAG( ph_bdof_disabled_flag ); |
3200 | 0 | picHeader->setDisBdofFlag( ph_bdof_disabled_flag ); |
3201 | 0 | } |
3202 | | |
3203 | | // picture level DMVR disable flags |
3204 | 0 | if( sps->getDmvrControlPresentInPhFlag() ) |
3205 | 0 | { |
3206 | 0 | X_READ_FLAG( ph_dmvr_disabled_flag ); |
3207 | 0 | picHeader->setDisDmvrFlag( ph_dmvr_disabled_flag ); |
3208 | 0 | } |
3209 | 0 | } |
3210 | | |
3211 | | // picture level PROF disable flags |
3212 | 0 | if( sps->getProfControlPresentInPhFlag() ) |
3213 | 0 | { |
3214 | 0 | X_READ_FLAG( ph_prof_disabled_flag ); |
3215 | 0 | picHeader->setDisProfFlag( ph_prof_disabled_flag ); |
3216 | 0 | } |
3217 | 0 | else |
3218 | 0 | { |
3219 | | // If sps_affine_prof_enabled_flag is equal to 1, the value of ph_prof_disabled_flag is inferred to be equal to 0. |
3220 | | // Otherwise (sps_affine_prof_enabled_flag is equal to 0), the value of ph_prof_disabled_flag is inferred to be equal to 1. |
3221 | |
|
3222 | 0 | picHeader->setDisProfFlag( !sps->getUsePROF() ); |
3223 | 0 | } |
3224 | |
|
3225 | 0 | if( ( pps->getUseWP() || pps->getWPBiPred() ) && pps->getWpInfoInPhFlag() ) |
3226 | 0 | { |
3227 | 0 | parsePredWeightTable( picHeader, sps, pps ); |
3228 | 0 | } |
3229 | 0 | } // if( ph_inter_slice_allowed_flag ) |
3230 | | |
3231 | 6 | picHeader->setMinQTSizes( minQT ); |
3232 | 6 | picHeader->setMaxMTTHierarchyDepths( maxBTD ); |
3233 | 6 | picHeader->setMaxBTSizes( maxBTSize ); |
3234 | 6 | picHeader->setMaxTTSizes( maxTTSize ); |
3235 | | |
3236 | | // ibc merge candidate list size |
3237 | 6 | if( pps->getQpDeltaInfoInPhFlag() ) |
3238 | 0 | { |
3239 | 0 | X_READ_SVLC_NO_RANGE( ph_qp_delta ); |
3240 | 0 | int SliceQpY = 26 + pps->getPicInitQPMinus26() + ph_qp_delta; |
3241 | 0 | CHECK( SliceQpY < -sps->getQpBDOffset() || SliceQpY > 63, "The value of SliceQpY shall be in the range of −QpBdOffset to +63, inclusive." ); |
3242 | 0 | picHeader->setQpDelta( ph_qp_delta ); |
3243 | 0 | } |
3244 | | |
3245 | | // joint Cb/Cr sign flag |
3246 | 6 | if( sps->getJointCbCrEnabledFlag() ) |
3247 | 0 | { |
3248 | 0 | X_READ_FLAG( ph_joint_cbcr_sign_flag ); |
3249 | 0 | picHeader->setJointCbCrSignFlag( ph_joint_cbcr_sign_flag ); |
3250 | 0 | } |
3251 | | |
3252 | | // sao enable flags |
3253 | 6 | if( sps->getUseSAO() && pps->getSaoInfoInPhFlag() ) |
3254 | 0 | { |
3255 | 0 | X_READ_FLAG( ph_sao_luma_enabled_flag ); |
3256 | 0 | picHeader->setSaoEnabledFlag( CHANNEL_TYPE_LUMA, ph_sao_luma_enabled_flag ); |
3257 | |
|
3258 | 0 | if( sps->getChromaFormatIdc() != CHROMA_400 ) |
3259 | 0 | { |
3260 | 0 | X_READ_FLAG( ph_sao_chroma_enabled_flag ); |
3261 | 0 | picHeader->setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, ph_sao_chroma_enabled_flag ); |
3262 | 0 | } |
3263 | 0 | } |
3264 | | |
3265 | | // deblocking filter controls |
3266 | | |
3267 | 6 | if( pps->getDbfInfoInPhFlag() ) |
3268 | 0 | { |
3269 | 0 | X_READ_FLAG( ph_deblocking_params_present_flag ); |
3270 | 0 | picHeader->setDeblockingFilterOverrideFlag( ph_deblocking_params_present_flag ); |
3271 | 0 | } |
3272 | | |
3273 | 6 | if( pps->getPPSDeblockingFilterDisabledFlag() == 1 && picHeader->getDeblockingFilterOverrideFlag() == 1 ) |
3274 | 0 | { |
3275 | | // If pps_deblocking_filter_disabled_flag and ph_deblocking_params_present_flag are both equal to 1, the value of ph_deblocking_filter_disabled_flag |
3276 | | // is inferred to be equal to 0. |
3277 | 0 | picHeader->setDeblockingFilterDisable( false ); |
3278 | 0 | } |
3279 | 6 | else // ( pps->getPPSDeblockingFilterDisabledFlag() == 0 || picHeader->getDeblockingFilterOverrideFlag() == 0 ) |
3280 | 6 | { |
3281 | | // Otherwise (pps_deblocking_filter_disabled_flag or ph_deblocking_params_present_flag is equal to 0), the value of ph_deblocking_filter_disabled_flag is |
3282 | | // inferred to be equal to pps_deblocking_filter_disabled_flag. |
3283 | 6 | picHeader->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() ); |
3284 | 6 | } |
3285 | | |
3286 | | // When not present, the values of ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2 are inferred to be equal to pps_luma_beta_offset_div2 and |
3287 | | // pps_luma_tc_offset_div2, respectively. |
3288 | 6 | picHeader->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() ); |
3289 | 6 | picHeader->setDeblockingFilterTcOffsetDiv2( pps->getDeblockingFilterTcOffsetDiv2() ); |
3290 | | |
3291 | 6 | if( picHeader->getDeblockingFilterOverrideFlag() /*ph_deblocking_params_present_flag*/ ) |
3292 | 0 | { |
3293 | 0 | if( !pps->getPPSDeblockingFilterDisabledFlag() ) |
3294 | 0 | { |
3295 | 0 | X_READ_FLAG( ph_deblocking_filter_disabled_flag ); |
3296 | 0 | picHeader->setDeblockingFilterDisable( ph_deblocking_filter_disabled_flag ); |
3297 | 0 | } |
3298 | |
|
3299 | 0 | if( !picHeader->getDeblockingFilterDisable() ) |
3300 | 0 | { |
3301 | 0 | X_READ_SVLC( ph_luma_beta_offset_div2, -12, 12 ); |
3302 | 0 | picHeader->setDeblockingFilterBetaOffsetDiv2( ph_luma_beta_offset_div2 ); |
3303 | |
|
3304 | 0 | X_READ_SVLC( ph_luma_tc_offset_div2, -12, 12 ); |
3305 | 0 | picHeader->setDeblockingFilterTcOffsetDiv2( ph_luma_tc_offset_div2 ); |
3306 | 0 | } |
3307 | 0 | } |
3308 | | |
3309 | 6 | if( picHeader->getDeblockingFilterOverrideFlag() /*ph_deblocking_params_present_flag*/ |
3310 | 0 | && !picHeader->getDeblockingFilterDisable() && pps->getPPSChromaToolFlag() ) |
3311 | 0 | { |
3312 | 0 | X_READ_SVLC( ph_cb_beta_offset_div2, -12, 12 ); |
3313 | 0 | picHeader->setDeblockingFilterCbBetaOffsetDiv2( ph_cb_beta_offset_div2 ); |
3314 | |
|
3315 | 0 | X_READ_SVLC( ph_cb_tc_offset_div2, -12, 12 ); |
3316 | 0 | picHeader->setDeblockingFilterCbTcOffsetDiv2( ph_cb_tc_offset_div2 ); |
3317 | |
|
3318 | 0 | X_READ_SVLC( ph_cr_beta_offset_div2, -12, 12 ); |
3319 | 0 | picHeader->setDeblockingFilterCrBetaOffsetDiv2( ph_cr_beta_offset_div2 ); |
3320 | |
|
3321 | 0 | X_READ_SVLC( ph_cr_tc_offset_div2, -12, 12 ); |
3322 | 0 | picHeader->setDeblockingFilterCrTcOffsetDiv2( ph_cr_tc_offset_div2 ); |
3323 | 0 | } |
3324 | 6 | else |
3325 | 6 | { |
3326 | | // When not present, the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred as follows: |
3327 | | // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred to be equal to |
3328 | | // pps_cb_beta_offset_div2 and pps_cb_tc_offset_div2, respectively. |
3329 | | // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred to be equal |
3330 | | // to ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2, respectively. |
3331 | 6 | picHeader->setDeblockingFilterCbBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbBetaOffsetDiv2() |
3332 | 6 | : picHeader->getDeblockingFilterBetaOffsetDiv2() ); |
3333 | 6 | picHeader->setDeblockingFilterCbTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbTcOffsetDiv2() |
3334 | 6 | : picHeader->getDeblockingFilterTcOffsetDiv2() ); |
3335 | | |
3336 | | // When not present, the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred as follows: |
3337 | | // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred to be equal to |
3338 | | // pps_cr_beta_offset_div2 and pps_cr_tc_offset_div2, respectively. |
3339 | | // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred to be equal |
3340 | | // to ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2, respectively. |
3341 | 6 | picHeader->setDeblockingFilterCrBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrBetaOffsetDiv2() |
3342 | 6 | : picHeader->getDeblockingFilterBetaOffsetDiv2() ); |
3343 | 6 | picHeader->setDeblockingFilterCrTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrTcOffsetDiv2() |
3344 | 6 | : picHeader->getDeblockingFilterTcOffsetDiv2() ); |
3345 | 6 | } |
3346 | | |
3347 | | // picture header extension |
3348 | 6 | if( pps->getPictureHeaderExtensionPresentFlag() ) |
3349 | 0 | { |
3350 | 0 | X_READ_UVLC( ph_extension_length, 0, 256 ); |
3351 | 0 | for( unsigned i = 0; i < ph_extension_length; i++ ) |
3352 | 0 | { |
3353 | 0 | X_READ_CODE_NO_RANGE_idx( ph_extension_data_byte, "[i]", 8 ); |
3354 | 0 | (void) ph_extension_data_byte; |
3355 | 0 | } |
3356 | 0 | } |
3357 | | |
3358 | 6 | if( readRbspTrailingBits ) |
3359 | 0 | { |
3360 | 0 | xReadRbspTrailingBits(); |
3361 | 0 | } |
3362 | 6 | picHeader->setValid(); |
3363 | 6 | } |
3364 | | |
3365 | | void HLSyntaxReader::checkAlfNaluTidAndPicTid( const Slice* pcSlice, const PicHeader* picHeader, const ParameterSetManager *parameterSetManager ) |
3366 | 0 | { |
3367 | 0 | const SPS* sps = parameterSetManager->getSPS(picHeader->getSPSId()); |
3368 | 0 | const PPS* pps = parameterSetManager->getPPS(picHeader->getPPSId()); |
3369 | |
|
3370 | 0 | int curPicTid = pcSlice->getTLayer(); |
3371 | 0 | const APS* aps = nullptr; |
3372 | |
|
3373 | 0 | if( sps->getUseALF() && pps->getAlfInfoInPhFlag() && picHeader->getAlfEnabledFlag( COMPONENT_Y ) ) |
3374 | 0 | { |
3375 | 0 | const auto& apsIds = picHeader->getAlfAPSIds(); |
3376 | | //luma |
3377 | 0 | for( int i = 0; i < picHeader->getNumAlfAps(); i++ ) |
3378 | 0 | { |
3379 | 0 | aps = parameterSetManager->getAPS( apsIds[i], ALF_APS ); |
3380 | 0 | CHECK( aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_luma[i] shall be less than or equal to the TemporalId of the picture associated with the PH." ); |
3381 | 0 | if( pcSlice->getNalUnitLayerId() != aps->getLayerId() ) |
3382 | 0 | { |
3383 | 0 | CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); |
3384 | 0 | CHECK( sps->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); |
3385 | 0 | const VPS* vps = parameterSetManager->getVPS( sps->getVPSId() ); |
3386 | 0 | for( int i = 0; i < vps->getNumOutputLayerSets(); i++ ) |
3387 | 0 | { |
3388 | 0 | bool isCurrLayerInOls = false; |
3389 | 0 | bool isRefLayerInOls = false; |
3390 | 0 | for( int j = vps->getNumLayersInOls(i) - 1; j >= 0; j-- ) |
3391 | 0 | { |
3392 | 0 | if( vps->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) |
3393 | 0 | { |
3394 | 0 | isCurrLayerInOls = true; |
3395 | 0 | } |
3396 | 0 | if( vps->getLayerIdInOls(i, j) == aps->getLayerId() ) |
3397 | 0 | { |
3398 | 0 | isRefLayerInOls = true; |
3399 | 0 | } |
3400 | 0 | } |
3401 | 0 | CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); |
3402 | 0 | } |
3403 | 0 | } |
3404 | 0 | } |
3405 | | //chroma |
3406 | 0 | if( picHeader->getAlfEnabledFlag(COMPONENT_Cb) || picHeader->getAlfEnabledFlag( COMPONENT_Cr ) ) |
3407 | 0 | { |
3408 | 0 | int chromaAlfApsId = picHeader->getAlfApsIdChroma(); |
3409 | 0 | aps = parameterSetManager->getAPS( chromaAlfApsId, ALF_APS ); |
3410 | 0 | CHECK( aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be less than or equal to the TemporalId of the picture associated with the PH.") ; |
3411 | 0 | if( pcSlice->getNalUnitLayerId() != aps->getLayerId() ) |
3412 | 0 | { |
3413 | 0 | CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); |
3414 | 0 | CHECK( sps->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); |
3415 | 0 | const VPS* vps = parameterSetManager->getVPS( sps->getVPSId() ); |
3416 | 0 | for( int i = 0; i < vps->getNumOutputLayerSets(); i++ ) |
3417 | 0 | { |
3418 | 0 | bool isCurrLayerInOls = false; |
3419 | 0 | bool isRefLayerInOls = false; |
3420 | 0 | for( int j = vps->getNumLayersInOls(i) - 1; j >= 0; j-- ) |
3421 | 0 | { |
3422 | 0 | if( vps->getLayerIdInOls( i, j ) == pcSlice->getNalUnitLayerId() ) |
3423 | 0 | { |
3424 | 0 | isCurrLayerInOls = true; |
3425 | 0 | } |
3426 | 0 | if( vps->getLayerIdInOls(i, j) == aps->getLayerId() ) |
3427 | 0 | { |
3428 | 0 | isRefLayerInOls = true; |
3429 | 0 | } |
3430 | 0 | } |
3431 | 0 | CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); |
3432 | 0 | } |
3433 | 0 | } |
3434 | 0 | } |
3435 | 0 | } |
3436 | 0 | } |
3437 | | |
3438 | | void HLSyntaxReader::parseSliceHeader( Slice* pcSlice, |
3439 | | std::shared_ptr<PicHeader>& picHeader, |
3440 | | const ParameterSetManager* parameterSetManager, |
3441 | | const int prevTid0POC, |
3442 | | bool& firstSliceInPic ) |
3443 | 18 | { |
3444 | | #if ENABLE_TRACING |
3445 | | xTraceSliceHeader(); |
3446 | | #endif |
3447 | | |
3448 | 18 | X_READ_FLAG( sh_picture_header_in_slice_header_flag ); |
3449 | 18 | pcSlice->setPictureHeaderInSliceHeader( sh_picture_header_in_slice_header_flag ); |
3450 | | |
3451 | 18 | if( sh_picture_header_in_slice_header_flag ) |
3452 | 2 | { |
3453 | 2 | picHeader.reset( new PicHeader ); |
3454 | 2 | parsePictureHeader( picHeader.get(), parameterSetManager, false ); |
3455 | 2 | } |
3456 | 18 | CHECK( !picHeader, "Picture Header not allocated" ); // should always be allocated, even if it is not valid |
3457 | 4 | CHECK( !picHeader->isValid(), "Picture Header missing" ); |
3458 | | |
3459 | 4 | checkAlfNaluTidAndPicTid( pcSlice, picHeader.get(), parameterSetManager ); |
3460 | | |
3461 | 4 | const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() ); |
3462 | 4 | CHECK( pps == 0, "Invalid PPS" ); |
3463 | 4 | const SPS* sps = parameterSetManager->getSPS( pps->getSPSId() ); |
3464 | 4 | CHECK( sps == 0, "Invalid SPS" ); |
3465 | | |
3466 | 4 | auto gci = sps->getProfileTierLevel()->getConstraintInfo(); |
3467 | 4 | CHECK_CONSTRAINT( gci->getPicHeaderInSliceHeaderConstraintFlag() && !sh_picture_header_in_slice_header_flag, |
3468 | 4 | "PH shall be present in SH, when pic_header_in_slice_header_constraint_flag is equal to 1" ); |
3469 | | |
3470 | 4 | if( sh_picture_header_in_slice_header_flag ) |
3471 | 0 | { |
3472 | 0 | CHECK( pps->getRplInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, rpl_info_in_ph_flag shall be equal to 0" ); |
3473 | 0 | CHECK( pps->getDbfInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, dbf_info_in_ph_flag shall be equal to 0" ); |
3474 | 0 | CHECK( pps->getSaoInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, sao_info_in_ph_flag shall be equal to 0" ); |
3475 | 0 | CHECK( pps->getAlfInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, alf_info_in_ph_flag shall be equal to 0" ); |
3476 | 0 | CHECK( pps->getWpInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, wp_info_in_ph_flag shall be equal to 0" ); |
3477 | 0 | CHECK( pps->getQpDeltaInfoInPhFlag() == 1, |
3478 | 0 | "When sh_picture_header_in_slice_header_flag is equal to 1, qp_delta_info_in_ph_flag shall be equal to 0" ); |
3479 | 0 | CHECK( sps->getSubPicInfoPresentFlag() == 1, |
3480 | 0 | "When sps_subpic_info_present_flag is equal to 1, the value of sh_picture_header_in_slice_header_flag shall be equal to 0" ); |
3481 | 0 | } |
3482 | 4 | CHECK( sps->getSubPicInfoPresentFlag() == 1 && sps->getVirtualBoundariesEnabledFlag() == 1 && sps->getVirtualBoundariesPresentFlag() == 0, |
3483 | 4 | "when sps_subpic_info_present_flag is equal to 1 and sps_virtual_boundaries_enabled_flag is equal to 1, " |
3484 | 4 | "sps_virtual_boundaries_present_flag shall be equal 1" ); |
3485 | | |
3486 | | |
3487 | 4 | const bool bChroma = sps->getChromaFormatIdc() != CHROMA_400; |
3488 | | |
3489 | | // picture order count |
3490 | 4 | const int iPOClsb = picHeader->getPocLsb(); |
3491 | 4 | const int iMaxPOClsb = 1 << sps->getBitsForPOC(); |
3492 | 4 | if( pcSlice->getIdrPicFlag() ) |
3493 | 0 | { |
3494 | 0 | int iPOCmsb; |
3495 | 0 | if( picHeader->getPocMsbPresentFlag() ) |
3496 | 0 | { |
3497 | 0 | iPOCmsb = picHeader->getPocMsbVal() * iMaxPOClsb; |
3498 | 0 | } |
3499 | 0 | else |
3500 | 0 | { |
3501 | 0 | iPOCmsb = 0; |
3502 | 0 | } |
3503 | 0 | pcSlice->setPOC( iPOCmsb + iPOClsb ); |
3504 | 0 | } |
3505 | 4 | else |
3506 | 4 | { |
3507 | 4 | const int iPrevPOC = prevTid0POC; |
3508 | 4 | const int iPrevPOClsb = iPrevPOC & ( iMaxPOClsb - 1 ); |
3509 | 4 | const int iPrevPOCmsb = iPrevPOC - iPrevPOClsb; |
3510 | 4 | int iPOCmsb; |
3511 | 4 | if( picHeader->getPocMsbPresentFlag() ) |
3512 | 0 | { |
3513 | 0 | iPOCmsb = picHeader->getPocMsbVal() * iMaxPOClsb; |
3514 | 0 | } |
3515 | 4 | else |
3516 | 4 | { |
3517 | 4 | if( ( iPOClsb < iPrevPOClsb ) && ( ( iPrevPOClsb - iPOClsb ) >= ( iMaxPOClsb / 2 ) ) ) |
3518 | 0 | { |
3519 | 0 | iPOCmsb = iPrevPOCmsb + iMaxPOClsb; |
3520 | 0 | } |
3521 | 4 | else if( ( iPOClsb > iPrevPOClsb ) && ( ( iPOClsb - iPrevPOClsb ) > ( iMaxPOClsb / 2 ) ) ) |
3522 | 0 | { |
3523 | 0 | iPOCmsb = iPrevPOCmsb - iMaxPOClsb; |
3524 | 0 | } |
3525 | 4 | else |
3526 | 4 | { |
3527 | 4 | iPOCmsb = iPrevPOCmsb; |
3528 | 4 | } |
3529 | 4 | } |
3530 | 4 | pcSlice->setPOC( iPOCmsb + iPOClsb ); |
3531 | 4 | } |
3532 | | |
3533 | 4 | if( sps->getSubPicInfoPresentFlag() ) |
3534 | 0 | { |
3535 | 0 | X_READ_CODE_NO_RANGE( sh_subpic_id, sps->getSubPicIdLen() ); |
3536 | 0 | pcSlice->setSliceSubPicId( sh_subpic_id ); |
3537 | 0 | } |
3538 | | |
3539 | 4 | const unsigned NumTilesInPic = pps->getNumTiles(); |
3540 | | |
3541 | 4 | uint32_t sliceAddr = 0; |
3542 | 4 | if( !pps->getRectSliceFlag() ) // raster scan slices |
3543 | 0 | { |
3544 | 0 | if( NumTilesInPic > 1 ) |
3545 | 0 | { |
3546 | | // slice address is the raster scan tile index of first tile in slice |
3547 | 0 | const int bitsSliceAddress = (int) std::ceil( std::log2( NumTilesInPic ) ); |
3548 | 0 | X_READ_CODE( sh_slice_address, bitsSliceAddress, 0, NumTilesInPic - 1 ); |
3549 | 0 | sliceAddr = sh_slice_address; |
3550 | 0 | } |
3551 | 0 | } |
3552 | 4 | else // rectangular slices |
3553 | 4 | { |
3554 | | // slice address is the index of the slice within the current sub-picture |
3555 | 4 | const uint32_t currSubPicIdx = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() ); |
3556 | 4 | const SubPic& currSubPic = pps->getSubPic( currSubPicIdx ); |
3557 | 4 | const unsigned NumSlicesInCurrSubpic = currSubPic.getNumSlicesInSubPic(); |
3558 | 4 | if( NumSlicesInCurrSubpic > 1 ) |
3559 | 0 | { |
3560 | 0 | const int bitsSliceAddress = (int) std::ceil( std::log2( NumSlicesInCurrSubpic ) ); |
3561 | 0 | X_READ_CODE( sh_slice_address, bitsSliceAddress, 0, NumSlicesInCurrSubpic - 1 ); |
3562 | 0 | sliceAddr = sh_slice_address; |
3563 | 0 | } |
3564 | 4 | } |
3565 | | |
3566 | 4 | const std::vector<bool>& shExtraBitsPresent = sps->getExtraSHBitPresentFlags(); |
3567 | 4 | for( int i = 0; i < sps->getNumExtraSHBitsBytes() * 8; i++ ) |
3568 | 0 | { |
3569 | | // extra bits are ignored (when present) |
3570 | 0 | if( shExtraBitsPresent[i] ) |
3571 | 0 | { |
3572 | 0 | X_READ_FLAG_idx( sh_extra_bit, "[i]" ); |
3573 | 0 | (void) sh_extra_bit; |
3574 | 0 | } |
3575 | 0 | } |
3576 | | |
3577 | 4 | uint32_t numTilesInSlice = 1; |
3578 | 4 | if( !pps->getRectSliceFlag() && (int) NumTilesInPic - (int) sliceAddr > 1 ) |
3579 | 0 | { |
3580 | 0 | X_READ_UVLC( sh_num_tiles_in_slice_minus1, 0, NumTilesInPic - 1 ); |
3581 | 0 | CHECK_CONSTRAINT( gci->getOneSlicePerPicConstraintFlag() && sh_num_tiles_in_slice_minus1 != NumTilesInPic - 1, |
3582 | 0 | "When rect_slice_flag is equal to 0 and one_slice_per_pic_constraint_flag equal to 1, the value of num_tiles_in_slice_minus1 present in" |
3583 | 0 | " each slice header shall be equal to NumTilesInPic - 1" ); |
3584 | 0 | numTilesInSlice = sh_num_tiles_in_slice_minus1 + 1; |
3585 | 0 | } |
3586 | | |
3587 | 4 | if( !pps->getRectSliceFlag() ) |
3588 | 0 | { |
3589 | 0 | CHECK( sliceAddr >= pps->getNumTiles(), "Invalid slice address" ); |
3590 | |
|
3591 | 0 | pcSlice->resetSliceMap(); |
3592 | 0 | pcSlice->setSliceID( sliceAddr ); |
3593 | | |
3594 | | // NumCtusInCurrSlice = 0; |
3595 | 0 | for( uint32_t tileIdx = sliceAddr; tileIdx < sliceAddr + numTilesInSlice; tileIdx++ ) |
3596 | 0 | { |
3597 | 0 | uint32_t tileX = tileIdx % pps->getNumTileColumns(); |
3598 | 0 | uint32_t tileY = tileIdx / pps->getNumTileColumns(); |
3599 | 0 | CHECK( tileY >= pps->getNumTileRows(), "Number of tiles in slice exceeds the remaining number of tiles in picture" ); |
3600 | |
|
3601 | 0 | pcSlice->addCtusToSlice( pps->getTileColumnBd( tileX ), pps->getTileColumnBd( tileX + 1 ), |
3602 | 0 | pps->getTileRowBd( tileY ), pps->getTileRowBd( tileY + 1 ), pps->getPicWidthInCtu() ); |
3603 | 0 | } |
3604 | 0 | } |
3605 | 4 | else |
3606 | 4 | { |
3607 | 4 | uint32_t picLevelSliceIdx = sliceAddr; |
3608 | 4 | const uint32_t currSubPicIdx = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() ); |
3609 | 4 | for( int subpic = 0; subpic < currSubPicIdx; subpic++ ) |
3610 | 0 | { |
3611 | 0 | picLevelSliceIdx += pps->getSubPic( subpic ).getNumSlicesInSubPic(); |
3612 | 0 | } |
3613 | 4 | pcSlice->setSliceMap( pps->getSliceMap( picLevelSliceIdx ) ); |
3614 | 4 | pcSlice->setSliceID( picLevelSliceIdx ); |
3615 | 4 | } |
3616 | | |
3617 | 4 | if( firstSliceInPic != ( pcSlice->getCtuAddrInSlice( 0 ) == 0 ) ) |
3618 | 0 | { |
3619 | | // exit early, because we need to start again with some fields copied from previous slice |
3620 | 0 | firstSliceInPic = false; |
3621 | 0 | return; |
3622 | 0 | } |
3623 | | |
3624 | 4 | if( picHeader->getPicInterSliceAllowedFlag() ) |
3625 | 0 | { |
3626 | 0 | X_READ_UVLC( sh_slice_type, 0, 2 ); |
3627 | 0 | pcSlice->setSliceType( (SliceType) sh_slice_type ); |
3628 | 0 | } |
3629 | 4 | else |
3630 | 4 | { |
3631 | 4 | pcSlice->setSliceType( I_SLICE ); |
3632 | 4 | } |
3633 | | |
3634 | 4 | CHECK( !picHeader->getPicIntraSliceAllowedFlag() && pcSlice->getSliceType() != B_SLICE && pcSlice->getSliceType() != P_SLICE, |
3635 | 4 | "When ph_intra_slice_allowed_flag is equal to 0, the value of sh_slice_type shall be equal to 0 or 1." ); |
3636 | | |
3637 | 4 | if( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL |
3638 | 0 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP |
3639 | 0 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA |
3640 | 0 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR ) |
3641 | 0 | { |
3642 | 0 | X_READ_FLAG( sh_no_output_of_prior_pics_flag ); |
3643 | 0 | pcSlice->setNoOutputOfPriorPicsFlag( sh_no_output_of_prior_pics_flag ); |
3644 | 0 | } |
3645 | | |
3646 | | // inherit values from picture header |
3647 | | // set default values in case slice overrides are disabled |
3648 | 4 | pcSlice->inheritFromPicHeader( picHeader.get(), pps, sps ); |
3649 | | |
3650 | 4 | if( sps->getUseALF() && !pps->getAlfInfoInPhFlag() ) |
3651 | 0 | { |
3652 | 0 | X_READ_FLAG( sh_alf_enabled_flag ); |
3653 | 0 | pcSlice->setAlfEnabledFlag( COMPONENT_Y, sh_alf_enabled_flag ); |
3654 | |
|
3655 | 0 | if( sh_alf_enabled_flag ) |
3656 | 0 | { |
3657 | 0 | X_READ_CODE_NO_RANGE( sh_num_alf_aps_ids_luma, 3 ); |
3658 | 0 | pcSlice->setNumAlfAps( sh_num_alf_aps_ids_luma ); |
3659 | |
|
3660 | 0 | AlfApsIdVec apsId( sh_num_alf_aps_ids_luma, -1 ); |
3661 | 0 | for( int i = 0; i < sh_num_alf_aps_ids_luma; i++ ) |
3662 | 0 | { |
3663 | 0 | X_READ_CODE_NO_RANGE_idx( sh_alf_aps_id_luma, "[i]", 3 ); |
3664 | 0 | apsId[i] = sh_alf_aps_id_luma; |
3665 | |
|
3666 | 0 | const APS* APStoCheckLuma = parameterSetManager->getAPS( apsId[i], ALF_APS ); |
3667 | 0 | CHECK( APStoCheckLuma == nullptr, "referenced APS not found" ); |
3668 | 0 | CHECK( APStoCheckLuma->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_LUMA] != 1, |
3669 | 0 | "The value of alf_luma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and" |
3670 | 0 | " aps_adaptation_parameter_set_id equal to sh_alf_aps_id_luma[ i ] shall be equal to 1." ); |
3671 | 0 | } |
3672 | 0 | pcSlice->setAlfApsIdsLuma( apsId ); |
3673 | |
|
3674 | 0 | if( bChroma ) |
3675 | 0 | { |
3676 | 0 | X_READ_FLAG( sh_alf_cb_enabled_flag ); |
3677 | 0 | pcSlice->setAlfEnabledFlag( COMPONENT_Cb, sh_alf_cb_enabled_flag ); |
3678 | |
|
3679 | 0 | X_READ_FLAG( sh_alf_cr_enabled_flag ); |
3680 | 0 | pcSlice->setAlfEnabledFlag( COMPONENT_Cr, sh_alf_cr_enabled_flag ); |
3681 | 0 | } |
3682 | |
|
3683 | 0 | if( pcSlice->getAlfEnabledFlag( COMPONENT_Cb ) || pcSlice->getAlfEnabledFlag( COMPONENT_Cr ) ) |
3684 | 0 | { |
3685 | 0 | X_READ_CODE_NO_RANGE( sh_alf_aps_id_chroma, 3 ); |
3686 | 0 | pcSlice->setAlfApsIdChroma( sh_alf_aps_id_chroma ); |
3687 | |
|
3688 | 0 | const APS* APStoCheckChroma = parameterSetManager->getAPS( sh_alf_aps_id_chroma, ALF_APS ); |
3689 | 0 | CHECK( APStoCheckChroma == nullptr, "referenced APS not found" ); |
3690 | 0 | CHECK( APStoCheckChroma->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_CHROMA] != 1, |
3691 | 0 | "The value of alf_chroma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and" |
3692 | 0 | " aps_adaptation_parameter_set_id equal to sh_alf_aps_id_chroma shall be equal to 1." ); |
3693 | 0 | } |
3694 | | |
3695 | 0 | if( sps->getUseCCALF() ) |
3696 | 0 | { |
3697 | 0 | X_READ_FLAG( sh_alf_cc_cb_enabled_flag ); |
3698 | 0 | pcSlice->setCcAlfCbEnabledFlag( sh_alf_cc_cb_enabled_flag ); |
3699 | |
|
3700 | 0 | if( sh_alf_cc_cb_enabled_flag ) |
3701 | 0 | { |
3702 | 0 | X_READ_CODE_NO_RANGE( sh_alf_cc_cb_aps_id, 3 ); |
3703 | 0 | pcSlice->setCcAlfCbApsId( sh_alf_cc_cb_aps_id ); |
3704 | |
|
3705 | 0 | const APS* APStoCheckCcCb = parameterSetManager->getAPS( sh_alf_cc_cb_aps_id, ALF_APS ); |
3706 | 0 | CHECK( !APStoCheckCcCb, "referenced APS not found" ); |
3707 | 0 | CHECK( APStoCheckCcCb->getCcAlfAPSParam().newCcAlfFilter[0] != 1, |
3708 | 0 | "The value of alf_cc_cb_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and " |
3709 | 0 | "aps_adaptation_parameter_set_id equal to sh_alf_cc_cb_aps_id shall be equal to 1." ); |
3710 | 0 | } |
3711 | | |
3712 | 0 | X_READ_FLAG( sh_alf_cc_cr_enabled_flag ); |
3713 | 0 | pcSlice->setCcAlfCrEnabledFlag( sh_alf_cc_cr_enabled_flag ); |
3714 | |
|
3715 | 0 | if( sh_alf_cc_cr_enabled_flag ) |
3716 | 0 | { |
3717 | 0 | X_READ_CODE_NO_RANGE( sh_alf_cc_cr_aps_id, 3 ); |
3718 | 0 | pcSlice->setCcAlfCrApsId( sh_alf_cc_cr_aps_id ); |
3719 | |
|
3720 | 0 | const APS* APStoCheckCcCr = parameterSetManager->getAPS( sh_alf_cc_cr_aps_id, ALF_APS ); |
3721 | 0 | CHECK( !APStoCheckCcCr, "referenced APS not found" ); |
3722 | 0 | CHECK( APStoCheckCcCr->getCcAlfAPSParam().newCcAlfFilter[1] != 1, |
3723 | 0 | "The value of alf_cc_cr_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and " |
3724 | 0 | "aps_adaptation_parameter_set_id equal to sh_alf_cc_cr_aps_id shall be equal to 1." ); |
3725 | 0 | } |
3726 | 0 | } |
3727 | 0 | } |
3728 | 0 | } |
3729 | | |
3730 | 4 | if( picHeader->getLmcsEnabledFlag() && !sh_picture_header_in_slice_header_flag ) |
3731 | 0 | { |
3732 | 0 | X_READ_FLAG( sh_lmcs_used_flag ); |
3733 | 0 | pcSlice->setLmcsEnabledFlag( sh_lmcs_used_flag ); |
3734 | 0 | } |
3735 | | |
3736 | 4 | if( picHeader->getExplicitScalingListEnabledFlag() && !sh_picture_header_in_slice_header_flag ) |
3737 | 0 | { |
3738 | 0 | X_READ_FLAG( sh_explicit_scaling_list_used_flag ); |
3739 | 0 | pcSlice->setExplicitScalingListUsed( sh_explicit_scaling_list_used_flag ); |
3740 | 0 | } |
3741 | | |
3742 | 4 | if( pps->getRplInfoInPhFlag() ) |
3743 | 0 | { |
3744 | | // inheritFromPicHeader() already called |
3745 | 0 | } |
3746 | 4 | else if( pcSlice->getIdrPicFlag() && !sps->getIDRRefParamListPresent() ) |
3747 | 0 | { |
3748 | 0 | pcSlice->clearRPL( REF_PIC_LIST_0 ); |
3749 | 0 | pcSlice->clearRPL( REF_PIC_LIST_1 ); |
3750 | 0 | } |
3751 | 4 | else |
3752 | 4 | { |
3753 | 4 | parsePicOrSliceHeaderRPL( pcSlice, sps, pps ); |
3754 | 4 | } |
3755 | | |
3756 | 4 | bool numRefIdxActiveOverrideFlag = true; |
3757 | 4 | unsigned numRefIdxActiveMinus1[2] = { 0, 0 }; |
3758 | 4 | if( ( !pcSlice->isIntra() && pcSlice->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() > 1 ) || // |
3759 | 0 | ( pcSlice->isInterB() && pcSlice->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 1 ) ) |
3760 | 0 | { |
3761 | 0 | X_READ_FLAG( sh_num_ref_idx_active_override_flag ); |
3762 | 0 | numRefIdxActiveOverrideFlag = sh_num_ref_idx_active_override_flag; |
3763 | |
|
3764 | 0 | if( sh_num_ref_idx_active_override_flag ) |
3765 | 0 | { |
3766 | 0 | for( int i = 0; i < ( pcSlice->isInterB() ? 2 : 1 ); ++i ) |
3767 | 0 | { |
3768 | 0 | if( pcSlice->getRPL( (RefPicList) i )->getNumRefEntries() > 1 ) |
3769 | 0 | { |
3770 | 0 | X_READ_UVLC_idx( sh_num_ref_idx_active_minus1, "[ i ]", 0, 14 ); |
3771 | 0 | numRefIdxActiveMinus1[i] = sh_num_ref_idx_active_minus1; |
3772 | 0 | } |
3773 | 0 | } |
3774 | 0 | } |
3775 | 0 | } |
3776 | | |
3777 | 4 | for( auto i: { REF_PIC_LIST_0, REF_PIC_LIST_1 } ) |
3778 | 0 | { |
3779 | 0 | if( pcSlice->isInterB() || ( pcSlice->isInterP() && i == REF_PIC_LIST_0 ) ) |
3780 | 0 | { |
3781 | 0 | if( numRefIdxActiveOverrideFlag ) |
3782 | 0 | { |
3783 | 0 | pcSlice->setNumRefIdx( i, numRefIdxActiveMinus1[i] + 1 ); |
3784 | 0 | } |
3785 | 0 | else |
3786 | 0 | { |
3787 | 0 | const int pps_num_ref_idx_default_active_minus1 = ( i == 0 ? pps->getNumRefIdxL0DefaultActive() : pps->getNumRefIdxL1DefaultActive() ) - 1; |
3788 | 0 | if( pcSlice->getRPL( i )->getNumRefEntries() >= pps_num_ref_idx_default_active_minus1 + 1 ) |
3789 | 0 | { |
3790 | 0 | pcSlice->setNumRefIdx( i, pps_num_ref_idx_default_active_minus1 + 1 ); |
3791 | 0 | } |
3792 | 0 | else |
3793 | 0 | { |
3794 | 0 | pcSlice->setNumRefIdx( i, pcSlice->getRPL( i )->getNumRefEntries() ); |
3795 | 0 | } |
3796 | 0 | } |
3797 | 0 | } |
3798 | 0 | else /* sh_slice_type == I || ( sh_slice_type == P && i == 1 ) */ |
3799 | 0 | { |
3800 | 0 | pcSlice->setNumRefIdx( i, 0 ); |
3801 | 0 | } |
3802 | 0 | } |
3803 | | |
3804 | 4 | if( pcSlice->isInterP() || pcSlice->isInterB() ) |
3805 | 0 | { |
3806 | 0 | CHECK( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) == 0, "Number of active entries in RPL0 of P or B picture shall be greater than 0" ); |
3807 | 0 | if( pcSlice->isInterB() ) |
3808 | 0 | { |
3809 | 0 | CHECK( pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) == 0, "Number of active entries in RPL1 of B picture shall be greater than 0" ); |
3810 | 0 | } |
3811 | 0 | } |
3812 | | |
3813 | 4 | if( !pcSlice->isIntra() ) |
3814 | 0 | { |
3815 | 0 | if( pps->getCabacInitPresentFlag() ) |
3816 | 0 | { |
3817 | 0 | X_READ_FLAG( sh_cabac_init_flag ); |
3818 | 0 | pcSlice->setCabacInitFlag( sh_cabac_init_flag ); |
3819 | 0 | } |
3820 | |
|
3821 | 0 | if( picHeader->getEnableTMVPFlag() && !pps->getRplInfoInPhFlag() ) |
3822 | 0 | { |
3823 | 0 | if( pcSlice->isInterB() ) |
3824 | 0 | { |
3825 | 0 | X_READ_FLAG( sh_collocated_from_l0_flag ); |
3826 | 0 | pcSlice->setColFromL0Flag( sh_collocated_from_l0_flag ); |
3827 | 0 | } |
3828 | |
|
3829 | 0 | if( ( pcSlice->getColFromL0Flag() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > 1 ) |
3830 | 0 | || ( !pcSlice->getColFromL0Flag() && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) > 1 ) ) |
3831 | 0 | { |
3832 | 0 | X_READ_UVLC( sh_collocated_ref_idx, 0, pcSlice->getNumRefIdx( pcSlice->getColFromL0Flag() ? REF_PIC_LIST_0 : REF_PIC_LIST_1 ) - 1u ); |
3833 | |
|
3834 | 0 | pcSlice->setColRefIdx( sh_collocated_ref_idx ); |
3835 | 0 | } |
3836 | 0 | } |
3837 | |
|
3838 | 0 | if( !pps->getWpInfoInPhFlag() && |
3839 | 0 | ( ( pps->getUseWP() && pcSlice->isInterP() ) || ( pps->getWPBiPred() && pcSlice->isInterB() ) ) ) |
3840 | 0 | { |
3841 | 0 | parsePredWeightTable( pcSlice, sps, pps, { pcSlice->getNumRefIdx( REF_PIC_LIST_0 ), pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) } ); |
3842 | 0 | } |
3843 | |
|
3844 | 0 | if( pps->getWpInfoInPhFlag() ) |
3845 | 0 | { |
3846 | 0 | CHECK( pps->getUseWP() && pcSlice->isInterP() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > picHeader->getNumL0Weights(), |
3847 | 0 | "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_pred_flag is equal to 1, and sh_slice_type is equal to P," |
3848 | 0 | " NumRefIdxActive[ 0 ] shall be less than or equal to the value of NumWeightsL0." ); |
3849 | 0 | CHECK( pps->getWPBiPred() && pcSlice->isInterB() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > picHeader->getNumL0Weights(), |
3850 | 0 | "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_bipred_flag is equal to 1, and sh_slice_type is equal to B," |
3851 | 0 | " NumRefIdxActive[ 0 ] shall be less than or equal to the value of NumWeightsL0." ); |
3852 | 0 | CHECK( pps->getWPBiPred() && pcSlice->isInterB() && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) > picHeader->getNumL1Weights(), |
3853 | 0 | "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_bipred_flag is equal to 1, and sh_slice_type is equal to B, " |
3854 | 0 | " the value of NumRefIdxActive[ 1 ] shall be less than or equal to the value of NumWeightsL1." ); |
3855 | 0 | } |
3856 | 0 | } |
3857 | | |
3858 | 4 | if( !pps->getQpDeltaInfoInPhFlag() ) |
3859 | 0 | { |
3860 | 0 | X_READ_SVLC_NO_RANGE( sh_qp_delta ); |
3861 | |
|
3862 | 0 | int SliceQpY = 26 + pps->getPicInitQPMinus26() + sh_qp_delta; |
3863 | 0 | CHECK_READ_RANGE( SliceQpY, -sps->getQpBDOffset(), MAX_QP, SliceQpY ); |
3864 | |
|
3865 | 0 | pcSlice->setSliceQp( SliceQpY ); |
3866 | 0 | } |
3867 | | |
3868 | 4 | if( pps->getSliceChromaQpFlag() ) |
3869 | 0 | { |
3870 | 0 | X_READ_SVLC( sh_cb_qp_offset, -12, +12 ); |
3871 | 0 | CHECK_READ_RANGE( sh_cb_qp_offset + pps->getQpOffset( COMPONENT_Cb ), -12, +12, "pps_cb_qp_offset + sh_cb_qp_offset" ); |
3872 | 0 | pcSlice->setSliceChromaQpDelta( COMPONENT_Cb, sh_cb_qp_offset ); |
3873 | |
|
3874 | 0 | X_READ_SVLC( sh_cr_qp_offset, -12, +12 ); |
3875 | 0 | CHECK_READ_RANGE( sh_cr_qp_offset + pps->getQpOffset( COMPONENT_Cr ), -12, +12, "pps_cr_qp_offset + sh_cr_qp_offset" ); |
3876 | 0 | pcSlice->setSliceChromaQpDelta( COMPONENT_Cr, sh_cr_qp_offset ); |
3877 | |
|
3878 | 0 | if( sps->getJointCbCrEnabledFlag() ) |
3879 | 0 | { |
3880 | 0 | X_READ_SVLC( sh_joint_cbcr_qp_offset, -12, +12 ); |
3881 | 0 | CHECK_READ_RANGE( sh_joint_cbcr_qp_offset + pps->getQpOffset( JOINT_CbCr ), -12, +12, "pps_joint_cbcr_qp_offset_value + sh_joint_cbcr_qp_offset" ); |
3882 | 0 | pcSlice->setSliceChromaQpDelta( JOINT_CbCr, sh_joint_cbcr_qp_offset ); |
3883 | 0 | } |
3884 | 0 | } |
3885 | 4 | if( pps->getCuChromaQpOffsetEnabledFlag() ) |
3886 | 0 | { |
3887 | 0 | X_READ_FLAG( sh_cu_chroma_qp_offset_enabled_flag ); |
3888 | 0 | pcSlice->setUseChromaQpAdj( sh_cu_chroma_qp_offset_enabled_flag ); |
3889 | 0 | } |
3890 | | |
3891 | 4 | if( sps->getUseSAO() && !pps->getSaoInfoInPhFlag() ) |
3892 | 0 | { |
3893 | 0 | X_READ_FLAG( sh_sao_luma_used_flag ); |
3894 | 0 | pcSlice->setSaoEnabledFlag( CHANNEL_TYPE_LUMA, sh_sao_luma_used_flag ); |
3895 | |
|
3896 | 0 | if( bChroma ) |
3897 | 0 | { |
3898 | 0 | X_READ_FLAG( sh_sao_chroma_used_flag ); |
3899 | 0 | pcSlice->setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, sh_sao_chroma_used_flag ); |
3900 | 0 | } |
3901 | 0 | } |
3902 | | |
3903 | 4 | if( pps->getDeblockingFilterOverrideEnabledFlag() && !pps->getDbfInfoInPhFlag() ) |
3904 | 0 | { |
3905 | 0 | X_READ_FLAG( sh_deblocking_params_present_flag ); |
3906 | 0 | pcSlice->setDeblockingFilterOverrideFlag( sh_deblocking_params_present_flag ); |
3907 | 0 | } |
3908 | | // If pps_deblocking_filter_disabled_flag and sh_deblocking_params_present_flag are both equal to 1, the value of sh_deblocking_filter_disabled_flag is |
3909 | | // inferred to be equal to 0. |
3910 | | // Otherwise (pps_deblocking_filter_disabled_flag or sh_deblocking_params_present_flag is equal to 0), the value of sh_deblocking_filter_disabled_flag is |
3911 | | // inferred to be equal to ph_deblocking_filter_disabled_flag. |
3912 | 4 | pcSlice->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() && pcSlice->getDeblockingFilterOverrideFlag() |
3913 | 4 | ? 0 : picHeader->getDeblockingFilterDisable() ); |
3914 | | |
3915 | 4 | if( pcSlice->getDeblockingFilterOverrideFlag() ) |
3916 | 0 | { |
3917 | 0 | if( !pps->getPPSDeblockingFilterDisabledFlag() ) |
3918 | 0 | { |
3919 | 0 | X_READ_FLAG( sh_deblocking_filter_disabled_flag ); |
3920 | 0 | pcSlice->setDeblockingFilterDisable( sh_deblocking_filter_disabled_flag ); |
3921 | 0 | } |
3922 | |
|
3923 | 0 | if( !pcSlice->getDeblockingFilterDisable() ) |
3924 | 0 | { |
3925 | 0 | X_READ_SVLC( sh_luma_beta_offset_div2, -12, 12 ); |
3926 | 0 | pcSlice->setDeblockingFilterBetaOffsetDiv2( sh_luma_beta_offset_div2 ); |
3927 | 0 | X_READ_SVLC( sh_luma_tc_offset_div2, -12, 12 ); |
3928 | 0 | pcSlice->setDeblockingFilterTcOffsetDiv2( sh_luma_tc_offset_div2 ); |
3929 | 0 | } |
3930 | 0 | } |
3931 | | |
3932 | 4 | if( pcSlice->getDeblockingFilterOverrideFlag() && !pcSlice->getDeblockingFilterDisable() && pps->getPPSChromaToolFlag() ) |
3933 | 0 | { |
3934 | 0 | X_READ_SVLC( sh_cb_beta_offset_div2, -12, 12 ); |
3935 | 0 | pcSlice->setDeblockingFilterCbBetaOffsetDiv2( sh_cb_beta_offset_div2 ); |
3936 | |
|
3937 | 0 | X_READ_SVLC( sh_cb_tc_offset_div2, -12, 12 ); |
3938 | 0 | pcSlice->setDeblockingFilterCbTcOffsetDiv2( sh_cb_tc_offset_div2 ); |
3939 | |
|
3940 | 0 | X_READ_SVLC( sh_cr_beta_offset_div2, -12, 12 ); |
3941 | 0 | pcSlice->setDeblockingFilterCrBetaOffsetDiv2( sh_cr_beta_offset_div2 ); |
3942 | |
|
3943 | 0 | X_READ_SVLC( sh_cr_tc_offset_div2, -12, 12 ); |
3944 | 0 | pcSlice->setDeblockingFilterCrTcOffsetDiv2( sh_cr_tc_offset_div2 ); |
3945 | 0 | } |
3946 | 4 | else |
3947 | 4 | { |
3948 | 4 | if( pps->getPPSChromaToolFlag() ) |
3949 | 0 | { |
3950 | | // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of sh_cb_beta_offset_div2 and sh_cb_tc_offset_div2 are inferred to be equal to |
3951 | | // ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2, respectively. |
3952 | | // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of sh_cr_beta_offset_div2 and sh_cr_tc_offset_div2 are inferred to be equal to |
3953 | | // ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2, respectively. |
3954 | |
|
3955 | 0 | pcSlice->setDeblockingFilterCbBetaOffsetDiv2( picHeader->getDeblockingFilterCbBetaOffsetDiv2() ); |
3956 | 0 | pcSlice->setDeblockingFilterCbTcOffsetDiv2 ( picHeader->getDeblockingFilterCbTcOffsetDiv2() ); |
3957 | 0 | pcSlice->setDeblockingFilterCrBetaOffsetDiv2( picHeader->getDeblockingFilterCrBetaOffsetDiv2() ); |
3958 | 0 | pcSlice->setDeblockingFilterCrTcOffsetDiv2 ( picHeader->getDeblockingFilterCrTcOffsetDiv2() ); |
3959 | 0 | } |
3960 | 4 | else |
3961 | 4 | { |
3962 | | // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of sh_cb_beta_offset_div2 and sh_cb_tc_offset_div2 are inferred to be equal to |
3963 | | // sh_luma_beta_offset_div2 and sh_luma_tc_offset_div2, respectively. |
3964 | | // Otherwise( pps_chroma_tool_offsets_present_flag is equal to 0 ), the values of sh_cr_beta_offset_div2 and sh_cr_tc_offset_div2 are inferred to be equal |
3965 | | // to sh_luma_beta_offset_div2 and sh_luma_tc_offset_div2, respectively. |
3966 | | |
3967 | 4 | pcSlice->setDeblockingFilterCbBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() ); |
3968 | 4 | pcSlice->setDeblockingFilterCbTcOffsetDiv2 ( pcSlice->getDeblockingFilterTcOffsetDiv2() ); |
3969 | 4 | pcSlice->setDeblockingFilterCrBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() ); |
3970 | 4 | pcSlice->setDeblockingFilterCrTcOffsetDiv2 ( pcSlice->getDeblockingFilterTcOffsetDiv2() ); |
3971 | 4 | } |
3972 | 4 | } |
3973 | | |
3974 | | // dependent quantization |
3975 | 4 | if( sps->getDepQuantEnabledFlag() ) |
3976 | 0 | { |
3977 | 0 | X_READ_FLAG( sh_dep_quant_used_flag ); |
3978 | 0 | pcSlice->setDepQuantEnabledFlag( sh_dep_quant_used_flag ); |
3979 | 0 | } |
3980 | | |
3981 | | // sign data hiding |
3982 | 4 | if( sps->getSignDataHidingEnabledFlag() && !pcSlice->getDepQuantEnabledFlag() ) |
3983 | 0 | { |
3984 | 0 | X_READ_FLAG( sh_sign_data_hiding_used_flag ); |
3985 | 0 | pcSlice->setSignDataHidingEnabledFlag( sh_sign_data_hiding_used_flag ); |
3986 | 0 | } |
3987 | | |
3988 | | // signal TS residual coding disabled flag |
3989 | 4 | if( sps->getTransformSkipEnabledFlag() && !pcSlice->getDepQuantEnabledFlag() && !pcSlice->getSignDataHidingEnabledFlag() ) |
3990 | 0 | { |
3991 | 0 | X_READ_FLAG( sh_ts_residual_coding_disabled_flag ); |
3992 | 0 | pcSlice->setTSResidualCodingDisabledFlag( sh_ts_residual_coding_disabled_flag ); |
3993 | 0 | } |
3994 | | |
3995 | 4 | if( pps->getSliceHeaderExtensionPresentFlag() ) |
3996 | 0 | { |
3997 | 0 | X_READ_UVLC( sh_slice_header_extension_length, 0, 256 ); |
3998 | 0 | for( int i = 0; i < sh_slice_header_extension_length; i++ ) |
3999 | 0 | { |
4000 | 0 | X_READ_CODE_NO_RANGE_idx( sh_slice_header_extension_data_byte, "[ i ]", 8 ); |
4001 | 0 | (void) sh_slice_header_extension_data_byte; |
4002 | 0 | } |
4003 | 0 | } |
4004 | | |
4005 | 4 | std::vector<uint32_t> entryPointOffset; |
4006 | 4 | pcSlice->setNumEntryPoints( sps, pps ); |
4007 | 4 | if( pcSlice->getNumEntryPoints() > 0 ) |
4008 | 0 | { |
4009 | 0 | entryPointOffset.resize( pcSlice->getNumEntryPoints() ); |
4010 | |
|
4011 | 0 | X_READ_UVLC( sh_entry_offset_len_minus1, 0, 31 ); |
4012 | 0 | for( uint32_t idx = 0; idx < pcSlice->getNumEntryPoints(); idx++ ) |
4013 | 0 | { |
4014 | 0 | X_READ_CODE_NO_RANGE_idx( sh_entry_point_offset_minus1, "[i]", sh_entry_offset_len_minus1 + 1 ); |
4015 | 0 | entryPointOffset[idx] = sh_entry_point_offset_minus1 + 1; |
4016 | 0 | } |
4017 | 0 | } |
4018 | | |
4019 | | #if RExt__DECODER_DEBUG_BIT_STATISTICS |
4020 | | CodingStatistics::IncrementStatisticEP(STATS__BYTE_ALIGNMENT_BITS,m_pcBitstream->readByteAlignment(),0); |
4021 | | #else |
4022 | 4 | m_pcBitstream->readByteAlignment(); |
4023 | 4 | #endif |
4024 | | |
4025 | | |
4026 | 4 | if( pcSlice->getFirstCtuRsAddrInSlice() == 0 ) |
4027 | 0 | { |
4028 | 0 | pcSlice->setDefaultClpRng( *sps ); |
4029 | 0 | } |
4030 | | |
4031 | 4 | pcSlice->clearSubstreamSizes(); |
4032 | | |
4033 | 4 | if( pcSlice->getNumEntryPoints() > 0 ) |
4034 | 0 | { |
4035 | 0 | int endOfSliceHeaderLocation = m_pcBitstream->getByteLocation(); |
4036 | | |
4037 | | // Adjust endOfSliceHeaderLocation to account for emulation prevention bytes in the slice segment header |
4038 | 0 | for( uint32_t curByteIdx = 0; curByteIdx < m_pcBitstream->numEmulationPreventionBytesRead(); curByteIdx++ ) |
4039 | 0 | { |
4040 | 0 | if( m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) < endOfSliceHeaderLocation ) |
4041 | 0 | { |
4042 | 0 | endOfSliceHeaderLocation++; |
4043 | 0 | } |
4044 | 0 | } |
4045 | |
|
4046 | 0 | uint32_t prevEntryPoint = 0; |
4047 | 0 | for( uint32_t idx = 0; idx < entryPointOffset.size(); idx++ ) |
4048 | 0 | { |
4049 | 0 | const uint32_t currEntryPoint = prevEntryPoint + entryPointOffset[idx]; |
4050 | |
|
4051 | 0 | int emulationPreventionByteCount = 0; |
4052 | 0 | for( uint32_t curByteIdx = 0; curByteIdx < m_pcBitstream->numEmulationPreventionBytesRead(); curByteIdx++ ) |
4053 | 0 | { |
4054 | 0 | if( m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) >= prevEntryPoint + endOfSliceHeaderLocation |
4055 | 0 | && m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) < currEntryPoint + endOfSliceHeaderLocation ) |
4056 | 0 | { |
4057 | 0 | emulationPreventionByteCount++; |
4058 | 0 | } |
4059 | 0 | } |
4060 | |
|
4061 | 0 | entryPointOffset[idx] -= emulationPreventionByteCount; |
4062 | |
|
4063 | 0 | prevEntryPoint = currEntryPoint; |
4064 | 0 | } |
4065 | |
|
4066 | 0 | pcSlice->setSubstreamSizes( std::move( entryPointOffset ) ); |
4067 | 0 | } |
4068 | 4 | } |
4069 | | |
4070 | | template<typename HeaderT> |
4071 | | void HLSyntaxReader::parsePicOrSliceHeaderRPL( HeaderT* header, const SPS* sps, const PPS* pps ) |
4072 | 0 | { |
4073 | 0 | bool rplSpsFlag[2] = { false, false }; |
4074 | | |
4075 | | // List0 and List1 |
4076 | 0 | for( RefPicList listIdx: { REF_PIC_LIST_0, REF_PIC_LIST_1 } ) |
4077 | 0 | { |
4078 | 0 | const unsigned sps_num_ref_pic_lists_i = sps->getNumRPL( listIdx ); |
4079 | 0 | const bool pps_rpl1_idx_present_flag = pps->getRpl1IdxPresentFlag(); |
4080 | |
|
4081 | 0 | if( sps_num_ref_pic_lists_i > 0 && ( listIdx == 0 || ( listIdx == 1 && pps_rpl1_idx_present_flag ) ) ) |
4082 | 0 | { |
4083 | 0 | X_READ_FLAG_idx( ref_pic_list_sps_flag, "[i]" ); // rpl_sps_flag[i] in the standard |
4084 | 0 | rplSpsFlag[listIdx] = ref_pic_list_sps_flag; |
4085 | 0 | } |
4086 | 0 | else if( sps_num_ref_pic_lists_i == 0 ) |
4087 | 0 | { |
4088 | 0 | rplSpsFlag[listIdx] = false; |
4089 | 0 | } |
4090 | 0 | else if( sps_num_ref_pic_lists_i > 0 && !pps_rpl1_idx_present_flag && listIdx == REF_PIC_LIST_1 ) |
4091 | 0 | { |
4092 | 0 | rplSpsFlag[listIdx] = rplSpsFlag[0]; |
4093 | 0 | } |
4094 | |
|
4095 | 0 | if( rplSpsFlag[listIdx] ) |
4096 | 0 | { |
4097 | | // When rpl_sps_flag[ i ] is equal to 1 and sps_num_ref_pic_lists[ i ] is equal to 1, the value of rpl_idx[ i ] is inferred to be |
4098 | | // equal to 0. When rpl_sps_flag[ 1 ] is equal to 1, pps_rpl1_idx_present_flag is equal to 0, and sps_num_ref_pic_lists[ 1 ] |
4099 | | // is greater than 1, the value of rpl_idx[ 1 ] is inferred to be equal to rpl_idx[ 0 ]. |
4100 | 0 | int rpl_idx_i = 0; |
4101 | 0 | if( rplSpsFlag[listIdx] && sps_num_ref_pic_lists_i == 1 ) |
4102 | 0 | { |
4103 | 0 | rpl_idx_i = 0; |
4104 | 0 | } |
4105 | 0 | else if( listIdx == REF_PIC_LIST_1 && rplSpsFlag[1] && !pps_rpl1_idx_present_flag && sps->getNumRPL( REF_PIC_LIST_1 ) > 1 ) |
4106 | 0 | { |
4107 | 0 | rpl_idx_i = header->getRPLIdx( REF_PIC_LIST_0 ); |
4108 | 0 | } |
4109 | |
|
4110 | 0 | if( sps_num_ref_pic_lists_i > 1 && ( listIdx == REF_PIC_LIST_0 || ( listIdx == REF_PIC_LIST_1 && pps_rpl1_idx_present_flag ) ) ) |
4111 | 0 | { |
4112 | 0 | int numBits = std::ceil( std::log2( sps_num_ref_pic_lists_i ) ); |
4113 | 0 | X_READ_CODE_idx( ref_pic_list_idx, "[ listIdx ]", numBits, 0, sps_num_ref_pic_lists_i - 1 ); // rpl_idx[i] in the standard |
4114 | 0 | rpl_idx_i = ref_pic_list_idx; |
4115 | 0 | } |
4116 | |
|
4117 | 0 | CHECK( rpl_idx_i < 0 || rpl_idx_i > (int) sps_num_ref_pic_lists_i - 1, |
4118 | 0 | "The value of rpl_idx[ i ] shall be in the range of 0 to sps_num_ref_pic_lists[ i ] - 1, inclusive." ); |
4119 | |
|
4120 | 0 | header->setRPL( listIdx, sps->getRPLList( listIdx )[rpl_idx_i] ); |
4121 | 0 | header->setRPLIdx( listIdx, rpl_idx_i ); |
4122 | 0 | } |
4123 | 0 | else |
4124 | 0 | { |
4125 | 0 | header->clearRPL( listIdx ); |
4126 | 0 | parseRefPicList( header->getRPL( listIdx ), -1, sps ); // ref_pic_list_struct( i, sps_num_ref_pic_lists[ i ] ) |
4127 | 0 | header->setRPLIdx( listIdx, -1 ); |
4128 | 0 | } |
4129 | | |
4130 | 0 | if( std::is_same<HeaderT, PicHeader>::value ) // The contained CHECK is only valid, when we are in a PicHeader. |
4131 | 0 | { |
4132 | | // The reinterpret_cast<> is a no-op, but it's needed for compilation. It's never executed in the case, when HeaderT is not a PicHeader due to the |
4133 | | // surrounding if-condition |
4134 | 0 | CHECK( pps->getRplInfoInPhFlag() && reinterpret_cast<PicHeader*>( header )->getPicInterSliceAllowedFlag() |
4135 | 0 | && header->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() <= 0, |
4136 | 0 | "When pps_rpl_info_in_ph_flag is equal to 1 and ph_inter_slice_allowed_flag is equal to 1, the value of" |
4137 | 0 | " num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] shall be greater than 0." ) |
4138 | 0 | } |
4139 | | |
4140 | | // Deal POC Msb cycle signalling for LTRP |
4141 | 0 | auto* rpl = header->getRPL( listIdx ); |
4142 | 0 | for( int j = 0; j < rpl->getNumRefEntries(); ++j ) |
4143 | 0 | { |
4144 | 0 | if( !rpl->isRefPicLongterm( j ) ) |
4145 | 0 | { |
4146 | 0 | continue; |
4147 | 0 | } |
4148 | | |
4149 | 0 | if( rpl->getLtrpInSliceHeaderFlag() ) |
4150 | 0 | { |
4151 | 0 | X_READ_CODE_NO_RANGE_idx( poc_lsb_lt, "[i][j]", sps->getBitsForPOC() ); |
4152 | 0 | rpl->setRefPicIdentifier( j, poc_lsb_lt, true, false, 0 ); |
4153 | 0 | } |
4154 | |
|
4155 | 0 | X_READ_FLAG_idx( delta_poc_msb_cycle_present_flag, "[i][j]" ); |
4156 | 0 | rpl->setDeltaPocMSBPresentFlag( j, delta_poc_msb_cycle_present_flag ); |
4157 | |
|
4158 | 0 | if( delta_poc_msb_cycle_present_flag ) |
4159 | 0 | { |
4160 | 0 | X_READ_UVLC( delta_poc_msb_cycle_lt, 0, 1 << ( 32 - sps->getBitsForPOC() ) ); |
4161 | 0 | rpl->setDeltaPocMSBCycleLT( j, delta_poc_msb_cycle_lt ); |
4162 | 0 | } |
4163 | 0 | } |
4164 | 0 | } |
4165 | 0 | } Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePicOrSliceHeaderRPL<vvdec::PicHeader>(vvdec::PicHeader*, vvdec::SPS const*, vvdec::PPS const*) Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePicOrSliceHeaderRPL<vvdec::Slice>(vvdec::Slice*, vvdec::SPS const*, vvdec::PPS const*) |
4166 | | |
4167 | | void HLSyntaxReader::parseConstraintInfo( ConstraintInfo *cinfo ) |
4168 | 78 | { |
4169 | 78 | uint32_t symbol; |
4170 | 78 | READ_FLAG( symbol, "gci_present_flag" ); cinfo->setGciPresentFlag( symbol ? true : false ); |
4171 | 78 | if( cinfo->getGciPresentFlag() ) |
4172 | 32 | { |
4173 | | /* general */ |
4174 | 32 | READ_FLAG( symbol, "gci_intra_only_constraint_flag" ); cinfo->setIntraOnlyConstraintFlag( symbol ? true : false ); |
4175 | 32 | READ_FLAG( symbol, "gci_all_layers_independent_constraint_flag" ); cinfo->setAllLayersIndependentConstraintFlag( symbol ? true : false ); |
4176 | 32 | READ_FLAG( symbol, "gci_one_au_only_constraint_flag" ); cinfo->setOnePictureOnlyConstraintFlag( symbol ? true : false ); |
4177 | | |
4178 | | /* picture format */ |
4179 | 32 | READ_CODE( 4, symbol, "gci_sixteen_minus_max_bitdepth_constraint_idc" ); cinfo->setMaxBitDepthConstraintIdc( symbol>8 ? 16 : ( 16 - symbol ) ); |
4180 | 32 | CHECK(symbol>8, "gci_sixteen_minus_max_bitdepth_constraint_idc shall be in the range 0 to 8, inclusive"); |
4181 | 30 | READ_CODE( 2, symbol, "gci_three_minus_max_chroma_format_constraint_idc" ); |
4182 | 30 | cinfo->setMaxChromaFormatConstraintIdc( (ChromaFormat)( 3 - symbol ) ); |
4183 | | |
4184 | | /* NAL unit type related */ |
4185 | 30 | READ_FLAG( symbol, "gci_no_mixed_nalu_types_in_pic_constraint_flag" ); cinfo->setNoMixedNaluTypesInPicConstraintFlag( symbol > 0 ? true : false ); |
4186 | 30 | READ_FLAG( symbol, "gci_no_trail_constraint_flag" ); cinfo->setNoTrailConstraintFlag( symbol > 0 ? true : false ); |
4187 | 30 | READ_FLAG( symbol, "gci_no_stsa_constraint_flag" ); cinfo->setNoStsaConstraintFlag( symbol > 0 ? true : false ); |
4188 | 30 | READ_FLAG( symbol, "gci_no_rasl_constraint_flag" ); cinfo->setNoRaslConstraintFlag( symbol > 0 ? true : false ); |
4189 | 30 | READ_FLAG( symbol, "gci_no_radl_constraint_flag" ); cinfo->setNoRadlConstraintFlag( symbol > 0 ? true : false ); |
4190 | 30 | READ_FLAG( symbol, "gci_no_idr_constraint_flag" ); cinfo->setNoIdrConstraintFlag( symbol > 0 ? true : false ); |
4191 | 30 | READ_FLAG( symbol, "gci_no_cra_constraint_flag" ); cinfo->setNoCraConstraintFlag( symbol > 0 ? true : false ); |
4192 | 30 | READ_FLAG( symbol, "gci_no_gdr_constraint_flag" ); cinfo->setNoGdrConstraintFlag( symbol > 0 ? true : false ); |
4193 | 30 | READ_FLAG( symbol, "gci_no_aps_constraint_flag" ); cinfo->setNoApsConstraintFlag( symbol > 0 ? true : false ); |
4194 | 30 | READ_FLAG( symbol, "gci_no_idr_rpl_constraint_flag" ); cinfo->setNoIdrRplConstraintFlag( symbol > 0 ? true : false ); |
4195 | | |
4196 | | /* tile, slice, subpicture partitioning */ |
4197 | 30 | READ_FLAG( symbol, "gci_one_tile_per_pic_constraint_flag" ); cinfo->setOneTilePerPicConstraintFlag( symbol > 0 ? true : false ); |
4198 | 30 | READ_FLAG( symbol, "gci_pic_header_in_slice_header_constraint_flag" ); cinfo->setPicHeaderInSliceHeaderConstraintFlag( symbol > 0 ? true : false ); |
4199 | 30 | READ_FLAG( symbol, "gci_one_slice_per_pic_constraint_flag" ); cinfo->setOneSlicePerPicConstraintFlag( symbol > 0 ? true : false ); |
4200 | 30 | READ_FLAG( symbol, "gci_no_rectangular_slice_constraint_flag" ); cinfo->setNoRectSliceConstraintFlag( symbol > 0 ? true : false ); |
4201 | 30 | READ_FLAG( symbol, "gci_one_slice_per_subpic_constraint_flag" ); cinfo->setOneSlicePerSubpicConstraintFlag( symbol > 0 ? true : false ); |
4202 | 30 | READ_FLAG( symbol, "gci_no_subpic_info_constraint_flag" ); cinfo->setNoSubpicInfoConstraintFlag( symbol > 0 ? true : false ); |
4203 | | |
4204 | | /* CTU and block partitioning */ |
4205 | 30 | READ_CODE( 2, symbol, "gci_three_minus_max_log2_ctu_size_constraint_idc"); cinfo->setMaxLog2CtuSizeConstraintIdc( ( ( 3 - symbol ) + 5 ) ); |
4206 | 30 | READ_FLAG( symbol, "gci_no_partition_constraints_override_constraint_flag"); cinfo->setNoPartitionConstraintsOverrideConstraintFlag( symbol > 0 ? true : false ); |
4207 | 30 | READ_FLAG( symbol, "gci_no_mtt_constraint_flag"); cinfo->setNoMttConstraintFlag( symbol > 0 ? true : false); |
4208 | 30 | READ_FLAG( symbol, "gci_no_qtbtt_dual_tree_intra_constraint_flag"); cinfo->setNoQtbttDualTreeIntraConstraintFlag( symbol > 0 ? true : false ); |
4209 | | |
4210 | | /* intra */ |
4211 | 30 | READ_FLAG( symbol, "gci_no_palette_constraint_flag" ); cinfo->setNoPaletteConstraintFlag( symbol > 0 ? true : false ); |
4212 | 30 | READ_FLAG( symbol, "gci_no_ibc_constraint_flag" ); cinfo->setNoIbcConstraintFlag( symbol > 0 ? true : false ); |
4213 | 30 | READ_FLAG( symbol, "gci_no_isp_constraint_flag" ); cinfo->setNoIspConstraintFlag( symbol > 0 ? true : false ); |
4214 | 30 | READ_FLAG( symbol, "gci_no_mrl_constraint_flag" ); cinfo->setNoMrlConstraintFlag( symbol > 0 ? true : false ); |
4215 | 30 | READ_FLAG( symbol, "gci_no_mip_constraint_flag" ); cinfo->setNoMipConstraintFlag( symbol > 0 ? true : false ); |
4216 | 30 | READ_FLAG( symbol, "gci_no_cclm_constraint_flag" ); cinfo->setNoCclmConstraintFlag( symbol > 0 ? true : false ); |
4217 | | |
4218 | | /* inter */ |
4219 | 30 | READ_FLAG( symbol, "gci_no_ref_pic_resampling_constraint_flag" ); cinfo->setNoRprConstraintFlag( symbol > 0 ? true : false ); |
4220 | 30 | READ_FLAG( symbol, "gci_no_res_change_in_clvs_constraint_flag" ); cinfo->setNoResChangeInClvsConstraintFlag( symbol > 0 ? true : false ); |
4221 | 30 | READ_FLAG( symbol, "gci_no_weighted_prediction_constraint_flag" ); cinfo->setNoWeightedPredictionConstraintFlag( symbol > 0 ? true : false ); |
4222 | 30 | READ_FLAG( symbol, "gci_no_ref_wraparound_constraint_flag" ); cinfo->setNoRefWraparoundConstraintFlag( symbol > 0 ? true : false ); |
4223 | 30 | READ_FLAG( symbol, "gci_no_temporal_mvp_constraint_flag" ); cinfo->setNoTemporalMvpConstraintFlag( symbol > 0 ? true : false ); |
4224 | 30 | READ_FLAG( symbol, "gci_no_sbtmvp_constraint_flag" ); cinfo->setNoSbtmvpConstraintFlag( symbol > 0 ? true : false ); |
4225 | 30 | READ_FLAG( symbol, "gci_no_amvr_constraint_flag" ); cinfo->setNoAmvrConstraintFlag( symbol > 0 ? true : false ); |
4226 | 30 | READ_FLAG( symbol, "gci_no_bdof_constraint_flag" ); cinfo->setNoBdofConstraintFlag( symbol > 0 ? true : false ); |
4227 | 30 | READ_FLAG( symbol, "gci_no_smvd_constraint_flag" ); cinfo->setNoSmvdConstraintFlag( symbol > 0 ? true : false ); |
4228 | 30 | READ_FLAG( symbol, "gci_no_dmvr_constraint_flag" ); cinfo->setNoDmvrConstraintFlag( symbol > 0 ? true : false ); |
4229 | 30 | READ_FLAG( symbol, "gci_no_mmvd_constraint_flag" ); cinfo->setNoMmvdConstraintFlag( symbol > 0 ? true : false ); |
4230 | 30 | READ_FLAG( symbol, "gci_no_affine_motion_constraint_flag" ); cinfo->setNoAffineMotionConstraintFlag( symbol > 0 ? true : false ); |
4231 | 30 | READ_FLAG( symbol, "gci_no_prof_constraint_flag" ); cinfo->setNoProfConstraintFlag( symbol > 0 ? true : false ); |
4232 | 30 | READ_FLAG( symbol, "gci_no_bcw_constraint_flag" ); cinfo->setNoBcwConstraintFlag( symbol > 0 ? true : false ); |
4233 | 30 | READ_FLAG( symbol, "gci_no_ciip_constraint_flag" ); cinfo->setNoCiipConstraintFlag( symbol > 0 ? true : false ); |
4234 | 30 | READ_FLAG( symbol, "gci_no_gpm_constraint_flag" ); cinfo->setNoGeoConstraintFlag( symbol > 0 ? true : false ); |
4235 | | |
4236 | | /* transform, quantization, residual */ |
4237 | 30 | READ_FLAG( symbol, "gci_no_luma_transform_size_64_constraint_flag" ); cinfo->setNoLumaTransformSize64ConstraintFlag( symbol > 0 ? true : false ); |
4238 | 30 | READ_FLAG( symbol, "gci_no_transform_skip_constraint_flag" ); cinfo->setNoTransformSkipConstraintFlag( symbol > 0 ? true : false ); |
4239 | 30 | READ_FLAG( symbol, "gci_no_bdpcm_constraint_flag" ); cinfo->setNoBDPCMConstraintFlag( symbol > 0 ? true : false ); |
4240 | 30 | READ_FLAG( symbol, "gci_no_mts_constraint_flag" ); cinfo->setNoMtsConstraintFlag( symbol > 0 ? true : false ); |
4241 | 30 | READ_FLAG( symbol, "gci_no_lfnst_constraint_flag" ); cinfo->setNoLfnstConstraintFlag( symbol > 0 ? true : false ); |
4242 | 30 | READ_FLAG( symbol, "gci_no_joint_cbcr_constraint_flag" ); cinfo->setNoJointCbCrConstraintFlag( symbol > 0 ? true : false ); |
4243 | 30 | READ_FLAG( symbol, "gci_no_sbt_constraint_flag" ); cinfo->setNoSbtConstraintFlag( symbol > 0 ? true : false ); |
4244 | 30 | READ_FLAG( symbol, "gci_no_act_constraint_flag" ); cinfo->setNoActConstraintFlag( symbol > 0 ? true : false ); |
4245 | 30 | READ_FLAG( symbol, "gci_no_explicit_scaling_list_constraint_flag" ); cinfo->setNoExplicitScaleListConstraintFlag( symbol > 0 ? true : false ); |
4246 | 30 | READ_FLAG( symbol, "gci_no_dep_quant_constraint_flag" ); cinfo->setNoDepQuantConstraintFlag( symbol > 0 ? true : false ); |
4247 | 30 | READ_FLAG( symbol, "gci_no_sign_data_hiding_constraint_flag" ); cinfo->setNoSignDataHidingConstraintFlag( symbol > 0 ? true : false) ; |
4248 | 30 | READ_FLAG( symbol, "gci_no_cu_qp_delta_constraint_flag" ); cinfo->setNoQpDeltaConstraintFlag( symbol > 0 ? true : false ); |
4249 | 30 | READ_FLAG( symbol, "gci_no_chroma_qp_offset_constraint_flag" ); cinfo->setNoChromaQpOffsetConstraintFlag( symbol > 0 ? true : false ); |
4250 | | |
4251 | | /* loop filter */ |
4252 | 30 | READ_FLAG( symbol, "gci_no_sao_constraint_flag" ); cinfo->setNoSaoConstraintFlag( symbol > 0 ? true : false ); |
4253 | 30 | READ_FLAG( symbol, "gci_no_alf_constraint_flag" ); cinfo->setNoAlfConstraintFlag( symbol > 0 ? true : false ); |
4254 | 30 | READ_FLAG( symbol, "gci_no_ccalf_constraint_flag" ); cinfo->setNoCCAlfConstraintFlag( symbol > 0 ? true : false ); |
4255 | 30 | READ_FLAG( symbol, "gci_no_lmcs_constraint_flag" ); cinfo->setNoLmcsConstraintFlag( symbol > 0 ? true : false ); |
4256 | 30 | READ_FLAG( symbol, "gci_no_ladf_constraint_flag" ); cinfo->setNoLadfConstraintFlag( symbol > 0 ? true : false ); |
4257 | 30 | READ_FLAG( symbol, "gci_no_virtual_boundaries_constraint_flag" ); cinfo->setNoVirtualBoundaryConstraintFlag( symbol > 0 ? true : false ); |
4258 | | |
4259 | 30 | READ_CODE( 8, symbol, "gci_num_reserved_bits" ); |
4260 | 30 | uint32_t const numReservedBits = symbol; |
4261 | 50 | for (int i = 0; i < numReservedBits; i++) |
4262 | 28 | { |
4263 | 28 | READ_FLAG( symbol, "gci_reserved_zero_bit" ); CHECK( symbol != 0, "gci_reserved_zero_bit not equal to zero" ); |
4264 | 20 | } |
4265 | 30 | } |
4266 | 340 | while( !isByteAligned() ) |
4267 | 280 | { |
4268 | 280 | READ_FLAG( symbol, "gci_alignment_zero_bit" ); CHECK( symbol != 0, "gci_alignment_zero_bit not equal to zero" ); |
4269 | 272 | } |
4270 | 68 | } |
4271 | | |
4272 | | |
4273 | | void HLSyntaxReader::parseProfileTierLevel( ProfileTierLevel *ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1 ) |
4274 | 90 | { |
4275 | 90 | if( profileTierPresentFlag ) |
4276 | 90 | { |
4277 | 90 | X_READ_CODE_NO_RANGE( general_profile_idc, 7 ); |
4278 | 90 | ptl->setProfileIdc( Profile::Name( general_profile_idc ) ); |
4279 | | |
4280 | 90 | X_READ_FLAG( general_tier_flag ); |
4281 | 90 | ptl->setTierFlag( general_tier_flag ? Tier::HIGH : Tier::MAIN ); |
4282 | 90 | } |
4283 | | |
4284 | 90 | X_READ_CODE_NO_RANGE( general_level_idc, 8 ); |
4285 | 90 | ptl->setLevelIdc( vvdecLevel( general_level_idc ) ); |
4286 | | |
4287 | 90 | X_READ_FLAG( ptl_frame_only_constraint_flag ); |
4288 | 90 | ptl->setFrameOnlyConstraintFlag( ptl_frame_only_constraint_flag ); |
4289 | | |
4290 | 90 | X_READ_FLAG( ptl_multilayer_enabled_flag ); |
4291 | 90 | ptl->setMultiLayerEnabledFlag( ptl_multilayer_enabled_flag ); |
4292 | | |
4293 | 90 | CHECK( ( ptl->getProfileIdc() == Profile::MAIN_10 || ptl->getProfileIdc() == Profile::MAIN_10_444 |
4294 | 90 | || ptl->getProfileIdc() == Profile::MAIN_10_STILL_PICTURE |
4295 | 90 | || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE ) |
4296 | 90 | && ptl_multilayer_enabled_flag, |
4297 | 90 | "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles"); |
4298 | | |
4299 | 86 | CHECK_UNSUPPORTED( ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_STILL_PICTURE || |
4300 | 86 | ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE, |
4301 | 86 | "Multilayer profiles not yet supported" ); |
4302 | | |
4303 | 80 | if( ptl->getProfileIdc() == Profile::MAIN_10_444 || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE ) |
4304 | 2 | { |
4305 | 2 | msg( WARNING, "Warning: MAIN_10_444 and MAIN_10_444_STILL_PICTURE is still experimental.\n" ); |
4306 | 2 | } |
4307 | | |
4308 | 80 | if( profileTierPresentFlag ) |
4309 | 78 | { |
4310 | 78 | parseConstraintInfo( ptl->getConstraintInfo() ); |
4311 | 78 | } |
4312 | | |
4313 | 226 | for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- ) |
4314 | 146 | { |
4315 | 146 | X_READ_FLAG_idx( sub_layer_level_present_flag, "[i]" ); |
4316 | 146 | ptl->setSubLayerLevelPresentFlag( i, sub_layer_level_present_flag ); |
4317 | 146 | } |
4318 | | |
4319 | 158 | while( !isByteAligned() ) |
4320 | 78 | { |
4321 | 78 | X_READ_FLAG( ptl_reserved_zero_bit ); |
4322 | 78 | CHECK_WARN( ptl_reserved_zero_bit != 0, "ptl_reserved_zero_bit not equal to zero" ); |
4323 | 78 | } |
4324 | | |
4325 | 80 | ptl->setSubLayerLevelIdc( maxNumSubLayersMinus1, ptl->getLevelIdc() ); |
4326 | 226 | for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- ) |
4327 | 146 | { |
4328 | 146 | if( ptl->getSubLayerLevelPresentFlag( i ) ) |
4329 | 26 | { |
4330 | 26 | X_READ_CODE_NO_RANGE_idx( sub_layer_level_idc, "[i]", 8 ); |
4331 | 26 | ptl->setSubLayerLevelIdc( i, vvdecLevel( sub_layer_level_idc ) ); |
4332 | 26 | } |
4333 | 120 | else |
4334 | 120 | { |
4335 | 120 | ptl->setSubLayerLevelIdc( i, ptl->getSubLayerLevelIdc( i + 1 ) ); |
4336 | 120 | } |
4337 | 146 | } |
4338 | | |
4339 | 80 | if( profileTierPresentFlag ) |
4340 | 52 | { |
4341 | 52 | X_READ_CODE_NO_RANGE( ptl_num_sub_profiles, 8 ); |
4342 | 52 | ptl->setNumSubProfile( ptl_num_sub_profiles ); |
4343 | | |
4344 | 102 | for( int i = 0; i < ptl_num_sub_profiles; i++ ) |
4345 | 50 | { |
4346 | 50 | X_READ_CODE_NO_RANGE_idx( general_sub_profile_idc, "[i]", 32 ); |
4347 | 50 | ptl->setSubProfileIdc( i, general_sub_profile_idc ); |
4348 | 50 | } |
4349 | 52 | } |
4350 | 80 | } |
4351 | | |
4352 | | |
4353 | | // ==================================================================================================================== |
4354 | | // Protected member functions |
4355 | | // ==================================================================================================================== |
4356 | | |
4357 | | //! parse explicit wp tables |
4358 | | template<typename HeaderT> |
4359 | | void HLSyntaxReader::parsePredWeightTable( HeaderT* sh_or_ph, const SPS* sps, const PPS* pps, std::array<int, 2> numRefIdxActive ) |
4360 | 0 | { |
4361 | 0 | const bool bChroma = sps->getChromaFormatIdc() != CHROMA_400; |
4362 | 0 | const bool pps_wp_info_in_ph_flag = pps->getWpInfoInPhFlag(); |
4363 | 0 | const bool pps_weighted_bipred_flag = pps->getWPBiPred(); |
4364 | |
|
4365 | 0 | uint32_t log2WeightDenomChroma = 0; |
4366 | 0 | uint32_t sumWeightFlags = 0; |
4367 | |
|
4368 | 0 | X_READ_UVLC( luma_log2_weight_denom, 0, 7 ); |
4369 | 0 | if( bChroma ) |
4370 | 0 | { |
4371 | 0 | X_READ_SVLC_NO_RANGE( delta_chroma_log2_weight_denom ); |
4372 | 0 | CHECK_READ_RANGE( luma_log2_weight_denom + delta_chroma_log2_weight_denom, 0, 7, "luma_log2_weight_denom + delta_chroma_log2_weight_denom" ) |
4373 | | |
4374 | 0 | log2WeightDenomChroma = luma_log2_weight_denom + delta_chroma_log2_weight_denom; |
4375 | 0 | } |
4376 | | |
4377 | 0 | for( auto& l: { REF_PIC_LIST_0, REF_PIC_LIST_1 } ) |
4378 | 0 | { |
4379 | 0 | const int num_ref_entries = sh_or_ph->getRPL( l )->getNumRefEntries(); |
4380 | |
|
4381 | 0 | unsigned numWeights = numRefIdxActive[l]; |
4382 | 0 | if( l == REF_PIC_LIST_0 ) |
4383 | 0 | { |
4384 | | // derive NumWeightsL0 |
4385 | 0 | if( pps_wp_info_in_ph_flag ) |
4386 | 0 | { |
4387 | 0 | X_READ_UVLC( num_l0_weights, 1, std::min<unsigned>( 15, num_ref_entries ) ); |
4388 | 0 | numWeights = num_l0_weights; |
4389 | |
|
4390 | 0 | CHECK( ( !std::is_same<HeaderT, PicHeader>::value ), |
4391 | 0 | "Implementation error: parsePredWeightTable() should not be called with a Slice, when pps_wp_info_in_ph_flag is true." ); |
4392 | 0 | if( std::is_same<HeaderT, PicHeader>::value ) |
4393 | 0 | { |
4394 | | // We know HeaderT is a PicHeader, so we use reinterpret_cast here just so it compiles for the HeaderT==Slice case. |
4395 | 0 | reinterpret_cast<PicHeader*>( sh_or_ph )->setNumL0Weights( num_l0_weights ); |
4396 | 0 | } |
4397 | 0 | } |
4398 | 0 | } |
4399 | 0 | else if( l == REF_PIC_LIST_1 ) |
4400 | 0 | { |
4401 | | // The variable NumWeightsL1 is derived as follows (semantics section): |
4402 | 0 | if( !pps_weighted_bipred_flag || ( pps_wp_info_in_ph_flag && num_ref_entries == 0 ) ) |
4403 | 0 | { |
4404 | 0 | numWeights = 0; |
4405 | 0 | } |
4406 | 0 | else if( pps_weighted_bipred_flag ) // condition from semantics section |
4407 | 0 | { |
4408 | | // What should numWeights be set, when pps_weighted_bipred_flag && !pps_wp_info_in_ph_flag && num_ref_entries > 0 ? |
4409 | | // According to the syntax section num_l1_weights isn't read, but the semantics says, we should set NumWeightsL1 = num_l1_weights. |
4410 | | // It seems to work, when we leave numWeights set to NumRefIdxActive[ 1 ]. |
4411 | | //CHECK( pps_weighted_bipred_flag && !pps_wp_info_in_ph_flag && num_ref_entries > 0, |
4412 | | // "don't know how to set NumWeightsL1: it's missing from the spec" ); |
4413 | |
|
4414 | 0 | if( pps_weighted_bipred_flag && pps_wp_info_in_ph_flag && num_ref_entries > 0 ) // condition from syntax section |
4415 | 0 | { |
4416 | 0 | X_READ_UVLC( num_l1_weights, 1, std::min<unsigned>( 15, num_ref_entries ) ); |
4417 | 0 | numWeights = num_l1_weights; |
4418 | |
|
4419 | 0 | CHECK( ( !std::is_same<HeaderT, PicHeader>::value ), |
4420 | 0 | "Implementation error: parsePredWeightTable() should not be called with a Slice, when pps_wp_info_in_ph_flag is true." ); |
4421 | 0 | if( std::is_same<HeaderT, PicHeader>::value ) |
4422 | 0 | { |
4423 | | // We know HeaderT is a PicHeader, so we use reinterpret_cast here just so it compiles for the HeaderT==Slice case. |
4424 | 0 | reinterpret_cast<PicHeader*>( sh_or_ph )->setNumL1Weights( num_l1_weights ); |
4425 | 0 | } |
4426 | 0 | } |
4427 | 0 | } |
4428 | 0 | } |
4429 | | |
4430 | 0 | for( int i = 0; i < numWeights; i++ ) |
4431 | 0 | { |
4432 | 0 | WPScalingParam* wp; |
4433 | 0 | sh_or_ph->getWpScaling( l, i, wp ); |
4434 | |
|
4435 | 0 | X_READ_FLAG_idx( luma_weight_lX_flag, "[i]" ); |
4436 | 0 | wp[COMPONENT_Y].bPresentFlag = luma_weight_lX_flag; |
4437 | 0 | wp[COMPONENT_Y].uiLog2WeightDenom = luma_log2_weight_denom; |
4438 | |
|
4439 | 0 | sumWeightFlags += luma_weight_lX_flag; |
4440 | 0 | } |
4441 | |
|
4442 | 0 | if( bChroma ) |
4443 | 0 | { |
4444 | 0 | for( int i = 0; i < numWeights; i++ ) |
4445 | 0 | { |
4446 | 0 | WPScalingParam* wp; |
4447 | 0 | sh_or_ph->getWpScaling( l, i, wp ); |
4448 | |
|
4449 | 0 | X_READ_FLAG_idx( chroma_weight_lX_flag, "[i]" ); |
4450 | 0 | wp[COMPONENT_Cb].bPresentFlag = wp[COMPONENT_Cr].bPresentFlag = chroma_weight_lX_flag; |
4451 | 0 | wp[COMPONENT_Cb].uiLog2WeightDenom = wp[COMPONENT_Cr].uiLog2WeightDenom = log2WeightDenomChroma; |
4452 | |
|
4453 | 0 | sumWeightFlags += 2 * chroma_weight_lX_flag; |
4454 | 0 | } |
4455 | 0 | } |
4456 | |
|
4457 | 0 | for( int i = 0; i < numWeights; i++ ) |
4458 | 0 | { |
4459 | 0 | WPScalingParam* wp; |
4460 | 0 | sh_or_ph->getWpScaling( l, i, wp ); |
4461 | |
|
4462 | 0 | wp[COMPONENT_Y].iWeight = ( 1 << wp[COMPONENT_Y].uiLog2WeightDenom ); |
4463 | 0 | wp[COMPONENT_Y].iOffset = 0; |
4464 | |
|
4465 | 0 | if( wp[COMPONENT_Y].bPresentFlag /*luma_weight_l0_flag[i]*/ ) |
4466 | 0 | { |
4467 | 0 | X_READ_SVLC_idx( delta_luma_weight_lX, "[i]", -128, 127 ); |
4468 | 0 | wp[COMPONENT_Y].iWeight += delta_luma_weight_lX; |
4469 | |
|
4470 | 0 | X_READ_SVLC_idx( luma_offset_lX, "[i]", -128, 127 ); |
4471 | 0 | wp[COMPONENT_Y].iOffset = luma_offset_lX; |
4472 | 0 | } |
4473 | |
|
4474 | 0 | for( int j = COMPONENT_Cb; j < MAX_NUM_COMPONENT; j++ ) |
4475 | 0 | { |
4476 | 0 | wp[j].iWeight = ( 1 << wp[j].uiLog2WeightDenom ); |
4477 | 0 | wp[j].iOffset = 0; |
4478 | 0 | if( wp[j].bPresentFlag /*chroma_weight_l0_flag[i]*/ ) |
4479 | 0 | { |
4480 | 0 | X_READ_SVLC_idx( delta_chroma_weight_lX, "[i][j]", -128, 127 ); |
4481 | 0 | wp[j].iWeight += delta_chroma_weight_lX; |
4482 | |
|
4483 | 0 | X_READ_SVLC_idx( delta_chroma_offset_lX, "[i][j]", -4 * 128, 4 * 127 ); |
4484 | 0 | wp[j].iOffset = Clip3( -128, 127, 128 + delta_chroma_offset_lX - ( ( 128 * wp[j].iWeight ) >> wp[j].uiLog2WeightDenom ) ); |
4485 | 0 | } |
4486 | 0 | } |
4487 | 0 | } |
4488 | |
|
4489 | 0 | for( int iRefIdx = numWeights; iRefIdx < MAX_NUM_REF; iRefIdx++ ) |
4490 | 0 | { |
4491 | 0 | WPScalingParam* wp; |
4492 | 0 | sh_or_ph->getWpScaling( l, iRefIdx, wp ); |
4493 | |
|
4494 | 0 | wp[0].bPresentFlag = false; |
4495 | 0 | wp[1].bPresentFlag = false; |
4496 | 0 | wp[2].bPresentFlag = false; |
4497 | 0 | } |
4498 | 0 | } |
4499 | | |
4500 | 0 | CHECK( sumWeightFlags > 24, |
4501 | 0 | "It is a requirement of bitstream conformance that, when sh_slice_type is equal to P, sumWeightL0Flags shall be less than" |
4502 | 0 | " or equal to 24 and when sh_slice_type is equal to B, the sum of sumWeightL0Flags and sumWeightL1Flags shall be less" |
4503 | 0 | " than or equal to 24." ); |
4504 | 0 | } Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePredWeightTable<vvdec::PicHeader>(vvdec::PicHeader*, vvdec::SPS const*, vvdec::PPS const*, std::__1::array<int, 2ul>) Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePredWeightTable<vvdec::Slice>(vvdec::Slice*, vvdec::SPS const*, vvdec::PPS const*, std::__1::array<int, 2ul>) |
4505 | | |
4506 | | /** decode quantization matrix |
4507 | | * \param scalingList quantization matrix information |
4508 | | */ |
4509 | | void HLSyntaxReader::parseScalingList( ScalingList *scalingList, bool aps_chromaPresentFlag ) |
4510 | 46 | { |
4511 | 46 | scalingList->reset(); |
4512 | | |
4513 | 924 | for( int id = 0; id < 28; id++ ) |
4514 | 878 | { |
4515 | 878 | if( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) ) |
4516 | 406 | { |
4517 | 406 | X_READ_FLAG( scaling_list_copy_mode_flag ); |
4518 | | |
4519 | 406 | bool scalingListPredModeFlag = false; |
4520 | 406 | if( !scaling_list_copy_mode_flag ) |
4521 | 60 | { |
4522 | 60 | X_READ_FLAG( scaling_list_pred_mode_flag ); |
4523 | 60 | scalingListPredModeFlag = scaling_list_pred_mode_flag; |
4524 | 60 | } |
4525 | | |
4526 | 406 | int scalingListPredIdDelta = 0; |
4527 | 406 | if( ( scaling_list_copy_mode_flag || scalingListPredModeFlag ) |
4528 | 370 | && id != SCALING_LIST_1D_START_2x2 && id != SCALING_LIST_1D_START_4x4 |
4529 | 326 | && id != SCALING_LIST_1D_START_8x8 ) // Copy Mode |
4530 | 290 | { |
4531 | 290 | const unsigned maxIdDelta = id < 2 ? id : ( id < 8 ? id - 2 : id - 8 ); |
4532 | 290 | X_READ_UVLC_idx( scaling_list_pred_id_delta, "[id]", 0, maxIdDelta ); |
4533 | | |
4534 | 290 | scalingListPredIdDelta = scaling_list_pred_id_delta; |
4535 | 290 | } |
4536 | | |
4537 | 406 | decodeScalingList( scalingList, id, scalingListPredIdDelta, scaling_list_copy_mode_flag, scalingListPredModeFlag ); |
4538 | 406 | } // ( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) ) |
4539 | 878 | } |
4540 | | |
4541 | 46 | return; |
4542 | 46 | } |
4543 | | |
4544 | | void HLSyntaxReader::decodeScalingList( ScalingList* scalingList, uint32_t id, uint32_t scalingListPredIdDelta, bool scalingListCopyModeFlag , bool scalingListPredModeFlag) |
4545 | 398 | { |
4546 | 398 | const unsigned matrixSize = ScalingList::matrixSize( id ); |
4547 | | |
4548 | 398 | const int refId = id - scalingListPredIdDelta; |
4549 | 398 | CHECK( refId<0, "refId < 0 doesn't make sense" ); |
4550 | | |
4551 | 398 | int scalingMatrixDcPred = 0; |
4552 | 398 | auto& scalingMatrixPred = scalingList->getScalingListVec( id ); // we use the same storage for scalingMatrixPred and scalingMatrixRec |
4553 | 398 | { |
4554 | | // Derive scalingMatrixPred and scalingMatrixDcPred |
4555 | | |
4556 | 398 | const size_t scalingMatrixPred_size = matrixSize * matrixSize; |
4557 | 398 | CHECK( scalingMatrixPred_size != scalingList->getScalingListVec( id ).size(), "wrong scalingMatrixPred/Rec[] size" ) |
4558 | | |
4559 | 398 | if( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 ) |
4560 | 36 | { |
4561 | 36 | scalingMatrixPred.assign( scalingMatrixPred_size, 8 ); |
4562 | 36 | scalingMatrixDcPred = 8; |
4563 | 36 | } |
4564 | 362 | else if( scalingListPredIdDelta == 0 ) |
4565 | 330 | { |
4566 | 330 | scalingMatrixPred.assign( scalingMatrixPred_size, 16 ); |
4567 | 330 | scalingMatrixDcPred = 16; |
4568 | 330 | } |
4569 | 32 | else |
4570 | 32 | { |
4571 | 32 | CHECK( ( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 ) || scalingListPredIdDelta <= 0, |
4572 | 32 | "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and" |
4573 | 32 | " scaling_list_pred_id_delta[ id ] is greater than 0)," ); |
4574 | | |
4575 | 32 | CHECK( scalingListCopyModeFlag == 0 && ( scalingListPredModeFlag == 0 || scalingListPredIdDelta <= 0 ), |
4576 | 32 | "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and" |
4577 | 32 | " scaling_list_pred_id_delta[ id ] is greater than 0)," ); |
4578 | | |
4579 | | // scalingMatrixPred is set equal to ScalingMatrixRec[ refId ] |
4580 | 32 | scalingMatrixPred = scalingList->getScalingListVec( refId ); |
4581 | | |
4582 | 190 | #define MINUS_14 -( 14 * 0 ) // TODO: where did the -14 from the standard go ? when it is there, it breaks decoding. |
4583 | | |
4584 | 32 | scalingMatrixDcPred = refId > 13 ? scalingList->getScalingListDC( refId MINUS_14 ) : scalingList->getScalingListVec( id )[0]; |
4585 | 32 | } |
4586 | 398 | } |
4587 | | |
4588 | 398 | if( scalingListCopyModeFlag ) |
4589 | 340 | { |
4590 | | // When not present, the value of scaling_list_dc_coef[id − 14] is inferred to be equal to 0. |
4591 | 340 | if( id >= 14 ) |
4592 | 142 | { |
4593 | 142 | scalingList->setScalingListDC( id MINUS_14, scalingMatrixDcPred ); |
4594 | 142 | } |
4595 | 340 | return; |
4596 | 340 | } |
4597 | | |
4598 | 58 | const auto& DiagScanOrder = g_scanOrder[SCAN_UNGROUPED]; |
4599 | | |
4600 | 58 | int nextCoef = 0; |
4601 | 58 | if( id > 13 ) |
4602 | 28 | { |
4603 | 28 | X_READ_SVLC_idx( scaling_list_dc_coef, "[id-14]", -128, 127 ); |
4604 | 28 | nextCoef += scaling_list_dc_coef; |
4605 | | |
4606 | 28 | scalingList->setScalingListDC( id MINUS_14, ( scalingMatrixDcPred + scaling_list_dc_coef ) & 255 ); |
4607 | 28 | CHECK( scalingList->getScalingListDC( id MINUS_14 ) <= 0, "The value of ScalingMatrixDcRec[" << id MINUS_14 << "] shall be greater than 0." ) |
4608 | 28 | } |
4609 | | |
4610 | 1.19k | for( unsigned i = 0; i < matrixSize * matrixSize; i++ ) |
4611 | 1.14k | { |
4612 | 1.14k | const int numBits = g_sizeIdxInfo.idxFrom( matrixSize ); |
4613 | 1.14k | const int x = DiagScanOrder[3][3][i] & ( ( 1 << numBits ) - 1 ); |
4614 | 1.14k | const int y = DiagScanOrder[3][3][i] >> numBits; |
4615 | | |
4616 | 1.14k | if( !( id > 25 && x >= 4 && y >= 4 ) ) |
4617 | 1.01k | { |
4618 | 1.01k | X_READ_SVLC_idx( scaling_list_delta_coef, "[id][i]", -128, 127 ); |
4619 | 1.01k | nextCoef += scaling_list_delta_coef; |
4620 | 1.01k | } |
4621 | | |
4622 | 1.14k | int pos = DiagScanOrder[getLog2( matrixSize )][getLog2( matrixSize )][i]; |
4623 | | |
4624 | 1.14k | auto& scalingMatrixRec = scalingList->getScalingListVec( id ); |
4625 | 1.14k | scalingMatrixRec[pos] = ( scalingMatrixPred[pos] + nextCoef ) & 255; |
4626 | 1.14k | CHECK( scalingMatrixRec[pos] <= 0, "The value of ScalingMatrixRec[" << id << " ][x][y] shall be greater than 0." ) |
4627 | 1.14k | } |
4628 | 56 | } |
4629 | | bool HLSyntaxReader::xMoreRbspData() |
4630 | 3.58k | { |
4631 | 3.58k | int bitsLeft = m_pcBitstream->getNumBitsLeft(); |
4632 | | |
4633 | | // if there are more than 8 bits, it cannot be rbsp_trailing_bits |
4634 | 3.58k | if( bitsLeft > 8 ) |
4635 | 3.38k | { |
4636 | 3.38k | return true; |
4637 | 3.38k | } |
4638 | | |
4639 | 204 | uint8_t lastByte = m_pcBitstream->peekBits( bitsLeft ); |
4640 | 204 | int cnt = bitsLeft; |
4641 | | |
4642 | | // remove trailing bits equal to zero |
4643 | 438 | while( ( cnt > 0 ) && ( ( lastByte & 1 ) == 0 ) ) |
4644 | 234 | { |
4645 | 234 | lastByte >>= 1; |
4646 | 234 | cnt--; |
4647 | 234 | } |
4648 | | // remove bit equal to one |
4649 | 204 | cnt--; |
4650 | | |
4651 | | // we should not have a negative number of bits |
4652 | 204 | CHECK( cnt<0, "Negative number of bits") ; |
4653 | | |
4654 | | // we have more data, if cnt is not zero |
4655 | 202 | return ( cnt>0 ); |
4656 | 204 | } |
4657 | | |
4658 | | |
4659 | | void HLSyntaxReader::alfFilterCoeffs( AlfSliceParam& alfSliceParam, const bool isChroma, const int altIdx ) |
4660 | 46 | { |
4661 | 46 | const bool isLuma = !isChroma; |
4662 | | |
4663 | | // derive maxGolombIdx |
4664 | 46 | const int numCoeff = g_alfNumCoeff[isLuma]; |
4665 | 46 | const int numFilters = isLuma ? alfSliceParam.numLumaFilters : 1; |
4666 | 46 | short* coeff = isLuma ? alfSliceParam.lumaCoeff : alfSliceParam.chromaCoeff + altIdx * MAX_NUM_ALF_CHROMA_COEFF; |
4667 | 46 | short* clipp = isLuma ? alfSliceParam.lumaClipp : alfSliceParam.chromaClipp + altIdx * MAX_NUM_ALF_CHROMA_COEFF; |
4668 | | |
4669 | | // Filter coefficients |
4670 | 100 | for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx ) |
4671 | 60 | { |
4672 | 578 | for( int j = 0; j < numCoeff - 1; j++ ) |
4673 | 524 | { |
4674 | 524 | uint32_t code; |
4675 | 524 | READ_UVLC( code, isLuma ? "alf_luma_coeff_abs" : "alf_chroma_coeff_abs" ); |
4676 | 524 | CHECK_READ_RANGE( code, 0, 128, ( isLuma ? "alf_luma_coeff_abs[sfIdx][j]" : "alf_chroma_coeff_abs[sfIdx][j]" ) ); |
4677 | 518 | coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code; |
4678 | | |
4679 | 518 | if( code ) |
4680 | 136 | { |
4681 | 136 | READ_FLAG( code, isLuma ? "alf_luma_coeff_sign" : "alf_chroma_coeff_sign" ); |
4682 | | |
4683 | 136 | const int sign = code ? -1 : 1; |
4684 | 136 | coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] *= sign; |
4685 | | |
4686 | 136 | CHECK_READ_RANGE( coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j], |
4687 | 136 | -( 1 << 7 ), ( 1 << 7 ) - 1, |
4688 | 136 | ( isLuma ? "AlfLumaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" : "AlfChromaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" ) ); |
4689 | 136 | } |
4690 | 518 | } |
4691 | | |
4692 | 54 | const int factor = 1 << ( AdaptiveLoopFilter::m_NUM_BITS - 1 ); |
4693 | 54 | coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + numCoeff - 1] = factor; |
4694 | 54 | } |
4695 | | |
4696 | | // Clipping values coding |
4697 | 40 | bool alfClipFlag = isLuma ? alfSliceParam.nonLinearFlagLuma : alfSliceParam.nonLinearFlagChroma; |
4698 | 40 | if( alfClipFlag ) |
4699 | 14 | { |
4700 | | // Filter coefficients |
4701 | 28 | for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx ) |
4702 | 14 | { |
4703 | 182 | for( int j = 0; j < numCoeff - 1; j++ ) |
4704 | 168 | { |
4705 | 168 | uint32_t code; |
4706 | 168 | READ_CODE( 2, code, isLuma ? "alf_luma_clip_idx" : "alf_chroma_clip_idx" ); |
4707 | 168 | clipp[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code; |
4708 | 168 | } |
4709 | 14 | } |
4710 | 14 | } |
4711 | 40 | } |
4712 | | |
4713 | | } // namespace vvdec |