| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 // Read at least one child. False means error or no such child present. | 133 // Read at least one child. False means error or no such child present. |
| 134 template<typename T> bool ReadChildren( | 134 template<typename T> bool ReadChildren( |
| 135 std::vector<T>* children) WARN_UNUSED_RESULT; | 135 std::vector<T>* children) WARN_UNUSED_RESULT; |
| 136 | 136 |
| 137 // Read any number of children. False means error. | 137 // Read any number of children. False means error. |
| 138 template<typename T> bool MaybeReadChildren( | 138 template<typename T> bool MaybeReadChildren( |
| 139 std::vector<T>* children) WARN_UNUSED_RESULT; | 139 std::vector<T>* children) WARN_UNUSED_RESULT; |
| 140 | 140 |
| 141 // Read all children, regardless of FourCC. This is used from exactly one box, | 141 // Read all children, regardless of FourCC. This is used from exactly one box, |
| 142 // corresponding to a rather significant inconsistency in the BMFF spec. | 142 // corresponding to a rather significant inconsistency in the BMFF spec. |
| 143 // Note that this method is mutually exclusive with ScanChildren(). | 143 // Note that this method is mutually exclusive with ScanChildren() and |
| 144 template<typename T> bool ReadAllChildren( | 144 // ReadAllChildrenAndCheckFourCC(). |
| 145 std::vector<T>* children) WARN_UNUSED_RESULT; | 145 template <typename T> |
| 146 bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT; |
| 147 |
| 148 // Read all children and verify that the FourCC matches what is expected. |
| 149 // Returns true if all children are successfully parsed and have the correct |
| 150 // box type for |T|. Note that this method is mutually exclusive with |
| 151 // ScanChildren() and ReadAllChildren(). |
| 152 template <typename T> |
| 153 bool ReadAllChildrenAndCheckFourCC(std::vector<T>* children) |
| 154 WARN_UNUSED_RESULT; |
| 146 | 155 |
| 147 // Populate the values of 'version()' and 'flags()' from a full box header. | 156 // Populate the values of 'version()' and 'flags()' from a full box header. |
| 148 // Many boxes, but not all, use these values. This call should happen after | 157 // Many boxes, but not all, use these values. This call should happen after |
| 149 // the box has been initialized, and does not re-read the main box header. | 158 // the box has been initialized, and does not re-read the main box header. |
| 150 bool ReadFullBoxHeader() WARN_UNUSED_RESULT; | 159 bool ReadFullBoxHeader() WARN_UNUSED_RESULT; |
| 151 | 160 |
| 152 FourCC type() const { return type_; } | 161 FourCC type() const { return type_; } |
| 153 uint8 version() const { return version_; } | 162 uint8 version() const { return version_; } |
| 154 uint32 flags() const { return flags_; } | 163 uint32 flags() const { return flags_; } |
| 155 | 164 |
| 156 const LogCB& log_cb() const { return log_cb_; } | 165 const LogCB& log_cb() const { return log_cb_; } |
| 157 | 166 |
| 158 private: | 167 private: |
| 159 // Create a BoxReader from |buf|. |is_EOS| should be true if |buf| is | 168 // 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). | 169 // 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); | 170 BoxReader(const uint8* buf, const int size, const LogCB& log_cb, bool is_EOS); |
| 162 | 171 |
| 163 // Must be called immediately after init. If the return is false, this | 172 // Must be called immediately after init. If the return is false, this |
| 164 // indicates that the box header and its contents were not available in the | 173 // indicates that the box header and its contents were not available in the |
| 165 // stream or were nonsensical, and that the box must not be used further. In | 174 // stream or were nonsensical, and that the box must not be used further. In |
| 166 // this case, if |*err| is false, the problem was simply a lack of data, and | 175 // this case, if |*err| is false, the problem was simply a lack of data, and |
| 167 // should only be an error condition if some higher-level component knows that | 176 // should only be an error condition if some higher-level component knows that |
| 168 // no more data is coming (i.e. EOS or end of containing box). If |*err| is | 177 // no more data is coming (i.e. EOS or end of containing box). If |*err| is |
| 169 // true, the error is unrecoverable and the stream should be aborted. | 178 // true, the error is unrecoverable and the stream should be aborted. |
| 170 bool ReadHeader(bool* err); | 179 bool ReadHeader(bool* err); |
| 171 | 180 |
| 181 // Read all children, optionally checking FourCC. Returns true if all |
| 182 // children are successfully parsed and, if |check_box_type|, have the |
| 183 // correct box type for |T|. Note that this method is mutually exclusive |
| 184 // with ScanChildren(). |
| 185 template <typename T> |
| 186 bool ReadAllChildrenInternal(std::vector<T>* children, bool check_box_type); |
| 187 |
| 172 LogCB log_cb_; | 188 LogCB log_cb_; |
| 173 FourCC type_; | 189 FourCC type_; |
| 174 uint8 version_; | 190 uint8 version_; |
| 175 uint32 flags_; | 191 uint32 flags_; |
| 176 | 192 |
| 177 typedef std::multimap<FourCC, BoxReader> ChildMap; | 193 typedef std::multimap<FourCC, BoxReader> ChildMap; |
| 178 | 194 |
| 179 // The set of child box FourCCs and their corresponding buffer readers. Only | 195 // The set of child box FourCCs and their corresponding buffer readers. Only |
| 180 // valid if scanned_ is true. | 196 // valid if scanned_ is true. |
| 181 ChildMap children_; | 197 ChildMap children_; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 207 RCHECK(child_itr->Parse(&itr->second)); | 223 RCHECK(child_itr->Parse(&itr->second)); |
| 208 ++child_itr; | 224 ++child_itr; |
| 209 } | 225 } |
| 210 children_.erase(start_itr, end_itr); | 226 children_.erase(start_itr, end_itr); |
| 211 | 227 |
| 212 DVLOG(2) << "Found " << children->size() << " " | 228 DVLOG(2) << "Found " << children->size() << " " |
| 213 << FourCCToString(child_type) << " boxes."; | 229 << FourCCToString(child_type) << " boxes."; |
| 214 return true; | 230 return true; |
| 215 } | 231 } |
| 216 | 232 |
| 217 template<typename T> | 233 template <typename T> |
| 218 bool BoxReader::ReadAllChildren(std::vector<T>* children) { | 234 bool BoxReader::ReadAllChildren(std::vector<T>* children) { |
| 235 return ReadAllChildrenInternal(children, false); |
| 236 } |
| 237 |
| 238 template <typename T> |
| 239 bool BoxReader::ReadAllChildrenAndCheckFourCC(std::vector<T>* children) { |
| 240 return ReadAllChildrenInternal(children, true); |
| 241 } |
| 242 |
| 243 template <typename T> |
| 244 bool BoxReader::ReadAllChildrenInternal(std::vector<T>* children, |
| 245 bool check_box_type) { |
| 219 DCHECK(!scanned_); | 246 DCHECK(!scanned_); |
| 220 scanned_ = true; | 247 scanned_ = true; |
| 221 | 248 |
| 222 bool err = false; | 249 bool err = false; |
| 223 while (pos_ < size_) { | 250 while (pos_ < size_) { |
| 224 BoxReader child_reader(&buf_[pos_], size_ - pos_, log_cb_, is_EOS_); | 251 BoxReader child_reader(&buf_[pos_], size_ - pos_, log_cb_, is_EOS_); |
| 225 if (!child_reader.ReadHeader(&err)) break; | 252 if (!child_reader.ReadHeader(&err)) break; |
| 226 T child; | 253 T child; |
| 254 RCHECK(!check_box_type || child_reader.type() == child.BoxType()); |
| 227 RCHECK(child.Parse(&child_reader)); | 255 RCHECK(child.Parse(&child_reader)); |
| 228 children->push_back(child); | 256 children->push_back(child); |
| 229 pos_ += child_reader.size(); | 257 pos_ += child_reader.size(); |
| 230 } | 258 } |
| 231 | 259 |
| 232 return !err; | 260 return !err; |
| 233 } | 261 } |
| 234 | 262 |
| 235 } // namespace mp4 | 263 } // namespace mp4 |
| 236 } // namespace media | 264 } // namespace media |
| 237 | 265 |
| 238 #endif // MEDIA_FORMATS_MP4_BOX_READER_H_ | 266 #endif // MEDIA_FORMATS_MP4_BOX_READER_H_ |
| OLD | NEW |