tenfourfox/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

782 lines
20 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ISOMediaBoxes_h_
#define ISOMediaBoxes_h_
#include <bitset>
#include "nsString.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "MuxerOperation.h"
#include "mozilla/UniquePtr.h"
#define WRITE_FULLBOX(_compositor, _size) \
BoxSizeChecker checker(_compositor, _size); \
FullBox::Write();
#define FOURCC(a, b, c, d) ( ((a) << 24) | ((b) << 16) | ((c) << 8) | (d) )
namespace mozilla {
/**
* track type from spec 8.4.3.3
*/
#define Audio_Track 0x01
#define Video_Track 0x02
class AudioTrackMetadata;
class VideoTrackMetadata;
class ISOControl;
/**
* This is the base class for all ISO media format boxes.
* It provides the fields of box type(four CC) and size.
* The data members in the beginning of a Box (or its descendants)
* are the 14496-12 defined member. Other members prefix with 'm'
* are private control data.
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class Box : public MuxerOperation {
protected:
// ISO BMFF members
uint32_t size; // 14496-12 4-2 'Object Structure'. Size of this box.
nsCString boxType; // four CC name, all table names are listed in
// 14496-12 table 1.
public:
// MuxerOperation methods
nsresult Write() override;
nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) override;
// This helper class will compare the written size in Write() and the size in
// Generate(). If their are not equal, it will assert.
class BoxSizeChecker {
public:
BoxSizeChecker(ISOControl* aControl, uint32_t aSize);
~BoxSizeChecker();
uint32_t ori_size;
uint32_t box_size;
ISOControl* mControl;
};
protected:
Box() = delete;
Box(const nsACString& aType, ISOControl* aControl);
ISOControl* mControl;
RefPtr<AudioTrackMetadata> mAudioMeta;
RefPtr<VideoTrackMetadata> mVideoMeta;
};
/**
* FullBox (and its descendants) is the box which contains the 'real' data
* members. It is the edge in the ISO box structure and it doesn't contain
* any box.
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class FullBox : public Box {
public:
// ISO BMFF members
uint8_t version; // 14496-12 4.2 'Object Structure'
std::bitset<24> flags; //
// MuxerOperation methods
nsresult Write() override;
protected:
// FullBox methods
FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags,
ISOControl* aControl);
FullBox() = delete;
};
/**
* The default implementation of the container box.
* Basically, the container box inherits this class and overrides the
* constructor only.
*
* According to 14496-12 3.1.1 'container box', a container box is
* 'box whose sole purpose is to contain and group a set of related boxes'
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class DefaultContainerImpl : public Box {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) override;
protected:
// DefaultContainerImpl methods
DefaultContainerImpl(const nsACString& aType, ISOControl* aControl);
DefaultContainerImpl() = delete;
nsTArray<RefPtr<MuxerOperation>> boxes;
};
// 14496-12 4.3 'File Type Box'
// Box type: 'ftyp'
class FileTypeBox : public Box {
public:
// ISO BMFF members
nsCString major_brand; // four chars
uint32_t minor_version;
nsTArray<nsCString> compatible_brands;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// FileTypeBox methods
FileTypeBox(ISOControl* aControl);
~FileTypeBox();
};
// 14496-12 8.2.1 'Movie Box'
// Box type: 'moov'
// MovieBox contains MovieHeaderBox, TrackBox and MovieExtendsBox.
class MovieBox : public DefaultContainerImpl {
public:
MovieBox(ISOControl* aControl);
~MovieBox();
};
// 14496-12 8.2.2 'Movie Header Box'
// Box type: 'mvhd'
class MovieHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t creation_time;
uint32_t modification_time;
uint32_t timescale;
uint32_t duration;
uint32_t rate;
uint16_t volume;
uint16_t reserved16;
uint32_t reserved32[2];
uint32_t matrix[9];
uint32_t pre_defined[6];
uint32_t next_track_ID;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MovieHeaderBox methods
MovieHeaderBox(ISOControl* aControl);
~MovieHeaderBox();
uint32_t GetTimeScale();
};
// 14496-12 8.4.2 'Media Header Box'
// Box type: 'mdhd'
class MediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t creation_time;
uint32_t modification_time;
uint32_t timescale;
uint32_t duration;
std::bitset<1> pad;
std::bitset<5> lang1;
std::bitset<5> lang2;
std::bitset<5> lang3;
uint16_t pre_defined;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MediaHeaderBox methods
MediaHeaderBox(uint32_t aType, ISOControl* aControl);
~MediaHeaderBox();
uint32_t GetTimeScale();
protected:
uint32_t mTrackType;
};
// 14496-12 8.3.1 'Track Box'
// Box type: 'trak'
// TrackBox contains TrackHeaderBox and MediaBox.
class TrackBox : public DefaultContainerImpl {
public:
TrackBox(uint32_t aTrackType, ISOControl* aControl);
~TrackBox();
};
// 14496-12 8.1.1 'Media Data Box'
// Box type: 'mdat'
class MediaDataBox : public Box {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MediaDataBox methods
uint32_t GetAllSampleSize() { return mAllSampleSize; }
uint32_t FirstSampleOffsetInMediaDataBox() { return mFirstSampleOffset; }
MediaDataBox(uint32_t aTrackType, ISOControl* aControl);
~MediaDataBox();
protected:
uint32_t mAllSampleSize; // All audio and video sample size in this box.
uint32_t mFirstSampleOffset; // The offset of first sample in this box from
// the beginning of this mp4 file.
uint32_t mTrackType;
};
// flags for TrackRunBox::flags, 14496-12 8.8.8.1.
#define flags_data_offset_present 0x000001
#define flags_first_sample_flags_present 0x000002
#define flags_sample_duration_present 0x000100
#define flags_sample_size_present 0x000200
#define flags_sample_flags_present 0x000400
#define flags_sample_composition_time_offsets_present 0x000800
// flag for TrackRunBox::tbl::sample_flags and TrackExtendsBox::default_sample_flags
// which is defined in 14496-12 8.8.3.1.
uint32_t set_sample_flags(bool aSync);
// 14496-12 8.8.8 'Track Fragment Run Box'
// Box type: 'trun'
class TrackRunBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t sample_duration;
uint32_t sample_size;
uint32_t sample_flags;
uint32_t sample_composition_time_offset;
} tbl;
uint32_t sample_count;
// the following are optional fields
uint32_t data_offset; // data offset exists when audio/video are present in file.
uint32_t first_sample_flags;
UniquePtr<tbl[]> sample_info_table;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackRunBox methods
uint32_t GetAllSampleSize() { return mAllSampleSize; }
nsresult SetDataOffset(uint32_t aOffset);
TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
~TrackRunBox();
protected:
uint32_t fillSampleTable();
uint32_t mAllSampleSize;
uint32_t mTrackType;
};
// tf_flags in TrackFragmentHeaderBox, 14496-12 8.8.7.1.
#define base_data_offset_present 0x000001
#define sample_description_index_present 0x000002
#define default_sample_duration_present 0x000008
#define default_sample_size_present 0x000010
#define default_sample_flags_present 0x000020
#define duration_is_empty 0x010000
#define default_base_is_moof 0x020000
// 14496-12 8.8.7 'Track Fragment Header Box'
// Box type: 'tfhd'
class TrackFragmentHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t track_ID;
uint64_t base_data_offset;
uint32_t default_sample_duration;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackFragmentHeaderBox methods
nsresult UpdateBaseDataOffset(uint64_t aOffset); // The offset of the first
// sample in file.
TrackFragmentHeaderBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
~TrackFragmentHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.6 'Track Fragment Box'
// Box type: 'traf'
// TrackFragmentBox cotains TrackFragmentHeaderBox and TrackRunBox.
class TrackFragmentBox : public DefaultContainerImpl {
public:
TrackFragmentBox(uint32_t aType, ISOControl* aControl);
~TrackFragmentBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.5 'Movie Fragment Header Box'
// Box type: 'mfhd'
class MovieFragmentHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t sequence_number;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MovieFragmentHeaderBox methods
MovieFragmentHeaderBox(uint32_t aType, ISOControl* aControl);
~MovieFragmentHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.4 'Movie Fragment Box'
// Box type: 'moof'
// MovieFragmentBox contains MovieFragmentHeaderBox and TrackFragmentBox.
class MovieFragmentBox : public DefaultContainerImpl {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
// MovieFragmentBox methods
MovieFragmentBox(uint32_t aType, ISOControl* aControl);
~MovieFragmentBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.3 'Track Extends Box'
// Box type: 'trex'
class TrackExtendsBox : public FullBox {
public:
// ISO BMFF members
uint32_t track_ID;
uint32_t default_sample_description_index;
uint32_t default_sample_duration;
uint32_t default_sample_size;
uint32_t default_sample_flags;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackExtendsBox methods
TrackExtendsBox(uint32_t aType, ISOControl* aControl);
~TrackExtendsBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.1 'Movie Extends Box'
// Box type: 'mvex'
// MovieExtendsBox contains TrackExtendsBox.
class MovieExtendsBox : public DefaultContainerImpl {
public:
MovieExtendsBox(ISOControl* aControl);
~MovieExtendsBox();
};
// 14496-12 8.7.5 'Chunk Offset Box'
// Box type: 'stco'
class ChunkOffsetBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t chunk_offset;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// ChunkOffsetBox methods
ChunkOffsetBox(uint32_t aType, ISOControl* aControl);
~ChunkOffsetBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.7.4 'Sample To Chunk Box'
// Box type: 'stsc'
class SampleToChunkBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t first_chunk;
uint32_t sample_per_chunk;
uint32_t sample_description_index;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleToChunkBox methods
SampleToChunkBox(uint32_t aType, ISOControl* aControl);
~SampleToChunkBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.6.1.2 'Decoding Time to Sample Box'
// Box type: 'stts'
class TimeToSampleBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t sample_count;
uint32_t sample_delta;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TimeToSampleBox methods
TimeToSampleBox(uint32_t aType, ISOControl* aControl);
~TimeToSampleBox();
protected:
uint32_t mTrackType;
};
/**
* 14496-12 8.5.2 'Sample Description Box'
* This is the base class for VisualSampleEntry and AudioSampleEntry.
*
* This class is for inherited only, it shouldn't be instanced directly.
*
* The inhertied tree of a codec box should be:
*
* +--> AVCSampleEntry
* +--> VisualSampleEntryBox +
* | +--> ...
* SampleEntryBox +
* | +--> MP4AudioSampleEntry
* +--> AudioSampleEntryBox +
* +--> AMRSampleEntry
* +
* +--> ...
*
*/
class SampleEntryBox : public Box {
public:
// ISO BMFF members
uint8_t reserved[6];
uint16_t data_reference_index;
// sampleentrybox methods
SampleEntryBox(const nsACString& aFormat, ISOControl* aControl);
// MuxerOperation methods
nsresult Write() override;
protected:
SampleEntryBox() = delete;
};
// 14496-12 8.5.2 'Sample Description Box'
// Box type: 'stsd'
class SampleDescriptionBox : public FullBox {
public:
// ISO BMFF members
uint32_t entry_count;
RefPtr<SampleEntryBox> sample_entry_box;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleDescriptionBox methods
SampleDescriptionBox(uint32_t aType, ISOControl* aControl);
~SampleDescriptionBox();
protected:
nsresult CreateAudioSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry);
nsresult CreateVideoSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry);
uint32_t mTrackType;
};
// 14496-12 8.5.2.2
// The base class for audio codec box.
// This class is for inherited only, it shouldn't be instanced directly.
class AudioSampleEntry : public SampleEntryBox {
public:
// ISO BMFF members
uint16_t sound_version;
uint8_t reserved2[6];
uint16_t channels;
uint16_t sample_size;
uint16_t compressionId;
uint16_t packet_size;
uint32_t timeScale; // (sample rate of media) <<16
// MuxerOperation methods
nsresult Write() override;
~AudioSampleEntry();
protected:
AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl);
};
// 14496-12 8.5.2.2
// The base class for video codec box.
// This class is for inherited only, it shouldn't be instanced directly.
class VisualSampleEntry : public SampleEntryBox {
public:
// ISO BMFF members
uint8_t reserved[16];
uint16_t width;
uint16_t height;
uint32_t horizresolution; // 72 dpi
uint32_t vertresolution; // 72 dpi
uint32_t reserved2;
uint16_t frame_count; // 1, defined in 14496-12 8.5.2.2
uint8_t compressorName[32];
uint16_t depth; // 0x0018, defined in 14496-12 8.5.2.2;
uint16_t pre_defined; // -1, defined in 14496-12 8.5.2.2;
// MuxerOperation methods
nsresult Write() override;
// VisualSampleEntry methods
~VisualSampleEntry();
protected:
VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl);
};
// 14496-12 8.7.3.2 'Sample Size Box'
// Box type: 'stsz'
class SampleSizeBox : public FullBox {
public:
// ISO BMFF members
uint32_t sample_size;
uint32_t sample_count;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleSizeBox methods
SampleSizeBox(ISOControl* aControl);
~SampleSizeBox();
};
// 14496-12 8.5.1 'Sample Table Box'
// Box type: 'stbl'
//
// SampleTableBox contains SampleDescriptionBox,
// TimeToSampleBox,
// SampleToChunkBox,
// SampleSizeBox and
// ChunkOffsetBox.
class SampleTableBox : public DefaultContainerImpl {
public:
SampleTableBox(uint32_t aType, ISOControl* aControl);
~SampleTableBox();
};
// 14496-12 8.7.2 'Data Reference Box'
// Box type: 'url '
class DataEntryUrlBox : public FullBox {
public:
// ISO BMFF members
// flags in DataEntryUrlBox::flags
const static uint16_t flags_media_at_the_same_file = 0x0001;
nsCString location;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// DataEntryUrlBox methods
DataEntryUrlBox();
DataEntryUrlBox(ISOControl* aControl);
DataEntryUrlBox(const DataEntryUrlBox& aBox);
~DataEntryUrlBox();
};
// 14496-12 8.7.2 'Data Reference Box'
// Box type: 'dref'
class DataReferenceBox : public FullBox {
public:
// ISO BMFF members
uint32_t entry_count;
nsTArray<nsAutoPtr<DataEntryUrlBox>> urls;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// DataReferenceBox methods
DataReferenceBox(ISOControl* aControl);
~DataReferenceBox();
};
// 14496-12 8.7.1 'Data Information Box'
// Box type: 'dinf'
// DataInformationBox contains DataReferenceBox.
class DataInformationBox : public DefaultContainerImpl {
public:
DataInformationBox(ISOControl* aControl);
~DataInformationBox();
};
// 14496-12 8.4.5.2 'Video Media Header Box'
// Box type: 'vmhd'
class VideoMediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint16_t graphicsmode;
uint16_t opcolor[3];
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// VideoMediaHeaderBox methods
VideoMediaHeaderBox(ISOControl* aControl);
~VideoMediaHeaderBox();
};
// 14496-12 8.4.5.3 'Sound Media Header Box'
// Box type: 'smhd'
class SoundMediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint16_t balance;
uint16_t reserved;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SoundMediaHeaderBox methods
SoundMediaHeaderBox(ISOControl* aControl);
~SoundMediaHeaderBox();
};
// 14496-12 8.4.4 'Media Information Box'
// Box type: 'minf'
// MediaInformationBox contains SoundMediaHeaderBox, DataInformationBox and
// SampleTableBox.
class MediaInformationBox : public DefaultContainerImpl {
public:
MediaInformationBox(uint32_t aType, ISOControl* aControl);
~MediaInformationBox();
protected:
uint32_t mTrackType;
};
// flags for TrackHeaderBox::flags.
#define flags_track_enabled 0x000001
#define flags_track_in_movie 0x000002
#define flags_track_in_preview 0x000004
// 14496-12 8.3.2 'Track Header Box'
// Box type: 'tkhd'
class TrackHeaderBox : public FullBox {
public:
// ISO BMFF members
// version = 0
uint32_t creation_time;
uint32_t modification_time;
uint32_t track_ID;
uint32_t reserved;
uint32_t duration;
uint32_t reserved2[2];
uint16_t layer;
uint16_t alternate_group;
uint16_t volume;
uint16_t reserved3;
uint32_t matrix[9];
uint32_t width;
uint32_t height;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackHeaderBox methods
TrackHeaderBox(uint32_t aType, ISOControl* aControl);
~TrackHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.4.3 'Handler Reference Box'
// Box type: 'hdlr'
class HandlerBox : public FullBox {
public:
// ISO BMFF members
uint32_t pre_defined;
uint32_t handler_type;
uint32_t reserved[3];
nsCString name;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// HandlerBox methods
HandlerBox(uint32_t aType, ISOControl* aControl);
~HandlerBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.4.1 'Media Box'
// Box type: 'mdia'
// MediaBox contains MediaHeaderBox, HandlerBox, and MediaInformationBox.
class MediaBox : public DefaultContainerImpl {
public:
MediaBox(uint32_t aType, ISOControl* aControl);
~MediaBox();
protected:
uint32_t mTrackType;
};
}
#endif // ISOMediaBoxes_h_