diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 86e8fbc9c..fd4778e67 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -117,12 +117,9 @@ int srs_mp4_string_length(const string& v) void srs_mp4_string_write(SrsBuffer* buf, const string& v) { - // Nothing for empty string. - if (v.empty()) { - return; + if (!v.empty()) { + buf->write_bytes((char*)v.data(), (int)v.length()); } - - buf->write_bytes((char*)v.data(), (int)v.length()); buf->write_1bytes(0x00); } @@ -193,6 +190,19 @@ int SrsMp4Box::sz_header() return nb_header(); } +int SrsMp4Box::update_size() +{ + uint64_t size = nb_bytes(); + + if (size > 0xffffffff) { + largesize = size; + } else { + smallsize = (uint32_t)size; + } + + return (int)size; +} + int SrsMp4Box::left_space(SrsBuffer* buf) { int left = (int)sz() - (buf->pos() - start_pos); @@ -391,13 +401,8 @@ int SrsMp4Box::nb_bytes() srs_error_t SrsMp4Box::encode(SrsBuffer* buf) { srs_error_t err = srs_success; - - uint64_t size = nb_bytes(); - if (size > 0xffffffff) { - largesize = size; - } else { - smallsize = (uint32_t)size; - } + + update_size(); start_pos = buf->pos(); @@ -1161,7 +1166,7 @@ stringstream& SrsMp4TrunEntry::dumps(stringstream& ss, SrsMp4DumpContext dc) SrsMp4TrackFragmentRunBox::SrsMp4TrackFragmentRunBox() { type = SrsMp4BoxTypeTRUN; - sample_count = first_sample_flags = 0; + first_sample_flags = 0; data_offset = 0; } @@ -1201,7 +1206,8 @@ srs_error_t SrsMp4TrackFragmentRunBox::encode_header(SrsBuffer* buf) if ((err = SrsMp4FullBox::encode_header(buf)) != srs_success) { return srs_error_wrap(err, "encode header"); } - + + uint32_t sample_count = (uint32_t)entries.size(); buf->write_4bytes(sample_count); if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) { @@ -1230,7 +1236,7 @@ srs_error_t SrsMp4TrackFragmentRunBox::decode_header(SrsBuffer* buf) return srs_error_wrap(err, "decode header"); } - sample_count = buf->read_4bytes(); + uint32_t sample_count = buf->read_4bytes(); if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) { data_offset = buf->read_4bytes(); @@ -1258,7 +1264,8 @@ srs_error_t SrsMp4TrackFragmentRunBox::decode_header(SrsBuffer* buf) stringstream& SrsMp4TrackFragmentRunBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc) { SrsMp4FullBox::dumps_detail(ss, dc); - + + uint32_t sample_count = (uint32_t)entries.size(); ss << ", samples=" << sample_count; if ((flags&SrsMp4TrunFlagsDataOffset) == SrsMp4TrunFlagsDataOffset) { @@ -2201,7 +2208,7 @@ void SrsMp4MediaBox::set_minf(SrsMp4MediaInformationBox* v) boxes.push_back(v); } -SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() : creation_time(0), modification_time(0), duration(0) +SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() : creation_time(0), modification_time(0), timescale(0), duration(0) { type = SrsMp4BoxTypeMDHD; language = 0; @@ -2392,7 +2399,9 @@ stringstream& SrsMp4HandlerReferenceBox::dumps_detail(stringstream& ss, SrsMp4Du ss << ", "; srs_print_mp4_type(ss, (uint32_t)handler_type); - ss << ", " << name; + if (!name.empty()) { + ss << ", " << name; + } return ss; } @@ -4860,8 +4869,7 @@ srs_error_t SrsMp4SampleManager::write(SrsMp4MovieFragmentBox* moof, uint64_t& d trun->flags = SrsMp4TrunFlagsDataOffset | SrsMp4TrunFlagsSampleDuration | SrsMp4TrunFlagsSampleSize | SrsMp4TrunFlagsSampleFlag | SrsMp4TrunFlagsSampleCtsOffset; - trun->sample_count = (uint32_t)samples.size(); - + SrsMp4Sample* previous = NULL; vector::iterator it; diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index a0ae66149..a0f965456 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -202,6 +202,8 @@ public: // Get the size of header, without contained boxes. // @remark For mdat box, we must codec its header, use this instead of sz(). virtual int sz_header(); + // Update the size of box. + virtual int update_size(); // Get the left space of box, for decoder. virtual int left_space(SrsBuffer* buf); // Box type helper. @@ -507,7 +509,7 @@ class SrsMp4TrackFragmentRunBox : public SrsMp4FullBox public: // The number of samples being added in this run; also the number of rows in the following // table (the rows can be empty) - uint32_t sample_count; + //uint32_t sample_count; // The following are optional fields public: // added to the implicit or explicit data_offset established in the track fragment header. diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp index edcfa37e8..5f4ce4cb1 100644 --- a/trunk/src/utest/srs_utest_mp4.cpp +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -481,52 +481,758 @@ VOID TEST(KernelMp4Test, UUIDBoxEncode) VOID TEST(KernelMp4Test, FullBoxDump) { + srs_error_t err; + + if (true) { + uint8_t data[12]; + SrsBuffer b((char*)data, sizeof(data)); + b.write_4bytes(12); b.write_4bytes(SrsMp4BoxTypeMFHD); b.write_1bytes(1); b.write_3bytes(2); b.skip(-12); + + SrsMp4FullBox box; + HELPER_ASSERT_SUCCESS(box.decode(&b)); + EXPECT_EQ(1, box.version); + EXPECT_EQ(2, box.flags); + } + if (true) { - stringstream ss; - SrsMp4DumpContext dc; SrsMp4FileTypeBox box; box.major_brand = SrsMp4BoxBrandISO2; box.compatible_brands.push_back(SrsMp4BoxBrandISOM); + EXPECT_EQ(20, box.update_size()); + + stringstream ss; + SrsMp4DumpContext dc; box.dumps(ss, dc); string v = ss.str(); - EXPECT_STREQ("ftyp, 0B, brands:iso2,0(isom)\n", v.c_str()); + EXPECT_STREQ("ftyp, 20B, brands:iso2,0(isom)\n", v.c_str()); } if (true) { - stringstream ss; - SrsMp4DumpContext dc; SrsMp4FullBox box; box.type = SrsMp4BoxTypeFTYP; box.version = 1; box.flags = 0x02; + EXPECT_EQ(12, box.update_size()); + + stringstream ss; + SrsMp4DumpContext dc; box.dumps(ss, dc); string v = ss.str(); - EXPECT_STREQ("ftyp, 0B, FB(4B,V1,0x02)\n", v.c_str()); + EXPECT_STREQ("ftyp, 12B, FB(4B,V1,0x02)\n", v.c_str()); } if (true) { + SrsMp4FullBox box; + box.type = SrsMp4BoxTypeFTYP; + box.version = 1; + EXPECT_EQ(12, box.update_size()); + stringstream ss; SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("ftyp, 12B, FB(4B,V1,0x00)\n", v.c_str()); + } + + if (true) { SrsMp4FullBox box; box.type = SrsMp4BoxTypeFTYP; - box.version = 1; + EXPECT_EQ(12, box.update_size()); + + stringstream ss; + SrsMp4DumpContext dc; box.dumps(ss, dc); string v = ss.str(); - EXPECT_STREQ("ftyp, 0B, FB(4B,V1,0x00)\n", v.c_str()); + EXPECT_STREQ("ftyp, 12B, FB(4B)\n", v.c_str()); + } +} + +VOID TEST(KernelMp4Test, MFHDBox) +{ + srs_error_t err; + + if (true) { + uint8_t data[12+4]; + SrsBuffer b((char*)data, sizeof(data)); + b.write_4bytes(16); b.write_4bytes(SrsMp4BoxTypeMFHD); b.write_1bytes(0); b.write_3bytes(0); + b.write_4bytes(3); b.skip(-16); + + SrsMp4MovieFragmentHeaderBox box; + HELPER_ASSERT_SUCCESS(box.decode(&b)); + EXPECT_EQ(3, box.sequence_number); } if (true) { + SrsMp4MovieFragmentHeaderBox box; + box.sequence_number = 3; + EXPECT_EQ(16, box.update_size()); + stringstream ss; SrsMp4DumpContext dc; - SrsMp4FullBox box; - box.type = SrsMp4BoxTypeFTYP; box.dumps(ss, dc); string v = ss.str(); - EXPECT_STREQ("ftyp, 0B, FB(4B)\n", v.c_str()); + EXPECT_STREQ("mfhd, 16B, FB(4B), sequence=3\n", v.c_str()); + } + + SrsMp4TrackFragmentBox box; + EXPECT_TRUE(NULL == box.tfhd()); + EXPECT_TRUE(NULL == box.tfdt()); +} + +VOID TEST(KernelMp4Test, TFHDBox) +{ + srs_error_t err; + + if (true) { + char buf[12+4]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentHeaderBox box; + box.track_id = 100; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tfhd, 16B, FB(4B), track=100\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(100, box.track_id); + } + } + + if (true) { + char buf[12+28]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentHeaderBox box; + box.track_id = 100; + box.flags = SrsMp4TfhdFlagsBaseDataOffset | SrsMp4TfhdFlagsSampleDescriptionIndex + | SrsMp4TfhdFlagsDefaultSampleDuration | SrsMp4TfhdFlagsDefautlSampleSize + | SrsMp4TfhdFlagsDefaultSampleFlags | SrsMp4TfhdFlagsDurationIsEmpty + | SrsMp4TfhdFlagsDefaultBaseIsMoof; + box.base_data_offset = 10; + box.sample_description_index = 11; + box.default_sample_duration = 12; + box.default_sample_size = 13; + box.default_sample_flags = 14; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tfhd, 40B, FB(4B,V0,0x3003b), track=100, bdo=10, sdi=11, dsu=12, dss=13, dsf=14, empty-duration, moof-base\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(100, box.track_id); + EXPECT_EQ(box.base_data_offset, 10); + EXPECT_EQ(box.sample_description_index, 11); + EXPECT_EQ(box.default_sample_duration, 12); + EXPECT_EQ(box.default_sample_size, 13); + EXPECT_EQ(box.default_sample_flags, 14); + } + } +} + +VOID TEST(KernelMp4Test, TFDTBox) +{ + srs_error_t err; + + if (true) { + char buf[12+4]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentDecodeTimeBox box; + box.base_media_decode_time = 100; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tfdt, 16B, FB(4B), bmdt=100\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentDecodeTimeBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(100, box.base_media_decode_time); + } + } + + if (true) { + char buf[12+8]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentDecodeTimeBox box; + box.version = 1; + box.base_media_decode_time = 100; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tfdt, 20B, FB(4B,V1,0x00), bmdt=100\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentDecodeTimeBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(100, box.base_media_decode_time); + } + } +} + +VOID TEST(KernelMp4Test, TRUNBox) +{ + srs_error_t err; + + if (true) { + char buf[12+4]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentRunBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("trun, 16B, FB(4B), samples=0\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentDecodeTimeBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[12+8]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackFragmentRunBox box; + box.flags = SrsMp4TrunFlagsSampleDuration; + + SrsMp4TrunEntry* entry = new SrsMp4TrunEntry(&box); + entry->sample_duration = 1000; + box.entries.push_back(entry); + + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("trun, 20B, FB(4B,V0,0x100), samples=1\n duration=1000\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackFragmentRunBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + ASSERT_EQ(1, box.entries.size()); + + SrsMp4TrunEntry* entry = box.entries.at(0); + EXPECT_EQ(1000, entry->sample_duration); + } + } +} + +VOID TEST(KernelMp4Test, FreeBox) +{ + srs_error_t err; + + if (true) { + char buf[8+4]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4FreeSpaceBox box(SrsMp4BoxTypeFREE); + box.data.resize(4); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("free, 12B, free 4B\n 0x00, 0x00, 0x00, 0x00\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4FreeSpaceBox box(SrsMp4BoxTypeSKIP); + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(4, box.data.size()); + } + } +} + +VOID TEST(KernelMp4Test, MOOVBox) +{ + srs_error_t err; + + if (true) { + char buf[8]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4MovieBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("moov, 8B\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4MovieBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4MovieBox box; + EXPECT_TRUE(NULL == box.mvhd()); + EXPECT_TRUE(NULL == box.mvex()); + EXPECT_TRUE(NULL == box.video()); + EXPECT_TRUE(NULL == box.audio()); + EXPECT_EQ(0, box.nb_vide_tracks()); + EXPECT_EQ(0, box.nb_soun_tracks()); + + SrsMp4MovieHeaderBox* mvhd = new SrsMp4MovieHeaderBox(); + box.set_mvhd(mvhd); + EXPECT_TRUE(mvhd == box.mvhd()); + + SrsMp4MovieExtendsBox* mvex = new SrsMp4MovieExtendsBox(); + box.set_mvex(mvex); + EXPECT_TRUE(mvex == box.mvex()); + + SrsMp4TrackBox* video = new SrsMp4TrackBox(); + if (true) { + SrsMp4MediaBox* media = new SrsMp4MediaBox(); + SrsMp4HandlerReferenceBox* hdr = new SrsMp4HandlerReferenceBox(); + hdr->handler_type = SrsMp4HandlerTypeVIDE; + media->set_hdlr(hdr); + video->set_mdia(media); + } + box.add_trak(video); + EXPECT_TRUE(video == box.video()); + EXPECT_EQ(1, box.nb_vide_tracks()); + + SrsMp4TrackBox* audio = new SrsMp4TrackBox(); + if (true) { + SrsMp4MediaBox* media = new SrsMp4MediaBox(); + SrsMp4HandlerReferenceBox* hdr = new SrsMp4HandlerReferenceBox(); + hdr->handler_type = SrsMp4HandlerTypeSOUN; + media->set_hdlr(hdr); + audio->set_mdia(media); + } + box.add_trak(audio); + EXPECT_TRUE(audio == box.audio()); + EXPECT_EQ(1, box.nb_soun_tracks()); + } +} + +VOID TEST(KernelMp4Test, TREXBox) +{ + srs_error_t err; + + if (true) { + char buf[12+20]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackExtendsBox box; + box.track_ID = 1; box.default_sample_description_index = 2; box.default_sample_size = 3; + box.default_sample_duration = 4; box.default_sample_flags = 5; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("trex, 32B, FB(4B), track=#1, default-sample(index:2, size:3, duration:4, flags:5)\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackExtendsBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(box.track_ID, 1); + EXPECT_EQ(box.default_sample_description_index, 2); + EXPECT_EQ(box.default_sample_size, 3); + EXPECT_EQ(box.default_sample_duration, 4); + EXPECT_EQ(box.default_sample_flags, 5); + } + } + + SrsMp4MovieExtendsBox box; + EXPECT_TRUE(NULL == box.trex()); + + SrsMp4TrackExtendsBox* trex = new SrsMp4TrackExtendsBox(); + box.set_trex(trex); + EXPECT_TRUE(trex == box.trex()); +} + +VOID TEST(KernelMp4Test, TKHDBox) +{ + srs_error_t err; + + if (true) { + char buf[12+20+60]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackHeaderBox box; + box.track_ID = 1; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tkhd, 92B, FB(4B,V0,0x03), track #1, 0TBN, size=0x0\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(box.track_ID, 1); + } + } + + if (true) { + char buf[12+32+60]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4TrackHeaderBox box; + box.version = 1; + box.track_ID = 1; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("tkhd, 104B, FB(4B,V1,0x03), track #1, 0TBN, size=0x0\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4TrackHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(box.track_ID, 1); + } + } +} + +VOID TEST(KernelMp4Test, ELSTBox) +{ + srs_error_t err; + + if (true) { + char buf[12+4]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4EditListBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("elst, 16B, FB(4B), 0 childs\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4EditListBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[12+4+12]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4EditListBox box; + if (true) { + SrsMp4ElstEntry entry; + box.entries.push_back(entry); + } + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("elst, 28B, FB(4B), 1 childs(+)\n Entry, 0TBN, start=0TBN, rate=0,0\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4EditListBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4MediaBox box; + SrsMp4HandlerReferenceBox* hdlr = new SrsMp4HandlerReferenceBox(); + box.set_hdlr(hdlr); + EXPECT_TRUE(hdlr == box.hdlr()); + } +} + +VOID TEST(KernelMp4Test, MDHDBox) +{ + srs_error_t err; + + if (true) { + char buf[12+20]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4MediaHeaderBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("mdhd, 32B, FB(4B), TBN=0, 0TBN\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4MediaHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[12+20]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4MediaHeaderBox box; + box.set_language0('C'); + box.set_language1('N'); + box.set_language2('E'); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("mdhd, 32B, FB(4B), TBN=0, 0TBN, LANG=cne\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4MediaHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4MediaHeaderBox box; + + box.set_language0('C'); + EXPECT_EQ('c', box.language0()); + + box.set_language1('N'); + EXPECT_EQ('n', box.language1()); + + box.set_language2('E'); + EXPECT_EQ('e', box.language2()); + } + + if (true) { + SrsMp4HandlerReferenceBox box; + box.handler_type = SrsMp4HandlerTypeVIDE; + EXPECT_TRUE(box.is_video()); + } + + if (true) { + SrsMp4HandlerReferenceBox box; + box.handler_type = SrsMp4HandlerTypeSOUN; + EXPECT_TRUE(box.is_audio()); + } +} + +VOID TEST(KernelMp4Test, HDLRBox) +{ + srs_error_t err; + + if (true) { + char buf[12+21]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4HandlerReferenceBox box; + box.handler_type = SrsMp4HandlerTypeSOUN; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("hdlr, 33B, FB(4B), soun\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4HandlerReferenceBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(SrsMp4HandlerTypeSOUN, box.handler_type); + } + } + + if (true) { + char buf[12+21]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4HandlerReferenceBox box; + box.handler_type = SrsMp4HandlerTypeVIDE; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("hdlr, 33B, FB(4B), vide\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4HandlerReferenceBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(SrsMp4HandlerTypeVIDE, box.handler_type); + } + } + + if (true) { + char buf[12+24]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4HandlerReferenceBox box; + box.handler_type = SrsMp4HandlerTypeVIDE; + box.name = "srs"; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps(ss, dc); + + string v = ss.str(); + EXPECT_STREQ("hdlr, 36B, FB(4B), vide, srs\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4HandlerReferenceBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + EXPECT_EQ(SrsMp4HandlerTypeVIDE, box.handler_type); + } + } + + if (true) { + SrsMp4MediaInformationBox box; + SrsMp4VideoMeidaHeaderBox* vmhd = new SrsMp4VideoMeidaHeaderBox(); + box.set_vmhd(vmhd); + EXPECT_TRUE(vmhd == box.vmhd()); + } + + if (true) { + SrsMp4MediaInformationBox box; + SrsMp4SoundMeidaHeaderBox* smhd = new SrsMp4SoundMeidaHeaderBox(); + box.set_smhd(smhd); + EXPECT_TRUE(smhd == box.smhd()); + } + + if (true) { + SrsMp4MediaInformationBox box; + SrsMp4DataInformationBox* dinf = new SrsMp4DataInformationBox(); + box.set_dinf(dinf); + EXPECT_TRUE(dinf == box.dinf()); + } + + if (true) { + SrsMp4DataInformationBox box; + SrsMp4DataReferenceBox* dref = new SrsMp4DataReferenceBox(); + box.set_dref(dref); + EXPECT_TRUE(dref == box.dref()); } }