OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MEDIA_FORMATS_MP4_BOX_READER_H_ | 5 #ifndef MEDIA_FORMATS_MP4_BOX_READER_H_ |
6 #define MEDIA_FORMATS_MP4_BOX_READER_H_ | 6 #define MEDIA_FORMATS_MP4_BOX_READER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 // true. The semantics of |*err| are the same as above. | 94 // true. The semantics of |*err| are the same as above. |
95 // | 95 // |
96 // |buf| is not retained. | 96 // |buf| is not retained. |
97 static bool StartTopLevelBox(const uint8* buf, | 97 static bool StartTopLevelBox(const uint8* buf, |
98 const int buf_size, | 98 const int buf_size, |
99 const LogCB& log_cb, | 99 const LogCB& log_cb, |
100 FourCC* type, | 100 FourCC* type, |
101 int* box_size, | 101 int* box_size, |
102 bool* err) WARN_UNUSED_RESULT; | 102 bool* err) WARN_UNUSED_RESULT; |
103 | 103 |
| 104 // Create a BoxReader from a buffer. |buf| must be the complete buffer, as |
| 105 // errors are returned when sufficient data is not available. |buf| can start |
| 106 // with any type of box -- it does not have to be IsValidTopLevelBox(). |
| 107 // |
| 108 // |buf| is retained but not owned, and must outlive the BoxReader instance. |
| 109 static BoxReader* ReadConcatentatedBoxes(const uint8* buf, |
| 110 const int buf_size); |
| 111 |
104 // Returns true if |type| is recognized to be a top-level box, false | 112 // Returns true if |type| is recognized to be a top-level box, false |
105 // otherwise. This returns true for some boxes which we do not parse. | 113 // otherwise. This returns true for some boxes which we do not parse. |
106 // Helpful in debugging misaligned appends. | 114 // Helpful in debugging misaligned appends. |
107 static bool IsValidTopLevelBox(const FourCC& type, | 115 static bool IsValidTopLevelBox(const FourCC& type, |
108 const LogCB& log_cb); | 116 const LogCB& log_cb); |
109 | 117 |
110 // Scan through all boxes within the current box, starting at the current | 118 // Scan through all boxes within the current box, starting at the current |
111 // buffer position. Must be called before any of the *Child functions work. | 119 // buffer position. Must be called before any of the *Child functions work. |
112 bool ScanChildren() WARN_UNUSED_RESULT; | 120 bool ScanChildren() WARN_UNUSED_RESULT; |
113 | 121 |
(...skipping 27 matching lines...) Expand all Loading... |
141 // the box has been initialized, and does not re-read the main box header. | 149 // the box has been initialized, and does not re-read the main box header. |
142 bool ReadFullBoxHeader() WARN_UNUSED_RESULT; | 150 bool ReadFullBoxHeader() WARN_UNUSED_RESULT; |
143 | 151 |
144 FourCC type() const { return type_; } | 152 FourCC type() const { return type_; } |
145 uint8 version() const { return version_; } | 153 uint8 version() const { return version_; } |
146 uint32 flags() const { return flags_; } | 154 uint32 flags() const { return flags_; } |
147 | 155 |
148 const LogCB& log_cb() const { return log_cb_; } | 156 const LogCB& log_cb() const { return log_cb_; } |
149 | 157 |
150 private: | 158 private: |
151 BoxReader(const uint8* buf, const int size, const LogCB& log_cb); | 159 // Create a BoxReader from |buf|. |is_EOS| should be true if |buf| is |
| 160 // complete stream (i.e. no additional data is expected to be appended). |
| 161 BoxReader(const uint8* buf, const int size, const LogCB& log_cb, bool is_EOS); |
152 | 162 |
153 // Must be called immediately after init. If the return is false, this | 163 // Must be called immediately after init. If the return is false, this |
154 // indicates that the box header and its contents were not available in the | 164 // indicates that the box header and its contents were not available in the |
155 // stream or were nonsensical, and that the box must not be used further. In | 165 // stream or were nonsensical, and that the box must not be used further. In |
156 // this case, if |*err| is false, the problem was simply a lack of data, and | 166 // this case, if |*err| is false, the problem was simply a lack of data, and |
157 // should only be an error condition if some higher-level component knows that | 167 // should only be an error condition if some higher-level component knows that |
158 // no more data is coming (i.e. EOS or end of containing box). If |*err| is | 168 // no more data is coming (i.e. EOS or end of containing box). If |*err| is |
159 // true, the error is unrecoverable and the stream should be aborted. | 169 // true, the error is unrecoverable and the stream should be aborted. |
160 bool ReadHeader(bool* err); | 170 bool ReadHeader(bool* err); |
161 | 171 |
162 LogCB log_cb_; | 172 LogCB log_cb_; |
163 FourCC type_; | 173 FourCC type_; |
164 uint8 version_; | 174 uint8 version_; |
165 uint32 flags_; | 175 uint32 flags_; |
166 | 176 |
167 typedef std::multimap<FourCC, BoxReader> ChildMap; | 177 typedef std::multimap<FourCC, BoxReader> ChildMap; |
168 | 178 |
169 // The set of child box FourCCs and their corresponding buffer readers. Only | 179 // The set of child box FourCCs and their corresponding buffer readers. Only |
170 // valid if scanned_ is true. | 180 // valid if scanned_ is true. |
171 ChildMap children_; | 181 ChildMap children_; |
172 bool scanned_; | 182 bool scanned_; |
| 183 |
| 184 // True if the buffer provided to the reader is the complete stream. |
| 185 const bool is_EOS_; |
173 }; | 186 }; |
174 | 187 |
175 // Template definitions | 188 // Template definitions |
176 template<typename T> bool BoxReader::ReadChildren(std::vector<T>* children) { | 189 template<typename T> bool BoxReader::ReadChildren(std::vector<T>* children) { |
177 RCHECK(MaybeReadChildren(children) && !children->empty()); | 190 RCHECK(MaybeReadChildren(children) && !children->empty()); |
178 return true; | 191 return true; |
179 } | 192 } |
180 | 193 |
181 template<typename T> | 194 template<typename T> |
182 bool BoxReader::MaybeReadChildren(std::vector<T>* children) { | 195 bool BoxReader::MaybeReadChildren(std::vector<T>* children) { |
(...skipping 17 matching lines...) Expand all Loading... |
200 << FourCCToString(child_type) << " boxes."; | 213 << FourCCToString(child_type) << " boxes."; |
201 return true; | 214 return true; |
202 } | 215 } |
203 | 216 |
204 template<typename T> | 217 template<typename T> |
205 bool BoxReader::ReadAllChildren(std::vector<T>* children) { | 218 bool BoxReader::ReadAllChildren(std::vector<T>* children) { |
206 DCHECK(!scanned_); | 219 DCHECK(!scanned_); |
207 scanned_ = true; | 220 scanned_ = true; |
208 | 221 |
209 bool err = false; | 222 bool err = false; |
210 while (pos() < size()) { | 223 while (pos_ < size_) { |
211 BoxReader child_reader(&buf_[pos_], size_ - pos_, log_cb_); | 224 BoxReader child_reader(&buf_[pos_], size_ - pos_, log_cb_, is_EOS_); |
212 if (!child_reader.ReadHeader(&err)) break; | 225 if (!child_reader.ReadHeader(&err)) break; |
213 T child; | 226 T child; |
214 RCHECK(child.Parse(&child_reader)); | 227 RCHECK(child.Parse(&child_reader)); |
215 children->push_back(child); | 228 children->push_back(child); |
216 pos_ += child_reader.size(); | 229 pos_ += child_reader.size(); |
217 } | 230 } |
218 | 231 |
219 return !err; | 232 return !err; |
220 } | 233 } |
221 | 234 |
222 } // namespace mp4 | 235 } // namespace mp4 |
223 } // namespace media | 236 } // namespace media |
224 | 237 |
225 #endif // MEDIA_FORMATS_MP4_BOX_READER_H_ | 238 #endif // MEDIA_FORMATS_MP4_BOX_READER_H_ |
OLD | NEW |