• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The libgav1 Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LIBGAV1_SRC_OBU_PARSER_H_
18 #define LIBGAV1_SRC_OBU_PARSER_H_
19 
20 #include <array>
21 #include <cstddef>
22 #include <cstdint>
23 #include <memory>
24 #include <type_traits>
25 #include <utility>
26 
27 #include "src/buffer_pool.h"
28 #include "src/decoder_state.h"
29 #include "src/dsp/common.h"
30 #include "src/gav1/decoder_buffer.h"
31 #include "src/gav1/status_code.h"
32 #include "src/quantizer.h"
33 #include "src/utils/common.h"
34 #include "src/utils/compiler_attributes.h"
35 #include "src/utils/constants.h"
36 #include "src/utils/raw_bit_reader.h"
37 #include "src/utils/segmentation.h"
38 #include "src/utils/vector.h"
39 
40 namespace libgav1 {
41 
42 // structs and enums related to Open Bitstream Units (OBU).
43 
44 enum {
45   kMinimumMajorBitstreamLevel = 2,
46   kSelectScreenContentTools = 2,
47   kSelectIntegerMv = 2,
48   kLoopRestorationTileSizeMax = 256,
49   kGlobalMotionAlphaBits = 12,
50   kGlobalMotionTranslationBits = 12,
51   kGlobalMotionTranslationOnlyBits = 9,
52   kGlobalMotionAlphaPrecisionBits = 15,
53   kGlobalMotionTranslationPrecisionBits = 6,
54   kGlobalMotionTranslationOnlyPrecisionBits = 3,
55   kMaxTileWidth = 4096,
56   kMaxTileArea = 4096 * 2304,
57   kPrimaryReferenceNone = 7,
58   // A special value of the scalability_mode_idc syntax element that indicates
59   // the picture prediction structure is specified in scalability_structure().
60   kScalabilitySS = 14
61 };  // anonymous enum
62 
63 struct ObuHeader {
64   ObuType type;
65   bool has_extension;
66   bool has_size_field;
67   int8_t temporal_id;
68   int8_t spatial_id;
69 };
70 
71 enum BitstreamProfile : uint8_t {
72   kProfile0,
73   kProfile1,
74   kProfile2,
75   kMaxProfiles
76 };
77 
78 // In the bitstream the level is encoded in five bits: the first three bits
79 // encode |major| - 2 and the last two bits encode |minor|.
80 //
81 // If the mapped level (major.minor) is in the tables in Annex A.3, there are
82 // bitstream conformance requirements on the maximum or minimum values of
83 // several variables. The encoded value of 31 (which corresponds to the mapped
84 // level 9.3) is the "maximum parameters" level and imposes no level-based
85 // constraints on the bitstream.
86 struct BitStreamLevel {
87   uint8_t major;  // Range: 2-9.
88   uint8_t minor;  // Range: 0-3.
89 };
90 
91 struct ColorConfig {
92   int8_t bitdepth;
93   bool is_monochrome;
94   ColorPrimary color_primary;
95   TransferCharacteristics transfer_characteristics;
96   MatrixCoefficients matrix_coefficients;
97   // A binary value (0 or 1) that is associated with the VideoFullRangeFlag
98   // variable specified in ISO/IEC 23091-4/ITUT H.273.
99   // * 0: the studio swing representation.
100   // * 1: the full swing representation.
101   ColorRange color_range;
102   int8_t subsampling_x;
103   int8_t subsampling_y;
104   ChromaSamplePosition chroma_sample_position;
105   bool separate_uv_delta_q;
106 };
107 
108 struct TimingInfo {
109   uint32_t num_units_in_tick;
110   uint32_t time_scale;
111   bool equal_picture_interval;
112   uint32_t num_ticks_per_picture;
113 };
114 
115 struct DecoderModelInfo {
116   uint8_t encoder_decoder_buffer_delay_length;
117   uint32_t num_units_in_decoding_tick;
118   uint8_t buffer_removal_time_length;
119   uint8_t frame_presentation_time_length;
120 };
121 
122 struct OperatingParameters {
123   uint32_t decoder_buffer_delay[kMaxOperatingPoints];
124   uint32_t encoder_buffer_delay[kMaxOperatingPoints];
125   bool low_delay_mode_flag[kMaxOperatingPoints];
126 };
127 
128 struct ObuSequenceHeader {
129   // Section 7.5:
130   //   Within a particular coded video sequence, the contents of
131   //   sequence_header_obu must be bit-identical each time the sequence header
132   //   appears except for the contents of operating_parameters_info. A new
133   //   coded video sequence is required if the sequence header parameters
134   //   change.
135   //
136   // IMPORTANT: ParametersChanged() is implemented with a memcmp() call. For
137   // this to work, this object and the |old| object must be initialized with
138   // an empty brace-enclosed list, which initializes any padding to zero bits.
139   // See https://en.cppreference.com/w/cpp/language/zero_initialization.
140   bool ParametersChanged(const ObuSequenceHeader& old) const;
141 
142   BitstreamProfile profile;
143   bool still_picture;
144   bool reduced_still_picture_header;
145   int operating_points;
146   int operating_point_idc[kMaxOperatingPoints];
147   BitStreamLevel level[kMaxOperatingPoints];
148   int8_t tier[kMaxOperatingPoints];
149   int8_t frame_width_bits;
150   int8_t frame_height_bits;
151   int32_t max_frame_width;
152   int32_t max_frame_height;
153   bool frame_id_numbers_present;
154   int8_t frame_id_length_bits;
155   int8_t delta_frame_id_length_bits;
156   bool use_128x128_superblock;
157   bool enable_filter_intra;
158   bool enable_intra_edge_filter;
159   bool enable_interintra_compound;
160   bool enable_masked_compound;
161   bool enable_warped_motion;
162   bool enable_dual_filter;
163   bool enable_order_hint;
164   // If enable_order_hint is true, order_hint_bits is in the range [1, 8].
165   // If enable_order_hint is false, order_hint_bits is 0.
166   int8_t order_hint_bits;
167   // order_hint_shift_bits equals (32 - order_hint_bits) % 32.
168   // This is used frequently in GetRelativeDistance().
169   uint8_t order_hint_shift_bits;
170   bool enable_jnt_comp;
171   bool enable_ref_frame_mvs;
172   bool choose_screen_content_tools;
173   int8_t force_screen_content_tools;
174   bool choose_integer_mv;
175   int8_t force_integer_mv;
176   bool enable_superres;
177   bool enable_cdef;
178   bool enable_restoration;
179   ColorConfig color_config;
180   bool timing_info_present_flag;
181   TimingInfo timing_info;
182   bool decoder_model_info_present_flag;
183   DecoderModelInfo decoder_model_info;
184   bool decoder_model_present_for_operating_point[kMaxOperatingPoints];
185   bool initial_display_delay_present_flag;
186   uint8_t initial_display_delay[kMaxOperatingPoints];
187   bool film_grain_params_present;
188 
189   // IMPORTANT: the operating_parameters member must be at the end of the
190   // struct so that ParametersChanged() can be implemented with a memcmp()
191   // call.
192   OperatingParameters operating_parameters;
193 };
194 // Verify it is safe to use offsetof with ObuSequenceHeader and to use memcmp
195 // to compare two ObuSequenceHeader objects.
196 static_assert(std::is_standard_layout<ObuSequenceHeader>::value, "");
197 // Verify operating_parameters is the last member of ObuSequenceHeader. The
198 // second assertion assumes that ObuSequenceHeader has no padding after the
199 // operating_parameters field. The first assertion is a sufficient condition
200 // for ObuSequenceHeader to have no padding after the operating_parameters
201 // field.
202 static_assert(alignof(ObuSequenceHeader) == alignof(OperatingParameters), "");
203 static_assert(sizeof(ObuSequenceHeader) ==
204                   offsetof(ObuSequenceHeader, operating_parameters) +
205                       sizeof(OperatingParameters),
206               "");
207 
208 struct TileBuffer {
209   const uint8_t* data;
210   size_t size;
211 };
212 
213 enum MetadataType : uint8_t {
214   // 0 is reserved for AOM use.
215   kMetadataTypeHdrContentLightLevel = 1,
216   kMetadataTypeHdrMasteringDisplayColorVolume = 2,
217   kMetadataTypeScalability = 3,
218   kMetadataTypeItutT35 = 4,
219   kMetadataTypeTimecode = 5,
220   // 6-31 are unregistered user private.
221   // 32 and greater are reserved for AOM use.
222 };
223 
224 class ObuParser : public Allocable {
225  public:
ObuParser(const uint8_t * const data,size_t size,int operating_point,BufferPool * const buffer_pool,DecoderState * const decoder_state)226   ObuParser(const uint8_t* const data, size_t size, int operating_point,
227             BufferPool* const buffer_pool, DecoderState* const decoder_state)
228       : data_(data),
229         size_(size),
230         operating_point_(operating_point),
231         buffer_pool_(buffer_pool),
232         decoder_state_(*decoder_state) {}
233 
234   // Not copyable or movable.
235   ObuParser(const ObuParser& rhs) = delete;
236   ObuParser& operator=(const ObuParser& rhs) = delete;
237 
238   // Returns true if there is more data that needs to be parsed.
239   bool HasData() const;
240 
241   // Parses a sequence of Open Bitstream Units until a decodable frame is found
242   // (or until the end of stream is reached). A decodable frame is considered to
243   // be found when one of the following happens:
244   //   * A kObuFrame is seen.
245   //   * The kObuTileGroup containing the last tile is seen.
246   //   * A kFrameHeader with show_existing_frame = true is seen.
247   //
248   // If the parsing is successful, relevant fields will be populated. The fields
249   // are valid only if the return value is kStatusOk. Returns kStatusOk on
250   // success, an error status otherwise. On success, |current_frame| will be
251   // populated with a valid frame buffer.
252   StatusCode ParseOneFrame(RefCountedBufferPtr* current_frame);
253 
254   // Get the AV1CodecConfigurationBox as described in
255   // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox. This
256   // does minimal bitstream parsing to obtain the necessary information to
257   // generate the av1c box. Returns a std::unique_ptr that contains the av1c
258   // data on success, nullptr otherwise. |av1c_size| must not be nullptr and
259   // will contain the size of the buffer pointed to by the std::unique_ptr.
260   static std::unique_ptr<uint8_t[]> GetAV1CodecConfigurationBox(
261       const uint8_t* data, size_t size, size_t* av1c_size);
262 
263   // Getters. Only valid if ParseOneFrame() completes successfully.
obu_headers()264   const Vector<ObuHeader>& obu_headers() const { return obu_headers_; }
sequence_header()265   const ObuSequenceHeader& sequence_header() const { return sequence_header_; }
frame_header()266   const ObuFrameHeader& frame_header() const { return frame_header_; }
tile_buffers()267   const Vector<TileBuffer>& tile_buffers() const { return tile_buffers_; }
268   // Returns true if the last call to ParseOneFrame() encountered a sequence
269   // header change.
sequence_header_changed()270   bool sequence_header_changed() const { return sequence_header_changed_; }
271 
272   // Setters.
set_sequence_header(const ObuSequenceHeader & sequence_header)273   void set_sequence_header(const ObuSequenceHeader& sequence_header) {
274     sequence_header_ = sequence_header;
275     has_sequence_header_ = true;
276   }
277 
278   // Moves |tile_buffers_| into |tile_buffers|.
MoveTileBuffers(Vector<TileBuffer> * tile_buffers)279   void MoveTileBuffers(Vector<TileBuffer>* tile_buffers) {
280     *tile_buffers = std::move(tile_buffers_);
281   }
282 
283  private:
284   // Initializes the bit reader. This is a function of its own to make unit
285   // testing of private functions simpler.
286   LIBGAV1_MUST_USE_RESULT bool InitBitReader(const uint8_t* data, size_t size);
287 
288   // Parse helper functions.
289   bool ParseHeader();  // 5.3.2 and 5.3.3.
290   bool ParseColorConfig(ObuSequenceHeader* sequence_header);       // 5.5.2.
291   bool ParseTimingInfo(ObuSequenceHeader* sequence_header);        // 5.5.3.
292   bool ParseDecoderModelInfo(ObuSequenceHeader* sequence_header);  // 5.5.4.
293   bool ParseOperatingParameters(ObuSequenceHeader* sequence_header,
294                                 int index);          // 5.5.5.
295   bool ParseSequenceHeader(bool seen_frame_header);  // 5.5.1.
296   bool ParseFrameParameters();                       // 5.9.2, 5.9.7 and 5.9.10.
297   void MarkInvalidReferenceFrames();                 // 5.9.4.
298   bool ParseFrameSizeAndRenderSize();                // 5.9.5 and 5.9.6.
299   bool ParseSuperResParametersAndComputeImageSize();  // 5.9.8 and 5.9.9.
300   // Checks the bitstream conformance requirement in Section 6.8.6.
301   bool ValidateInterFrameSize() const;
302   bool ParseReferenceOrderHint();
303   static int FindLatestBackwardReference(
304       const int current_frame_hint,
305       const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
306       const std::array<bool, kNumReferenceFrameTypes>& used_frame);
307   static int FindEarliestBackwardReference(
308       const int current_frame_hint,
309       const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
310       const std::array<bool, kNumReferenceFrameTypes>& used_frame);
311   static int FindLatestForwardReference(
312       const int current_frame_hint,
313       const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints,
314       const std::array<bool, kNumReferenceFrameTypes>& used_frame);
315   static int FindReferenceWithSmallestOutputOrder(
316       const std::array<int, kNumReferenceFrameTypes>& shifted_order_hints);
317   bool SetFrameReferences(int8_t last_frame_idx,
318                           int8_t gold_frame_idx);  // 7.8.
319   bool ParseLoopFilterParameters();                // 5.9.11.
320   bool ParseDeltaQuantizer(int8_t* delta);         // 5.9.13.
321   bool ParseQuantizerParameters();                 // 5.9.12.
322   bool ParseSegmentationParameters();              // 5.9.14.
323   bool ParseQuantizerIndexDeltaParameters();       // 5.9.17.
324   bool ParseLoopFilterDeltaParameters();           // 5.9.18.
325   void ComputeSegmentLosslessAndQIndex();
326   bool ParseCdefParameters();             // 5.9.19.
327   bool ParseLoopRestorationParameters();  // 5.9.20.
328   bool ParseTxModeSyntax();               // 5.9.21.
329   bool ParseFrameReferenceModeSyntax();   // 5.9.23.
330   // Returns whether skip mode is allowed. When it returns true, it also sets
331   // the frame_header_.skip_mode_frame array.
332   bool IsSkipModeAllowed();
333   bool ParseSkipModeParameters();  // 5.9.22.
334   bool ReadAllowWarpedMotion();
335   bool ParseGlobalParamSyntax(
336       int ref, int index,
337       const std::array<GlobalMotion, kNumReferenceFrameTypes>&
338           prev_global_motions);        // 5.9.25.
339   bool ParseGlobalMotionParameters();  // 5.9.24.
340   bool ParseFilmGrainParameters();     // 5.9.30.
341   bool ParseTileInfoSyntax();          // 5.9.15.
342   bool ParseFrameHeader();             // 5.9.
343   // |data| and |size| specify the payload data of the padding OBU.
344   // NOTE: Although the payload data is available in the bit_reader_ member,
345   // it is also passed to ParsePadding() as function parameters so that
346   // ParsePadding() can find the trailing bit of the OBU and skip over the
347   // payload data as an opaque chunk of data.
348   bool ParsePadding(const uint8_t* data, size_t size);  // 5.7.
349   bool ParseMetadataScalability();                      // 5.8.5 and 5.8.6.
350   bool ParseMetadataTimecode();                         // 5.8.7.
351   // |data| and |size| specify the payload data of the metadata OBU.
352   // NOTE: Although the payload data is available in the bit_reader_ member,
353   // it is also passed to ParseMetadata() as function parameters so that
354   // ParseMetadata() can find the trailing bit of the OBU and either extract
355   // or skip over the payload data as an opaque chunk of data.
356   bool ParseMetadata(const uint8_t* data, size_t size);  // 5.8.
357   // Adds and populates the TileBuffer for each tile in the tile group and
358   // updates |next_tile_group_start_|
359   bool AddTileBuffers(int start, int end, size_t total_size,
360                       size_t tg_header_size, size_t bytes_consumed_so_far);
361   bool ParseTileGroup(size_t size, size_t bytes_consumed_so_far);  // 5.11.1.
362 
363   // Populates |current_frame_| from the |buffer_pool_| if |current_frame_| is
364   // nullptr. Does not do anything otherwise. Returns true on success, false
365   // otherwise.
366   bool EnsureCurrentFrameIsNotNull();
367 
368   // Parses the basic bitstream information from the given AV1 stream in |data|.
369   // This is used for generating the AV1CodecConfigurationBox.
370   static StatusCode ParseBasicStreamInfo(const uint8_t* data, size_t size,
371                                          ObuSequenceHeader* sequence_header,
372                                          size_t* sequence_header_offset,
373                                          size_t* sequence_header_size);
374 
375   // Parser elements.
376   std::unique_ptr<RawBitReader> bit_reader_;
377   const uint8_t* data_;
378   size_t size_;
379   const int operating_point_;
380 
381   // OBU elements. Only valid if ParseOneFrame() completes successfully.
382   Vector<ObuHeader> obu_headers_;
383   ObuSequenceHeader sequence_header_ = {};
384   ObuFrameHeader frame_header_ = {};
385   Vector<TileBuffer> tile_buffers_;
386   // The expected starting tile number of the next Tile Group.
387   int next_tile_group_start_ = 0;
388   // If true, the sequence_header_ field is valid.
389   bool has_sequence_header_ = false;
390   // If true, it means that the last call to ParseOneFrame() encountered a
391   // sequence header change.
392   bool sequence_header_changed_ = false;
393   // If true, the obu_extension_flag syntax element in the OBU header must be
394   // 0. Set to true when parsing a sequence header if OperatingPointIdc is 0.
395   bool extension_disallowed_ = false;
396 
397   BufferPool* const buffer_pool_;
398   DecoderState& decoder_state_;
399   // Used by ParseOneFrame() to populate the current frame that is being
400   // decoded. The invariant maintained is that this variable will be nullptr at
401   // the beginning and at the end of each call to ParseOneFrame(). This ensures
402   // that the ObuParser is not holding on to any references to the current
403   // frame once the ParseOneFrame() call is complete.
404   RefCountedBufferPtr current_frame_;
405 
406   // For unit testing private functions.
407   friend class ObuParserTest;
408 };
409 
410 }  // namespace libgav1
411 
412 #endif  // LIBGAV1_SRC_OBU_PARSER_H_
413