diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index 59ca14806..884568f31 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -420,10 +420,8 @@ srs_error_t SrsFlvTransmuxer::write_metadata(char type, char* data, int size) { srs_error_t err = srs_success; - srs_assert(data); - - if ((err = write_metadata_to_cache(type, data, size, tag_header)) != srs_success) { - return srs_error_wrap(err, "cache metadata"); + if (size > 0) { + cache_metadata(type, data, size, tag_header); } if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) { @@ -437,10 +435,8 @@ srs_error_t SrsFlvTransmuxer::write_audio(int64_t timestamp, char* data, int siz { srs_error_t err = srs_success; - srs_assert(data); - - if ((err = write_audio_to_cache(timestamp, data, size, tag_header)) != srs_success) { - return srs_error_wrap(err, "cache audio"); + if (size > 0) { + cache_audio(timestamp, data, size, tag_header); } if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) { @@ -454,10 +450,8 @@ srs_error_t SrsFlvTransmuxer::write_video(int64_t timestamp, char* data, int siz { srs_error_t err = srs_success; - srs_assert(data); - - if ((err = write_video_to_cache(timestamp, data, size, tag_header)) != srs_success) { - return srs_error_wrap(err, "cache video"); + if (size > 0) { + cache_video(timestamp, data, size, tag_header); } if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) { @@ -513,23 +507,15 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count) // cache all flv header. if (msg->is_audio()) { - if ((err = write_audio_to_cache(msg->timestamp, msg->payload, msg->size, cache)) != srs_success) { - return srs_error_wrap(err, "cache audio"); - } + cache_audio(msg->timestamp, msg->payload, msg->size, cache); } else if (msg->is_video()) { - if ((err = write_video_to_cache(msg->timestamp, msg->payload, msg->size, cache)) != srs_success) { - return srs_error_wrap(err, "cache video"); - } + cache_video(msg->timestamp, msg->payload, msg->size, cache); } else { - if ((err = write_metadata_to_cache(SrsFrameTypeScript, msg->payload, msg->size, cache)) != srs_success) { - return srs_error_wrap(err, "cache metadata"); - } + cache_metadata(SrsFrameTypeScript, msg->payload, msg->size, cache); } // cache all pts. - if ((err = write_pts_to_cache(SRS_FLV_TAG_HEADER_SIZE + msg->size, pts)) != srs_success) { - return srs_error_wrap(err, "cache pts"); - } + cache_pts(SRS_FLV_TAG_HEADER_SIZE + msg->size, pts); // all ioves. iovs[0].iov_base = cache; @@ -553,10 +539,8 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count) } #endif -srs_error_t SrsFlvTransmuxer::write_metadata_to_cache(char type, char* data, int size, char* cache) +void SrsFlvTransmuxer::cache_metadata(char type, char* data, int size, char* cache) { - srs_error_t err = srs_success; - srs_assert(data); // 11 bytes tag header @@ -577,14 +561,10 @@ srs_error_t SrsFlvTransmuxer::write_metadata_to_cache(char type, char* data, int tag_stream->write_3bytes(0x00); tag_stream->write_1bytes(0x00); tag_stream->write_3bytes(0x00); - - return err; } -srs_error_t SrsFlvTransmuxer::write_audio_to_cache(int64_t timestamp, char* data, int size, char* cache) +void SrsFlvTransmuxer::cache_audio(int64_t timestamp, char* data, int size, char* cache) { - srs_error_t err = srs_success; - srs_assert(data); timestamp &= 0x7fffffff; @@ -608,14 +588,10 @@ srs_error_t SrsFlvTransmuxer::write_audio_to_cache(int64_t timestamp, char* data // default to little-endian tag_stream->write_1bytes((timestamp >> 24) & 0xFF); tag_stream->write_3bytes(0x00); - - return err; } -srs_error_t SrsFlvTransmuxer::write_video_to_cache(int64_t timestamp, char* data, int size, char* cache) +void SrsFlvTransmuxer::cache_video(int64_t timestamp, char* data, int size, char* cache) { - srs_error_t err = srs_success; - srs_assert(data); timestamp &= 0x7fffffff; @@ -639,20 +615,13 @@ srs_error_t SrsFlvTransmuxer::write_video_to_cache(int64_t timestamp, char* data // default to little-endian tag_stream->write_1bytes((timestamp >> 24) & 0xFF); tag_stream->write_3bytes(0x00); - - return err; } -srs_error_t SrsFlvTransmuxer::write_pts_to_cache(int size, char* cache) +void SrsFlvTransmuxer::cache_pts(int size, char* cache) { - srs_error_t err = srs_success; - SrsBuffer* tag_stream = new SrsBuffer(cache, 11); SrsAutoFree(SrsBuffer, tag_stream); - tag_stream->write_4bytes(size); - - return err; } srs_error_t SrsFlvTransmuxer::write_tag(char* header, int header_size, char* tag, int tag_size) @@ -661,9 +630,7 @@ srs_error_t SrsFlvTransmuxer::write_tag(char* header, int header_size, char* tag // PreviousTagSizeN UI32 Size of last tag, including its header, in bytes. char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE]; - if ((err = write_pts_to_cache(tag_size + header_size, pre_size)) != srs_success) { - return srs_error_wrap(err, "cache pts"); - } + cache_pts(tag_size + header_size, pre_size); iovec iovs[3]; iovs[0].iov_base = header; diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index 80cd62e9c..bc2ad6ed7 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -394,10 +394,10 @@ public: virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count); #endif private: - virtual srs_error_t write_metadata_to_cache(char type, char* data, int size, char* cache); - virtual srs_error_t write_audio_to_cache(int64_t timestamp, char* data, int size, char* cache); - virtual srs_error_t write_video_to_cache(int64_t timestamp, char* data, int size, char* cache); - virtual srs_error_t write_pts_to_cache(int size, char* cache); + virtual void cache_metadata(char type, char* data, int size, char* cache); + virtual void cache_audio(int64_t timestamp, char* data, int size, char* cache); + virtual void cache_video(int64_t timestamp, char* data, int size, char* cache); + virtual void cache_pts(int size, char* cache); virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size); }; diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index c988d2034..bb6395dec 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -46,7 +46,7 @@ MockSrsFileWriter::MockSrsFileWriter() data = new char[size]; offset = 0; err = srs_success; - error_offset = 0; + error_offset = -1; opened = false; } @@ -95,8 +95,9 @@ srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) } int nwriten = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count); - - memcpy(data + offset, buf, nwriten); + if (nwriten > 0) { + memcpy(data + offset, buf, nwriten); + } if (pnwrite) { *pnwrite = nwriten; @@ -105,7 +106,7 @@ srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) offset += nwriten; size = srs_max(size, offset); - if (error_offset > 0 && offset >= error_offset) { + if (error_offset >= 0 && offset > error_offset) { return srs_error_new(-1, "exceed offset"); } @@ -658,6 +659,89 @@ VOID TEST(KernelFlvTest, FlvEncoderSizeTag) EXPECT_EQ(11+4+0, SrsFlvTransmuxer::size_tag(0)); } +VOID TEST(KernelFLVTest, CoverErrorCase) +{ + srs_error_t err; + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_SUCCESS(m.write_header()); + } + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 0; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_FAILED(m.write_header()); + } + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 9; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_FAILED(m.write_header()); + } + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 0; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_FAILED(m.write_metadata(0, NULL, 0)); + } + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 0; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_FAILED(m.write_audio(0, NULL, 0)); + } + + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 0; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + HELPER_EXPECT_FAILED(m.write_video(0, NULL, 0)); + } + +#ifdef SRS_PERF_FAST_FLV_ENCODER + if (true) { + MockSrsFileWriter w; + HELPER_EXPECT_SUCCESS(w.open("")); + w.error_offset = 0; + + SrsFlvTransmuxer m; + HELPER_EXPECT_SUCCESS(m.initialize(&w)); + + SrsMessageHeader h; + h.initialize_video(10, 30, 20); + SrsSharedPtrMessage msg; + HELPER_EXPECT_SUCCESS(msg.create(&h, new char[1], 1)); + + SrsSharedPtrMessage* msgs = &msg; + HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1)); + } +#endif +} + /** * test the flv decoder, * exception: file stream not open. @@ -2403,7 +2487,7 @@ VOID TEST(KernelAACTest, TransmaxRTMP2AAC) EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]); EXPECT_EQ(2, m.aac_channels); - f.error_offset = 7; + f.error_offset = 6; err = m.write_audio(0, (char*)"\xaf\x01\x00", 3); EXPECT_TRUE(srs_success != err); @@ -2427,7 +2511,7 @@ VOID TEST(KernelAACTest, TransmaxRTMP2AAC) EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]); EXPECT_EQ(2, m.aac_channels); - f.error_offset = 8; + f.error_offset = 7; err = m.write_audio(0, (char*)"\xaf\x01\x00", 3); EXPECT_TRUE(srs_success != err); diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp index a08562b72..53ebdb692 100644 --- a/trunk/src/utest/srs_utest_kernel.hpp +++ b/trunk/src/utest/srs_utest_kernel.hpp @@ -53,7 +53,9 @@ public: int size; int offset; srs_error_t err; + // Error if exceed this offset. int error_offset; + // Whether opened. bool opened; public: MockSrsFileWriter();