xref: /aosp_15_r20/external/libgav1/src/obu_parser.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop //      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop 
15*09537850SAkhilesh Sanikop #include "src/obu_parser.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <algorithm>
18*09537850SAkhilesh Sanikop #include <array>
19*09537850SAkhilesh Sanikop #include <cassert>
20*09537850SAkhilesh Sanikop #include <climits>
21*09537850SAkhilesh Sanikop #include <cstddef>
22*09537850SAkhilesh Sanikop #include <cstdint>
23*09537850SAkhilesh Sanikop #include <cstring>
24*09537850SAkhilesh Sanikop #include <memory>
25*09537850SAkhilesh Sanikop 
26*09537850SAkhilesh Sanikop #include "src/buffer_pool.h"
27*09537850SAkhilesh Sanikop #include "src/decoder_impl.h"
28*09537850SAkhilesh Sanikop #include "src/motion_vector.h"
29*09537850SAkhilesh Sanikop #include "src/utils/common.h"
30*09537850SAkhilesh Sanikop #include "src/utils/logging.h"
31*09537850SAkhilesh Sanikop 
32*09537850SAkhilesh Sanikop namespace libgav1 {
33*09537850SAkhilesh Sanikop namespace {
34*09537850SAkhilesh Sanikop 
35*09537850SAkhilesh Sanikop // 5.9.16.
36*09537850SAkhilesh Sanikop // Find the smallest value of k such that block_size << k is greater than or
37*09537850SAkhilesh Sanikop // equal to target.
38*09537850SAkhilesh Sanikop //
39*09537850SAkhilesh Sanikop // NOTE: TileLog2(block_size, target) is equal to
40*09537850SAkhilesh Sanikop //   CeilLog2(ceil((double)target / block_size))
41*09537850SAkhilesh Sanikop // where the division is a floating-point number division. (This equality holds
42*09537850SAkhilesh Sanikop // even when |target| is equal to 0.) In the special case of block_size == 1,
43*09537850SAkhilesh Sanikop // TileLog2(1, target) is equal to CeilLog2(target).
TileLog2(int block_size,int target)44*09537850SAkhilesh Sanikop int TileLog2(int block_size, int target) {
45*09537850SAkhilesh Sanikop   int k = 0;
46*09537850SAkhilesh Sanikop   for (; (block_size << k) < target; ++k) {
47*09537850SAkhilesh Sanikop   }
48*09537850SAkhilesh Sanikop   return k;
49*09537850SAkhilesh Sanikop }
50*09537850SAkhilesh Sanikop 
ParseBitStreamLevel(BitStreamLevel * const level,uint8_t level_bits)51*09537850SAkhilesh Sanikop void ParseBitStreamLevel(BitStreamLevel* const level, uint8_t level_bits) {
52*09537850SAkhilesh Sanikop   level->major = kMinimumMajorBitstreamLevel + (level_bits >> 2);
53*09537850SAkhilesh Sanikop   level->minor = level_bits & 3;
54*09537850SAkhilesh Sanikop }
55*09537850SAkhilesh Sanikop 
56*09537850SAkhilesh Sanikop // This function assumes loop_filter is zero-initialized, so only it needs to
57*09537850SAkhilesh Sanikop // set the nonzero default values.
SetDefaultRefDeltas(LoopFilter * const loop_filter)58*09537850SAkhilesh Sanikop void SetDefaultRefDeltas(LoopFilter* const loop_filter) {
59*09537850SAkhilesh Sanikop   loop_filter->ref_deltas[kReferenceFrameIntra] = 1;
60*09537850SAkhilesh Sanikop   loop_filter->ref_deltas[kReferenceFrameGolden] = -1;
61*09537850SAkhilesh Sanikop   loop_filter->ref_deltas[kReferenceFrameAlternate] = -1;
62*09537850SAkhilesh Sanikop   loop_filter->ref_deltas[kReferenceFrameAlternate2] = -1;
63*09537850SAkhilesh Sanikop }
64*09537850SAkhilesh Sanikop 
InTemporalLayer(int operating_point_idc,int temporal_id)65*09537850SAkhilesh Sanikop bool InTemporalLayer(int operating_point_idc, int temporal_id) {
66*09537850SAkhilesh Sanikop   return ((operating_point_idc >> temporal_id) & 1) != 0;
67*09537850SAkhilesh Sanikop }
68*09537850SAkhilesh Sanikop 
InSpatialLayer(int operating_point_idc,int spatial_id)69*09537850SAkhilesh Sanikop bool InSpatialLayer(int operating_point_idc, int spatial_id) {
70*09537850SAkhilesh Sanikop   return ((operating_point_idc >> (spatial_id + 8)) & 1) != 0;
71*09537850SAkhilesh Sanikop }
72*09537850SAkhilesh Sanikop 
73*09537850SAkhilesh Sanikop // Returns the index of the last nonzero byte in the |data| buffer of |size|
74*09537850SAkhilesh Sanikop // bytes. If there is no nonzero byte in the |data| buffer, returns -1.
GetLastNonzeroByteIndex(const uint8_t * data,size_t size)75*09537850SAkhilesh Sanikop int GetLastNonzeroByteIndex(const uint8_t* data, size_t size) {
76*09537850SAkhilesh Sanikop   // Scan backward for a nonzero byte.
77*09537850SAkhilesh Sanikop   if (size > INT_MAX) return -1;
78*09537850SAkhilesh Sanikop   int i = static_cast<int>(size) - 1;
79*09537850SAkhilesh Sanikop   while (i >= 0 && data[i] == 0) {
80*09537850SAkhilesh Sanikop     --i;
81*09537850SAkhilesh Sanikop   }
82*09537850SAkhilesh Sanikop   return i;
83*09537850SAkhilesh Sanikop }
84*09537850SAkhilesh Sanikop 
85*09537850SAkhilesh Sanikop // A cleanup helper class that releases the frame buffer reference held in
86*09537850SAkhilesh Sanikop // |frame| in the destructor.
87*09537850SAkhilesh Sanikop class RefCountedBufferPtrCleanup {
88*09537850SAkhilesh Sanikop  public:
RefCountedBufferPtrCleanup(RefCountedBufferPtr * frame)89*09537850SAkhilesh Sanikop   explicit RefCountedBufferPtrCleanup(RefCountedBufferPtr* frame)
90*09537850SAkhilesh Sanikop       : frame_(*frame) {}
91*09537850SAkhilesh Sanikop 
92*09537850SAkhilesh Sanikop   // Not copyable or movable.
93*09537850SAkhilesh Sanikop   RefCountedBufferPtrCleanup(const RefCountedBufferPtrCleanup&) = delete;
94*09537850SAkhilesh Sanikop   RefCountedBufferPtrCleanup& operator=(const RefCountedBufferPtrCleanup&) =
95*09537850SAkhilesh Sanikop       delete;
96*09537850SAkhilesh Sanikop 
~RefCountedBufferPtrCleanup()97*09537850SAkhilesh Sanikop   ~RefCountedBufferPtrCleanup() { frame_ = nullptr; }
98*09537850SAkhilesh Sanikop 
99*09537850SAkhilesh Sanikop  private:
100*09537850SAkhilesh Sanikop   RefCountedBufferPtr& frame_;
101*09537850SAkhilesh Sanikop };
102*09537850SAkhilesh Sanikop 
103*09537850SAkhilesh Sanikop }  // namespace
104*09537850SAkhilesh Sanikop 
ParametersChanged(const ObuSequenceHeader & old) const105*09537850SAkhilesh Sanikop bool ObuSequenceHeader::ParametersChanged(const ObuSequenceHeader& old) const {
106*09537850SAkhilesh Sanikop   // Note that the operating_parameters field is not compared per Section 7.5:
107*09537850SAkhilesh Sanikop   //   Within a particular coded video sequence, the contents of
108*09537850SAkhilesh Sanikop   //   sequence_header_obu must be bit-identical each time the sequence header
109*09537850SAkhilesh Sanikop   //   appears except for the contents of operating_parameters_info.
110*09537850SAkhilesh Sanikop   return memcmp(this, &old,
111*09537850SAkhilesh Sanikop                 offsetof(ObuSequenceHeader, operating_parameters)) != 0;
112*09537850SAkhilesh Sanikop }
113*09537850SAkhilesh Sanikop 
114*09537850SAkhilesh Sanikop // Macros to avoid repeated error checks in the parser code.
115*09537850SAkhilesh Sanikop #define OBU_LOG_AND_RETURN_FALSE                                            \
116*09537850SAkhilesh Sanikop   do {                                                                      \
117*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "%s:%d (%s): Not enough bits.", __FILE__, __LINE__, \
118*09537850SAkhilesh Sanikop                  __func__);                                                 \
119*09537850SAkhilesh Sanikop     return false;                                                           \
120*09537850SAkhilesh Sanikop   } while (false)
121*09537850SAkhilesh Sanikop #define OBU_PARSER_FAIL         \
122*09537850SAkhilesh Sanikop   do {                          \
123*09537850SAkhilesh Sanikop     if (scratch == -1) {        \
124*09537850SAkhilesh Sanikop       OBU_LOG_AND_RETURN_FALSE; \
125*09537850SAkhilesh Sanikop     }                           \
126*09537850SAkhilesh Sanikop   } while (false)
127*09537850SAkhilesh Sanikop #define OBU_READ_BIT_OR_FAIL        \
128*09537850SAkhilesh Sanikop   scratch = bit_reader_->ReadBit(); \
129*09537850SAkhilesh Sanikop   OBU_PARSER_FAIL
130*09537850SAkhilesh Sanikop #define OBU_READ_LITERAL_OR_FAIL(n)      \
131*09537850SAkhilesh Sanikop   scratch = bit_reader_->ReadLiteral(n); \
132*09537850SAkhilesh Sanikop   OBU_PARSER_FAIL
133*09537850SAkhilesh Sanikop #define OBU_READ_UVLC_OR_FAIL(x)        \
134*09537850SAkhilesh Sanikop   do {                                  \
135*09537850SAkhilesh Sanikop     if (!bit_reader_->ReadUvlc(&(x))) { \
136*09537850SAkhilesh Sanikop       OBU_LOG_AND_RETURN_FALSE;         \
137*09537850SAkhilesh Sanikop     }                                   \
138*09537850SAkhilesh Sanikop   } while (false)
139*09537850SAkhilesh Sanikop 
ParseColorConfig(ObuSequenceHeader * sequence_header)140*09537850SAkhilesh Sanikop bool ObuParser::ParseColorConfig(ObuSequenceHeader* sequence_header) {
141*09537850SAkhilesh Sanikop   int64_t scratch;
142*09537850SAkhilesh Sanikop   ColorConfig* const color_config = &sequence_header->color_config;
143*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
144*09537850SAkhilesh Sanikop   const bool high_bitdepth = scratch != 0;
145*09537850SAkhilesh Sanikop   if (sequence_header->profile == kProfile2 && high_bitdepth) {
146*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
147*09537850SAkhilesh Sanikop     const bool is_twelve_bit = scratch != 0;
148*09537850SAkhilesh Sanikop     color_config->bitdepth = is_twelve_bit ? 12 : 10;
149*09537850SAkhilesh Sanikop   } else {
150*09537850SAkhilesh Sanikop     color_config->bitdepth = high_bitdepth ? 10 : 8;
151*09537850SAkhilesh Sanikop   }
152*09537850SAkhilesh Sanikop   if (sequence_header->profile == kProfile1) {
153*09537850SAkhilesh Sanikop     color_config->is_monochrome = false;
154*09537850SAkhilesh Sanikop   } else {
155*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
156*09537850SAkhilesh Sanikop     color_config->is_monochrome = scratch != 0;
157*09537850SAkhilesh Sanikop   }
158*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
159*09537850SAkhilesh Sanikop   const bool color_description_present_flag = scratch != 0;
160*09537850SAkhilesh Sanikop   if (color_description_present_flag) {
161*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
162*09537850SAkhilesh Sanikop     color_config->color_primary = static_cast<ColorPrimary>(scratch);
163*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
164*09537850SAkhilesh Sanikop     color_config->transfer_characteristics =
165*09537850SAkhilesh Sanikop         static_cast<TransferCharacteristics>(scratch);
166*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
167*09537850SAkhilesh Sanikop     color_config->matrix_coefficients =
168*09537850SAkhilesh Sanikop         static_cast<MatrixCoefficients>(scratch);
169*09537850SAkhilesh Sanikop   } else {
170*09537850SAkhilesh Sanikop     color_config->color_primary = kColorPrimaryUnspecified;
171*09537850SAkhilesh Sanikop     color_config->transfer_characteristics =
172*09537850SAkhilesh Sanikop         kTransferCharacteristicsUnspecified;
173*09537850SAkhilesh Sanikop     color_config->matrix_coefficients = kMatrixCoefficientsUnspecified;
174*09537850SAkhilesh Sanikop   }
175*09537850SAkhilesh Sanikop   if (color_config->is_monochrome) {
176*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
177*09537850SAkhilesh Sanikop     color_config->color_range = static_cast<ColorRange>(scratch);
178*09537850SAkhilesh Sanikop     // Set subsampling_x and subsampling_y to 1 for monochrome. This makes it
179*09537850SAkhilesh Sanikop     // easy to allow monochrome to be supported in profile 0. Profile 0
180*09537850SAkhilesh Sanikop     // requires subsampling_x and subsampling_y to be 1.
181*09537850SAkhilesh Sanikop     color_config->subsampling_x = 1;
182*09537850SAkhilesh Sanikop     color_config->subsampling_y = 1;
183*09537850SAkhilesh Sanikop     color_config->chroma_sample_position = kChromaSamplePositionUnknown;
184*09537850SAkhilesh Sanikop   } else {
185*09537850SAkhilesh Sanikop     if (color_config->color_primary == kColorPrimaryBt709 &&
186*09537850SAkhilesh Sanikop         color_config->transfer_characteristics ==
187*09537850SAkhilesh Sanikop             kTransferCharacteristicsSrgb &&
188*09537850SAkhilesh Sanikop         color_config->matrix_coefficients == kMatrixCoefficientsIdentity) {
189*09537850SAkhilesh Sanikop       color_config->color_range = kColorRangeFull;
190*09537850SAkhilesh Sanikop       color_config->subsampling_x = 0;
191*09537850SAkhilesh Sanikop       color_config->subsampling_y = 0;
192*09537850SAkhilesh Sanikop       // YUV 4:4:4 is only allowed in profile 1, or profile 2 with bit depth 12.
193*09537850SAkhilesh Sanikop       // See the table at the beginning of Section 6.4.1.
194*09537850SAkhilesh Sanikop       if (sequence_header->profile != kProfile1 &&
195*09537850SAkhilesh Sanikop           (sequence_header->profile != kProfile2 ||
196*09537850SAkhilesh Sanikop            color_config->bitdepth != 12)) {
197*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR,
198*09537850SAkhilesh Sanikop                      "YUV 4:4:4 is not allowed in profile %d for bitdepth %d.",
199*09537850SAkhilesh Sanikop                      sequence_header->profile, color_config->bitdepth);
200*09537850SAkhilesh Sanikop         return false;
201*09537850SAkhilesh Sanikop       }
202*09537850SAkhilesh Sanikop     } else {
203*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
204*09537850SAkhilesh Sanikop       color_config->color_range = static_cast<ColorRange>(scratch);
205*09537850SAkhilesh Sanikop       if (sequence_header->profile == kProfile0) {
206*09537850SAkhilesh Sanikop         color_config->subsampling_x = 1;
207*09537850SAkhilesh Sanikop         color_config->subsampling_y = 1;
208*09537850SAkhilesh Sanikop       } else if (sequence_header->profile == kProfile1) {
209*09537850SAkhilesh Sanikop         color_config->subsampling_x = 0;
210*09537850SAkhilesh Sanikop         color_config->subsampling_y = 0;
211*09537850SAkhilesh Sanikop       } else {
212*09537850SAkhilesh Sanikop         if (color_config->bitdepth == 12) {
213*09537850SAkhilesh Sanikop           OBU_READ_BIT_OR_FAIL;
214*09537850SAkhilesh Sanikop           color_config->subsampling_x = scratch;
215*09537850SAkhilesh Sanikop           if (color_config->subsampling_x == 1) {
216*09537850SAkhilesh Sanikop             OBU_READ_BIT_OR_FAIL;
217*09537850SAkhilesh Sanikop             color_config->subsampling_y = scratch;
218*09537850SAkhilesh Sanikop           } else {
219*09537850SAkhilesh Sanikop             color_config->subsampling_y = 0;
220*09537850SAkhilesh Sanikop           }
221*09537850SAkhilesh Sanikop         } else {
222*09537850SAkhilesh Sanikop           color_config->subsampling_x = 1;
223*09537850SAkhilesh Sanikop           color_config->subsampling_y = 0;
224*09537850SAkhilesh Sanikop         }
225*09537850SAkhilesh Sanikop       }
226*09537850SAkhilesh Sanikop       if (color_config->subsampling_x == 1 &&
227*09537850SAkhilesh Sanikop           color_config->subsampling_y == 1) {
228*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(2);
229*09537850SAkhilesh Sanikop         color_config->chroma_sample_position =
230*09537850SAkhilesh Sanikop             static_cast<ChromaSamplePosition>(scratch);
231*09537850SAkhilesh Sanikop       }
232*09537850SAkhilesh Sanikop     }
233*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
234*09537850SAkhilesh Sanikop     color_config->separate_uv_delta_q = scratch != 0;
235*09537850SAkhilesh Sanikop   }
236*09537850SAkhilesh Sanikop   if (color_config->matrix_coefficients == kMatrixCoefficientsIdentity &&
237*09537850SAkhilesh Sanikop       (color_config->subsampling_x != 0 || color_config->subsampling_y != 0)) {
238*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR,
239*09537850SAkhilesh Sanikop                  "matrix_coefficients is MC_IDENTITY, but subsampling_x (%d) "
240*09537850SAkhilesh Sanikop                  "and subsampling_y (%d) are not both 0.",
241*09537850SAkhilesh Sanikop                  color_config->subsampling_x, color_config->subsampling_y);
242*09537850SAkhilesh Sanikop     return false;
243*09537850SAkhilesh Sanikop   }
244*09537850SAkhilesh Sanikop   return true;
245*09537850SAkhilesh Sanikop }
246*09537850SAkhilesh Sanikop 
ParseTimingInfo(ObuSequenceHeader * sequence_header)247*09537850SAkhilesh Sanikop bool ObuParser::ParseTimingInfo(ObuSequenceHeader* sequence_header) {
248*09537850SAkhilesh Sanikop   int64_t scratch;
249*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
250*09537850SAkhilesh Sanikop   sequence_header->timing_info_present_flag = scratch != 0;
251*09537850SAkhilesh Sanikop   if (!sequence_header->timing_info_present_flag) return true;
252*09537850SAkhilesh Sanikop   TimingInfo* const info = &sequence_header->timing_info;
253*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(32);
254*09537850SAkhilesh Sanikop   info->num_units_in_tick = static_cast<uint32_t>(scratch);
255*09537850SAkhilesh Sanikop   if (info->num_units_in_tick == 0) {
256*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "num_units_in_tick is 0.");
257*09537850SAkhilesh Sanikop     return false;
258*09537850SAkhilesh Sanikop   }
259*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(32);
260*09537850SAkhilesh Sanikop   info->time_scale = static_cast<uint32_t>(scratch);
261*09537850SAkhilesh Sanikop   if (info->time_scale == 0) {
262*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "time_scale is 0.");
263*09537850SAkhilesh Sanikop     return false;
264*09537850SAkhilesh Sanikop   }
265*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
266*09537850SAkhilesh Sanikop   info->equal_picture_interval = scratch != 0;
267*09537850SAkhilesh Sanikop   if (info->equal_picture_interval) {
268*09537850SAkhilesh Sanikop     OBU_READ_UVLC_OR_FAIL(info->num_ticks_per_picture);
269*09537850SAkhilesh Sanikop     ++info->num_ticks_per_picture;
270*09537850SAkhilesh Sanikop   }
271*09537850SAkhilesh Sanikop   return true;
272*09537850SAkhilesh Sanikop }
273*09537850SAkhilesh Sanikop 
ParseDecoderModelInfo(ObuSequenceHeader * sequence_header)274*09537850SAkhilesh Sanikop bool ObuParser::ParseDecoderModelInfo(ObuSequenceHeader* sequence_header) {
275*09537850SAkhilesh Sanikop   if (!sequence_header->timing_info_present_flag) return true;
276*09537850SAkhilesh Sanikop   int64_t scratch;
277*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
278*09537850SAkhilesh Sanikop   sequence_header->decoder_model_info_present_flag = scratch != 0;
279*09537850SAkhilesh Sanikop   if (!sequence_header->decoder_model_info_present_flag) return true;
280*09537850SAkhilesh Sanikop   DecoderModelInfo* const info = &sequence_header->decoder_model_info;
281*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(5);
282*09537850SAkhilesh Sanikop   info->encoder_decoder_buffer_delay_length = 1 + scratch;
283*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(32);
284*09537850SAkhilesh Sanikop   info->num_units_in_decoding_tick = static_cast<uint32_t>(scratch);
285*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(5);
286*09537850SAkhilesh Sanikop   info->buffer_removal_time_length = 1 + scratch;
287*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(5);
288*09537850SAkhilesh Sanikop   info->frame_presentation_time_length = 1 + scratch;
289*09537850SAkhilesh Sanikop   return true;
290*09537850SAkhilesh Sanikop }
291*09537850SAkhilesh Sanikop 
ParseOperatingParameters(ObuSequenceHeader * sequence_header,int index)292*09537850SAkhilesh Sanikop bool ObuParser::ParseOperatingParameters(ObuSequenceHeader* sequence_header,
293*09537850SAkhilesh Sanikop                                          int index) {
294*09537850SAkhilesh Sanikop   int64_t scratch;
295*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
296*09537850SAkhilesh Sanikop   sequence_header->decoder_model_present_for_operating_point[index] =
297*09537850SAkhilesh Sanikop       scratch != 0;
298*09537850SAkhilesh Sanikop   if (!sequence_header->decoder_model_present_for_operating_point[index]) {
299*09537850SAkhilesh Sanikop     return true;
300*09537850SAkhilesh Sanikop   }
301*09537850SAkhilesh Sanikop   OperatingParameters* const params = &sequence_header->operating_parameters;
302*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(
303*09537850SAkhilesh Sanikop       sequence_header->decoder_model_info.encoder_decoder_buffer_delay_length);
304*09537850SAkhilesh Sanikop   params->decoder_buffer_delay[index] = static_cast<uint32_t>(scratch);
305*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(
306*09537850SAkhilesh Sanikop       sequence_header->decoder_model_info.encoder_decoder_buffer_delay_length);
307*09537850SAkhilesh Sanikop   params->encoder_buffer_delay[index] = static_cast<uint32_t>(scratch);
308*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
309*09537850SAkhilesh Sanikop   params->low_delay_mode_flag[index] = scratch != 0;
310*09537850SAkhilesh Sanikop   return true;
311*09537850SAkhilesh Sanikop }
312*09537850SAkhilesh Sanikop 
ParseSequenceHeader(bool seen_frame_header)313*09537850SAkhilesh Sanikop bool ObuParser::ParseSequenceHeader(bool seen_frame_header) {
314*09537850SAkhilesh Sanikop   ObuSequenceHeader sequence_header = {};
315*09537850SAkhilesh Sanikop   int64_t scratch;
316*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(3);
317*09537850SAkhilesh Sanikop   if (scratch >= kMaxProfiles) {
318*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Invalid profile: %d.", static_cast<int>(scratch));
319*09537850SAkhilesh Sanikop     return false;
320*09537850SAkhilesh Sanikop   }
321*09537850SAkhilesh Sanikop   sequence_header.profile = static_cast<BitstreamProfile>(scratch);
322*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
323*09537850SAkhilesh Sanikop   sequence_header.still_picture = scratch != 0;
324*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
325*09537850SAkhilesh Sanikop   sequence_header.reduced_still_picture_header = scratch != 0;
326*09537850SAkhilesh Sanikop   if (sequence_header.reduced_still_picture_header) {
327*09537850SAkhilesh Sanikop     if (!sequence_header.still_picture) {
328*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
329*09537850SAkhilesh Sanikop           ERROR, "reduced_still_picture_header is 1, but still_picture is 0.");
330*09537850SAkhilesh Sanikop       return false;
331*09537850SAkhilesh Sanikop     }
332*09537850SAkhilesh Sanikop     sequence_header.operating_points = 1;
333*09537850SAkhilesh Sanikop     sequence_header.operating_point_idc[0] = 0;
334*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(5);
335*09537850SAkhilesh Sanikop     ParseBitStreamLevel(&sequence_header.level[0], scratch);
336*09537850SAkhilesh Sanikop   } else {
337*09537850SAkhilesh Sanikop     if (!ParseTimingInfo(&sequence_header) ||
338*09537850SAkhilesh Sanikop         !ParseDecoderModelInfo(&sequence_header)) {
339*09537850SAkhilesh Sanikop       return false;
340*09537850SAkhilesh Sanikop     }
341*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
342*09537850SAkhilesh Sanikop     const bool initial_display_delay_present_flag = scratch != 0;
343*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(5);
344*09537850SAkhilesh Sanikop     sequence_header.operating_points = static_cast<int>(1 + scratch);
345*09537850SAkhilesh Sanikop     if (operating_point_ >= sequence_header.operating_points) {
346*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
347*09537850SAkhilesh Sanikop           ERROR,
348*09537850SAkhilesh Sanikop           "Invalid operating point: %d (valid range is [0,%d] inclusive).",
349*09537850SAkhilesh Sanikop           operating_point_, sequence_header.operating_points - 1);
350*09537850SAkhilesh Sanikop       return false;
351*09537850SAkhilesh Sanikop     }
352*09537850SAkhilesh Sanikop     for (int i = 0; i < sequence_header.operating_points; ++i) {
353*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(12);
354*09537850SAkhilesh Sanikop       sequence_header.operating_point_idc[i] = static_cast<int>(scratch);
355*09537850SAkhilesh Sanikop       for (int j = 0; j < i; ++j) {
356*09537850SAkhilesh Sanikop         if (sequence_header.operating_point_idc[i] ==
357*09537850SAkhilesh Sanikop             sequence_header.operating_point_idc[j]) {
358*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
359*09537850SAkhilesh Sanikop                        "operating_point_idc[%d] (%d) is equal to "
360*09537850SAkhilesh Sanikop                        "operating_point_idc[%d] (%d).",
361*09537850SAkhilesh Sanikop                        i, sequence_header.operating_point_idc[i], j,
362*09537850SAkhilesh Sanikop                        sequence_header.operating_point_idc[j]);
363*09537850SAkhilesh Sanikop           return false;
364*09537850SAkhilesh Sanikop         }
365*09537850SAkhilesh Sanikop       }
366*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(5);
367*09537850SAkhilesh Sanikop       ParseBitStreamLevel(&sequence_header.level[i], scratch);
368*09537850SAkhilesh Sanikop       if (sequence_header.level[i].major > 3) {
369*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
370*09537850SAkhilesh Sanikop         sequence_header.tier[i] = scratch;
371*09537850SAkhilesh Sanikop       }
372*09537850SAkhilesh Sanikop       if (sequence_header.decoder_model_info_present_flag &&
373*09537850SAkhilesh Sanikop           !ParseOperatingParameters(&sequence_header, i)) {
374*09537850SAkhilesh Sanikop         return false;
375*09537850SAkhilesh Sanikop       }
376*09537850SAkhilesh Sanikop       if (initial_display_delay_present_flag) {
377*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
378*09537850SAkhilesh Sanikop         if (scratch != 0) {
379*09537850SAkhilesh Sanikop           OBU_READ_LITERAL_OR_FAIL(4);
380*09537850SAkhilesh Sanikop           sequence_header.initial_display_delay[i] = 1 + scratch;
381*09537850SAkhilesh Sanikop         }
382*09537850SAkhilesh Sanikop       }
383*09537850SAkhilesh Sanikop     }
384*09537850SAkhilesh Sanikop   }
385*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(4);
386*09537850SAkhilesh Sanikop   sequence_header.frame_width_bits = 1 + scratch;
387*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(4);
388*09537850SAkhilesh Sanikop   sequence_header.frame_height_bits = 1 + scratch;
389*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(sequence_header.frame_width_bits);
390*09537850SAkhilesh Sanikop   sequence_header.max_frame_width = static_cast<int32_t>(1 + scratch);
391*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(sequence_header.frame_height_bits);
392*09537850SAkhilesh Sanikop   sequence_header.max_frame_height = static_cast<int32_t>(1 + scratch);
393*09537850SAkhilesh Sanikop   if (!sequence_header.reduced_still_picture_header) {
394*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
395*09537850SAkhilesh Sanikop     sequence_header.frame_id_numbers_present = scratch != 0;
396*09537850SAkhilesh Sanikop   }
397*09537850SAkhilesh Sanikop   if (sequence_header.frame_id_numbers_present) {
398*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
399*09537850SAkhilesh Sanikop     sequence_header.delta_frame_id_length_bits = 2 + scratch;
400*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
401*09537850SAkhilesh Sanikop     sequence_header.frame_id_length_bits =
402*09537850SAkhilesh Sanikop         sequence_header.delta_frame_id_length_bits + 1 + scratch;
403*09537850SAkhilesh Sanikop     // Section 6.8.2: It is a requirement of bitstream conformance that the
404*09537850SAkhilesh Sanikop     // number of bits needed to read display_frame_id does not exceed 16. This
405*09537850SAkhilesh Sanikop     // is equivalent to the constraint that idLen <= 16.
406*09537850SAkhilesh Sanikop     if (sequence_header.frame_id_length_bits > 16) {
407*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid frame_id_length_bits: %d.",
408*09537850SAkhilesh Sanikop                    sequence_header.frame_id_length_bits);
409*09537850SAkhilesh Sanikop       return false;
410*09537850SAkhilesh Sanikop     }
411*09537850SAkhilesh Sanikop   }
412*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
413*09537850SAkhilesh Sanikop   sequence_header.use_128x128_superblock = scratch != 0;
414*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
415*09537850SAkhilesh Sanikop   sequence_header.enable_filter_intra = scratch != 0;
416*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
417*09537850SAkhilesh Sanikop   sequence_header.enable_intra_edge_filter = scratch != 0;
418*09537850SAkhilesh Sanikop   if (sequence_header.reduced_still_picture_header) {
419*09537850SAkhilesh Sanikop     sequence_header.force_screen_content_tools = kSelectScreenContentTools;
420*09537850SAkhilesh Sanikop     sequence_header.force_integer_mv = kSelectIntegerMv;
421*09537850SAkhilesh Sanikop   } else {
422*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
423*09537850SAkhilesh Sanikop     sequence_header.enable_interintra_compound = scratch != 0;
424*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
425*09537850SAkhilesh Sanikop     sequence_header.enable_masked_compound = scratch != 0;
426*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
427*09537850SAkhilesh Sanikop     sequence_header.enable_warped_motion = scratch != 0;
428*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
429*09537850SAkhilesh Sanikop     sequence_header.enable_dual_filter = scratch != 0;
430*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
431*09537850SAkhilesh Sanikop     sequence_header.enable_order_hint = scratch != 0;
432*09537850SAkhilesh Sanikop     if (sequence_header.enable_order_hint) {
433*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
434*09537850SAkhilesh Sanikop       sequence_header.enable_jnt_comp = scratch != 0;
435*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
436*09537850SAkhilesh Sanikop       sequence_header.enable_ref_frame_mvs = scratch != 0;
437*09537850SAkhilesh Sanikop     }
438*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
439*09537850SAkhilesh Sanikop     sequence_header.choose_screen_content_tools = scratch != 0;
440*09537850SAkhilesh Sanikop     if (sequence_header.choose_screen_content_tools) {
441*09537850SAkhilesh Sanikop       sequence_header.force_screen_content_tools = kSelectScreenContentTools;
442*09537850SAkhilesh Sanikop     } else {
443*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
444*09537850SAkhilesh Sanikop       sequence_header.force_screen_content_tools = scratch;
445*09537850SAkhilesh Sanikop     }
446*09537850SAkhilesh Sanikop     if (sequence_header.force_screen_content_tools > 0) {
447*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
448*09537850SAkhilesh Sanikop       sequence_header.choose_integer_mv = scratch != 0;
449*09537850SAkhilesh Sanikop       if (sequence_header.choose_integer_mv) {
450*09537850SAkhilesh Sanikop         sequence_header.force_integer_mv = kSelectIntegerMv;
451*09537850SAkhilesh Sanikop       } else {
452*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
453*09537850SAkhilesh Sanikop         sequence_header.force_integer_mv = scratch;
454*09537850SAkhilesh Sanikop       }
455*09537850SAkhilesh Sanikop     } else {
456*09537850SAkhilesh Sanikop       sequence_header.force_integer_mv = kSelectIntegerMv;
457*09537850SAkhilesh Sanikop     }
458*09537850SAkhilesh Sanikop     if (sequence_header.enable_order_hint) {
459*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(3);
460*09537850SAkhilesh Sanikop       sequence_header.order_hint_bits = 1 + scratch;
461*09537850SAkhilesh Sanikop       sequence_header.order_hint_shift_bits =
462*09537850SAkhilesh Sanikop           Mod32(32 - sequence_header.order_hint_bits);
463*09537850SAkhilesh Sanikop     }
464*09537850SAkhilesh Sanikop   }
465*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
466*09537850SAkhilesh Sanikop   sequence_header.enable_superres = scratch != 0;
467*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
468*09537850SAkhilesh Sanikop   sequence_header.enable_cdef = scratch != 0;
469*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
470*09537850SAkhilesh Sanikop   sequence_header.enable_restoration = scratch != 0;
471*09537850SAkhilesh Sanikop   if (!ParseColorConfig(&sequence_header)) return false;
472*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
473*09537850SAkhilesh Sanikop   sequence_header.film_grain_params_present = scratch != 0;
474*09537850SAkhilesh Sanikop   // Compare new sequence header with old sequence header.
475*09537850SAkhilesh Sanikop   if (has_sequence_header_ &&
476*09537850SAkhilesh Sanikop       sequence_header.ParametersChanged(sequence_header_)) {
477*09537850SAkhilesh Sanikop     // Between the frame header OBU and the last tile group OBU of the frame,
478*09537850SAkhilesh Sanikop     // do not allow the sequence header to change.
479*09537850SAkhilesh Sanikop     if (seen_frame_header) {
480*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Sequence header changed in the middle of a frame.");
481*09537850SAkhilesh Sanikop       return false;
482*09537850SAkhilesh Sanikop     }
483*09537850SAkhilesh Sanikop     sequence_header_changed_ = true;
484*09537850SAkhilesh Sanikop     decoder_state_.ClearReferenceFrames();
485*09537850SAkhilesh Sanikop   }
486*09537850SAkhilesh Sanikop   sequence_header_ = sequence_header;
487*09537850SAkhilesh Sanikop   if (!has_sequence_header_) {
488*09537850SAkhilesh Sanikop     sequence_header_changed_ = true;
489*09537850SAkhilesh Sanikop   }
490*09537850SAkhilesh Sanikop   has_sequence_header_ = true;
491*09537850SAkhilesh Sanikop   // Section 6.4.1: It is a requirement of bitstream conformance that if
492*09537850SAkhilesh Sanikop   // OperatingPointIdc is equal to 0, then obu_extension_flag is equal to 0 for
493*09537850SAkhilesh Sanikop   // all OBUs that follow this sequence header until the next sequence header.
494*09537850SAkhilesh Sanikop   extension_disallowed_ =
495*09537850SAkhilesh Sanikop       (sequence_header_.operating_point_idc[operating_point_] == 0);
496*09537850SAkhilesh Sanikop   return true;
497*09537850SAkhilesh Sanikop }
498*09537850SAkhilesh Sanikop 
499*09537850SAkhilesh Sanikop // Marks reference frames as invalid for referencing when they are too far in
500*09537850SAkhilesh Sanikop // the past to be referenced by the frame id mechanism.
MarkInvalidReferenceFrames()501*09537850SAkhilesh Sanikop void ObuParser::MarkInvalidReferenceFrames() {
502*09537850SAkhilesh Sanikop   // The current lower bound of the frame ids for reference frames.
503*09537850SAkhilesh Sanikop   int lower_bound = decoder_state_.current_frame_id -
504*09537850SAkhilesh Sanikop                     (1 << sequence_header_.delta_frame_id_length_bits);
505*09537850SAkhilesh Sanikop   // True if lower_bound is smaller than current_frame_id. False if lower_bound
506*09537850SAkhilesh Sanikop   // wraps around (in modular arithmetic) to the other side of current_frame_id.
507*09537850SAkhilesh Sanikop   bool lower_bound_is_smaller = true;
508*09537850SAkhilesh Sanikop   if (lower_bound <= 0) {
509*09537850SAkhilesh Sanikop     lower_bound += 1 << sequence_header_.frame_id_length_bits;
510*09537850SAkhilesh Sanikop     lower_bound_is_smaller = false;
511*09537850SAkhilesh Sanikop   }
512*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
513*09537850SAkhilesh Sanikop     const uint16_t reference_frame_id = decoder_state_.reference_frame_id[i];
514*09537850SAkhilesh Sanikop     if (lower_bound_is_smaller) {
515*09537850SAkhilesh Sanikop       if (reference_frame_id > decoder_state_.current_frame_id ||
516*09537850SAkhilesh Sanikop           reference_frame_id < lower_bound) {
517*09537850SAkhilesh Sanikop         decoder_state_.reference_frame[i] = nullptr;
518*09537850SAkhilesh Sanikop       }
519*09537850SAkhilesh Sanikop     } else {
520*09537850SAkhilesh Sanikop       if (reference_frame_id > decoder_state_.current_frame_id &&
521*09537850SAkhilesh Sanikop           reference_frame_id < lower_bound) {
522*09537850SAkhilesh Sanikop         decoder_state_.reference_frame[i] = nullptr;
523*09537850SAkhilesh Sanikop       }
524*09537850SAkhilesh Sanikop     }
525*09537850SAkhilesh Sanikop   }
526*09537850SAkhilesh Sanikop }
527*09537850SAkhilesh Sanikop 
ParseFrameSizeAndRenderSize()528*09537850SAkhilesh Sanikop bool ObuParser::ParseFrameSizeAndRenderSize() {
529*09537850SAkhilesh Sanikop   int64_t scratch;
530*09537850SAkhilesh Sanikop   // Frame Size.
531*09537850SAkhilesh Sanikop   if (frame_header_.frame_size_override_flag) {
532*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(sequence_header_.frame_width_bits);
533*09537850SAkhilesh Sanikop     frame_header_.width = static_cast<int32_t>(1 + scratch);
534*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(sequence_header_.frame_height_bits);
535*09537850SAkhilesh Sanikop     frame_header_.height = static_cast<int32_t>(1 + scratch);
536*09537850SAkhilesh Sanikop     if (frame_header_.width > sequence_header_.max_frame_width ||
537*09537850SAkhilesh Sanikop         frame_header_.height > sequence_header_.max_frame_height) {
538*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
539*09537850SAkhilesh Sanikop                    "Frame dimensions are larger than the maximum values");
540*09537850SAkhilesh Sanikop       return false;
541*09537850SAkhilesh Sanikop     }
542*09537850SAkhilesh Sanikop   } else {
543*09537850SAkhilesh Sanikop     frame_header_.width = sequence_header_.max_frame_width;
544*09537850SAkhilesh Sanikop     frame_header_.height = sequence_header_.max_frame_height;
545*09537850SAkhilesh Sanikop   }
546*09537850SAkhilesh Sanikop   if (!ParseSuperResParametersAndComputeImageSize()) return false;
547*09537850SAkhilesh Sanikop 
548*09537850SAkhilesh Sanikop   // Render Size.
549*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
550*09537850SAkhilesh Sanikop   frame_header_.render_and_frame_size_different = scratch != 0;
551*09537850SAkhilesh Sanikop   if (frame_header_.render_and_frame_size_different) {
552*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(16);
553*09537850SAkhilesh Sanikop     frame_header_.render_width = static_cast<int32_t>(1 + scratch);
554*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(16);
555*09537850SAkhilesh Sanikop     frame_header_.render_height = static_cast<int32_t>(1 + scratch);
556*09537850SAkhilesh Sanikop   } else {
557*09537850SAkhilesh Sanikop     frame_header_.render_width = frame_header_.upscaled_width;
558*09537850SAkhilesh Sanikop     frame_header_.render_height = frame_header_.height;
559*09537850SAkhilesh Sanikop   }
560*09537850SAkhilesh Sanikop 
561*09537850SAkhilesh Sanikop   return true;
562*09537850SAkhilesh Sanikop }
563*09537850SAkhilesh Sanikop 
ParseSuperResParametersAndComputeImageSize()564*09537850SAkhilesh Sanikop bool ObuParser::ParseSuperResParametersAndComputeImageSize() {
565*09537850SAkhilesh Sanikop   int64_t scratch;
566*09537850SAkhilesh Sanikop   // SuperRes.
567*09537850SAkhilesh Sanikop   frame_header_.upscaled_width = frame_header_.width;
568*09537850SAkhilesh Sanikop   frame_header_.use_superres = false;
569*09537850SAkhilesh Sanikop   if (sequence_header_.enable_superres) {
570*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
571*09537850SAkhilesh Sanikop     frame_header_.use_superres = scratch != 0;
572*09537850SAkhilesh Sanikop   }
573*09537850SAkhilesh Sanikop   if (frame_header_.use_superres) {
574*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
575*09537850SAkhilesh Sanikop     // 9 is the smallest value for the denominator.
576*09537850SAkhilesh Sanikop     frame_header_.superres_scale_denominator = scratch + 9;
577*09537850SAkhilesh Sanikop     frame_header_.width =
578*09537850SAkhilesh Sanikop         (frame_header_.upscaled_width * kSuperResScaleNumerator +
579*09537850SAkhilesh Sanikop          (frame_header_.superres_scale_denominator / 2)) /
580*09537850SAkhilesh Sanikop         frame_header_.superres_scale_denominator;
581*09537850SAkhilesh Sanikop   } else {
582*09537850SAkhilesh Sanikop     frame_header_.superres_scale_denominator = kSuperResScaleNumerator;
583*09537850SAkhilesh Sanikop   }
584*09537850SAkhilesh Sanikop   assert(frame_header_.width != 0);
585*09537850SAkhilesh Sanikop   assert(frame_header_.height != 0);
586*09537850SAkhilesh Sanikop   // Check if multiplying upscaled_width by height would overflow.
587*09537850SAkhilesh Sanikop   assert(frame_header_.upscaled_width >= frame_header_.width);
588*09537850SAkhilesh Sanikop   if (frame_header_.upscaled_width > INT32_MAX / frame_header_.height) {
589*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Frame dimensions too big: width=%d height=%d.",
590*09537850SAkhilesh Sanikop                  frame_header_.width, frame_header_.height);
591*09537850SAkhilesh Sanikop     return false;
592*09537850SAkhilesh Sanikop   }
593*09537850SAkhilesh Sanikop   frame_header_.columns4x4 = ((frame_header_.width + 7) >> 3) << 1;
594*09537850SAkhilesh Sanikop   frame_header_.rows4x4 = ((frame_header_.height + 7) >> 3) << 1;
595*09537850SAkhilesh Sanikop   return true;
596*09537850SAkhilesh Sanikop }
597*09537850SAkhilesh Sanikop 
ValidateInterFrameSize() const598*09537850SAkhilesh Sanikop bool ObuParser::ValidateInterFrameSize() const {
599*09537850SAkhilesh Sanikop   for (int index : frame_header_.reference_frame_index) {
600*09537850SAkhilesh Sanikop     const RefCountedBuffer* reference_frame =
601*09537850SAkhilesh Sanikop         decoder_state_.reference_frame[index].get();
602*09537850SAkhilesh Sanikop     if (2 * frame_header_.width < reference_frame->upscaled_width() ||
603*09537850SAkhilesh Sanikop         2 * frame_header_.height < reference_frame->frame_height() ||
604*09537850SAkhilesh Sanikop         frame_header_.width > 16 * reference_frame->upscaled_width() ||
605*09537850SAkhilesh Sanikop         frame_header_.height > 16 * reference_frame->frame_height()) {
606*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
607*09537850SAkhilesh Sanikop                    "Invalid inter frame size: width=%d, height=%d. Reference "
608*09537850SAkhilesh Sanikop                    "frame: index=%d, upscaled width=%d, height=%d.",
609*09537850SAkhilesh Sanikop                    frame_header_.width, frame_header_.height, index,
610*09537850SAkhilesh Sanikop                    reference_frame->upscaled_width(),
611*09537850SAkhilesh Sanikop                    reference_frame->frame_height());
612*09537850SAkhilesh Sanikop       return false;
613*09537850SAkhilesh Sanikop     }
614*09537850SAkhilesh Sanikop   }
615*09537850SAkhilesh Sanikop   return true;
616*09537850SAkhilesh Sanikop }
617*09537850SAkhilesh Sanikop 
ParseReferenceOrderHint()618*09537850SAkhilesh Sanikop bool ObuParser::ParseReferenceOrderHint() {
619*09537850SAkhilesh Sanikop   if (!frame_header_.error_resilient_mode ||
620*09537850SAkhilesh Sanikop       !sequence_header_.enable_order_hint) {
621*09537850SAkhilesh Sanikop     return true;
622*09537850SAkhilesh Sanikop   }
623*09537850SAkhilesh Sanikop   int64_t scratch;
624*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
625*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(sequence_header_.order_hint_bits);
626*09537850SAkhilesh Sanikop     frame_header_.reference_order_hint[i] = scratch;
627*09537850SAkhilesh Sanikop     if (frame_header_.reference_order_hint[i] !=
628*09537850SAkhilesh Sanikop         decoder_state_.reference_order_hint[i]) {
629*09537850SAkhilesh Sanikop       decoder_state_.reference_frame[i] = nullptr;
630*09537850SAkhilesh Sanikop     }
631*09537850SAkhilesh Sanikop   }
632*09537850SAkhilesh Sanikop   return true;
633*09537850SAkhilesh Sanikop }
634*09537850SAkhilesh Sanikop 
635*09537850SAkhilesh Sanikop // static
FindLatestBackwardReference(const int current_frame_hint,const std::array<int,kNumReferenceFrameTypes> & shifted_order_hints,const std::array<bool,kNumReferenceFrameTypes> & used_frame)636*09537850SAkhilesh Sanikop int ObuParser::FindLatestBackwardReference(
637*09537850SAkhilesh Sanikop     const int current_frame_hint,
638*09537850SAkhilesh Sanikop     const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
639*09537850SAkhilesh Sanikop     const std::array<bool, kNumReferenceFrameTypes>& used_frame) {
640*09537850SAkhilesh Sanikop   int ref = -1;
641*09537850SAkhilesh Sanikop   int latest_order_hint = INT_MIN;
642*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
643*09537850SAkhilesh Sanikop     const int hint = shifted_order_hints[i];
644*09537850SAkhilesh Sanikop     if (!used_frame[i] && hint >= current_frame_hint &&
645*09537850SAkhilesh Sanikop         hint >= latest_order_hint) {
646*09537850SAkhilesh Sanikop       ref = i;
647*09537850SAkhilesh Sanikop       latest_order_hint = hint;
648*09537850SAkhilesh Sanikop     }
649*09537850SAkhilesh Sanikop   }
650*09537850SAkhilesh Sanikop   return ref;
651*09537850SAkhilesh Sanikop }
652*09537850SAkhilesh Sanikop 
653*09537850SAkhilesh Sanikop // static
FindEarliestBackwardReference(const int current_frame_hint,const std::array<int,kNumReferenceFrameTypes> & shifted_order_hints,const std::array<bool,kNumReferenceFrameTypes> & used_frame)654*09537850SAkhilesh Sanikop int ObuParser::FindEarliestBackwardReference(
655*09537850SAkhilesh Sanikop     const int current_frame_hint,
656*09537850SAkhilesh Sanikop     const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
657*09537850SAkhilesh Sanikop     const std::array<bool, kNumReferenceFrameTypes>& used_frame) {
658*09537850SAkhilesh Sanikop   int ref = -1;
659*09537850SAkhilesh Sanikop   int earliest_order_hint = INT_MAX;
660*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
661*09537850SAkhilesh Sanikop     const int hint = shifted_order_hints[i];
662*09537850SAkhilesh Sanikop     if (!used_frame[i] && hint >= current_frame_hint &&
663*09537850SAkhilesh Sanikop         hint < earliest_order_hint) {
664*09537850SAkhilesh Sanikop       ref = i;
665*09537850SAkhilesh Sanikop       earliest_order_hint = hint;
666*09537850SAkhilesh Sanikop     }
667*09537850SAkhilesh Sanikop   }
668*09537850SAkhilesh Sanikop   return ref;
669*09537850SAkhilesh Sanikop }
670*09537850SAkhilesh Sanikop 
671*09537850SAkhilesh Sanikop // static
FindLatestForwardReference(const int current_frame_hint,const std::array<int,kNumReferenceFrameTypes> & shifted_order_hints,const std::array<bool,kNumReferenceFrameTypes> & used_frame)672*09537850SAkhilesh Sanikop int ObuParser::FindLatestForwardReference(
673*09537850SAkhilesh Sanikop     const int current_frame_hint,
674*09537850SAkhilesh Sanikop     const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
675*09537850SAkhilesh Sanikop     const std::array<bool, kNumReferenceFrameTypes>& used_frame) {
676*09537850SAkhilesh Sanikop   int ref = -1;
677*09537850SAkhilesh Sanikop   int latest_order_hint = INT_MIN;
678*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
679*09537850SAkhilesh Sanikop     const int hint = shifted_order_hints[i];
680*09537850SAkhilesh Sanikop     if (!used_frame[i] && hint < current_frame_hint &&
681*09537850SAkhilesh Sanikop         hint >= latest_order_hint) {
682*09537850SAkhilesh Sanikop       ref = i;
683*09537850SAkhilesh Sanikop       latest_order_hint = hint;
684*09537850SAkhilesh Sanikop     }
685*09537850SAkhilesh Sanikop   }
686*09537850SAkhilesh Sanikop   return ref;
687*09537850SAkhilesh Sanikop }
688*09537850SAkhilesh Sanikop 
689*09537850SAkhilesh Sanikop // static
FindReferenceWithSmallestOutputOrder(const std::array<int,kNumReferenceFrameTypes> & shifted_order_hints)690*09537850SAkhilesh Sanikop int ObuParser::FindReferenceWithSmallestOutputOrder(
691*09537850SAkhilesh Sanikop     const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints) {
692*09537850SAkhilesh Sanikop   int ref = -1;
693*09537850SAkhilesh Sanikop   int earliest_order_hint = INT_MAX;
694*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
695*09537850SAkhilesh Sanikop     const int hint = shifted_order_hints[i];
696*09537850SAkhilesh Sanikop     if (hint < earliest_order_hint) {
697*09537850SAkhilesh Sanikop       ref = i;
698*09537850SAkhilesh Sanikop       earliest_order_hint = hint;
699*09537850SAkhilesh Sanikop     }
700*09537850SAkhilesh Sanikop   }
701*09537850SAkhilesh Sanikop   return ref;
702*09537850SAkhilesh Sanikop }
703*09537850SAkhilesh Sanikop 
704*09537850SAkhilesh Sanikop // Computes the elements in the frame_header_.reference_frame_index array
705*09537850SAkhilesh Sanikop // based on:
706*09537850SAkhilesh Sanikop // * the syntax elements last_frame_idx and gold_frame_idx, and
707*09537850SAkhilesh Sanikop // * the values stored within the decoder_state_.reference_order_hint array
708*09537850SAkhilesh Sanikop //   (these values represent the least significant bits of the expected output
709*09537850SAkhilesh Sanikop //   order of the frames).
710*09537850SAkhilesh Sanikop //
711*09537850SAkhilesh Sanikop // Frame type: {
712*09537850SAkhilesh Sanikop //       libgav1_name              spec_name              int
713*09537850SAkhilesh Sanikop //   kReferenceFrameLast,          LAST_FRAME              1
714*09537850SAkhilesh Sanikop //   kReferenceFrameLast2,         LAST2_FRAME             2
715*09537850SAkhilesh Sanikop //   kReferenceFrameLast3,         LAST3_FRAME             3
716*09537850SAkhilesh Sanikop //   kReferenceFrameGolden,        GOLDEN_FRAME            4
717*09537850SAkhilesh Sanikop //   kReferenceFrameBackward,      BWDREF_FRAME            5
718*09537850SAkhilesh Sanikop //   kReferenceFrameAlternate2,    ALTREF2_FRAME           6
719*09537850SAkhilesh Sanikop //   kReferenceFrameAlternate,     ALTREF_FRAME            7
720*09537850SAkhilesh Sanikop // }
721*09537850SAkhilesh Sanikop //
722*09537850SAkhilesh Sanikop // A typical case of a group of pictures (frames) in display order:
723*09537850SAkhilesh Sanikop // (However, more complex cases are possibly allowed in terms of
724*09537850SAkhilesh Sanikop // bitstream conformance.)
725*09537850SAkhilesh Sanikop //
726*09537850SAkhilesh Sanikop // |         |         |         |         |         |         |         |
727*09537850SAkhilesh Sanikop // |         |         |         |         |         |         |         |
728*09537850SAkhilesh Sanikop // |         |         |         |         |         |         |         |
729*09537850SAkhilesh Sanikop // |         |         |         |         |         |         |         |
730*09537850SAkhilesh Sanikop //
731*09537850SAkhilesh Sanikop // 4         3         2         1   current_frame   5         6         7
732*09537850SAkhilesh Sanikop //
SetFrameReferences(const int8_t last_frame_idx,const int8_t gold_frame_idx)733*09537850SAkhilesh Sanikop bool ObuParser::SetFrameReferences(const int8_t last_frame_idx,
734*09537850SAkhilesh Sanikop                                    const int8_t gold_frame_idx) {
735*09537850SAkhilesh Sanikop   // Set the ref_frame_idx entries for kReferenceFrameLast and
736*09537850SAkhilesh Sanikop   // kReferenceFrameGolden to last_frame_idx and gold_frame_idx. Initialize
737*09537850SAkhilesh Sanikop   // the other entries to -1.
738*09537850SAkhilesh Sanikop   for (int8_t& reference_frame_index : frame_header_.reference_frame_index) {
739*09537850SAkhilesh Sanikop     reference_frame_index = -1;
740*09537850SAkhilesh Sanikop   }
741*09537850SAkhilesh Sanikop   frame_header_
742*09537850SAkhilesh Sanikop       .reference_frame_index[kReferenceFrameLast - kReferenceFrameLast] =
743*09537850SAkhilesh Sanikop       last_frame_idx;
744*09537850SAkhilesh Sanikop   frame_header_
745*09537850SAkhilesh Sanikop       .reference_frame_index[kReferenceFrameGolden - kReferenceFrameLast] =
746*09537850SAkhilesh Sanikop       gold_frame_idx;
747*09537850SAkhilesh Sanikop 
748*09537850SAkhilesh Sanikop   // used_frame records which reference frames have been used.
749*09537850SAkhilesh Sanikop   std::array<bool, kNumReferenceFrameTypes> used_frame;
750*09537850SAkhilesh Sanikop   used_frame.fill(false);
751*09537850SAkhilesh Sanikop   used_frame[last_frame_idx] = true;
752*09537850SAkhilesh Sanikop   used_frame[gold_frame_idx] = true;
753*09537850SAkhilesh Sanikop 
754*09537850SAkhilesh Sanikop   assert(sequence_header_.order_hint_bits >= 1);
755*09537850SAkhilesh Sanikop   const int current_frame_hint = 1 << (sequence_header_.order_hint_bits - 1);
756*09537850SAkhilesh Sanikop   // shifted_order_hints contains the expected output order shifted such that
757*09537850SAkhilesh Sanikop   // the current frame has hint equal to current_frame_hint.
758*09537850SAkhilesh Sanikop   std::array<int, kNumReferenceFrameTypes> shifted_order_hints;
759*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumReferenceFrameTypes; ++i) {
760*09537850SAkhilesh Sanikop     const int relative_distance = GetRelativeDistance(
761*09537850SAkhilesh Sanikop         decoder_state_.reference_order_hint[i], frame_header_.order_hint,
762*09537850SAkhilesh Sanikop         sequence_header_.order_hint_shift_bits);
763*09537850SAkhilesh Sanikop     shifted_order_hints[i] = current_frame_hint + relative_distance;
764*09537850SAkhilesh Sanikop   }
765*09537850SAkhilesh Sanikop 
766*09537850SAkhilesh Sanikop   // The expected output orders for kReferenceFrameLast and
767*09537850SAkhilesh Sanikop   // kReferenceFrameGolden.
768*09537850SAkhilesh Sanikop   const int last_order_hint = shifted_order_hints[last_frame_idx];
769*09537850SAkhilesh Sanikop   const int gold_order_hint = shifted_order_hints[gold_frame_idx];
770*09537850SAkhilesh Sanikop 
771*09537850SAkhilesh Sanikop   // Section 7.8: It is a requirement of bitstream conformance that
772*09537850SAkhilesh Sanikop   // lastOrderHint and goldOrderHint are strictly less than curFrameHint.
773*09537850SAkhilesh Sanikop   if (last_order_hint >= current_frame_hint ||
774*09537850SAkhilesh Sanikop       gold_order_hint >= current_frame_hint) {
775*09537850SAkhilesh Sanikop     return false;
776*09537850SAkhilesh Sanikop   }
777*09537850SAkhilesh Sanikop 
778*09537850SAkhilesh Sanikop   // Find a backward reference to the frame with highest output order. If
779*09537850SAkhilesh Sanikop   // found, set the kReferenceFrameAlternate reference to that backward
780*09537850SAkhilesh Sanikop   // reference.
781*09537850SAkhilesh Sanikop   int ref = FindLatestBackwardReference(current_frame_hint, shifted_order_hints,
782*09537850SAkhilesh Sanikop                                         used_frame);
783*09537850SAkhilesh Sanikop   if (ref >= 0) {
784*09537850SAkhilesh Sanikop     frame_header_
785*09537850SAkhilesh Sanikop         .reference_frame_index[kReferenceFrameAlternate - kReferenceFrameLast] =
786*09537850SAkhilesh Sanikop         ref;
787*09537850SAkhilesh Sanikop     used_frame[ref] = true;
788*09537850SAkhilesh Sanikop   }
789*09537850SAkhilesh Sanikop 
790*09537850SAkhilesh Sanikop   // Find a backward reference to the closest frame. If found, set the
791*09537850SAkhilesh Sanikop   // kReferenceFrameBackward reference to that backward reference.
792*09537850SAkhilesh Sanikop   ref = FindEarliestBackwardReference(current_frame_hint, shifted_order_hints,
793*09537850SAkhilesh Sanikop                                       used_frame);
794*09537850SAkhilesh Sanikop   if (ref >= 0) {
795*09537850SAkhilesh Sanikop     frame_header_
796*09537850SAkhilesh Sanikop         .reference_frame_index[kReferenceFrameBackward - kReferenceFrameLast] =
797*09537850SAkhilesh Sanikop         ref;
798*09537850SAkhilesh Sanikop     used_frame[ref] = true;
799*09537850SAkhilesh Sanikop   }
800*09537850SAkhilesh Sanikop 
801*09537850SAkhilesh Sanikop   // Set the kReferenceFrameAlternate2 reference to the next closest backward
802*09537850SAkhilesh Sanikop   // reference.
803*09537850SAkhilesh Sanikop   ref = FindEarliestBackwardReference(current_frame_hint, shifted_order_hints,
804*09537850SAkhilesh Sanikop                                       used_frame);
805*09537850SAkhilesh Sanikop   if (ref >= 0) {
806*09537850SAkhilesh Sanikop     frame_header_.reference_frame_index[kReferenceFrameAlternate2 -
807*09537850SAkhilesh Sanikop                                         kReferenceFrameLast] = ref;
808*09537850SAkhilesh Sanikop     used_frame[ref] = true;
809*09537850SAkhilesh Sanikop   }
810*09537850SAkhilesh Sanikop 
811*09537850SAkhilesh Sanikop   // The remaining references are set to be forward references in
812*09537850SAkhilesh Sanikop   // reverse chronological order.
813*09537850SAkhilesh Sanikop   static constexpr ReferenceFrameType
814*09537850SAkhilesh Sanikop       kRefFrameList[kNumInterReferenceFrameTypes - 2] = {
815*09537850SAkhilesh Sanikop           kReferenceFrameLast2, kReferenceFrameLast3, kReferenceFrameBackward,
816*09537850SAkhilesh Sanikop           kReferenceFrameAlternate2, kReferenceFrameAlternate};
817*09537850SAkhilesh Sanikop   for (const ReferenceFrameType ref_frame : kRefFrameList) {
818*09537850SAkhilesh Sanikop     if (frame_header_.reference_frame_index[ref_frame - kReferenceFrameLast] <
819*09537850SAkhilesh Sanikop         0) {
820*09537850SAkhilesh Sanikop       ref = FindLatestForwardReference(current_frame_hint, shifted_order_hints,
821*09537850SAkhilesh Sanikop                                        used_frame);
822*09537850SAkhilesh Sanikop       if (ref >= 0) {
823*09537850SAkhilesh Sanikop         frame_header_.reference_frame_index[ref_frame - kReferenceFrameLast] =
824*09537850SAkhilesh Sanikop             ref;
825*09537850SAkhilesh Sanikop         used_frame[ref] = true;
826*09537850SAkhilesh Sanikop       }
827*09537850SAkhilesh Sanikop     }
828*09537850SAkhilesh Sanikop   }
829*09537850SAkhilesh Sanikop 
830*09537850SAkhilesh Sanikop   // Finally, any remaining references are set to the reference frame with
831*09537850SAkhilesh Sanikop   // smallest output order.
832*09537850SAkhilesh Sanikop   ref = FindReferenceWithSmallestOutputOrder(shifted_order_hints);
833*09537850SAkhilesh Sanikop   assert(ref >= 0);
834*09537850SAkhilesh Sanikop   for (int8_t& reference_frame_index : frame_header_.reference_frame_index) {
835*09537850SAkhilesh Sanikop     if (reference_frame_index < 0) {
836*09537850SAkhilesh Sanikop       reference_frame_index = ref;
837*09537850SAkhilesh Sanikop     }
838*09537850SAkhilesh Sanikop   }
839*09537850SAkhilesh Sanikop 
840*09537850SAkhilesh Sanikop   return true;
841*09537850SAkhilesh Sanikop }
842*09537850SAkhilesh Sanikop 
ParseLoopFilterParameters()843*09537850SAkhilesh Sanikop bool ObuParser::ParseLoopFilterParameters() {
844*09537850SAkhilesh Sanikop   LoopFilter* const loop_filter = &frame_header_.loop_filter;
845*09537850SAkhilesh Sanikop   if (frame_header_.coded_lossless || frame_header_.allow_intrabc) {
846*09537850SAkhilesh Sanikop     SetDefaultRefDeltas(loop_filter);
847*09537850SAkhilesh Sanikop     return true;
848*09537850SAkhilesh Sanikop   }
849*09537850SAkhilesh Sanikop   // IsIntraFrame implies kPrimaryReferenceNone.
850*09537850SAkhilesh Sanikop   assert(!IsIntraFrame(frame_header_.frame_type) ||
851*09537850SAkhilesh Sanikop          frame_header_.primary_reference_frame == kPrimaryReferenceNone);
852*09537850SAkhilesh Sanikop   if (frame_header_.primary_reference_frame == kPrimaryReferenceNone) {
853*09537850SAkhilesh Sanikop     // Part of the setup_past_independence() function in the spec. It is not
854*09537850SAkhilesh Sanikop     // necessary to set loop_filter->delta_enabled to true. See
855*09537850SAkhilesh Sanikop     // https://crbug.com/aomedia/2305.
856*09537850SAkhilesh Sanikop     SetDefaultRefDeltas(loop_filter);
857*09537850SAkhilesh Sanikop   } else {
858*09537850SAkhilesh Sanikop     // Part of the load_previous() function in the spec.
859*09537850SAkhilesh Sanikop     const int prev_frame_index =
860*09537850SAkhilesh Sanikop         frame_header_
861*09537850SAkhilesh Sanikop             .reference_frame_index[frame_header_.primary_reference_frame];
862*09537850SAkhilesh Sanikop     const RefCountedBuffer* prev_frame =
863*09537850SAkhilesh Sanikop         decoder_state_.reference_frame[prev_frame_index].get();
864*09537850SAkhilesh Sanikop     loop_filter->ref_deltas = prev_frame->loop_filter_ref_deltas();
865*09537850SAkhilesh Sanikop     loop_filter->mode_deltas = prev_frame->loop_filter_mode_deltas();
866*09537850SAkhilesh Sanikop   }
867*09537850SAkhilesh Sanikop   int64_t scratch;
868*09537850SAkhilesh Sanikop   for (int i = 0; i < 2; ++i) {
869*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(6);
870*09537850SAkhilesh Sanikop     loop_filter->level[i] = scratch;
871*09537850SAkhilesh Sanikop   }
872*09537850SAkhilesh Sanikop   if (!sequence_header_.color_config.is_monochrome &&
873*09537850SAkhilesh Sanikop       (loop_filter->level[0] != 0 || loop_filter->level[1] != 0)) {
874*09537850SAkhilesh Sanikop     for (int i = 2; i < 4; ++i) {
875*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(6);
876*09537850SAkhilesh Sanikop       loop_filter->level[i] = scratch;
877*09537850SAkhilesh Sanikop     }
878*09537850SAkhilesh Sanikop   }
879*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(3);
880*09537850SAkhilesh Sanikop   loop_filter->sharpness = scratch;
881*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
882*09537850SAkhilesh Sanikop   loop_filter->delta_enabled = scratch != 0;
883*09537850SAkhilesh Sanikop   if (loop_filter->delta_enabled) {
884*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
885*09537850SAkhilesh Sanikop     loop_filter->delta_update = scratch != 0;
886*09537850SAkhilesh Sanikop     if (loop_filter->delta_update) {
887*09537850SAkhilesh Sanikop       for (auto& ref_delta : loop_filter->ref_deltas) {
888*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
889*09537850SAkhilesh Sanikop         const bool update_ref_delta = scratch != 0;
890*09537850SAkhilesh Sanikop         if (update_ref_delta) {
891*09537850SAkhilesh Sanikop           int scratch_int;
892*09537850SAkhilesh Sanikop           if (!bit_reader_->ReadInverseSignedLiteral(6, &scratch_int)) {
893*09537850SAkhilesh Sanikop             LIBGAV1_DLOG(ERROR, "Not enough bits.");
894*09537850SAkhilesh Sanikop             return false;
895*09537850SAkhilesh Sanikop           }
896*09537850SAkhilesh Sanikop           ref_delta = scratch_int;
897*09537850SAkhilesh Sanikop         }
898*09537850SAkhilesh Sanikop       }
899*09537850SAkhilesh Sanikop       for (auto& mode_delta : loop_filter->mode_deltas) {
900*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
901*09537850SAkhilesh Sanikop         const bool update_mode_delta = scratch != 0;
902*09537850SAkhilesh Sanikop         if (update_mode_delta) {
903*09537850SAkhilesh Sanikop           int scratch_int;
904*09537850SAkhilesh Sanikop           if (!bit_reader_->ReadInverseSignedLiteral(6, &scratch_int)) {
905*09537850SAkhilesh Sanikop             LIBGAV1_DLOG(ERROR, "Not enough bits.");
906*09537850SAkhilesh Sanikop             return false;
907*09537850SAkhilesh Sanikop           }
908*09537850SAkhilesh Sanikop           mode_delta = scratch_int;
909*09537850SAkhilesh Sanikop         }
910*09537850SAkhilesh Sanikop       }
911*09537850SAkhilesh Sanikop     }
912*09537850SAkhilesh Sanikop   } else {
913*09537850SAkhilesh Sanikop     loop_filter->delta_update = false;
914*09537850SAkhilesh Sanikop   }
915*09537850SAkhilesh Sanikop   return true;
916*09537850SAkhilesh Sanikop }
917*09537850SAkhilesh Sanikop 
ParseDeltaQuantizer(int8_t * const delta)918*09537850SAkhilesh Sanikop bool ObuParser::ParseDeltaQuantizer(int8_t* const delta) {
919*09537850SAkhilesh Sanikop   int64_t scratch;
920*09537850SAkhilesh Sanikop   *delta = 0;
921*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
922*09537850SAkhilesh Sanikop   const bool delta_coded = scratch != 0;
923*09537850SAkhilesh Sanikop   if (delta_coded) {
924*09537850SAkhilesh Sanikop     int scratch_int;
925*09537850SAkhilesh Sanikop     if (!bit_reader_->ReadInverseSignedLiteral(6, &scratch_int)) {
926*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Not enough bits.");
927*09537850SAkhilesh Sanikop       return false;
928*09537850SAkhilesh Sanikop     }
929*09537850SAkhilesh Sanikop     *delta = scratch_int;
930*09537850SAkhilesh Sanikop   }
931*09537850SAkhilesh Sanikop   return true;
932*09537850SAkhilesh Sanikop }
933*09537850SAkhilesh Sanikop 
ParseQuantizerParameters()934*09537850SAkhilesh Sanikop bool ObuParser::ParseQuantizerParameters() {
935*09537850SAkhilesh Sanikop   int64_t scratch;
936*09537850SAkhilesh Sanikop   QuantizerParameters* const quantizer = &frame_header_.quantizer;
937*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(8);
938*09537850SAkhilesh Sanikop   quantizer->base_index = scratch;
939*09537850SAkhilesh Sanikop   if (!ParseDeltaQuantizer(&quantizer->delta_dc[kPlaneY])) return false;
940*09537850SAkhilesh Sanikop   if (!sequence_header_.color_config.is_monochrome) {
941*09537850SAkhilesh Sanikop     bool diff_uv_delta = false;
942*09537850SAkhilesh Sanikop     if (sequence_header_.color_config.separate_uv_delta_q) {
943*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
944*09537850SAkhilesh Sanikop       diff_uv_delta = scratch != 0;
945*09537850SAkhilesh Sanikop     }
946*09537850SAkhilesh Sanikop     if (!ParseDeltaQuantizer(&quantizer->delta_dc[kPlaneU]) ||
947*09537850SAkhilesh Sanikop         !ParseDeltaQuantizer(&quantizer->delta_ac[kPlaneU])) {
948*09537850SAkhilesh Sanikop       return false;
949*09537850SAkhilesh Sanikop     }
950*09537850SAkhilesh Sanikop     if (diff_uv_delta) {
951*09537850SAkhilesh Sanikop       if (!ParseDeltaQuantizer(&quantizer->delta_dc[kPlaneV]) ||
952*09537850SAkhilesh Sanikop           !ParseDeltaQuantizer(&quantizer->delta_ac[kPlaneV])) {
953*09537850SAkhilesh Sanikop         return false;
954*09537850SAkhilesh Sanikop       }
955*09537850SAkhilesh Sanikop     } else {
956*09537850SAkhilesh Sanikop       quantizer->delta_dc[kPlaneV] = quantizer->delta_dc[kPlaneU];
957*09537850SAkhilesh Sanikop       quantizer->delta_ac[kPlaneV] = quantizer->delta_ac[kPlaneU];
958*09537850SAkhilesh Sanikop     }
959*09537850SAkhilesh Sanikop   }
960*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
961*09537850SAkhilesh Sanikop   quantizer->use_matrix = scratch != 0;
962*09537850SAkhilesh Sanikop   if (quantizer->use_matrix) {
963*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
964*09537850SAkhilesh Sanikop     quantizer->matrix_level[kPlaneY] = scratch;
965*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
966*09537850SAkhilesh Sanikop     quantizer->matrix_level[kPlaneU] = scratch;
967*09537850SAkhilesh Sanikop     if (sequence_header_.color_config.separate_uv_delta_q) {
968*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(4);
969*09537850SAkhilesh Sanikop       quantizer->matrix_level[kPlaneV] = scratch;
970*09537850SAkhilesh Sanikop     } else {
971*09537850SAkhilesh Sanikop       quantizer->matrix_level[kPlaneV] = quantizer->matrix_level[kPlaneU];
972*09537850SAkhilesh Sanikop     }
973*09537850SAkhilesh Sanikop   }
974*09537850SAkhilesh Sanikop   return true;
975*09537850SAkhilesh Sanikop }
976*09537850SAkhilesh Sanikop 
977*09537850SAkhilesh Sanikop // This method implements the following functions in the spec:
978*09537850SAkhilesh Sanikop // - segmentation_params()
979*09537850SAkhilesh Sanikop // - part of setup_past_independence(): Set the FeatureData and FeatureEnabled
980*09537850SAkhilesh Sanikop //   arrays to all 0.
981*09537850SAkhilesh Sanikop // - part of load_previous(): Call load_segmentation_params().
982*09537850SAkhilesh Sanikop //
983*09537850SAkhilesh Sanikop // A careful analysis of the spec shows the part of setup_past_independence()
984*09537850SAkhilesh Sanikop // can be optimized away and the part of load_previous() only needs to be
985*09537850SAkhilesh Sanikop // invoked under a specific condition. Although the logic looks different from
986*09537850SAkhilesh Sanikop // the spec, it is equivalent and more efficient.
ParseSegmentationParameters()987*09537850SAkhilesh Sanikop bool ObuParser::ParseSegmentationParameters() {
988*09537850SAkhilesh Sanikop   int64_t scratch;
989*09537850SAkhilesh Sanikop   Segmentation* const segmentation = &frame_header_.segmentation;
990*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
991*09537850SAkhilesh Sanikop   segmentation->enabled = scratch != 0;
992*09537850SAkhilesh Sanikop   if (!segmentation->enabled) return true;
993*09537850SAkhilesh Sanikop   if (frame_header_.primary_reference_frame == kPrimaryReferenceNone) {
994*09537850SAkhilesh Sanikop     segmentation->update_map = true;
995*09537850SAkhilesh Sanikop     segmentation->update_data = true;
996*09537850SAkhilesh Sanikop   } else {
997*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
998*09537850SAkhilesh Sanikop     segmentation->update_map = scratch != 0;
999*09537850SAkhilesh Sanikop     if (segmentation->update_map) {
1000*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1001*09537850SAkhilesh Sanikop       segmentation->temporal_update = scratch != 0;
1002*09537850SAkhilesh Sanikop     }
1003*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1004*09537850SAkhilesh Sanikop     segmentation->update_data = scratch != 0;
1005*09537850SAkhilesh Sanikop     if (!segmentation->update_data) {
1006*09537850SAkhilesh Sanikop       // Part of the load_previous() function in the spec.
1007*09537850SAkhilesh Sanikop       const int prev_frame_index =
1008*09537850SAkhilesh Sanikop           frame_header_
1009*09537850SAkhilesh Sanikop               .reference_frame_index[frame_header_.primary_reference_frame];
1010*09537850SAkhilesh Sanikop       decoder_state_.reference_frame[prev_frame_index]
1011*09537850SAkhilesh Sanikop           ->GetSegmentationParameters(segmentation);
1012*09537850SAkhilesh Sanikop       return true;
1013*09537850SAkhilesh Sanikop     }
1014*09537850SAkhilesh Sanikop   }
1015*09537850SAkhilesh Sanikop   for (int8_t i = 0; i < kMaxSegments; ++i) {
1016*09537850SAkhilesh Sanikop     for (int8_t j = 0; j < kSegmentFeatureMax; ++j) {
1017*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1018*09537850SAkhilesh Sanikop       segmentation->feature_enabled[i][j] = scratch != 0;
1019*09537850SAkhilesh Sanikop       if (segmentation->feature_enabled[i][j]) {
1020*09537850SAkhilesh Sanikop         if (Segmentation::FeatureSigned(static_cast<SegmentFeature>(j))) {
1021*09537850SAkhilesh Sanikop           int scratch_int;
1022*09537850SAkhilesh Sanikop           if (!bit_reader_->ReadInverseSignedLiteral(
1023*09537850SAkhilesh Sanikop                   kSegmentationFeatureBits[j], &scratch_int)) {
1024*09537850SAkhilesh Sanikop             LIBGAV1_DLOG(ERROR, "Not enough bits.");
1025*09537850SAkhilesh Sanikop             return false;
1026*09537850SAkhilesh Sanikop           }
1027*09537850SAkhilesh Sanikop           segmentation->feature_data[i][j] =
1028*09537850SAkhilesh Sanikop               Clip3(scratch_int, -kSegmentationFeatureMaxValues[j],
1029*09537850SAkhilesh Sanikop                     kSegmentationFeatureMaxValues[j]);
1030*09537850SAkhilesh Sanikop         } else {
1031*09537850SAkhilesh Sanikop           if (kSegmentationFeatureBits[j] > 0) {
1032*09537850SAkhilesh Sanikop             OBU_READ_LITERAL_OR_FAIL(kSegmentationFeatureBits[j]);
1033*09537850SAkhilesh Sanikop             segmentation->feature_data[i][j] = Clip3(
1034*09537850SAkhilesh Sanikop                 static_cast<int>(scratch), 0, kSegmentationFeatureMaxValues[j]);
1035*09537850SAkhilesh Sanikop           } else {
1036*09537850SAkhilesh Sanikop             segmentation->feature_data[i][j] = 0;
1037*09537850SAkhilesh Sanikop           }
1038*09537850SAkhilesh Sanikop         }
1039*09537850SAkhilesh Sanikop         segmentation->last_active_segment_id = i;
1040*09537850SAkhilesh Sanikop         if (j >= kSegmentFeatureReferenceFrame) {
1041*09537850SAkhilesh Sanikop           segmentation->segment_id_pre_skip = true;
1042*09537850SAkhilesh Sanikop         }
1043*09537850SAkhilesh Sanikop       }
1044*09537850SAkhilesh Sanikop     }
1045*09537850SAkhilesh Sanikop   }
1046*09537850SAkhilesh Sanikop   return true;
1047*09537850SAkhilesh Sanikop }
1048*09537850SAkhilesh Sanikop 
ParseQuantizerIndexDeltaParameters()1049*09537850SAkhilesh Sanikop bool ObuParser::ParseQuantizerIndexDeltaParameters() {
1050*09537850SAkhilesh Sanikop   int64_t scratch;
1051*09537850SAkhilesh Sanikop   if (frame_header_.quantizer.base_index > 0) {
1052*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1053*09537850SAkhilesh Sanikop     frame_header_.delta_q.present = scratch != 0;
1054*09537850SAkhilesh Sanikop     if (frame_header_.delta_q.present) {
1055*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(2);
1056*09537850SAkhilesh Sanikop       frame_header_.delta_q.scale = scratch;
1057*09537850SAkhilesh Sanikop     }
1058*09537850SAkhilesh Sanikop   }
1059*09537850SAkhilesh Sanikop   return true;
1060*09537850SAkhilesh Sanikop }
1061*09537850SAkhilesh Sanikop 
ParseLoopFilterDeltaParameters()1062*09537850SAkhilesh Sanikop bool ObuParser::ParseLoopFilterDeltaParameters() {
1063*09537850SAkhilesh Sanikop   int64_t scratch;
1064*09537850SAkhilesh Sanikop   if (frame_header_.delta_q.present) {
1065*09537850SAkhilesh Sanikop     if (!frame_header_.allow_intrabc) {
1066*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1067*09537850SAkhilesh Sanikop       frame_header_.delta_lf.present = scratch != 0;
1068*09537850SAkhilesh Sanikop     }
1069*09537850SAkhilesh Sanikop     if (frame_header_.delta_lf.present) {
1070*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(2);
1071*09537850SAkhilesh Sanikop       frame_header_.delta_lf.scale = scratch;
1072*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1073*09537850SAkhilesh Sanikop       frame_header_.delta_lf.multi = scratch != 0;
1074*09537850SAkhilesh Sanikop     }
1075*09537850SAkhilesh Sanikop   }
1076*09537850SAkhilesh Sanikop   return true;
1077*09537850SAkhilesh Sanikop }
1078*09537850SAkhilesh Sanikop 
ComputeSegmentLosslessAndQIndex()1079*09537850SAkhilesh Sanikop void ObuParser::ComputeSegmentLosslessAndQIndex() {
1080*09537850SAkhilesh Sanikop   frame_header_.coded_lossless = true;
1081*09537850SAkhilesh Sanikop   Segmentation* const segmentation = &frame_header_.segmentation;
1082*09537850SAkhilesh Sanikop   const QuantizerParameters* const quantizer = &frame_header_.quantizer;
1083*09537850SAkhilesh Sanikop   for (int i = 0; i < kMaxSegments; ++i) {
1084*09537850SAkhilesh Sanikop     segmentation->qindex[i] =
1085*09537850SAkhilesh Sanikop         GetQIndex(*segmentation, i, quantizer->base_index);
1086*09537850SAkhilesh Sanikop     segmentation->lossless[i] =
1087*09537850SAkhilesh Sanikop         segmentation->qindex[i] == 0 && quantizer->delta_dc[kPlaneY] == 0 &&
1088*09537850SAkhilesh Sanikop         quantizer->delta_dc[kPlaneU] == 0 &&
1089*09537850SAkhilesh Sanikop         quantizer->delta_ac[kPlaneU] == 0 &&
1090*09537850SAkhilesh Sanikop         quantizer->delta_dc[kPlaneV] == 0 && quantizer->delta_ac[kPlaneV] == 0;
1091*09537850SAkhilesh Sanikop     if (!segmentation->lossless[i]) frame_header_.coded_lossless = false;
1092*09537850SAkhilesh Sanikop     // The spec calls for setting up a two-dimensional SegQMLevel array here.
1093*09537850SAkhilesh Sanikop     // We avoid the SegQMLevel array by using segmentation->lossless[i] and
1094*09537850SAkhilesh Sanikop     // quantizer->matrix_level[plane] directly in the reconstruct process of
1095*09537850SAkhilesh Sanikop     // Section 7.12.3.
1096*09537850SAkhilesh Sanikop   }
1097*09537850SAkhilesh Sanikop   frame_header_.upscaled_lossless =
1098*09537850SAkhilesh Sanikop       frame_header_.coded_lossless &&
1099*09537850SAkhilesh Sanikop       frame_header_.width == frame_header_.upscaled_width;
1100*09537850SAkhilesh Sanikop }
1101*09537850SAkhilesh Sanikop 
ParseCdefParameters()1102*09537850SAkhilesh Sanikop bool ObuParser::ParseCdefParameters() {
1103*09537850SAkhilesh Sanikop   const int coeff_shift = sequence_header_.color_config.bitdepth - 8;
1104*09537850SAkhilesh Sanikop   if (frame_header_.coded_lossless || frame_header_.allow_intrabc ||
1105*09537850SAkhilesh Sanikop       !sequence_header_.enable_cdef) {
1106*09537850SAkhilesh Sanikop     frame_header_.cdef.damping = 3 + coeff_shift;
1107*09537850SAkhilesh Sanikop     return true;
1108*09537850SAkhilesh Sanikop   }
1109*09537850SAkhilesh Sanikop   Cdef* const cdef = &frame_header_.cdef;
1110*09537850SAkhilesh Sanikop   int64_t scratch;
1111*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1112*09537850SAkhilesh Sanikop   cdef->damping = scratch + 3 + coeff_shift;
1113*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1114*09537850SAkhilesh Sanikop   cdef->bits = scratch;
1115*09537850SAkhilesh Sanikop   for (int i = 0; i < (1 << cdef->bits); ++i) {
1116*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
1117*09537850SAkhilesh Sanikop     cdef->y_primary_strength[i] = scratch << coeff_shift;
1118*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
1119*09537850SAkhilesh Sanikop     cdef->y_secondary_strength[i] = scratch;
1120*09537850SAkhilesh Sanikop     if (cdef->y_secondary_strength[i] == 3) ++cdef->y_secondary_strength[i];
1121*09537850SAkhilesh Sanikop     cdef->y_secondary_strength[i] <<= coeff_shift;
1122*09537850SAkhilesh Sanikop     if (sequence_header_.color_config.is_monochrome) continue;
1123*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
1124*09537850SAkhilesh Sanikop     cdef->uv_primary_strength[i] = scratch << coeff_shift;
1125*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
1126*09537850SAkhilesh Sanikop     cdef->uv_secondary_strength[i] = scratch;
1127*09537850SAkhilesh Sanikop     if (cdef->uv_secondary_strength[i] == 3) ++cdef->uv_secondary_strength[i];
1128*09537850SAkhilesh Sanikop     cdef->uv_secondary_strength[i] <<= coeff_shift;
1129*09537850SAkhilesh Sanikop   }
1130*09537850SAkhilesh Sanikop   return true;
1131*09537850SAkhilesh Sanikop }
1132*09537850SAkhilesh Sanikop 
ParseLoopRestorationParameters()1133*09537850SAkhilesh Sanikop bool ObuParser::ParseLoopRestorationParameters() {
1134*09537850SAkhilesh Sanikop   if (frame_header_.upscaled_lossless || frame_header_.allow_intrabc ||
1135*09537850SAkhilesh Sanikop       !sequence_header_.enable_restoration) {
1136*09537850SAkhilesh Sanikop     return true;
1137*09537850SAkhilesh Sanikop   }
1138*09537850SAkhilesh Sanikop   int64_t scratch;
1139*09537850SAkhilesh Sanikop   bool uses_loop_restoration = false;
1140*09537850SAkhilesh Sanikop   bool uses_chroma_loop_restoration = false;
1141*09537850SAkhilesh Sanikop   LoopRestoration* const loop_restoration = &frame_header_.loop_restoration;
1142*09537850SAkhilesh Sanikop   const int num_planes = sequence_header_.color_config.is_monochrome
1143*09537850SAkhilesh Sanikop                              ? kMaxPlanesMonochrome
1144*09537850SAkhilesh Sanikop                              : kMaxPlanes;
1145*09537850SAkhilesh Sanikop   for (int i = 0; i < num_planes; ++i) {
1146*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
1147*09537850SAkhilesh Sanikop     loop_restoration->type[i] = static_cast<LoopRestorationType>(scratch);
1148*09537850SAkhilesh Sanikop     if (loop_restoration->type[i] != kLoopRestorationTypeNone) {
1149*09537850SAkhilesh Sanikop       uses_loop_restoration = true;
1150*09537850SAkhilesh Sanikop       if (i > 0) uses_chroma_loop_restoration = true;
1151*09537850SAkhilesh Sanikop     }
1152*09537850SAkhilesh Sanikop   }
1153*09537850SAkhilesh Sanikop   if (uses_loop_restoration) {
1154*09537850SAkhilesh Sanikop     uint8_t unit_shift;
1155*09537850SAkhilesh Sanikop     if (sequence_header_.use_128x128_superblock) {
1156*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1157*09537850SAkhilesh Sanikop       unit_shift = scratch + 1;
1158*09537850SAkhilesh Sanikop     } else {
1159*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1160*09537850SAkhilesh Sanikop       unit_shift = scratch;
1161*09537850SAkhilesh Sanikop       if (unit_shift != 0) {
1162*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
1163*09537850SAkhilesh Sanikop         const uint8_t unit_extra_shift = scratch;
1164*09537850SAkhilesh Sanikop         unit_shift += unit_extra_shift;
1165*09537850SAkhilesh Sanikop       }
1166*09537850SAkhilesh Sanikop     }
1167*09537850SAkhilesh Sanikop     loop_restoration->unit_size_log2[kPlaneY] = 6 + unit_shift;
1168*09537850SAkhilesh Sanikop     uint8_t uv_shift = 0;
1169*09537850SAkhilesh Sanikop     if (sequence_header_.color_config.subsampling_x != 0 &&
1170*09537850SAkhilesh Sanikop         sequence_header_.color_config.subsampling_y != 0 &&
1171*09537850SAkhilesh Sanikop         uses_chroma_loop_restoration) {
1172*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1173*09537850SAkhilesh Sanikop       uv_shift = scratch;
1174*09537850SAkhilesh Sanikop     }
1175*09537850SAkhilesh Sanikop     loop_restoration->unit_size_log2[kPlaneU] =
1176*09537850SAkhilesh Sanikop         loop_restoration->unit_size_log2[kPlaneV] =
1177*09537850SAkhilesh Sanikop             loop_restoration->unit_size_log2[0] - uv_shift;
1178*09537850SAkhilesh Sanikop   }
1179*09537850SAkhilesh Sanikop   return true;
1180*09537850SAkhilesh Sanikop }
1181*09537850SAkhilesh Sanikop 
ParseTxModeSyntax()1182*09537850SAkhilesh Sanikop bool ObuParser::ParseTxModeSyntax() {
1183*09537850SAkhilesh Sanikop   if (frame_header_.coded_lossless) {
1184*09537850SAkhilesh Sanikop     frame_header_.tx_mode = kTxModeOnly4x4;
1185*09537850SAkhilesh Sanikop     return true;
1186*09537850SAkhilesh Sanikop   }
1187*09537850SAkhilesh Sanikop   int64_t scratch;
1188*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1189*09537850SAkhilesh Sanikop   frame_header_.tx_mode = (scratch == 1) ? kTxModeSelect : kTxModeLargest;
1190*09537850SAkhilesh Sanikop   return true;
1191*09537850SAkhilesh Sanikop }
1192*09537850SAkhilesh Sanikop 
ParseFrameReferenceModeSyntax()1193*09537850SAkhilesh Sanikop bool ObuParser::ParseFrameReferenceModeSyntax() {
1194*09537850SAkhilesh Sanikop   int64_t scratch;
1195*09537850SAkhilesh Sanikop   if (!IsIntraFrame(frame_header_.frame_type)) {
1196*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1197*09537850SAkhilesh Sanikop     frame_header_.reference_mode_select = scratch != 0;
1198*09537850SAkhilesh Sanikop   }
1199*09537850SAkhilesh Sanikop   return true;
1200*09537850SAkhilesh Sanikop }
1201*09537850SAkhilesh Sanikop 
IsSkipModeAllowed()1202*09537850SAkhilesh Sanikop bool ObuParser::IsSkipModeAllowed() {
1203*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type) ||
1204*09537850SAkhilesh Sanikop       !frame_header_.reference_mode_select ||
1205*09537850SAkhilesh Sanikop       !sequence_header_.enable_order_hint) {
1206*09537850SAkhilesh Sanikop     return false;
1207*09537850SAkhilesh Sanikop   }
1208*09537850SAkhilesh Sanikop   // Identify the nearest forward and backward references.
1209*09537850SAkhilesh Sanikop   int forward_index = -1;
1210*09537850SAkhilesh Sanikop   int backward_index = -1;
1211*09537850SAkhilesh Sanikop   int forward_hint = -1;
1212*09537850SAkhilesh Sanikop   int backward_hint = -1;
1213*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumInterReferenceFrameTypes; ++i) {
1214*09537850SAkhilesh Sanikop     const unsigned int reference_hint =
1215*09537850SAkhilesh Sanikop         decoder_state_
1216*09537850SAkhilesh Sanikop             .reference_order_hint[frame_header_.reference_frame_index[i]];
1217*09537850SAkhilesh Sanikop     // TODO(linfengz): |relative_distance| equals
1218*09537850SAkhilesh Sanikop     // current_frame_->reference_info()->
1219*09537850SAkhilesh Sanikop     //     relative_distance_from[i + kReferenceFrameLast];
1220*09537850SAkhilesh Sanikop     // However, the unit test ObuParserTest.SkipModeParameters() would fail.
1221*09537850SAkhilesh Sanikop     // Will figure out how to initialize |current_frame_.reference_info_| in the
1222*09537850SAkhilesh Sanikop     // RefCountedBuffer later.
1223*09537850SAkhilesh Sanikop     const int relative_distance =
1224*09537850SAkhilesh Sanikop         GetRelativeDistance(reference_hint, frame_header_.order_hint,
1225*09537850SAkhilesh Sanikop                             sequence_header_.order_hint_shift_bits);
1226*09537850SAkhilesh Sanikop     if (relative_distance < 0) {
1227*09537850SAkhilesh Sanikop       if (forward_index < 0 ||
1228*09537850SAkhilesh Sanikop           GetRelativeDistance(reference_hint, forward_hint,
1229*09537850SAkhilesh Sanikop                               sequence_header_.order_hint_shift_bits) > 0) {
1230*09537850SAkhilesh Sanikop         forward_index = i;
1231*09537850SAkhilesh Sanikop         forward_hint = reference_hint;
1232*09537850SAkhilesh Sanikop       }
1233*09537850SAkhilesh Sanikop     } else if (relative_distance > 0) {
1234*09537850SAkhilesh Sanikop       if (backward_index < 0 ||
1235*09537850SAkhilesh Sanikop           GetRelativeDistance(reference_hint, backward_hint,
1236*09537850SAkhilesh Sanikop                               sequence_header_.order_hint_shift_bits) < 0) {
1237*09537850SAkhilesh Sanikop         backward_index = i;
1238*09537850SAkhilesh Sanikop         backward_hint = reference_hint;
1239*09537850SAkhilesh Sanikop       }
1240*09537850SAkhilesh Sanikop     }
1241*09537850SAkhilesh Sanikop   }
1242*09537850SAkhilesh Sanikop   if (forward_index < 0) return false;
1243*09537850SAkhilesh Sanikop   if (backward_index >= 0) {
1244*09537850SAkhilesh Sanikop     // Bidirectional prediction.
1245*09537850SAkhilesh Sanikop     frame_header_.skip_mode_frame[0] = static_cast<ReferenceFrameType>(
1246*09537850SAkhilesh Sanikop         kReferenceFrameLast + std::min(forward_index, backward_index));
1247*09537850SAkhilesh Sanikop     frame_header_.skip_mode_frame[1] = static_cast<ReferenceFrameType>(
1248*09537850SAkhilesh Sanikop         kReferenceFrameLast + std::max(forward_index, backward_index));
1249*09537850SAkhilesh Sanikop     return true;
1250*09537850SAkhilesh Sanikop   }
1251*09537850SAkhilesh Sanikop   // Forward prediction only. Identify the second nearest forward reference.
1252*09537850SAkhilesh Sanikop   int second_forward_index = -1;
1253*09537850SAkhilesh Sanikop   int second_forward_hint = -1;
1254*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumInterReferenceFrameTypes; ++i) {
1255*09537850SAkhilesh Sanikop     const unsigned int reference_hint =
1256*09537850SAkhilesh Sanikop         decoder_state_
1257*09537850SAkhilesh Sanikop             .reference_order_hint[frame_header_.reference_frame_index[i]];
1258*09537850SAkhilesh Sanikop     if (GetRelativeDistance(reference_hint, forward_hint,
1259*09537850SAkhilesh Sanikop                             sequence_header_.order_hint_shift_bits) < 0) {
1260*09537850SAkhilesh Sanikop       if (second_forward_index < 0 ||
1261*09537850SAkhilesh Sanikop           GetRelativeDistance(reference_hint, second_forward_hint,
1262*09537850SAkhilesh Sanikop                               sequence_header_.order_hint_shift_bits) > 0) {
1263*09537850SAkhilesh Sanikop         second_forward_index = i;
1264*09537850SAkhilesh Sanikop         second_forward_hint = reference_hint;
1265*09537850SAkhilesh Sanikop       }
1266*09537850SAkhilesh Sanikop     }
1267*09537850SAkhilesh Sanikop   }
1268*09537850SAkhilesh Sanikop   if (second_forward_index < 0) return false;
1269*09537850SAkhilesh Sanikop   frame_header_.skip_mode_frame[0] = static_cast<ReferenceFrameType>(
1270*09537850SAkhilesh Sanikop       kReferenceFrameLast + std::min(forward_index, second_forward_index));
1271*09537850SAkhilesh Sanikop   frame_header_.skip_mode_frame[1] = static_cast<ReferenceFrameType>(
1272*09537850SAkhilesh Sanikop       kReferenceFrameLast + std::max(forward_index, second_forward_index));
1273*09537850SAkhilesh Sanikop   return true;
1274*09537850SAkhilesh Sanikop }
1275*09537850SAkhilesh Sanikop 
ParseSkipModeParameters()1276*09537850SAkhilesh Sanikop bool ObuParser::ParseSkipModeParameters() {
1277*09537850SAkhilesh Sanikop   if (!IsSkipModeAllowed()) return true;
1278*09537850SAkhilesh Sanikop   int64_t scratch;
1279*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1280*09537850SAkhilesh Sanikop   frame_header_.skip_mode_present = scratch != 0;
1281*09537850SAkhilesh Sanikop   return true;
1282*09537850SAkhilesh Sanikop }
1283*09537850SAkhilesh Sanikop 
1284*09537850SAkhilesh Sanikop // Sets frame_header_.global_motion[ref].params[index].
ParseGlobalParamSyntax(int ref,int index,const std::array<GlobalMotion,kNumReferenceFrameTypes> & prev_global_motions)1285*09537850SAkhilesh Sanikop bool ObuParser::ParseGlobalParamSyntax(
1286*09537850SAkhilesh Sanikop     int ref, int index,
1287*09537850SAkhilesh Sanikop     const std::array<GlobalMotion, kNumReferenceFrameTypes>&
1288*09537850SAkhilesh Sanikop         prev_global_motions) {
1289*09537850SAkhilesh Sanikop   GlobalMotion* const global_motion = &frame_header_.global_motion[ref];
1290*09537850SAkhilesh Sanikop   const GlobalMotion* const prev_global_motion = &prev_global_motions[ref];
1291*09537850SAkhilesh Sanikop   int abs_bits = kGlobalMotionAlphaBits;
1292*09537850SAkhilesh Sanikop   int precision_bits = kGlobalMotionAlphaPrecisionBits;
1293*09537850SAkhilesh Sanikop   if (index < 2) {
1294*09537850SAkhilesh Sanikop     if (global_motion->type == kGlobalMotionTransformationTypeTranslation) {
1295*09537850SAkhilesh Sanikop       const auto high_precision_mv_factor =
1296*09537850SAkhilesh Sanikop           static_cast<int>(!frame_header_.allow_high_precision_mv);
1297*09537850SAkhilesh Sanikop       abs_bits = kGlobalMotionTranslationOnlyBits - high_precision_mv_factor;
1298*09537850SAkhilesh Sanikop       precision_bits =
1299*09537850SAkhilesh Sanikop           kGlobalMotionTranslationOnlyPrecisionBits - high_precision_mv_factor;
1300*09537850SAkhilesh Sanikop     } else {
1301*09537850SAkhilesh Sanikop       abs_bits = kGlobalMotionTranslationBits;
1302*09537850SAkhilesh Sanikop       precision_bits = kGlobalMotionTranslationPrecisionBits;
1303*09537850SAkhilesh Sanikop     }
1304*09537850SAkhilesh Sanikop   }
1305*09537850SAkhilesh Sanikop   const int precision_diff = kWarpedModelPrecisionBits - precision_bits;
1306*09537850SAkhilesh Sanikop   const int round = (index % 3 == 2) ? 1 << kWarpedModelPrecisionBits : 0;
1307*09537850SAkhilesh Sanikop   const int sub = (index % 3 == 2) ? 1 << precision_bits : 0;
1308*09537850SAkhilesh Sanikop   const int mx = 1 << abs_bits;
1309*09537850SAkhilesh Sanikop   const int reference =
1310*09537850SAkhilesh Sanikop       (prev_global_motion->params[index] >> precision_diff) - sub;
1311*09537850SAkhilesh Sanikop   int scratch;
1312*09537850SAkhilesh Sanikop   if (!bit_reader_->DecodeSignedSubexpWithReference(
1313*09537850SAkhilesh Sanikop           -mx, mx + 1, reference, kGlobalMotionReadControl, &scratch)) {
1314*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Not enough bits.");
1315*09537850SAkhilesh Sanikop     return false;
1316*09537850SAkhilesh Sanikop   }
1317*09537850SAkhilesh Sanikop   global_motion->params[index] = LeftShift(scratch, precision_diff) + round;
1318*09537850SAkhilesh Sanikop   return true;
1319*09537850SAkhilesh Sanikop }
1320*09537850SAkhilesh Sanikop 
ParseGlobalMotionParameters()1321*09537850SAkhilesh Sanikop bool ObuParser::ParseGlobalMotionParameters() {
1322*09537850SAkhilesh Sanikop   for (int ref = kReferenceFrameLast; ref <= kReferenceFrameAlternate; ++ref) {
1323*09537850SAkhilesh Sanikop     frame_header_.global_motion[ref].type =
1324*09537850SAkhilesh Sanikop         kGlobalMotionTransformationTypeIdentity;
1325*09537850SAkhilesh Sanikop     for (int i = 0; i < 6; ++i) {
1326*09537850SAkhilesh Sanikop       frame_header_.global_motion[ref].params[i] =
1327*09537850SAkhilesh Sanikop           (i % 3 == 2) ? 1 << kWarpedModelPrecisionBits : 0;
1328*09537850SAkhilesh Sanikop     }
1329*09537850SAkhilesh Sanikop   }
1330*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type)) return true;
1331*09537850SAkhilesh Sanikop   const std::array<GlobalMotion, kNumReferenceFrameTypes>* prev_global_motions =
1332*09537850SAkhilesh Sanikop       nullptr;
1333*09537850SAkhilesh Sanikop   if (frame_header_.primary_reference_frame == kPrimaryReferenceNone) {
1334*09537850SAkhilesh Sanikop     // Part of the setup_past_independence() function in the spec. The value
1335*09537850SAkhilesh Sanikop     // that the spec says PrevGmParams[ref][i] should be set to is exactly
1336*09537850SAkhilesh Sanikop     // the value frame_header_.global_motion[ref].params[i] is set to by the
1337*09537850SAkhilesh Sanikop     // for loop above. Therefore prev_global_motions can simply point to
1338*09537850SAkhilesh Sanikop     // frame_header_.global_motion.
1339*09537850SAkhilesh Sanikop     prev_global_motions = &frame_header_.global_motion;
1340*09537850SAkhilesh Sanikop   } else {
1341*09537850SAkhilesh Sanikop     // Part of the load_previous() function in the spec.
1342*09537850SAkhilesh Sanikop     const int prev_frame_index =
1343*09537850SAkhilesh Sanikop         frame_header_
1344*09537850SAkhilesh Sanikop             .reference_frame_index[frame_header_.primary_reference_frame];
1345*09537850SAkhilesh Sanikop     prev_global_motions =
1346*09537850SAkhilesh Sanikop         &decoder_state_.reference_frame[prev_frame_index]->GlobalMotions();
1347*09537850SAkhilesh Sanikop   }
1348*09537850SAkhilesh Sanikop   for (int ref = kReferenceFrameLast; ref <= kReferenceFrameAlternate; ++ref) {
1349*09537850SAkhilesh Sanikop     GlobalMotion* const global_motion = &frame_header_.global_motion[ref];
1350*09537850SAkhilesh Sanikop     int64_t scratch;
1351*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1352*09537850SAkhilesh Sanikop     const bool is_global = scratch != 0;
1353*09537850SAkhilesh Sanikop     if (is_global) {
1354*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1355*09537850SAkhilesh Sanikop       const bool is_rot_zoom = scratch != 0;
1356*09537850SAkhilesh Sanikop       if (is_rot_zoom) {
1357*09537850SAkhilesh Sanikop         global_motion->type = kGlobalMotionTransformationTypeRotZoom;
1358*09537850SAkhilesh Sanikop       } else {
1359*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
1360*09537850SAkhilesh Sanikop         const bool is_translation = scratch != 0;
1361*09537850SAkhilesh Sanikop         global_motion->type = is_translation
1362*09537850SAkhilesh Sanikop                                   ? kGlobalMotionTransformationTypeTranslation
1363*09537850SAkhilesh Sanikop                                   : kGlobalMotionTransformationTypeAffine;
1364*09537850SAkhilesh Sanikop       }
1365*09537850SAkhilesh Sanikop     } else {
1366*09537850SAkhilesh Sanikop       global_motion->type = kGlobalMotionTransformationTypeIdentity;
1367*09537850SAkhilesh Sanikop     }
1368*09537850SAkhilesh Sanikop     if (global_motion->type >= kGlobalMotionTransformationTypeRotZoom) {
1369*09537850SAkhilesh Sanikop       if (!ParseGlobalParamSyntax(ref, 2, *prev_global_motions) ||
1370*09537850SAkhilesh Sanikop           !ParseGlobalParamSyntax(ref, 3, *prev_global_motions)) {
1371*09537850SAkhilesh Sanikop         return false;
1372*09537850SAkhilesh Sanikop       }
1373*09537850SAkhilesh Sanikop       if (global_motion->type == kGlobalMotionTransformationTypeAffine) {
1374*09537850SAkhilesh Sanikop         if (!ParseGlobalParamSyntax(ref, 4, *prev_global_motions) ||
1375*09537850SAkhilesh Sanikop             !ParseGlobalParamSyntax(ref, 5, *prev_global_motions)) {
1376*09537850SAkhilesh Sanikop           return false;
1377*09537850SAkhilesh Sanikop         }
1378*09537850SAkhilesh Sanikop       } else {
1379*09537850SAkhilesh Sanikop         global_motion->params[4] = -global_motion->params[3];
1380*09537850SAkhilesh Sanikop         global_motion->params[5] = global_motion->params[2];
1381*09537850SAkhilesh Sanikop       }
1382*09537850SAkhilesh Sanikop     }
1383*09537850SAkhilesh Sanikop     if (global_motion->type >= kGlobalMotionTransformationTypeTranslation) {
1384*09537850SAkhilesh Sanikop       if (!ParseGlobalParamSyntax(ref, 0, *prev_global_motions) ||
1385*09537850SAkhilesh Sanikop           !ParseGlobalParamSyntax(ref, 1, *prev_global_motions)) {
1386*09537850SAkhilesh Sanikop         return false;
1387*09537850SAkhilesh Sanikop       }
1388*09537850SAkhilesh Sanikop     }
1389*09537850SAkhilesh Sanikop   }
1390*09537850SAkhilesh Sanikop   return true;
1391*09537850SAkhilesh Sanikop }
1392*09537850SAkhilesh Sanikop 
ParseFilmGrainParameters()1393*09537850SAkhilesh Sanikop bool ObuParser::ParseFilmGrainParameters() {
1394*09537850SAkhilesh Sanikop   if (!sequence_header_.film_grain_params_present ||
1395*09537850SAkhilesh Sanikop       (!frame_header_.show_frame && !frame_header_.showable_frame)) {
1396*09537850SAkhilesh Sanikop     // frame_header_.film_grain_params is already zero-initialized.
1397*09537850SAkhilesh Sanikop     return true;
1398*09537850SAkhilesh Sanikop   }
1399*09537850SAkhilesh Sanikop 
1400*09537850SAkhilesh Sanikop   FilmGrainParams& film_grain_params = frame_header_.film_grain_params;
1401*09537850SAkhilesh Sanikop   int64_t scratch;
1402*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1403*09537850SAkhilesh Sanikop   film_grain_params.apply_grain = scratch != 0;
1404*09537850SAkhilesh Sanikop   if (!film_grain_params.apply_grain) {
1405*09537850SAkhilesh Sanikop     // film_grain_params is already zero-initialized.
1406*09537850SAkhilesh Sanikop     return true;
1407*09537850SAkhilesh Sanikop   }
1408*09537850SAkhilesh Sanikop 
1409*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(16);
1410*09537850SAkhilesh Sanikop   film_grain_params.grain_seed = static_cast<int>(scratch);
1411*09537850SAkhilesh Sanikop   film_grain_params.update_grain = true;
1412*09537850SAkhilesh Sanikop   if (frame_header_.frame_type == kFrameInter) {
1413*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1414*09537850SAkhilesh Sanikop     film_grain_params.update_grain = scratch != 0;
1415*09537850SAkhilesh Sanikop   }
1416*09537850SAkhilesh Sanikop   if (!film_grain_params.update_grain) {
1417*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
1418*09537850SAkhilesh Sanikop     film_grain_params.reference_index = static_cast<int>(scratch);
1419*09537850SAkhilesh Sanikop     bool found = false;
1420*09537850SAkhilesh Sanikop     for (const auto index : frame_header_.reference_frame_index) {
1421*09537850SAkhilesh Sanikop       if (film_grain_params.reference_index == index) {
1422*09537850SAkhilesh Sanikop         found = true;
1423*09537850SAkhilesh Sanikop         break;
1424*09537850SAkhilesh Sanikop       }
1425*09537850SAkhilesh Sanikop     }
1426*09537850SAkhilesh Sanikop     if (!found) {
1427*09537850SAkhilesh Sanikop       static_assert(sizeof(frame_header_.reference_frame_index) /
1428*09537850SAkhilesh Sanikop                             sizeof(frame_header_.reference_frame_index[0]) ==
1429*09537850SAkhilesh Sanikop                         7,
1430*09537850SAkhilesh Sanikop                     "");
1431*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
1432*09537850SAkhilesh Sanikop                    "Invalid value for film_grain_params_ref_idx (%d). "
1433*09537850SAkhilesh Sanikop                    "ref_frame_idx = {%d, %d, %d, %d, %d, %d, %d}",
1434*09537850SAkhilesh Sanikop                    film_grain_params.reference_index,
1435*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[0],
1436*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[1],
1437*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[2],
1438*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[3],
1439*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[4],
1440*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[5],
1441*09537850SAkhilesh Sanikop                    frame_header_.reference_frame_index[6]);
1442*09537850SAkhilesh Sanikop       return false;
1443*09537850SAkhilesh Sanikop     }
1444*09537850SAkhilesh Sanikop     const RefCountedBuffer* grain_params_reference_frame =
1445*09537850SAkhilesh Sanikop         decoder_state_.reference_frame[film_grain_params.reference_index].get();
1446*09537850SAkhilesh Sanikop     if (grain_params_reference_frame == nullptr) {
1447*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Buffer %d does not contain a decoded frame",
1448*09537850SAkhilesh Sanikop                    film_grain_params.reference_index);
1449*09537850SAkhilesh Sanikop       return false;
1450*09537850SAkhilesh Sanikop     }
1451*09537850SAkhilesh Sanikop     const int temp_grain_seed = film_grain_params.grain_seed;
1452*09537850SAkhilesh Sanikop     const bool temp_update_grain = film_grain_params.update_grain;
1453*09537850SAkhilesh Sanikop     const int temp_reference_index = film_grain_params.reference_index;
1454*09537850SAkhilesh Sanikop     film_grain_params = grain_params_reference_frame->film_grain_params();
1455*09537850SAkhilesh Sanikop     film_grain_params.grain_seed = temp_grain_seed;
1456*09537850SAkhilesh Sanikop     film_grain_params.update_grain = temp_update_grain;
1457*09537850SAkhilesh Sanikop     film_grain_params.reference_index = temp_reference_index;
1458*09537850SAkhilesh Sanikop     return true;
1459*09537850SAkhilesh Sanikop   }
1460*09537850SAkhilesh Sanikop 
1461*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(4);
1462*09537850SAkhilesh Sanikop   film_grain_params.num_y_points = scratch;
1463*09537850SAkhilesh Sanikop   if (film_grain_params.num_y_points > 14) {
1464*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Invalid value for num_y_points (%d).",
1465*09537850SAkhilesh Sanikop                  film_grain_params.num_y_points);
1466*09537850SAkhilesh Sanikop     return false;
1467*09537850SAkhilesh Sanikop   }
1468*09537850SAkhilesh Sanikop   for (int i = 0; i < film_grain_params.num_y_points; ++i) {
1469*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1470*09537850SAkhilesh Sanikop     film_grain_params.point_y_value[i] = scratch;
1471*09537850SAkhilesh Sanikop     if (i != 0 && film_grain_params.point_y_value[i - 1] >=
1472*09537850SAkhilesh Sanikop                       film_grain_params.point_y_value[i]) {
1473*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "point_y_value[%d] (%d) >= point_y_value[%d] (%d).",
1474*09537850SAkhilesh Sanikop                    i - 1, film_grain_params.point_y_value[i - 1], i,
1475*09537850SAkhilesh Sanikop                    film_grain_params.point_y_value[i]);
1476*09537850SAkhilesh Sanikop       return false;
1477*09537850SAkhilesh Sanikop     }
1478*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1479*09537850SAkhilesh Sanikop     film_grain_params.point_y_scaling[i] = scratch;
1480*09537850SAkhilesh Sanikop   }
1481*09537850SAkhilesh Sanikop   if (sequence_header_.color_config.is_monochrome) {
1482*09537850SAkhilesh Sanikop     film_grain_params.chroma_scaling_from_luma = false;
1483*09537850SAkhilesh Sanikop   } else {
1484*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1485*09537850SAkhilesh Sanikop     film_grain_params.chroma_scaling_from_luma = scratch != 0;
1486*09537850SAkhilesh Sanikop   }
1487*09537850SAkhilesh Sanikop   if (sequence_header_.color_config.is_monochrome ||
1488*09537850SAkhilesh Sanikop       film_grain_params.chroma_scaling_from_luma ||
1489*09537850SAkhilesh Sanikop       (sequence_header_.color_config.subsampling_x == 1 &&
1490*09537850SAkhilesh Sanikop        sequence_header_.color_config.subsampling_y == 1 &&
1491*09537850SAkhilesh Sanikop        film_grain_params.num_y_points == 0)) {
1492*09537850SAkhilesh Sanikop     film_grain_params.num_u_points = 0;
1493*09537850SAkhilesh Sanikop     film_grain_params.num_v_points = 0;
1494*09537850SAkhilesh Sanikop   } else {
1495*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
1496*09537850SAkhilesh Sanikop     film_grain_params.num_u_points = scratch;
1497*09537850SAkhilesh Sanikop     if (film_grain_params.num_u_points > 10) {
1498*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid value for num_u_points (%d).",
1499*09537850SAkhilesh Sanikop                    film_grain_params.num_u_points);
1500*09537850SAkhilesh Sanikop       return false;
1501*09537850SAkhilesh Sanikop     }
1502*09537850SAkhilesh Sanikop     for (int i = 0; i < film_grain_params.num_u_points; ++i) {
1503*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1504*09537850SAkhilesh Sanikop       film_grain_params.point_u_value[i] = scratch;
1505*09537850SAkhilesh Sanikop       if (i != 0 && film_grain_params.point_u_value[i - 1] >=
1506*09537850SAkhilesh Sanikop                         film_grain_params.point_u_value[i]) {
1507*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "point_u_value[%d] (%d) >= point_u_value[%d] (%d).",
1508*09537850SAkhilesh Sanikop                      i - 1, film_grain_params.point_u_value[i - 1], i,
1509*09537850SAkhilesh Sanikop                      film_grain_params.point_u_value[i]);
1510*09537850SAkhilesh Sanikop         return false;
1511*09537850SAkhilesh Sanikop       }
1512*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1513*09537850SAkhilesh Sanikop       film_grain_params.point_u_scaling[i] = scratch;
1514*09537850SAkhilesh Sanikop     }
1515*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(4);
1516*09537850SAkhilesh Sanikop     film_grain_params.num_v_points = scratch;
1517*09537850SAkhilesh Sanikop     if (film_grain_params.num_v_points > 10) {
1518*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid value for num_v_points (%d).",
1519*09537850SAkhilesh Sanikop                    film_grain_params.num_v_points);
1520*09537850SAkhilesh Sanikop       return false;
1521*09537850SAkhilesh Sanikop     }
1522*09537850SAkhilesh Sanikop     if (sequence_header_.color_config.subsampling_x == 1 &&
1523*09537850SAkhilesh Sanikop         sequence_header_.color_config.subsampling_y == 1 &&
1524*09537850SAkhilesh Sanikop         (film_grain_params.num_u_points == 0) !=
1525*09537850SAkhilesh Sanikop             (film_grain_params.num_v_points == 0)) {
1526*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
1527*09537850SAkhilesh Sanikop                    "Invalid values for num_u_points (%d) and num_v_points (%d) "
1528*09537850SAkhilesh Sanikop                    "for 4:2:0 chroma subsampling.",
1529*09537850SAkhilesh Sanikop                    film_grain_params.num_u_points,
1530*09537850SAkhilesh Sanikop                    film_grain_params.num_v_points);
1531*09537850SAkhilesh Sanikop       return false;
1532*09537850SAkhilesh Sanikop     }
1533*09537850SAkhilesh Sanikop     for (int i = 0; i < film_grain_params.num_v_points; ++i) {
1534*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1535*09537850SAkhilesh Sanikop       film_grain_params.point_v_value[i] = scratch;
1536*09537850SAkhilesh Sanikop       if (i != 0 && film_grain_params.point_v_value[i - 1] >=
1537*09537850SAkhilesh Sanikop                         film_grain_params.point_v_value[i]) {
1538*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "point_v_value[%d] (%d) >= point_v_value[%d] (%d).",
1539*09537850SAkhilesh Sanikop                      i - 1, film_grain_params.point_v_value[i - 1], i,
1540*09537850SAkhilesh Sanikop                      film_grain_params.point_v_value[i]);
1541*09537850SAkhilesh Sanikop         return false;
1542*09537850SAkhilesh Sanikop       }
1543*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1544*09537850SAkhilesh Sanikop       film_grain_params.point_v_scaling[i] = scratch;
1545*09537850SAkhilesh Sanikop     }
1546*09537850SAkhilesh Sanikop   }
1547*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1548*09537850SAkhilesh Sanikop   film_grain_params.chroma_scaling = scratch + 8;
1549*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1550*09537850SAkhilesh Sanikop   film_grain_params.auto_regression_coeff_lag = scratch;
1551*09537850SAkhilesh Sanikop 
1552*09537850SAkhilesh Sanikop   const int num_pos_y =
1553*09537850SAkhilesh Sanikop       MultiplyBy2(film_grain_params.auto_regression_coeff_lag) *
1554*09537850SAkhilesh Sanikop       (film_grain_params.auto_regression_coeff_lag + 1);
1555*09537850SAkhilesh Sanikop   int num_pos_uv = num_pos_y;
1556*09537850SAkhilesh Sanikop   if (film_grain_params.num_y_points > 0) {
1557*09537850SAkhilesh Sanikop     ++num_pos_uv;
1558*09537850SAkhilesh Sanikop     for (int i = 0; i < num_pos_y; ++i) {
1559*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1560*09537850SAkhilesh Sanikop       film_grain_params.auto_regression_coeff_y[i] =
1561*09537850SAkhilesh Sanikop           static_cast<int8_t>(scratch - 128);
1562*09537850SAkhilesh Sanikop     }
1563*09537850SAkhilesh Sanikop   }
1564*09537850SAkhilesh Sanikop   if (film_grain_params.chroma_scaling_from_luma ||
1565*09537850SAkhilesh Sanikop       film_grain_params.num_u_points > 0) {
1566*09537850SAkhilesh Sanikop     for (int i = 0; i < num_pos_uv; ++i) {
1567*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1568*09537850SAkhilesh Sanikop       film_grain_params.auto_regression_coeff_u[i] =
1569*09537850SAkhilesh Sanikop           static_cast<int8_t>(scratch - 128);
1570*09537850SAkhilesh Sanikop     }
1571*09537850SAkhilesh Sanikop   }
1572*09537850SAkhilesh Sanikop   if (film_grain_params.chroma_scaling_from_luma ||
1573*09537850SAkhilesh Sanikop       film_grain_params.num_v_points > 0) {
1574*09537850SAkhilesh Sanikop     for (int i = 0; i < num_pos_uv; ++i) {
1575*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
1576*09537850SAkhilesh Sanikop       film_grain_params.auto_regression_coeff_v[i] =
1577*09537850SAkhilesh Sanikop           static_cast<int8_t>(scratch - 128);
1578*09537850SAkhilesh Sanikop     }
1579*09537850SAkhilesh Sanikop   }
1580*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1581*09537850SAkhilesh Sanikop   film_grain_params.auto_regression_shift = static_cast<uint8_t>(scratch + 6);
1582*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(2);
1583*09537850SAkhilesh Sanikop   film_grain_params.grain_scale_shift = static_cast<int>(scratch);
1584*09537850SAkhilesh Sanikop   if (film_grain_params.num_u_points > 0) {
1585*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1586*09537850SAkhilesh Sanikop     film_grain_params.u_multiplier = static_cast<int8_t>(scratch - 128);
1587*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1588*09537850SAkhilesh Sanikop     film_grain_params.u_luma_multiplier = static_cast<int8_t>(scratch - 128);
1589*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(9);
1590*09537850SAkhilesh Sanikop     film_grain_params.u_offset = static_cast<int16_t>(scratch - 256);
1591*09537850SAkhilesh Sanikop   }
1592*09537850SAkhilesh Sanikop   if (film_grain_params.num_v_points > 0) {
1593*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1594*09537850SAkhilesh Sanikop     film_grain_params.v_multiplier = static_cast<int8_t>(scratch - 128);
1595*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1596*09537850SAkhilesh Sanikop     film_grain_params.v_luma_multiplier = static_cast<int8_t>(scratch - 128);
1597*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(9);
1598*09537850SAkhilesh Sanikop     film_grain_params.v_offset = static_cast<int16_t>(scratch - 256);
1599*09537850SAkhilesh Sanikop   }
1600*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1601*09537850SAkhilesh Sanikop   film_grain_params.overlap_flag = scratch != 0;
1602*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1603*09537850SAkhilesh Sanikop   film_grain_params.clip_to_restricted_range = scratch != 0;
1604*09537850SAkhilesh Sanikop   return true;
1605*09537850SAkhilesh Sanikop }
1606*09537850SAkhilesh Sanikop 
ParseTileInfoSyntax()1607*09537850SAkhilesh Sanikop bool ObuParser::ParseTileInfoSyntax() {
1608*09537850SAkhilesh Sanikop   TileInfo* const tile_info = &frame_header_.tile_info;
1609*09537850SAkhilesh Sanikop   const int sb_columns = sequence_header_.use_128x128_superblock
1610*09537850SAkhilesh Sanikop                              ? ((frame_header_.columns4x4 + 31) >> 5)
1611*09537850SAkhilesh Sanikop                              : ((frame_header_.columns4x4 + 15) >> 4);
1612*09537850SAkhilesh Sanikop   const int sb_rows = sequence_header_.use_128x128_superblock
1613*09537850SAkhilesh Sanikop                           ? ((frame_header_.rows4x4 + 31) >> 5)
1614*09537850SAkhilesh Sanikop                           : ((frame_header_.rows4x4 + 15) >> 4);
1615*09537850SAkhilesh Sanikop   tile_info->sb_columns = sb_columns;
1616*09537850SAkhilesh Sanikop   tile_info->sb_rows = sb_rows;
1617*09537850SAkhilesh Sanikop   const int sb_shift = sequence_header_.use_128x128_superblock ? 5 : 4;
1618*09537850SAkhilesh Sanikop   const int sb_size = 2 + sb_shift;
1619*09537850SAkhilesh Sanikop   const int sb_max_tile_width = kMaxTileWidth >> sb_size;
1620*09537850SAkhilesh Sanikop   const int sb_max_tile_area = kMaxTileArea >> MultiplyBy2(sb_size);
1621*09537850SAkhilesh Sanikop   const int minlog2_tile_columns = TileLog2(sb_max_tile_width, sb_columns);
1622*09537850SAkhilesh Sanikop   const int maxlog2_tile_columns =
1623*09537850SAkhilesh Sanikop       CeilLog2(std::min(sb_columns, static_cast<int>(kMaxTileColumns)));
1624*09537850SAkhilesh Sanikop   const int maxlog2_tile_rows =
1625*09537850SAkhilesh Sanikop       CeilLog2(std::min(sb_rows, static_cast<int>(kMaxTileRows)));
1626*09537850SAkhilesh Sanikop   const int min_log2_tiles = std::max(
1627*09537850SAkhilesh Sanikop       minlog2_tile_columns, TileLog2(sb_max_tile_area, sb_rows * sb_columns));
1628*09537850SAkhilesh Sanikop   int64_t scratch;
1629*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1630*09537850SAkhilesh Sanikop   tile_info->uniform_spacing = scratch != 0;
1631*09537850SAkhilesh Sanikop   if (tile_info->uniform_spacing) {
1632*09537850SAkhilesh Sanikop     // Read tile columns.
1633*09537850SAkhilesh Sanikop     tile_info->tile_columns_log2 = minlog2_tile_columns;
1634*09537850SAkhilesh Sanikop     while (tile_info->tile_columns_log2 < maxlog2_tile_columns) {
1635*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1636*09537850SAkhilesh Sanikop       if (scratch == 0) break;
1637*09537850SAkhilesh Sanikop       ++tile_info->tile_columns_log2;
1638*09537850SAkhilesh Sanikop     }
1639*09537850SAkhilesh Sanikop 
1640*09537850SAkhilesh Sanikop     // Compute tile column starts.
1641*09537850SAkhilesh Sanikop     const int sb_tile_width =
1642*09537850SAkhilesh Sanikop         (sb_columns + (1 << tile_info->tile_columns_log2) - 1) >>
1643*09537850SAkhilesh Sanikop         tile_info->tile_columns_log2;
1644*09537850SAkhilesh Sanikop     if (sb_tile_width <= 0) return false;
1645*09537850SAkhilesh Sanikop     int i = 0;
1646*09537850SAkhilesh Sanikop     for (int sb_start = 0; sb_start < sb_columns; sb_start += sb_tile_width) {
1647*09537850SAkhilesh Sanikop       if (i >= kMaxTileColumns) {
1648*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR,
1649*09537850SAkhilesh Sanikop                      "tile_columns would be greater than kMaxTileColumns.");
1650*09537850SAkhilesh Sanikop         return false;
1651*09537850SAkhilesh Sanikop       }
1652*09537850SAkhilesh Sanikop       tile_info->tile_column_start[i++] = sb_start << sb_shift;
1653*09537850SAkhilesh Sanikop     }
1654*09537850SAkhilesh Sanikop     tile_info->tile_column_start[i] = frame_header_.columns4x4;
1655*09537850SAkhilesh Sanikop     tile_info->tile_columns = i;
1656*09537850SAkhilesh Sanikop 
1657*09537850SAkhilesh Sanikop     // Read tile rows.
1658*09537850SAkhilesh Sanikop     const int minlog2_tile_rows =
1659*09537850SAkhilesh Sanikop         std::max(min_log2_tiles - tile_info->tile_columns_log2, 0);
1660*09537850SAkhilesh Sanikop     tile_info->tile_rows_log2 = minlog2_tile_rows;
1661*09537850SAkhilesh Sanikop     while (tile_info->tile_rows_log2 < maxlog2_tile_rows) {
1662*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1663*09537850SAkhilesh Sanikop       if (scratch == 0) break;
1664*09537850SAkhilesh Sanikop       ++tile_info->tile_rows_log2;
1665*09537850SAkhilesh Sanikop     }
1666*09537850SAkhilesh Sanikop 
1667*09537850SAkhilesh Sanikop     // Compute tile row starts.
1668*09537850SAkhilesh Sanikop     const int sb_tile_height =
1669*09537850SAkhilesh Sanikop         (sb_rows + (1 << tile_info->tile_rows_log2) - 1) >>
1670*09537850SAkhilesh Sanikop         tile_info->tile_rows_log2;
1671*09537850SAkhilesh Sanikop     if (sb_tile_height <= 0) return false;
1672*09537850SAkhilesh Sanikop     i = 0;
1673*09537850SAkhilesh Sanikop     for (int sb_start = 0; sb_start < sb_rows; sb_start += sb_tile_height) {
1674*09537850SAkhilesh Sanikop       if (i >= kMaxTileRows) {
1675*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "tile_rows would be greater than kMaxTileRows.");
1676*09537850SAkhilesh Sanikop         return false;
1677*09537850SAkhilesh Sanikop       }
1678*09537850SAkhilesh Sanikop       tile_info->tile_row_start[i++] = sb_start << sb_shift;
1679*09537850SAkhilesh Sanikop     }
1680*09537850SAkhilesh Sanikop     tile_info->tile_row_start[i] = frame_header_.rows4x4;
1681*09537850SAkhilesh Sanikop     tile_info->tile_rows = i;
1682*09537850SAkhilesh Sanikop   } else {
1683*09537850SAkhilesh Sanikop     int widest_tile_sb = 1;
1684*09537850SAkhilesh Sanikop     int i = 0;
1685*09537850SAkhilesh Sanikop     for (int sb_start = 0; sb_start < sb_columns; ++i) {
1686*09537850SAkhilesh Sanikop       if (i >= kMaxTileColumns) {
1687*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR,
1688*09537850SAkhilesh Sanikop                      "tile_columns would be greater than kMaxTileColumns.");
1689*09537850SAkhilesh Sanikop         return false;
1690*09537850SAkhilesh Sanikop       }
1691*09537850SAkhilesh Sanikop       tile_info->tile_column_start[i] = sb_start << sb_shift;
1692*09537850SAkhilesh Sanikop       const int max_width =
1693*09537850SAkhilesh Sanikop           std::min(sb_columns - sb_start, static_cast<int>(sb_max_tile_width));
1694*09537850SAkhilesh Sanikop       if (!bit_reader_->DecodeUniform(
1695*09537850SAkhilesh Sanikop               max_width, &tile_info->tile_column_width_in_superblocks[i])) {
1696*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Not enough bits.");
1697*09537850SAkhilesh Sanikop         return false;
1698*09537850SAkhilesh Sanikop       }
1699*09537850SAkhilesh Sanikop       ++tile_info->tile_column_width_in_superblocks[i];
1700*09537850SAkhilesh Sanikop       widest_tile_sb = std::max(tile_info->tile_column_width_in_superblocks[i],
1701*09537850SAkhilesh Sanikop                                 widest_tile_sb);
1702*09537850SAkhilesh Sanikop       sb_start += tile_info->tile_column_width_in_superblocks[i];
1703*09537850SAkhilesh Sanikop     }
1704*09537850SAkhilesh Sanikop     tile_info->tile_column_start[i] = frame_header_.columns4x4;
1705*09537850SAkhilesh Sanikop     tile_info->tile_columns = i;
1706*09537850SAkhilesh Sanikop     tile_info->tile_columns_log2 = CeilLog2(tile_info->tile_columns);
1707*09537850SAkhilesh Sanikop 
1708*09537850SAkhilesh Sanikop     int max_tile_area_sb = sb_rows * sb_columns;
1709*09537850SAkhilesh Sanikop     if (min_log2_tiles > 0) max_tile_area_sb >>= min_log2_tiles + 1;
1710*09537850SAkhilesh Sanikop     const int max_tile_height_sb =
1711*09537850SAkhilesh Sanikop         std::max(max_tile_area_sb / widest_tile_sb, 1);
1712*09537850SAkhilesh Sanikop 
1713*09537850SAkhilesh Sanikop     i = 0;
1714*09537850SAkhilesh Sanikop     for (int sb_start = 0; sb_start < sb_rows; ++i) {
1715*09537850SAkhilesh Sanikop       if (i >= kMaxTileRows) {
1716*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "tile_rows would be greater than kMaxTileRows.");
1717*09537850SAkhilesh Sanikop         return false;
1718*09537850SAkhilesh Sanikop       }
1719*09537850SAkhilesh Sanikop       tile_info->tile_row_start[i] = sb_start << sb_shift;
1720*09537850SAkhilesh Sanikop       const int max_height = std::min(sb_rows - sb_start, max_tile_height_sb);
1721*09537850SAkhilesh Sanikop       if (!bit_reader_->DecodeUniform(
1722*09537850SAkhilesh Sanikop               max_height, &tile_info->tile_row_height_in_superblocks[i])) {
1723*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Not enough bits.");
1724*09537850SAkhilesh Sanikop         return false;
1725*09537850SAkhilesh Sanikop       }
1726*09537850SAkhilesh Sanikop       ++tile_info->tile_row_height_in_superblocks[i];
1727*09537850SAkhilesh Sanikop       sb_start += tile_info->tile_row_height_in_superblocks[i];
1728*09537850SAkhilesh Sanikop     }
1729*09537850SAkhilesh Sanikop     tile_info->tile_row_start[i] = frame_header_.rows4x4;
1730*09537850SAkhilesh Sanikop     tile_info->tile_rows = i;
1731*09537850SAkhilesh Sanikop     tile_info->tile_rows_log2 = CeilLog2(tile_info->tile_rows);
1732*09537850SAkhilesh Sanikop   }
1733*09537850SAkhilesh Sanikop   tile_info->tile_count = tile_info->tile_rows * tile_info->tile_columns;
1734*09537850SAkhilesh Sanikop   if (!tile_buffers_.reserve(tile_info->tile_count)) {
1735*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Unable to allocate memory for tile_buffers_.");
1736*09537850SAkhilesh Sanikop     return false;
1737*09537850SAkhilesh Sanikop   }
1738*09537850SAkhilesh Sanikop   tile_info->context_update_id = 0;
1739*09537850SAkhilesh Sanikop   const int tile_bits =
1740*09537850SAkhilesh Sanikop       tile_info->tile_columns_log2 + tile_info->tile_rows_log2;
1741*09537850SAkhilesh Sanikop   if (tile_bits != 0) {
1742*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(tile_bits);
1743*09537850SAkhilesh Sanikop     tile_info->context_update_id = static_cast<int16_t>(scratch);
1744*09537850SAkhilesh Sanikop     if (tile_info->context_update_id >= tile_info->tile_count) {
1745*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid context_update_tile_id (%d) >= %d.",
1746*09537850SAkhilesh Sanikop                    tile_info->context_update_id, tile_info->tile_count);
1747*09537850SAkhilesh Sanikop       return false;
1748*09537850SAkhilesh Sanikop     }
1749*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
1750*09537850SAkhilesh Sanikop     tile_info->tile_size_bytes = 1 + scratch;
1751*09537850SAkhilesh Sanikop   }
1752*09537850SAkhilesh Sanikop   return true;
1753*09537850SAkhilesh Sanikop }
1754*09537850SAkhilesh Sanikop 
ReadAllowWarpedMotion()1755*09537850SAkhilesh Sanikop bool ObuParser::ReadAllowWarpedMotion() {
1756*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type) ||
1757*09537850SAkhilesh Sanikop       frame_header_.error_resilient_mode ||
1758*09537850SAkhilesh Sanikop       !sequence_header_.enable_warped_motion) {
1759*09537850SAkhilesh Sanikop     return true;
1760*09537850SAkhilesh Sanikop   }
1761*09537850SAkhilesh Sanikop   int64_t scratch;
1762*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1763*09537850SAkhilesh Sanikop   frame_header_.allow_warped_motion = scratch != 0;
1764*09537850SAkhilesh Sanikop   return true;
1765*09537850SAkhilesh Sanikop }
1766*09537850SAkhilesh Sanikop 
ParseFrameParameters()1767*09537850SAkhilesh Sanikop bool ObuParser::ParseFrameParameters() {
1768*09537850SAkhilesh Sanikop   int64_t scratch;
1769*09537850SAkhilesh Sanikop   if (sequence_header_.reduced_still_picture_header) {
1770*09537850SAkhilesh Sanikop     frame_header_.show_frame = true;
1771*09537850SAkhilesh Sanikop     if (!EnsureCurrentFrameIsNotNull()) return false;
1772*09537850SAkhilesh Sanikop   } else {
1773*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1774*09537850SAkhilesh Sanikop     frame_header_.show_existing_frame = scratch != 0;
1775*09537850SAkhilesh Sanikop     if (frame_header_.show_existing_frame) {
1776*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(3);
1777*09537850SAkhilesh Sanikop       frame_header_.frame_to_show = scratch;
1778*09537850SAkhilesh Sanikop       if (sequence_header_.decoder_model_info_present_flag &&
1779*09537850SAkhilesh Sanikop           !sequence_header_.timing_info.equal_picture_interval) {
1780*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(
1781*09537850SAkhilesh Sanikop             sequence_header_.decoder_model_info.frame_presentation_time_length);
1782*09537850SAkhilesh Sanikop         frame_header_.frame_presentation_time = static_cast<uint32_t>(scratch);
1783*09537850SAkhilesh Sanikop       }
1784*09537850SAkhilesh Sanikop       if (sequence_header_.frame_id_numbers_present) {
1785*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(sequence_header_.frame_id_length_bits);
1786*09537850SAkhilesh Sanikop         frame_header_.display_frame_id = static_cast<uint16_t>(scratch);
1787*09537850SAkhilesh Sanikop         // Section 6.8.2: It is a requirement of bitstream conformance that
1788*09537850SAkhilesh Sanikop         // whenever display_frame_id is read, the value matches
1789*09537850SAkhilesh Sanikop         // RefFrameId[ frame_to_show_map_idx ] ..., and that
1790*09537850SAkhilesh Sanikop         // RefValid[ frame_to_show_map_idx ] is equal to 1.
1791*09537850SAkhilesh Sanikop         //
1792*09537850SAkhilesh Sanikop         // The current_frame_ == nullptr check below is equivalent to checking
1793*09537850SAkhilesh Sanikop         // if RefValid[ frame_to_show_map_idx ] is equal to 1.
1794*09537850SAkhilesh Sanikop         if (frame_header_.display_frame_id !=
1795*09537850SAkhilesh Sanikop             decoder_state_.reference_frame_id[frame_header_.frame_to_show]) {
1796*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
1797*09537850SAkhilesh Sanikop                        "Reference buffer %d has a frame id number mismatch.",
1798*09537850SAkhilesh Sanikop                        frame_header_.frame_to_show);
1799*09537850SAkhilesh Sanikop           return false;
1800*09537850SAkhilesh Sanikop         }
1801*09537850SAkhilesh Sanikop       }
1802*09537850SAkhilesh Sanikop       // Section 7.18.2. Note: This is also needed for Section 7.21 if
1803*09537850SAkhilesh Sanikop       // frame_type is kFrameKey.
1804*09537850SAkhilesh Sanikop       current_frame_ =
1805*09537850SAkhilesh Sanikop           decoder_state_.reference_frame[frame_header_.frame_to_show];
1806*09537850SAkhilesh Sanikop       if (current_frame_ == nullptr) {
1807*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Buffer %d does not contain a decoded frame",
1808*09537850SAkhilesh Sanikop                      frame_header_.frame_to_show);
1809*09537850SAkhilesh Sanikop         return false;
1810*09537850SAkhilesh Sanikop       }
1811*09537850SAkhilesh Sanikop       // Section 6.8.2: It is a requirement of bitstream conformance that
1812*09537850SAkhilesh Sanikop       // when show_existing_frame is used to show a previous frame, that the
1813*09537850SAkhilesh Sanikop       // value of showable_frame for the previous frame was equal to 1.
1814*09537850SAkhilesh Sanikop       if (!current_frame_->showable_frame()) {
1815*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Buffer %d does not contain a showable frame",
1816*09537850SAkhilesh Sanikop                      frame_header_.frame_to_show);
1817*09537850SAkhilesh Sanikop         return false;
1818*09537850SAkhilesh Sanikop       }
1819*09537850SAkhilesh Sanikop       if (current_frame_->frame_type() == kFrameKey) {
1820*09537850SAkhilesh Sanikop         frame_header_.refresh_frame_flags = 0xff;
1821*09537850SAkhilesh Sanikop         // Section 6.8.2: It is a requirement of bitstream conformance that
1822*09537850SAkhilesh Sanikop         // when show_existing_frame is used to show a previous frame with
1823*09537850SAkhilesh Sanikop         // RefFrameType[ frame_to_show_map_idx ] equal to KEY_FRAME, that
1824*09537850SAkhilesh Sanikop         // the frame is output via the show_existing_frame mechanism at most
1825*09537850SAkhilesh Sanikop         // once.
1826*09537850SAkhilesh Sanikop         current_frame_->set_showable_frame(false);
1827*09537850SAkhilesh Sanikop 
1828*09537850SAkhilesh Sanikop         // Section 7.21. Note: decoder_state_.current_frame_id must be set
1829*09537850SAkhilesh Sanikop         // only when frame_type is kFrameKey per the spec. Among all the
1830*09537850SAkhilesh Sanikop         // variables set in Section 7.21, current_frame_id is the only one
1831*09537850SAkhilesh Sanikop         // whose value lives across frames. (PrevFrameID is set equal to the
1832*09537850SAkhilesh Sanikop         // current_frame_id value for the previous frame.)
1833*09537850SAkhilesh Sanikop         decoder_state_.current_frame_id =
1834*09537850SAkhilesh Sanikop             decoder_state_.reference_frame_id[frame_header_.frame_to_show];
1835*09537850SAkhilesh Sanikop         decoder_state_.order_hint =
1836*09537850SAkhilesh Sanikop             decoder_state_.reference_order_hint[frame_header_.frame_to_show];
1837*09537850SAkhilesh Sanikop       }
1838*09537850SAkhilesh Sanikop       return true;
1839*09537850SAkhilesh Sanikop     }
1840*09537850SAkhilesh Sanikop     if (!EnsureCurrentFrameIsNotNull()) return false;
1841*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
1842*09537850SAkhilesh Sanikop     frame_header_.frame_type = static_cast<FrameType>(scratch);
1843*09537850SAkhilesh Sanikop     current_frame_->set_frame_type(frame_header_.frame_type);
1844*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1845*09537850SAkhilesh Sanikop     frame_header_.show_frame = scratch != 0;
1846*09537850SAkhilesh Sanikop     if (frame_header_.show_frame &&
1847*09537850SAkhilesh Sanikop         sequence_header_.decoder_model_info_present_flag &&
1848*09537850SAkhilesh Sanikop         !sequence_header_.timing_info.equal_picture_interval) {
1849*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(
1850*09537850SAkhilesh Sanikop           sequence_header_.decoder_model_info.frame_presentation_time_length);
1851*09537850SAkhilesh Sanikop       frame_header_.frame_presentation_time = static_cast<uint32_t>(scratch);
1852*09537850SAkhilesh Sanikop     }
1853*09537850SAkhilesh Sanikop     if (frame_header_.show_frame) {
1854*09537850SAkhilesh Sanikop       frame_header_.showable_frame = (frame_header_.frame_type != kFrameKey);
1855*09537850SAkhilesh Sanikop     } else {
1856*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1857*09537850SAkhilesh Sanikop       frame_header_.showable_frame = scratch != 0;
1858*09537850SAkhilesh Sanikop     }
1859*09537850SAkhilesh Sanikop     current_frame_->set_showable_frame(frame_header_.showable_frame);
1860*09537850SAkhilesh Sanikop     if (frame_header_.frame_type == kFrameSwitch ||
1861*09537850SAkhilesh Sanikop         (frame_header_.frame_type == kFrameKey && frame_header_.show_frame)) {
1862*09537850SAkhilesh Sanikop       frame_header_.error_resilient_mode = true;
1863*09537850SAkhilesh Sanikop     } else {
1864*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1865*09537850SAkhilesh Sanikop       frame_header_.error_resilient_mode = scratch != 0;
1866*09537850SAkhilesh Sanikop     }
1867*09537850SAkhilesh Sanikop   }
1868*09537850SAkhilesh Sanikop   if (frame_header_.frame_type == kFrameKey && frame_header_.show_frame) {
1869*09537850SAkhilesh Sanikop     decoder_state_.reference_order_hint.fill(0);
1870*09537850SAkhilesh Sanikop     decoder_state_.reference_frame.fill(nullptr);
1871*09537850SAkhilesh Sanikop   }
1872*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
1873*09537850SAkhilesh Sanikop   frame_header_.enable_cdf_update = scratch == 0;
1874*09537850SAkhilesh Sanikop   if (sequence_header_.force_screen_content_tools ==
1875*09537850SAkhilesh Sanikop       kSelectScreenContentTools) {
1876*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1877*09537850SAkhilesh Sanikop     frame_header_.allow_screen_content_tools = scratch != 0;
1878*09537850SAkhilesh Sanikop   } else {
1879*09537850SAkhilesh Sanikop     frame_header_.allow_screen_content_tools =
1880*09537850SAkhilesh Sanikop         sequence_header_.force_screen_content_tools != 0;
1881*09537850SAkhilesh Sanikop   }
1882*09537850SAkhilesh Sanikop   if (frame_header_.allow_screen_content_tools) {
1883*09537850SAkhilesh Sanikop     if (sequence_header_.force_integer_mv == kSelectIntegerMv) {
1884*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1885*09537850SAkhilesh Sanikop       frame_header_.force_integer_mv = scratch;
1886*09537850SAkhilesh Sanikop     } else {
1887*09537850SAkhilesh Sanikop       frame_header_.force_integer_mv = sequence_header_.force_integer_mv;
1888*09537850SAkhilesh Sanikop     }
1889*09537850SAkhilesh Sanikop   } else {
1890*09537850SAkhilesh Sanikop     frame_header_.force_integer_mv = 0;
1891*09537850SAkhilesh Sanikop   }
1892*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type)) {
1893*09537850SAkhilesh Sanikop     frame_header_.force_integer_mv = 1;
1894*09537850SAkhilesh Sanikop   }
1895*09537850SAkhilesh Sanikop   if (sequence_header_.frame_id_numbers_present) {
1896*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(sequence_header_.frame_id_length_bits);
1897*09537850SAkhilesh Sanikop     frame_header_.current_frame_id = static_cast<uint16_t>(scratch);
1898*09537850SAkhilesh Sanikop     const int previous_frame_id = decoder_state_.current_frame_id;
1899*09537850SAkhilesh Sanikop     decoder_state_.current_frame_id = frame_header_.current_frame_id;
1900*09537850SAkhilesh Sanikop     if (frame_header_.frame_type != kFrameKey || !frame_header_.show_frame) {
1901*09537850SAkhilesh Sanikop       if (previous_frame_id >= 0) {
1902*09537850SAkhilesh Sanikop         // Section 6.8.2: ..., it is a requirement of bitstream conformance
1903*09537850SAkhilesh Sanikop         // that all of the following conditions are true:
1904*09537850SAkhilesh Sanikop         //   * current_frame_id is not equal to PrevFrameID,
1905*09537850SAkhilesh Sanikop         //   * DiffFrameID is less than 1 << ( idLen - 1 )
1906*09537850SAkhilesh Sanikop         int diff_frame_id = decoder_state_.current_frame_id - previous_frame_id;
1907*09537850SAkhilesh Sanikop         const int id_length_max_value =
1908*09537850SAkhilesh Sanikop             1 << sequence_header_.frame_id_length_bits;
1909*09537850SAkhilesh Sanikop         if (diff_frame_id <= 0) {
1910*09537850SAkhilesh Sanikop           diff_frame_id += id_length_max_value;
1911*09537850SAkhilesh Sanikop         }
1912*09537850SAkhilesh Sanikop         if (diff_frame_id >= DivideBy2(id_length_max_value)) {
1913*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
1914*09537850SAkhilesh Sanikop                        "current_frame_id (%d) equals or differs too much from "
1915*09537850SAkhilesh Sanikop                        "previous_frame_id (%d).",
1916*09537850SAkhilesh Sanikop                        decoder_state_.current_frame_id, previous_frame_id);
1917*09537850SAkhilesh Sanikop           return false;
1918*09537850SAkhilesh Sanikop         }
1919*09537850SAkhilesh Sanikop       }
1920*09537850SAkhilesh Sanikop       MarkInvalidReferenceFrames();
1921*09537850SAkhilesh Sanikop     }
1922*09537850SAkhilesh Sanikop   } else {
1923*09537850SAkhilesh Sanikop     frame_header_.current_frame_id = 0;
1924*09537850SAkhilesh Sanikop     decoder_state_.current_frame_id = frame_header_.current_frame_id;
1925*09537850SAkhilesh Sanikop   }
1926*09537850SAkhilesh Sanikop   if (frame_header_.frame_type == kFrameSwitch) {
1927*09537850SAkhilesh Sanikop     frame_header_.frame_size_override_flag = true;
1928*09537850SAkhilesh Sanikop   } else if (!sequence_header_.reduced_still_picture_header) {
1929*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1930*09537850SAkhilesh Sanikop     frame_header_.frame_size_override_flag = scratch != 0;
1931*09537850SAkhilesh Sanikop   }
1932*09537850SAkhilesh Sanikop   if (sequence_header_.order_hint_bits > 0) {
1933*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(sequence_header_.order_hint_bits);
1934*09537850SAkhilesh Sanikop     frame_header_.order_hint = scratch;
1935*09537850SAkhilesh Sanikop   }
1936*09537850SAkhilesh Sanikop   decoder_state_.order_hint = frame_header_.order_hint;
1937*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type) ||
1938*09537850SAkhilesh Sanikop       frame_header_.error_resilient_mode) {
1939*09537850SAkhilesh Sanikop     frame_header_.primary_reference_frame = kPrimaryReferenceNone;
1940*09537850SAkhilesh Sanikop   } else {
1941*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
1942*09537850SAkhilesh Sanikop     frame_header_.primary_reference_frame = scratch;
1943*09537850SAkhilesh Sanikop   }
1944*09537850SAkhilesh Sanikop   if (sequence_header_.decoder_model_info_present_flag) {
1945*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
1946*09537850SAkhilesh Sanikop     const bool buffer_removal_time_present = scratch != 0;
1947*09537850SAkhilesh Sanikop     if (buffer_removal_time_present) {
1948*09537850SAkhilesh Sanikop       for (int i = 0; i < sequence_header_.operating_points; ++i) {
1949*09537850SAkhilesh Sanikop         if (!sequence_header_.decoder_model_present_for_operating_point[i]) {
1950*09537850SAkhilesh Sanikop           continue;
1951*09537850SAkhilesh Sanikop         }
1952*09537850SAkhilesh Sanikop         const int index = sequence_header_.operating_point_idc[i];
1953*09537850SAkhilesh Sanikop         if (index == 0 ||
1954*09537850SAkhilesh Sanikop             (InTemporalLayer(index, obu_headers_.back().temporal_id) &&
1955*09537850SAkhilesh Sanikop              InSpatialLayer(index, obu_headers_.back().spatial_id))) {
1956*09537850SAkhilesh Sanikop           OBU_READ_LITERAL_OR_FAIL(
1957*09537850SAkhilesh Sanikop               sequence_header_.decoder_model_info.buffer_removal_time_length);
1958*09537850SAkhilesh Sanikop           frame_header_.buffer_removal_time[i] = static_cast<uint32_t>(scratch);
1959*09537850SAkhilesh Sanikop         }
1960*09537850SAkhilesh Sanikop       }
1961*09537850SAkhilesh Sanikop     }
1962*09537850SAkhilesh Sanikop   }
1963*09537850SAkhilesh Sanikop   if (frame_header_.frame_type == kFrameSwitch ||
1964*09537850SAkhilesh Sanikop       (frame_header_.frame_type == kFrameKey && frame_header_.show_frame)) {
1965*09537850SAkhilesh Sanikop     frame_header_.refresh_frame_flags = 0xff;
1966*09537850SAkhilesh Sanikop   } else {
1967*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(8);
1968*09537850SAkhilesh Sanikop     frame_header_.refresh_frame_flags = scratch;
1969*09537850SAkhilesh Sanikop     // Section 6.8.2: If frame_type is equal to INTRA_ONLY_FRAME, it is a
1970*09537850SAkhilesh Sanikop     // requirement of bitstream conformance that refresh_frame_flags is not
1971*09537850SAkhilesh Sanikop     // equal to 0xff.
1972*09537850SAkhilesh Sanikop     if (frame_header_.frame_type == kFrameIntraOnly &&
1973*09537850SAkhilesh Sanikop         frame_header_.refresh_frame_flags == 0xff) {
1974*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Intra only frames cannot have refresh flags 0xFF.");
1975*09537850SAkhilesh Sanikop       return false;
1976*09537850SAkhilesh Sanikop     }
1977*09537850SAkhilesh Sanikop   }
1978*09537850SAkhilesh Sanikop   if ((!IsIntraFrame(frame_header_.frame_type) ||
1979*09537850SAkhilesh Sanikop        frame_header_.refresh_frame_flags != 0xff) &&
1980*09537850SAkhilesh Sanikop       !ParseReferenceOrderHint()) {
1981*09537850SAkhilesh Sanikop     return false;
1982*09537850SAkhilesh Sanikop   }
1983*09537850SAkhilesh Sanikop   if (IsIntraFrame(frame_header_.frame_type)) {
1984*09537850SAkhilesh Sanikop     if (!ParseFrameSizeAndRenderSize()) return false;
1985*09537850SAkhilesh Sanikop     if (frame_header_.allow_screen_content_tools &&
1986*09537850SAkhilesh Sanikop         frame_header_.width == frame_header_.upscaled_width) {
1987*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1988*09537850SAkhilesh Sanikop       frame_header_.allow_intrabc = scratch != 0;
1989*09537850SAkhilesh Sanikop     }
1990*09537850SAkhilesh Sanikop   } else {
1991*09537850SAkhilesh Sanikop     if (!sequence_header_.enable_order_hint) {
1992*09537850SAkhilesh Sanikop       frame_header_.frame_refs_short_signaling = false;
1993*09537850SAkhilesh Sanikop     } else {
1994*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
1995*09537850SAkhilesh Sanikop       frame_header_.frame_refs_short_signaling = scratch != 0;
1996*09537850SAkhilesh Sanikop       if (frame_header_.frame_refs_short_signaling) {
1997*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(3);
1998*09537850SAkhilesh Sanikop         const int8_t last_frame_idx = scratch;
1999*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(3);
2000*09537850SAkhilesh Sanikop         const int8_t gold_frame_idx = scratch;
2001*09537850SAkhilesh Sanikop         if (!SetFrameReferences(last_frame_idx, gold_frame_idx)) {
2002*09537850SAkhilesh Sanikop           return false;
2003*09537850SAkhilesh Sanikop         }
2004*09537850SAkhilesh Sanikop       }
2005*09537850SAkhilesh Sanikop     }
2006*09537850SAkhilesh Sanikop     for (int i = 0; i < kNumInterReferenceFrameTypes; ++i) {
2007*09537850SAkhilesh Sanikop       if (!frame_header_.frame_refs_short_signaling) {
2008*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(3);
2009*09537850SAkhilesh Sanikop         frame_header_.reference_frame_index[i] = scratch;
2010*09537850SAkhilesh Sanikop       }
2011*09537850SAkhilesh Sanikop       const int reference_frame_index = frame_header_.reference_frame_index[i];
2012*09537850SAkhilesh Sanikop       assert(reference_frame_index >= 0);
2013*09537850SAkhilesh Sanikop       // Section 6.8.2: It is a requirement of bitstream conformance that
2014*09537850SAkhilesh Sanikop       // RefValid[ ref_frame_idx[ i ] ] is equal to 1 ...
2015*09537850SAkhilesh Sanikop       // The remainder of the statement is handled by ParseSequenceHeader().
2016*09537850SAkhilesh Sanikop       // Note if support for Annex C: Error resilience behavior is added this
2017*09537850SAkhilesh Sanikop       // check should be omitted per C.5 Decoder consequences of processable
2018*09537850SAkhilesh Sanikop       // frames.
2019*09537850SAkhilesh Sanikop       if (decoder_state_.reference_frame[reference_frame_index] == nullptr) {
2020*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "ref_frame_idx[%d] (%d) is not valid.", i,
2021*09537850SAkhilesh Sanikop                      reference_frame_index);
2022*09537850SAkhilesh Sanikop         return false;
2023*09537850SAkhilesh Sanikop       }
2024*09537850SAkhilesh Sanikop       if (sequence_header_.frame_id_numbers_present) {
2025*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(sequence_header_.delta_frame_id_length_bits);
2026*09537850SAkhilesh Sanikop         const int delta_frame_id = static_cast<int>(1 + scratch);
2027*09537850SAkhilesh Sanikop         const int id_length_max_value =
2028*09537850SAkhilesh Sanikop             1 << sequence_header_.frame_id_length_bits;
2029*09537850SAkhilesh Sanikop         frame_header_.expected_frame_id[i] =
2030*09537850SAkhilesh Sanikop             (frame_header_.current_frame_id + id_length_max_value -
2031*09537850SAkhilesh Sanikop              delta_frame_id) %
2032*09537850SAkhilesh Sanikop             id_length_max_value;
2033*09537850SAkhilesh Sanikop         // Section 6.8.2: It is a requirement of bitstream conformance that
2034*09537850SAkhilesh Sanikop         // whenever expectedFrameId[ i ] is calculated, the value matches
2035*09537850SAkhilesh Sanikop         // RefFrameId[ ref_frame_idx[ i ] ] ...
2036*09537850SAkhilesh Sanikop         if (frame_header_.expected_frame_id[i] !=
2037*09537850SAkhilesh Sanikop             decoder_state_.reference_frame_id[reference_frame_index]) {
2038*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
2039*09537850SAkhilesh Sanikop                        "Reference buffer %d has a frame id number mismatch.",
2040*09537850SAkhilesh Sanikop                        reference_frame_index);
2041*09537850SAkhilesh Sanikop           return false;
2042*09537850SAkhilesh Sanikop         }
2043*09537850SAkhilesh Sanikop       }
2044*09537850SAkhilesh Sanikop     }
2045*09537850SAkhilesh Sanikop     if (frame_header_.frame_size_override_flag &&
2046*09537850SAkhilesh Sanikop         !frame_header_.error_resilient_mode) {
2047*09537850SAkhilesh Sanikop       // Section 5.9.7.
2048*09537850SAkhilesh Sanikop       for (int index : frame_header_.reference_frame_index) {
2049*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
2050*09537850SAkhilesh Sanikop         frame_header_.found_reference = scratch != 0;
2051*09537850SAkhilesh Sanikop         if (frame_header_.found_reference) {
2052*09537850SAkhilesh Sanikop           const RefCountedBuffer* reference_frame =
2053*09537850SAkhilesh Sanikop               decoder_state_.reference_frame[index].get();
2054*09537850SAkhilesh Sanikop           // frame_header_.upscaled_width will be set in the
2055*09537850SAkhilesh Sanikop           // ParseSuperResParametersAndComputeImageSize() call below.
2056*09537850SAkhilesh Sanikop           frame_header_.width = reference_frame->upscaled_width();
2057*09537850SAkhilesh Sanikop           frame_header_.height = reference_frame->frame_height();
2058*09537850SAkhilesh Sanikop           frame_header_.render_width = reference_frame->render_width();
2059*09537850SAkhilesh Sanikop           frame_header_.render_height = reference_frame->render_height();
2060*09537850SAkhilesh Sanikop           if (!ParseSuperResParametersAndComputeImageSize()) return false;
2061*09537850SAkhilesh Sanikop           break;
2062*09537850SAkhilesh Sanikop         }
2063*09537850SAkhilesh Sanikop       }
2064*09537850SAkhilesh Sanikop       if (!frame_header_.found_reference && !ParseFrameSizeAndRenderSize()) {
2065*09537850SAkhilesh Sanikop         return false;
2066*09537850SAkhilesh Sanikop       }
2067*09537850SAkhilesh Sanikop     } else {
2068*09537850SAkhilesh Sanikop       if (!ParseFrameSizeAndRenderSize()) return false;
2069*09537850SAkhilesh Sanikop     }
2070*09537850SAkhilesh Sanikop     if (!ValidateInterFrameSize()) return false;
2071*09537850SAkhilesh Sanikop     if (frame_header_.force_integer_mv != 0) {
2072*09537850SAkhilesh Sanikop       frame_header_.allow_high_precision_mv = false;
2073*09537850SAkhilesh Sanikop     } else {
2074*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
2075*09537850SAkhilesh Sanikop       frame_header_.allow_high_precision_mv = scratch != 0;
2076*09537850SAkhilesh Sanikop     }
2077*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2078*09537850SAkhilesh Sanikop     const bool is_filter_switchable = scratch != 0;
2079*09537850SAkhilesh Sanikop     if (is_filter_switchable) {
2080*09537850SAkhilesh Sanikop       frame_header_.interpolation_filter = kInterpolationFilterSwitchable;
2081*09537850SAkhilesh Sanikop     } else {
2082*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(2);
2083*09537850SAkhilesh Sanikop       frame_header_.interpolation_filter =
2084*09537850SAkhilesh Sanikop           static_cast<InterpolationFilter>(scratch);
2085*09537850SAkhilesh Sanikop     }
2086*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2087*09537850SAkhilesh Sanikop     frame_header_.is_motion_mode_switchable = scratch != 0;
2088*09537850SAkhilesh Sanikop     if (frame_header_.error_resilient_mode ||
2089*09537850SAkhilesh Sanikop         !sequence_header_.enable_ref_frame_mvs) {
2090*09537850SAkhilesh Sanikop       frame_header_.use_ref_frame_mvs = false;
2091*09537850SAkhilesh Sanikop     } else {
2092*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
2093*09537850SAkhilesh Sanikop       frame_header_.use_ref_frame_mvs = scratch != 0;
2094*09537850SAkhilesh Sanikop     }
2095*09537850SAkhilesh Sanikop   }
2096*09537850SAkhilesh Sanikop   // At this point, we have parsed the frame and render sizes and computed
2097*09537850SAkhilesh Sanikop   // the image size, whether it's an intra or inter frame. So we can save
2098*09537850SAkhilesh Sanikop   // the sizes in the current frame now.
2099*09537850SAkhilesh Sanikop   if (!current_frame_->SetFrameDimensions(frame_header_)) {
2100*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Setting current frame dimensions failed.");
2101*09537850SAkhilesh Sanikop     return false;
2102*09537850SAkhilesh Sanikop   }
2103*09537850SAkhilesh Sanikop   if (!IsIntraFrame(frame_header_.frame_type)) {
2104*09537850SAkhilesh Sanikop     // Initialize the kReferenceFrameIntra type reference frame information to
2105*09537850SAkhilesh Sanikop     // simplify the frame type validation in motion field projection.
2106*09537850SAkhilesh Sanikop     // Set the kReferenceFrameIntra type |order_hint_| to
2107*09537850SAkhilesh Sanikop     // |frame_header_.order_hint|. This guarantees that in SIMD implementations,
2108*09537850SAkhilesh Sanikop     // the other reference frame information of the kReferenceFrameIntra type
2109*09537850SAkhilesh Sanikop     // could be correctly initialized using the following loop with
2110*09537850SAkhilesh Sanikop     // |frame_header_.order_hint| being the |hint|.
2111*09537850SAkhilesh Sanikop     ReferenceInfo* const reference_info = current_frame_->reference_info();
2112*09537850SAkhilesh Sanikop     reference_info->order_hint[kReferenceFrameIntra] = frame_header_.order_hint;
2113*09537850SAkhilesh Sanikop     reference_info->relative_distance_from[kReferenceFrameIntra] = 0;
2114*09537850SAkhilesh Sanikop     reference_info->relative_distance_to[kReferenceFrameIntra] = 0;
2115*09537850SAkhilesh Sanikop     reference_info->skip_references[kReferenceFrameIntra] = true;
2116*09537850SAkhilesh Sanikop     reference_info->projection_divisions[kReferenceFrameIntra] = 0;
2117*09537850SAkhilesh Sanikop 
2118*09537850SAkhilesh Sanikop     for (int i = kReferenceFrameLast; i <= kNumInterReferenceFrameTypes; ++i) {
2119*09537850SAkhilesh Sanikop       const auto reference_frame = static_cast<ReferenceFrameType>(i);
2120*09537850SAkhilesh Sanikop       const uint8_t hint =
2121*09537850SAkhilesh Sanikop           decoder_state_.reference_order_hint
2122*09537850SAkhilesh Sanikop               [frame_header_.reference_frame_index[i - kReferenceFrameLast]];
2123*09537850SAkhilesh Sanikop       reference_info->order_hint[reference_frame] = hint;
2124*09537850SAkhilesh Sanikop       const int relative_distance_from =
2125*09537850SAkhilesh Sanikop           GetRelativeDistance(hint, frame_header_.order_hint,
2126*09537850SAkhilesh Sanikop                               sequence_header_.order_hint_shift_bits);
2127*09537850SAkhilesh Sanikop       const int relative_distance_to =
2128*09537850SAkhilesh Sanikop           GetRelativeDistance(frame_header_.order_hint, hint,
2129*09537850SAkhilesh Sanikop                               sequence_header_.order_hint_shift_bits);
2130*09537850SAkhilesh Sanikop       reference_info->relative_distance_from[reference_frame] =
2131*09537850SAkhilesh Sanikop           relative_distance_from;
2132*09537850SAkhilesh Sanikop       reference_info->relative_distance_to[reference_frame] =
2133*09537850SAkhilesh Sanikop           relative_distance_to;
2134*09537850SAkhilesh Sanikop       reference_info->skip_references[reference_frame] =
2135*09537850SAkhilesh Sanikop           relative_distance_to > kMaxFrameDistance || relative_distance_to <= 0;
2136*09537850SAkhilesh Sanikop       reference_info->projection_divisions[reference_frame] =
2137*09537850SAkhilesh Sanikop           reference_info->skip_references[reference_frame]
2138*09537850SAkhilesh Sanikop               ? 0
2139*09537850SAkhilesh Sanikop               : kProjectionMvDivisionLookup[relative_distance_to];
2140*09537850SAkhilesh Sanikop       decoder_state_.reference_frame_sign_bias[reference_frame] =
2141*09537850SAkhilesh Sanikop           relative_distance_from > 0;
2142*09537850SAkhilesh Sanikop     }
2143*09537850SAkhilesh Sanikop   }
2144*09537850SAkhilesh Sanikop   if (frame_header_.enable_cdf_update &&
2145*09537850SAkhilesh Sanikop       !sequence_header_.reduced_still_picture_header) {
2146*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2147*09537850SAkhilesh Sanikop     frame_header_.enable_frame_end_update_cdf = scratch == 0;
2148*09537850SAkhilesh Sanikop   } else {
2149*09537850SAkhilesh Sanikop     frame_header_.enable_frame_end_update_cdf = false;
2150*09537850SAkhilesh Sanikop   }
2151*09537850SAkhilesh Sanikop   return true;
2152*09537850SAkhilesh Sanikop }
2153*09537850SAkhilesh Sanikop 
ParseFrameHeader()2154*09537850SAkhilesh Sanikop bool ObuParser::ParseFrameHeader() {
2155*09537850SAkhilesh Sanikop   // Section 6.8.1: It is a requirement of bitstream conformance that a
2156*09537850SAkhilesh Sanikop   // sequence header OBU has been received before a frame header OBU.
2157*09537850SAkhilesh Sanikop   if (!has_sequence_header_) return false;
2158*09537850SAkhilesh Sanikop   if (!ParseFrameParameters()) return false;
2159*09537850SAkhilesh Sanikop   if (frame_header_.show_existing_frame) return true;
2160*09537850SAkhilesh Sanikop   assert(!obu_headers_.empty());
2161*09537850SAkhilesh Sanikop   current_frame_->set_spatial_id(obu_headers_.back().spatial_id);
2162*09537850SAkhilesh Sanikop   current_frame_->set_temporal_id(obu_headers_.back().temporal_id);
2163*09537850SAkhilesh Sanikop   bool status = ParseTileInfoSyntax() && ParseQuantizerParameters() &&
2164*09537850SAkhilesh Sanikop                 ParseSegmentationParameters();
2165*09537850SAkhilesh Sanikop   if (!status) return false;
2166*09537850SAkhilesh Sanikop   current_frame_->SetSegmentationParameters(frame_header_.segmentation);
2167*09537850SAkhilesh Sanikop   status =
2168*09537850SAkhilesh Sanikop       ParseQuantizerIndexDeltaParameters() && ParseLoopFilterDeltaParameters();
2169*09537850SAkhilesh Sanikop   if (!status) return false;
2170*09537850SAkhilesh Sanikop   ComputeSegmentLosslessAndQIndex();
2171*09537850SAkhilesh Sanikop   // Section 6.8.2: It is a requirement of bitstream conformance that
2172*09537850SAkhilesh Sanikop   // delta_q_present is equal to 0 when CodedLossless is equal to 1.
2173*09537850SAkhilesh Sanikop   if (frame_header_.coded_lossless && frame_header_.delta_q.present) {
2174*09537850SAkhilesh Sanikop     return false;
2175*09537850SAkhilesh Sanikop   }
2176*09537850SAkhilesh Sanikop   status = ParseLoopFilterParameters();
2177*09537850SAkhilesh Sanikop   if (!status) return false;
2178*09537850SAkhilesh Sanikop   current_frame_->SetLoopFilterDeltas(frame_header_.loop_filter);
2179*09537850SAkhilesh Sanikop   status = ParseCdefParameters() && ParseLoopRestorationParameters() &&
2180*09537850SAkhilesh Sanikop            ParseTxModeSyntax() && ParseFrameReferenceModeSyntax() &&
2181*09537850SAkhilesh Sanikop            ParseSkipModeParameters() && ReadAllowWarpedMotion();
2182*09537850SAkhilesh Sanikop   if (!status) return false;
2183*09537850SAkhilesh Sanikop   int64_t scratch;
2184*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2185*09537850SAkhilesh Sanikop   frame_header_.reduced_tx_set = scratch != 0;
2186*09537850SAkhilesh Sanikop   status = ParseGlobalMotionParameters();
2187*09537850SAkhilesh Sanikop   if (!status) return false;
2188*09537850SAkhilesh Sanikop   current_frame_->SetGlobalMotions(frame_header_.global_motion);
2189*09537850SAkhilesh Sanikop   status = ParseFilmGrainParameters();
2190*09537850SAkhilesh Sanikop   if (!status) return false;
2191*09537850SAkhilesh Sanikop   if (sequence_header_.film_grain_params_present) {
2192*09537850SAkhilesh Sanikop     current_frame_->set_film_grain_params(frame_header_.film_grain_params);
2193*09537850SAkhilesh Sanikop   }
2194*09537850SAkhilesh Sanikop   return true;
2195*09537850SAkhilesh Sanikop }
2196*09537850SAkhilesh Sanikop 
ParsePadding(const uint8_t * data,size_t size)2197*09537850SAkhilesh Sanikop bool ObuParser::ParsePadding(const uint8_t* data, size_t size) {
2198*09537850SAkhilesh Sanikop   // The spec allows a padding OBU to be header-only (i.e., |size| = 0). So
2199*09537850SAkhilesh Sanikop   // check trailing bits only if |size| > 0.
2200*09537850SAkhilesh Sanikop   if (size == 0) return true;
2201*09537850SAkhilesh Sanikop   // The payload of a padding OBU is byte aligned. Therefore the first
2202*09537850SAkhilesh Sanikop   // trailing byte should be 0x80. See https://crbug.com/aomedia/2393.
2203*09537850SAkhilesh Sanikop   const int i = GetLastNonzeroByteIndex(data, size);
2204*09537850SAkhilesh Sanikop   if (i < 0) {
2205*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Trailing bit is missing.");
2206*09537850SAkhilesh Sanikop     return false;
2207*09537850SAkhilesh Sanikop   }
2208*09537850SAkhilesh Sanikop   if (data[i] != 0x80) {
2209*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(
2210*09537850SAkhilesh Sanikop         ERROR,
2211*09537850SAkhilesh Sanikop         "The last nonzero byte of the payload data is 0x%x, should be 0x80.",
2212*09537850SAkhilesh Sanikop         data[i]);
2213*09537850SAkhilesh Sanikop     return false;
2214*09537850SAkhilesh Sanikop   }
2215*09537850SAkhilesh Sanikop   // Skip all bits before the trailing bit.
2216*09537850SAkhilesh Sanikop   bit_reader_->SkipBytes(i);
2217*09537850SAkhilesh Sanikop   return true;
2218*09537850SAkhilesh Sanikop }
2219*09537850SAkhilesh Sanikop 
ParseMetadataScalability()2220*09537850SAkhilesh Sanikop bool ObuParser::ParseMetadataScalability() {
2221*09537850SAkhilesh Sanikop   int64_t scratch;
2222*09537850SAkhilesh Sanikop   // scalability_mode_idc
2223*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(8);
2224*09537850SAkhilesh Sanikop   const auto scalability_mode_idc = static_cast<int>(scratch);
2225*09537850SAkhilesh Sanikop   if (scalability_mode_idc == kScalabilitySS) {
2226*09537850SAkhilesh Sanikop     // Parse scalability_structure().
2227*09537850SAkhilesh Sanikop     // spatial_layers_cnt_minus_1
2228*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
2229*09537850SAkhilesh Sanikop     const auto spatial_layers_count = static_cast<int>(scratch) + 1;
2230*09537850SAkhilesh Sanikop     // spatial_layer_dimensions_present_flag
2231*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2232*09537850SAkhilesh Sanikop     const auto spatial_layer_dimensions_present_flag = scratch != 0;
2233*09537850SAkhilesh Sanikop     // spatial_layer_description_present_flag
2234*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2235*09537850SAkhilesh Sanikop     const auto spatial_layer_description_present_flag = scratch != 0;
2236*09537850SAkhilesh Sanikop     // temporal_group_description_present_flag
2237*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2238*09537850SAkhilesh Sanikop     const auto temporal_group_description_present_flag = scratch != 0;
2239*09537850SAkhilesh Sanikop     // scalability_structure_reserved_3bits
2240*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
2241*09537850SAkhilesh Sanikop     if (scratch != 0) {
2242*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(WARNING,
2243*09537850SAkhilesh Sanikop                    "scalability_structure_reserved_3bits is not zero.");
2244*09537850SAkhilesh Sanikop     }
2245*09537850SAkhilesh Sanikop     if (spatial_layer_dimensions_present_flag) {
2246*09537850SAkhilesh Sanikop       for (int i = 0; i < spatial_layers_count; ++i) {
2247*09537850SAkhilesh Sanikop         // spatial_layer_max_width[i]
2248*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(16);
2249*09537850SAkhilesh Sanikop         // spatial_layer_max_height[i]
2250*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(16);
2251*09537850SAkhilesh Sanikop       }
2252*09537850SAkhilesh Sanikop     }
2253*09537850SAkhilesh Sanikop     if (spatial_layer_description_present_flag) {
2254*09537850SAkhilesh Sanikop       for (int i = 0; i < spatial_layers_count; ++i) {
2255*09537850SAkhilesh Sanikop         // spatial_layer_ref_id[i]
2256*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(8);
2257*09537850SAkhilesh Sanikop       }
2258*09537850SAkhilesh Sanikop     }
2259*09537850SAkhilesh Sanikop     if (temporal_group_description_present_flag) {
2260*09537850SAkhilesh Sanikop       // temporal_group_size
2261*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
2262*09537850SAkhilesh Sanikop       const auto temporal_group_size = static_cast<int>(scratch);
2263*09537850SAkhilesh Sanikop       for (int i = 0; i < temporal_group_size; ++i) {
2264*09537850SAkhilesh Sanikop         // temporal_group_temporal_id[i]
2265*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(3);
2266*09537850SAkhilesh Sanikop         // temporal_group_temporal_switching_up_point_flag[i]
2267*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
2268*09537850SAkhilesh Sanikop         // temporal_group_spatial_switching_up_point_flag[i]
2269*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
2270*09537850SAkhilesh Sanikop         // temporal_group_ref_cnt[i]
2271*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(3);
2272*09537850SAkhilesh Sanikop         const auto temporal_group_ref_count = static_cast<int>(scratch);
2273*09537850SAkhilesh Sanikop         for (int j = 0; j < temporal_group_ref_count; ++j) {
2274*09537850SAkhilesh Sanikop           // temporal_group_ref_pic_diff[i][j]
2275*09537850SAkhilesh Sanikop           OBU_READ_LITERAL_OR_FAIL(8);
2276*09537850SAkhilesh Sanikop         }
2277*09537850SAkhilesh Sanikop       }
2278*09537850SAkhilesh Sanikop     }
2279*09537850SAkhilesh Sanikop   }
2280*09537850SAkhilesh Sanikop   return true;
2281*09537850SAkhilesh Sanikop }
2282*09537850SAkhilesh Sanikop 
ParseMetadataTimecode()2283*09537850SAkhilesh Sanikop bool ObuParser::ParseMetadataTimecode() {
2284*09537850SAkhilesh Sanikop   int64_t scratch;
2285*09537850SAkhilesh Sanikop   // counting_type: should be the same for all pictures in the coded video
2286*09537850SAkhilesh Sanikop   // sequence. 7..31 are reserved.
2287*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(5);
2288*09537850SAkhilesh Sanikop   // full_timestamp_flag
2289*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2290*09537850SAkhilesh Sanikop   const bool full_timestamp_flag = scratch != 0;
2291*09537850SAkhilesh Sanikop   // discontinuity_flag
2292*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2293*09537850SAkhilesh Sanikop   // cnt_dropped_flag
2294*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2295*09537850SAkhilesh Sanikop   // n_frames
2296*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(9);
2297*09537850SAkhilesh Sanikop   if (full_timestamp_flag) {
2298*09537850SAkhilesh Sanikop     // seconds_value
2299*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(6);
2300*09537850SAkhilesh Sanikop     const auto seconds_value = static_cast<int>(scratch);
2301*09537850SAkhilesh Sanikop     if (seconds_value > 59) {
2302*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid seconds_value %d.", seconds_value);
2303*09537850SAkhilesh Sanikop       return false;
2304*09537850SAkhilesh Sanikop     }
2305*09537850SAkhilesh Sanikop     // minutes_value
2306*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(6);
2307*09537850SAkhilesh Sanikop     const auto minutes_value = static_cast<int>(scratch);
2308*09537850SAkhilesh Sanikop     if (minutes_value > 59) {
2309*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid minutes_value %d.", minutes_value);
2310*09537850SAkhilesh Sanikop       return false;
2311*09537850SAkhilesh Sanikop     }
2312*09537850SAkhilesh Sanikop     // hours_value
2313*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(5);
2314*09537850SAkhilesh Sanikop     const auto hours_value = static_cast<int>(scratch);
2315*09537850SAkhilesh Sanikop     if (hours_value > 23) {
2316*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Invalid hours_value %d.", hours_value);
2317*09537850SAkhilesh Sanikop       return false;
2318*09537850SAkhilesh Sanikop     }
2319*09537850SAkhilesh Sanikop   } else {
2320*09537850SAkhilesh Sanikop     // seconds_flag
2321*09537850SAkhilesh Sanikop     OBU_READ_BIT_OR_FAIL;
2322*09537850SAkhilesh Sanikop     const bool seconds_flag = scratch != 0;
2323*09537850SAkhilesh Sanikop     if (seconds_flag) {
2324*09537850SAkhilesh Sanikop       // seconds_value
2325*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(6);
2326*09537850SAkhilesh Sanikop       const auto seconds_value = static_cast<int>(scratch);
2327*09537850SAkhilesh Sanikop       if (seconds_value > 59) {
2328*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Invalid seconds_value %d.", seconds_value);
2329*09537850SAkhilesh Sanikop         return false;
2330*09537850SAkhilesh Sanikop       }
2331*09537850SAkhilesh Sanikop       // minutes_flag
2332*09537850SAkhilesh Sanikop       OBU_READ_BIT_OR_FAIL;
2333*09537850SAkhilesh Sanikop       const bool minutes_flag = scratch != 0;
2334*09537850SAkhilesh Sanikop       if (minutes_flag) {
2335*09537850SAkhilesh Sanikop         // minutes_value
2336*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(6);
2337*09537850SAkhilesh Sanikop         const auto minutes_value = static_cast<int>(scratch);
2338*09537850SAkhilesh Sanikop         if (minutes_value > 59) {
2339*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Invalid minutes_value %d.", minutes_value);
2340*09537850SAkhilesh Sanikop           return false;
2341*09537850SAkhilesh Sanikop         }
2342*09537850SAkhilesh Sanikop         // hours_flag
2343*09537850SAkhilesh Sanikop         OBU_READ_BIT_OR_FAIL;
2344*09537850SAkhilesh Sanikop         const bool hours_flag = scratch != 0;
2345*09537850SAkhilesh Sanikop         if (hours_flag) {
2346*09537850SAkhilesh Sanikop           // hours_value
2347*09537850SAkhilesh Sanikop           OBU_READ_LITERAL_OR_FAIL(5);
2348*09537850SAkhilesh Sanikop           const auto hours_value = static_cast<int>(scratch);
2349*09537850SAkhilesh Sanikop           if (hours_value > 23) {
2350*09537850SAkhilesh Sanikop             LIBGAV1_DLOG(ERROR, "Invalid hours_value %d.", hours_value);
2351*09537850SAkhilesh Sanikop             return false;
2352*09537850SAkhilesh Sanikop           }
2353*09537850SAkhilesh Sanikop         }
2354*09537850SAkhilesh Sanikop       }
2355*09537850SAkhilesh Sanikop     }
2356*09537850SAkhilesh Sanikop   }
2357*09537850SAkhilesh Sanikop   // time_offset_length: should be the same for all pictures in the coded
2358*09537850SAkhilesh Sanikop   // video sequence.
2359*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(5);
2360*09537850SAkhilesh Sanikop   const auto time_offset_length = static_cast<int>(scratch);
2361*09537850SAkhilesh Sanikop   if (time_offset_length > 0) {
2362*09537850SAkhilesh Sanikop     // time_offset_value
2363*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(time_offset_length);
2364*09537850SAkhilesh Sanikop   }
2365*09537850SAkhilesh Sanikop   // Compute clockTimestamp. Section 6.7.7:
2366*09537850SAkhilesh Sanikop   //   When timing_info_present_flag is equal to 1 and discontinuity_flag is
2367*09537850SAkhilesh Sanikop   //   equal to 0, the value of clockTimestamp shall be greater than or equal
2368*09537850SAkhilesh Sanikop   //   to the value of clockTimestamp for the previous set of clock timestamp
2369*09537850SAkhilesh Sanikop   //   syntax elements in output order.
2370*09537850SAkhilesh Sanikop   return true;
2371*09537850SAkhilesh Sanikop }
2372*09537850SAkhilesh Sanikop 
ParseMetadata(const uint8_t * data,size_t size)2373*09537850SAkhilesh Sanikop bool ObuParser::ParseMetadata(const uint8_t* data, size_t size) {
2374*09537850SAkhilesh Sanikop   const size_t start_offset = bit_reader_->byte_offset();
2375*09537850SAkhilesh Sanikop   size_t metadata_type;
2376*09537850SAkhilesh Sanikop   if (!bit_reader_->ReadUnsignedLeb128(&metadata_type)) {
2377*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Could not read metadata_type.");
2378*09537850SAkhilesh Sanikop     return false;
2379*09537850SAkhilesh Sanikop   }
2380*09537850SAkhilesh Sanikop   const size_t metadata_type_size = bit_reader_->byte_offset() - start_offset;
2381*09537850SAkhilesh Sanikop   if (size < metadata_type_size) {
2382*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(
2383*09537850SAkhilesh Sanikop         ERROR, "metadata_type is longer than metadata OBU payload %zu vs %zu.",
2384*09537850SAkhilesh Sanikop         metadata_type_size, size);
2385*09537850SAkhilesh Sanikop     return false;
2386*09537850SAkhilesh Sanikop   }
2387*09537850SAkhilesh Sanikop   data += metadata_type_size;
2388*09537850SAkhilesh Sanikop   size -= metadata_type_size;
2389*09537850SAkhilesh Sanikop   int64_t scratch;
2390*09537850SAkhilesh Sanikop   switch (metadata_type) {
2391*09537850SAkhilesh Sanikop     case kMetadataTypeHdrContentLightLevel: {
2392*09537850SAkhilesh Sanikop       ObuMetadataHdrCll hdr_cll;
2393*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(16);
2394*09537850SAkhilesh Sanikop       hdr_cll.max_cll = scratch;
2395*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(16);
2396*09537850SAkhilesh Sanikop       hdr_cll.max_fall = scratch;
2397*09537850SAkhilesh Sanikop       if (!EnsureCurrentFrameIsNotNull()) return false;
2398*09537850SAkhilesh Sanikop       current_frame_->set_hdr_cll(hdr_cll);
2399*09537850SAkhilesh Sanikop       break;
2400*09537850SAkhilesh Sanikop     }
2401*09537850SAkhilesh Sanikop     case kMetadataTypeHdrMasteringDisplayColorVolume: {
2402*09537850SAkhilesh Sanikop       ObuMetadataHdrMdcv hdr_mdcv;
2403*09537850SAkhilesh Sanikop       for (int i = 0; i < 3; ++i) {
2404*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(16);
2405*09537850SAkhilesh Sanikop         hdr_mdcv.primary_chromaticity_x[i] = scratch;
2406*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(16);
2407*09537850SAkhilesh Sanikop         hdr_mdcv.primary_chromaticity_y[i] = scratch;
2408*09537850SAkhilesh Sanikop       }
2409*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(16);
2410*09537850SAkhilesh Sanikop       hdr_mdcv.white_point_chromaticity_x = scratch;
2411*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(16);
2412*09537850SAkhilesh Sanikop       hdr_mdcv.white_point_chromaticity_y = scratch;
2413*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(32);
2414*09537850SAkhilesh Sanikop       hdr_mdcv.luminance_max = static_cast<uint32_t>(scratch);
2415*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(32);
2416*09537850SAkhilesh Sanikop       hdr_mdcv.luminance_min = static_cast<uint32_t>(scratch);
2417*09537850SAkhilesh Sanikop       if (!EnsureCurrentFrameIsNotNull()) return false;
2418*09537850SAkhilesh Sanikop       current_frame_->set_hdr_mdcv(hdr_mdcv);
2419*09537850SAkhilesh Sanikop       break;
2420*09537850SAkhilesh Sanikop     }
2421*09537850SAkhilesh Sanikop     case kMetadataTypeScalability:
2422*09537850SAkhilesh Sanikop       if (!ParseMetadataScalability()) return false;
2423*09537850SAkhilesh Sanikop       break;
2424*09537850SAkhilesh Sanikop     case kMetadataTypeItutT35: {
2425*09537850SAkhilesh Sanikop       ObuMetadataItutT35 itut_t35;
2426*09537850SAkhilesh Sanikop       OBU_READ_LITERAL_OR_FAIL(8);
2427*09537850SAkhilesh Sanikop       itut_t35.country_code = static_cast<uint8_t>(scratch);
2428*09537850SAkhilesh Sanikop       ++data;
2429*09537850SAkhilesh Sanikop       --size;
2430*09537850SAkhilesh Sanikop       if (itut_t35.country_code == 0xFF) {
2431*09537850SAkhilesh Sanikop         OBU_READ_LITERAL_OR_FAIL(8);
2432*09537850SAkhilesh Sanikop         itut_t35.country_code_extension_byte = static_cast<uint8_t>(scratch);
2433*09537850SAkhilesh Sanikop         ++data;
2434*09537850SAkhilesh Sanikop         --size;
2435*09537850SAkhilesh Sanikop       }
2436*09537850SAkhilesh Sanikop       // Read itut_t35.payload_bytes. Section 6.7.2 of the spec says:
2437*09537850SAkhilesh Sanikop       //   itut_t35.payload_bytes shall be bytes containing data registered as
2438*09537850SAkhilesh Sanikop       //   specified in Recommendation ITU-T T.35.
2439*09537850SAkhilesh Sanikop       // Therefore itut_t35.payload_bytes is byte aligned and the first trailing
2440*09537850SAkhilesh Sanikop       // byte should be 0x80. Since the exact syntax of itut_t35.payload_bytes
2441*09537850SAkhilesh Sanikop       // is not defined in the AV1 spec, identify the end of
2442*09537850SAkhilesh Sanikop       // itut_t35.payload_bytes by searching for the trailing bit.
2443*09537850SAkhilesh Sanikop       const int i = GetLastNonzeroByteIndex(data, size);
2444*09537850SAkhilesh Sanikop       if (i < 0) {
2445*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Trailing bit is missing.");
2446*09537850SAkhilesh Sanikop         return false;
2447*09537850SAkhilesh Sanikop       }
2448*09537850SAkhilesh Sanikop       if (data[i] != 0x80) {
2449*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(
2450*09537850SAkhilesh Sanikop             ERROR,
2451*09537850SAkhilesh Sanikop             "itut_t35.payload_bytes is not byte aligned. The last nonzero byte "
2452*09537850SAkhilesh Sanikop             "of the payload data is 0x%x, should be 0x80.",
2453*09537850SAkhilesh Sanikop             data[i]);
2454*09537850SAkhilesh Sanikop         return false;
2455*09537850SAkhilesh Sanikop       }
2456*09537850SAkhilesh Sanikop       itut_t35.payload_size = i;
2457*09537850SAkhilesh Sanikop       if (!EnsureCurrentFrameIsNotNull() ||
2458*09537850SAkhilesh Sanikop           !current_frame_->set_itut_t35(itut_t35, data)) {
2459*09537850SAkhilesh Sanikop         return false;
2460*09537850SAkhilesh Sanikop       }
2461*09537850SAkhilesh Sanikop       // Skip all bits before the trailing bit.
2462*09537850SAkhilesh Sanikop       bit_reader_->SkipBytes(i);
2463*09537850SAkhilesh Sanikop       break;
2464*09537850SAkhilesh Sanikop     }
2465*09537850SAkhilesh Sanikop     case kMetadataTypeTimecode:
2466*09537850SAkhilesh Sanikop       if (!ParseMetadataTimecode()) return false;
2467*09537850SAkhilesh Sanikop       break;
2468*09537850SAkhilesh Sanikop     default: {
2469*09537850SAkhilesh Sanikop       // metadata_type is equal to a value reserved for future use or a user
2470*09537850SAkhilesh Sanikop       // private value.
2471*09537850SAkhilesh Sanikop       //
2472*09537850SAkhilesh Sanikop       // The Note in Section 5.8.1 says "Decoders should ignore the entire OBU
2473*09537850SAkhilesh Sanikop       // if they do not understand the metadata_type." Find the trailing bit
2474*09537850SAkhilesh Sanikop       // and skip all bits before the trailing bit.
2475*09537850SAkhilesh Sanikop       const int i = GetLastNonzeroByteIndex(data, size);
2476*09537850SAkhilesh Sanikop       if (i >= 0) {
2477*09537850SAkhilesh Sanikop         // The last 1 bit in the last nonzero byte is the trailing bit. Skip
2478*09537850SAkhilesh Sanikop         // all bits before the trailing bit.
2479*09537850SAkhilesh Sanikop         const int n = CountTrailingZeros(data[i]);
2480*09537850SAkhilesh Sanikop         bit_reader_->SkipBits(i * 8 + 7 - n);
2481*09537850SAkhilesh Sanikop       }
2482*09537850SAkhilesh Sanikop       break;
2483*09537850SAkhilesh Sanikop     }
2484*09537850SAkhilesh Sanikop   }
2485*09537850SAkhilesh Sanikop   return true;
2486*09537850SAkhilesh Sanikop }
2487*09537850SAkhilesh Sanikop 
AddTileBuffers(int start,int end,size_t total_size,size_t tg_header_size,size_t bytes_consumed_so_far)2488*09537850SAkhilesh Sanikop bool ObuParser::AddTileBuffers(int start, int end, size_t total_size,
2489*09537850SAkhilesh Sanikop                                size_t tg_header_size,
2490*09537850SAkhilesh Sanikop                                size_t bytes_consumed_so_far) {
2491*09537850SAkhilesh Sanikop   // Validate that the tile group start and end are within the allowed range.
2492*09537850SAkhilesh Sanikop   if (start != next_tile_group_start_ || start > end ||
2493*09537850SAkhilesh Sanikop       end >= frame_header_.tile_info.tile_count) {
2494*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR,
2495*09537850SAkhilesh Sanikop                  "Invalid tile group start %d or end %d: expected tile group "
2496*09537850SAkhilesh Sanikop                  "start %d, tile_count %d.",
2497*09537850SAkhilesh Sanikop                  start, end, next_tile_group_start_,
2498*09537850SAkhilesh Sanikop                  frame_header_.tile_info.tile_count);
2499*09537850SAkhilesh Sanikop     return false;
2500*09537850SAkhilesh Sanikop   }
2501*09537850SAkhilesh Sanikop   next_tile_group_start_ = end + 1;
2502*09537850SAkhilesh Sanikop 
2503*09537850SAkhilesh Sanikop   if (total_size < tg_header_size) {
2504*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "total_size (%zu) is less than tg_header_size (%zu).)",
2505*09537850SAkhilesh Sanikop                  total_size, tg_header_size);
2506*09537850SAkhilesh Sanikop     return false;
2507*09537850SAkhilesh Sanikop   }
2508*09537850SAkhilesh Sanikop   size_t bytes_left = total_size - tg_header_size;
2509*09537850SAkhilesh Sanikop   const uint8_t* data = data_ + bytes_consumed_so_far + tg_header_size;
2510*09537850SAkhilesh Sanikop   for (int tile_number = start; tile_number <= end; ++tile_number) {
2511*09537850SAkhilesh Sanikop     size_t tile_size = 0;
2512*09537850SAkhilesh Sanikop     if (tile_number != end) {
2513*09537850SAkhilesh Sanikop       RawBitReader bit_reader(data, bytes_left);
2514*09537850SAkhilesh Sanikop       if (!bit_reader.ReadLittleEndian(frame_header_.tile_info.tile_size_bytes,
2515*09537850SAkhilesh Sanikop                                        &tile_size)) {
2516*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Could not read tile size for tile #%d",
2517*09537850SAkhilesh Sanikop                      tile_number);
2518*09537850SAkhilesh Sanikop         return false;
2519*09537850SAkhilesh Sanikop       }
2520*09537850SAkhilesh Sanikop       ++tile_size;
2521*09537850SAkhilesh Sanikop       data += frame_header_.tile_info.tile_size_bytes;
2522*09537850SAkhilesh Sanikop       bytes_left -= frame_header_.tile_info.tile_size_bytes;
2523*09537850SAkhilesh Sanikop       if (tile_size > bytes_left) {
2524*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Invalid tile size %zu for tile #%d", tile_size,
2525*09537850SAkhilesh Sanikop                      tile_number);
2526*09537850SAkhilesh Sanikop         return false;
2527*09537850SAkhilesh Sanikop       }
2528*09537850SAkhilesh Sanikop     } else {
2529*09537850SAkhilesh Sanikop       tile_size = bytes_left;
2530*09537850SAkhilesh Sanikop       if (tile_size == 0) {
2531*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Invalid tile size %zu for tile #%d", tile_size,
2532*09537850SAkhilesh Sanikop                      tile_number);
2533*09537850SAkhilesh Sanikop         return false;
2534*09537850SAkhilesh Sanikop       }
2535*09537850SAkhilesh Sanikop     }
2536*09537850SAkhilesh Sanikop     // The memory for this has been allocated in ParseTileInfoSyntax(). So it is
2537*09537850SAkhilesh Sanikop     // safe to use push_back_unchecked here.
2538*09537850SAkhilesh Sanikop     tile_buffers_.push_back_unchecked({data, tile_size});
2539*09537850SAkhilesh Sanikop     data += tile_size;
2540*09537850SAkhilesh Sanikop     bytes_left -= tile_size;
2541*09537850SAkhilesh Sanikop   }
2542*09537850SAkhilesh Sanikop   bit_reader_->SkipBytes(total_size - tg_header_size);
2543*09537850SAkhilesh Sanikop   return true;
2544*09537850SAkhilesh Sanikop }
2545*09537850SAkhilesh Sanikop 
ParseTileGroup(size_t size,size_t bytes_consumed_so_far)2546*09537850SAkhilesh Sanikop bool ObuParser::ParseTileGroup(size_t size, size_t bytes_consumed_so_far) {
2547*09537850SAkhilesh Sanikop   const TileInfo* const tile_info = &frame_header_.tile_info;
2548*09537850SAkhilesh Sanikop   const size_t start_offset = bit_reader_->byte_offset();
2549*09537850SAkhilesh Sanikop   const int tile_bits =
2550*09537850SAkhilesh Sanikop       tile_info->tile_columns_log2 + tile_info->tile_rows_log2;
2551*09537850SAkhilesh Sanikop   if (tile_bits == 0) {
2552*09537850SAkhilesh Sanikop     return AddTileBuffers(0, 0, size, 0, bytes_consumed_so_far);
2553*09537850SAkhilesh Sanikop   }
2554*09537850SAkhilesh Sanikop   int64_t scratch;
2555*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2556*09537850SAkhilesh Sanikop   const bool tile_start_and_end_present_flag = scratch != 0;
2557*09537850SAkhilesh Sanikop   if (!tile_start_and_end_present_flag) {
2558*09537850SAkhilesh Sanikop     if (!bit_reader_->AlignToNextByte()) {
2559*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Byte alignment has non zero bits.");
2560*09537850SAkhilesh Sanikop       return false;
2561*09537850SAkhilesh Sanikop     }
2562*09537850SAkhilesh Sanikop     return AddTileBuffers(0, tile_info->tile_count - 1, size, 1,
2563*09537850SAkhilesh Sanikop                           bytes_consumed_so_far);
2564*09537850SAkhilesh Sanikop   }
2565*09537850SAkhilesh Sanikop   if (obu_headers_.back().type == kObuFrame) {
2566*09537850SAkhilesh Sanikop     // 6.10.1: If obu_type is equal to OBU_FRAME, it is a requirement of
2567*09537850SAkhilesh Sanikop     // bitstream conformance that the value of tile_start_and_end_present_flag
2568*09537850SAkhilesh Sanikop     // is equal to 0.
2569*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR,
2570*09537850SAkhilesh Sanikop                  "tile_start_and_end_present_flag must be 0 in Frame OBU");
2571*09537850SAkhilesh Sanikop     return false;
2572*09537850SAkhilesh Sanikop   }
2573*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(tile_bits);
2574*09537850SAkhilesh Sanikop   const int start = static_cast<int>(scratch);
2575*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(tile_bits);
2576*09537850SAkhilesh Sanikop   const int end = static_cast<int>(scratch);
2577*09537850SAkhilesh Sanikop   if (!bit_reader_->AlignToNextByte()) {
2578*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Byte alignment has non zero bits.");
2579*09537850SAkhilesh Sanikop     return false;
2580*09537850SAkhilesh Sanikop   }
2581*09537850SAkhilesh Sanikop   const size_t tg_header_size = bit_reader_->byte_offset() - start_offset;
2582*09537850SAkhilesh Sanikop   return AddTileBuffers(start, end, size, tg_header_size,
2583*09537850SAkhilesh Sanikop                         bytes_consumed_so_far);
2584*09537850SAkhilesh Sanikop }
2585*09537850SAkhilesh Sanikop 
ParseHeader()2586*09537850SAkhilesh Sanikop bool ObuParser::ParseHeader() {
2587*09537850SAkhilesh Sanikop   ObuHeader obu_header;
2588*09537850SAkhilesh Sanikop   int64_t scratch = bit_reader_->ReadBit();
2589*09537850SAkhilesh Sanikop   if (scratch != 0) {
2590*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "forbidden_bit is not zero.");
2591*09537850SAkhilesh Sanikop     return false;
2592*09537850SAkhilesh Sanikop   }
2593*09537850SAkhilesh Sanikop   OBU_READ_LITERAL_OR_FAIL(4);
2594*09537850SAkhilesh Sanikop   obu_header.type = static_cast<libgav1::ObuType>(scratch);
2595*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2596*09537850SAkhilesh Sanikop   const bool extension_flag = scratch != 0;
2597*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;
2598*09537850SAkhilesh Sanikop   obu_header.has_size_field = scratch != 0;
2599*09537850SAkhilesh Sanikop   OBU_READ_BIT_OR_FAIL;  // reserved.
2600*09537850SAkhilesh Sanikop   if (scratch != 0) {
2601*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(WARNING, "obu_reserved_1bit is not zero.");
2602*09537850SAkhilesh Sanikop   }
2603*09537850SAkhilesh Sanikop   obu_header.has_extension = extension_flag;
2604*09537850SAkhilesh Sanikop   if (extension_flag) {
2605*09537850SAkhilesh Sanikop     if (extension_disallowed_) {
2606*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
2607*09537850SAkhilesh Sanikop                    "OperatingPointIdc is 0, but obu_extension_flag is 1.");
2608*09537850SAkhilesh Sanikop       return false;
2609*09537850SAkhilesh Sanikop     }
2610*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);
2611*09537850SAkhilesh Sanikop     obu_header.temporal_id = scratch;
2612*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(2);
2613*09537850SAkhilesh Sanikop     obu_header.spatial_id = scratch;
2614*09537850SAkhilesh Sanikop     OBU_READ_LITERAL_OR_FAIL(3);  // reserved.
2615*09537850SAkhilesh Sanikop     if (scratch != 0) {
2616*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(WARNING, "extension_header_reserved_3bits is not zero.");
2617*09537850SAkhilesh Sanikop     }
2618*09537850SAkhilesh Sanikop   } else {
2619*09537850SAkhilesh Sanikop     obu_header.temporal_id = 0;
2620*09537850SAkhilesh Sanikop     obu_header.spatial_id = 0;
2621*09537850SAkhilesh Sanikop   }
2622*09537850SAkhilesh Sanikop   return obu_headers_.push_back(obu_header);
2623*09537850SAkhilesh Sanikop }
2624*09537850SAkhilesh Sanikop 
2625*09537850SAkhilesh Sanikop #undef OBU_READ_UVLC_OR_FAIL
2626*09537850SAkhilesh Sanikop #undef OBU_READ_LITERAL_OR_FAIL
2627*09537850SAkhilesh Sanikop #undef OBU_READ_BIT_OR_FAIL
2628*09537850SAkhilesh Sanikop #undef OBU_PARSER_FAIL
2629*09537850SAkhilesh Sanikop #undef OBU_LOG_AND_RETURN_FALSE
2630*09537850SAkhilesh Sanikop 
InitBitReader(const uint8_t * const data,size_t size)2631*09537850SAkhilesh Sanikop bool ObuParser::InitBitReader(const uint8_t* const data, size_t size) {
2632*09537850SAkhilesh Sanikop   bit_reader_.reset(new (std::nothrow) RawBitReader(data, size));
2633*09537850SAkhilesh Sanikop   return bit_reader_ != nullptr;
2634*09537850SAkhilesh Sanikop }
2635*09537850SAkhilesh Sanikop 
EnsureCurrentFrameIsNotNull()2636*09537850SAkhilesh Sanikop bool ObuParser::EnsureCurrentFrameIsNotNull() {
2637*09537850SAkhilesh Sanikop   if (current_frame_ != nullptr) return true;
2638*09537850SAkhilesh Sanikop   current_frame_ = buffer_pool_->GetFreeBuffer();
2639*09537850SAkhilesh Sanikop   if (current_frame_ == nullptr) {
2640*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Could not get current_frame from the buffer pool.");
2641*09537850SAkhilesh Sanikop     return false;
2642*09537850SAkhilesh Sanikop   }
2643*09537850SAkhilesh Sanikop   return true;
2644*09537850SAkhilesh Sanikop }
2645*09537850SAkhilesh Sanikop 
HasData() const2646*09537850SAkhilesh Sanikop bool ObuParser::HasData() const { return size_ > 0; }
2647*09537850SAkhilesh Sanikop 
ParseOneFrame(RefCountedBufferPtr * const current_frame)2648*09537850SAkhilesh Sanikop StatusCode ObuParser::ParseOneFrame(RefCountedBufferPtr* const current_frame) {
2649*09537850SAkhilesh Sanikop   if (data_ == nullptr || size_ == 0) return kStatusInvalidArgument;
2650*09537850SAkhilesh Sanikop 
2651*09537850SAkhilesh Sanikop   assert(current_frame_ == nullptr);
2652*09537850SAkhilesh Sanikop   // This is used to release any references held in case of parsing failure.
2653*09537850SAkhilesh Sanikop   RefCountedBufferPtrCleanup current_frame_cleanup(&current_frame_);
2654*09537850SAkhilesh Sanikop 
2655*09537850SAkhilesh Sanikop   const uint8_t* data = data_;
2656*09537850SAkhilesh Sanikop   size_t size = size_;
2657*09537850SAkhilesh Sanikop 
2658*09537850SAkhilesh Sanikop   // Clear everything except the sequence header.
2659*09537850SAkhilesh Sanikop   obu_headers_.clear();
2660*09537850SAkhilesh Sanikop   frame_header_ = {};
2661*09537850SAkhilesh Sanikop   tile_buffers_.clear();
2662*09537850SAkhilesh Sanikop   next_tile_group_start_ = 0;
2663*09537850SAkhilesh Sanikop   sequence_header_changed_ = false;
2664*09537850SAkhilesh Sanikop 
2665*09537850SAkhilesh Sanikop   bool parsed_one_full_frame = false;
2666*09537850SAkhilesh Sanikop   bool seen_frame_header = false;
2667*09537850SAkhilesh Sanikop   const uint8_t* frame_header = nullptr;
2668*09537850SAkhilesh Sanikop   size_t frame_header_size_in_bits = 0;
2669*09537850SAkhilesh Sanikop   while (size > 0 && !parsed_one_full_frame) {
2670*09537850SAkhilesh Sanikop     if (!InitBitReader(data, size)) {
2671*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Failed to initialize bit reader.");
2672*09537850SAkhilesh Sanikop       return kStatusOutOfMemory;
2673*09537850SAkhilesh Sanikop     }
2674*09537850SAkhilesh Sanikop     if (!ParseHeader()) {
2675*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Failed to parse OBU Header.");
2676*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2677*09537850SAkhilesh Sanikop     }
2678*09537850SAkhilesh Sanikop     const ObuHeader& obu_header = obu_headers_.back();
2679*09537850SAkhilesh Sanikop     if (!obu_header.has_size_field) {
2680*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
2681*09537850SAkhilesh Sanikop           ERROR,
2682*09537850SAkhilesh Sanikop           "has_size_field is zero. libgav1 does not support such streams.");
2683*09537850SAkhilesh Sanikop       return kStatusUnimplemented;
2684*09537850SAkhilesh Sanikop     }
2685*09537850SAkhilesh Sanikop     const size_t obu_header_size = bit_reader_->byte_offset();
2686*09537850SAkhilesh Sanikop     size_t obu_size;
2687*09537850SAkhilesh Sanikop     if (!bit_reader_->ReadUnsignedLeb128(&obu_size)) {
2688*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Could not read OBU size.");
2689*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2690*09537850SAkhilesh Sanikop     }
2691*09537850SAkhilesh Sanikop     const size_t obu_length_size = bit_reader_->byte_offset() - obu_header_size;
2692*09537850SAkhilesh Sanikop     if (size - bit_reader_->byte_offset() < obu_size) {
2693*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Not enough bits left to parse OBU %zu vs %zu.",
2694*09537850SAkhilesh Sanikop                    size - bit_reader_->bit_offset(), obu_size);
2695*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2696*09537850SAkhilesh Sanikop     }
2697*09537850SAkhilesh Sanikop 
2698*09537850SAkhilesh Sanikop     const ObuType obu_type = obu_header.type;
2699*09537850SAkhilesh Sanikop     if (obu_type != kObuSequenceHeader && obu_type != kObuTemporalDelimiter &&
2700*09537850SAkhilesh Sanikop         has_sequence_header_ &&
2701*09537850SAkhilesh Sanikop         sequence_header_.operating_point_idc[operating_point_] != 0 &&
2702*09537850SAkhilesh Sanikop         obu_header.has_extension &&
2703*09537850SAkhilesh Sanikop         (!InTemporalLayer(
2704*09537850SAkhilesh Sanikop              sequence_header_.operating_point_idc[operating_point_],
2705*09537850SAkhilesh Sanikop              obu_header.temporal_id) ||
2706*09537850SAkhilesh Sanikop          !InSpatialLayer(sequence_header_.operating_point_idc[operating_point_],
2707*09537850SAkhilesh Sanikop                          obu_header.spatial_id))) {
2708*09537850SAkhilesh Sanikop       obu_headers_.pop_back();
2709*09537850SAkhilesh Sanikop       bit_reader_->SkipBytes(obu_size);
2710*09537850SAkhilesh Sanikop       data += bit_reader_->byte_offset();
2711*09537850SAkhilesh Sanikop       size -= bit_reader_->byte_offset();
2712*09537850SAkhilesh Sanikop       continue;
2713*09537850SAkhilesh Sanikop     }
2714*09537850SAkhilesh Sanikop 
2715*09537850SAkhilesh Sanikop     const size_t obu_start_position = bit_reader_->bit_offset();
2716*09537850SAkhilesh Sanikop     // The bit_reader_ is byte aligned after reading obu_header and obu_size.
2717*09537850SAkhilesh Sanikop     // Therefore the byte offset can be computed as obu_start_position >> 3
2718*09537850SAkhilesh Sanikop     // below.
2719*09537850SAkhilesh Sanikop     assert((obu_start_position & 7) == 0);
2720*09537850SAkhilesh Sanikop     bool obu_skipped = false;
2721*09537850SAkhilesh Sanikop     switch (obu_type) {
2722*09537850SAkhilesh Sanikop       case kObuTemporalDelimiter:
2723*09537850SAkhilesh Sanikop         break;
2724*09537850SAkhilesh Sanikop       case kObuSequenceHeader:
2725*09537850SAkhilesh Sanikop         if (!ParseSequenceHeader(seen_frame_header)) {
2726*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse SequenceHeader OBU.");
2727*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2728*09537850SAkhilesh Sanikop         }
2729*09537850SAkhilesh Sanikop         if (sequence_header_.color_config.bitdepth > LIBGAV1_MAX_BITDEPTH) {
2730*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(
2731*09537850SAkhilesh Sanikop               ERROR,
2732*09537850SAkhilesh Sanikop               "Bitdepth %d is not supported. The maximum bitdepth is %d.",
2733*09537850SAkhilesh Sanikop               sequence_header_.color_config.bitdepth, LIBGAV1_MAX_BITDEPTH);
2734*09537850SAkhilesh Sanikop           return kStatusUnimplemented;
2735*09537850SAkhilesh Sanikop         }
2736*09537850SAkhilesh Sanikop         break;
2737*09537850SAkhilesh Sanikop       case kObuFrameHeader:
2738*09537850SAkhilesh Sanikop         if (seen_frame_header) {
2739*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
2740*09537850SAkhilesh Sanikop                        "Frame header found but frame header was already seen.");
2741*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2742*09537850SAkhilesh Sanikop         }
2743*09537850SAkhilesh Sanikop         if (!ParseFrameHeader()) {
2744*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse FrameHeader OBU.");
2745*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2746*09537850SAkhilesh Sanikop         }
2747*09537850SAkhilesh Sanikop         frame_header = &data[obu_start_position >> 3];
2748*09537850SAkhilesh Sanikop         frame_header_size_in_bits =
2749*09537850SAkhilesh Sanikop             bit_reader_->bit_offset() - obu_start_position;
2750*09537850SAkhilesh Sanikop         seen_frame_header = true;
2751*09537850SAkhilesh Sanikop         parsed_one_full_frame = frame_header_.show_existing_frame;
2752*09537850SAkhilesh Sanikop         break;
2753*09537850SAkhilesh Sanikop       case kObuRedundantFrameHeader: {
2754*09537850SAkhilesh Sanikop         if (!seen_frame_header) {
2755*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
2756*09537850SAkhilesh Sanikop                        "Redundant frame header found but frame header was not "
2757*09537850SAkhilesh Sanikop                        "yet seen.");
2758*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2759*09537850SAkhilesh Sanikop         }
2760*09537850SAkhilesh Sanikop         const size_t fh_size = (frame_header_size_in_bits + 7) >> 3;
2761*09537850SAkhilesh Sanikop         if (obu_size < fh_size ||
2762*09537850SAkhilesh Sanikop             memcmp(frame_header, &data[obu_start_position >> 3], fh_size) !=
2763*09537850SAkhilesh Sanikop                 0) {
2764*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
2765*09537850SAkhilesh Sanikop                        "Redundant frame header differs from frame header.");
2766*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2767*09537850SAkhilesh Sanikop         }
2768*09537850SAkhilesh Sanikop         bit_reader_->SkipBits(frame_header_size_in_bits);
2769*09537850SAkhilesh Sanikop         break;
2770*09537850SAkhilesh Sanikop       }
2771*09537850SAkhilesh Sanikop       case kObuFrame: {
2772*09537850SAkhilesh Sanikop         const size_t fh_start_offset = bit_reader_->byte_offset();
2773*09537850SAkhilesh Sanikop         if (seen_frame_header) {
2774*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR,
2775*09537850SAkhilesh Sanikop                        "Frame header found but frame header was already seen.");
2776*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2777*09537850SAkhilesh Sanikop         }
2778*09537850SAkhilesh Sanikop         if (!ParseFrameHeader()) {
2779*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse FrameHeader in Frame OBU.");
2780*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2781*09537850SAkhilesh Sanikop         }
2782*09537850SAkhilesh Sanikop         // Section 6.8.2: If obu_type is equal to OBU_FRAME, it is a
2783*09537850SAkhilesh Sanikop         // requirement of bitstream conformance that show_existing_frame is
2784*09537850SAkhilesh Sanikop         // equal to 0.
2785*09537850SAkhilesh Sanikop         if (frame_header_.show_existing_frame) {
2786*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Frame OBU cannot set show_existing_frame to 1.");
2787*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2788*09537850SAkhilesh Sanikop         }
2789*09537850SAkhilesh Sanikop         if (!bit_reader_->AlignToNextByte()) {
2790*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Byte alignment has non zero bits.");
2791*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2792*09537850SAkhilesh Sanikop         }
2793*09537850SAkhilesh Sanikop         const size_t fh_size = bit_reader_->byte_offset() - fh_start_offset;
2794*09537850SAkhilesh Sanikop         if (fh_size >= obu_size) {
2795*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Frame header size (%zu) >= obu_size (%zu).",
2796*09537850SAkhilesh Sanikop                        fh_size, obu_size);
2797*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2798*09537850SAkhilesh Sanikop         }
2799*09537850SAkhilesh Sanikop         if (!ParseTileGroup(obu_size - fh_size,
2800*09537850SAkhilesh Sanikop                             size_ - size + bit_reader_->byte_offset())) {
2801*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse TileGroup in Frame OBU.");
2802*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2803*09537850SAkhilesh Sanikop         }
2804*09537850SAkhilesh Sanikop         parsed_one_full_frame = true;
2805*09537850SAkhilesh Sanikop         break;
2806*09537850SAkhilesh Sanikop       }
2807*09537850SAkhilesh Sanikop       case kObuTileGroup:
2808*09537850SAkhilesh Sanikop         if (!ParseTileGroup(obu_size,
2809*09537850SAkhilesh Sanikop                             size_ - size + bit_reader_->byte_offset())) {
2810*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse TileGroup OBU.");
2811*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2812*09537850SAkhilesh Sanikop         }
2813*09537850SAkhilesh Sanikop         parsed_one_full_frame =
2814*09537850SAkhilesh Sanikop             (next_tile_group_start_ == frame_header_.tile_info.tile_count);
2815*09537850SAkhilesh Sanikop         break;
2816*09537850SAkhilesh Sanikop       case kObuTileList:
2817*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR, "Decoding of tile list OBUs is not supported.");
2818*09537850SAkhilesh Sanikop         return kStatusUnimplemented;
2819*09537850SAkhilesh Sanikop       case kObuPadding:
2820*09537850SAkhilesh Sanikop         if (!ParsePadding(&data[obu_start_position >> 3], obu_size)) {
2821*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse Padding OBU.");
2822*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2823*09537850SAkhilesh Sanikop         }
2824*09537850SAkhilesh Sanikop         break;
2825*09537850SAkhilesh Sanikop       case kObuMetadata:
2826*09537850SAkhilesh Sanikop         if (!ParseMetadata(&data[obu_start_position >> 3], obu_size)) {
2827*09537850SAkhilesh Sanikop           LIBGAV1_DLOG(ERROR, "Failed to parse Metadata OBU.");
2828*09537850SAkhilesh Sanikop           return kStatusBitstreamError;
2829*09537850SAkhilesh Sanikop         }
2830*09537850SAkhilesh Sanikop         break;
2831*09537850SAkhilesh Sanikop       default:
2832*09537850SAkhilesh Sanikop         // Skip reserved OBUs. Section 6.2.2: Reserved units are for future use
2833*09537850SAkhilesh Sanikop         // and shall be ignored by AV1 decoder.
2834*09537850SAkhilesh Sanikop         bit_reader_->SkipBytes(obu_size);
2835*09537850SAkhilesh Sanikop         obu_skipped = true;
2836*09537850SAkhilesh Sanikop         break;
2837*09537850SAkhilesh Sanikop     }
2838*09537850SAkhilesh Sanikop     if (obu_size > 0 && !obu_skipped && obu_type != kObuFrame &&
2839*09537850SAkhilesh Sanikop         obu_type != kObuTileGroup) {
2840*09537850SAkhilesh Sanikop       const size_t parsed_obu_size_in_bits =
2841*09537850SAkhilesh Sanikop           bit_reader_->bit_offset() - obu_start_position;
2842*09537850SAkhilesh Sanikop       if (obu_size * 8 < parsed_obu_size_in_bits) {
2843*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(
2844*09537850SAkhilesh Sanikop             ERROR,
2845*09537850SAkhilesh Sanikop             "Parsed OBU size (%zu bits) is greater than expected OBU size "
2846*09537850SAkhilesh Sanikop             "(%zu bytes) obu_type: %d.",
2847*09537850SAkhilesh Sanikop             parsed_obu_size_in_bits, obu_size, obu_type);
2848*09537850SAkhilesh Sanikop         return kStatusBitstreamError;
2849*09537850SAkhilesh Sanikop       }
2850*09537850SAkhilesh Sanikop       if (!bit_reader_->VerifyAndSkipTrailingBits(obu_size * 8 -
2851*09537850SAkhilesh Sanikop                                                   parsed_obu_size_in_bits)) {
2852*09537850SAkhilesh Sanikop         LIBGAV1_DLOG(ERROR,
2853*09537850SAkhilesh Sanikop                      "Error when verifying trailing bits for obu type: %d",
2854*09537850SAkhilesh Sanikop                      obu_type);
2855*09537850SAkhilesh Sanikop         return kStatusBitstreamError;
2856*09537850SAkhilesh Sanikop       }
2857*09537850SAkhilesh Sanikop     }
2858*09537850SAkhilesh Sanikop     const size_t bytes_consumed = bit_reader_->byte_offset();
2859*09537850SAkhilesh Sanikop     const size_t consumed_obu_size =
2860*09537850SAkhilesh Sanikop         bytes_consumed - obu_length_size - obu_header_size;
2861*09537850SAkhilesh Sanikop     if (consumed_obu_size != obu_size) {
2862*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR,
2863*09537850SAkhilesh Sanikop                    "OBU size (%zu) and consumed size (%zu) does not match for "
2864*09537850SAkhilesh Sanikop                    "obu_type: %d.",
2865*09537850SAkhilesh Sanikop                    obu_size, consumed_obu_size, obu_type);
2866*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2867*09537850SAkhilesh Sanikop     }
2868*09537850SAkhilesh Sanikop     data += bytes_consumed;
2869*09537850SAkhilesh Sanikop     size -= bytes_consumed;
2870*09537850SAkhilesh Sanikop   }
2871*09537850SAkhilesh Sanikop   if (!parsed_one_full_frame && seen_frame_header) {
2872*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "The last tile group in the frame was not received.");
2873*09537850SAkhilesh Sanikop     return kStatusBitstreamError;
2874*09537850SAkhilesh Sanikop   }
2875*09537850SAkhilesh Sanikop   data_ = data;
2876*09537850SAkhilesh Sanikop   size_ = size;
2877*09537850SAkhilesh Sanikop   *current_frame = std::move(current_frame_);
2878*09537850SAkhilesh Sanikop   return kStatusOk;
2879*09537850SAkhilesh Sanikop }
2880*09537850SAkhilesh Sanikop 
2881*09537850SAkhilesh Sanikop // AV1CodecConfigurationBox specification:
2882*09537850SAkhilesh Sanikop // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox.
2883*09537850SAkhilesh Sanikop // static
GetAV1CodecConfigurationBox(const uint8_t * data,size_t size,size_t * const av1c_size)2884*09537850SAkhilesh Sanikop std::unique_ptr<uint8_t[]> ObuParser::GetAV1CodecConfigurationBox(
2885*09537850SAkhilesh Sanikop     const uint8_t* data, size_t size, size_t* const av1c_size) {
2886*09537850SAkhilesh Sanikop   if (data == nullptr || av1c_size == nullptr) return nullptr;
2887*09537850SAkhilesh Sanikop 
2888*09537850SAkhilesh Sanikop   ObuSequenceHeader sequence_header;
2889*09537850SAkhilesh Sanikop   size_t sequence_header_offset;
2890*09537850SAkhilesh Sanikop   size_t sequence_header_size;
2891*09537850SAkhilesh Sanikop   const StatusCode status =
2892*09537850SAkhilesh Sanikop       ParseBasicStreamInfo(data, size, &sequence_header,
2893*09537850SAkhilesh Sanikop                            &sequence_header_offset, &sequence_header_size);
2894*09537850SAkhilesh Sanikop   if (status != kStatusOk) {
2895*09537850SAkhilesh Sanikop     *av1c_size = 0;
2896*09537850SAkhilesh Sanikop     return nullptr;
2897*09537850SAkhilesh Sanikop   }
2898*09537850SAkhilesh Sanikop 
2899*09537850SAkhilesh Sanikop   *av1c_size = 4 + sequence_header_size;
2900*09537850SAkhilesh Sanikop   std::unique_ptr<uint8_t[]> av1c_ptr(new (std::nothrow) uint8_t[*av1c_size]);
2901*09537850SAkhilesh Sanikop   if (av1c_ptr == nullptr) {
2902*09537850SAkhilesh Sanikop     *av1c_size = 0;
2903*09537850SAkhilesh Sanikop     return nullptr;
2904*09537850SAkhilesh Sanikop   }
2905*09537850SAkhilesh Sanikop   uint8_t* av1c = av1c_ptr.get();
2906*09537850SAkhilesh Sanikop   // unsigned int (1) marker = 1;
2907*09537850SAkhilesh Sanikop   // unsigned int (7) version = 1;
2908*09537850SAkhilesh Sanikop   av1c[0] = 0x81;
2909*09537850SAkhilesh Sanikop 
2910*09537850SAkhilesh Sanikop   // unsigned int (3) seq_profile;
2911*09537850SAkhilesh Sanikop   // unsigned int (5) seq_level_idx_0;
2912*09537850SAkhilesh Sanikop   const uint8_t seq_level_idx_0 = ((sequence_header.level[0].major - 2) << 2) |
2913*09537850SAkhilesh Sanikop                                   sequence_header.level[0].minor;
2914*09537850SAkhilesh Sanikop   av1c[1] = (sequence_header.profile << 5) | seq_level_idx_0;
2915*09537850SAkhilesh Sanikop 
2916*09537850SAkhilesh Sanikop   // unsigned int (1) seq_tier_0;
2917*09537850SAkhilesh Sanikop   // unsigned int (1) high_bitdepth;
2918*09537850SAkhilesh Sanikop   // unsigned int (1) twelve_bit;
2919*09537850SAkhilesh Sanikop   // unsigned int (1) monochrome;
2920*09537850SAkhilesh Sanikop   // unsigned int (1) chroma_subsampling_x;
2921*09537850SAkhilesh Sanikop   // unsigned int (1) chroma_subsampling_y;
2922*09537850SAkhilesh Sanikop   // unsigned int (2) chroma_sample_position;
2923*09537850SAkhilesh Sanikop   const auto high_bitdepth =
2924*09537850SAkhilesh Sanikop       static_cast<uint8_t>(sequence_header.color_config.bitdepth > 8);
2925*09537850SAkhilesh Sanikop   const auto twelve_bit =
2926*09537850SAkhilesh Sanikop       static_cast<uint8_t>(sequence_header.color_config.bitdepth == 12);
2927*09537850SAkhilesh Sanikop   av1c[2] =
2928*09537850SAkhilesh Sanikop       (sequence_header.tier[0] << 7) | (high_bitdepth << 6) |
2929*09537850SAkhilesh Sanikop       (twelve_bit << 5) |
2930*09537850SAkhilesh Sanikop       (static_cast<uint8_t>(sequence_header.color_config.is_monochrome) << 4) |
2931*09537850SAkhilesh Sanikop       (sequence_header.color_config.subsampling_x << 3) |
2932*09537850SAkhilesh Sanikop       (sequence_header.color_config.subsampling_y << 2) |
2933*09537850SAkhilesh Sanikop       sequence_header.color_config.chroma_sample_position;
2934*09537850SAkhilesh Sanikop 
2935*09537850SAkhilesh Sanikop   // unsigned int (3) reserved = 0;
2936*09537850SAkhilesh Sanikop   // unsigned int (1) initial_presentation_delay_present;
2937*09537850SAkhilesh Sanikop   // if (initial_presentation_delay_present) {
2938*09537850SAkhilesh Sanikop   //   unsigned int (4) initial_presentation_delay_minus_one;
2939*09537850SAkhilesh Sanikop   // } else {
2940*09537850SAkhilesh Sanikop   //   unsigned int (4) reserved = 0;
2941*09537850SAkhilesh Sanikop   // }
2942*09537850SAkhilesh Sanikop   av1c[3] = 0;
2943*09537850SAkhilesh Sanikop 
2944*09537850SAkhilesh Sanikop   // unsigned int (8) configOBUs[];
2945*09537850SAkhilesh Sanikop   memcpy(av1c + 4, data + sequence_header_offset, sequence_header_size);
2946*09537850SAkhilesh Sanikop 
2947*09537850SAkhilesh Sanikop   return av1c_ptr;
2948*09537850SAkhilesh Sanikop }
2949*09537850SAkhilesh Sanikop 
2950*09537850SAkhilesh Sanikop // static
ParseBasicStreamInfo(const uint8_t * data,size_t size,ObuSequenceHeader * sequence_header,size_t * sequence_header_offset,size_t * sequence_header_size)2951*09537850SAkhilesh Sanikop StatusCode ObuParser::ParseBasicStreamInfo(const uint8_t* data, size_t size,
2952*09537850SAkhilesh Sanikop                                            ObuSequenceHeader* sequence_header,
2953*09537850SAkhilesh Sanikop                                            size_t* sequence_header_offset,
2954*09537850SAkhilesh Sanikop                                            size_t* sequence_header_size) {
2955*09537850SAkhilesh Sanikop   DecoderState state;
2956*09537850SAkhilesh Sanikop   ObuParser parser(nullptr, 0, 0, nullptr, &state);
2957*09537850SAkhilesh Sanikop   if (!parser.InitBitReader(data, size)) {
2958*09537850SAkhilesh Sanikop     LIBGAV1_DLOG(ERROR, "Failed to initialize bit reader.");
2959*09537850SAkhilesh Sanikop     return kStatusOutOfMemory;
2960*09537850SAkhilesh Sanikop   }
2961*09537850SAkhilesh Sanikop   while (!parser.bit_reader_->Finished()) {
2962*09537850SAkhilesh Sanikop     const size_t obu_start_offset = parser.bit_reader_->byte_offset();
2963*09537850SAkhilesh Sanikop     if (!parser.ParseHeader()) {
2964*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Failed to parse OBU Header.");
2965*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2966*09537850SAkhilesh Sanikop     }
2967*09537850SAkhilesh Sanikop     const ObuHeader& obu_header = parser.obu_headers_.back();
2968*09537850SAkhilesh Sanikop     if (!obu_header.has_size_field) {
2969*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
2970*09537850SAkhilesh Sanikop           ERROR,
2971*09537850SAkhilesh Sanikop           "has_size_field is zero. libgav1 does not support such streams.");
2972*09537850SAkhilesh Sanikop       return kStatusUnimplemented;
2973*09537850SAkhilesh Sanikop     }
2974*09537850SAkhilesh Sanikop     size_t obu_size;
2975*09537850SAkhilesh Sanikop     if (!parser.bit_reader_->ReadUnsignedLeb128(&obu_size)) {
2976*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Could not read OBU size.");
2977*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2978*09537850SAkhilesh Sanikop     }
2979*09537850SAkhilesh Sanikop     if (size - parser.bit_reader_->byte_offset() < obu_size) {
2980*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Not enough bits left to parse OBU %zu vs %zu.",
2981*09537850SAkhilesh Sanikop                    size - parser.bit_reader_->bit_offset(), obu_size);
2982*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2983*09537850SAkhilesh Sanikop     }
2984*09537850SAkhilesh Sanikop     if (obu_header.type != kObuSequenceHeader) {
2985*09537850SAkhilesh Sanikop       parser.obu_headers_.pop_back();
2986*09537850SAkhilesh Sanikop       parser.bit_reader_->SkipBytes(obu_size);
2987*09537850SAkhilesh Sanikop       continue;
2988*09537850SAkhilesh Sanikop     }
2989*09537850SAkhilesh Sanikop     const size_t obu_start_position = parser.bit_reader_->bit_offset();
2990*09537850SAkhilesh Sanikop     if (!parser.ParseSequenceHeader(false)) {
2991*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(ERROR, "Failed to parse SequenceHeader OBU.");
2992*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
2993*09537850SAkhilesh Sanikop     }
2994*09537850SAkhilesh Sanikop     const size_t parsed_obu_size_in_bits =
2995*09537850SAkhilesh Sanikop         parser.bit_reader_->bit_offset() - obu_start_position;
2996*09537850SAkhilesh Sanikop     const uint64_t obu_size_in_bits = static_cast<uint64_t>(obu_size) * 8;
2997*09537850SAkhilesh Sanikop     if (obu_size_in_bits < parsed_obu_size_in_bits) {
2998*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
2999*09537850SAkhilesh Sanikop           ERROR,
3000*09537850SAkhilesh Sanikop           "Parsed OBU size (%zu bits) is greater than expected OBU size "
3001*09537850SAkhilesh Sanikop           "(%zu bytes)..",
3002*09537850SAkhilesh Sanikop           parsed_obu_size_in_bits, obu_size);
3003*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
3004*09537850SAkhilesh Sanikop     }
3005*09537850SAkhilesh Sanikop     if (!parser.bit_reader_->VerifyAndSkipTrailingBits(
3006*09537850SAkhilesh Sanikop             static_cast<size_t>(obu_size_in_bits - parsed_obu_size_in_bits))) {
3007*09537850SAkhilesh Sanikop       LIBGAV1_DLOG(
3008*09537850SAkhilesh Sanikop           ERROR, "Error when verifying trailing bits for the sequence header.");
3009*09537850SAkhilesh Sanikop       return kStatusBitstreamError;
3010*09537850SAkhilesh Sanikop     }
3011*09537850SAkhilesh Sanikop     *sequence_header = parser.sequence_header_;
3012*09537850SAkhilesh Sanikop     *sequence_header_offset = obu_start_offset;
3013*09537850SAkhilesh Sanikop     *sequence_header_size =
3014*09537850SAkhilesh Sanikop         parser.bit_reader_->byte_offset() - obu_start_offset;
3015*09537850SAkhilesh Sanikop     return kStatusOk;
3016*09537850SAkhilesh Sanikop   }
3017*09537850SAkhilesh Sanikop   // Sequence header was never found.
3018*09537850SAkhilesh Sanikop   return kStatusBitstreamError;
3019*09537850SAkhilesh Sanikop }
3020*09537850SAkhilesh Sanikop 
3021*09537850SAkhilesh Sanikop }  // namespace libgav1
3022