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