DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
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 MEDIA_FORMATS_MP4_BOX_READER_H_
6 #define MEDIA_FORMATS_MP4_BOX_READER_H_
7 
8 #include <map>
9 #include <vector>
10 
11 #include "packager/base/compiler_specific.h"
12 #include "packager/base/logging.h"
13 #include "packager/media/base/buffer_reader.h"
14 #include "packager/media/base/fourccs.h"
15 #include "packager/media/base/rcheck.h"
16 
17 namespace shaka {
18 namespace media {
19 namespace mp4 {
20 
21 struct Box;
22 
24 class BoxReader : public BufferReader {
25  public:
26  ~BoxReader();
27 
38  static BoxReader* ReadBox(const uint8_t* buf,
39  const size_t buf_size,
40  bool* err);
41 
51  static bool StartBox(const uint8_t* buf,
52  const size_t buf_size,
53  FourCC* type,
54  uint64_t* box_size,
55  bool* err) WARN_UNUSED_RESULT;
56 
61  bool ScanChildren() WARN_UNUSED_RESULT;
62 
64  bool ChildExist(Box* child) WARN_UNUSED_RESULT;
65 
69  bool ReadChild(Box* child) WARN_UNUSED_RESULT;
70 
73  bool TryReadChild(Box* child) WARN_UNUSED_RESULT;
74 
77  template <typename T>
78  bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
79 
82  template <typename T>
83  bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
84 
88  template <typename T>
89  bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
90 
91  bool ReadFourCC(FourCC* fourcc) {
92  uint32_t val;
93  if (!Read4(&val))
94  return false;
95  *fourcc = static_cast<FourCC>(val);
96  return true;
97  }
98 
99  FourCC type() const { return type_; }
100 
101  private:
102  BoxReader(const uint8_t* buf, size_t size);
103 
104  // Must be called immediately after init. If the return is false, this
105  // indicates that the box header and its contents were not available in the
106  // stream or were nonsensical, and that the box must not be used further. In
107  // this case, if |*err| is false, the problem was simply a lack of data, and
108  // should only be an error condition if some higher-level component knows that
109  // no more data is coming (i.e. EOS or end of containing box). If |*err| is
110  // true, the error is unrecoverable and the stream should be aborted.
111  bool ReadHeader(bool* err);
112 
113  FourCC type_;
114 
115  typedef std::multimap<FourCC, BoxReader*> ChildMap;
116 
117  // The set of child box FourCCs and their corresponding buffer readers. Only
118  // valid if scanned_ is true.
119  ChildMap children_;
120  bool scanned_;
121 
122  DISALLOW_COPY_AND_ASSIGN(BoxReader);
123 };
124 
125 // Template definitions.
126 template <typename T>
127 bool BoxReader::ReadChildren(std::vector<T>* children) {
128  RCHECK(TryReadChildren(children) && !children->empty());
129  return true;
130 }
131 
132 template <typename T>
133 bool BoxReader::TryReadChildren(std::vector<T>* children) {
134  DCHECK(scanned_);
135  DCHECK(children->empty());
136 
137  children->resize(1);
138  FourCC child_type = (*children)[0].BoxType();
139 
140  ChildMap::iterator start_itr = children_.lower_bound(child_type);
141  ChildMap::iterator end_itr = children_.upper_bound(child_type);
142  children->resize(std::distance(start_itr, end_itr));
143  typename std::vector<T>::iterator child_itr = children->begin();
144  for (ChildMap::iterator itr = start_itr; itr != end_itr; ++itr) {
145  RCHECK(child_itr->Parse(itr->second));
146  delete itr->second;
147  ++child_itr;
148  }
149  children_.erase(start_itr, end_itr);
150 
151  DVLOG(2) << "Found " << children->size() << " " << FourCCToString(child_type)
152  << " boxes.";
153  return true;
154 }
155 
156 template <typename T>
157 bool BoxReader::ReadAllChildren(std::vector<T>* children) {
158  DCHECK(!scanned_);
159  scanned_ = true;
160 
161  while (pos() < size()) {
162  BoxReader child_reader(&data()[pos()], size() - pos());
163  bool err;
164  if (!child_reader.ReadHeader(&err))
165  return false;
166 
167  T child;
168  RCHECK(child.Parse(&child_reader));
169  children->push_back(child);
170  RCHECK(SkipBytes(child_reader.size()));
171  }
172 
173  return true;
174 }
175 
176 } // namespace mp4
177 } // namespace media
178 } // namespace shaka
179 
180 #endif // MEDIA_FORMATS_MP4_BOX_READER_H_
bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:133
bool ReadAllChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:157
bool ScanChildren() WARN_UNUSED_RESULT
Definition: box_reader.cc:68
bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:127
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
Class for reading MP4 boxes.
Definition: box_reader.h:24
bool ReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:88
bool TryReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:105
static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULT
Definition: box_reader.cc:55
bool ChildExist(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:101
static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
Definition: box_reader.cc:37