diff --git a/media/base/buffer_reader.cc b/media/base/buffer_reader.cc new file mode 100644 index 0000000000..6cc124dfa7 --- /dev/null +++ b/media/base/buffer_reader.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2013 Google Inc. 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/base/buffer_reader.h" + +#include "base/logging.h" + +namespace media { + +bool BufferReader::Read1(uint8* v) { + DCHECK(v != NULL); + if (!HasBytes(1)) + return false; + *v = buf_[pos_++]; + return true; +} + +bool BufferReader::Read2(uint16* v) { return Read(v); } +bool BufferReader::Read2s(int16* v) { return Read(v); } +bool BufferReader::Read4(uint32* v) { return Read(v); } +bool BufferReader::Read4s(int32* v) { return Read(v); } +bool BufferReader::Read8(uint64* v) { return Read(v); } +bool BufferReader::Read8s(int64* v) { return Read(v); } +bool BufferReader::ReadNBytesInto8(uint64* v, size_t num_bytes) { + return ReadNBytes(v, num_bytes); +} +bool BufferReader::ReadNBytesInto8s(int64* v, size_t num_bytes) { + return ReadNBytes(v, num_bytes); +} + +bool BufferReader::ReadToVector(std::vector* vec, size_t count) { + DCHECK(vec != NULL); + if (!HasBytes(count)) + return false; + vec->assign(buf_ + pos_, buf_ + pos_ + count); + pos_ += count; + return true; +} + +bool BufferReader::SkipBytes(size_t num_bytes) { + if (!HasBytes(num_bytes)) + return false; + pos_ += num_bytes; + return true; +} + +template +bool BufferReader::Read(T* v) { + return ReadNBytes(v, sizeof(*v)); +} + +template +bool BufferReader::ReadNBytes(T* v, size_t num_bytes) { + DCHECK(v != NULL); + DCHECK_LE(num_bytes, sizeof(*v)); + if (!HasBytes(num_bytes)) + return false; + + // Sign extension is required only if + // |num_bytes| is less than size of T, and + // T is a signed type. + const bool sign_extension_required = + num_bytes < sizeof(*v) && static_cast(-1) < 0; + // Perform sign extension by casting the byte value to int8, which will be + // sign extended automatically when it is implicitly converted to T. + T tmp = + sign_extension_required ? static_cast(buf_[pos_++]) : buf_[pos_++]; + for (size_t i = 1; i < num_bytes; ++i) { + tmp <<= 8; + tmp |= buf_[pos_++]; + } + *v = tmp; + return true; +} + +} // namespace media diff --git a/media/base/buffer_reader.h b/media/base/buffer_reader.h new file mode 100644 index 0000000000..7af28e7f11 --- /dev/null +++ b/media/base/buffer_reader.h @@ -0,0 +1,68 @@ +// Copyright (c) 2013 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_BUFFER_READER_H_ +#define MEDIA_BASE_BUFFER_READER_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" + +namespace media { + +// A simple buffer reader implementation, which reads data of various type +// from a fixed byte array. +class BufferReader { + public: + BufferReader(const uint8* buf, size_t size) + : buf_(buf), size_(size), pos_(0) {} + ~BufferReader() {} + + bool HasBytes(size_t count) { return pos() + count <= size(); } + + // Read a value from the stream, performing endian correction, and advance + // the stream pointer. + // Return false if there are not enough bytes in the buffer. + bool Read1(uint8* v) WARN_UNUSED_RESULT; + bool Read2(uint16* v) WARN_UNUSED_RESULT; + bool Read2s(int16* v) WARN_UNUSED_RESULT; + bool Read4(uint32* v) WARN_UNUSED_RESULT; + bool Read4s(int32* v) WARN_UNUSED_RESULT; + bool Read8(uint64* v) WARN_UNUSED_RESULT; + bool Read8s(int64* v) WARN_UNUSED_RESULT; + // Read a N-byte integer of the corresponding signedness and store it in the + // 8-byte return type. |num_bytes| should not be larger than 8 bytes. + // Return false if there are not enough bytes in the buffer. + bool ReadNBytesInto8(uint64* v, size_t num_bytes) WARN_UNUSED_RESULT; + bool ReadNBytesInto8s(int64* v, size_t num_bytes) WARN_UNUSED_RESULT; + + bool ReadToVector(std::vector* t, size_t count) WARN_UNUSED_RESULT; + + // Advance the stream by this many bytes. + // Return false if there are not enough bytes in the buffer. + bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT; + + const uint8* data() const { return buf_; } + size_t size() const { return size_; } + void set_size(size_t size) { size_ = size; } + size_t pos() const { return pos_; } + + private: + // Internal implementation of multi-byte reads. + template + bool Read(T* t) WARN_UNUSED_RESULT; + template + bool ReadNBytes(T* t, size_t num_bytes) WARN_UNUSED_RESULT; + + const uint8* buf_; + size_t size_; + size_t pos_; + + DISALLOW_COPY_AND_ASSIGN(BufferReader); +}; + +} // namespace media + +#endif // MEDIA_BASE_BUFFER_READER_H_ diff --git a/media/base/demuxer.h b/media/base/demuxer.h index 26274a0879..6e58c4b93b 100644 --- a/media/base/demuxer.h +++ b/media/base/demuxer.h @@ -44,7 +44,7 @@ class Demuxer { Status Parse(); // Returns the vector of streams in this Demuxer. The caller cannot add or - // remove streams from the returned vector, but the caller could change + // remove streams from the returned vector, but the caller is safe to change // the internal state of the streams in the vector through MediaStream APIs. const std::vector& streams() { return streams_; } @@ -67,6 +67,7 @@ class Demuxer { DISALLOW_COPY_AND_ASSIGN(Demuxer); }; -} + +} // namespace media #endif // MEDIA_BASE_DEMUXER_H_ diff --git a/media/mp4/box_reader.cc b/media/mp4/box_reader.cc index e506259241..b6b3282229 100644 --- a/media/mp4/box_reader.cc +++ b/media/mp4/box_reader.cc @@ -19,66 +19,6 @@ namespace mp4 { Box::~Box() {} -bool BufferReader::Read1(uint8* v) { - RCHECK(HasBytes(1)); - *v = buf_[pos_++]; - return true; -} - -// Internal implementation of multi-byte reads -template 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::Read2(uint16* v) { return Read(v); } -bool BufferReader::Read2s(int16* v) { return Read(v); } -bool BufferReader::Read4(uint32* v) { return Read(v); } -bool BufferReader::Read4s(int32* v) { return Read(v); } -bool BufferReader::Read8(uint64* v) { return Read(v); } -bool BufferReader::Read8s(int64* v) { return Read(v); } - -bool BufferReader::ReadFourCC(FourCC* v) { - return Read4(reinterpret_cast(v)); -} - -bool BufferReader::ReadVec(std::vector* vec, int count) { - RCHECK(HasBytes(count)); - vec->clear(); - vec->insert(vec->end(), buf_ + pos_, buf_ + pos_ + count); - pos_ += count; - return true; -} - -bool BufferReader::SkipBytes(int bytes) { - RCHECK(HasBytes(bytes)); - pos_ += bytes; - return true; -} - -bool BufferReader::Read4Into8(uint64* v) { - uint32 tmp; - RCHECK(Read4(&tmp)); - *v = tmp; - return true; -} - -bool BufferReader::Read4sInto8s(int64* v) { - // Beware of the need for sign extension. - int32 tmp; - RCHECK(Read4s(&tmp)); - *v = tmp; - return true; -} - - BoxReader::BoxReader(const uint8* buf, const int size) : BufferReader(buf, size), type_(FOURCC_NULL), diff --git a/media/mp4/box_reader.h b/media/mp4/box_reader.h index ec723e1530..33a2ec1f21 100644 --- a/media/mp4/box_reader.h +++ b/media/mp4/box_reader.h @@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" +#include "media/base/buffer_reader.h" #include "media/mp4/fourccs.h" #include "media/mp4/rcheck.h" @@ -24,47 +25,6 @@ struct Box { virtual FourCC BoxType() const = 0; }; -class BufferReader { - public: - BufferReader(const uint8* buf, const int size) - : buf_(buf), size_(size), pos_(0) {} - - bool HasBytes(int count) { return (pos() + count <= size()); } - - // Read a value from the stream, perfoming endian correction, and advance the - // stream pointer. - bool Read1(uint8* v) WARN_UNUSED_RESULT; - bool Read2(uint16* v) WARN_UNUSED_RESULT; - bool Read2s(int16* v) WARN_UNUSED_RESULT; - bool Read4(uint32* v) WARN_UNUSED_RESULT; - bool Read4s(int32* v) WARN_UNUSED_RESULT; - bool Read8(uint64* v) WARN_UNUSED_RESULT; - bool Read8s(int64* v) WARN_UNUSED_RESULT; - - bool ReadFourCC(FourCC* v) WARN_UNUSED_RESULT; - - bool ReadVec(std::vector* t, int count) WARN_UNUSED_RESULT; - - // These variants read a 4-byte integer of the corresponding signedness and - // store it in the 8-byte return type. - bool Read4Into8(uint64* v) WARN_UNUSED_RESULT; - bool Read4sInto8s(int64* v) WARN_UNUSED_RESULT; - - // Advance the stream by this many bytes. - bool SkipBytes(int nbytes) WARN_UNUSED_RESULT; - - const uint8* data() const { return buf_; } - int size() const { return size_; } - int pos() const { return pos_; } - - protected: - const uint8* buf_; - int size_; - int pos_; - - template bool Read(T* t) WARN_UNUSED_RESULT; -}; - class BoxReader : public BufferReader { public: ~BoxReader();