Move BufferReader to media/base.

Added new functions ReadNBytesInto8(s) and several other minor
changes.

Change-Id: I175fd3be388fcfd04fc205e25ab7dec4c8b004ff
This commit is contained in:
Kongqun Yang 2013-11-21 14:33:07 -08:00
parent dc88702315
commit 3c2abdafb7
5 changed files with 149 additions and 103 deletions

View File

@ -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<uint8>* 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 <typename T>
bool BufferReader::Read(T* v) {
return ReadNBytes(v, sizeof(*v));
}
template <typename T>
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<T>(-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<int8>(buf_[pos_++]) : buf_[pos_++];
for (size_t i = 1; i < num_bytes; ++i) {
tmp <<= 8;
tmp |= buf_[pos_++];
}
*v = tmp;
return true;
}
} // namespace media

View File

@ -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 <vector>
#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<uint8>* 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 <typename T>
bool Read(T* t) WARN_UNUSED_RESULT;
template <typename T>
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_

View File

@ -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<MediaStream*>& streams() { return streams_; }
@ -67,6 +67,7 @@ class Demuxer {
DISALLOW_COPY_AND_ASSIGN(Demuxer);
};
}
} // namespace media
#endif // MEDIA_BASE_DEMUXER_H_

View File

@ -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<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::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<uint32*>(v));
}
bool BufferReader::ReadVec(std::vector<uint8>* 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),

View File

@ -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<uint8>* 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<typename T> bool Read(T* t) WARN_UNUSED_RESULT;
};
class BoxReader : public BufferReader {
public:
~BoxReader();