336 lines
14 KiB
C
336 lines
14 KiB
C
|
#ifndef _mov_internal_h_
|
||
|
#define _mov_internal_h_
|
||
|
|
||
|
#include "mov-box.h"
|
||
|
#include "mov-atom.h"
|
||
|
#include "mov-format.h"
|
||
|
#include "mov-buffer.h"
|
||
|
#include "mov-ioutil.h"
|
||
|
|
||
|
#define MOV_APP "ireader/media-server"
|
||
|
|
||
|
#define MOV_TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||
|
|
||
|
#define MOV_MOOV MOV_TAG('m', 'o', 'o', 'v')
|
||
|
#define MOV_ROOT MOV_TAG('r', 'o', 'o', 't')
|
||
|
#define MOV_TRAK MOV_TAG('t', 'r', 'a', 'k')
|
||
|
#define MOV_MDIA MOV_TAG('m', 'd', 'i', 'a')
|
||
|
#define MOV_EDTS MOV_TAG('e', 'd', 't', 's')
|
||
|
#define MOV_MINF MOV_TAG('m', 'i', 'n', 'f')
|
||
|
#define MOV_GMHD MOV_TAG('g', 'm', 'h', 'd') // Apple QuickTime gmhd(text media)
|
||
|
#define MOV_DINF MOV_TAG('d', 'i', 'n', 'f')
|
||
|
#define MOV_STBL MOV_TAG('s', 't', 'b', 'l')
|
||
|
#define MOV_MVEX MOV_TAG('m', 'v', 'e', 'x')
|
||
|
#define MOV_MOOF MOV_TAG('m', 'o', 'o', 'f')
|
||
|
#define MOV_TRAF MOV_TAG('t', 'r', 'a', 'f')
|
||
|
#define MOV_MFRA MOV_TAG('m', 'f', 'r', 'a')
|
||
|
|
||
|
#define MOV_VIDEO MOV_TAG('v', 'i', 'd', 'e') // ISO/IEC 14496-12:2015(E) 12.1 Video media (p169)
|
||
|
#define MOV_AUDIO MOV_TAG('s', 'o', 'u', 'n') // ISO/IEC 14496-12:2015(E) 12.2 Audio media (p173)
|
||
|
#define MOV_META MOV_TAG('m', 'e', 't', 'a') // ISO/IEC 14496-12:2015(E) 12.3 Metadata media (p181)
|
||
|
#define MOV_HINT MOV_TAG('h', 'i', 'n', 't') // ISO/IEC 14496-12:2015(E) 12.4 Hint media (p183)
|
||
|
#define MOV_TEXT MOV_TAG('t', 'e', 'x', 't') // ISO/IEC 14496-12:2015(E) 12.5 Text media (p184)
|
||
|
#define MOV_SUBT MOV_TAG('s', 'u', 'b', 't') // ISO/IEC 14496-12:2015(E) 12.6 Subtitle media (p185)
|
||
|
#define MOV_FONT MOV_TAG('f', 'd', 's', 'm') // ISO/IEC 14496-12:2015(E) 12.7 Font media (p186)
|
||
|
#define MOV_CLCP MOV_TAG('c', 'l', 'c', 'p') // ClosedCaptionHandler
|
||
|
#define MOV_ALIS MOV_TAG('a', 'l', 'i', 's') // Apple QuickTime Macintosh alias
|
||
|
#define MOV_SBTL MOV_TAG('s', 'b', 't', 'l') // text/tx3g
|
||
|
|
||
|
// https://developer.apple.com/library/content/documentation/General/Reference/HLSAuthoringSpec/Requirements.html#//apple_ref/doc/uid/TP40016596-CH2-SW1
|
||
|
// Video encoding requirements 1.10: Use 'avc1', 'hvc1', or 'dvh1' rather than 'avc3', 'hev1', or 'dvhe'
|
||
|
#define MOV_H264 MOV_TAG('a', 'v', 'c', '1') // H.264 ISO/IEC 14496-15:2010(E) 5.3.4 AVC Video Stream Definition (18)
|
||
|
#define MOV_H265 MOV_TAG('h', 'v', 'c', '1') // H.265
|
||
|
#define MOV_H266 MOV_TAG('v', 'v', 'c', '1') // H.266
|
||
|
#define MOV_MP4V MOV_TAG('m', 'p', '4', 'v') // MPEG-4 Video
|
||
|
#define MOV_MP4A MOV_TAG('m', 'p', '4', 'a') // AAC
|
||
|
#define MOV_MP4S MOV_TAG('m', 'p', '4', 's') // ISO/IEC 14496-14:2003(E) 5.6 Sample Description Boxes (p14)
|
||
|
#define MOV_OPUS MOV_TAG('O', 'p', 'u', 's') // http://www.opus-codec.org/docs/opus_in_isobmff.html
|
||
|
#define MOV_VP8 MOV_TAG('v', 'p', '0', '8')
|
||
|
#define MOV_VP9 MOV_TAG('v', 'p', '0', '9') // https://www.webmproject.org/vp9/mp4/
|
||
|
#define MOV_VP10 MOV_TAG('v', 'p', '1', '0')
|
||
|
#define MOV_AV1 MOV_TAG('a', 'v', '0', '1') // https://aomediacodec.github.io/av1-isobmff
|
||
|
#define MOV_VC1 MOV_TAG('v', 'c', '-', '1')
|
||
|
#define MOV_DIRAC MOV_TAG('d', 'r', 'a', 'c')
|
||
|
#define MOV_AC3 MOV_TAG('a', 'c', '-', '3')
|
||
|
#define MOV_DTS MOV_TAG('d', 't', 's', 'c') // DTS-HD
|
||
|
|
||
|
// ISO/IEC 14496-1:2010(E) 7.2.6.6 DecoderConfigDescriptor
|
||
|
// Table 6 - streamType Values (p51)
|
||
|
enum
|
||
|
{
|
||
|
MP4_STREAM_ODS = 0x01, /* ObjectDescriptorStream */
|
||
|
MP4_STREAM_CRS = 0x02, /* ClockReferenceStream */
|
||
|
MP4_STREAM_SDS = 0x03, /* SceneDescriptionStream */
|
||
|
MP4_STREAM_VISUAL = 0x04, /* VisualStream */
|
||
|
MP4_STREAM_AUDIO = 0x05, /* AudioStream */
|
||
|
MP4_STREAM_MP7 = 0x06, /* MPEG7Stream */
|
||
|
MP4_STREAM_IPMP = 0x07, /* IPMPStream */
|
||
|
MP4_STREAM_OCIS = 0x08, /* ObjectContentInfoStream */
|
||
|
MP4_STREAM_MPEGJ = 0x09, /* MPEGJStream */
|
||
|
MP4_STREAM_IS = 0x0A, /* Interaction Stream */
|
||
|
MP4_STREAM_IPMPTOOL = 0x0B, /* IPMPToolStream */
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
MOV_BRAND_ISOM = MOV_TAG('i', 's', 'o', 'm'),
|
||
|
MOV_BRAND_AVC1 = MOV_TAG('a', 'v', 'c', '1'),
|
||
|
MOV_BRAND_ISO2 = MOV_TAG('i', 's', 'o', '2'),
|
||
|
MOV_BRAND_MP71 = MOV_TAG('m', 'p', '7', '1'),
|
||
|
MOV_BRAND_ISO3 = MOV_TAG('i', 's', 'o', '3'),
|
||
|
MOV_BRAND_ISO4 = MOV_TAG('i', 's', 'o', '4'),
|
||
|
MOV_BRAND_ISO5 = MOV_TAG('i', 's', 'o', '5'),
|
||
|
MOV_BRAND_ISO6 = MOV_TAG('i', 's', 'o', '6'),
|
||
|
MOV_BRAND_MP41 = MOV_TAG('m', 'p', '4', '1'), // ISO/IEC 14496-1:2001 MP4 File Format v1
|
||
|
MOV_BRAND_MP42 = MOV_TAG('m', 'p', '4', '2'), // ISO/IEC 14496-14:2003 MP4 File Format v2
|
||
|
MOV_BRAND_MOV = MOV_TAG('q', 't', ' ', ' '), // Apple Quick-Time File Format
|
||
|
MOV_BRAND_DASH = MOV_TAG('d', 'a', 's', 'h'), // MPEG-DASH
|
||
|
MOV_BRAND_MSDH = MOV_TAG('m', 's', 'd', 'h'), // MPEG-DASH
|
||
|
MOV_BRAND_MSIX = MOV_TAG('m', 's', 'i', 'x'), // MPEG-DASH
|
||
|
};
|
||
|
|
||
|
#define MOV_TREX_FLAG_IS_LEADING_MASK 0x0C000000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_DEPENDS_ON_MASK 0x03000000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_IS_DEPENDED_ON_MASK 0x00C00000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_HAS_REDUNDANCY_MASK 0x00300000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_PADDING_VALUE_MASK 0x000E0000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_IS_NO_SYNC_SAMPLE 0x00010000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_DEGRADATION_PRIORITY_MASK 0x0000FFFF
|
||
|
|
||
|
// 8.6.4 Independent and Disposable Samples Box (p55)
|
||
|
#define MOV_TREX_FLAG_SAMPLE_DEPENDS_ON_I_PICTURE 0x02000000
|
||
|
#define MOV_TREX_FLAG_SAMPLE_DEPENDS_ON_NOT_I_PICTURE 0x01000000
|
||
|
|
||
|
#define MOV_TFHD_FLAG_BASE_DATA_OFFSET 0x00000001
|
||
|
#define MOV_TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX 0x00000002
|
||
|
#define MOV_TFHD_FLAG_DEFAULT_DURATION 0x00000008
|
||
|
#define MOV_TFHD_FLAG_DEFAULT_SIZE 0x00000010
|
||
|
#define MOV_TFHD_FLAG_DEFAULT_FLAGS 0x00000020
|
||
|
#define MOV_TFHD_FLAG_DURATION_IS_EMPTY 0x00010000
|
||
|
#define MOV_TFHD_FLAG_DEFAULT_BASE_IS_MOOF 0x00020000
|
||
|
|
||
|
#define MOV_TRUN_FLAG_DATA_OFFSET_PRESENT 0x0001
|
||
|
#define MOV_TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT 0x0004
|
||
|
#define MOV_TRUN_FLAG_SAMPLE_DURATION_PRESENT 0x0100
|
||
|
#define MOV_TRUN_FLAG_SAMPLE_SIZE_PRESENT 0x0200
|
||
|
#define MOV_TRUN_FLAG_SAMPLE_FLAGS_PRESENT 0x0400
|
||
|
#define MOV_TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT 0x0800
|
||
|
|
||
|
#define MOV_TRACK_FLAG_CTTS_V1 0x0001 //ctts version 1
|
||
|
|
||
|
struct mov_stbl_t
|
||
|
{
|
||
|
struct mov_stsc_t* stsc;
|
||
|
size_t stsc_count;
|
||
|
|
||
|
uint64_t* stco;
|
||
|
uint32_t stco_count;
|
||
|
|
||
|
struct mov_stts_t* stts;
|
||
|
size_t stts_count;
|
||
|
|
||
|
struct mov_stts_t* ctts;
|
||
|
size_t ctts_count;
|
||
|
|
||
|
uint32_t* stss; // sample_number, start from 1
|
||
|
size_t stss_count;
|
||
|
};
|
||
|
|
||
|
struct mov_sample_t
|
||
|
{
|
||
|
int flags; // MOV_AV_FLAG_KEYFREAME
|
||
|
int64_t pts; // track mdhd timescale
|
||
|
int64_t dts;
|
||
|
|
||
|
void* data;
|
||
|
uint64_t offset; // is a 32 or 64 bit integer that gives the offset of the start of a chunk into its containing media file.
|
||
|
uint32_t bytes;
|
||
|
|
||
|
uint32_t sample_description_index;
|
||
|
uint32_t samples_per_chunk; // write only
|
||
|
uint32_t first_chunk; // write only
|
||
|
};
|
||
|
|
||
|
struct mov_fragment_t
|
||
|
{
|
||
|
uint64_t time;
|
||
|
uint64_t offset; // moof offset
|
||
|
};
|
||
|
|
||
|
struct mov_track_t
|
||
|
{
|
||
|
uint32_t tag; // MOV_H264/MOV_MP4A
|
||
|
uint32_t handler_type; // MOV_VIDEO/MOV_AUDIO
|
||
|
const char* handler_descr; // VideoHandler/SoundHandler/SubtitleHandler
|
||
|
|
||
|
struct mov_tkhd_t tkhd;
|
||
|
struct mov_mdhd_t mdhd;
|
||
|
struct mov_stbl_t stbl;
|
||
|
|
||
|
// 8.8 Movie Fragments
|
||
|
struct mov_trex_t trex;
|
||
|
struct mov_tfhd_t tfhd;
|
||
|
struct mov_fragment_t* frags;
|
||
|
uint32_t frag_count, frag_capacity /*offset for read*/;
|
||
|
|
||
|
struct mov_stsd_t stsd;
|
||
|
|
||
|
struct mov_elst_t* elst;
|
||
|
size_t elst_count;
|
||
|
|
||
|
uint32_t chpl_track; // MOV_CHAPTER track
|
||
|
|
||
|
struct mov_sample_t* samples;
|
||
|
uint32_t sample_count;
|
||
|
size_t sample_offset; // sample_capacity
|
||
|
|
||
|
int64_t tfdt_dts; // tfdt baseMediaDecodeTime
|
||
|
int64_t start_dts; // write fmp4 only
|
||
|
uint64_t offset; // write only
|
||
|
int64_t last_dts; // write fmp4 only
|
||
|
int64_t turn_last_duration; // write fmp4 only
|
||
|
|
||
|
unsigned int flags;
|
||
|
};
|
||
|
|
||
|
struct mov_t
|
||
|
{
|
||
|
struct mov_ioutil_t io;
|
||
|
|
||
|
struct mov_ftyp_t ftyp;
|
||
|
struct mov_mvhd_t mvhd;
|
||
|
|
||
|
int flags;
|
||
|
int header;
|
||
|
uint32_t mfro; // mfro size
|
||
|
uint64_t moof_offset; // last moof offset(from file begin)
|
||
|
uint64_t implicit_offset;
|
||
|
|
||
|
struct mov_track_t* track; // current stream
|
||
|
struct mov_track_t* tracks;
|
||
|
int track_count;
|
||
|
|
||
|
const void* udta;
|
||
|
uint64_t udta_size;
|
||
|
};
|
||
|
|
||
|
int mov_reader_root(struct mov_t* mov);
|
||
|
int mov_reader_box(struct mov_t* mov, const struct mov_box_t* parent);
|
||
|
int mp4_read_extra(struct mov_t* mov, const struct mov_box_t* parent);
|
||
|
|
||
|
int mov_read_ftyp(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_mvhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_tkhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_hdlr(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_mdhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_vmhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_smhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_nmhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_esds(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_elst(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stsd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stsz(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stz2(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stsc(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stco(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stts(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_ctts(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_cslg(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_stss(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_extra(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_vpcc(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_tx3g(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_trex(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_leva(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_tfhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_trun(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_tfra(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_sidx(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_mfhd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_tfdt(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_mehd(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_dops(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_pasp(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_gmin(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_text(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_smdm(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_coll(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_udta(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
int mov_read_chpl(struct mov_t* mov, const struct mov_box_t* box);
|
||
|
|
||
|
size_t mov_write_ftyp(const struct mov_t* mov);
|
||
|
size_t mov_write_mvhd(const struct mov_t* mov);
|
||
|
size_t mov_write_mdhd(const struct mov_t* mov);
|
||
|
size_t mov_write_tkhd(const struct mov_t* mov);
|
||
|
size_t mov_write_hdlr(const struct mov_t* mov);
|
||
|
size_t mov_write_vmhd(const struct mov_t* mov);
|
||
|
size_t mov_write_smhd(const struct mov_t* mov);
|
||
|
size_t mov_write_nmhd(const struct mov_t* mov);
|
||
|
size_t mov_write_gmhd(const struct mov_t* mov);
|
||
|
size_t mov_write_sthd(const struct mov_t* mov);
|
||
|
size_t mov_write_dinf(const struct mov_t* mov);
|
||
|
size_t mov_write_dref(const struct mov_t* mov);
|
||
|
size_t mov_write_elst(const struct mov_t* mov);
|
||
|
size_t mov_write_stsd(const struct mov_t* mov);
|
||
|
size_t mov_write_stts(const struct mov_t* mov, uint32_t count);
|
||
|
size_t mov_write_ctts(const struct mov_t* mov, uint32_t count);
|
||
|
size_t mov_write_stco(const struct mov_t* mov, uint32_t count);
|
||
|
size_t mov_write_stss(const struct mov_t* mov);
|
||
|
size_t mov_write_stsc(const struct mov_t* mov);
|
||
|
size_t mov_write_stsz(const struct mov_t* mov);
|
||
|
size_t mov_write_esds(const struct mov_t* mov);
|
||
|
size_t mov_write_avcc(const struct mov_t* mov);
|
||
|
size_t mov_write_hvcc(const struct mov_t* mov);
|
||
|
size_t mov_write_vvcc(const struct mov_t* mov);
|
||
|
size_t mov_write_av1c(const struct mov_t* mov);
|
||
|
size_t mov_write_vpcc(const struct mov_t* mov);
|
||
|
size_t mov_write_tx3g(const struct mov_t* mov);
|
||
|
size_t mov_write_trex(const struct mov_t* mov);
|
||
|
size_t mov_write_tfhd(const struct mov_t* mov);
|
||
|
size_t mov_write_trun(const struct mov_t* mov, uint32_t from, uint32_t count, uint32_t offset);
|
||
|
size_t mov_write_tfra(const struct mov_t* mov);
|
||
|
size_t mov_write_styp(const struct mov_t* mov);
|
||
|
size_t mov_write_tfdt(const struct mov_t* mov);
|
||
|
size_t mov_write_mehd(const struct mov_t* mov);
|
||
|
size_t mov_write_sidx(const struct mov_t* mov, uint64_t offset);
|
||
|
size_t mov_write_mfhd(const struct mov_t* mov, uint32_t fragment);
|
||
|
size_t mov_write_edts(const struct mov_t* mov);
|
||
|
size_t mov_write_tref(const struct mov_t* mov);
|
||
|
size_t mov_write_stbl(const struct mov_t* mov);
|
||
|
size_t mov_write_minf(const struct mov_t* mov);
|
||
|
size_t mov_write_mdia(const struct mov_t* mov);
|
||
|
size_t mov_write_trak(const struct mov_t* mov);
|
||
|
size_t mov_write_dops(const struct mov_t* mov);
|
||
|
size_t mov_write_udta(const struct mov_t* mov);
|
||
|
|
||
|
uint32_t mov_build_stts(struct mov_track_t* track);
|
||
|
uint32_t mov_build_ctts(struct mov_track_t* track);
|
||
|
uint32_t mov_build_stco(struct mov_track_t* track);
|
||
|
void mov_apply_stco(struct mov_track_t* track);
|
||
|
void mov_apply_elst(struct mov_track_t *track);
|
||
|
void mov_apply_stts(struct mov_track_t* track);
|
||
|
void mov_apply_ctts(struct mov_track_t* track);
|
||
|
void mov_apply_stss(struct mov_track_t* track);
|
||
|
void mov_apply_elst_tfdt(struct mov_track_t *track);
|
||
|
|
||
|
void mov_write_size(const struct mov_t* mov, uint64_t offset, size_t size);
|
||
|
|
||
|
size_t mov_stco_size(const struct mov_track_t* track, uint64_t offset);
|
||
|
|
||
|
int mov_fragment_read_next_moof(struct mov_t* mov);
|
||
|
int mov_fragment_seek_read_mfra(struct mov_t* mov);
|
||
|
int mov_fragment_seek(struct mov_t* mov, int64_t* timestamp);
|
||
|
|
||
|
uint8_t mov_tag_to_object(uint32_t tag);
|
||
|
uint32_t mov_object_to_tag(uint8_t object);
|
||
|
|
||
|
void mov_free_track(struct mov_track_t* track);
|
||
|
struct mov_track_t* mov_add_track(struct mov_t* mov);
|
||
|
struct mov_track_t* mov_find_track(const struct mov_t* mov, uint32_t track);
|
||
|
struct mov_track_t* mov_fetch_track(struct mov_t* mov, uint32_t track); // find and add
|
||
|
int mov_add_audio(struct mov_track_t* track, const struct mov_mvhd_t* mvhd, uint32_t timescale, uint8_t object, int channel_count, int bits_per_sample, int sample_rate, const void* extra_data, size_t extra_data_size);
|
||
|
int mov_add_video(struct mov_track_t* track, const struct mov_mvhd_t* mvhd, uint32_t timescale, uint8_t object, int width, int height, const void* extra_data, size_t extra_data_size);
|
||
|
int mov_add_subtitle(struct mov_track_t* track, const struct mov_mvhd_t* mvhd, uint32_t timescale, uint8_t object, const void* extra_data, size_t extra_data_size);
|
||
|
|
||
|
#endif /* !_mov_internal_h_ */
|