diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index cf5c3f2e13..0fc9f1edaf 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -189,6 +189,7 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) case SrsMp4BoxTypeAVCC: box = new SrsMp4AvccBox(); break; case SrsMp4BoxTypeMP4A: box = new SrsMp4AudioSampleEntry(); break; case SrsMp4BoxTypeESDS: box = new SrsMp4EsdsBox(); break; + case SrsMp4BoxTypeUDTA: box = new SrsMp4UserDataBox(); break; default: ret = ERROR_MP4_BOX_ILLEGAL_TYPE; srs_error("MP4 illegal box type=%d. ret=%d", type, ret); @@ -624,6 +625,21 @@ SrsMp4MovieBox::~SrsMp4MovieBox() { } +int SrsMp4MovieBox::nb_header() +{ + return SrsMp4Box::nb_header(); +} + +int SrsMp4MovieBox::encode_header(SrsBuffer* buf) +{ + return SrsMp4Box::encode_header(buf); +} + +int SrsMp4MovieBox::decode_header(SrsBuffer* buf) +{ + return SrsMp4Box::decode_header(buf); +} + SrsMp4MovieHeaderBox::SrsMp4MovieHeaderBox() { type = SrsMp4BoxTypeMVHD; @@ -2621,6 +2637,55 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf) return ret; } +SrsMp4UserDataBox::SrsMp4UserDataBox() +{ + type = SrsMp4BoxTypeUDTA; + nb_data = 0; + data = NULL; +} + +SrsMp4UserDataBox::~SrsMp4UserDataBox() +{ + srs_freepa(data); +} + +int SrsMp4UserDataBox::nb_header() +{ + return SrsMp4Box::nb_header()+nb_data; +} + +int SrsMp4UserDataBox::encode_header(SrsBuffer* buf) +{ + int ret = ERROR_SUCCESS; + + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { + return ret; + } + + if (nb_data) { + buf->write_bytes((char*)data, nb_data); + } + + return ret; +} + +int SrsMp4UserDataBox::decode_header(SrsBuffer* buf) +{ + int ret = ERROR_SUCCESS; + + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { + return ret; + } + + nb_data = left_space(buf); + if (nb_data) { + data = new uint8_t[nb_data]; + buf->read_bytes((char*)data, nb_data); + } + + return ret; +} + #define SRS_MP4_BUF_SIZE 4096 SrsMp4Decoder::SrsMp4Decoder() @@ -2693,6 +2758,14 @@ int SrsMp4Decoder::initialize(ISrsReader* r) return ret; } + // Parse the MOOV. + SrsMp4MovieBox* moov = dynamic_cast(box); + return parse_moov(moov); +} + +int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov) +{ + int ret = ERROR_SUCCESS; return ret; } diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index a108c7ea72..eeb7ea9b91 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -80,6 +80,7 @@ enum SrsMp4BoxType SrsMp4BoxTypeAVCC = 0x61766343, // 'avcC' SrsMp4BoxTypeMP4A = 0x6d703461, // 'mp4a' SrsMp4BoxTypeESDS = 0x65736473, // 'esds' + SrsMp4BoxTypeUDTA = 0x75647461, // 'udta' SrsMp4BoxTypeVIDE = 0x76696465, // 'vide' SrsMp4BoxTypeSOUN = 0x736f756e, // 'soun' @@ -262,6 +263,10 @@ class SrsMp4MovieBox : public SrsMp4Box public: SrsMp4MovieBox(); virtual ~SrsMp4MovieBox(); +protected: + virtual int nb_header(); + virtual int encode_header(SrsBuffer* buf); + virtual int decode_header(SrsBuffer* buf); }; /** @@ -1205,6 +1210,26 @@ class SrsMp4SampleSizeBox : public SrsMp4FullBox virtual int decode_header(SrsBuffer* buf); }; +/** + * 8.10.1 User Data Box (udta) + * ISO_IEC_14496-12-base-format-2012.pdf, page 78 + * This box contains objects that declare user information about the containing box and its data (presentation or + * track). + */ +class SrsMp4UserDataBox : public SrsMp4Box +{ +public: + int nb_data; + uint8_t* data; +public: + SrsMp4UserDataBox(); + virtual ~SrsMp4UserDataBox(); +protected: + virtual int nb_header(); + virtual int encode_header(SrsBuffer* buf); + virtual int decode_header(SrsBuffer* buf); +}; + /** * The MP4 demuxer. */ @@ -1228,6 +1253,8 @@ class SrsMp4Decoder * the decoder just read data from the reader. */ virtual int initialize(ISrsReader* r); +private: + virtual int parse_moov(SrsMp4MovieBox* box); private: // Load the next box from reader. // @param required_box_type The box type required, 0 for any box.