Shaka Packager SDK
Loading...
Searching...
No Matches
box_reader.h
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
6#define PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
7
8#include <cstdint>
9#include <map>
10#include <memory>
11#include <vector>
12
13#include <absl/log/check.h>
14#include <absl/log/log.h>
15
16#include <packager/macros/classes.h>
17#include <packager/macros/logging.h>
18#include <packager/media/base/buffer_reader.h>
19#include <packager/media/base/fourccs.h>
20#include <packager/media/base/rcheck.h>
21
22namespace shaka {
23namespace media {
24namespace mp4 {
25
26struct Box;
27
29class BoxReader : public BufferReader {
30 public:
31 ~BoxReader();
32
43 static BoxReader* ReadBox(const uint8_t* buf,
44 const size_t buf_size,
45 bool* err);
46
56 [[nodiscard]] static bool StartBox(const uint8_t* buf,
57 const size_t buf_size,
58 FourCC* type,
59 uint64_t* box_size,
60 bool* err);
61
66 [[nodiscard]] bool ScanChildren();
67
69 [[nodiscard]] bool ChildExist(Box* child);
70
74 [[nodiscard]] bool ReadChild(Box* child);
75
78 [[nodiscard]] bool TryReadChild(Box* child);
79
82 template <typename T>
83 [[nodiscard]] bool ReadChildren(std::vector<T>* children);
84
87 template <typename T>
88 [[nodiscard]] bool TryReadChildren(std::vector<T>* children);
89
93 template <typename T>
94 [[nodiscard]] bool ReadAllChildren(std::vector<T>* children);
95
96 bool ReadFourCC(FourCC* fourcc) {
97 uint32_t val;
98 if (!Read4(&val))
99 return false;
100 *fourcc = static_cast<FourCC>(val);
101 return true;
102 }
103
104 FourCC type() const { return type_; }
105
106 private:
107 BoxReader(const uint8_t* buf, size_t size);
108
109 // Must be called immediately after init. If the return is false, this
110 // indicates that the box header and its contents were not available in the
111 // stream or were nonsensical, and that the box must not be used further. In
112 // this case, if |*err| is false, the problem was simply a lack of data, and
113 // should only be an error condition if some higher-level component knows that
114 // no more data is coming (i.e. EOS or end of containing box). If |*err| is
115 // true, the error is unrecoverable and the stream should be aborted.
116 bool ReadHeader(bool* err);
117
118 FourCC type_;
119
120 typedef std::multimap<FourCC, std::unique_ptr<BoxReader>> ChildMap;
121
122 // The set of child box FourCCs and their corresponding buffer readers. Only
123 // valid if scanned_ is true.
124 ChildMap children_;
125 bool scanned_;
126
127 DISALLOW_COPY_AND_ASSIGN(BoxReader);
128};
129
130// Template definitions.
131template <typename T>
132bool BoxReader::ReadChildren(std::vector<T>* children) {
133 RCHECK(TryReadChildren(children) && !children->empty());
134 return true;
135}
136
137template <typename T>
138bool BoxReader::TryReadChildren(std::vector<T>* children) {
139 DCHECK(scanned_);
140 DCHECK(children->empty());
141
142 children->resize(1);
143 FourCC child_type = (*children)[0].BoxType();
144
145 ChildMap::iterator start_itr = children_.lower_bound(child_type);
146 ChildMap::iterator end_itr = children_.upper_bound(child_type);
147 children->resize(std::distance(start_itr, end_itr));
148 typename std::vector<T>::iterator child_itr = children->begin();
149 for (ChildMap::iterator itr = start_itr; itr != end_itr; ++itr) {
150 RCHECK(child_itr->Parse(itr->second.get()));
151 ++child_itr;
152 }
153 children_.erase(start_itr, end_itr);
154
155 DVLOG(2) << "Found " << children->size() << " " << FourCCToString(child_type)
156 << " boxes.";
157 return true;
158}
159
160template <typename T>
161bool BoxReader::ReadAllChildren(std::vector<T>* children) {
162 DCHECK(!scanned_);
163 scanned_ = true;
164
165 while (pos() < size()) {
166 BoxReader child_reader(&data()[pos()], size() - pos());
167 bool err;
168 if (!child_reader.ReadHeader(&err))
169 return false;
170
171 T child;
172 RCHECK(child.Parse(&child_reader));
173 children->push_back(child);
174 RCHECK(SkipBytes(child_reader.size()));
175 }
176
177 return true;
178}
179
180} // namespace mp4
181} // namespace media
182} // namespace shaka
183
184#endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
bool SkipBytes(size_t num_bytes)
Class for reading MP4 boxes.
Definition box_reader.h:29
static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err)
Definition box_reader.cc:56
bool ReadChildren(std::vector< T > *children)
Definition box_reader.h:132
bool ChildExist(Box *child)
bool ReadChild(Box *child)
Definition box_reader.cc:92
bool TryReadChild(Box *child)
bool ReadAllChildren(std::vector< T > *children)
Definition box_reader.h:161
static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
Definition box_reader.cc:38
bool TryReadChildren(std::vector< T > *children)
Definition box_reader.h:138
All the methods that are virtual are virtual for mocking.