winlin

for #738, implements boxes codec

@@ -69,6 +69,7 @@ public: @@ -69,6 +69,7 @@ public:
69 /** 69 /**
70 * get the number of bytes to code to. 70 * get the number of bytes to code to.
71 */ 71 */
  72 + // TODO: FIXME: change to uint64_t.
72 virtual int nb_bytes() = 0; 73 virtual int nb_bytes() = 0;
73 /** 74 /**
74 * encode object to bytes in SrsBuffer. 75 * encode object to bytes in SrsBuffer.
@@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242 #define ERROR_REQUEST_DATA 3066 242 #define ERROR_REQUEST_DATA 3066
243 #define ERROR_EDGE_PORT_INVALID 3067 243 #define ERROR_EDGE_PORT_INVALID 3067
244 #define ERROR_EXPECT_FILE_IO 3068 244 #define ERROR_EXPECT_FILE_IO 3068
  245 +#define ERROR_MP4_BOX_OVERFLOW 3069
  246 +#define ERROR_MP4_BOX_REQUIRE_SPACE 3070
  247 +#define ERROR_MP4_BOX_ILLEGAL_TYPE 3071
  248 +#define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072
  249 +#define ERROR_MP4_BOX_STRING 3073
245 250
246 /////////////////////////////////////////////////////// 251 ///////////////////////////////////////////////////////
247 // HTTP/StreamCaster/KAFKA protocol error. 252 // HTTP/StreamCaster/KAFKA protocol error.
@@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9]) @@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9])
721 721
722 srs_assert(header); 722 srs_assert(header);
723 723
  724 + // TODO: FIXME: Should use readfully.
724 if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) { 725 if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) {
725 return ret; 726 return ret;
726 } 727 }
@@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p @@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p
746 char th[11]; // tag header 747 char th[11]; // tag header
747 748
748 // read tag header 749 // read tag header
  750 + // TODO: FIXME: Should use readfully.
749 if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) { 751 if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) {
750 if (ret != ERROR_SYSTEM_FILE_EOF) { 752 if (ret != ERROR_SYSTEM_FILE_EOF) {
751 srs_error("read flv tag header failed. ret=%d", ret); 753 srs_error("read flv tag header failed. ret=%d", ret);
@@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size) @@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size)
783 785
784 srs_assert(data); 786 srs_assert(data);
785 787
  788 + // TODO: FIXME: Should use readfully.
786 if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) { 789 if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) {
787 if (ret != ERROR_SYSTEM_FILE_EOF) { 790 if (ret != ERROR_SYSTEM_FILE_EOF) {
788 srs_error("read flv tag header failed. ret=%d", ret); 791 srs_error("read flv tag header failed. ret=%d", ret);
@@ -801,6 +804,7 @@ int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4]) @@ -801,6 +804,7 @@ int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4])
801 srs_assert(previous_tag_size); 804 srs_assert(previous_tag_size);
802 805
803 // ignore 4bytes tag size. 806 // ignore 4bytes tag size.
  807 + // TODO: FIXME: Should use readfully.
804 if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) { 808 if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) {
805 if (ret != ERROR_SYSTEM_FILE_EOF) { 809 if (ret != ERROR_SYSTEM_FILE_EOF) {
806 srs_error("read flv previous tag size failed. ret=%d", ret); 810 srs_error("read flv previous tag size failed. ret=%d", ret);
@@ -44,6 +44,10 @@ public: @@ -44,6 +44,10 @@ public:
44 ISrsReader(); 44 ISrsReader();
45 virtual ~ISrsReader(); 45 virtual ~ISrsReader();
46 public: 46 public:
  47 + /**
  48 + * Read bytes from reader.
  49 + * @param nread How many bytes read from channel. NULL to ignore.
  50 + */
47 virtual int read(void* buf, size_t size, ssize_t* nread) = 0; 51 virtual int read(void* buf, size_t size, ssize_t* nread) = 0;
48 }; 52 };
49 53
@@ -23,19 +23,380 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,19 +23,380 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_kernel_mp4.hpp> 24 #include <srs_kernel_mp4.hpp>
25 25
26 -#include <string.h>  
27 -  
28 #include <srs_kernel_log.hpp> 26 #include <srs_kernel_log.hpp>
29 #include <srs_kernel_error.hpp> 27 #include <srs_kernel_error.hpp>
  28 +#include <srs_kernel_stream.hpp>
  29 +#include <srs_core_autofree.hpp>
  30 +#include <srs_kernel_io.hpp>
  31 +#include <srs_kernel_buffer.hpp>
  32 +
  33 +#include <string.h>
  34 +using namespace std;
  35 +
  36 +#define SRS_MP4_BOX_UUID 0x75756964 // 'uuid'
  37 +#define SRS_MP4_BOX_FTYP 0x66747970 // 'ftyp'
  38 +#define SRS_MP4_BOX_MDAT 0x6d646174 // 'mdat'
  39 +#define SRS_MP4_BOX_FREE 0x66726565 // 'free'
  40 +#define SRS_MP4_BOX_SKIP 0x736b6970 // 'skip'
  41 +#define SRS_MP4_BOX_MOOV 0x6d6f6f76 // 'moov'
  42 +#define SRS_MP4_BOX_MVHD 0x6d766864 // 'mvhd'
  43 +#define SRS_MP4_BOX_TRAK 0x7472616b // 'trak'
  44 +#define SRS_MP4_BOX_TKHD 0x746b6864 // 'tkhd'
  45 +#define SRS_MP4_BOX_EDTS 0x65647473 // 'edts'
  46 +#define SRS_MP4_BOX_ELST 0x656c7374 // 'elst'
  47 +#define SRS_MP4_BOX_MDIA 0x6d646961 // 'mdia'
  48 +#define SRS_MP4_BOX_MDHD 0x6d646864 // 'mdhd'
  49 +#define SRS_MP4_BOX_HDLR 0x68646c72 // 'hdlr'
  50 +#define SRS_MP4_BOX_MINF 0x6d696e66 // 'minf'
  51 +#define SRS_MP4_BOX_VMHD 0x766d6864 // 'vmhd'
  52 +#define SRS_MP4_BOX_SMHD 0x736d6864 // 'smhd'
  53 +#define SRS_MP4_BOX_DINF 0x64696e66 // 'dinf'
  54 +#define SRS_MP4_BOX_URL 0x75726c20 // 'url '
  55 +#define SRS_MP4_BOX_URN 0x75726e20 // 'urn '
  56 +#define SRS_MP4_BOX_DREF 0x64726566 // 'dref'
  57 +#define SRS_MP4_BOX_STBL 0x7374626c // 'stbl'
  58 +#define SRS_MP4_BOX_STSD 0x73747364 // 'stsd'
  59 +#define SRS_MP4_BOX_STTS 0x73747473 // 'stts'
  60 +#define SRS_MP4_BOX_CTTS 0x63747473 // 'ctts'
  61 +#define SRS_MP4_BOX_STSS 0x73747373 // 'stss'
  62 +#define SRS_MP4_BOX_STSC 0x73747363 // 'stsc'
  63 +#define SRS_MP4_BOX_STCO 0x7374636f // 'stco'
  64 +#define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz'
  65 +
  66 +#define SRS_MP4_EOF_SIZE 0
  67 +#define SRS_MP4_USE_LARGE_SIZE 1
  68 +
  69 +int srs_mp4_string_length(const string& v)
  70 +{
  71 + return (int)v.length()+1;
  72 +}
  73 +
  74 +void srs_mp4_string_write(SrsBuffer* buf, const string& v)
  75 +{
  76 + if (!v.empty()) {
  77 + buf->write_bytes((char*)v.data(), (int)v.length());
  78 + }
  79 + buf->write_1bytes(0x00);
  80 +}
  81 +
  82 +int srs_mp4_string_read(SrsBuffer* buf, string& v, int left)
  83 +{
  84 + int ret = ERROR_SUCCESS;
  85 +
  86 + char* p = buf->data() + buf->pos();
  87 +
  88 + char* start = p;
  89 + while (p < start + left) {
  90 + if (*p == 0x00) {
  91 + v.append(start, p - start);
  92 + buf->skip((int)(p - start));
  93 + return ret;
  94 + }
  95 + }
  96 +
  97 + ret = ERROR_MP4_BOX_STRING;
  98 + srs_error("MP4 string corrupt, left=%d. ret=%d", left, ret);
  99 + return ret;
  100 +}
30 101
31 SrsMp4Box::SrsMp4Box() 102 SrsMp4Box::SrsMp4Box()
32 { 103 {
33 - size = 0; 104 + smallsize = 0;
  105 + largesize = 0;
  106 + usertype = NULL;
  107 + start_pos = 0;
34 type = 0; 108 type = 0;
35 } 109 }
36 110
37 SrsMp4Box::~SrsMp4Box() 111 SrsMp4Box::~SrsMp4Box()
38 { 112 {
  113 + vector<SrsMp4Box*>::iterator it;
  114 + for (it = boxes.begin(); it != boxes.end(); ++it) {
  115 + SrsMp4Box* box = *it;
  116 + srs_freep(box);
  117 + }
  118 + boxes.clear();
  119 +
  120 + srs_freepa(usertype);
  121 +}
  122 +
  123 +uint64_t SrsMp4Box::sz()
  124 +{
  125 + return smallsize == SRS_MP4_USE_LARGE_SIZE? largesize:smallsize;
  126 +}
  127 +
  128 +int SrsMp4Box::left_space(SrsBuffer* buf)
  129 +{
  130 + return (int)sz() - (buf->pos() - start_pos);
  131 +}
  132 +
  133 +int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
  134 +{
  135 + *ppbox = NULL;
  136 +
  137 + int ret = ERROR_SUCCESS;
  138 +
  139 + if (!buf->require(8)) {
  140 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  141 + srs_error("MP4 discovery require 8 bytes space. ret=%d", ret);
  142 + return ret;
  143 + }
  144 +
  145 + // Discovery the size and type.
  146 + uint64_t largesize = 0;
  147 + uint32_t smallsize = (uint32_t)buf->read_4bytes();
  148 + uint32_t type = (uint32_t)buf->read_4bytes();
  149 + if (smallsize == SRS_MP4_USE_LARGE_SIZE) {
  150 + if (!buf->require(8)) {
  151 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  152 + srs_error("MP4 discovery require 16 bytes space. ret=%d", ret);
  153 + return ret;
  154 + }
  155 + largesize = (uint64_t)buf->read_8bytes();
  156 + buf->skip(-8);
  157 + }
  158 + buf->skip(-8);
  159 +
  160 + // Only support 31bits size.
  161 + if (largesize > 0x7fffffff) {
  162 + ret = ERROR_MP4_BOX_OVERFLOW;
  163 + srs_error("MP4 discovery overflow 31bits, size=%"PRId64". ret=%d", largesize, ret);
  164 + return ret;
  165 + }
  166 +
  167 + SrsMp4Box* box = NULL;
  168 + switch(type) {
  169 + case SRS_MP4_BOX_FTYP: box = new SrsMp4FileTypeBox(); break;
  170 + case SRS_MP4_BOX_MDAT: box = new SrsMp4MediaDataBox(); break;
  171 + case SRS_MP4_BOX_FREE: case SRS_MP4_BOX_SKIP: box = new SrsMp4FreeSpaceBox(); break;
  172 + case SRS_MP4_BOX_MOOV: box = new SrsMp4MovieBox(); break;
  173 + case SRS_MP4_BOX_MVHD: box = new SrsMp4MovieHeaderBox(); break;
  174 + case SRS_MP4_BOX_TRAK: box = new SrsMp4TrackBox(); break;
  175 + case SRS_MP4_BOX_TKHD: box = new SrsMp4TrackHeaderBox(); break;
  176 + case SRS_MP4_BOX_EDTS: box = new SrsMp4EditBox(); break;
  177 + case SRS_MP4_BOX_ELST: box = new SrsMp4EditListBox(); break;
  178 + case SRS_MP4_BOX_MDIA: box = new SrsMp4MediaBox(); break;
  179 + case SRS_MP4_BOX_MDHD: box = new SrsMp4MediaHeaderBox(); break;
  180 + case SRS_MP4_BOX_HDLR: box = new SrsMp4HandlerReferenceBox(); break;
  181 + case SRS_MP4_BOX_MINF: box = new SrsMp4MediaInformationBox(); break;
  182 + case SRS_MP4_BOX_VMHD: box = new SrsMp4VideoMeidaHeaderBox(); break;
  183 + case SRS_MP4_BOX_SMHD: box = new SrsMp4SoundMeidaHeaderBox(); break;
  184 + case SRS_MP4_BOX_DINF: box = new SrsMp4DataInformationBox(); break;
  185 + case SRS_MP4_BOX_URL: box = new SrsMp4DataEntryUrlBox(); break;
  186 + case SRS_MP4_BOX_URN: box = new SrsMp4DataEntryUrnBox(); break;
  187 + case SRS_MP4_BOX_DREF: box = new SrsMp4DataReferenceBox(); break;
  188 + case SRS_MP4_BOX_STBL: box = new SrsMp4SampleTableBox(); break;
  189 + case SRS_MP4_BOX_STSD: box = new SrsMp4SampleDescriptionBox(); break;
  190 + case SRS_MP4_BOX_STTS: box = new SrsMp4DecodingTime2SampleBox(); break;
  191 + case SRS_MP4_BOX_CTTS: box = new SrsMp4CompositionTime2SampleBox(); break;
  192 + case SRS_MP4_BOX_STSS: box = new SrsMp4SyncSampleBox(); break;
  193 + case SRS_MP4_BOX_STSC: box = new SrsMp4Sample2ChunkBox(); break;
  194 + case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break;
  195 + case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break;
  196 + default:
  197 + ret = ERROR_MP4_BOX_ILLEGAL_TYPE;
  198 + srs_error("MP4 illegal box type=%d. ret=%d", type, ret);
  199 + break;
  200 + }
  201 +
  202 + if (box) {
  203 + box->smallsize = smallsize;
  204 + box->largesize = largesize;
  205 + box->type = type;
  206 + *ppbox = box;
  207 + }
  208 +
  209 + return ret;
  210 +}
  211 +
  212 +int SrsMp4Box::nb_bytes()
  213 +{
  214 + int sz = nb_header();
  215 +
  216 + vector<SrsMp4Box*>::iterator it;
  217 + for (it = boxes.begin(); it != boxes.end(); ++it) {
  218 + SrsMp4Box* box = *it;
  219 + sz += box->nb_bytes();
  220 + }
  221 +
  222 + return sz;
  223 +}
  224 +
  225 +int SrsMp4Box::encode(SrsBuffer* buf)
  226 +{
  227 + int ret = ERROR_SUCCESS;
  228 +
  229 + if ((ret = encode_header(buf)) != ERROR_SUCCESS) {
  230 + srs_error("MP4 encode box header failed. ret=%d", ret);
  231 + return ret;
  232 + }
  233 +
  234 + if ((ret = encode_boxes(buf)) != ERROR_SUCCESS) {
  235 + srs_error("MP4 encode contained boxes failed. ret=%d", ret);
  236 + return ret;
  237 + }
  238 +
  239 + return ret;
  240 +}
  241 +
  242 +int SrsMp4Box::decode(SrsBuffer* buf)
  243 +{
  244 + int ret = ERROR_SUCCESS;
  245 +
  246 + start_pos = buf->pos();
  247 +
  248 + if ((ret = decode_header(buf)) != ERROR_SUCCESS) {
  249 + srs_error("MP4 decode box header failed. ret=%d", ret);
  250 + return ret;
  251 + }
  252 +
  253 + if ((ret = decode_boxes(buf)) != ERROR_SUCCESS) {
  254 + srs_error("MP4 decode contained boxes failed. ret=%d", ret);
  255 + return ret;
  256 + }
  257 +
  258 + return ret;
  259 +}
  260 +
  261 +int SrsMp4Box::encode_boxes(SrsBuffer* buf)
  262 +{
  263 + int ret = ERROR_SUCCESS;
  264 +
  265 + vector<SrsMp4Box*>::iterator it;
  266 + for (it = boxes.begin(); it != boxes.end(); ++it) {
  267 + SrsMp4Box* box = *it;
  268 + if ((ret = box->encode(buf)) != ERROR_SUCCESS) {
  269 + srs_error("MP4 encode contained box failed. ret=%d", ret);
  270 + return ret;
  271 + }
  272 + }
  273 +
  274 + return ret;
  275 +}
  276 +
  277 +int SrsMp4Box::decode_boxes(SrsBuffer* buf)
  278 +{
  279 + int ret = ERROR_SUCCESS;
  280 +
  281 + int left = left_space(buf);
  282 + while (left > 0) {
  283 + SrsMp4Box* box = NULL;
  284 + if ((ret = discovery(buf, &box)) != ERROR_SUCCESS) {
  285 + srs_error("MP4 discovery contained box failed. ret=%d", ret);
  286 + return ret;
  287 + }
  288 +
  289 + srs_assert(box);
  290 + if ((ret = box->decode(buf)) != ERROR_SUCCESS) {
  291 + srs_freep(box);
  292 + srs_error("MP4 decode contained box failed. ret=%d", ret);
  293 + return ret;
  294 + }
  295 +
  296 + boxes.push_back(box);
  297 + left -= box->sz();
  298 + }
  299 +
  300 + return ret;
  301 +}
  302 +
  303 +int SrsMp4Box::nb_header()
  304 +{
  305 + int size = 8;
  306 + if (smallsize == SRS_MP4_USE_LARGE_SIZE) {
  307 + size += 8;
  308 + }
  309 +
  310 + if (type == SRS_MP4_BOX_UUID) {
  311 + size += 16;
  312 + }
  313 +
  314 + return size;
  315 +}
  316 +
  317 +int SrsMp4Box::encode_header(SrsBuffer* buf)
  318 +{
  319 + int ret = ERROR_SUCCESS;
  320 +
  321 + // Only support 31bits size.
  322 + if (sz() > 0x7fffffff) {
  323 + ret = ERROR_MP4_BOX_OVERFLOW;
  324 + srs_error("MP4 box size overflow 31bits, size=%"PRId64". ret=%d", sz(), ret);
  325 + return ret;
  326 + }
  327 +
  328 + int size = nb_header();
  329 + if (!buf->require(size)) {
  330 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  331 + srs_error("MP4 box require %d bytes space. ret=%d", size, ret);
  332 + return ret;
  333 + }
  334 +
  335 + buf->write_4bytes(smallsize);
  336 + if (smallsize == SRS_MP4_USE_LARGE_SIZE) {
  337 + buf->write_8bytes(largesize);
  338 + }
  339 + buf->write_4bytes(type);
  340 +
  341 + if (type == SRS_MP4_BOX_UUID) {
  342 + buf->write_bytes((char*)usertype, 16);
  343 + }
  344 +
  345 + return ret;
  346 +}
  347 +
  348 +int SrsMp4Box::decode_header(SrsBuffer* buf)
  349 +{
  350 + int ret = ERROR_SUCCESS;
  351 +
  352 + if (!buf->require(8)) {
  353 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  354 + srs_error("MP4 box require 8 bytes space. ret=%d", ret);
  355 + return ret;
  356 + }
  357 + smallsize = (uint32_t)buf->read_4bytes();
  358 + type = (uint32_t)buf->read_4bytes();
  359 +
  360 + if (smallsize == SRS_MP4_EOF_SIZE) {
  361 + srs_warn("MP4 box EOF.");
  362 + return ret;
  363 + }
  364 +
  365 + if (smallsize == SRS_MP4_USE_LARGE_SIZE) {
  366 + if (!buf->require(8)) {
  367 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  368 + srs_error("MP4 box require 8 bytes space. ret=%d", ret);
  369 + return ret;
  370 + }
  371 + largesize = (uint64_t)buf->read_8bytes();
  372 + }
  373 +
  374 + // Only support 31bits size.
  375 + if (sz() > 0x7fffffff) {
  376 + ret = ERROR_MP4_BOX_OVERFLOW;
  377 + srs_error("MP4 box size overflow 31bits, size=%"PRId64". ret=%d", sz(), ret);
  378 + return ret;
  379 + }
  380 +
  381 + if (type == SRS_MP4_BOX_UUID) {
  382 + if (!buf->require(16)) {
  383 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  384 + srs_error("MP4 box requires 16 bytes space. ret=%d", ret);
  385 + return ret;
  386 + }
  387 + usertype = new uint8_t[16];
  388 + buf->read_bytes((char*)usertype, 16);
  389 + }
  390 +
  391 + // The left required size, determined by the default version(0).
  392 + int lrsz = nb_header() - SrsMp4Box::nb_header();
  393 + if (!buf->require(lrsz)) {
  394 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  395 + srs_error("MP4 box requires %d bytes space. ret=%d", lrsz, ret);
  396 + return ret;
  397 + }
  398 +
  399 + return ret;
39 } 400 }
40 401
41 SrsMp4FullBox::SrsMp4FullBox() 402 SrsMp4FullBox::SrsMp4FullBox()
@@ -48,9 +409,58 @@ SrsMp4FullBox::~SrsMp4FullBox() @@ -48,9 +409,58 @@ SrsMp4FullBox::~SrsMp4FullBox()
48 { 409 {
49 } 410 }
50 411
  412 +int SrsMp4FullBox::nb_header()
  413 +{
  414 + return SrsMp4Box::nb_header() + 1 + 3;
  415 +}
  416 +
  417 +int SrsMp4FullBox::encode_header(SrsBuffer* buf)
  418 +{
  419 + int ret = ERROR_SUCCESS;
  420 +
  421 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  422 + return ret;
  423 + }
  424 +
  425 + buf->write_1bytes(version);
  426 + buf->write_3bytes(flags);
  427 +
  428 + return ret;
  429 +}
  430 +
  431 +int SrsMp4FullBox::decode_header(SrsBuffer* buf)
  432 +{
  433 + int ret = ERROR_SUCCESS;
  434 +
  435 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  436 + return ret;
  437 + }
  438 +
  439 + if (!buf->require(4)) {
  440 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  441 + srs_error("MP4 full box requires 4 bytes space. ret=%d", ret);
  442 + return ret;
  443 + }
  444 +
  445 + flags = (uint32_t)buf->read_4bytes();
  446 +
  447 + version = (uint8_t)((flags >> 24) & 0xff);
  448 + flags &= 0x00ffffff;
  449 +
  450 + // The left required size, determined by the version.
  451 + int lrsz = nb_header() - SrsMp4FullBox::nb_header();
  452 + if (!buf->require(lrsz)) {
  453 + ret = ERROR_MP4_BOX_REQUIRE_SPACE;
  454 + srs_error("MP4 full box requires %d bytes space. ret=%d", lrsz, ret);
  455 + return ret;
  456 + }
  457 +
  458 + return ret;
  459 +}
  460 +
51 SrsMp4FileTypeBox::SrsMp4FileTypeBox() 461 SrsMp4FileTypeBox::SrsMp4FileTypeBox()
52 { 462 {
53 - type = 0x66747970; // 'ftyp' 463 + type = SRS_MP4_BOX_FTYP;
54 nb_compatible_brands = 0; 464 nb_compatible_brands = 0;
55 compatible_brands = NULL; 465 compatible_brands = NULL;
56 major_brand = minor_version = 0; 466 major_brand = minor_version = 0;
@@ -61,9 +471,60 @@ SrsMp4FileTypeBox::~SrsMp4FileTypeBox() @@ -61,9 +471,60 @@ SrsMp4FileTypeBox::~SrsMp4FileTypeBox()
61 srs_freepa(compatible_brands); 471 srs_freepa(compatible_brands);
62 } 472 }
63 473
  474 +int SrsMp4FileTypeBox::nb_header()
  475 +{
  476 + return SrsMp4Box::nb_header() + 8 + nb_compatible_brands * 4;
  477 +}
  478 +
  479 +int SrsMp4FileTypeBox::encode_header(SrsBuffer* buf)
  480 +{
  481 + int ret = ERROR_SUCCESS;
  482 +
  483 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  484 + return ret;
  485 + }
  486 +
  487 + buf->write_4bytes(major_brand);
  488 + buf->write_4bytes(minor_version);
  489 +
  490 + for (int i = 0; i < nb_compatible_brands; i++) {
  491 + uint32_t& cb = compatible_brands[i];
  492 + buf->write_4bytes(cb);
  493 + }
  494 +
  495 + return ret;
  496 +}
  497 +
  498 +int SrsMp4FileTypeBox::decode_header(SrsBuffer* buf)
  499 +{
  500 + int ret = ERROR_SUCCESS;
  501 +
  502 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  503 + return ret;
  504 + }
  505 +
  506 + major_brand = buf->read_4bytes();
  507 + minor_version = buf->read_4bytes();
  508 +
  509 + // Compatible brands to the end of the box.
  510 + int left = left_space(buf);
  511 +
  512 + if (left > 0) {
  513 + nb_compatible_brands = left / 4;
  514 + compatible_brands = new uint32_t[nb_compatible_brands];
  515 + }
  516 +
  517 + for (int i = 0; left > 0; i++, left -= 4){
  518 + uint32_t cb = buf->read_4bytes();
  519 + compatible_brands[i] = cb;
  520 + }
  521 +
  522 + return ret;
  523 +}
  524 +
64 SrsMp4MediaDataBox::SrsMp4MediaDataBox() 525 SrsMp4MediaDataBox::SrsMp4MediaDataBox()
65 { 526 {
66 - type = 0x6d646174; // 'mdat' 527 + type = SRS_MP4_BOX_MDAT;
67 data = NULL; 528 data = NULL;
68 nb_data = 0; 529 nb_data = 0;
69 } 530 }
@@ -73,18 +534,95 @@ SrsMp4MediaDataBox::~SrsMp4MediaDataBox() @@ -73,18 +534,95 @@ SrsMp4MediaDataBox::~SrsMp4MediaDataBox()
73 srs_freepa(data); 534 srs_freepa(data);
74 } 535 }
75 536
  537 +int SrsMp4MediaDataBox::nb_header()
  538 +{
  539 + return SrsMp4Box::nb_header() + nb_data;
  540 +}
  541 +
  542 +int SrsMp4MediaDataBox::encode_header(SrsBuffer* buf)
  543 +{
  544 + int ret = ERROR_SUCCESS;
  545 +
  546 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  547 + return ret;
  548 + }
  549 +
  550 + if (nb_data) {
  551 + buf->write_bytes((char*)data, nb_data);
  552 + }
  553 +
  554 + return ret;
  555 +}
  556 +
  557 +int SrsMp4MediaDataBox::decode_header(SrsBuffer* buf)
  558 +{
  559 + int ret = ERROR_SUCCESS;
  560 +
  561 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  562 + return ret;
  563 + }
  564 +
  565 + int left = left_space(buf);
  566 + if (left) {
  567 + data = new uint8_t[left];
  568 + buf->read_bytes((char*)data, left);
  569 + }
  570 +
  571 + return ret;
  572 +}
  573 +
76 SrsMp4FreeSpaceBox::SrsMp4FreeSpaceBox() 574 SrsMp4FreeSpaceBox::SrsMp4FreeSpaceBox()
77 { 575 {
78 - type = 0x66726565; // ‘free’ or ‘skip’ 576 + type = SRS_MP4_BOX_FREE; // 'free' or 'skip'
  577 + data = NULL;
  578 + nb_data = 0;
79 } 579 }
80 580
81 SrsMp4FreeSpaceBox::~SrsMp4FreeSpaceBox() 581 SrsMp4FreeSpaceBox::~SrsMp4FreeSpaceBox()
82 { 582 {
  583 + srs_freepa(data);
  584 +}
  585 +
  586 +int SrsMp4FreeSpaceBox::nb_header()
  587 +{
  588 + return SrsMp4Box::nb_header() + nb_data;
  589 +}
  590 +
  591 +int SrsMp4FreeSpaceBox::encode_header(SrsBuffer* buf)
  592 +{
  593 + int ret = ERROR_SUCCESS;
  594 +
  595 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  596 + return ret;
  597 + }
  598 +
  599 + if (nb_data) {
  600 + buf->write_bytes((char*)data, nb_data);
  601 + }
  602 +
  603 + return ret;
  604 +}
  605 +
  606 +int SrsMp4FreeSpaceBox::decode_header(SrsBuffer* buf)
  607 +{
  608 + int ret = ERROR_SUCCESS;
  609 +
  610 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  611 + return ret;
  612 + }
  613 +
  614 + int left = left_space(buf);
  615 + if (left) {
  616 + data = new uint8_t[left];
  617 + buf->read_bytes((char*)data, left);
  618 + }
  619 +
  620 + return ret;
83 } 621 }
84 622
85 SrsMp4MovieBox::SrsMp4MovieBox() 623 SrsMp4MovieBox::SrsMp4MovieBox()
86 { 624 {
87 - type = 0x6d6f6f76; // 'moov' 625 + type = SRS_MP4_BOX_MOOV;
88 } 626 }
89 627
90 SrsMp4MovieBox::~SrsMp4MovieBox() 628 SrsMp4MovieBox::~SrsMp4MovieBox()
@@ -93,7 +631,7 @@ SrsMp4MovieBox::~SrsMp4MovieBox() @@ -93,7 +631,7 @@ SrsMp4MovieBox::~SrsMp4MovieBox()
93 631
94 SrsMp4MovieHeaderBox::SrsMp4MovieHeaderBox() 632 SrsMp4MovieHeaderBox::SrsMp4MovieHeaderBox()
95 { 633 {
96 - type = 0x6d766864; // 'mvhd' 634 + type = SRS_MP4_BOX_MVHD;
97 635
98 rate = 0x00010000; // typically 1.0 636 rate = 0x00010000; // typically 1.0
99 volume = 0x0100; // typically, full volume 637 volume = 0x0100; // typically, full volume
@@ -110,9 +648,92 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() @@ -110,9 +648,92 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox()
110 { 648 {
111 } 649 }
112 650
  651 +int SrsMp4MovieHeaderBox::nb_header()
  652 +{
  653 + int size = SrsMp4FullBox::nb_header();
  654 +
  655 + if (version == 1) {
  656 + size += 8+8+4+8;
  657 + } else {
  658 + size += 4+4+4+4;
  659 + }
  660 +
  661 + size += 4+2+2+8+36+24+4;
  662 +
  663 + return size;
  664 +}
  665 +
  666 +int SrsMp4MovieHeaderBox::encode_header(SrsBuffer* buf)
  667 +{
  668 + int ret = ERROR_SUCCESS;
  669 +
  670 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  671 + return ret;
  672 + }
  673 +
  674 + if (version == 1) {
  675 + buf->write_8bytes(creation_time);
  676 + buf->write_8bytes(modification_time);
  677 + buf->write_4bytes(timescale);
  678 + buf->write_8bytes(duration);
  679 + } else {
  680 + buf->write_4bytes((uint32_t)creation_time);
  681 + buf->write_4bytes((uint32_t)modification_time);
  682 + buf->write_4bytes(timescale);
  683 + buf->write_4bytes((uint32_t)duration);
  684 + }
  685 +
  686 + buf->write_4bytes(rate);
  687 + buf->write_2bytes(volume);
  688 + buf->write_2bytes(reserved0);
  689 + buf->write_8bytes(reserved1);
  690 + for (int i = 0; i < 9; i++) {
  691 + buf->write_4bytes(matrix[i]);
  692 + }
  693 + for (int i = 0; i < 6; i++) {
  694 + buf->write_4bytes(pre_defined[i]);
  695 + }
  696 + buf->write_4bytes(next_track_ID);
  697 +
  698 + return ret;
  699 +}
  700 +
  701 +int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf)
  702 +{
  703 + int ret = ERROR_SUCCESS;
  704 +
  705 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  706 + return ret;
  707 + }
  708 +
  709 + if (version == 1) {
  710 + creation_time = buf->read_8bytes();
  711 + modification_time = buf->read_8bytes();
  712 + timescale = buf->read_4bytes();
  713 + duration = buf->read_8bytes();
  714 + } else {
  715 + creation_time = buf->read_4bytes();
  716 + modification_time = buf->read_4bytes();
  717 + timescale = buf->read_4bytes();
  718 + duration = buf->read_4bytes();
  719 + }
  720 +
  721 + rate = buf->read_4bytes();
  722 + volume = buf->read_4bytes();
  723 + buf->skip(2);
  724 + buf->skip(8);
  725 + for (int i = 0; i < 9; i++) {
  726 + matrix[i] = buf->read_4bytes();
  727 + }
  728 + buf->skip(24);
  729 + next_track_ID = buf->read_4bytes();
  730 +
  731 + return ret;
  732 +}
  733 +
113 SrsMp4TrackBox::SrsMp4TrackBox() 734 SrsMp4TrackBox::SrsMp4TrackBox()
114 { 735 {
115 - type = 0x7472616b; // 'trak' 736 + type = SRS_MP4_BOX_TRAK;
116 } 737 }
117 738
118 SrsMp4TrackBox::~SrsMp4TrackBox() 739 SrsMp4TrackBox::~SrsMp4TrackBox()
@@ -121,13 +742,13 @@ SrsMp4TrackBox::~SrsMp4TrackBox() @@ -121,13 +742,13 @@ SrsMp4TrackBox::~SrsMp4TrackBox()
121 742
122 SrsMp4TrackHeaderBox::SrsMp4TrackHeaderBox() 743 SrsMp4TrackHeaderBox::SrsMp4TrackHeaderBox()
123 { 744 {
124 - type = 0x746b6864; // 'tkhd' 745 + type = SRS_MP4_BOX_TKHD;
125 746
126 reserved0 = 0; 747 reserved0 = 0;
127 reserved1 = 0; 748 reserved1 = 0;
128 reserved2 = 0; 749 reserved2 = 0;
129 layer = alternate_group = 0; 750 layer = alternate_group = 0;
130 - volume = 0x0100; // if track_is_audio 0x0100 else 0 751 + volume = 0; // if track_is_audio 0x0100 else 0
131 752
132 int32_t v[] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000}; 753 int32_t v[] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};
133 memcpy(matrix, v, 36); 754 memcpy(matrix, v, 36);
@@ -137,9 +758,96 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox() @@ -137,9 +758,96 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox()
137 { 758 {
138 } 759 }
139 760
  761 +int SrsMp4TrackHeaderBox::nb_header()
  762 +{
  763 + int size = SrsMp4FullBox::nb_header();
  764 +
  765 + if (version == 1) {
  766 + size += 8+8+4+4+8;
  767 + } else {
  768 + size += 4+4+4+4+4;
  769 + }
  770 +
  771 + size += 8+2+2+2+2+36+4+4;
  772 +
  773 + return size;
  774 +}
  775 +
  776 +int SrsMp4TrackHeaderBox::encode_header(SrsBuffer* buf)
  777 +{
  778 + int ret = ERROR_SUCCESS;
  779 +
  780 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  781 + return ret;
  782 + }
  783 +
  784 + if (version == 1) {
  785 + buf->write_8bytes(creation_time);
  786 + buf->write_8bytes(modification_time);
  787 + buf->write_4bytes(track_ID);
  788 + buf->write_4bytes(reserved0);
  789 + buf->write_8bytes(duration);
  790 + } else {
  791 + buf->write_4bytes((uint32_t)creation_time);
  792 + buf->write_4bytes((uint32_t)modification_time);
  793 + buf->write_4bytes(track_ID);
  794 + buf->write_4bytes(reserved0);
  795 + buf->write_4bytes((uint32_t)duration);
  796 + }
  797 +
  798 + buf->write_8bytes(reserved1);
  799 + buf->write_2bytes(layer);
  800 + buf->write_2bytes(alternate_group);
  801 + buf->write_2bytes(volume);
  802 + buf->write_2bytes(reserved2);
  803 + for (int i = 0; i < 9; i++) {
  804 + buf->write_4bytes(matrix[i]);
  805 + }
  806 + buf->write_4bytes(width);
  807 + buf->write_4bytes(height);
  808 +
  809 + return ret;
  810 +}
  811 +
  812 +int SrsMp4TrackHeaderBox::decode_header(SrsBuffer* buf)
  813 +{
  814 + int ret = ERROR_SUCCESS;
  815 +
  816 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  817 + return ret;
  818 + }
  819 +
  820 + if (version == 1) {
  821 + creation_time = buf->read_8bytes();
  822 + modification_time = buf->read_8bytes();
  823 + track_ID = buf->read_4bytes();
  824 + buf->skip(4);
  825 + duration = buf->read_8bytes();
  826 + } else {
  827 + creation_time = buf->read_4bytes();
  828 + modification_time = buf->read_4bytes();
  829 + track_ID = buf->read_4bytes();
  830 + buf->skip(4);
  831 + duration = buf->read_4bytes();
  832 + }
  833 +
  834 + buf->skip(8);
  835 + layer = buf->read_2bytes();
  836 + alternate_group = buf->read_2bytes();
  837 + volume = buf->read_2bytes();
  838 + buf->skip(2);
  839 + for (int i = 0; i < 9; i++) {
  840 + matrix[i] = buf->read_4bytes();
  841 + }
  842 + width = buf->read_4bytes();
  843 + height = buf->read_4bytes();
  844 +
  845 + return ret;
  846 +}
  847 +
140 SrsMp4EditBox::SrsMp4EditBox() 848 SrsMp4EditBox::SrsMp4EditBox()
141 { 849 {
142 - type = 0x65647473; // 'edts' 850 + type = SRS_MP4_BOX_EDTS;
143 } 851 }
144 852
145 SrsMp4EditBox::~SrsMp4EditBox() 853 SrsMp4EditBox::~SrsMp4EditBox()
@@ -151,9 +859,56 @@ SrsMp4ElstEntry::SrsMp4ElstEntry() @@ -151,9 +859,56 @@ SrsMp4ElstEntry::SrsMp4ElstEntry()
151 media_rate_fraction = 0; 859 media_rate_fraction = 0;
152 } 860 }
153 861
  862 +int SrsMp4ElstEntry::nb_header(uint32_t version)
  863 +{
  864 + int size = 0;
  865 +
  866 + if (version == 1) {
  867 + size += 8+8;
  868 + } else {
  869 + size += 4+4;
  870 + }
  871 +
  872 + size += 2+2;
  873 +
  874 + return size;
  875 +}
  876 +
  877 +int SrsMp4ElstEntry::encode_header(SrsBuffer* buf, uint32_t version)
  878 +{
  879 + if (version == 1) {
  880 + buf->write_8bytes(segment_duration);
  881 + buf->write_8bytes(media_time);
  882 + } else {
  883 + buf->write_4bytes((uint32_t)segment_duration);
  884 + buf->write_4bytes((int32_t)media_time);
  885 + }
  886 +
  887 + buf->write_2bytes(media_rate_integer);
  888 + buf->write_2bytes(media_rate_fraction);
  889 +
  890 + return ERROR_SUCCESS;
  891 +}
  892 +
  893 +int SrsMp4ElstEntry::decode_header(SrsBuffer* buf, uint32_t version)
  894 +{
  895 + if (version == 1) {
  896 + segment_duration = buf->read_8bytes();
  897 + media_time = buf->read_8bytes();
  898 + } else {
  899 + segment_duration = buf->read_4bytes();
  900 + media_time = buf->read_4bytes();
  901 + }
  902 +
  903 + media_rate_integer = buf->read_2bytes();
  904 + media_rate_fraction = buf->read_2bytes();
  905 +
  906 + return ERROR_SUCCESS;
  907 +}
  908 +
154 SrsMp4EditListBox::SrsMp4EditListBox() 909 SrsMp4EditListBox::SrsMp4EditListBox()
155 { 910 {
156 - type = 0x656c7374; // 'elst' 911 + type = SRS_MP4_BOX_ELST;
157 912
158 entry_count = 0; 913 entry_count = 0;
159 entries = NULL; 914 entries = NULL;
@@ -164,9 +919,62 @@ SrsMp4EditListBox::~SrsMp4EditListBox() @@ -164,9 +919,62 @@ SrsMp4EditListBox::~SrsMp4EditListBox()
164 srs_freepa(entries); 919 srs_freepa(entries);
165 } 920 }
166 921
  922 +int SrsMp4EditListBox::nb_header()
  923 +{
  924 + int size = SrsMp4FullBox::nb_header();
  925 +
  926 + for (uint32_t i = 0; i < entry_count; i++) {
  927 + SrsMp4ElstEntry& entry = entries[i];
  928 + size += entry.nb_header(version);
  929 + }
  930 +
  931 + return size;
  932 +}
  933 +
  934 +int SrsMp4EditListBox::encode_header(SrsBuffer* buf)
  935 +{
  936 + int ret = ERROR_SUCCESS;
  937 +
  938 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  939 + return ret;
  940 + }
  941 +
  942 + for (uint32_t i = 0; i < entry_count; i++) {
  943 + SrsMp4ElstEntry& entry = entries[i];
  944 + if ((ret = entry.encode_header(buf, version)) != ERROR_SUCCESS) {
  945 + return ret;
  946 + }
  947 + }
  948 +
  949 + return ret;
  950 +}
  951 +
  952 +int SrsMp4EditListBox::decode_header(SrsBuffer* buf)
  953 +{
  954 + int ret = ERROR_SUCCESS;
  955 +
  956 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  957 + return ret;
  958 + }
  959 +
  960 + int left = left_space(buf);
  961 + entry_count = left / SrsMp4ElstEntry().nb_header(version);
  962 + if (entry_count > 0) {
  963 + entries = new SrsMp4ElstEntry[entry_count];
  964 + }
  965 + for (int i = 0; i < entry_count; i++) {
  966 + SrsMp4ElstEntry& entry = entries[i];
  967 + if ((ret = entry.decode_header(buf, version)) != ERROR_SUCCESS) {
  968 + return ret;
  969 + }
  970 + }
  971 +
  972 + return ret;
  973 +}
  974 +
167 SrsMp4MediaBox::SrsMp4MediaBox() 975 SrsMp4MediaBox::SrsMp4MediaBox()
168 { 976 {
169 - type = 0x6d646961; // 'mdia' 977 + type = SRS_MP4_BOX_MDIA;
170 } 978 }
171 979
172 SrsMp4MediaBox::~SrsMp4MediaBox() 980 SrsMp4MediaBox::~SrsMp4MediaBox()
@@ -175,9 +983,8 @@ SrsMp4MediaBox::~SrsMp4MediaBox() @@ -175,9 +983,8 @@ SrsMp4MediaBox::~SrsMp4MediaBox()
175 983
176 SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() 984 SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox()
177 { 985 {
178 - type = 0x6d646864; // 'mdhd'  
179 -  
180 - pad = 0; 986 + type = SRS_MP4_BOX_MDHD;
  987 + language = 0;
181 pre_defined = 0; 988 pre_defined = 0;
182 } 989 }
183 990
@@ -185,90 +992,468 @@ SrsMp4MediaHeaderBox::~SrsMp4MediaHeaderBox() @@ -185,90 +992,468 @@ SrsMp4MediaHeaderBox::~SrsMp4MediaHeaderBox()
185 { 992 {
186 } 993 }
187 994
  995 +uint8_t SrsMp4MediaHeaderBox::language0()
  996 +{
  997 + return (language >> 10) & 0x1f;
  998 +}
  999 +
  1000 +void SrsMp4MediaHeaderBox::set_language0(uint8_t v)
  1001 +{
  1002 + language |= uint16_t(v & 0x1f) << 10;
  1003 +}
  1004 +
  1005 +uint8_t SrsMp4MediaHeaderBox::language1()
  1006 +{
  1007 + return (language >> 5) & 0x1f;
  1008 +}
  1009 +
  1010 +void SrsMp4MediaHeaderBox::set_language1(uint8_t v)
  1011 +{
  1012 + language |= uint16_t(v & 0x1f) << 5;
  1013 +}
  1014 +
  1015 +uint8_t SrsMp4MediaHeaderBox::language2()
  1016 +{
  1017 + return language & 0x1f;
  1018 +}
  1019 +
  1020 +void SrsMp4MediaHeaderBox::set_language2(uint8_t v)
  1021 +{
  1022 + language |= uint16_t(v & 0x1f);
  1023 +}
  1024 +
  1025 +int SrsMp4MediaHeaderBox::nb_header()
  1026 +{
  1027 + int size = SrsMp4FullBox::nb_header();
  1028 +
  1029 + if (version == 1) {
  1030 + size += 8+8+4+8;
  1031 + } else {
  1032 + size += 4+4+4+4;
  1033 + }
  1034 +
  1035 + size += 2+2;
  1036 +
  1037 + return size;
  1038 +}
  1039 +
  1040 +int SrsMp4MediaHeaderBox::encode_header(SrsBuffer* buf)
  1041 +{
  1042 + int ret = ERROR_SUCCESS;
  1043 +
  1044 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1045 + return ret;
  1046 + }
  1047 +
  1048 + if (version == 1) {
  1049 + buf->write_8bytes(creation_time);
  1050 + buf->write_8bytes(modification_time);
  1051 + buf->write_4bytes(timescale);
  1052 + buf->write_8bytes(duration);
  1053 + } else {
  1054 + buf->write_4bytes((uint32_t)creation_time);
  1055 + buf->write_4bytes((uint32_t)modification_time);
  1056 + buf->write_4bytes(timescale);
  1057 + buf->write_4bytes((uint32_t)duration);
  1058 + }
  1059 +
  1060 + buf->write_2bytes(language);
  1061 + buf->write_2bytes(pre_defined);
  1062 +
  1063 + return ret;
  1064 +}
  1065 +
  1066 +int SrsMp4MediaHeaderBox::decode_header(SrsBuffer* buf)
  1067 +{
  1068 + int ret = ERROR_SUCCESS;
  1069 +
  1070 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1071 + return ret;
  1072 + }
  1073 +
  1074 + if (version == 1) {
  1075 + creation_time = buf->read_8bytes();
  1076 + modification_time = buf->read_8bytes();
  1077 + timescale = buf->read_4bytes();
  1078 + duration = buf->read_8bytes();
  1079 + } else {
  1080 + creation_time = buf->read_4bytes();
  1081 + modification_time = buf->read_4bytes();
  1082 + timescale = buf->read_4bytes();
  1083 + duration = buf->read_4bytes();
  1084 + }
  1085 +
  1086 + language = buf->read_2bytes();
  1087 + buf->skip(2);
  1088 +
  1089 + return ret;
  1090 +}
  1091 +
188 SrsMp4HandlerReferenceBox::SrsMp4HandlerReferenceBox() 1092 SrsMp4HandlerReferenceBox::SrsMp4HandlerReferenceBox()
189 { 1093 {
190 - type = 0x68646c72; // 'hdlr' 1094 + type = SRS_MP4_BOX_HDLR;
  1095 +
  1096 + pre_defined = 0;
  1097 + memset(reserved, 0, 12);
  1098 +}
  1099 +
  1100 +SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox()
  1101 +{
  1102 +}
  1103 +
  1104 +int SrsMp4HandlerReferenceBox::nb_header()
  1105 +{
  1106 + return SrsMp4FullBox::nb_header()+4+4+12+srs_mp4_string_length(name);
  1107 +}
  1108 +
  1109 +int SrsMp4HandlerReferenceBox::encode_header(SrsBuffer* buf)
  1110 +{
  1111 + int ret = ERROR_SUCCESS;
  1112 +
  1113 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1114 + return ret;
  1115 + }
  1116 +
  1117 + buf->write_4bytes(pre_defined);
  1118 + buf->write_4bytes(handler_type);
  1119 + buf->write_4bytes(reserved[0]);
  1120 + buf->write_4bytes(reserved[1]);
  1121 + buf->write_4bytes(reserved[2]);
  1122 + srs_mp4_string_write(buf, name);
  1123 +
  1124 + return ret;
  1125 +}
  1126 +
  1127 +int SrsMp4HandlerReferenceBox::decode_header(SrsBuffer* buf)
  1128 +{
  1129 + int ret = ERROR_SUCCESS;
  1130 +
  1131 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1132 + return ret;
  1133 + }
  1134 +
  1135 + buf->skip(4);
  1136 + handler_type = buf->read_4bytes();
  1137 + buf->skip(12);
  1138 +
  1139 + if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) {
  1140 + srs_error("MP4 hdlr read string failed. ret=%d", ret);
  1141 + return ret;
  1142 + }
  1143 +
  1144 + return ret;
  1145 +}
  1146 +
  1147 +SrsMp4MediaInformationBox::SrsMp4MediaInformationBox()
  1148 +{
  1149 + type = SRS_MP4_BOX_MINF;
  1150 +}
  1151 +
  1152 +SrsMp4MediaInformationBox::~SrsMp4MediaInformationBox()
  1153 +{
  1154 +}
  1155 +
  1156 +SrsMp4VideoMeidaHeaderBox::SrsMp4VideoMeidaHeaderBox()
  1157 +{
  1158 + type = SRS_MP4_BOX_VMHD;
  1159 + version = 0;
  1160 + flags = 1;
  1161 +
  1162 + graphicsmode = 0;
  1163 + memset(opcolor, 0, 6);
  1164 +}
  1165 +
  1166 +SrsMp4VideoMeidaHeaderBox::~SrsMp4VideoMeidaHeaderBox()
  1167 +{
  1168 +}
  1169 +
  1170 +int SrsMp4VideoMeidaHeaderBox::nb_header()
  1171 +{
  1172 + return SrsMp4FullBox::nb_header()+2+6;
  1173 +}
  1174 +
  1175 +int SrsMp4VideoMeidaHeaderBox::encode_header(SrsBuffer* buf)
  1176 +{
  1177 + int ret = ERROR_SUCCESS;
  1178 +
  1179 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1180 + return ret;
  1181 + }
  1182 +
  1183 + buf->write_2bytes(graphicsmode);
  1184 + buf->write_2bytes(opcolor[0]);
  1185 + buf->write_2bytes(opcolor[1]);
  1186 + buf->write_2bytes(opcolor[2]);
  1187 +
  1188 + return ret;
  1189 +}
  1190 +
  1191 +int SrsMp4VideoMeidaHeaderBox::decode_header(SrsBuffer* buf)
  1192 +{
  1193 + int ret = ERROR_SUCCESS;
  1194 +
  1195 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1196 + return ret;
  1197 + }
  1198 +
  1199 + graphicsmode = buf->read_2bytes();
  1200 + opcolor[0] = buf->read_2bytes();
  1201 + opcolor[1] = buf->read_2bytes();
  1202 + opcolor[2] = buf->read_2bytes();
  1203 +
  1204 + return ret;
  1205 +}
  1206 +
  1207 +SrsMp4SoundMeidaHeaderBox::SrsMp4SoundMeidaHeaderBox()
  1208 +{
  1209 + type = SRS_MP4_BOX_SMHD;
  1210 +
  1211 + reserved = balance = 0;
  1212 +}
  1213 +
  1214 +SrsMp4SoundMeidaHeaderBox::~SrsMp4SoundMeidaHeaderBox()
  1215 +{
  1216 +}
  1217 +
  1218 +int SrsMp4SoundMeidaHeaderBox::nb_header()
  1219 +{
  1220 + return SrsMp4FullBox::nb_header()+2+2;
  1221 +}
  1222 +
  1223 +int SrsMp4SoundMeidaHeaderBox::encode_header(SrsBuffer* buf)
  1224 +{
  1225 + int ret = ERROR_SUCCESS;
  1226 +
  1227 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1228 + return ret;
  1229 + }
  1230 +
  1231 + buf->write_2bytes(balance);
  1232 + buf->write_2bytes(reserved);
  1233 +
  1234 + return ret;
  1235 +}
  1236 +
  1237 +int SrsMp4SoundMeidaHeaderBox::decode_header(SrsBuffer* buf)
  1238 +{
  1239 + int ret = ERROR_SUCCESS;
  1240 +
  1241 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1242 + return ret;
  1243 + }
  1244 +
  1245 + balance = buf->read_2bytes();
  1246 + buf->skip(2);
  1247 +
  1248 + return ret;
  1249 +}
  1250 +
  1251 +SrsMp4DataInformationBox::SrsMp4DataInformationBox()
  1252 +{
  1253 + type = SRS_MP4_BOX_DINF;
  1254 +}
  1255 +
  1256 +SrsMp4DataInformationBox::~SrsMp4DataInformationBox()
  1257 +{
  1258 +}
  1259 +
  1260 +SrsMp4DataEntryBox::SrsMp4DataEntryBox()
  1261 +{
  1262 +}
  1263 +
  1264 +SrsMp4DataEntryBox::~SrsMp4DataEntryBox()
  1265 +{
  1266 +}
  1267 +
  1268 +int SrsMp4DataEntryBox::nb_header()
  1269 +{
  1270 + return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location);
  1271 +}
  1272 +
  1273 +int SrsMp4DataEntryBox::encode_header(SrsBuffer* buf)
  1274 +{
  1275 + int ret = ERROR_SUCCESS;
  1276 +
  1277 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1278 + return ret;
  1279 + }
  1280 +
  1281 + srs_mp4_string_write(buf, location);
  1282 +
  1283 + return ret;
  1284 +}
  1285 +
  1286 +int SrsMp4DataEntryBox::decode_header(SrsBuffer* buf)
  1287 +{
  1288 + int ret = ERROR_SUCCESS;
191 1289
192 - pre_defined = 0;  
193 - memset(reserved, 0, 12); 1290 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1291 + return ret;
  1292 + }
  1293 +
  1294 + if ((ret = srs_mp4_string_read(buf, location, left_space(buf))) != ERROR_SUCCESS) {
  1295 + srs_error("MP4 urx read string failed. ret=%d", ret);
  1296 + return ret;
  1297 + }
  1298 +
  1299 + return ret;
194 } 1300 }
195 1301
196 -SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() 1302 +SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox()
197 { 1303 {
  1304 + type = SRS_MP4_BOX_URL;
198 } 1305 }
199 1306
200 -SrsMp4MediaInformationBox::SrsMp4MediaInformationBox() 1307 +SrsMp4DataEntryUrlBox::~SrsMp4DataEntryUrlBox()
201 { 1308 {
202 - type = 0x6d696e66; // 'minf'  
203 } 1309 }
204 1310
205 -SrsMp4MediaInformationBox::~SrsMp4MediaInformationBox() 1311 +SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox()
206 { 1312 {
  1313 + type = SRS_MP4_BOX_URN;
207 } 1314 }
208 1315
209 -SrsMp4VideoMeidaHeaderBox::SrsMp4VideoMeidaHeaderBox() 1316 +SrsMp4DataEntryUrnBox::~SrsMp4DataEntryUrnBox()
210 { 1317 {
211 - type = 0x766d6864; // 'vmhd'  
212 - version = 0;  
213 - flags = 1;  
214 -  
215 - graphicsmode = 0;  
216 - memset(opcolor, 0, 6);  
217 } 1318 }
218 1319
219 -SrsMp4VideoMeidaHeaderBox::~SrsMp4VideoMeidaHeaderBox() 1320 +int SrsMp4DataEntryUrnBox::nb_header()
220 { 1321 {
  1322 + return SrsMp4DataEntryBox::nb_header()+srs_mp4_string_length(name);
221 } 1323 }
222 1324
223 -SrsMp4SoundMeidaHeaderBox::SrsMp4SoundMeidaHeaderBox() 1325 +int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf)
224 { 1326 {
225 - type = 0x736d6864; // 'smhd' 1327 + int ret = ERROR_SUCCESS;
226 1328
227 - reserved = balance = 0; 1329 + if ((ret = SrsMp4DataEntryBox::encode_header(buf)) != ERROR_SUCCESS) {
  1330 + return ret;
  1331 + }
  1332 +
  1333 + srs_mp4_string_write(buf, name);
  1334 +
  1335 + return ret;
228 } 1336 }
229 1337
230 -SrsMp4SoundMeidaHeaderBox::~SrsMp4SoundMeidaHeaderBox() 1338 +int SrsMp4DataEntryUrnBox::decode_header(SrsBuffer* buf)
231 { 1339 {
  1340 + int ret = ERROR_SUCCESS;
  1341 +
  1342 + if ((ret = SrsMp4DataEntryBox::decode_header(buf)) != ERROR_SUCCESS) {
  1343 + return ret;
  1344 + }
  1345 +
  1346 + if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) {
  1347 + srs_error("MP4 urn read string failed. ret=%d", ret);
  1348 + return ret;
  1349 + }
  1350 +
  1351 + return ret;
232 } 1352 }
233 1353
234 -SrsMp4DataInformationBox::SrsMp4DataInformationBox() 1354 +SrsMp4DataReferenceBox::SrsMp4DataReferenceBox()
235 { 1355 {
236 - type = 0x64696e66; // 'dinf' 1356 + type = SRS_MP4_BOX_DREF;
237 } 1357 }
238 1358
239 -SrsMp4DataInformationBox::~SrsMp4DataInformationBox() 1359 +SrsMp4DataReferenceBox::~SrsMp4DataReferenceBox()
240 { 1360 {
  1361 + vector<SrsMp4DataEntryBox*>::iterator it;
  1362 + for (it = entries.begin(); it != entries.end(); ++it) {
  1363 + SrsMp4DataEntryBox* entry = *it;
  1364 + srs_freep(entry);
  1365 + }
  1366 + entries.clear();
241 } 1367 }
242 1368
243 -SrsMp4DataEntryBox::SrsMp4DataEntryBox() 1369 +uint32_t SrsMp4DataReferenceBox::entry_count()
244 { 1370 {
  1371 + return (uint32_t)entries.size();
245 } 1372 }
246 1373
247 -SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox() 1374 +SrsMp4DataEntryBox* SrsMp4DataReferenceBox::entry_at(int index)
248 { 1375 {
249 - type = 0x75726c20; // 'url ' 1376 + return entries.at(index);
250 } 1377 }
251 1378
252 -SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox() 1379 +int SrsMp4DataReferenceBox::nb_header()
253 { 1380 {
254 - type = 0x75726e20; // 'urn ' 1381 + int size = SrsMp4FullBox::nb_header();
  1382 +
  1383 + size += 4;
  1384 +
  1385 + vector<SrsMp4DataEntryBox*>::iterator it;
  1386 + for (it = entries.begin(); it != entries.end(); ++it) {
  1387 + SrsMp4DataEntryBox* entry = *it;
  1388 + size += entry->nb_bytes();
  1389 + }
  1390 +
  1391 + return size;
255 } 1392 }
256 1393
257 -SrsMp4DataReferenceBox::SrsMp4DataReferenceBox() 1394 +int SrsMp4DataReferenceBox::encode_header(SrsBuffer* buf)
258 { 1395 {
259 - type = 0x64726566; // 'dref' 1396 + int ret = ERROR_SUCCESS;
260 1397
261 - entry_count = 0;  
262 - entries = NULL; 1398 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1399 + return ret;
  1400 + }
  1401 +
  1402 + buf->write_4bytes((int32_t)entries.size());
  1403 +
  1404 + vector<SrsMp4DataEntryBox*>::iterator it;
  1405 + for (it = entries.begin(); it != entries.end(); ++it) {
  1406 + SrsMp4DataEntryBox* entry = *it;
  1407 + if ((ret = entry->encode(buf)) != ERROR_SUCCESS) {
  1408 + return ret;
  1409 + }
  1410 + }
  1411 +
  1412 + return ret;
263 } 1413 }
264 1414
265 -SrsMp4DataReferenceBox::~SrsMp4DataReferenceBox() 1415 +int SrsMp4DataReferenceBox::decode_header(SrsBuffer* buf)
266 { 1416 {
  1417 + int ret = ERROR_SUCCESS;
  1418 +
  1419 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1420 + return ret;
  1421 + }
  1422 +
  1423 + int left = left_space(buf);
  1424 + while (left > 0) {
  1425 + SrsMp4Box* box = NULL;
  1426 + if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) {
  1427 + return ret;
  1428 + }
  1429 +
  1430 + int pos = buf->pos();
  1431 + if ((ret = box->decode(buf)) != ERROR_SUCCESS) {
  1432 + return ret;
  1433 + }
  1434 + left -= buf->pos() - pos;
  1435 +
  1436 + SrsMp4FullBox* fbox = dynamic_cast<SrsMp4FullBox*>(box);
  1437 + if (fbox) {
  1438 + fbox->version = version;
  1439 + fbox->flags = flags;
  1440 + }
  1441 +
  1442 + if (box->type == SRS_MP4_BOX_URL) {
  1443 + entries.push_back(dynamic_cast<SrsMp4DataEntryUrlBox*>(box));
  1444 + } else if (box->type == SRS_MP4_BOX_URN) {
  1445 + entries.push_back(dynamic_cast<SrsMp4DataEntryUrnBox*>(box));
  1446 + } else {
  1447 + srs_freep(box);
  1448 + }
  1449 + }
  1450 +
  1451 + return ret;
267 } 1452 }
268 1453
269 SrsMp4SampleTableBox::SrsMp4SampleTableBox() 1454 SrsMp4SampleTableBox::SrsMp4SampleTableBox()
270 { 1455 {
271 - type = 0x7374626c; // 'stbl' 1456 + type = SRS_MP4_BOX_STBL;
272 } 1457 }
273 1458
274 SrsMp4SampleTableBox::~SrsMp4SampleTableBox() 1459 SrsMp4SampleTableBox::~SrsMp4SampleTableBox()
@@ -284,6 +1469,41 @@ SrsMp4SampleEntry::~SrsMp4SampleEntry() @@ -284,6 +1469,41 @@ SrsMp4SampleEntry::~SrsMp4SampleEntry()
284 { 1469 {
285 } 1470 }
286 1471
  1472 +int SrsMp4SampleEntry::nb_header()
  1473 +{
  1474 + return SrsMp4Box::nb_header()+6+2;
  1475 +}
  1476 +
  1477 +int SrsMp4SampleEntry::encode_header(SrsBuffer* buf)
  1478 +{
  1479 + int ret = ERROR_SUCCESS;
  1480 +
  1481 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  1482 + return ret;
  1483 + }
  1484 +
  1485 + for (int i = 0; i < 6; i++) {
  1486 + buf->write_1bytes(reserved[i]);
  1487 + }
  1488 + buf->write_2bytes(data_reference_index);
  1489 +
  1490 + return ret;
  1491 +}
  1492 +
  1493 +int SrsMp4SampleEntry::decode_header(SrsBuffer* buf)
  1494 +{
  1495 + int ret = ERROR_SUCCESS;
  1496 +
  1497 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  1498 + return ret;
  1499 + }
  1500 +
  1501 + buf->skip(6);
  1502 + data_reference_index = buf->read_2bytes();
  1503 +
  1504 + return ret;
  1505 +}
  1506 +
287 SrsMp4VisualSampleEntry::SrsMp4VisualSampleEntry() 1507 SrsMp4VisualSampleEntry::SrsMp4VisualSampleEntry()
288 { 1508 {
289 pre_defined0 = 0; 1509 pre_defined0 = 0;
@@ -302,9 +1522,64 @@ SrsMp4VisualSampleEntry::~SrsMp4VisualSampleEntry() @@ -302,9 +1522,64 @@ SrsMp4VisualSampleEntry::~SrsMp4VisualSampleEntry()
302 { 1522 {
303 } 1523 }
304 1524
  1525 +int SrsMp4VisualSampleEntry::nb_header()
  1526 +{
  1527 + return SrsMp4SampleEntry::nb_header()+2+2+12+2+2+4+4+4+2+32+2+2;
  1528 +}
  1529 +
  1530 +int SrsMp4VisualSampleEntry::encode_header(SrsBuffer* buf)
  1531 +{
  1532 + int ret = ERROR_SUCCESS;
  1533 +
  1534 + if ((ret = SrsMp4SampleEntry::encode_header(buf)) != ERROR_SUCCESS) {
  1535 + return ret;
  1536 + }
  1537 +
  1538 + buf->write_2bytes(pre_defined0);
  1539 + buf->write_2bytes(reserved0);
  1540 + buf->write_4bytes(pre_defined1[0]);
  1541 + buf->write_4bytes(pre_defined1[1]);
  1542 + buf->write_4bytes(pre_defined1[2]);
  1543 + buf->write_2bytes(width);
  1544 + buf->write_2bytes(height);
  1545 + buf->write_4bytes(horizresolution);
  1546 + buf->write_4bytes(vertresolution);
  1547 + buf->write_4bytes(reserved1);
  1548 + buf->write_2bytes(frame_count);
  1549 + buf->write_bytes(compressorname, 32);
  1550 + buf->write_2bytes(depth);
  1551 + buf->write_2bytes(pre_defined2);
  1552 +
  1553 + return ret;
  1554 +}
  1555 +
  1556 +int SrsMp4VisualSampleEntry::decode_header(SrsBuffer* buf)
  1557 +{
  1558 + int ret = ERROR_SUCCESS;
  1559 +
  1560 + if ((ret = SrsMp4SampleEntry::decode_header(buf)) != ERROR_SUCCESS) {
  1561 + return ret;
  1562 + }
  1563 +
  1564 + buf->skip(2);
  1565 + buf->skip(2);
  1566 + buf->skip(12);
  1567 + width = buf->read_2bytes();
  1568 + height = buf->read_2bytes();
  1569 + horizresolution = buf->read_4bytes();
  1570 + vertresolution = buf->read_4bytes();
  1571 + buf->skip(4);
  1572 + frame_count = buf->read_2bytes();
  1573 + buf->read_bytes(compressorname, 32);
  1574 + depth = buf->read_2bytes();
  1575 + buf->skip(2);
  1576 +
  1577 + return ret;
  1578 +}
  1579 +
305 SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry() 1580 SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry()
306 { 1581 {
307 - memset(reserved0, 0, 8); 1582 + reserved0 = 0;
308 pre_defined0 = 0; 1583 pre_defined0 = 0;
309 reserved1 = 0; 1584 reserved1 = 0;
310 channelcount = 2; 1585 channelcount = 2;
@@ -315,17 +1590,134 @@ SrsMp4AudioSampleEntry::~SrsMp4AudioSampleEntry() @@ -315,17 +1590,134 @@ SrsMp4AudioSampleEntry::~SrsMp4AudioSampleEntry()
315 { 1590 {
316 } 1591 }
317 1592
318 -SrsMp4SampleDescriptionBox::SrsMp4SampleDescriptionBox() 1593 +int SrsMp4AudioSampleEntry::nb_header()
  1594 +{
  1595 + return SrsMp4SampleEntry::nb_header()+8+2+2+2+2+4;
  1596 +}
  1597 +
  1598 +int SrsMp4AudioSampleEntry::encode_header(SrsBuffer* buf)
319 { 1599 {
320 - type = 0x73747364; // 'stsd' 1600 + int ret = ERROR_SUCCESS;
321 1601
322 - entry_count = 0;  
323 - entries = NULL; 1602 + if ((ret = SrsMp4SampleEntry::encode_header(buf)) != ERROR_SUCCESS) {
  1603 + return ret;
  1604 + }
  1605 +
  1606 + buf->write_8bytes(reserved0);
  1607 + buf->write_2bytes(channelcount);
  1608 + buf->write_2bytes(samplesize);
  1609 + buf->write_2bytes(pre_defined0);
  1610 + buf->write_2bytes(reserved1);
  1611 + buf->write_4bytes(samplerate);
  1612 +
  1613 + return ret;
  1614 +}
  1615 +
  1616 +int SrsMp4AudioSampleEntry::decode_header(SrsBuffer* buf)
  1617 +{
  1618 + int ret = ERROR_SUCCESS;
  1619 +
  1620 + if ((ret = SrsMp4SampleEntry::decode_header(buf)) != ERROR_SUCCESS) {
  1621 + return ret;
  1622 + }
  1623 +
  1624 + buf->skip(8);
  1625 + channelcount = buf->read_2bytes();
  1626 + samplesize = buf->read_2bytes();
  1627 + buf->skip(2);
  1628 + buf->skip(2);
  1629 + samplerate = buf->read_4bytes();
  1630 +
  1631 + return ret;
  1632 +}
  1633 +
  1634 +SrsMp4SampleDescriptionBox::SrsMp4SampleDescriptionBox()
  1635 +{
  1636 + type = SRS_MP4_BOX_STSD;
324 } 1637 }
325 1638
326 SrsMp4SampleDescriptionBox::~SrsMp4SampleDescriptionBox() 1639 SrsMp4SampleDescriptionBox::~SrsMp4SampleDescriptionBox()
327 { 1640 {
328 - srs_freepa(entries); 1641 + vector<SrsMp4SampleEntry*>::iterator it;
  1642 + for (it = entries.begin(); it != entries.end(); ++it) {
  1643 + SrsMp4SampleEntry* entry = *it;
  1644 + srs_freep(entry);
  1645 + }
  1646 + entries.clear();
  1647 +}
  1648 +
  1649 +uint32_t SrsMp4SampleDescriptionBox::entry_count()
  1650 +{
  1651 + return (uint32_t)entries.size();
  1652 +}
  1653 +
  1654 +SrsMp4SampleEntry* SrsMp4SampleDescriptionBox::entrie_at(int index)
  1655 +{
  1656 + return entries.at(index);
  1657 +}
  1658 +
  1659 +int SrsMp4SampleDescriptionBox::nb_header()
  1660 +{
  1661 + int size = SrsMp4FullBox::nb_header();
  1662 +
  1663 + vector<SrsMp4SampleEntry*>::iterator it;
  1664 + for (it = entries.begin(); it != entries.end(); ++it) {
  1665 + SrsMp4SampleEntry* entry = *it;
  1666 + size += entry->nb_bytes();
  1667 + }
  1668 +
  1669 + return size;
  1670 +}
  1671 +
  1672 +int SrsMp4SampleDescriptionBox::encode_header(SrsBuffer* buf)
  1673 +{
  1674 + int ret = ERROR_SUCCESS;
  1675 +
  1676 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1677 + return ret;
  1678 + }
  1679 +
  1680 + vector<SrsMp4SampleEntry*>::iterator it;
  1681 + for (it = entries.begin(); it != entries.end(); ++it) {
  1682 + SrsMp4SampleEntry* entry = *it;
  1683 + if ((ret = entry->encode(buf)) != ERROR_SUCCESS) {
  1684 + return ret;
  1685 + }
  1686 + }
  1687 +
  1688 + return ret;
  1689 +}
  1690 +
  1691 +int SrsMp4SampleDescriptionBox::decode_header(SrsBuffer* buf)
  1692 +{
  1693 + int ret = ERROR_SUCCESS;
  1694 +
  1695 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1696 + return ret;
  1697 + }
  1698 +
  1699 + int left = left_space(buf);
  1700 + while (left > 0) {
  1701 + SrsMp4Box* box = NULL;
  1702 + if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) {
  1703 + return ret;
  1704 + }
  1705 +
  1706 + int pos = buf->pos();
  1707 + if ((ret = box->decode(buf)) != ERROR_SUCCESS) {
  1708 + return ret;
  1709 + }
  1710 + left -= buf->pos() - pos;
  1711 +
  1712 + SrsMp4SampleEntry* entry = dynamic_cast<SrsMp4SampleEntry*>(box);
  1713 + if (entry) {
  1714 + entries.push_back(entry);
  1715 + } else {
  1716 + srs_freep(box);
  1717 + }
  1718 + }
  1719 +
  1720 + return ret;
329 } 1721 }
330 1722
331 SrsMp4SttsEntry::SrsMp4SttsEntry() 1723 SrsMp4SttsEntry::SrsMp4SttsEntry()
@@ -336,7 +1728,7 @@ SrsMp4SttsEntry::SrsMp4SttsEntry() @@ -336,7 +1728,7 @@ SrsMp4SttsEntry::SrsMp4SttsEntry()
336 1728
337 SrsMp4DecodingTime2SampleBox::SrsMp4DecodingTime2SampleBox() 1729 SrsMp4DecodingTime2SampleBox::SrsMp4DecodingTime2SampleBox()
338 { 1730 {
339 - type = 0x73747473; // 'stts' 1731 + type = SRS_MP4_BOX_STTS;
340 1732
341 entry_count = 0; 1733 entry_count = 0;
342 entries = NULL; 1734 entries = NULL;
@@ -347,6 +1739,33 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox() @@ -347,6 +1739,33 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox()
347 srs_freepa(entries); 1739 srs_freepa(entries);
348 } 1740 }
349 1741
  1742 +int SrsMp4DecodingTime2SampleBox::nb_header()
  1743 +{
  1744 + return SrsMp4FullBox::nb_header();
  1745 +}
  1746 +
  1747 +int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf)
  1748 +{
  1749 + int ret = ERROR_SUCCESS;
  1750 +
  1751 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1752 + return ret;
  1753 + }
  1754 +
  1755 + return ret;
  1756 +}
  1757 +
  1758 +int SrsMp4DecodingTime2SampleBox::decode_header(SrsBuffer* buf)
  1759 +{
  1760 + int ret = ERROR_SUCCESS;
  1761 +
  1762 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1763 + return ret;
  1764 + }
  1765 +
  1766 + return ret;
  1767 +}
  1768 +
350 SrsMp4CttsEntry::SrsMp4CttsEntry() 1769 SrsMp4CttsEntry::SrsMp4CttsEntry()
351 { 1770 {
352 sample_count = 0; 1771 sample_count = 0;
@@ -355,7 +1774,7 @@ SrsMp4CttsEntry::SrsMp4CttsEntry() @@ -355,7 +1774,7 @@ SrsMp4CttsEntry::SrsMp4CttsEntry()
355 1774
356 SrsMp4CompositionTime2SampleBox::SrsMp4CompositionTime2SampleBox() 1775 SrsMp4CompositionTime2SampleBox::SrsMp4CompositionTime2SampleBox()
357 { 1776 {
358 - type = 0x63747473; // 'ctts' 1777 + type = SRS_MP4_BOX_CTTS;
359 1778
360 entry_count = 0; 1779 entry_count = 0;
361 entries = NULL; 1780 entries = NULL;
@@ -366,9 +1785,36 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox() @@ -366,9 +1785,36 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox()
366 srs_freepa(entries); 1785 srs_freepa(entries);
367 } 1786 }
368 1787
  1788 +int SrsMp4CompositionTime2SampleBox::nb_header()
  1789 +{
  1790 + return SrsMp4FullBox::nb_header();
  1791 +}
  1792 +
  1793 +int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf)
  1794 +{
  1795 + int ret = ERROR_SUCCESS;
  1796 +
  1797 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1798 + return ret;
  1799 + }
  1800 +
  1801 + return ret;
  1802 +}
  1803 +
  1804 +int SrsMp4CompositionTime2SampleBox::decode_header(SrsBuffer* buf)
  1805 +{
  1806 + int ret = ERROR_SUCCESS;
  1807 +
  1808 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1809 + return ret;
  1810 + }
  1811 +
  1812 + return ret;
  1813 +}
  1814 +
369 SrsMp4SyncSampleBox::SrsMp4SyncSampleBox() 1815 SrsMp4SyncSampleBox::SrsMp4SyncSampleBox()
370 { 1816 {
371 - type = 0x73747373; // 'stss' 1817 + type = SRS_MP4_BOX_STSS;
372 1818
373 entry_count = 0; 1819 entry_count = 0;
374 sample_numbers = NULL; 1820 sample_numbers = NULL;
@@ -379,6 +1825,33 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox() @@ -379,6 +1825,33 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox()
379 srs_freepa(sample_numbers); 1825 srs_freepa(sample_numbers);
380 } 1826 }
381 1827
  1828 +int SrsMp4SyncSampleBox::nb_header()
  1829 +{
  1830 + return SrsMp4FullBox::nb_header();
  1831 +}
  1832 +
  1833 +int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf)
  1834 +{
  1835 + int ret = ERROR_SUCCESS;
  1836 +
  1837 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1838 + return ret;
  1839 + }
  1840 +
  1841 + return ret;
  1842 +}
  1843 +
  1844 +int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf)
  1845 +{
  1846 + int ret = ERROR_SUCCESS;
  1847 +
  1848 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1849 + return ret;
  1850 + }
  1851 +
  1852 + return ret;
  1853 +}
  1854 +
382 SrsMp4StscEntry::SrsMp4StscEntry() 1855 SrsMp4StscEntry::SrsMp4StscEntry()
383 { 1856 {
384 first_chunk = 0; 1857 first_chunk = 0;
@@ -388,7 +1861,7 @@ SrsMp4StscEntry::SrsMp4StscEntry() @@ -388,7 +1861,7 @@ SrsMp4StscEntry::SrsMp4StscEntry()
388 1861
389 SrsMp4Sample2ChunkBox::SrsMp4Sample2ChunkBox() 1862 SrsMp4Sample2ChunkBox::SrsMp4Sample2ChunkBox()
390 { 1863 {
391 - type = 0x73747363; // 'stsc' 1864 + type = SRS_MP4_BOX_STSC;
392 1865
393 entry_count = 0; 1866 entry_count = 0;
394 entries = NULL; 1867 entries = NULL;
@@ -399,9 +1872,36 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox() @@ -399,9 +1872,36 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox()
399 srs_freepa(entries); 1872 srs_freepa(entries);
400 } 1873 }
401 1874
  1875 +int SrsMp4Sample2ChunkBox::nb_header()
  1876 +{
  1877 + return SrsMp4FullBox::nb_header();
  1878 +}
  1879 +
  1880 +int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf)
  1881 +{
  1882 + int ret = ERROR_SUCCESS;
  1883 +
  1884 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1885 + return ret;
  1886 + }
  1887 +
  1888 + return ret;
  1889 +}
  1890 +
  1891 +int SrsMp4Sample2ChunkBox::decode_header(SrsBuffer* buf)
  1892 +{
  1893 + int ret = ERROR_SUCCESS;
  1894 +
  1895 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1896 + return ret;
  1897 + }
  1898 +
  1899 + return ret;
  1900 +}
  1901 +
402 SrsMp4ChunkOffsetBox::SrsMp4ChunkOffsetBox() 1902 SrsMp4ChunkOffsetBox::SrsMp4ChunkOffsetBox()
403 { 1903 {
404 - type = 0x7374636f; // 'stco' 1904 + type = SRS_MP4_BOX_STCO;
405 1905
406 entry_count = 0; 1906 entry_count = 0;
407 entries = NULL; 1907 entries = NULL;
@@ -412,9 +1912,36 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox() @@ -412,9 +1912,36 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox()
412 srs_freepa(entries); 1912 srs_freepa(entries);
413 } 1913 }
414 1914
  1915 +int SrsMp4ChunkOffsetBox::nb_header()
  1916 +{
  1917 + return SrsMp4FullBox::nb_header();
  1918 +}
  1919 +
  1920 +int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf)
  1921 +{
  1922 + int ret = ERROR_SUCCESS;
  1923 +
  1924 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1925 + return ret;
  1926 + }
  1927 +
  1928 + return ret;
  1929 +}
  1930 +
  1931 +int SrsMp4ChunkOffsetBox::decode_header(SrsBuffer* buf)
  1932 +{
  1933 + int ret = ERROR_SUCCESS;
  1934 +
  1935 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1936 + return ret;
  1937 + }
  1938 +
  1939 + return ret;
  1940 +}
  1941 +
415 SrsMp4SampleSizeBox::SrsMp4SampleSizeBox() 1942 SrsMp4SampleSizeBox::SrsMp4SampleSizeBox()
416 { 1943 {
417 - type = 0x7374737a; // 'stsz' 1944 + type = SRS_MP4_BOX_STSZ;
418 1945
419 sample_size = sample_count = 0; 1946 sample_size = sample_count = 0;
420 entry_sizes = NULL; 1947 entry_sizes = NULL;
@@ -425,12 +1952,44 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox() @@ -425,12 +1952,44 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox()
425 srs_freepa(entry_sizes); 1952 srs_freepa(entry_sizes);
426 } 1953 }
427 1954
  1955 +int SrsMp4SampleSizeBox::nb_header()
  1956 +{
  1957 + return SrsMp4FullBox::nb_header();
  1958 +}
  1959 +
  1960 +int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf)
  1961 +{
  1962 + int ret = ERROR_SUCCESS;
  1963 +
  1964 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  1965 + return ret;
  1966 + }
  1967 +
  1968 + return ret;
  1969 +}
  1970 +
  1971 +int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf)
  1972 +{
  1973 + int ret = ERROR_SUCCESS;
  1974 +
  1975 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  1976 + return ret;
  1977 + }
  1978 +
  1979 + return ret;
  1980 +}
  1981 +
428 SrsMp4Decoder::SrsMp4Decoder() 1982 SrsMp4Decoder::SrsMp4Decoder()
429 { 1983 {
  1984 + reader = NULL;
  1985 + next = NULL;
  1986 + stream = new SrsSimpleStream();
430 } 1987 }
431 1988
432 SrsMp4Decoder::~SrsMp4Decoder() 1989 SrsMp4Decoder::~SrsMp4Decoder()
433 { 1990 {
  1991 + srs_freep(next);
  1992 + srs_freep(stream);
434 } 1993 }
435 1994
436 int SrsMp4Decoder::initialize(ISrsReader* r) 1995 int SrsMp4Decoder::initialize(ISrsReader* r)
@@ -440,6 +1999,67 @@ int SrsMp4Decoder::initialize(ISrsReader* r) @@ -440,6 +1999,67 @@ int SrsMp4Decoder::initialize(ISrsReader* r)
440 srs_assert(r); 1999 srs_assert(r);
441 reader = r; 2000 reader = r;
442 2001
  2002 + if ((ret = load_next_box(&next)) != ERROR_SUCCESS) {
  2003 + return ret;
  2004 + }
  2005 +
  2006 + if (next->type != SRS_MP4_BOX_FTYP) {
  2007 + ret = ERROR_MP4_BOX_ILLEGAL_SCHEMA;
  2008 + srs_error("MP4 first box must be FTYP, not %d. ret=%d", next->type, ret);
  2009 + return ret;
  2010 + }
  2011 +
  2012 + return ret;
  2013 +}
  2014 +
  2015 +int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox)
  2016 +{
  2017 + int ret = ERROR_SUCCESS;
  2018 +
  2019 + // Ignore for already loaded.
  2020 + if (next) {
  2021 + return ret;
  2022 + }
  2023 +
  2024 + char* buf = new char[4096];
  2025 + SrsAutoFreeA(char, buf);
  2026 +
  2027 + while (true) {
  2028 + uint64_t required = next? next->sz():4;
  2029 + while (stream->length() < required) {
  2030 + ssize_t nread;
  2031 + if ((ret = reader->read(buf, 4096, &nread)) != ERROR_SUCCESS) {
  2032 + srs_error("MP4 load failed, nread=%d, required=%d. ret=%d", nread, required, ret);
  2033 + return ret;
  2034 + }
  2035 +
  2036 + srs_assert(nread > 0);
  2037 + stream->append(buf, (int)nread);
  2038 + }
  2039 +
  2040 + SrsBuffer* buffer = new SrsBuffer(stream->bytes(), stream->length());
  2041 + SrsAutoFree(SrsBuffer, buffer);
  2042 +
  2043 + // Discovery the box with basic header.
  2044 + if (!next && (ret = SrsMp4Box::discovery(buffer, ppbox)) != ERROR_SUCCESS) {
  2045 + if (ret == ERROR_MP4_BOX_REQUIRE_SPACE) {
  2046 + continue;
  2047 + }
  2048 + srs_error("MP4 load box failed. ret=%d", ret);
  2049 + return ret;
  2050 + }
  2051 +
  2052 + // Decode util we can demux the whole box.
  2053 + if (!buffer->require((int)next->sz())) {
  2054 + continue;
  2055 + }
  2056 + ret = next->decode(buffer);
  2057 +
  2058 + // Remove the consumed bytes.
  2059 + stream->erase((int)next->sz());
  2060 + break;
  2061 + }
  2062 +
443 return ret; 2063 return ret;
444 } 2064 }
445 2065
@@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
  32 +#include <srs_kernel_buffer.hpp>
  33 +
32 #include <string> 34 #include <string>
  35 +#include <vector>
33 36
34 class ISrsReader; 37 class ISrsReader;
  38 +class SrsSimpleStream;
35 39
36 /** 40 /**
37 * 4.2 Object Structure 41 * 4.2 Object Structure
38 * ISO_IEC_14496-12-base-format-2012.pdf, page 16 42 * ISO_IEC_14496-12-base-format-2012.pdf, page 16
39 */ 43 */
40 -class SrsMp4Box 44 +class SrsMp4Box : public ISrsCodec
41 { 45 {
42 -public: 46 +private:
  47 + // The size is the entire size of the box, including the size and type header, fields,
  48 + // and all contained boxes. This facilitates general parsing of the file.
  49 + //
43 // if size is 1 then the actual size is in the field largesize; 50 // if size is 1 then the actual size is in the field largesize;
44 // if size is 0, then this box is the last one in the file, and its contents 51 // if size is 0, then this box is the last one in the file, and its contents
45 // extend to the end of the file (normally only used for a Media Data Box) 52 // extend to the end of the file (normally only used for a Media Data Box)
46 - uint32_t size; 53 + uint32_t smallsize;
  54 + uint64_t largesize;
  55 +public:
  56 + // identifies the box type; standard boxes use a compact type, which is normally four printable
  57 + // characters, to permit ease of identification, and is shown so in the boxes below. User extensions use
  58 + // an extended type; in this case, the type field is set to ‘uuid’.
47 uint32_t type; 59 uint32_t type;
  60 + // For box 'uuid'.
  61 + uint8_t* usertype;
  62 +private:
  63 + std::vector<SrsMp4Box*> boxes;
  64 +private:
  65 + // The position at buffer to start demux the box.
  66 + int start_pos;
48 public: 67 public:
49 SrsMp4Box(); 68 SrsMp4Box();
50 virtual ~SrsMp4Box(); 69 virtual ~SrsMp4Box();
  70 +public:
  71 + // Get the size of box, whatever small or large size.
  72 + virtual uint64_t sz();
  73 + // Get the left space of box, for decoder.
  74 + virtual int left_space(SrsBuffer* buf);
  75 + /**
  76 + * Discovery the box from buffer.
  77 + * @param ppbox Output the discoveried box, which user must free it.
  78 + */
  79 + static int discovery(SrsBuffer* buf, SrsMp4Box** ppbox);
  80 +// Interface ISrsCodec
  81 +public:
  82 + virtual int nb_bytes();
  83 + virtual int encode(SrsBuffer* buf);
  84 + virtual int decode(SrsBuffer* buf);
  85 +protected:
  86 + virtual int encode_boxes(SrsBuffer* buf);
  87 + virtual int decode_boxes(SrsBuffer* buf);
  88 +// Sub classes can override these functions for special codec.
  89 +protected:
  90 + // The size of header, not including the contained boxes.
  91 + virtual int nb_header();
  92 + // It's not necessary to check the buffer, because we already know the size in parent function,
  93 + // so we have checked the buffer is ok to write.
  94 + virtual int encode_header(SrsBuffer* buf);
  95 + // It's not necessary to check the buffer, unless the box is not only determined by the verson.
  96 + // Generally, it's not necessary, that is, all boxes is determinated by version.
  97 + virtual int decode_header(SrsBuffer* buf);
51 }; 98 };
52 99
53 /** 100 /**
54 * 4.2 Object Structure 101 * 4.2 Object Structure
55 - * ISO_IEC_14496-12-base-format-2012.pdf, page 16 102 + * ISO_IEC_14496-12-base-format-2012.pdf, page 17
56 */ 103 */
57 class SrsMp4FullBox : public SrsMp4Box 104 class SrsMp4FullBox : public SrsMp4Box
58 { 105 {
@@ -64,6 +111,10 @@ public: @@ -64,6 +111,10 @@ public:
64 public: 111 public:
65 SrsMp4FullBox(); 112 SrsMp4FullBox();
66 virtual ~SrsMp4FullBox(); 113 virtual ~SrsMp4FullBox();
  114 +protected:
  115 + virtual int nb_header();
  116 + virtual int encode_header(SrsBuffer* buf);
  117 + virtual int decode_header(SrsBuffer* buf);
67 }; 118 };
68 119
69 /** 120 /**
@@ -88,6 +139,10 @@ private: @@ -88,6 +139,10 @@ private:
88 public: 139 public:
89 SrsMp4FileTypeBox(); 140 SrsMp4FileTypeBox();
90 virtual ~SrsMp4FileTypeBox(); 141 virtual ~SrsMp4FileTypeBox();
  142 +protected:
  143 + virtual int nb_header();
  144 + virtual int encode_header(SrsBuffer* buf);
  145 + virtual int decode_header(SrsBuffer* buf);
91 }; 146 };
92 147
93 /** 148 /**
@@ -101,11 +156,16 @@ public: @@ -101,11 +156,16 @@ public:
101 class SrsMp4MediaDataBox : public SrsMp4Box 156 class SrsMp4MediaDataBox : public SrsMp4Box
102 { 157 {
103 private: 158 private:
  159 + // the contained media data
104 int nb_data; 160 int nb_data;
105 uint8_t* data; 161 uint8_t* data;
106 public: 162 public:
107 SrsMp4MediaDataBox(); 163 SrsMp4MediaDataBox();
108 virtual ~SrsMp4MediaDataBox(); 164 virtual ~SrsMp4MediaDataBox();
  165 +protected:
  166 + virtual int nb_header();
  167 + virtual int encode_header(SrsBuffer* buf);
  168 + virtual int decode_header(SrsBuffer* buf);
109 }; 169 };
110 170
111 /** 171 /**
@@ -114,9 +174,16 @@ public: @@ -114,9 +174,16 @@ public:
114 */ 174 */
115 class SrsMp4FreeSpaceBox : public SrsMp4Box 175 class SrsMp4FreeSpaceBox : public SrsMp4Box
116 { 176 {
  177 +private:
  178 + int nb_data;
  179 + uint8_t* data;
117 public: 180 public:
118 SrsMp4FreeSpaceBox(); 181 SrsMp4FreeSpaceBox();
119 virtual ~SrsMp4FreeSpaceBox(); 182 virtual ~SrsMp4FreeSpaceBox();
  183 +protected:
  184 + virtual int nb_header();
  185 + virtual int encode_header(SrsBuffer* buf);
  186 + virtual int decode_header(SrsBuffer* buf);
120 }; 187 };
121 188
122 /** 189 /**
@@ -172,6 +239,10 @@ public: @@ -172,6 +239,10 @@ public:
172 public: 239 public:
173 SrsMp4MovieHeaderBox(); 240 SrsMp4MovieHeaderBox();
174 virtual ~SrsMp4MovieHeaderBox(); 241 virtual ~SrsMp4MovieHeaderBox();
  242 +protected:
  243 + virtual int nb_header();
  244 + virtual int encode_header(SrsBuffer* buf);
  245 + virtual int decode_header(SrsBuffer* buf);
175 }; 246 };
176 247
177 /** 248 /**
@@ -201,10 +272,6 @@ public: @@ -201,10 +272,6 @@ public:
201 // an integer that declares the most recent time the presentation was modified (in 272 // an integer that declares the most recent time the presentation was modified (in
202 // seconds since midnight, Jan. 1, 1904, in UTC time) 273 // seconds since midnight, Jan. 1, 1904, in UTC time)
203 uint64_t modification_time; 274 uint64_t modification_time;
204 - // an integer that specifies the time-scale for the entire presentation; this is the number of  
205 - // time units that pass in one second. For example, a time coordinate system that measures time in  
206 - // sixtieths of a second has a time scale of 60.  
207 - uint32_t timescale;  
208 // an integer that uniquely identifies this track over the entire life-time of this presentation. 275 // an integer that uniquely identifies this track over the entire life-time of this presentation.
209 // Track IDs are never re-used and cannot be zero. 276 // Track IDs are never re-used and cannot be zero.
210 uint32_t track_ID; 277 uint32_t track_ID;
@@ -244,6 +311,10 @@ public: @@ -244,6 +311,10 @@ public:
244 public: 311 public:
245 SrsMp4TrackHeaderBox(); 312 SrsMp4TrackHeaderBox();
246 virtual ~SrsMp4TrackHeaderBox(); 313 virtual ~SrsMp4TrackHeaderBox();
  314 +protected:
  315 + virtual int nb_header();
  316 + virtual int encode_header(SrsBuffer* buf);
  317 + virtual int decode_header(SrsBuffer* buf);
247 }; 318 };
248 319
249 /** 320 /**
@@ -282,6 +353,10 @@ public: @@ -282,6 +353,10 @@ public:
282 int16_t media_rate_fraction; 353 int16_t media_rate_fraction;
283 public: 354 public:
284 SrsMp4ElstEntry(); 355 SrsMp4ElstEntry();
  356 +public:
  357 + virtual int nb_header(uint32_t version);
  358 + virtual int encode_header(SrsBuffer* buf, uint32_t version);
  359 + virtual int decode_header(SrsBuffer* buf, uint32_t version);
285 }; 360 };
286 361
287 /** 362 /**
@@ -300,6 +375,10 @@ public: @@ -300,6 +375,10 @@ public:
300 public: 375 public:
301 SrsMp4EditListBox(); 376 SrsMp4EditListBox();
302 virtual ~SrsMp4EditListBox(); 377 virtual ~SrsMp4EditListBox();
  378 +protected:
  379 + virtual int nb_header();
  380 + virtual int encode_header(SrsBuffer* buf);
  381 + virtual int decode_header(SrsBuffer* buf);
303 }; 382 };
304 383
305 /** 384 /**
@@ -338,16 +417,29 @@ public: @@ -338,16 +417,29 @@ public:
338 // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the 417 // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the
339 // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. 418 // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s.
340 uint64_t duration; 419 uint64_t duration;
341 -public:  
342 - uint8_t pad:1; 420 +private:
343 // the language code for this media. See ISO 639-2/T for the set of three character 421 // the language code for this media. See ISO 639-2/T for the set of three character
344 // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code 422 // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
345 // is confined to being three lower-case letters, these values are strictly positive. 423 // is confined to being three lower-case letters, these values are strictly positive.
346 - uint16_t language:15; 424 + uint16_t language;
347 uint16_t pre_defined; 425 uint16_t pre_defined;
348 public: 426 public:
349 SrsMp4MediaHeaderBox(); 427 SrsMp4MediaHeaderBox();
350 virtual ~SrsMp4MediaHeaderBox(); 428 virtual ~SrsMp4MediaHeaderBox();
  429 +public:
  430 + // the language code for this media. See ISO 639-2/T for the set of three character
  431 + // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
  432 + // is confined to being three lower-case letters, these values are strictly positive.
  433 + virtual uint8_t language0();
  434 + virtual void set_language0(uint8_t v);
  435 + virtual uint8_t language1();
  436 + virtual void set_language1(uint8_t v);
  437 + virtual uint8_t language2();
  438 + virtual void set_language2(uint8_t v);
  439 +protected:
  440 + virtual int nb_header();
  441 + virtual int encode_header(SrsBuffer* buf);
  442 + virtual int decode_header(SrsBuffer* buf);
351 }; 443 };
352 444
353 /** 445 /**
@@ -371,6 +463,10 @@ public: @@ -371,6 +463,10 @@ public:
371 public: 463 public:
372 SrsMp4HandlerReferenceBox(); 464 SrsMp4HandlerReferenceBox();
373 virtual ~SrsMp4HandlerReferenceBox(); 465 virtual ~SrsMp4HandlerReferenceBox();
  466 +protected:
  467 + virtual int nb_header();
  468 + virtual int encode_header(SrsBuffer* buf);
  469 + virtual int decode_header(SrsBuffer* buf);
374 }; 470 };
375 471
376 /** 472 /**
@@ -403,6 +499,10 @@ public: @@ -403,6 +499,10 @@ public:
403 public: 499 public:
404 SrsMp4VideoMeidaHeaderBox(); 500 SrsMp4VideoMeidaHeaderBox();
405 virtual ~SrsMp4VideoMeidaHeaderBox(); 501 virtual ~SrsMp4VideoMeidaHeaderBox();
  502 +protected:
  503 + virtual int nb_header();
  504 + virtual int encode_header(SrsBuffer* buf);
  505 + virtual int decode_header(SrsBuffer* buf);
406 }; 506 };
407 507
408 /** 508 /**
@@ -421,6 +521,10 @@ public: @@ -421,6 +521,10 @@ public:
421 public: 521 public:
422 SrsMp4SoundMeidaHeaderBox(); 522 SrsMp4SoundMeidaHeaderBox();
423 virtual ~SrsMp4SoundMeidaHeaderBox(); 523 virtual ~SrsMp4SoundMeidaHeaderBox();
  524 +protected:
  525 + virtual int nb_header();
  526 + virtual int encode_header(SrsBuffer* buf);
  527 + virtual int decode_header(SrsBuffer* buf);
424 }; 528 };
425 529
426 /** 530 /**
@@ -445,6 +549,11 @@ public: @@ -445,6 +549,11 @@ public:
445 std::string location; 549 std::string location;
446 public: 550 public:
447 SrsMp4DataEntryBox(); 551 SrsMp4DataEntryBox();
  552 + virtual ~SrsMp4DataEntryBox();
  553 +protected:
  554 + virtual int nb_header();
  555 + virtual int encode_header(SrsBuffer* buf);
  556 + virtual int decode_header(SrsBuffer* buf);
448 }; 557 };
449 558
450 /** 559 /**
@@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox @@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox
455 { 564 {
456 public: 565 public:
457 SrsMp4DataEntryUrlBox(); 566 SrsMp4DataEntryUrlBox();
  567 + virtual ~SrsMp4DataEntryUrlBox();
458 }; 568 };
459 569
460 /** 570 /**
@@ -467,6 +577,11 @@ public: @@ -467,6 +577,11 @@ public:
467 std::string name; 577 std::string name;
468 public: 578 public:
469 SrsMp4DataEntryUrnBox(); 579 SrsMp4DataEntryUrnBox();
  580 + virtual ~SrsMp4DataEntryUrnBox();
  581 +protected:
  582 + virtual int nb_header();
  583 + virtual int encode_header(SrsBuffer* buf);
  584 + virtual int decode_header(SrsBuffer* buf);
470 }; 585 };
471 586
472 /** 587 /**
@@ -478,13 +593,18 @@ public: @@ -478,13 +593,18 @@ public:
478 */ 593 */
479 class SrsMp4DataReferenceBox : public SrsMp4FullBox 594 class SrsMp4DataReferenceBox : public SrsMp4FullBox
480 { 595 {
481 -public:  
482 - // an integer that counts the actual entries  
483 - uint32_t entry_count;  
484 - SrsMp4DataEntryBox* entries; 596 +private:
  597 + std::vector<SrsMp4DataEntryBox*> entries;
485 public: 598 public:
486 SrsMp4DataReferenceBox(); 599 SrsMp4DataReferenceBox();
487 virtual ~SrsMp4DataReferenceBox(); 600 virtual ~SrsMp4DataReferenceBox();
  601 +public:
  602 + virtual uint32_t entry_count();
  603 + virtual SrsMp4DataEntryBox* entry_at(int index);
  604 +protected:
  605 + virtual int nb_header();
  606 + virtual int encode_header(SrsBuffer* buf);
  607 + virtual int decode_header(SrsBuffer* buf);
488 }; 608 };
489 609
490 /** 610 /**
@@ -516,6 +636,10 @@ public: @@ -516,6 +636,10 @@ public:
516 public: 636 public:
517 SrsMp4SampleEntry(); 637 SrsMp4SampleEntry();
518 virtual ~SrsMp4SampleEntry(); 638 virtual ~SrsMp4SampleEntry();
  639 +protected:
  640 + virtual int nb_header();
  641 + virtual int encode_header(SrsBuffer* buf);
  642 + virtual int decode_header(SrsBuffer* buf);
519 }; 643 };
520 644
521 /** 645 /**
@@ -549,6 +673,10 @@ public: @@ -549,6 +673,10 @@ public:
549 public: 673 public:
550 SrsMp4VisualSampleEntry(); 674 SrsMp4VisualSampleEntry();
551 virtual ~SrsMp4VisualSampleEntry(); 675 virtual ~SrsMp4VisualSampleEntry();
  676 +protected:
  677 + virtual int nb_header();
  678 + virtual int encode_header(SrsBuffer* buf);
  679 + virtual int decode_header(SrsBuffer* buf);
552 }; 680 };
553 681
554 /** 682 /**
@@ -558,7 +686,7 @@ public: @@ -558,7 +686,7 @@ public:
558 class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry 686 class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry
559 { 687 {
560 public: 688 public:
561 - uint32_t reserved0[2]; 689 + uint64_t reserved0;
562 uint16_t channelcount; 690 uint16_t channelcount;
563 uint16_t samplesize; 691 uint16_t samplesize;
564 uint16_t pre_defined0; 692 uint16_t pre_defined0;
@@ -567,6 +695,10 @@ public: @@ -567,6 +695,10 @@ public:
567 public: 695 public:
568 SrsMp4AudioSampleEntry(); 696 SrsMp4AudioSampleEntry();
569 virtual ~SrsMp4AudioSampleEntry(); 697 virtual ~SrsMp4AudioSampleEntry();
  698 +protected:
  699 + virtual int nb_header();
  700 + virtual int encode_header(SrsBuffer* buf);
  701 + virtual int decode_header(SrsBuffer* buf);
570 }; 702 };
571 703
572 /** 704 /**
@@ -577,13 +709,18 @@ public: @@ -577,13 +709,18 @@ public:
577 */ 709 */
578 class SrsMp4SampleDescriptionBox : public SrsMp4FullBox 710 class SrsMp4SampleDescriptionBox : public SrsMp4FullBox
579 { 711 {
580 -public:  
581 - // an integer that gives the number of entries in the following table  
582 - uint32_t entry_count;  
583 - SrsMp4SampleEntry* entries; 712 +private:
  713 + std::vector<SrsMp4SampleEntry*> entries;
584 public: 714 public:
585 SrsMp4SampleDescriptionBox(); 715 SrsMp4SampleDescriptionBox();
586 virtual ~SrsMp4SampleDescriptionBox(); 716 virtual ~SrsMp4SampleDescriptionBox();
  717 +public:
  718 + virtual uint32_t entry_count();
  719 + virtual SrsMp4SampleEntry* entrie_at(int index);
  720 +protected:
  721 + virtual int nb_header();
  722 + virtual int encode_header(SrsBuffer* buf);
  723 + virtual int decode_header(SrsBuffer* buf);
587 }; 724 };
588 725
589 /** 726 /**
@@ -618,6 +755,10 @@ public: @@ -618,6 +755,10 @@ public:
618 public: 755 public:
619 SrsMp4DecodingTime2SampleBox(); 756 SrsMp4DecodingTime2SampleBox();
620 virtual ~SrsMp4DecodingTime2SampleBox(); 757 virtual ~SrsMp4DecodingTime2SampleBox();
  758 +protected:
  759 + virtual int nb_header();
  760 + virtual int encode_header(SrsBuffer* buf);
  761 + virtual int decode_header(SrsBuffer* buf);
621 }; 762 };
622 763
623 764
@@ -657,6 +798,10 @@ public: @@ -657,6 +798,10 @@ public:
657 public: 798 public:
658 SrsMp4CompositionTime2SampleBox(); 799 SrsMp4CompositionTime2SampleBox();
659 virtual ~SrsMp4CompositionTime2SampleBox(); 800 virtual ~SrsMp4CompositionTime2SampleBox();
  801 +protected:
  802 + virtual int nb_header();
  803 + virtual int encode_header(SrsBuffer* buf);
  804 + virtual int decode_header(SrsBuffer* buf);
660 }; 805 };
661 806
662 /** 807 /**
@@ -676,6 +821,10 @@ public: @@ -676,6 +821,10 @@ public:
676 public: 821 public:
677 SrsMp4SyncSampleBox(); 822 SrsMp4SyncSampleBox();
678 virtual ~SrsMp4SyncSampleBox(); 823 virtual ~SrsMp4SyncSampleBox();
  824 +protected:
  825 + virtual int nb_header();
  826 + virtual int encode_header(SrsBuffer* buf);
  827 + virtual int decode_header(SrsBuffer* buf);
679 }; 828 };
680 829
681 /** 830 /**
@@ -716,6 +865,10 @@ public: @@ -716,6 +865,10 @@ public:
716 public: 865 public:
717 SrsMp4Sample2ChunkBox(); 866 SrsMp4Sample2ChunkBox();
718 virtual ~SrsMp4Sample2ChunkBox(); 867 virtual ~SrsMp4Sample2ChunkBox();
  868 +protected:
  869 + virtual int nb_header();
  870 + virtual int encode_header(SrsBuffer* buf);
  871 + virtual int decode_header(SrsBuffer* buf);
719 }; 872 };
720 873
721 /** 874 /**
@@ -736,6 +889,10 @@ public: @@ -736,6 +889,10 @@ public:
736 public: 889 public:
737 SrsMp4ChunkOffsetBox(); 890 SrsMp4ChunkOffsetBox();
738 virtual ~SrsMp4ChunkOffsetBox(); 891 virtual ~SrsMp4ChunkOffsetBox();
  892 +protected:
  893 + virtual int nb_header();
  894 + virtual int encode_header(SrsBuffer* buf);
  895 + virtual int decode_header(SrsBuffer* buf);
739 }; 896 };
740 897
741 /** 898 /**
@@ -760,6 +917,10 @@ public: @@ -760,6 +917,10 @@ public:
760 public: 917 public:
761 SrsMp4SampleSizeBox(); 918 SrsMp4SampleSizeBox();
762 virtual ~SrsMp4SampleSizeBox(); 919 virtual ~SrsMp4SampleSizeBox();
  920 +protected:
  921 + virtual int nb_header();
  922 + virtual int encode_header(SrsBuffer* buf);
  923 + virtual int decode_header(SrsBuffer* buf);
763 }; 924 };
764 925
765 /** 926 /**
@@ -768,7 +929,13 @@ public: @@ -768,7 +929,13 @@ public:
768 class SrsMp4Decoder 929 class SrsMp4Decoder
769 { 930 {
770 private: 931 private:
  932 + // Underlayer reader.
771 ISrsReader* reader; 933 ISrsReader* reader;
  934 + // The stream used to demux the boxes.
  935 + // TODO: FIXME: refine for performance issue.
  936 + SrsSimpleStream* stream;
  937 + // Always load next box.
  938 + SrsMp4Box* next;
772 public: 939 public:
773 SrsMp4Decoder(); 940 SrsMp4Decoder();
774 virtual ~SrsMp4Decoder(); 941 virtual ~SrsMp4Decoder();
@@ -779,6 +946,8 @@ public: @@ -779,6 +946,8 @@ public:
779 * the decoder just read data from the reader. 946 * the decoder just read data from the reader.
780 */ 947 */
781 virtual int initialize(ISrsReader* r); 948 virtual int initialize(ISrsReader* r);
  949 +private:
  950 + virtual int load_next_box(SrsMp4Box** ppbox);
782 }; 951 };
783 952
784 #endif 953 #endif