From adad90d3168fbe54a53604b421a5be62c3420573 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 15:15:56 +0800 Subject: [PATCH 1/6] Refactor the mock file reader/writer --- trunk/src/kernel/srs_kernel_mp4.cpp | 11 +- trunk/src/utest/srs_utest_kernel.cpp | 335 +++++++++++++++------------ trunk/src/utest/srs_utest_kernel.hpp | 40 +++- trunk/src/utest/srs_utest_mp4.cpp | 29 +++ 4 files changed, 250 insertions(+), 165 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index fd4778e67..ce7a36a25 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -371,8 +371,9 @@ srs_error_t SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) case SrsMp4BoxTypeUUID: box = new SrsMp4FreeSpaceBox(type); break; default: - err = srs_error_new(ERROR_MP4_BOX_ILLEGAL_TYPE, "illegal box type=%d", type); - break; + box = new SrsMp4FreeSpaceBox(type); break; + //err = srs_error_new(ERROR_MP4_BOX_ILLEGAL_TYPE, "illegal box type=%d", type); + //break; } if (box) { @@ -2619,11 +2620,11 @@ srs_error_t SrsMp4DataEntryUrlBox::encode_header(SrsBuffer* buf) if ((err = SrsMp4FullBox::encode_header(buf)) != srs_success) { return srs_error_wrap(err, "encode header"); } - + if (!location.empty()) { srs_mp4_string_write(buf, location); } - + return err; } @@ -2634,7 +2635,7 @@ srs_error_t SrsMp4DataEntryUrlBox::decode_header(SrsBuffer* buf) if ((err = SrsMp4FullBox::decode_header(buf)) != srs_success) { return srs_error_wrap(err, "decode header"); } - + // a 24-bit integer with flags; one flag is defined (x000001) which means that the media // data is in the same file as the Movie Box containing this data reference. if (flags == 0x01) { diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 9816da8c7..b6784b562 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -40,37 +40,121 @@ using namespace std; #define MAX_MOCK_DATA_SIZE 1024 * 1024 +MockSrsFile::MockSrsFile() +{ + _buf = new SrsBuffer(_data.bytes(), _data.length()); +} + +MockSrsFile::~MockSrsFile() +{ + close(); +} + +srs_error_t MockSrsFile::open(std::string /*file*/) +{ + srs_error_t err = srs_success; + return err; +} + +void MockSrsFile::close() +{ + srs_freep(_buf); +} + +srs_error_t MockSrsFile::write(void* data, size_t count, ssize_t* pnwrite) +{ + srs_error_t err = srs_success; + + for (;;) { + if (_buf->left() >= (int)count) { + _buf->write_bytes((char*)data, count); + break; + } + + // Append enough data and rebuild the buffer. + off_t pos = _buf->pos(); + _data.append((const char*)data, count - _buf->left()); + srs_freep(_buf); + _buf = new SrsBuffer(_data.bytes(), _data.length()); + lseek(pos, SEEK_SET, NULL); + } + + if (pnwrite) { + *pnwrite = count; + } + + return err; +} + +srs_error_t MockSrsFile::read(void* data, size_t count, ssize_t* pnread) +{ + srs_error_t err = srs_success; + + int limit = srs_min(_buf->left(), (int)count); + + if (limit <= 0) { + return srs_error_new(-1, "EOF"); + } + + _buf->read_bytes((char*)data, limit); + + if (pnread) { + *pnread = limit; + } + + return err; +} + +srs_error_t MockSrsFile::lseek(off_t offset, int whence, off_t* seeked) +{ + srs_error_t err = srs_success; + + if (whence == SEEK_SET) { + if (offset > _data.length()) { + return srs_error_new(-1, "Overflow"); + } + if (_buf->data()) { + _buf->skip(offset - _buf->pos()); + } + } else if (whence == SEEK_CUR) { + } else if (whence == SEEK_END) { + if (_buf->data()) { + _buf->skip(_buf->left()); + } + } + + if (seeked) { + *seeked = (off_t)_buf->pos(); + } + return err; +} + MockSrsFileWriter::MockSrsFileWriter() { - size = MAX_MOCK_DATA_SIZE; - data = new char[size]; - offset = 0; err = srs_success; error_offset = -1; opened = false; + uf = new MockSrsFile(); } MockSrsFileWriter::~MockSrsFileWriter() { srs_freep(err); - srs_freep(data); + srs_freep(uf); } -srs_error_t MockSrsFileWriter::open(string /*file*/) +srs_error_t MockSrsFileWriter::open(string file) { - offset = 0; - if (err != srs_success) { return srs_error_copy(err); } - opened = true; - return srs_success; + return uf->open(file); } void MockSrsFileWriter::close() { - opened = false; + uf->close(); } bool MockSrsFileWriter::is_open() @@ -80,103 +164,89 @@ bool MockSrsFileWriter::is_open() void MockSrsFileWriter::seek2(int64_t offset) { - this->offset = offset; + lseek(offset, SEEK_SET, NULL); } int64_t MockSrsFileWriter::tellg() { + off_t offset = 0; + lseek(0, SEEK_CUR, &offset); + return (int64_t)offset; +} + +int64_t MockSrsFileWriter::filesize() +{ + int64_t cur = tellg(); + + off_t offset = 0; + lseek(0, SEEK_END, &offset); + + seek2(cur); return offset; } +char* MockSrsFileWriter::data() +{ + return uf->_data.bytes(); +} + srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) { if (err != srs_success) { return srs_error_copy(err); } - - int nwriten = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count); - if (nwriten > 0) { - memcpy(data + offset, buf, nwriten); + + if (error_offset >= 0 && tellg() >= error_offset) { + return srs_error_new(-1, "overflow"); } - if (pnwrite) { - *pnwrite = nwriten; - } - - offset += nwriten; - size = srs_max(size, offset); - - if (error_offset >= 0 && offset > error_offset) { - return srs_error_new(-1, "exceed offset"); - } - - return srs_success; + return uf->write(buf, count, pnwrite); } -srs_error_t MockSrsFileWriter::lseek(off_t _offset, int whence, off_t* seeked) +srs_error_t MockSrsFileWriter::lseek(off_t offset, int whence, off_t* seeked) { - if (whence == SEEK_SET) { - offset = (int)_offset; + if (error_offset >= 0 && offset > error_offset) { + return srs_error_new(-1, "overflow"); } - if (whence == SEEK_CUR) { - offset += (int)_offset; - } - if (whence == SEEK_END) { - offset = (int)(size + _offset); - } - - if (seeked) { - *seeked = (off_t)offset; - } - - return srs_success; + return uf->lseek(offset, whence, seeked); } void MockSrsFileWriter::mock_reset_offset() { - offset = 0; + seek2(0); } MockSrsFileReader::MockSrsFileReader() { - data = new char[MAX_MOCK_DATA_SIZE]; - size = 0; - offset = 0; opened = false; seekable = true; + uf = new MockSrsFile(); } MockSrsFileReader::MockSrsFileReader(const char* src, int nb_src) { - data = NULL; - size = nb_src; - - if (nb_src > 0) { - data = new char[nb_src]; - memcpy(data, src, nb_src); - } - - offset = 0; opened = false; seekable = true; + uf = new MockSrsFile(); + + uf->write((void*)src, nb_src, NULL); + uf->lseek(0, SEEK_SET, NULL); } MockSrsFileReader::~MockSrsFileReader() { - srs_freep(data); + srs_freep(uf); } -srs_error_t MockSrsFileReader::open(string /*file*/) +srs_error_t MockSrsFileReader::open(string file) { - offset = 0; opened = true; - - return srs_success; + return uf->open(file); } void MockSrsFileReader::close() { - offset = 0; + uf->close(); } bool MockSrsFileReader::is_open() @@ -186,77 +256,56 @@ bool MockSrsFileReader::is_open() int64_t MockSrsFileReader::tellg() { + off_t offset = 0; + lseek(0, SEEK_CUR, &offset); return offset; } void MockSrsFileReader::skip(int64_t _size) { - offset += _size; + int64_t offset = tellg() + _size; + lseek(offset, SEEK_SET, NULL); } int64_t MockSrsFileReader::seek2(int64_t _offset) { - if (!seekable) { - return -1; - } - - offset = (int)_offset; + off_t offset = 0; + lseek(_offset, SEEK_SET, &offset); return offset; } int64_t MockSrsFileReader::filesize() { - return size; + int64_t cur = tellg(); + + off_t offset = 0; + lseek(0, SEEK_END, &offset); + + seek2(cur); + return offset; } srs_error_t MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread) { - int s = srs_min(size - offset, (int)count); - - if (s <= 0) { - return srs_error_new(ERROR_SYSTEM_FILE_EOF, "EOF left=%d", s); - } - - memcpy(buf, data + offset, s); - offset += s; - - if (pnread) { - *pnread = s; - } - - return srs_success; + return uf->read(buf, count, pnread); } -srs_error_t MockSrsFileReader::lseek(off_t _offset, int whence, off_t* seeked) +srs_error_t MockSrsFileReader::lseek(off_t offset, int whence, off_t* seeked) { - if (whence == SEEK_SET) { - offset = (int)_offset; + if (!seekable) { + return srs_error_new(-1, "unseekable"); } - if (whence == SEEK_CUR) { - offset += (int)_offset; - } - if (whence == SEEK_END) { - offset = (int)(size + _offset); - } - - if (seeked) { - *seeked = (off_t)offset; - } - - return srs_success; + return uf->lseek(offset, whence, seeked); } -void MockSrsFileReader::mock_append_data(const char* _data, int _size) +void MockSrsFileReader::mock_append_data(const char* data, int size) { - int s = srs_min(MAX_MOCK_DATA_SIZE - offset, _size); - memcpy(data + offset, _data, s); - size += s; - offset += s; + uf->write((void*)data, size, NULL); } void MockSrsFileReader::mock_reset_offset() { - offset = 0; + seek2(0); } MockBufferReader::MockBufferReader(const char* data) @@ -596,10 +645,10 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteHeader) char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 }; EXPECT_TRUE(ERROR_SUCCESS == enc.write_header()); - ASSERT_TRUE(9 + 4 == fs.offset); + ASSERT_TRUE(9 + 4 == fs.tellg()); - EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9)); - EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4)); + EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data(), 9)); + EXPECT_TRUE(srs_bytes_equals(pts, fs.data() + 9, 4)); // customer header flv_header[3] = 0xF0; @@ -609,10 +658,10 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteHeader) fs.mock_reset_offset(); EXPECT_TRUE(ERROR_SUCCESS == enc.write_header(flv_header)); - ASSERT_TRUE(9 + 4 == fs.offset); + ASSERT_TRUE(9 + 4 == fs.tellg()); - EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9)); - EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4)); + EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data(), 9)); + EXPECT_TRUE(srs_bytes_equals(pts, fs.data() + 9, 4)); } /** @@ -641,12 +690,12 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteMetadata) char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; ASSERT_TRUE(ERROR_SUCCESS == enc.write_metadata(18, md, 8)); - ASSERT_TRUE(11 + 8 + 4 == fs.offset); + ASSERT_TRUE(11 + 8 + 4 == fs.tellg()); - EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); - EXPECT_TRUE(srs_bytes_equals(md, fs.data + 11, 8)); + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data(), 11)); + EXPECT_TRUE(srs_bytes_equals(md, fs.data() + 11, 8)); EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. - EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 19, 4)); + EXPECT_TRUE(srs_bytes_equals(pts, fs.data() + 19, 4)); } /** @@ -675,12 +724,12 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteAudio) char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; ASSERT_TRUE(ERROR_SUCCESS == enc.write_audio(0x30, audio, 8)); - ASSERT_TRUE(11 + 8 + 4 == fs.offset); + ASSERT_TRUE(11 + 8 + 4 == fs.tellg()); - EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); - EXPECT_TRUE(srs_bytes_equals(audio, fs.data + 11, 8)); + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data(), 11)); + EXPECT_TRUE(srs_bytes_equals(audio, fs.data() + 11, 8)); EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. - EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); + EXPECT_TRUE(srs_bytes_equals(pts, fs.data() + 11 + 8, 4)); } /** @@ -709,12 +758,12 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteVideo) char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; ASSERT_TRUE(ERROR_SUCCESS == enc.write_video(0x30, video, 8)); - ASSERT_TRUE(11 + 8 + 4 == fs.offset); + ASSERT_TRUE(11 + 8 + 4 == fs.tellg()); - EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11)); - EXPECT_TRUE(srs_bytes_equals(video, fs.data + 11, 8)); + EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data(), 11)); + EXPECT_TRUE(srs_bytes_equals(video, fs.data() + 11, 8)); EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled. - EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); + EXPECT_TRUE(srs_bytes_equals(pts, fs.data() + 11 + 8, 4)); } /** @@ -1478,13 +1527,13 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSeek) (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. }; fs.mock_append_data(tag_header, 11); - EXPECT_TRUE(11 == fs.offset); + EXPECT_TRUE(11 == fs.tellg()); EXPECT_TRUE(ERROR_SUCCESS == dec.seek2(0)); - EXPECT_TRUE(0 == fs.offset); + EXPECT_TRUE(0 == fs.tellg()); EXPECT_TRUE(ERROR_SUCCESS == dec.seek2(5)); - EXPECT_TRUE(5 == fs.offset); + EXPECT_TRUE(5 == fs.tellg()); } VOID TEST(KernelFLVTest, CoverFLVVodError) @@ -2805,15 +2854,15 @@ VOID TEST(KernelAACTest, TransmaxRTMP2AAC) EXPECT_TRUE(srs_success == err); srs_freep(err); - EXPECT_EQ(8, f.offset); - EXPECT_EQ((char)0xff, f.data[0]); - EXPECT_EQ((char)0xf1, f.data[1]); - EXPECT_EQ((char)0x50, f.data[2]); - EXPECT_EQ((char)0x80, f.data[3]); - EXPECT_EQ((char)0x01, f.data[4]); - EXPECT_EQ((char)0x00, f.data[5]); - EXPECT_EQ((char)0xfc, f.data[6]); - EXPECT_EQ((char)0xcb, f.data[7]); + EXPECT_EQ(8, f.tellg()); + EXPECT_EQ((char)0xff, f.data()[0]); + EXPECT_EQ((char)0xf1, f.data()[1]); + EXPECT_EQ((char)0x50, f.data()[2]); + EXPECT_EQ((char)0x80, f.data()[3]); + EXPECT_EQ((char)0x01, f.data()[4]); + EXPECT_EQ((char)0x00, f.data()[5]); + EXPECT_EQ((char)0xfc, f.data()[6]); + EXPECT_EQ((char)0xcb, f.data()[7]); } if (true) { @@ -3915,7 +3964,7 @@ VOID TEST(KernelFLVTest, CoverAll) SrsSharedPtrMessage* msgs = &m; EXPECT_TRUE(srs_success == mux.write_tags(&msgs, 1)); - EXPECT_EQ(16, f.offset); + EXPECT_EQ(16, f.tellg()); } #endif } @@ -3992,7 +4041,7 @@ VOID TEST(KernelMp3Test, CoverAll) EXPECT_TRUE(srs_success == m.initialize(&f)); EXPECT_TRUE(srs_success == m.write_header()); - EXPECT_EQ((char)0x49, f.data[0]); + EXPECT_EQ((char)0x49, f.data()[0]); } if (true) { @@ -4002,7 +4051,7 @@ VOID TEST(KernelMp3Test, CoverAll) EXPECT_TRUE(srs_success == m.initialize(&f)); EXPECT_TRUE(srs_success == m.write_audio(0, (char*)"\x20\x01", 2)); - EXPECT_EQ((char)0x01, f.data[0]); + EXPECT_EQ((char)0x01, f.data()[0]); } if (true) { @@ -4020,16 +4069,6 @@ VOID TEST(KernelMp3Test, CoverAll) srs_freep(err); } - if (true) { - SrsMp3Transmuxer m; - MockSrsFileWriter f; - f.offset = -1; - - srs_error_t err = m.initialize(&f); - EXPECT_TRUE(srs_success != err); - srs_freep(err); - } - if (true) { SrsMp3Transmuxer m; MockSrsFileWriter f; @@ -4641,7 +4680,7 @@ VOID TEST(KernelMP4Test, CoverMP4Codec) EXPECT_TRUE(srs_success == enc.flush()); if (true) { - MockSrsFileReader fr((const char*)f.data, f.size); + MockSrsFileReader fr((const char*)f.data(), f.filesize()); SrsMp4Decoder dec; EXPECT_TRUE(srs_success == dec.initialize(&fr)); @@ -4655,7 +4694,7 @@ VOID TEST(KernelMP4Test, CoverMP4Codec) if (true) { SrsMp4BoxReader br; - MockSrsFileReader fr((const char*)f.data, f.size); + MockSrsFileReader fr((const char*)f.data(), f.filesize()); EXPECT_TRUE(srs_success == br.initialize(&fr)); SrsSimpleStream stream; diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp index fc59cf2bb..6db2b7d35 100644 --- a/trunk/src/utest/srs_utest_kernel.hpp +++ b/trunk/src/utest/srs_utest_kernel.hpp @@ -34,24 +34,29 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include -class MockBufferReader: public ISrsReader +class MockSrsFile { -private: - std::string str; public: - MockBufferReader(const char* data); - virtual ~MockBufferReader(); + SrsBuffer* _buf; + SrsSimpleStream _data; public: - virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); + MockSrsFile(); + virtual ~MockSrsFile(); +public: + virtual srs_error_t open(std::string file); + virtual void close(); +public: + virtual srs_error_t write(void* data, size_t count, ssize_t* pnwrite); + virtual srs_error_t read(void* data, size_t count, ssize_t* pnread); + virtual srs_error_t lseek(off_t offset, int whence, off_t* seeked); }; class MockSrsFileWriter : public SrsFileWriter { public: - char* data; - int size; - int offset; + MockSrsFile* uf; srs_error_t err; // Error if exceed this offset. int error_offset; @@ -67,6 +72,8 @@ public: virtual bool is_open(); virtual void seek2(int64_t offset); virtual int64_t tellg(); + virtual int64_t filesize(); + virtual char* data(); public: virtual srs_error_t write(void* buf, size_t count, ssize_t* pnwrite); virtual srs_error_t lseek(off_t offset, int whence, off_t* seeked); @@ -78,9 +85,7 @@ public: class MockSrsFileReader : public SrsFileReader { public: - char* data; - int size; - int offset; + MockSrsFile* uf; bool opened; // Could seek. bool seekable; @@ -107,6 +112,17 @@ public: void mock_reset_offset(); }; +class MockBufferReader: public ISrsReader +{ +private: + std::string str; +public: + MockBufferReader(const char* data); + virtual ~MockBufferReader(); +public: + virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); +}; + class MockSrsCodec : public ISrsCodec { public: diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp index 5f4ce4cb1..12e87a1f1 100644 --- a/trunk/src/utest/srs_utest_mp4.cpp +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -1236,3 +1236,32 @@ VOID TEST(KernelMp4Test, HDLRBox) } } +VOID TEST(KernelMp4Test, URLBox) +{ + srs_error_t err; + + if (true) { + char buf[12+1]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DataEntryUrlBox 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("url , 13B, FB(4B,V0,0x01), URL: Same file\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DataEntryUrlBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } +} + From 9cb24491755d26bbd47e16153b80e3972e3b0cad Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 15:35:45 +0800 Subject: [PATCH 2/6] Fix mp4 url/urn bug. --- trunk/src/kernel/srs_kernel_buffer.cpp | 2 ++ trunk/src/kernel/srs_kernel_mp4.cpp | 23 +++++++---------------- trunk/src/kernel/srs_kernel_ts.cpp | 2 +- trunk/src/utest/srs_utest_mp4.cpp | 4 ++-- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_buffer.cpp b/trunk/src/kernel/srs_kernel_buffer.cpp index 0f0b9e1dc..e6fcfe1fa 100644 --- a/trunk/src/kernel/srs_kernel_buffer.cpp +++ b/trunk/src/kernel/srs_kernel_buffer.cpp @@ -94,6 +94,8 @@ bool SrsBuffer::require(int required_size) void SrsBuffer::skip(int size) { srs_assert(p); + srs_assert(p + size >= bytes); + srs_assert(p + size <= bytes + nb_bytes); p += size; } diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index ce7a36a25..8f19b2cb8 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -2599,11 +2599,6 @@ SrsMp4DataEntryUrlBox::~SrsMp4DataEntryUrlBox() int SrsMp4DataEntryUrlBox::nb_header() { - // a 24-bit integer with flags; one flag is defined (x000001) which means that the media - // data is in the same file as the Movie Box containing this data reference. - if (location.empty()) { - return SrsMp4FullBox::nb_header(); - } return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location); } @@ -2621,9 +2616,7 @@ srs_error_t SrsMp4DataEntryUrlBox::encode_header(SrsBuffer* buf) return srs_error_wrap(err, "encode header"); } - if (!location.empty()) { - srs_mp4_string_write(buf, location); - } + srs_mp4_string_write(buf, location); return err; } @@ -2635,12 +2628,6 @@ srs_error_t SrsMp4DataEntryUrlBox::decode_header(SrsBuffer* buf) if ((err = SrsMp4FullBox::decode_header(buf)) != srs_success) { return srs_error_wrap(err, "decode header"); } - - // a 24-bit integer with flags; one flag is defined (x000001) which means that the media - // data is in the same file as the Movie Box containing this data reference. - if (flags == 0x01) { - return err; - } if ((err = srs_mp4_string_read(buf, location, left_space(buf))) != srs_success) { return srs_error_wrap(err, "url read location"); @@ -2651,7 +2638,9 @@ srs_error_t SrsMp4DataEntryUrlBox::decode_header(SrsBuffer* buf) stringstream& SrsMp4DataEntryUrlBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc) { - ss << "URL: " << location; + SrsMp4FullBox::dumps_detail(ss, dc); + + ss << ", URL: " << location; if (location.empty()) { ss << "Same file"; } @@ -2707,7 +2696,9 @@ srs_error_t SrsMp4DataEntryUrnBox::decode_header(SrsBuffer* buf) stringstream& SrsMp4DataEntryUrnBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc) { - ss << "URN: " << name << ", " << location; + SrsMp4FullBox::dumps_detail(ss, dc); + + ss << ", URN: " << name << ", " << location; return ss; } diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 81328dd8d..1c3b92edf 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -620,7 +620,7 @@ srs_error_t SrsTsPacket::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) payload = new SrsTsPayloadPES(this); } else { // left bytes as reserved. - stream->skip(nb_payload); + stream->skip(srs_min(stream->left(), nb_payload)); } } diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp index 12e87a1f1..d1ebdf34f 100644 --- a/trunk/src/utest/srs_utest_mp4.cpp +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -388,9 +388,9 @@ VOID TEST(KernelMp4Test, UUIDBoxDecode) if (true) { uint8_t data[24]; SrsBuffer b((char*)data, sizeof(data)); - b.write_4bytes(8); b.write_4bytes(SrsMp4BoxTypeUUID); b.skip(-24); + b.write_4bytes(8); b.write_4bytes(SrsMp4BoxTypeUUID); b.skip(-8); SrsMp4Box box; - HELPER_ASSERT_FAILED(box.decode(&b)); + HELPER_EXPECT_SUCCESS(box.decode(&b)); } if (true) { From e8dbee1474bf5eed8df0df700a12793ce57deca1 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 15:55:34 +0800 Subject: [PATCH 3/6] Refine url/urn box dumps --- trunk/src/kernel/srs_kernel_mp4.cpp | 14 +++++++------- trunk/src/kernel/srs_kernel_mp4.hpp | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 8f19b2cb8..7b9d3e242 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -368,12 +368,8 @@ srs_error_t SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) case SrsMp4BoxTypeSIDX: box = new SrsMp4SegmentIndexBox(); break; // Skip some unknown boxes. case SrsMp4BoxTypeFREE: case SrsMp4BoxTypeSKIP: case SrsMp4BoxTypePASP: - case SrsMp4BoxTypeUUID: + case SrsMp4BoxTypeUUID: default: box = new SrsMp4FreeSpaceBox(type); break; - default: - box = new SrsMp4FreeSpaceBox(type); break; - //err = srs_error_new(ERROR_MP4_BOX_ILLEGAL_TYPE, "illegal box type=%d", type); - //break; } if (box) { @@ -2588,6 +2584,11 @@ SrsMp4DataEntryBox::~SrsMp4DataEntryBox() { } +bool SrsMp4DataEntryBox::boxes_in_header() +{ + return true; +} + SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox() { type = SrsMp4BoxTypeURL; @@ -2813,8 +2814,7 @@ stringstream& SrsMp4DataReferenceBox::dumps_detail(stringstream& ss, SrsMp4DumpC ss << ", " << entries.size() << " childs"; if (!entries.empty()) { ss << "(+)" << endl; - srs_mp4_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail2, srs_mp4_delimiter_newline); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_box2, srs_mp4_delimiter_newline); } return ss; } diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index a0f965456..6d06ea106 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -1122,6 +1122,8 @@ public: public: SrsMp4DataEntryBox(); virtual ~SrsMp4DataEntryBox(); +public: + virtual bool boxes_in_header(); }; // 8.7.2 Data Reference Box (url ) From 1cfadfed3af4232cda56058444da1dc8cac22fce Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 18:59:30 +0800 Subject: [PATCH 4/6] Improve test coverage for mp4 boxes --- trunk/src/kernel/srs_kernel_mp4.cpp | 22 +- trunk/src/utest/srs_utest_mp4.cpp | 472 +++++++++++++++++++++++++++- 2 files changed, 491 insertions(+), 3 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 7b9d3e242..8a5ef5536 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -2665,6 +2665,12 @@ int SrsMp4DataEntryUrnBox::nb_header() srs_error_t SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf) { srs_error_t err = srs_success; + + // a 24-bit integer with flags; one flag is defined (x000001) which means that the media + // data is in the same file as the Movie Box containing this data reference. + if (location.empty()) { + flags = 0x01; + } if ((err = SrsMp4DataEntryBox::encode_header(buf)) != srs_success) { return srs_error_wrap(err, "encode entry"); @@ -2699,7 +2705,14 @@ stringstream& SrsMp4DataEntryUrnBox::dumps_detail(stringstream& ss, SrsMp4DumpCo { SrsMp4FullBox::dumps_detail(ss, dc); - ss << ", URN: " << name << ", " << location; + ss << ", URL: " << location; + if (location.empty()) { + ss << "Same file"; + } + if (!name.empty()) { + ss << ", " << name; + } + return ss; } @@ -3467,7 +3480,11 @@ stringstream& SrsMp4DecoderConfigDescriptor::dumps_detail(stringstream& ss, SrsM srs_mp4_padding(ss, dc.indent()); ss << "decoder specific"; - return decSpecificInfo->dumps_detail(ss, dc.indent()); + if (decSpecificInfo) { + decSpecificInfo->dumps_detail(ss, dc.indent()); + } + + return ss; } SrsMp4SLConfigDescriptor::SrsMp4SLConfigDescriptor() @@ -4546,6 +4563,7 @@ stringstream& SrsMp4UserDataBox::dumps_detail(stringstream& ss, SrsMp4DumpContex SrsMp4SegmentIndexBox::SrsMp4SegmentIndexBox() { type = SrsMp4BoxTypeSIDX; + version = 0; } SrsMp4SegmentIndexBox::~SrsMp4SegmentIndexBox() diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp index d1ebdf34f..5e9dc88e1 100644 --- a/trunk/src/utest/srs_utest_mp4.cpp +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -1254,7 +1254,7 @@ VOID TEST(KernelMp4Test, URLBox) box.dumps(ss, dc); string v = ss.str(); - EXPECT_STREQ("url , 13B, FB(4B,V0,0x01), URL: Same file\n", v.c_str()); + EXPECT_STREQ("url , 13B, FB(4B,V0,0x01), URL: Same file", v.c_str()); } if (true) { @@ -1263,5 +1263,475 @@ VOID TEST(KernelMp4Test, URLBox) HELPER_EXPECT_SUCCESS(box.decode(&b)); } } + + if (true) { + char buf[12+2]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DataEntryUrnBox 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("urn , 14B, FB(4B,V0,0x01), URL: Same file", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DataEntryUrnBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4DataReferenceBox box; + SrsMp4DataEntryUrnBox* urn = new SrsMp4DataEntryUrnBox(); + box.append(urn); + EXPECT_TRUE(urn == box.entry_at(0)); + } + + if (true) { + char buf[12+4 + 12+2]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DataReferenceBox box; + SrsMp4DataEntryUrnBox* urn = new SrsMp4DataEntryUrnBox(); + box.append(urn); + 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("dref, 30B, FB(4B), 1 childs(+)\n urn , 14B, FB(4B,V0,0x01), URL: Same file\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DataReferenceBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4SampleTableBox box; + SrsMp4CompositionTime2SampleBox* ctts = new SrsMp4CompositionTime2SampleBox(); + box.set_ctts(ctts); + EXPECT_TRUE(ctts == box.ctts()); + } +} + +VOID TEST(KernelMp4Test, SampleDescBox) +{ + srs_error_t err; + + if (true) { + char buf[8+8+70]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4VisualSampleEntry box; + box.data_reference_index = 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("avc1, 86B, refs#1, size=0x0\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4VisualSampleEntry box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[8]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4AvccBox 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("avcC, 8B, AVC Config: 0B\n \n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4AvccBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[8+8+20]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4AudioSampleEntry box; + box.data_reference_index = 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("mp4a, 36B, refs#1, 2 channels, 16 bits, 0 Hz\n", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4AudioSampleEntry box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } +} + +VOID TEST(KernelMp4Test, SpecificInfoBox) +{ + srs_error_t err; + + if (true) { + char buf[2+2]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DecoderSpecificInfo box; + box.asc.resize(2); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", tag=0x05, ASC 2B\n 0x00, 0x00", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DecoderSpecificInfo box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[2+13]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DecoderConfigDescriptor box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", tag=0x04, type=0, stream=0\n decoder specific", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DecoderConfigDescriptor box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[2+21]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4ES_Descriptor box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", tag=0x03, ID=0\n decoder config, tag=0x04, type=0, stream=0\n decoder specific", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DecoderConfigDescriptor box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } +} + +VOID TEST(KernelMp4Test, STSDBox) +{ + srs_error_t err; + + if (true) { + char buf[32]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4SampleDescriptionBox box; + box.entries.push_back(new SrsMp4SampleEntry()); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 1 childs(+)\n ", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4SampleDescriptionBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[24]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4DecodingTime2SampleBox box; + box.entries.push_back(SrsMp4SttsEntry()); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 1 childs (+)\n count=0, delta=0", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4DecodingTime2SampleBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[24]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4CompositionTime2SampleBox box; + box.entries.push_back(SrsMp4CttsEntry()); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 1 childs (+)\n count=0, offset=0", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4CompositionTime2SampleBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[16]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4SyncSampleBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), count=0", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4SyncSampleBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[16]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4Sample2ChunkBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 0 childs (+)", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4Sample2ChunkBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[16]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4ChunkOffsetBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 0 childs (+)", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4ChunkOffsetBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[16]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4ChunkLargeOffsetBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 0 childs (+)", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4ChunkLargeOffsetBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[20]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4SampleSizeBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), size=0, 0 childs (+)", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4SampleSizeBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[10]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4UserDataBox box; + box.data.resize(2); + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", total 2B\n 0x00, 0x00", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4UserDataBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + char buf[32]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4SegmentIndexBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_TRUE(v.length() > 0); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4SegmentIndexBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } } From 7597a956ed115548f6e69df2586e0d79e14dcad5 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 19:17:40 +0800 Subject: [PATCH 5/6] Improve test coverage for dash init encoder --- trunk/src/kernel/srs_kernel_mp4.cpp | 3 + trunk/src/utest/srs_utest_mp4.cpp | 102 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 8a5ef5536..29e58d816 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -1549,6 +1549,9 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() uint64_t SrsMp4MovieHeaderBox::duration() { + if (timescale <= 0) { + return 0; + } return duration_in_tbn * 1000 / timescale; } diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp index 5e9dc88e1..d94b053b9 100644 --- a/trunk/src/utest/srs_utest_mp4.cpp +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include using namespace std; +#include #include #include #include @@ -1733,5 +1734,106 @@ VOID TEST(KernelMp4Test, STSDBox) HELPER_EXPECT_SUCCESS(box.decode(&b)); } } + + if (true) { + char buf[108]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4MovieHeaderBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 0ms, TBN=0, nTID=0", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4MovieHeaderBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } + + if (true) { + SrsMp4TrackBox box; + SrsMp4TrackHeaderBox* tkhd = new SrsMp4TrackHeaderBox(); + box.set_tkhd(tkhd); + EXPECT_TRUE(tkhd == box.tkhd()); + } + + if (true) { + char buf[16]; + SrsBuffer b(buf, sizeof(buf)); + + if (true) { + SrsMp4CompositionTime2SampleBox box; + EXPECT_EQ(sizeof(buf), box.nb_bytes()); + HELPER_EXPECT_SUCCESS(box.encode(&b)); + + stringstream ss; + SrsMp4DumpContext dc; + box.dumps_detail(ss, dc); + + string v = ss.str(); + EXPECT_STREQ(", FB(4B), 0 childs (+)", v.c_str()); + } + + if (true) { + b.skip(-1 * b.pos()); + SrsMp4CompositionTime2SampleBox box; + HELPER_EXPECT_SUCCESS(box.decode(&b)); + } + } +} + +VOID TEST(KernelMp4Test, SrsMp4M2tsInitEncoder) +{ + srs_error_t err; + + if (true) { + MockSrsFileWriter fw; + HELPER_ASSERT_SUCCESS(fw.open("test.mp4")); + + SrsMp4M2tsInitEncoder enc; + HELPER_ASSERT_SUCCESS(enc.initialize(&fw)); + + SrsFormat fmt; + EXPECT_TRUE(srs_success == fmt.initialize()); + + uint8_t raw[] = { + 0x17, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20, + 0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, + 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c + }; + EXPECT_TRUE(srs_success == fmt.on_video(0, (char*)raw, sizeof(raw))); + + HELPER_ASSERT_SUCCESS(enc.write(&fmt, true, 1)); + EXPECT_TRUE(fw.filesize() > 0); + } + + if (true) { + MockSrsFileWriter fw; + HELPER_ASSERT_SUCCESS(fw.open("test.mp4")); + + SrsMp4M2tsInitEncoder enc; + HELPER_ASSERT_SUCCESS(enc.initialize(&fw)); + + SrsFormat fmt; + EXPECT_TRUE(srs_success == fmt.initialize()); + + uint8_t raw[] = { + 0xaf, 0x00, 0x12, 0x10 + }; + EXPECT_TRUE(srs_success == fmt.on_audio(0, (char*)raw, sizeof(raw))); + + HELPER_ASSERT_SUCCESS(enc.write(&fmt, false, 1)); + EXPECT_TRUE(fw.filesize() > 0); + } } From c3e0dcfa9e0cfa6e7db7d22b499eb3fcc5d38f50 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 31 Dec 2019 19:37:48 +0800 Subject: [PATCH 6/6] Improve test coverage for mp4 decoder --- trunk/src/kernel/srs_kernel_mp4.cpp | 6 +++--- trunk/src/utest/srs_utest_kernel.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 29e58d816..ddcce00be 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -4791,10 +4791,10 @@ srs_error_t SrsMp4SampleManager::load(SrsMp4MovieBox* moov) SrsMp4Sample* SrsMp4SampleManager::at(uint32_t index) { - if (index >= samples.size() - 1) { - return NULL; + if (index < samples.size()) { + return samples.at(index); } - return samples.at(index); + return NULL; } void SrsMp4SampleManager::append(SrsMp4Sample* sample) diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index b6784b562..7e4d32f11 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -4688,8 +4688,34 @@ VOID TEST(KernelMP4Test, CoverMP4Codec) uint16_t ft, ct; uint32_t dts, pts, nb_sample; uint8_t* sample; + EXPECT_TRUE(srs_success == dec.read_sample(&ht, &ft, &ct, &dts, &pts, &sample, &nb_sample)); EXPECT_EQ(0, (int)dts); + EXPECT_EQ(41, nb_sample); + EXPECT_EQ(SrsMp4HandlerTypeVIDE, ht); + EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, ct); + srs_freepa(sample); + + EXPECT_TRUE(srs_success == dec.read_sample(&ht, &ft, &ct, &dts, &pts, &sample, &nb_sample)); + EXPECT_EQ(0, (int)dts); + EXPECT_EQ(2, nb_sample); + EXPECT_EQ(SrsMp4HandlerTypeSOUN, ht); + EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, ct); + srs_freepa(sample); + + EXPECT_TRUE(srs_success == dec.read_sample(&ht, &ft, &ct, &dts, &pts, &sample, &nb_sample)); + EXPECT_EQ(0, (int)dts); + EXPECT_EQ(87, nb_sample); + EXPECT_EQ(SrsMp4HandlerTypeSOUN, ht); + EXPECT_NE(SrsAudioAacFrameTraitSequenceHeader, ct); + srs_freepa(sample); + + EXPECT_TRUE(srs_success == dec.read_sample(&ht, &ft, &ct, &dts, &pts, &sample, &nb_sample)); + EXPECT_EQ(0, (int)dts); + EXPECT_EQ(127, nb_sample); + EXPECT_EQ(SrsMp4HandlerTypeVIDE, ht); + EXPECT_NE(SrsAudioAacFrameTraitSequenceHeader, ct); + srs_freepa(sample); } if (true) {