Some code clean ups in box definitions

- Add Box::WriteHeader and Box::HeaderSize methods. The concrete
  box implementations should not need care about whether it is a
  Box or FullBox normally.
- Rename Box::ReadWrite to Box::ReadWriteInternal to make it clear
  that it is an internal methods. Make it private so it cannot be
  incorrectly called in box implementions.
- Make an internal implementation of ComputeSizeInternal to compute
  box size. |atom_size| is updated in ComputeSize, which wraps
  ComputeSizeInternal.

Change-Id: I3fbcf8c527581b676d9d13f1ac1dd798da7c4d5f
This commit is contained in:
KongQun Yang 2015-12-14 16:07:51 -08:00 committed by Gerrit Code Review
parent 05f5682728
commit c8e3345959
9 changed files with 484 additions and 484 deletions

View File

@ -17,23 +17,47 @@ Box::Box() : atom_size(0) {}
Box::~Box() {}
bool Box::Parse(BoxReader* reader) {
DCHECK(reader != NULL);
DCHECK(reader);
BoxBuffer buffer(reader);
return ReadWrite(&buffer);
return ReadWriteInternal(&buffer);
}
void Box::Write(BufferWriter* writer) {
DCHECK(writer != NULL);
DCHECK(writer);
// Compute and update atom_size.
uint32_t size = ComputeSize();
DCHECK_EQ(size, this->atom_size);
size_t buffer_size_before_write = writer->Size();
BoxBuffer buffer(writer);
CHECK(ReadWrite(&buffer));
CHECK(ReadWriteInternal(&buffer));
DCHECK_EQ(this->atom_size, writer->Size() - buffer_size_before_write);
}
bool Box::ReadWrite(BoxBuffer* buffer) {
void Box::WriteHeader(BufferWriter* writer) {
DCHECK(writer);
// Compute and update atom_size.
uint32_t size = ComputeSize();
DCHECK_EQ(size, this->atom_size);
size_t buffer_size_before_write = writer->Size();
BoxBuffer buffer(writer);
CHECK(ReadWriteHeaderInternal(&buffer));
DCHECK_EQ(HeaderSize(), writer->Size() - buffer_size_before_write);
}
uint32_t Box::ComputeSize() {
this->atom_size = ComputeSizeInternal();
return this->atom_size;
}
uint32_t Box::HeaderSize() const {
const uint32_t kFourCCSize = 4;
// We don't support 64-bit size.
return kFourCCSize + sizeof(uint32_t);
}
bool Box::ReadWriteHeaderInternal(BoxBuffer* buffer) {
if (buffer->Reading()) {
// Skip for read mode, which is handled already in BoxReader.
} else {
@ -47,8 +71,13 @@ bool Box::ReadWrite(BoxBuffer* buffer) {
FullBox::FullBox() : version(0), flags(0) {}
FullBox::~FullBox() {}
bool FullBox::ReadWrite(BoxBuffer* buffer) {
RCHECK(Box::ReadWrite(buffer));
uint32_t FullBox::HeaderSize() const {
// Additional 1-byte version and 3-byte flags.
return Box::HeaderSize() + 1 + 3;
}
bool FullBox::ReadWriteHeaderInternal(BoxBuffer* buffer) {
RCHECK(Box::ReadWriteHeaderInternal(buffer));
uint32_t vflags;
if (buffer->Reading()) {

View File

@ -9,7 +9,6 @@
#include <stdint.h>
#include "packager/base/compiler_specific.h"
#include "packager/media/formats/mp4/fourccs.h"
namespace edash_packager {
@ -32,24 +31,46 @@ struct Box {
/// Parse the mp4 box.
/// @param reader points to a BoxReader object which parses the box.
bool Parse(BoxReader* reader);
/// Write the box to buffer.
/// This function calls ComputeSize internally to compute box size.
/// Write the box to buffer. This function calls ComputeSize internally to
/// compute and update box size.
/// @param writer points to a BufferWriter object which wraps the buffer for
/// writing.
void Write(BufferWriter* writer);
/// Compute the size of this box.
/// The calculated size will be saved in |atom_size| for later consumption.
virtual uint32_t ComputeSize() = 0;
/// Write the box header to buffer. This function calls ComputeSize internally
/// to compute and update box size.
/// @param writer points to a BufferWriter object which wraps the buffer for
/// writing.
void WriteHeader(BufferWriter* writer);
/// Compute the size of this box. It will also update box size.
/// @return The size of result box including child boxes. A value of 0 should
/// be returned if the box should not be written.
uint32_t ComputeSize();
/// @return box header size in bytes.
virtual uint32_t HeaderSize() const;
/// @return box type.
virtual FourCC BoxType() const = 0;
protected:
friend class BoxBuffer;
/// Read/write the mp4 box from/to BoxBuffer.
virtual bool ReadWrite(BoxBuffer* buffer);
/// Read/write mp4 box header. Note that this function expects box size
/// updated already.
/// @return true on success, false otherwise.
virtual bool ReadWriteHeaderInternal(BoxBuffer* buffer);
/// We don't support 64-bit atom sizes. 32-bit should be large enough for our
/// current needs.
private:
friend class BoxBuffer;
// Read/write the mp4 box from/to BoxBuffer. Note that this function expects
// box size updated already.
virtual bool ReadWriteInternal(BoxBuffer* buffer) = 0;
// Compute the size of this box. A value of 0 should be returned if the box
// should not be written. Note that this function won't update box size.
virtual uint32_t ComputeSizeInternal() = 0;
// We don't support 64-bit atom sizes. 32-bit should be large enough for our
// current needs.
uint32_t atom_size;
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
// generated copy constructor and assignment operator.
};
/// Defines FullBox, the other base ISO BMFF box objects as defined in
@ -60,11 +81,16 @@ struct FullBox : Box {
FullBox();
~FullBox() override;
uint32_t HeaderSize() const final;
uint8_t version;
uint32_t flags;
protected:
bool ReadWrite(BoxBuffer* buffer) override;
bool ReadWriteHeaderInternal(BoxBuffer* buffer) final;
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
// generated copy constructor and assignment operator.
};
} // namespace mp4

View File

@ -146,7 +146,7 @@ class BoxBuffer {
return reader_->ReadChild(box);
// The box is mandatory, i.e. the box size should not be 0.
DCHECK_NE(0u, box->atom_size);
CHECK(box->ReadWrite(this));
CHECK(box->ReadWriteInternal(this));
return true;
}
@ -157,7 +157,7 @@ class BoxBuffer {
return reader_->TryReadChild(box);
// The box is optional, i.e. it can be skipped if the box size is 0.
if (box->atom_size != 0)
CHECK(box->ReadWrite(this));
CHECK(box->ReadWriteInternal(this));
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,16 @@ enum TrackType {
class BoxBuffer;
#define DECLARE_BOX_METHODS(T) \
public: \
T(); \
~T() override; \
bool ReadWrite(BoxBuffer* buffer) override; \
FourCC BoxType() const override; \
uint32_t ComputeSize() override;
~T() override; \
FourCC BoxType() const override; \
\
private: \
bool ReadWriteInternal(BoxBuffer* buffer) override; \
uint32_t ComputeSizeInternal() override; \
\
public:
struct FileType : Box {
DECLARE_BOX_METHODS(FileType);
@ -44,7 +49,7 @@ struct FileType : Box {
};
struct SegmentType : FileType {
DECLARE_BOX_METHODS(SegmentType);
FourCC BoxType() const override;
};
struct ProtectionSystemSpecificHeader : FullBox {
@ -168,12 +173,13 @@ struct CodecConfigurationRecord : Box {
DECLARE_BOX_METHODS(CodecConfigurationRecord);
FourCC box_type;
// Contains full codec configuration record, including possible extension boxes.
// Contains full codec configuration record, including possible extension
// boxes.
std::vector<uint8_t> data;
};
struct PixelAspectRatioBox : Box {
DECLARE_BOX_METHODS(PixelAspectRatioBox);
struct PixelAspectRatio : Box {
DECLARE_BOX_METHODS(PixelAspectRatio);
uint32_t h_spacing;
uint32_t v_spacing;
@ -191,7 +197,7 @@ struct VideoSampleEntry : Box {
uint16_t width;
uint16_t height;
PixelAspectRatioBox pixel_aspect;
PixelAspectRatio pixel_aspect;
ProtectionSchemeInfo sinf;
CodecConfigurationRecord codec_config_record;
};
@ -203,8 +209,8 @@ struct ElementaryStreamDescriptor : FullBox {
ESDescriptor es_descriptor;
};
struct DTSSpecificBox : Box {
DECLARE_BOX_METHODS(DTSSpecificBox);
struct DTSSpecific : Box {
DECLARE_BOX_METHODS(DTSSpecific);
std::vector<uint8_t> data;
};
@ -224,7 +230,7 @@ struct AudioSampleEntry : Box {
ProtectionSchemeInfo sinf;
ElementaryStreamDescriptor esds;
DTSSpecificBox ddts;
DTSSpecific ddts;
};
struct SampleDescription : FullBox {
@ -578,14 +584,9 @@ struct SegmentIndex : FullBox {
std::vector<SegmentReference> references;
};
// The actual data is parsed and written separately, so we do not inherit it
// from Box.
struct MediaData {
MediaData();
~MediaData();
void Write(BufferWriter* buffer_writer);
uint32_t ComputeSize();
FourCC BoxType() const;
// The actual data is parsed and written separately.
struct MediaData : Box {
DECLARE_BOX_METHODS(MediaData);
uint32_t data_size;
};

View File

@ -170,8 +170,8 @@ inline bool operator==(const CodecConfigurationRecord& lhs,
return lhs.data == rhs.data;
}
inline bool operator==(const PixelAspectRatioBox& lhs,
const PixelAspectRatioBox& rhs) {
inline bool operator==(const PixelAspectRatio& lhs,
const PixelAspectRatio& rhs) {
return lhs.h_spacing == rhs.h_spacing && lhs.v_spacing == rhs.v_spacing;
}
@ -194,8 +194,8 @@ inline bool operator==(const ElementaryStreamDescriptor& lhs,
return lhs.es_descriptor == rhs.es_descriptor;
}
inline bool operator==(const DTSSpecificBox& lhs,
const DTSSpecificBox& rhs) {
inline bool operator==(const DTSSpecific& lhs,
const DTSSpecific& rhs) {
return lhs.data == rhs.data;
}

View File

@ -267,12 +267,12 @@ class BoxDefinitionsTestGeneral : public testing::Test {
void Modify(HandlerReference* hdlr) { hdlr->type = kAudio; }
void Fill(PixelAspectRatioBox* pasp) {
void Fill(PixelAspectRatio* pasp) {
pasp->h_spacing = 5;
pasp->v_spacing = 8;
}
void Modify(PixelAspectRatioBox* pasp) { pasp->v_spacing *= 8; }
void Modify(PixelAspectRatio* pasp) { pasp->v_spacing *= 8; }
void Fill(CodecConfigurationRecord* codec_config_record) {
const uint8_t kAvccData[] = {
@ -724,7 +724,7 @@ class BoxDefinitionsTestGeneral : public testing::Test {
bool IsOptional(const EditList* box) { return true; }
bool IsOptional(const Edit* box) { return true; }
bool IsOptional(const CodecConfigurationRecord* box) { return true; }
bool IsOptional(const PixelAspectRatioBox* box) { return true; }
bool IsOptional(const PixelAspectRatio* box) { return true; }
bool IsOptional(const ElementaryStreamDescriptor* box) { return true; }
bool IsOptional(const CompositionTimeToSample* box) { return true; }
bool IsOptional(const SyncSample* box) { return true; }
@ -754,7 +754,7 @@ typedef testing::Types<
Edit,
HandlerReference,
CodecConfigurationRecord,
PixelAspectRatioBox,
PixelAspectRatio,
VideoSampleEntry,
ElementaryStreamDescriptor,
AudioSampleEntry,
@ -797,6 +797,15 @@ typedef testing::Types<
TYPED_TEST_CASE_P(BoxDefinitionsTestGeneral);
TYPED_TEST_P(BoxDefinitionsTestGeneral, WriteHeader) {
TypeParam box;
LOG(INFO) << "Processing " << FourCCToString(box.BoxType());
this->Fill(&box);
box.WriteHeader(this->buffer_.get());
// Box header size should be either 8 bytes or 12 bytes.
EXPECT_TRUE(this->buffer_->Size() == 8 || this->buffer_->Size() == 12);
}
TYPED_TEST_P(BoxDefinitionsTestGeneral, WriteReadbackCompare) {
TypeParam box;
LOG(INFO) << "Processing " << FourCCToString(box.BoxType());
@ -840,6 +849,7 @@ TYPED_TEST_P(BoxDefinitionsTestGeneral, Empty) {
}
REGISTER_TYPED_TEST_CASE_P(BoxDefinitionsTestGeneral,
WriteHeader,
WriteReadbackCompare,
WriteModifyWrite,
Empty);

View File

@ -30,22 +30,22 @@ static const uint8_t kSkipBox[] = {
0x00};
struct FreeBox : Box {
bool ReadWrite(BoxBuffer* buffer) override {
FourCC BoxType() const override { return FOURCC_FREE; }
bool ReadWriteInternal(BoxBuffer* buffer) override {
return true;
}
FourCC BoxType() const override { return FOURCC_FREE; }
uint32_t ComputeSize() override {
uint32_t ComputeSizeInternal() override {
NOTIMPLEMENTED();
return 0;
}
};
struct PsshBox : Box {
bool ReadWrite(BoxBuffer* buffer) override {
FourCC BoxType() const override { return FOURCC_PSSH; }
bool ReadWriteInternal(BoxBuffer* buffer) override {
return buffer->ReadWriteUInt32(&val);
}
FourCC BoxType() const override { return FOURCC_PSSH; }
uint32_t ComputeSize() override {
uint32_t ComputeSizeInternal() override {
NOTIMPLEMENTED();
return 0;
}
@ -54,8 +54,9 @@ struct PsshBox : Box {
};
struct SkipBox : FullBox {
bool ReadWrite(BoxBuffer* buffer) override {
RCHECK(FullBox::ReadWrite(buffer) && buffer->ReadWriteUInt8(&a) &&
FourCC BoxType() const override { return FOURCC_SKIP; }
bool ReadWriteInternal(BoxBuffer* buffer) override {
RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt8(&a) &&
buffer->ReadWriteUInt8(&b) && buffer->ReadWriteUInt16(&c) &&
buffer->ReadWriteInt32(&d) &&
buffer->ReadWriteInt64NBytes(&e, sizeof(uint32_t)));
@ -68,8 +69,7 @@ struct SkipBox : FullBox {
}
return buffer->TryReadWriteChild(&empty);
}
FourCC BoxType() const override { return FOURCC_SKIP; }
uint32_t ComputeSize() override {
uint32_t ComputeSizeInternal() override {
NOTIMPLEMENTED();
return 0;
}

View File

@ -408,7 +408,7 @@ Status Segmenter::FinalizeFragment(bool finalize_segment,
Fragmenter* fragmenter = fragmenters_[i];
mdat.data_size =
fragmenter->aux_data()->Size() + fragmenter->data()->Size();
mdat.Write(fragment_buffer_.get());
mdat.WriteHeader(fragment_buffer_.get());
if (fragmenter->aux_data()->Size()) {
fragment_buffer_->AppendBuffer(*fragmenter->aux_data());
}