First draft doxygen documentation for media/mp4.

Change-Id: I13a28245168724a237a4653e298d6b835c24f17b
This commit is contained in:
Kongqun Yang 2014-01-23 14:34:39 -08:00
parent 6046cde3d8
commit cca3767c25
17 changed files with 298 additions and 237 deletions

View File

@ -15,50 +15,56 @@ class BitReader;
namespace mp4 { namespace mp4 {
// This class parses the AAC information from decoder specific information /// This class parses the AAC information from decoder specific information
// embedded in the esds box in an ISO BMFF file. /// embedded in the @b esds box in an ISO BMFF file.
// Please refer to ISO 14496 Part 3 Table 1.13 - Syntax of AudioSpecificConfig /// Please refer to ISO 14496 Part 3 Table 1.13 - Syntax of AudioSpecificConfig
// for more details. /// for more details.
class AACAudioSpecificConfig { class AACAudioSpecificConfig {
public: public:
AACAudioSpecificConfig(); AACAudioSpecificConfig();
~AACAudioSpecificConfig(); ~AACAudioSpecificConfig();
// Parse the AAC config from the raw binary data embedded in esds box. /// Parse the AAC config from decoder specific information embedded in an @b
// The function will parse the data and get the ElementaryStreamDescriptor, /// esds box. The function will parse the data and get the
// then it will parse the ElementaryStreamDescriptor to get audio stream /// ElementaryStreamDescriptor, then it will parse the
// configurations. /// ElementaryStreamDescriptor to get audio stream configurations.
/// @param data contains decoder specific information from an @b esds box.
/// @return true if successful, false otherwise.
bool Parse(const std::vector<uint8>& data); bool Parse(const std::vector<uint8>& data);
// Get the output sample rate for the AAC stream. /// @param sbr_in_mimetype indicates whether SBR mode is specified in the
// |sbr_in_mimetype| should be set to true if the SBR mode is /// mimetype, i.e. codecs parameter contains mp4a.40.5.
// signalled in the mimetype. (ie mp4a.40.5 in the codecs parameter). /// @return Output sample rate for the AAC stream.
uint32 GetOutputSamplesPerSecond(bool sbr_in_mimetype) const; uint32 GetOutputSamplesPerSecond(bool sbr_in_mimetype) const;
// Get number of channels for the AAC stream. /// @param sbr_in_mimetype indicates whether SBR mode is specified in the
// |sbr_in_mimetype| should be set to true if the SBR mode is /// mimetype, i.e. codecs parameter contains mp4a.40.5.
// signalled in the mimetype. (ie mp4a.40.5 in the codecs parameter). /// @return Number of channels for the AAC stream.
uint8 GetNumChannels(bool sbr_in_mimetype) const; uint8 GetNumChannels(bool sbr_in_mimetype) const;
// This function converts a raw AAC frame into an AAC frame with an ADTS /// Convert a raw AAC frame into an AAC frame with an ADTS header.
// header. On success, the function returns true and stores the converted data /// @param[in,out] buffer contains the raw AAC frame on input, and the
// in the buffer. The function returns false on failure and leaves the buffer /// converted frame on output if successful; it is untouched
// unchanged. /// on failure.
/// @return true on success, false otherwise.
bool ConvertToADTS(std::vector<uint8>* buffer) const; bool ConvertToADTS(std::vector<uint8>* buffer) const;
/// @return The audio object type for this AAC config.
uint8 audio_object_type() const { uint8 audio_object_type() const {
return audio_object_type_; return audio_object_type_;
} }
/// @return The sampling frequency for this AAC config.
uint32 frequency() const { uint32 frequency() const {
return frequency_; return frequency_;
} }
/// @return Number of channels for this AAC config.
uint8 num_channels() const { uint8 num_channels() const {
return num_channels_; return num_channels_;
} }
// Size in bytes of the ADTS header added by ConvertEsdsToADTS(). /// Size in bytes of the ADTS header added by ConvertEsdsToADTS().
static const size_t kADTSHeaderSize = 7; static const size_t kADTSHeaderSize = 7;
private: private:

View File

@ -20,32 +20,39 @@ namespace mp4 {
class BoxBuffer; class BoxBuffer;
class BoxReader; class BoxReader;
// Defines Box and FullBox, the two base ISO BMFF box objects as defined in /// Defines the base ISO BMFF box objects as defined in ISO 14496-12:2012
// ISO 14496-12:2012 ISO BMFF section 4.2. All ISO BMFF compatible boxes /// ISO BMFF section 4.2. All ISO BMFF compatible boxes inherit from either
// inherits either Box or FullBox. /// Box or FullBox.
struct Box { struct Box {
public: public:
Box(); Box();
virtual ~Box(); virtual ~Box();
/// Parse the mp4 box.
/// @param reader points to a BoxReader object which parses the box.
bool Parse(BoxReader* reader); bool Parse(BoxReader* reader);
// Write the box to buffer. /// Write the box to buffer.
// The function calls ComputeSize internally to compute box size. /// This function calls ComputeSize internally to compute box size.
/// @param writer points to a BufferWriter object which wraps the buffer for
/// writing.
void Write(BufferWriter* writer); void Write(BufferWriter* writer);
// Computer box size. /// Compute the size of this box.
// The calculated size will be saved in |atom_size| for consumption later. /// The calculated size will be saved in |atom_size| for later consumption.
virtual uint32 ComputeSize() = 0; virtual uint32 ComputeSize() = 0;
virtual FourCC BoxType() const = 0; virtual FourCC BoxType() const = 0;
protected: protected:
friend class BoxBuffer; friend class BoxBuffer;
// Read or write the mp4 box through BoxBuffer. /// Read/write the mp4 box from/to BoxBuffer.
virtual bool ReadWrite(BoxBuffer* buffer); virtual bool ReadWrite(BoxBuffer* buffer);
// We don't support 64-bit atom size. 32-bit should be large enough for our /// We don't support 64-bit atom sizes. 32-bit should be large enough for our
// current needs. /// current needs.
uint32 atom_size; uint32 atom_size;
}; };
/// Defines FullBox, the other base ISO BMFF box objects as defined in
/// ISO 14496-12:2012 ISO BMFF section 4.2. All ISO BMFF compatible boxes
/// inherit from either Box or FullBox.
struct FullBox : Box { struct FullBox : Box {
public: public:
FullBox(); FullBox();

View File

@ -15,45 +15,47 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
// Defines a wrapper for mp4 box reading/writing, which is symmetric in most /// Class for MP4 box I/O. Box I/O is symmetric and exclusive, so we can define
// cases, i.e. we can use one single routine for the reading and writing. /// a single method to do either reading or writing box objects.
// BoxBuffer wraps either BoxReader for reading or BufferWriter for writing. /// BoxBuffer wraps either BoxReader for reading or BufferWriter for writing.
// Thus it is capable of doing either reading or writing, but not both. /// Thus it is capable of doing either reading or writing, but not both.
class BoxBuffer { class BoxBuffer {
public: public:
// Creates a "reader" version of the BoxBuffer. /// Create a reader version of the BoxBuffer.
// Caller retains |reader| ownership. |reader| should not be NULL. /// @param reader should not be NULL.
explicit BoxBuffer(BoxReader* reader) : reader_(reader), writer_(NULL) { explicit BoxBuffer(BoxReader* reader) : reader_(reader), writer_(NULL) {
DCHECK(reader); DCHECK(reader);
} }
// Creates a "writer" version of the BoxBuffer. /// Create a writer version of the BoxBuffer.
// Caller retains |writer| ownership. |writer| should not be NULL. /// @param writer should not be NULL.
explicit BoxBuffer(BufferWriter* writer) : reader_(NULL), writer_(writer) { explicit BoxBuffer(BufferWriter* writer) : reader_(NULL), writer_(writer) {
DCHECK(writer); DCHECK(writer);
} }
~BoxBuffer() {} ~BoxBuffer() {}
// Reading or writing? /// @return true for reader, false for writer.
bool Reading() const { return reader_ != NULL; } bool Reading() const { return reader_ != NULL; }
// Returns current read/write position. In read mode, this is the current /// @return Current read/write position. In read mode, this is the current
// read position. In write mode, it is the same as Size(). /// read position. In write mode, it is the same as Size().
size_t Pos() const { size_t Pos() const {
if (reader_) if (reader_)
return reader_->pos(); return reader_->pos();
return writer_->Size(); return writer_->Size();
} }
// Returns total buffer size.In read mode, it includes data that has already /// @return Total buffer size. In read mode, it includes data that has already
// been read or skipped, and will not change. In write mode, it includes all /// been read or skipped, and will not change. In write mode, it
// data that has been written, and will change as data is written. /// includes all data that has been written, and will change as more
/// data is written.
size_t Size() const { size_t Size() const {
if (reader_) if (reader_)
return reader_->size(); return reader_->size();
return writer_->Size(); return writer_->Size();
} }
// Read/write integers of various size and unsigned/signed. /// @name Read/write integers of various sizes and signedness.
/// @{
bool ReadWriteUInt8(uint8* v) { bool ReadWriteUInt8(uint8* v) {
if (reader_) if (reader_)
return reader_->Read1(v); return reader_->Read1(v);
@ -96,9 +98,11 @@ class BoxBuffer {
writer_->AppendInt(*v); writer_->AppendInt(*v);
return true; return true;
} }
/// @}
// Read/write the least significant |num_bytes| of |v| from/to buffer. /// Read/write the least significant |num_bytes| of |v| from/to the buffer.
// |num_bytes| should not be larger than sizeof(v), i.e. 8. /// @param num_bytes should not be larger than sizeof(v), i.e. 8.
/// @return true on success, false otherwise.
bool ReadWriteUInt64NBytes(uint64* v, size_t num_bytes) { bool ReadWriteUInt64NBytes(uint64* v, size_t num_bytes) {
if (reader_) if (reader_)
return reader_->ReadNBytesInto8(v, num_bytes); return reader_->ReadNBytesInto8(v, num_bytes);
@ -125,7 +129,8 @@ class BoxBuffer {
return true; return true;
} }
// Prepare child boxes for read/write. /// Prepare child boxes for reading/writing.
/// @return true on success, false otherwise.
bool PrepareChildren() { bool PrepareChildren() {
if (reader_) if (reader_)
return reader_->ScanChildren(); return reader_->ScanChildren();
@ -133,7 +138,8 @@ class BoxBuffer {
return true; return true;
} }
// Read/write child box. /// Read/write child box.
/// @return true on success, false otherwise.
bool ReadWriteChild(Box* box) { bool ReadWriteChild(Box* box) {
if (reader_) if (reader_)
return reader_->ReadChild(box); return reader_->ReadChild(box);
@ -143,7 +149,8 @@ class BoxBuffer {
return true; return true;
} }
// Read/write child box if exist. /// Read/write child box if exists.
/// @return true on success, false otherwise.
bool TryReadWriteChild(Box* box) { bool TryReadWriteChild(Box* box) {
if (reader_) if (reader_)
return reader_->TryReadChild(box); return reader_->TryReadChild(box);
@ -153,7 +160,9 @@ class BoxBuffer {
return true; return true;
} }
// Skip |num_bytes| in read mode, otherwise fill with |num_bytes| of '\0'. /// @param num_bytes specifies number of bytes to skip in read mode or number
/// of bytes to be padded with zero in write mode.
/// @return true on success, false otherwise.
bool IgnoreBytes(size_t num_bytes) { bool IgnoreBytes(size_t num_bytes) {
if (reader_) if (reader_)
return reader_->SkipBytes(num_bytes); return reader_->SkipBytes(num_bytes);
@ -162,7 +171,9 @@ class BoxBuffer {
return true; return true;
} }
/// @return A pointer to the inner reader object.
BoxReader* reader() { return reader_; } BoxReader* reader() { return reader_; }
/// @return A pointer to the inner writer object.
BufferWriter* writer() { return writer_; } BufferWriter* writer() { return writer_; }
private: private:

View File

@ -19,63 +19,74 @@ namespace mp4 {
class Box; class Box;
/// Class for reading MP4 boxes.
class BoxReader : public BufferReader { class BoxReader : public BufferReader {
public: public:
~BoxReader(); ~BoxReader();
// Create a BoxReader from a buffer. Note that this function may return NULL /// Create a BoxReader from a buffer.
// if an intact, complete box was not available in the buffer. If |*err| is /// @param buf is retained but not owned, and must outlive the BoxReader
// set, there was a stream-level error when creating the box; otherwise, NULL /// instance.
// values are only expected when insufficient data is available. /// @param buf_size indicates the size of the input buffer.
// /// @param[out] err is set to true if there was a stream-level error when
// |buf| is retained but not owned, and must outlive the BoxReader instance. /// reading the box.
/// @return New box reader if successful, NULL otherwise.
static BoxReader* ReadTopLevelBox(const uint8* buf, static BoxReader* ReadTopLevelBox(const uint8* buf,
const int buf_size, const int buf_size,
bool* err); bool* err);
// Read the box header from the current buffer. This function returns true if /// Read the box header from the current buffer.
// there is enough data to read the header and the header is sane; that is, it /// @param buf is not retained.
// does not check to ensure the entire box is in the buffer before returning /// @param buf_size indicates the size of the input buffer.
// true. The semantics of |*err| are the same as above. /// @param[out] type is filled with the fourcc of the box on success.
// /// @param[out] box_size is filled with the size of the box on success.
// |buf| is not retained. /// @param[out] err is set to true if there was a stream-level error when
/// reading the box.
/// @return true if there is enough data to read the header and the header is
/// sane, which does not imply that the entire box is in the buffer.
static bool StartTopLevelBox(const uint8* buf, static bool StartTopLevelBox(const uint8* buf,
const int buf_size, const int buf_size,
FourCC* type, FourCC* type,
int* box_size, int* box_size,
bool* err) WARN_UNUSED_RESULT; bool* err) WARN_UNUSED_RESULT;
// Returns true if |type| is recognized to be a top-level box, false /// @return true if @a type is recognized to be the fourcc of a top-level box,
// otherwise. This returns true for some boxes which we do not parse. /// false otherwise. This returns true for some boxes which we do not
// Helpful in debugging misaligned appends. /// parse.
/// This method is helpful for debugging misaligned appends.
static bool IsValidTopLevelBox(const FourCC& type); static bool IsValidTopLevelBox(const FourCC& type);
// Scan through all boxes within the current box, starting at the current /// Scan through all boxes within the current box, starting at the current
// buffer position. Must be called before any of the *Child functions work. /// buffer position. Must be called before any of the @b *Child functions
/// work.
/// @return true on success, false otherwise.
bool ScanChildren() WARN_UNUSED_RESULT; bool ScanChildren() WARN_UNUSED_RESULT;
// Return true if child with type |child.BoxType()| exists. /// @return true if child with type @a child.BoxType() exists.
bool ChildExist(Box* child) WARN_UNUSED_RESULT; bool ChildExist(Box* child) WARN_UNUSED_RESULT;
// Read exactly one child box from the set of children. The type of the child /// Read exactly one child box from the set of children. The type of the
// will be determined by the BoxType() method of |child|. /// child will be determined by the BoxType() of @a child.
/// @return true on success, false otherwise.
bool ReadChild(Box* child) WARN_UNUSED_RESULT; bool ReadChild(Box* child) WARN_UNUSED_RESULT;
// Read one child if available. Returns false on error, true on successful /// Read one child if available.
// read or on child absent. /// @return false on error, true on successful read or on child absent.
bool TryReadChild(Box* child) WARN_UNUSED_RESULT; bool TryReadChild(Box* child) WARN_UNUSED_RESULT;
// Read at least one child. False means error or no such child present. /// Read at least one child.
/// @return false on error or no child of type <T> present.
template <typename T> template <typename T>
bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT; bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
// Read any number of children. False means error. /// Read any number of children.
/// @return false on error.
template <typename T> template <typename T>
bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT; bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
// Read all children, regardless of FourCC. This is used from exactly one box, /// Read all children. It expects all children to be of type T.
// corresponding to a rather significant inconsistency in the BMFF spec. /// Note that this method is mutually exclusive with ScanChildren().
// Note that this method is mutually exclusive with ScanChildren(). /// @return true on success, false otherwise.
template <typename T> template <typename T>
bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT; bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT;

View File

@ -3,10 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Implements a wrapper around Sample to Chunk Box (STSC) to iterate through
// the compressed table by sample/chunk. This class also provides a convenient
// function to query total number of samples from start_chunk to end_chunk.
#ifndef MEDIA_MP4_CHUNK_INFO_ITERATOR_H_ #ifndef MEDIA_MP4_CHUNK_INFO_ITERATOR_H_
#define MEDIA_MP4_CHUNK_INFO_ITERATOR_H_ #define MEDIA_MP4_CHUNK_INFO_ITERATOR_H_
@ -18,38 +14,42 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
/// Sample to chunk box (STSC) iterator used to iterate through the compressed
/// table by sample/chunk. This class also provides a convenient function to
/// query total number of samples from start_chunk to end_chunk.
class ChunkInfoIterator { class ChunkInfoIterator {
public: public:
/// Create ChunkInfoIterator from sample to chunk box.
explicit ChunkInfoIterator(const SampleToChunk& sample_to_chunk); explicit ChunkInfoIterator(const SampleToChunk& sample_to_chunk);
~ChunkInfoIterator(); ~ChunkInfoIterator();
// Advance the properties to refer to the next chunk. Return status /// Advance to the next chunk.
// indicating whether the chunk is still valid. /// @return true if not past the last chunk, false otherwise.
bool AdvanceChunk(); bool AdvanceChunk();
// Advance the properties to refer to the next sample. Return status /// Advance to the next sample.
// indicating whether the sample is still valid. /// @return true if not past the last sample, false otherwise.
bool AdvanceSample(); bool AdvanceSample();
// Return whether the current chunk is valid. /// @return true if not past the last chunk/sample, false otherwise.
bool IsValid() const; bool IsValid() const;
// Return current chunk. /// @return Current chunk.
uint32 current_chunk() const { return current_chunk_; } uint32 current_chunk() const { return current_chunk_; }
// Return samples per chunk for current chunk. /// @return Samples per chunk for current chunk.
uint32 samples_per_chunk() const { return iterator_->samples_per_chunk; } uint32 samples_per_chunk() const { return iterator_->samples_per_chunk; }
// Return sample description index for current chunk. /// @return Sample description index for current chunk.
uint32 sample_description_index() const { uint32 sample_description_index() const {
return iterator_->sample_description_index; return iterator_->sample_description_index;
} }
// Return number of samples from start_chunk to end_chunk, both 1-based, /// @return Number of samples from start_chunk to end_chunk, both 1-based,
// inclusive. /// inclusive.
uint32 NumSamples(uint32 start_chunk, uint32 end_chunk) const; uint32 NumSamples(uint32 start_chunk, uint32 end_chunk) const;
// Return the last first_chunk in chunk_info_table. /// @return The last first_chunk in chunk_info_table.
uint32 LastFirstChunk() const { uint32 LastFirstChunk() const {
return chunk_info_table_.empty() ? 0 return chunk_info_table_.empty() ? 0
: chunk_info_table_.back().first_chunk; : chunk_info_table_.back().first_chunk;

View File

@ -3,11 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Implements a wrapper around Composition Time to Sample Box (CTTS) to iterate
// through the compressed table. This class also provides convenient functions
// to query total number of samples and the composition offset for a particular
// sample.
#ifndef MEDIA_MP4_COMPOSITION_OFFSET_ITERATOR_H_ #ifndef MEDIA_MP4_COMPOSITION_OFFSET_ITERATOR_H_
#define MEDIA_MP4_COMPOSITION_OFFSET_ITERATOR_H_ #define MEDIA_MP4_COMPOSITION_OFFSET_ITERATOR_H_
@ -19,26 +14,31 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
/// Composition time to sample box (CTTS) iterator used to iterate through the
/// compressed table. This class also provides convenient functions to query
/// total number of samples and the composition offset for a particular sample.
class CompositionOffsetIterator { class CompositionOffsetIterator {
public: public:
/// Create CompositionOffsetIterator from composition time to sample box.
explicit CompositionOffsetIterator( explicit CompositionOffsetIterator(
const CompositionTimeToSample& composition_time_to_sample); const CompositionTimeToSample& composition_time_to_sample);
~CompositionOffsetIterator(); ~CompositionOffsetIterator();
// Advance the properties to refer to the next sample. Return status /// Advance the iterator to the next sample.
// indicating whether the sample is still valid. /// @return true if not past the last sample, false otherwise.
bool AdvanceSample(); bool AdvanceSample();
// Return whether the current sample is valid. /// @return true if the iterator is still valid, false if past the last
/// sample.
bool IsValid() const; bool IsValid() const;
// Return sample offset for current sample. /// @return Sample offset for current sample.
uint32 sample_offset() const { return iterator_->sample_offset; } uint32 sample_offset() const { return iterator_->sample_offset; }
// Return sample offset @ sample, 1-based. /// @return Sample offset @a sample, 1-based.
uint32 SampleOffset(uint32 sample) const; uint32 SampleOffset(uint32 sample) const;
// Return total number of samples. /// @return Total number of samples.
uint32 NumSamples() const; uint32 NumSamples() const;
private: private:

View File

@ -3,11 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Implements a wrapper around Decoding Time to Sample Box (STTS) to iterate
// through the compressed table. This class also provides convenient functions
// to query total number of samples and the duration from start_sample to
// end_sample.
#ifndef MEDIA_MP4_DECODING_TIME_ITERATOR_H_ #ifndef MEDIA_MP4_DECODING_TIME_ITERATOR_H_
#define MEDIA_MP4_DECODING_TIME_ITERATOR_H_ #define MEDIA_MP4_DECODING_TIME_ITERATOR_H_
@ -19,26 +14,31 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
/// Decoding time to sample box (STTS) iterator used to iterate through the
/// compressed table. This class also provides convenient functions to query
/// total number of samples and the duration from start_sample to end_sample.
class DecodingTimeIterator { class DecodingTimeIterator {
public: public:
/// Create DecodingTimeIterator from decoding time to sample box.
explicit DecodingTimeIterator( explicit DecodingTimeIterator(
const DecodingTimeToSample& decoding_time_to_sample); const DecodingTimeToSample& decoding_time_to_sample);
~DecodingTimeIterator(); ~DecodingTimeIterator();
// Advance the properties to refer to the next sample. Return status /// Advance to the next sample.
// indicating whether the sample is still valid. /// @return true if not past the last sample, false otherwise.
bool AdvanceSample(); bool AdvanceSample();
// Return whether the current sample is valid. /// @return true if the iterator is still valid, false if past the last
/// sample.
bool IsValid() const; bool IsValid() const;
// Return sample delta for current sample. /// @return Sample delta for current sample.
uint32 sample_delta() const { return iterator_->sample_delta; } uint32 sample_delta() const { return iterator_->sample_delta; }
// Return duration from start_sample to end_sample, both 1-based, inclusive. /// @return Duration from start_sample to end_sample, both 1-based, inclusive.
uint64 Duration(uint32 start_sample, uint32 end_sample) const; uint64 Duration(uint32 start_sample, uint32 end_sample) const;
// Return total number of samples in the table. /// @return Total number of samples in the table.
uint32 NumSamples() const; uint32 NumSamples() const;
private: private:

View File

@ -25,9 +25,9 @@ enum ObjectType {
kEAC3 = 0xa6 // Dolby Digital Plus kEAC3 = 0xa6 // Dolby Digital Plus
}; };
// This class parse object type and decoder specific information from an /// This class parses object type and decoder specific information from an
// elementary stream descriptor, which is usually contained in an esds box. /// elementary stream descriptor, which is usually contained in an esds
// Please refer to ISO 14496 Part 1 7.2.6.5 for more details. /// box. Please refer to ISO 14496 Part 1 7.2.6.5 for more details.
class ESDescriptor { class ESDescriptor {
public: public:
ESDescriptor(); ESDescriptor();
@ -51,7 +51,7 @@ class ESDescriptor {
decoder_specific_info_ = decoder_specific_info; decoder_specific_info_ = decoder_specific_info;
} }
// Check if the stream is AAC. /// @return true if the stream is AAC.
bool IsAAC() const { bool IsAAC() const {
return object_type_ == kISO_14496_3 || object_type_ == kISO_13818_7_AAC_LC; return object_type_ == kISO_14496_3 || object_type_ == kISO_13818_7_AAC_LC;
} }

View File

@ -3,10 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// MP4Fragmenter is responsible for the generation of MP4 fragments, i.e. traf
// and the corresponding mdat. The samples are also encrypted if encryption is
// requested.
#ifndef MEDIA_MP4_MP4_FRAGMENTER_H_ #ifndef MEDIA_MP4_MP4_FRAGMENTER_H_
#define MEDIA_MP4_MP4_FRAGMENTER_H_ #define MEDIA_MP4_MP4_FRAGMENTER_H_
@ -28,13 +24,20 @@ namespace mp4 {
class SegmentReference; class SegmentReference;
class TrackFragment; class TrackFragment;
/// MP4Fragmenter is responsible for the generation of MP4 fragments, i.e. traf
/// box and corresponding mdat box. The samples are also encrypted if encryption
/// is requested.
class MP4Fragmenter { class MP4Fragmenter {
public: public:
// Caller retains the ownership of |traf| and transfers ownership of /// @param traf points to a TrackFragment box.
// |encryptor|. |clear_time| specifies clear time in the current track /// @param encryptor handles encryption of the samples. It can be NULL, which
// timescale. |nalu_length_size| specifies NAL unit length size, for /// indicates no encryption is required.
// subsample encryption. |normalize_presentation_timestamp| defines whether /// @param clear_time specifies clear lead duration in units of the current
// PTS should be normalized to start from zero. /// track's timescale.
/// @param nalu_length_size NAL unit length size, in bytes, for subsample
/// encryption.
/// @param normalize_presentation_timestamp defines whether PTS should be
/// normalized to start from zero.
MP4Fragmenter(TrackFragment* traf, MP4Fragmenter(TrackFragment* traf,
scoped_ptr<AesCtrEncryptor> encryptor, scoped_ptr<AesCtrEncryptor> encryptor,
int64 clear_time, int64 clear_time,
@ -42,15 +45,16 @@ class MP4Fragmenter {
bool normalize_presentation_timestamp); bool normalize_presentation_timestamp);
~MP4Fragmenter(); ~MP4Fragmenter();
/// Add a sample to the fragmenter.
virtual Status AddSample(scoped_refptr<MediaSample> sample); virtual Status AddSample(scoped_refptr<MediaSample> sample);
// Initialize the fragment with default data. /// Initialize the fragment with default data.
void InitializeFragment(); void InitializeFragment();
// Finalize and optimize the fragment. /// Finalize and optimize the fragment.
void FinalizeFragment(); void FinalizeFragment();
// Fill in |reference| with current fragment information. /// Fill @a reference with current fragment information.
void GenerateSegmentReference(SegmentReference* reference); void GenerateSegmentReference(SegmentReference* reference);
uint64 fragment_duration() const { return fragment_duration_; } uint64 fragment_duration() const { return fragment_duration_; }

View File

@ -3,20 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Segmenter for MP4 live, main and simple profiles. The generated media file
// could contain one to many segments with segment duration defined by
// |MuxerOptions.segment_duration|. A segment could contain one to many
// subsegments defined by |num_subsegments_per_sidx|. A subsegment could
// contain one to many fragments with fragment duration defined by
// |MuxerOptions.fragment_duration|. The actual segment or fragment duration
// may not match the defined duration exactly but in a best effort basic, i.e.
// the segmenter tries to end segment/fragment at the first sample with
// overall segment/fragment duration not smaller than defined duration and
// yet meet SAP requirements. The generated segments are written into files
// defined by |MuxerOptions.segment_template| if it is defined; otherwise,
// the segments are appended to the main output file defined by
// |MuxerOptions.output_file_name|.
#ifndef MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_ #ifndef MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_
#define MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_ #define MEDIA_MP4_MP4_GENERAL_SEGMENTER_H_
@ -28,21 +14,35 @@ namespace mp4 {
struct SegmentType; struct SegmentType;
/// Segmenter for MP4 live, main and simple profiles. The generated media file
/// can contain one or many segments with segment duration defined by @b
/// MuxerOptions.segment_duration. A segment can contain one or many
/// subsegments defined by @b num_subsegments_per_sidx. A subsegment can
/// contain one or many fragments with fragment duration defined by @b
/// MuxerOptions.fragment_duration. The actual segment or fragment duration
/// may not match the requested duration exactly, but will be approximated.
/// That is, the segmenter tries to end segment/fragment at the first sample
/// with overall segment/fragment duration not smaller than defined duration
/// and yet meet SAP requirements. The generated segments are written to files
/// defined by @b MuxerOptions.segment_template if specified; otherwise,
/// the segments are appended to the main output file specified by @b
/// MuxerOptions.output_file_name.
class MP4GeneralSegmenter : public MP4Segmenter { class MP4GeneralSegmenter : public MP4Segmenter {
public: public:
// Caller transfers the ownership of |ftyp| and |moov| to this class.
MP4GeneralSegmenter(const MuxerOptions& options, MP4GeneralSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4GeneralSegmenter(); virtual ~MP4GeneralSegmenter();
// MP4Segmenter implementations. /// @name MP4Segmenter implementation overrides.
/// @{
virtual Status Initialize(EncryptorSource* encryptor_source, virtual Status Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
const std::vector<MediaStream*>& streams) OVERRIDE; const std::vector<MediaStream*>& streams) OVERRIDE;
virtual bool GetInitRange(size_t* offset, size_t* size) OVERRIDE; virtual bool GetInitRange(size_t* offset, size_t* size) OVERRIDE;
virtual bool GetIndexRange(size_t* offset, size_t* size) OVERRIDE; virtual bool GetIndexRange(size_t* offset, size_t* size) OVERRIDE;
/// @}
protected: protected:
virtual Status FinalizeSegment() OVERRIDE; virtual Status FinalizeSegment() OVERRIDE;

View File

@ -30,10 +30,13 @@ class MP4MediaParser : public MediaParser {
MP4MediaParser(); MP4MediaParser();
virtual ~MP4MediaParser(); virtual ~MP4MediaParser();
/// @name MediaParser implementation overrides.
/// @{
virtual void Init(const InitCB& init_cb, virtual void Init(const InitCB& init_cb,
const NewSampleCB& new_sample_cb, const NewSampleCB& new_sample_cb,
const NeedKeyCB& need_key_cb) OVERRIDE; const NeedKeyCB& need_key_cb) OVERRIDE;
virtual bool Parse(const uint8* buf, int size) OVERRIDE; virtual bool Parse(const uint8* buf, int size) OVERRIDE;
/// @}
private: private:
enum State { enum State {

View File

@ -3,8 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Implements MP4 Muxer.
#ifndef MEDIA_MP4_MP4_MUXER_H_ #ifndef MEDIA_MP4_MP4_MUXER_H_
#define MEDIA_MP4_MP4_MUXER_H_ #define MEDIA_MP4_MP4_MUXER_H_
@ -28,16 +26,21 @@ struct ProtectionSchemeInfo;
struct ProtectionSystemSpecificHeader; struct ProtectionSystemSpecificHeader;
struct Track; struct Track;
/// Implements MP4 Muxer for ISO-BMFF. Please refer to ISO/IEC 14496-12: ISO
/// base media file format for details.
class MP4Muxer : public Muxer { class MP4Muxer : public Muxer {
public: public:
/// Create a MP4Muxer object from MuxerOptions.
explicit MP4Muxer(const MuxerOptions& options); explicit MP4Muxer(const MuxerOptions& options);
virtual ~MP4Muxer(); virtual ~MP4Muxer();
// Muxer implementations. /// @name Muxer implementation overrides.
/// @{
virtual Status Initialize() OVERRIDE; virtual Status Initialize() OVERRIDE;
virtual Status Finalize() OVERRIDE; virtual Status Finalize() OVERRIDE;
virtual Status AddSample(const MediaStream* stream, virtual Status AddSample(const MediaStream* stream,
scoped_refptr<MediaSample> sample) OVERRIDE; scoped_refptr<MediaSample> sample) OVERRIDE;
/// @}
private: private:
// Generate Audio/Video Track atom. // Generate Audio/Video Track atom.

View File

@ -3,13 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// This class defines the MP4 Segmenter which is responsible for organizing
// MP4 fragments into segments/subsegments and package into a MP4 file.
// Inherited by MP4GeneralSegmenter and MP4VODSegmenter. MP4VODSegmenter defines
// the segmenter for DASH Video-On-Demand with a single segment for each media
// presentation while MP4GeneralSegmenter handles all other cases including
// DASH live profile.
#ifndef MEDIA_MP4_MP4_SEGMENTER_H_ #ifndef MEDIA_MP4_MP4_SEGMENTER_H_
#define MEDIA_MP4_MP4_SEGMENTER_H_ #define MEDIA_MP4_MP4_SEGMENTER_H_
@ -39,18 +32,24 @@ struct Movie;
struct MovieFragment; struct MovieFragment;
struct SegmentIndex; struct SegmentIndex;
/// This class defines the MP4 Segmenter which is responsible for organizing
/// MP4 fragments into segments/subsegments and package them into a MP4 file.
/// Inherited by MP4GeneralSegmenter and MP4VODSegmenter. MP4VODSegmenter
/// defines the segmenter for DASH Video-On-Demand with a single segment for
/// each media presentation while MP4GeneralSegmenter handles all other cases
/// including DASH live profile.
class MP4Segmenter { class MP4Segmenter {
public: public:
// Caller transfers the ownership of |ftyp| and |moov| to this class.
MP4Segmenter(const MuxerOptions& options, MP4Segmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4Segmenter(); virtual ~MP4Segmenter();
// Initialize the segmenter. Caller retains the ownership of /// Initialize the segmenter.
// |encryptor_source|. |encryptor_source| can be NULL. /// Calling other public methods of this class without this method returning
// Calling other public methods of this class without this method returning /// Status::OK, results in an undefined behavior.
// Status::OK, results in an undefined behavior. /// @param encryptor_source can be NULL.
/// @return Status::OK on success.
virtual Status Initialize(EncryptorSource* encryptor_source, virtual Status Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
const std::vector<MediaStream*>& streams); const std::vector<MediaStream*>& streams);
@ -60,19 +59,17 @@ class MP4Segmenter {
virtual Status AddSample(const MediaStream* stream, virtual Status AddSample(const MediaStream* stream,
scoped_refptr<MediaSample> sample); scoped_refptr<MediaSample> sample);
// Returns false if it does not apply. /// @return true if there is an initialization range, while setting @a offset
// If it has an initialization byte range this returns true and set |offset| /// and @a size; or false if initialization range does not apply.
// and |size|, otherwise returns false.
virtual bool GetInitRange(size_t* offset, size_t* size) = 0; virtual bool GetInitRange(size_t* offset, size_t* size) = 0;
// Returns false if it does not apply. /// @return true if there is an index byte range, while setting @a offset
// If it has an index byte range this returns true and set |offset| and /// and @a size; or false if index byte range does not apply.
// |size|, otherwise returns false.
virtual bool GetIndexRange(size_t* offset, size_t* size) = 0; virtual bool GetIndexRange(size_t* offset, size_t* size) = 0;
uint32 GetReferenceTimeScale() const; uint32 GetReferenceTimeScale() const;
// Returns the total length, in seconds, of segmented media files. /// @return The total length, in seconds, of segmented media files.
double GetDuration() const; double GetDuration() const;
protected: protected:

View File

@ -3,18 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Segmenter for MP4 Dash Video-On-Demand profile. A single MP4 file with a
// single segment is created, i.e. with only one SIDX box. The generated media
// file could contain one to many subsegments with subsegment duration
// defined by|MuxerOptions.segment_duration|. A subsegment could contain one
// to many fragments with fragment duration defined by
// |MuxerOptions.fragment_duration|. The actual subsegment or fragment duration
// may not match the defined duration exactly but in a best effort basic, i.e.
// the segmenter tries to end subsegment/fragment at the first sample with
// overall subsegment/fragment duration not smaller than defined duration and
// yet meet SAP requirements. VOD segmenter ignores
// |MuxerOptions.num_subsegments_per_sidx|.
#ifndef MEDIA_MP4_MP4_VOD_SEGMENTER_H_ #ifndef MEDIA_MP4_MP4_VOD_SEGMENTER_H_
#define MEDIA_MP4_MP4_VOD_SEGMENTER_H_ #define MEDIA_MP4_MP4_VOD_SEGMENTER_H_
@ -25,15 +13,26 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
/// Segmenter for MP4 Dash Video-On-Demand profile. A single MP4 file with a
/// single segment is created, i.e. with only one SIDX box. The generated media
/// file can contain one or many subsegments with subsegment duration
/// defined by @b MuxerOptions.segment_duration. A subsegment can contain one
/// or many fragments with fragment duration defined by @b
/// MuxerOptions.fragment_duration. The actual subsegment or fragment duration
/// may not match the requested duration exactly, but will be approximated. That
/// is, the segmenter tries to end subsegment/fragment at the first sample with
/// overall subsegment/fragment duration not smaller than defined duration and
/// yet meet SAP requirements. VOD segmenter ignores @b
/// MuxerOptions.num_subsegments_per_sidx.
class MP4VODSegmenter : public MP4Segmenter { class MP4VODSegmenter : public MP4Segmenter {
public: public:
// Caller transfers the ownership of |ftyp| and |moov| to this class.
MP4VODSegmenter(const MuxerOptions& options, MP4VODSegmenter(const MuxerOptions& options,
scoped_ptr<FileType> ftyp, scoped_ptr<FileType> ftyp,
scoped_ptr<Movie> moov); scoped_ptr<Movie> moov);
virtual ~MP4VODSegmenter(); virtual ~MP4VODSegmenter();
// MP4Segmenter implementations. /// @name MP4Segmenter implementation overrides.
/// @{
virtual Status Initialize(EncryptorSource* encryptor_source, virtual Status Initialize(EncryptorSource* encryptor_source,
double clear_lead_in_seconds, double clear_lead_in_seconds,
const std::vector<MediaStream*>& streams) OVERRIDE; const std::vector<MediaStream*>& streams) OVERRIDE;
@ -41,6 +40,7 @@ class MP4VODSegmenter : public MP4Segmenter {
virtual bool GetInitRange(size_t* offset, size_t* size) OVERRIDE; virtual bool GetInitRange(size_t* offset, size_t* size) OVERRIDE;
virtual bool GetIndexRange(size_t* offset, size_t* size) OVERRIDE; virtual bool GetIndexRange(size_t* offset, size_t* size) OVERRIDE;
/// @}
protected: protected:
virtual Status FinalizeSegment() OVERRIDE; virtual Status FinalizeSegment() OVERRIDE;

View File

@ -10,42 +10,46 @@
namespace media { namespace media {
// A wrapper around a ByteQueue which maintains a notion of a /// Wrapper around ByteQueue, which encapsulates the notion of a
// monotonically-increasing offset. All buffer access is done by passing these /// monotonically-increasing byte offset. All buffer access is done by passing
// offsets into this class, going some way towards preventing the proliferation /// these offsets into this class, reducing the proliferation of many different
// of many different meanings of "offset", "head", etc. /// meanings of "offset", "head", etc.
class OffsetByteQueue { class OffsetByteQueue {
public: public:
OffsetByteQueue(); OffsetByteQueue();
~OffsetByteQueue(); ~OffsetByteQueue();
// These work like their underlying ByteQueue counterparts. /// @name These work like their underlying ByteQueue counterparts.
/// @{
void Reset(); void Reset();
void Push(const uint8* buf, int size); void Push(const uint8* buf, int size);
void Peek(const uint8** buf, int* size); void Peek(const uint8** buf, int* size);
void Pop(int count); void Pop(int count);
/// @}
// Sets |buf| to point at the first buffered byte corresponding to |offset|, /// Set @a buf to point at the first buffered byte corresponding to @a offset,
// and |size| to the number of bytes available starting from that offset. /// and @a size to the number of bytes available starting from that offset.
// ///
// It is an error if the offset is before the current head. It's not an error /// It is an error if the offset is before the current head. It's not an error
// if the current offset is beyond tail(), but you will of course get back /// if the current offset is beyond tail(), but you will of course get back
// a null |buf| and a |size| of zero. /// a null @a buf and a @a size of zero.
void PeekAt(int64 offset, const uint8** buf, int* size); void PeekAt(int64 offset, const uint8** buf, int* size);
// Marks the bytes up to (but not including) |max_offset| as ready for /// Mark the bytes up to (but not including) @a max_offset as ready for
// deletion. This is relatively inexpensive, but will not necessarily reduce /// deletion. This is relatively inexpensive, but will not necessarily reduce
// the resident buffer size right away (or ever). /// the resident buffer size right away (or ever).
// ///
// Returns true if the full range of bytes were successfully trimmed, /// @return true if the full range of bytes were successfully trimmed,
// including the case where |max_offset| is less than the current head. /// including the case where @a max_offset is less than the current
// Returns false if |max_offset| > tail() (although all bytes currently /// head.
// buffered are still cleared). /// @return false if @a max_offset > tail() (although all bytes currently
/// buffered are still cleared).
bool Trim(int64 max_offset); bool Trim(int64 max_offset);
// The head and tail positions, in terms of the file's absolute offsets. /// @return The head position, in terms of the file's absolute offset.
// tail() is an exclusive bound.
int64 head() { return head_; } int64 head() { return head_; }
/// @return The tail position (exclusive), in terms of the file's absolute
/// offset.
int64 tail() { return head_ + size_; } int64 tail() { return head_ + size_; }
private: private:

View File

@ -3,9 +3,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
//
// Implements a wrapper around Sync Sample Box (STSS) to iterate through the
// compressed table.
#ifndef MEDIA_MP4_SYNC_SAMPLE_ITERATOR_H_ #ifndef MEDIA_MP4_SYNC_SAMPLE_ITERATOR_H_
#define MEDIA_MP4_SYNC_SAMPLE_ITERATOR_H_ #define MEDIA_MP4_SYNC_SAMPLE_ITERATOR_H_
@ -17,20 +14,22 @@
namespace media { namespace media {
namespace mp4 { namespace mp4 {
// Sample to Chunk Box (STSS) Iterator. /// Sync sample box (STSS) iterator used to iterate through the entries within
/// the compressed table.
class SyncSampleIterator { class SyncSampleIterator {
public: public:
/// Create a new SyncSampleIterator from sync sample box.
explicit SyncSampleIterator(const SyncSample& sync_sample); explicit SyncSampleIterator(const SyncSample& sync_sample);
~SyncSampleIterator(); ~SyncSampleIterator();
// Advance the properties to refer to the next sample. Return status /// Advance to the next sample.
// indicating whether the sample is still valid. /// @return true if not past the last sample, false otherwise.
bool AdvanceSample(); bool AdvanceSample();
// Return whether the current sample is a sync sample. /// @return true if the current sample is a sync sample, false otherwise.
bool IsSyncSample() const; bool IsSyncSample() const;
// Return whether sample (1-based) is a sync sample. /// @return true if @a sample (1-based) is a sync sample, false otherwise.
bool IsSyncSample(uint32 sample) const; bool IsSyncSample(uint32 sample) const;
private: private:

View File

@ -22,66 +22,82 @@ struct TrackRunInfo;
class TrackRunIterator { class TrackRunIterator {
public: public:
// Create a new TrackRunIterator. A reference to |moov| will be retained for /// Create a new TrackRunIterator from movie box.
// the lifetime of this object. /// @param moov should not be NULL.
explicit TrackRunIterator(const Movie* moov); explicit TrackRunIterator(const Movie* moov);
~TrackRunIterator(); ~TrackRunIterator();
// For non-fragmented mp4, moov contains all the chunks information; This /// For non-fragmented mp4, moov contains all the chunk information; This
// function sets up the iterator to handle all the chunks. /// function sets up the iterator to access all the chunks.
// For fragmented mp4, chunk and sample information are generally contained /// For fragmented mp4, chunk and sample information are generally contained
// in moof. This function is a no-op in this case. Init(moof) will be called /// in moof. This function is a no-op in this case. Init(moof) will be called
// later after parsing moof. /// later after parsing moof.
/// @return true on success, false otherwise.
bool Init(); bool Init();
// Sets up the iterator to handle all the runs from the current fragment. /// Set up the iterator to handle all the runs from the current fragment.
/// @return true on success, false otherwise.
bool Init(const MovieFragment& moof); bool Init(const MovieFragment& moof);
// Returns true if the properties of the current run or sample are valid. /// @return true if the iterator points to a valid run, false if past the
/// last run.
bool IsRunValid() const; bool IsRunValid() const;
/// @return true if the iterator points to a valid sample, false if past the
/// last sample.
bool IsSampleValid() const; bool IsSampleValid() const;
// Advance the properties to refer to the next run or sample. Requires that /// Advance iterator to the next run. Require that the iterator point to a
// the current sample be valid. /// valid run.
void AdvanceRun(); void AdvanceRun();
/// Advance iterator to the next sample. Require that the iterator point to a
/// valid sample.
void AdvanceSample(); void AdvanceSample();
// Returns true if this track run has auxiliary information and has not yet /// @return true if this track run has auxiliary information and has not yet
// been cached. Only valid if IsRunValid(). /// been cached. Only valid if IsRunValid().
bool AuxInfoNeedsToBeCached(); bool AuxInfoNeedsToBeCached();
// Caches the CENC data from the given buffer. |buf| must be a buffer starting /// Caches the CENC data from the given buffer.
// at the offset given by cenc_offset(), with a |size| of at least /// @param buf must be a buffer starting at the offset given by cenc_offset().
// cenc_size(). Returns true on success, false on error. /// @param size must be at least cenc_size().
/// @return true on success, false on error.
bool CacheAuxInfo(const uint8* buf, int size); bool CacheAuxInfo(const uint8* buf, int size);
// Returns the maximum buffer location at which no data earlier in the stream /// @return the maximum buffer location at which no data earlier in the
// will be required in order to read the current or any subsequent sample. You /// stream will be required in order to read the current or any
// may clear all data up to this offset before reading the current sample /// subsequent sample. You may clear all data up to this offset
// safely. Result is in the same units as offset() (for Media Source this is /// before reading the current sample safely. Result is in the same
// in bytes past the the head of the MOOF box). /// units as offset() (for Media Source this is in bytes past the
/// head of the MOOF box).
int64 GetMaxClearOffset(); int64 GetMaxClearOffset();
// Property of the current run. Only valid if IsRunValid(). /// @name Properties of the current run. Only valid if IsRunValid().
/// @{
uint32 track_id() const; uint32 track_id() const;
int64 aux_info_offset() const; int64 aux_info_offset() const;
int aux_info_size() const; int aux_info_size() const;
bool is_encrypted() const; bool is_encrypted() const;
bool is_audio() const; bool is_audio() const;
// Only one is valid, based on the value of is_audio(). /// @}
/// @name Only one is valid, based on the value of is_audio().
/// @{
const AudioSampleEntry& audio_description() const; const AudioSampleEntry& audio_description() const;
const VideoSampleEntry& video_description() const; const VideoSampleEntry& video_description() const;
/// @}
// Properties of the current sample. Only valid if IsSampleValid(). /// @name Properties of the current sample. Only valid if IsSampleValid().
/// @{
int64 sample_offset() const; int64 sample_offset() const;
int sample_size() const; int sample_size() const;
int64 dts() const; int64 dts() const;
int64 cts() const; int64 cts() const;
int64 duration() const; int64 duration() const;
bool is_keyframe() const; bool is_keyframe() const;
/// @}
// Only call when is_encrypted() is true and AuxInfoNeedsToBeCached() is /// Only call when is_encrypted() is true and AuxInfoNeedsToBeCached() is
// false. Result is owned by caller. /// false. Result is owned by caller.
scoped_ptr<DecryptConfig> GetDecryptConfig(); scoped_ptr<DecryptConfig> GetDecryptConfig();
private: private: