From 1e395e7c10077c0554a2cc59db41c83171e6df6c Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 5 Jul 2014 17:30:13 +0800 Subject: [PATCH] add assert to flv. --- trunk/src/kernel/srs_kernel_flv.cpp | 37 ++++-- trunk/src/kernel/srs_kernel_flv.hpp | 23 +++- trunk/src/utest/srs_utest_kernel.cpp | 164 +++++++++++++++++++++++++++ 3 files changed, 214 insertions(+), 10 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index 50071429c..61383d281 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -53,6 +53,8 @@ int SrsFlvEncoder::initialize(SrsFileWriter* fs) { int ret = ERROR_SUCCESS; + srs_assert(fs); + if (!fs->is_open()) { ret = ERROR_KERNEL_FLV_STREAM_CLOSED; srs_warn("stream is not open for decoder. ret=%d", ret); @@ -110,6 +112,8 @@ int SrsFlvEncoder::write_metadata(char* data, int size) { int ret = ERROR_SUCCESS; + srs_assert(data); + // 11 bytes tag header static char tag_header[] = { (char)18, // TagType UB [5], 18 = script data @@ -137,6 +141,8 @@ int SrsFlvEncoder::write_audio(int64_t timestamp, char* data, int size) { int ret = ERROR_SUCCESS; + srs_assert(data); + timestamp &= 0x7fffffff; // 11bytes tag header @@ -169,6 +175,8 @@ int SrsFlvEncoder::write_video(int64_t timestamp, char* data, int size) { int ret = ERROR_SUCCESS; + srs_assert(data); + timestamp &= 0x7fffffff; // 11bytes tag header @@ -199,6 +207,7 @@ int SrsFlvEncoder::write_video(int64_t timestamp, char* data, int size) int SrsFlvEncoder::size_tag(int data_size) { + srs_assert(data_size >= 0); return SRS_FLV_TAG_HEADER_SIZE + data_size + SRS_FLV_PREVIOUS_TAG_SIZE; } @@ -247,6 +256,8 @@ int SrsFlvDecoder::initialize(SrsFileReader* fs) { int ret = ERROR_SUCCESS; + srs_assert(fs); + if (!fs->is_open()) { ret = ERROR_KERNEL_FLV_STREAM_CLOSED; srs_warn("stream is not open for decoder. ret=%d", ret); @@ -262,6 +273,8 @@ int SrsFlvDecoder::read_header(char header[9]) { int ret = ERROR_SUCCESS; + srs_assert(header); + if ((ret = _fs->read(header, 9, NULL)) != ERROR_SUCCESS) { return ret; } @@ -280,6 +293,10 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* { int ret = ERROR_SUCCESS; + srs_assert(ptype); + srs_assert(pdata_size); + srs_assert(ptime); + char th[11]; // tag header // read tag header @@ -316,6 +333,8 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* int SrsFlvDecoder::read_tag_data(char* data, int32_t size) { int ret = ERROR_SUCCESS; + + srs_assert(data); if ((ret = _fs->read(data, size, NULL)) != ERROR_SUCCESS) { if (ret != ERROR_SYSTEM_FILE_EOF) { @@ -328,12 +347,14 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size) } -int SrsFlvDecoder::read_previous_tag_size(char ts[4]) +int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4]) { int ret = ERROR_SUCCESS; + + srs_assert(previous_tag_size); // ignore 4bytes tag size. - if ((ret = _fs->read(ts, 4, NULL)) != ERROR_SUCCESS) { + if ((ret = _fs->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) { if (ret != ERROR_SYSTEM_FILE_EOF) { srs_error("read flv previous tag size failed. ret=%d", ret); } @@ -358,6 +379,8 @@ int SrsFlvVodStreamDecoder::initialize(SrsFileReader* fs) { int ret = ERROR_SUCCESS; + srs_assert(fs); + if (!fs->is_open()) { ret = ERROR_KERNEL_FLV_STREAM_CLOSED; srs_warn("stream is not open for decoder. ret=%d", ret); @@ -373,7 +396,7 @@ int SrsFlvVodStreamDecoder::read_header_ext(char header[13]) { int ret = ERROR_SUCCESS; - srs_assert(_fs); + srs_assert(header); // @remark, always false, for sizeof(char[13]) equals to sizeof(char*) //srs_assert(13 == sizeof(header)); @@ -390,12 +413,10 @@ int SrsFlvVodStreamDecoder::read_header_ext(char header[13]) int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* psize) { - *pstart = 0; - *psize = 0; - int ret = ERROR_SUCCESS; - srs_assert(_fs); + srs_assert(pstart); + srs_assert(psize); // simply, the first video/audio must be the sequence header. // and must be a sequence video and audio. @@ -484,8 +505,6 @@ int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* p int SrsFlvVodStreamDecoder::lseek(int64_t offset) { int ret = ERROR_SUCCESS; - - srs_assert(_fs); if (offset >= _fs->filesize()) { ret = ERROR_SYSTEM_FILE_EOF; diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index 015250d15..b81b13c2b 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -69,10 +69,12 @@ public: * @param data, the amf0 metadata which serialize from: * AMF0 string: onMetaData, * AMF0 object: the metadata object. + * @remark assert data is not NULL. */ virtual int write_metadata(char* data, int size); /** * write audio/video packet. + * @remark assert data is not NULL. */ virtual int write_audio(int64_t timestamp, char* data, int size); virtual int write_video(int64_t timestamp, char* data, int size); @@ -80,6 +82,7 @@ public: /** * get the tag size, * including the tag header, body, and 4bytes previous tag size. + * @remark assert data_size is not negative. */ static int size_tag(int data_size); private: @@ -106,10 +109,26 @@ public: */ virtual int initialize(SrsFileReader* fs); public: + /** + * read the flv header, donot including the 4bytes previous tag size. + * @remark assert header not NULL. + */ virtual int read_header(char header[9]); + /** + * read the tag header infos. + * @remark assert ptype/pdata_size/ptime not NULL. + */ virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime); + /** + * read the tag data. + * @remark assert data not NULL. + */ virtual int read_tag_data(char* data, int32_t size); - virtual int read_previous_tag_size(char ts[4]); + /** + * read the 4bytes previous tag size. + * @remark assert previous_tag_size not NULL. + */ + virtual int read_previous_tag_size(char previous_tag_size[4]); }; /** @@ -137,6 +156,7 @@ public: /** * read the flv header and its size. * @param header, fill it 13bytes(9bytes header, 4bytes previous tag size). + * @remark assert header not NULL. */ virtual int read_header_ext(char header[13]); /** @@ -144,6 +164,7 @@ public: * @param pstart, the start offset of sequence header. * @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size). * @remark we think the first audio/video is sequence header. + * @remark assert pstart/psize not NULL. */ virtual int read_sequence_header_summary(int64_t* pstart, int* psize); public: diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 9800614a0..f6d9cb26a 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -176,6 +176,10 @@ void MockSrsFileReader::mock_reset_offset() offset = 0; } +/** +* test the codec, +* whether H.264 keyframe +*/ VOID TEST(KernelCodecTest, IsKeyFrame) { int8_t data; @@ -188,6 +192,10 @@ VOID TEST(KernelCodecTest, IsKeyFrame) EXPECT_FALSE(SrsFlvCodec::video_is_keyframe(&data, 1)); } +/** +* test the codec, +* check whether H.264 video +*/ VOID TEST(KernelCodecTest, IsH264) { int8_t data; @@ -204,6 +212,10 @@ VOID TEST(KernelCodecTest, IsH264) EXPECT_FALSE(SrsFlvCodec::video_is_h264(&data, 1)); } +/** +* test the codec, +* whether H.264 video sequence header +*/ VOID TEST(KernelCodecTest, IsSequenceHeader) { int16_t data; @@ -224,6 +236,10 @@ VOID TEST(KernelCodecTest, IsSequenceHeader) EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2)); } +/** +* test the codec, +* check whether AAC codec +*/ VOID TEST(KernelCodecTest, IsAAC) { int8_t data; @@ -240,6 +256,10 @@ VOID TEST(KernelCodecTest, IsAAC) EXPECT_FALSE(SrsFlvCodec::audio_is_aac(&data, 1)); } +/** +* test the codec, +* AAC audio sequence header +*/ VOID TEST(KernelCodecTest, IsAudioSequenceHeader) { int16_t data; @@ -258,6 +278,10 @@ VOID TEST(KernelCodecTest, IsAudioSequenceHeader) EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2)); } +/** +* test the flv encoder, +* exception: file stream not open +*/ VOID TEST(KernelFlvTest, FlvEncoderStreamClosed) { MockSrsFileWriter fs; @@ -265,6 +289,10 @@ VOID TEST(KernelFlvTest, FlvEncoderStreamClosed) ASSERT_TRUE(ERROR_SUCCESS != enc.initialize(&fs)); } +/** +* test the flv encoder, +* write flv header +*/ VOID TEST(KernelFlvTest, FlvEncoderWriteHeader) { MockSrsFileWriter fs; @@ -301,6 +329,10 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteHeader) EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4)); } +/** +* test the flv encoder, +* write metadata tag +*/ VOID TEST(KernelFlvTest, FlvEncoderWriteMetadata) { MockSrsFileWriter fs; @@ -331,6 +363,10 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteMetadata) EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 19, 4)); } +/** +* test the flv encoder, +* write audio tag +*/ VOID TEST(KernelFlvTest, FlvEncoderWriteAudio) { MockSrsFileWriter fs; @@ -361,6 +397,10 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteAudio) EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); } +/** +* test the flv encoder, +* write video tag +*/ VOID TEST(KernelFlvTest, FlvEncoderWriteVideo) { MockSrsFileWriter fs; @@ -391,12 +431,20 @@ VOID TEST(KernelFlvTest, FlvEncoderWriteVideo) EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4)); } +/** +* test the flv encoder, +* calc the tag size. +*/ VOID TEST(KernelFlvTest, FlvEncoderSizeTag) { EXPECT_EQ(11+4+10, SrsFlvEncoder::size_tag(10)); EXPECT_EQ(11+4+0, SrsFlvEncoder::size_tag(0)); } +/** +* test the flv decoder, +* exception: file stream not open. +*/ VOID TEST(KernelFlvTest, FlvDecoderStreamClosed) { MockSrsFileReader fs; @@ -404,6 +452,10 @@ VOID TEST(KernelFlvTest, FlvDecoderStreamClosed) ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs)); } +/** +* test the flv decoder, +* decode flv header +*/ VOID TEST(KernelFlvTest, FlvDecoderHeader) { MockSrsFileReader fs; @@ -432,6 +484,10 @@ VOID TEST(KernelFlvTest, FlvDecoderHeader) EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); } +/** +* test the flv decoder, +* decode metadata tag +*/ VOID TEST(KernelFlvTest, FlvDecoderMetadata) { MockSrsFileReader fs; @@ -474,6 +530,10 @@ VOID TEST(KernelFlvTest, FlvDecoderMetadata) EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); } +/** +* test the flv decoder, +* decode audio tag +*/ VOID TEST(KernelFlvTest, FlvDecoderAudio) { MockSrsFileReader fs; @@ -516,6 +576,10 @@ VOID TEST(KernelFlvTest, FlvDecoderAudio) EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); } +/** +* test the flv decoder, +* decode video tag +*/ VOID TEST(KernelFlvTest, FlvDecoderVideo) { MockSrsFileReader fs; @@ -558,6 +622,10 @@ VOID TEST(KernelFlvTest, FlvDecoderVideo) EXPECT_TRUE(srs_bytes_equals(pts, data, 4)); } +/** +* test the flv vod stream decoder, +* exception: file stream not open. +*/ VOID TEST(KernelFlvTest, FlvVSDecoderStreamClosed) { MockSrsFileReader fs; @@ -565,6 +633,10 @@ VOID TEST(KernelFlvTest, FlvVSDecoderStreamClosed) ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs)); } +/** +* test the flv vod stream decoder, +* decode the flv header +*/ VOID TEST(KernelFlvTest, FlvVSDecoderHeader) { MockSrsFileReader fs; @@ -591,6 +663,11 @@ VOID TEST(KernelFlvTest, FlvVSDecoderHeader) EXPECT_TRUE(srs_bytes_equals(flv_header, data, 9)); } +/** +* test the flv vod stream decoder, +* get the start offset and size of sequence header +* mock data: metadata-audio-video +*/ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) { MockSrsFileReader fs; @@ -598,6 +675,7 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); + // push metadata tag if (true) { // 11 bytes tag header char tag_header[] = { @@ -616,6 +694,7 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) fs.mock_append_data(md, 8); fs.mock_append_data(pts, 4); } + // push audio tag if (true) { // 11bytes tag header char tag_header[] = { @@ -634,6 +713,7 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) fs.mock_append_data(audio, 8); fs.mock_append_data(pts, 4); } + // push video tag if (true) { // 11bytes tag header char tag_header[] = { @@ -662,6 +742,90 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader) EXPECT_TRUE(46 == size); } +/** +* test the flv vod stream decoder, +* get the start offset and size of sequence header +* mock data: metadata-video-audio +*/ +VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader2) +{ + MockSrsFileReader fs; + SrsFlvVodStreamDecoder dec; + ASSERT_TRUE(ERROR_SUCCESS == fs.open("")); + ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs)); + + // push metadata tag + if (true) { + // 11 bytes tag header + char tag_header[] = { + (char)18, // TagType UB [5], 18 = script data + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. + (char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. + (char)0x00, // TimestampExtended UI8 + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. + }; + char md[] = { + (char)0x01, (char)0x02, (char)0x03, (char)0x04, + (char)0x04, (char)0x03, (char)0x02, (char)0x01 + }; + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; + fs.mock_append_data(tag_header, 11); + fs.mock_append_data(md, 8); + fs.mock_append_data(pts, 4); + } + // push video tag + if (true) { + // 11bytes tag header + char tag_header[] = { + (char)9, // TagType UB [5], 9 = video + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. + (char)0x00, // TimestampExtended UI8 + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. + }; + char video[] = { + (char)0x01, (char)0x02, (char)0x03, (char)0x04, + (char)0x04, (char)0x03, (char)0x02, (char)0x01 + }; + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; + fs.mock_append_data(tag_header, 11); + fs.mock_append_data(video, 8); + fs.mock_append_data(pts, 4); + } + // push audio tag + if (true) { + // 11bytes tag header + char tag_header[] = { + (char)8, // TagType UB [5], 8 = audio + (char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message. + (char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies. + (char)0x00, // TimestampExtended UI8 + (char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0. + }; + char audio[] = { + (char)0x01, (char)0x02, (char)0x03, (char)0x04, + (char)0x04, (char)0x03, (char)0x02, (char)0x01 + }; + char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 }; + fs.mock_append_data(tag_header, 11); + fs.mock_append_data(audio, 8); + fs.mock_append_data(pts, 4); + } + + fs.mock_reset_offset(); + + int64_t start = 0; + int size = 0; + EXPECT_TRUE(ERROR_SUCCESS == dec.read_sequence_header_summary(&start, &size)); + EXPECT_TRUE(23 == start); + EXPECT_TRUE(46 == size); +} + +/** +* test the flv vod stream decoder, +* seek stream after got the offset and start of flv sequence header, +* to directly response flv data by seek to the offset of file. +*/ VOID TEST(KernelFlvTest, FlvVSDecoderSeek) { MockSrsFileReader fs;