xref: /aosp_15_r20/external/libwebm/webm_parser/src/block_parser.h (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
1*103e46e4SHarish Mahendrakar // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2*103e46e4SHarish Mahendrakar //
3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license
4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source
5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found
6*103e46e4SHarish Mahendrakar // in the file PATENTS.  All contributing project authors may
7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree.
8*103e46e4SHarish Mahendrakar #ifndef SRC_BLOCK_PARSER_H_
9*103e46e4SHarish Mahendrakar #define SRC_BLOCK_PARSER_H_
10*103e46e4SHarish Mahendrakar 
11*103e46e4SHarish Mahendrakar #include <cassert>
12*103e46e4SHarish Mahendrakar #include <cstdint>
13*103e46e4SHarish Mahendrakar #include <type_traits>
14*103e46e4SHarish Mahendrakar #include <vector>
15*103e46e4SHarish Mahendrakar 
16*103e46e4SHarish Mahendrakar #include "src/block_header_parser.h"
17*103e46e4SHarish Mahendrakar #include "src/element_parser.h"
18*103e46e4SHarish Mahendrakar #include "src/var_int_parser.h"
19*103e46e4SHarish Mahendrakar #include "webm/callback.h"
20*103e46e4SHarish Mahendrakar #include "webm/dom_types.h"
21*103e46e4SHarish Mahendrakar #include "webm/element.h"
22*103e46e4SHarish Mahendrakar #include "webm/reader.h"
23*103e46e4SHarish Mahendrakar #include "webm/status.h"
24*103e46e4SHarish Mahendrakar 
25*103e46e4SHarish Mahendrakar namespace webm {
26*103e46e4SHarish Mahendrakar 
27*103e46e4SHarish Mahendrakar // Parses Block and SimpleBlock elements. It is recommended to use the
28*103e46e4SHarish Mahendrakar // BlockParser and SimpleBlockParser aliases.
29*103e46e4SHarish Mahendrakar // Spec reference:
30*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#Block
31*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#SimpleBlock
32*103e46e4SHarish Mahendrakar // http://www.webmproject.org/docs/container/#SimpleBlock
33*103e46e4SHarish Mahendrakar // http://www.webmproject.org/docs/container/#Block
34*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#block_structure
35*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#simpleblock_structure
36*103e46e4SHarish Mahendrakar template <typename T>
37*103e46e4SHarish Mahendrakar class BasicBlockParser : public ElementParser {
38*103e46e4SHarish Mahendrakar   static_assert(std::is_same<T, Block>::value ||
39*103e46e4SHarish Mahendrakar                     std::is_same<T, SimpleBlock>::value,
40*103e46e4SHarish Mahendrakar                 "T must be Block or SimpleBlock");
41*103e46e4SHarish Mahendrakar 
42*103e46e4SHarish Mahendrakar  public:
43*103e46e4SHarish Mahendrakar   Status Init(const ElementMetadata& metadata, std::uint64_t max_size) override;
44*103e46e4SHarish Mahendrakar 
45*103e46e4SHarish Mahendrakar   Status Feed(Callback* callback, Reader* reader,
46*103e46e4SHarish Mahendrakar               std::uint64_t* num_bytes_read) override;
47*103e46e4SHarish Mahendrakar 
48*103e46e4SHarish Mahendrakar   bool WasSkipped() const override;
49*103e46e4SHarish Mahendrakar 
50*103e46e4SHarish Mahendrakar   // Gets the parsed block header information. The frames are not included. This
51*103e46e4SHarish Mahendrakar   // must not be called until the parse has been successfully completed.
value()52*103e46e4SHarish Mahendrakar   const T& value() const {
53*103e46e4SHarish Mahendrakar     assert(state_ == State::kDone);
54*103e46e4SHarish Mahendrakar     return value_;
55*103e46e4SHarish Mahendrakar   }
56*103e46e4SHarish Mahendrakar 
57*103e46e4SHarish Mahendrakar   // Gets the parsed block header information. The frames are not included. This
58*103e46e4SHarish Mahendrakar   // must not be called until the parse has been successfully completed.
mutable_value()59*103e46e4SHarish Mahendrakar   T* mutable_value() {
60*103e46e4SHarish Mahendrakar     assert(state_ == State::kDone);
61*103e46e4SHarish Mahendrakar     return &value_;
62*103e46e4SHarish Mahendrakar   }
63*103e46e4SHarish Mahendrakar 
64*103e46e4SHarish Mahendrakar  private:
65*103e46e4SHarish Mahendrakar   // The number of header bytes read (header meaning everything before the
66*103e46e4SHarish Mahendrakar   // frames).
67*103e46e4SHarish Mahendrakar   std::uint64_t header_bytes_read_ = 0;
68*103e46e4SHarish Mahendrakar 
69*103e46e4SHarish Mahendrakar   // The parsed header value for the element.
70*103e46e4SHarish Mahendrakar   T value_{};
71*103e46e4SHarish Mahendrakar 
72*103e46e4SHarish Mahendrakar   // Metadata for the frame that is currently being read.
73*103e46e4SHarish Mahendrakar   FrameMetadata frame_metadata_;
74*103e46e4SHarish Mahendrakar 
75*103e46e4SHarish Mahendrakar   // Parser for parsing header metadata that is common between Block and
76*103e46e4SHarish Mahendrakar   // SimpleBlock.
77*103e46e4SHarish Mahendrakar   BlockHeaderParser header_parser_;
78*103e46e4SHarish Mahendrakar 
79*103e46e4SHarish Mahendrakar   // Parser for parsing unsigned EBML variable-sized integers.
80*103e46e4SHarish Mahendrakar   VarIntParser uint_parser_;
81*103e46e4SHarish Mahendrakar 
82*103e46e4SHarish Mahendrakar   // The current lace size when parsing Xiph lace sizes.
83*103e46e4SHarish Mahendrakar   std::uint64_t xiph_lace_size_ = 0;
84*103e46e4SHarish Mahendrakar 
85*103e46e4SHarish Mahendrakar   // Lace (frame) sizes, where each entry represents the size of a frame.
86*103e46e4SHarish Mahendrakar   std::vector<std::uint64_t> lace_sizes_;
87*103e46e4SHarish Mahendrakar 
88*103e46e4SHarish Mahendrakar   // The current index into lace_sizes_ for the current frame being read.
89*103e46e4SHarish Mahendrakar   std::size_t current_lace_ = 0;
90*103e46e4SHarish Mahendrakar 
91*103e46e4SHarish Mahendrakar   // Parsing states for the finite-state machine.
92*103e46e4SHarish Mahendrakar   enum class State {
93*103e46e4SHarish Mahendrakar     /* clang-format off */
94*103e46e4SHarish Mahendrakar     // State                        Transitions to state        When
95*103e46e4SHarish Mahendrakar     kReadingHeader,              // kGettingAction              no lacing
96*103e46e4SHarish Mahendrakar                                  // kReadingLaceCount           yes lacing
97*103e46e4SHarish Mahendrakar     kReadingLaceCount,           // kGettingAction              no errors
98*103e46e4SHarish Mahendrakar     kGettingAction,              // kSkipping                   action == skip
99*103e46e4SHarish Mahendrakar                                  // kValidatingSize             no lacing
100*103e46e4SHarish Mahendrakar                                  // kReadingXiphLaceSizes       xiph lacing
101*103e46e4SHarish Mahendrakar                                  // kReadingFirstEbmlLaceSize   ebml lacing
102*103e46e4SHarish Mahendrakar                                  // kCalculatingFixedLaceSizes  fixed lacing
103*103e46e4SHarish Mahendrakar     kReadingXiphLaceSizes,       // kValidatingSize             all sizes read
104*103e46e4SHarish Mahendrakar     kReadingFirstEbmlLaceSize,   // kReadingEbmlLaceSizes       first size read
105*103e46e4SHarish Mahendrakar     kReadingEbmlLaceSizes,       // kValidatingSize             all sizes read
106*103e46e4SHarish Mahendrakar     kCalculatingFixedLaceSizes,  // kReadingFrames              no errors
107*103e46e4SHarish Mahendrakar     kValidatingSize,             // kReadingFrames              no errors
108*103e46e4SHarish Mahendrakar     kSkipping,                   // No transitions from here (must call Init)
109*103e46e4SHarish Mahendrakar     kReadingFrames,              // kDone                       all frames read
110*103e46e4SHarish Mahendrakar     kDone,                       // No transitions from here (must call Init)
111*103e46e4SHarish Mahendrakar     /* clang-format on */
112*103e46e4SHarish Mahendrakar   };
113*103e46e4SHarish Mahendrakar 
114*103e46e4SHarish Mahendrakar   // The current state of the parser.
115*103e46e4SHarish Mahendrakar   State state_ = State::kReadingHeader;
116*103e46e4SHarish Mahendrakar };
117*103e46e4SHarish Mahendrakar 
118*103e46e4SHarish Mahendrakar extern template class BasicBlockParser<Block>;
119*103e46e4SHarish Mahendrakar extern template class BasicBlockParser<SimpleBlock>;
120*103e46e4SHarish Mahendrakar 
121*103e46e4SHarish Mahendrakar using BlockParser = BasicBlockParser<Block>;
122*103e46e4SHarish Mahendrakar using SimpleBlockParser = BasicBlockParser<SimpleBlock>;
123*103e46e4SHarish Mahendrakar 
124*103e46e4SHarish Mahendrakar }  // namespace webm
125*103e46e4SHarish Mahendrakar 
126*103e46e4SHarish Mahendrakar #endif  // SRC_BLOCK_PARSER_H_
127