151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// found in the LICENSE file.
451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "media/formats/mp4/box_reader.h"
651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include <string.h>
851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include <algorithm>
951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include <map>
1051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include <set>
1151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "base/logging.h"
1351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
1451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "media/formats/mp4/box_definitions.h"
1551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "media/formats/mp4/rcheck.h"
1651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)namespace media {
1851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)namespace mp4 {
1951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)Box::~Box() {}
2151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BufferReader::Read1(uint8* v) {
2351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(HasBytes(1));
2451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *v = buf_[pos_++];
2551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
2651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
2751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Internal implementation of multi-byte reads
2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template<typename T> bool BufferReader::Read(T* v) {
3051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(HasBytes(sizeof(T)));
3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  T tmp = 0;
3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  for (size_t i = 0; i < sizeof(T); i++) {
3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    tmp <<= 8;
3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    tmp += buf_[pos_++];
3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *v = tmp;
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
41a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read2(uint16* v) { return Read(v); }
42a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read2s(int16* v) { return Read(v); }
43a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read4(uint32* v) { return Read(v); }
44a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read4s(int32* v) { return Read(v); }
45a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read8(uint64* v) { return Read(v); }
46a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read8s(int64* v) { return Read(v); }
47a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
48a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::ReadFourCC(FourCC* v) {
49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  return Read4(reinterpret_cast<uint32*>(v));
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BufferReader::ReadVec(std::vector<uint8>* vec, int count) {
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(HasBytes(count));
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  vec->clear();
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  vec->insert(vec->end(), buf_ + pos_, buf_ + pos_ + count);
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  pos_ += count;
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BufferReader::SkipBytes(int bytes) {
6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(HasBytes(bytes));
6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  pos_ += bytes;
6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
64a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
65a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
66a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read4Into8(uint64* v) {
67a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  uint32 tmp;
68a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  RCHECK(Read4(&tmp));
69a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  *v = tmp;
70a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  return true;
71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BufferReader::Read4sInto8s(int64* v) {
74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  // Beware of the need for sign extension.
75a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  int32 tmp;
7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(Read4s(&tmp));
7751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *v = tmp;
7851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
7951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
8051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)BoxReader::BoxReader(const uint8* buf, const int size,
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                     const LogCB& log_cb)
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    : BufferReader(buf, size),
8551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      log_cb_(log_cb),
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      type_(FOURCC_NULL),
8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      version_(0),
8851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      flags_(0),
89a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)      scanned_(false) {
9051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)BoxReader::~BoxReader() {
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (scanned_ && !children_.empty()) {
9451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (ChildMap::iterator itr = children_.begin();
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)         itr != children_.end(); ++itr) {
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
100a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
101a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// static
102a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf,
103a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                      const int buf_size,
104a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                      const LogCB& log_cb,
105a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                      bool* err) {
106a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size, log_cb));
107a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  if (!reader->ReadHeader(err))
108a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return NULL;
109a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
11051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (!IsValidTopLevelBox(reader->type(), log_cb)) {
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *err = true;
112a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return NULL;
11351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
11451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (reader->size() <= buf_size)
11651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return reader.release();
11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return NULL;
11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
12051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// static
12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::StartTopLevelBox(const uint8* buf,
123a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                 const int buf_size,
12451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 const LogCB& log_cb,
12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 FourCC* type,
126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                                 int* box_size,
12751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                 bool* err) {
12851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  BoxReader reader(buf, buf_size, log_cb);
12951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (!reader.ReadHeader(err)) return false;
13051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (!IsValidTopLevelBox(reader.type(), log_cb)) {
13151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *err = true;
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
13351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
13451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *type = reader.type();
13551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *box_size = reader.size();
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
13851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
13951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// static
14051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::IsValidTopLevelBox(const FourCC& type,
14151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                                   const LogCB& log_cb) {
14251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  switch (type) {
14351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_FTYP:
14451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_PDIN:
14551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_BLOC:
14651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_MOOV:
14751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_MOOF:
14851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_MFRA:
14951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_MDAT:
15051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_FREE:
15151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_SKIP:
15251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_META:
15351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_MECO:
15451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_STYP:
15551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_SIDX:
15651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case FOURCC_SSIX:
157a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case FOURCC_PRFT:
158a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case FOURCC_UUID:
159a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case FOURCC_EMSG:
16051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      return true;
16151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    default:
162a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)      // Hex is used to show nonprintable characters and aid in debugging
16351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      MEDIA_LOG(log_cb) << "Unrecognized top-level box type "
164a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        << FourCCToString(type);
16551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      return false;
166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  }
167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
168a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
169a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool BoxReader::ScanChildren() {
170a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  DCHECK(!scanned_);
171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  scanned_ = true;
17251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
17351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  bool err = false;
17451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  while (pos() < size()) {
17551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    BoxReader child(&buf_[pos_], size_ - pos_, log_cb_);
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!child.ReadHeader(&err)) break;
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
17851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    children_.insert(std::pair<FourCC, BoxReader>(child.type(), child));
17951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    pos_ += child.size();
18051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
18151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
18251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  DCHECK(!err);
18351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return !err && pos() == size();
18451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
18551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
18651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::HasChild(Box* child) {
18751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  DCHECK(scanned_);
18851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  DCHECK(child);
18951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return children_.count(child->BoxType()) > 0;
19051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
191a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
19251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::ReadChild(Box* child) {
19351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  DCHECK(scanned_);
19451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  FourCC child_type = child->BoxType();
19551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
19651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  ChildMap::iterator itr = children_.find(child_type);
19751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(itr != children_.end());
19851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  DVLOG(2) << "Found a " << FourCCToString(child_type) << " box.";
19951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(child->Parse(&itr->second));
20051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  children_.erase(itr);
20151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
20251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
20351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
20451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::MaybeReadChild(Box* child) {
205a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  if (!children_.count(child->BoxType())) return true;
20651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return ReadChild(child);
20751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
20851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
20951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::ReadFullBoxHeader() {
21051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  uint32 vflags;
21151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  RCHECK(Read4(&vflags));
21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  version_ = vflags >> 24;
21351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  flags_ = vflags & 0xffffff;
21451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  return true;
21551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
21651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
21751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool BoxReader::ReadHeader(bool* err) {
21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  uint64 size = 0;
21951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  *err = false;
22051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
22151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (!HasBytes(8)) return false;
22251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  CHECK(Read4Into8(&size) && ReadFourCC(&type_));
22351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  if (size == 0) {
225a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // Media Source specific: we do not support boxes that run to EOS.
22651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *err = true;
22751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
22851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  } else if (size == 1) {
22951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!HasBytes(8)) return false;
23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CHECK(Read8(&size));
23151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
23251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
23351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  // Implementation-specific: support for boxes larger than 2^31 has been
23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  // removed.
235a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  if (size < static_cast<uint64>(pos_) ||
23651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      size > static_cast<uint64>(kint32max)) {
23751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *err = true;
23851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
23951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  }
24051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
24151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  // Note that the pos_ head has advanced to the byte immediately after the
24251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  // header, which is where we want it.
24351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  size_ = size;
244a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)  return true;
24551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
24651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
24751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}  // namespace mp4
24851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}  // namespace media
24951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)