Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Unified Diff: media/mp4/box_reader.cc

Issue 10536014: Implement ISO BMFF support in Media Source. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/mp4/box_reader.cc
diff --git a/media/mp4/box_reader.cc b/media/mp4/box_reader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a90be5c2e3f6ab2880d32e568682db2dc968cb90
--- /dev/null
+++ b/media/mp4/box_reader.cc
@@ -0,0 +1,164 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/mp4/box_reader.h"
+
+#include "base/logging.h"
+#include "media/mp4/rcheck.h"
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 alphabetical order
strobe_ 2012/06/07 16:33:54 Done.
+#include "media/mp4/box_definitions.h"
+#include <string.h>
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 system headers after box_reader.h
strobe_ 2012/06/07 16:33:54 Done.
+#include <algorithm>
+#include <map>
+#include <set>
+
+namespace media {
+namespace mp4 {
+
+bool BufferReader::Read(uint8* v) {
+ RCHECK(HasBytes(1));
+ *v = buf_[pos_++];
+ return true;
+}
+
+bool BufferReader::Read(int8* v) {
+ return Read(reinterpret_cast<uint8*>(v));
+}
+
+// Internal implementation of multi-byte reads
+template<typename T> bool BufferReader::Read_(T* v) {
+ RCHECK(HasBytes(sizeof(T)));
+
+ T tmp = 0;
+ for (size_t i = 0; i < sizeof(T); i++) {
+ tmp <<= 8;
+ tmp += buf_[pos_++];
+ }
+ *v = tmp;
+ return true;
+}
+
+bool BufferReader::Read(int16* v) { return Read_(v); }
+bool BufferReader::Read(int32* v) { return Read_(v); }
+bool BufferReader::Read(int64* v) { return Read_(v); }
+bool BufferReader::Read(uint16* v) { return Read_(v); }
+bool BufferReader::Read(uint32* v) { return Read_(v); }
+bool BufferReader::Read(uint64* v) { return Read_(v); }
+
+bool BufferReader::Read(std::vector<uint8>* t, size_t count) {
+ RCHECK(HasBytes(count));
+ t->clear();
+ t->insert(t->end(), buf_ + pos_, buf_ + pos_ + count);
+ pos_ += count;
+ return true;
+}
+
+bool BufferReader::Skip(size_t bytes) {
+ RCHECK(HasBytes(bytes));
+ pos_ += bytes;
+ return true;
+}
+
+bool BufferReader::Read4(uint64* v) {
+ uint32 tmp;
+ RCHECK(Read(&tmp));
+ *v = tmp;
+ return true;
+}
+
+bool BufferReader::Read4(int64* v) {
+ return Read4(reinterpret_cast<uint64*>(v));
+}
+
+
+BoxReader::BoxReader(const uint8* buf, const uint64 size)
+ : BufferReader(buf, size), scanned_(false) {};
+
+BoxReader::~BoxReader() {
+ if (scanned_ && !children_.empty()) {
+ for (auto itr = children_.begin(); itr != children_.end(); ++itr) {
+ DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
+ }
+ }
+}
+
+BoxReader* BoxReader::ReadTopLevelBox(const uint8* buf,
+ const size_t buf_size,
+ bool* err) {
+ BoxReader* r = new BoxReader(buf, buf_size);
+ if (r->ReadHeader(err) && r->size() <= buf_size) {
+ return r;
+ } else {
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 drop else to avoid a level of indent
strobe_ 2012/06/07 16:33:54 Done.
+ delete r;
+ return NULL;
+ }
+}
+
+bool BoxReader::StartTopLevelBox(const uint8* buf,
+ const size_t buf_size,
+ FourCC* type,
+ size_t* box_size,
+ bool* err) {
+ BoxReader r(buf, buf_size);
+ if (!r.ReadHeader(err)) return false;
+ *type = r.type();
+ *box_size = r.size();
+ return true;
+}
+
+bool BoxReader::ScanChildren() {
+ DCHECK(!scanned_);
+ scanned_ = true;
+
+ bool err;
+ // TODO(strobe): Check or correct for multimap not inserting elements in
+ // consistent order.
+ while (pos() < size()) {
+ BoxReader child(&buf_[pos_], size_ - pos_);
+ if (!child.ReadHeader(&err)) break;
+
+ children_.insert(std::pair<FourCC, BoxReader>(child.type(), child));
+ pos_ += child.size();
+ }
+
+ DCHECK(!err);
+ return !err && pos() == size();
+}
+
+bool BoxReader::ReadFullBoxHeader() {
+ uint32 vflags;
+ RCHECK(Read(&vflags));
+ version_ = vflags >> 24;
+ flags_ = vflags & 0xffffff;
+ return true;
+}
+
+bool BoxReader::ReadHeader(bool* err) {
+ uint64 size;
+ *err = false;
+
+ if (!HasBytes(8)) return false;
+ DCHECK(Read4(&size) && Read(&type_));
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 I believe you want CHECK here and below. Otherwise
strobe_ 2012/06/07 16:33:54 Done.
+
+ if (size == 0) {
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 Break this if/else chain up by early returning mor
strobe_ 2012/06/07 16:33:54 Done.
+ // Media Source specific: we do not support boxes that run to EOS.
+ *err = true;
+ } else if (size == 1) {
+ if (!HasBytes(8)) return false;
+ DCHECK(Read(&size));
+ if (size < 16) {
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 remove {}
strobe_ 2012/06/07 16:33:54 Done.
+ *err = true;
+ }
+ } else {
+ if (size < 8) {
acolwell GONE FROM CHROMIUM 2012/06/06 17:32:39 remove {}
strobe_ 2012/06/07 16:33:54 Done.
+ *err = true;
+ }
+ }
+ // Note that the pos_ head has advanced to the byte immediately after the
+ // header, which is where we want it.
+ size_ = size;
+ return !*err;
+}
+
+} // namespace mp4
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698