diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 26ab41841..cffd67cda 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -298,7 +298,7 @@ srs_error_t SrsTsContext::decode(SrsBuffer* stream, ISrsTsHandler* handler) return err; } -srs_error_t SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac) +srs_error_t SrsTsContext::encode(ISrsStreamWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac) { srs_error_t err = srs_success; @@ -380,7 +380,7 @@ void SrsTsContext::set_sync_byte(int8_t sb) sync_byte = sb; } -srs_error_t SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as) +srs_error_t SrsTsContext::encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as) { srs_error_t err = srs_success; @@ -441,7 +441,7 @@ srs_error_t SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, Sr return err; } -srs_error_t SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio) +srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio) { srs_error_t err = srs_success; @@ -2543,7 +2543,7 @@ srs_error_t SrsTsPayloadPMT::psi_encode(SrsBuffer* stream) return err; } -SrsTsContextWriter::SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc) +SrsTsContextWriter::SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc) { writer = w; context = c; @@ -2568,7 +2568,10 @@ srs_error_t SrsTsContextWriter::open(string p) // reset the context for a new ts start. context->reset(); - if ((err = writer->open(path)) != srs_success) { + SrsFileWriter* fw = dynamic_cast(writer); + srs_assert(fw); + + if ((err = fw->open(path)) != srs_success) { return srs_error_wrap(err, "ts: open writer"); } @@ -2607,7 +2610,10 @@ srs_error_t SrsTsContextWriter::write_video(SrsTsMessage* video) void SrsTsContextWriter::close() { - writer->close(); + SrsFileWriter* fw = dynamic_cast(writer); + srs_assert(fw); + + fw->close(); } SrsVideoCodecId SrsTsContextWriter::video_codec() @@ -3011,7 +3017,7 @@ SrsTsTransmuxer::~SrsTsTransmuxer() srs_freep(context); } -srs_error_t SrsTsTransmuxer::initialize(SrsFileWriter* fw) +srs_error_t SrsTsTransmuxer::initialize(ISrsStreamWriter* fw) { srs_error_t err = srs_success; @@ -3021,10 +3027,6 @@ srs_error_t SrsTsTransmuxer::initialize(SrsFileWriter* fw) srs_assert(fw); - if (!fw->is_open()) { - return srs_error_new(ERROR_KERNEL_FLV_STREAM_CLOSED, "ts: stream is not open"); - } - writer = fw; srs_freep(tscw); diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index 36fd5224a..e2e1e523a 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -38,7 +38,7 @@ class SrsBuffer; class SrsTsMessageCache; class SrsTsContextWriter; -class SrsFileWriter; +class ISrsStreamWriter; class SrsFileReader; class SrsFormat; class SrsSimpleStream; @@ -403,7 +403,7 @@ public: * @param vc the video codec, write the PAT/PMT table when changed. * @param ac the audio codec, write the PAT/PMT table when changed. */ - virtual srs_error_t encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac); + virtual srs_error_t encode(ISrsStreamWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac); // drm methods public: /** @@ -412,8 +412,8 @@ public: */ virtual void set_sync_byte(int8_t sb); private: - virtual srs_error_t encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); - virtual srs_error_t encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio); + virtual srs_error_t encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); + virtual srs_error_t encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio); }; /** @@ -1543,10 +1543,10 @@ private: SrsAudioCodecId acodec; private: SrsTsContext* context; - SrsFileWriter* writer; + ISrsStreamWriter* writer; std::string path; public: - SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc); + SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc); virtual ~SrsTsContextWriter(); public: /** @@ -1628,7 +1628,7 @@ private: class SrsTsTransmuxer { private: - SrsFileWriter* writer; + ISrsStreamWriter* writer; private: SrsFormat* format; SrsTsMessageCache* tsmc; @@ -1642,7 +1642,7 @@ public: * initialize the underlayer file stream. * @param fw the writer to use for ts encoder, user must free it. */ - virtual srs_error_t initialize(SrsFileWriter* fw); + virtual srs_error_t initialize(ISrsStreamWriter* fw); public: /** * write audio/video packet. diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index 6a3fe9afe..a919ea232 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -243,14 +243,19 @@ srs_error_t MockSrsCodec::decode(SrsBuffer* /*buf*/) MockTsHandler::MockTsHandler() { + msg = NULL; } MockTsHandler::~MockTsHandler() { + srs_freep(msg); } -srs_error_t MockTsHandler::on_ts_message(SrsTsMessage* /*msg*/) +srs_error_t MockTsHandler::on_ts_message(SrsTsMessage* m) { + srs_freep(msg); + msg = m->detach(); + return srs_success; } @@ -3201,7 +3206,7 @@ VOID TEST(KernelUtilityTest, CoverTimeUtilityAll) } } -VOID TEST(KernelTSTest, CoverBasicUtility) +VOID TEST(KernelTSTest, CoverContextUtility) { if (true) { EXPECT_STREQ("Reserved", srs_ts_stream2string(SrsTsStreamReserved).c_str()); @@ -3238,6 +3243,9 @@ VOID TEST(KernelTSTest, CoverBasicUtility) SrsTsMessage* cp = m.detach(); EXPECT_TRUE(cp != NULL); srs_freep(cp); + + ctx.reset(); + EXPECT_FALSE(ctx.ready); } if (true) { @@ -3294,6 +3302,44 @@ VOID TEST(KernelTSTest, CoverBasicUtility) EXPECT_TRUE(m.completed(0)); } + if (true) { + SrsTsMessage m; + + EXPECT_TRUE(m.completed(1)); + EXPECT_TRUE(!m.completed(0)); + + m.PES_packet_length = 8; + SrsBuffer b((char*)"\x00\x01\x02\x03", 4); + + int nb_bytes = 0; + EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes)); + EXPECT_EQ(4, nb_bytes); + + b.skip(-4); + EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes)); + EXPECT_EQ(4, nb_bytes); + + EXPECT_TRUE(m.completed(0)); + } + + if (true) { + MockTsHandler* h = new MockTsHandler(); + srs_freep(h); + + SrsTsContext ctx; + EXPECT_TRUE(!ctx.is_pure_audio()); + + ctx.set(100, SrsTsPidApplyPAT); + ctx.set(101, SrsTsPidApplyPMT); + ctx.set(102, SrsTsPidApplyVideo); + ctx.set(102, SrsTsPidApplyVideo); + + ctx.on_pmt_parsed(); + EXPECT_TRUE(!ctx.is_pure_audio()); + + EXPECT_EQ(100, ctx.get(100)->pid); + } + if (true) { MockTsHandler* h = new MockTsHandler(); srs_freep(h); @@ -3309,6 +3355,48 @@ VOID TEST(KernelTSTest, CoverBasicUtility) EXPECT_TRUE(ctx.is_pure_audio()); EXPECT_EQ(100, ctx.get(100)->pid); + EXPECT_TRUE(NULL == ctx.get(200)); + } + + if (true) { + SrsTsContext ctx; + EXPECT_EQ(0x47, ctx.sync_byte); + + ctx.set_sync_byte(0x01); + EXPECT_EQ(0x01, ctx.sync_byte); + } +} + +VOID TEST(KernelTSTest, CoverContextCodec) +{ + SrsTsContext ctx; + MockTsHandler h; + + if (true) { + SrsBuffer b; + EXPECT_TRUE(srs_success == ctx.decode(&b, &h)); + EXPECT_TRUE(NULL == h.msg); + } + + if (true) { + SrsBuffer b((char*)"\x00", 1); + + srs_error_t err = ctx.decode(&b, &h); + EXPECT_TRUE(srs_success != err); + srs_freep(err); + } + + if (true) { + MockSrsFileWriter f; + SrsTsMessage m; + + srs_error_t err = ctx.encode(&f, &m, SrsVideoCodecIdDisabled, SrsAudioCodecIdDisabled); + EXPECT_TRUE(srs_success != err); + srs_freep(err); + + err = ctx.encode(&f, &m, SrsVideoCodecIdHEVC, SrsAudioCodecIdOpus); + EXPECT_TRUE(srs_success != err); + srs_freep(err); } } diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp index 7b2adcab2..787920ae3 100644 --- a/trunk/src/utest/srs_utest_kernel.hpp +++ b/trunk/src/utest/srs_utest_kernel.hpp @@ -110,11 +110,13 @@ public: class MockTsHandler : public ISrsTsHandler { +public: + SrsTsMessage* msg; public: MockTsHandler(); virtual ~MockTsHandler(); public: - virtual srs_error_t on_ts_message(SrsTsMessage* msg); + virtual srs_error_t on_ts_message(SrsTsMessage* m); }; #endif