From 4e70bf5eaf5e4a8960e671b4d502b251dc740fae Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 15 Jan 2021 14:16:32 +0800 Subject: [PATCH] For #2142, Fix memory leak for bridger of RTC source stream. 4.0.61 --- trunk/src/app/srs_app_rtc_source.cpp | 70 +++++++++++++++++++--------- trunk/src/app/srs_app_rtc_source.hpp | 12 ++++- trunk/src/core/srs_core_version4.hpp | 2 +- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index c3f54a353..0503d2f96 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -309,11 +309,7 @@ SrsRtcStream::SrsRtcStream() stream_desc_ = NULL; req = NULL; -#ifdef SRS_FFMPEG_FIT - bridger_ = new SrsRtcFromRtmpBridger(this); -#else - bridger_ = new SrsRtcDummyBridger(); -#endif + bridger_ = new SrsRtcDummyBridger(this); } SrsRtcStream::~SrsRtcStream() @@ -333,13 +329,6 @@ srs_error_t SrsRtcStream::initialize(SrsRequest* r) req = r->copy(); -#ifdef SRS_FFMPEG_FIT - SrsRtcFromRtmpBridger* bridger = dynamic_cast(bridger_); - if ((err = bridger->initialize(req)) != srs_success) { - return srs_error_wrap(err, "bridge initialize"); - } -#endif - return err; } @@ -454,6 +443,16 @@ srs_error_t SrsRtcStream::on_publish() return srs_error_wrap(err, "source id change"); } + // Create a new bridger, because it's been disposed when unpublish. +#ifdef SRS_FFMPEG_FIT + SrsRtcFromRtmpBridger* impl = new SrsRtcFromRtmpBridger(this); + if ((err = impl->initialize(req)) != srs_success) { + return srs_error_wrap(err, "bridge initialize"); + } + + bridger_->setup(impl); +#endif + // TODO: FIXME: Handle by statistic. return err; @@ -484,6 +483,11 @@ void SrsRtcStream::on_unpublish() // release unpublish stream description. set_stream_desc(NULL); + // Dispose the impl of bridger, to free memory. +#ifdef SRS_FFMPEG_FIT + bridger_->setup(NULL); +#endif + // TODO: FIXME: Handle by statistic. } @@ -663,13 +667,14 @@ srs_error_t SrsRtcFromRtmpBridger::on_publish() void SrsRtcFromRtmpBridger::on_unpublish() { - // TODO: FIXME: Should sync with bridger? - source_->on_unpublish(); - // Reset the metadata cache, to make VLC happy when disable/enable stream. // @see https://github.com/ossrs/srs/issues/1630#issuecomment-597979448 meta->update_previous_vsh(); meta->update_previous_ash(); + + // @remark This bridger might be disposed here, so never use it. + // TODO: FIXME: Should sync with bridger? + source_->on_unpublish(); } srs_error_t SrsRtcFromRtmpBridger::on_audio(SrsSharedPtrMessage* msg) @@ -1147,31 +1152,54 @@ srs_error_t SrsRtcFromRtmpBridger::consume_packets(vector& pkts) } #endif -SrsRtcDummyBridger::SrsRtcDummyBridger() +SrsRtcDummyBridger::SrsRtcDummyBridger(SrsRtcStream* s) { + rtc_ = s; + impl_ = NULL; } SrsRtcDummyBridger::~SrsRtcDummyBridger() { + srs_freep(impl_); } srs_error_t SrsRtcDummyBridger::on_publish() { - return srs_error_new(ERROR_RTC_DUMMY_BRIDGER, "no FFmpeg fit"); + if (impl_) { + return impl_->on_publish(); + } + return rtc_->on_publish(); } -srs_error_t SrsRtcDummyBridger::on_audio(SrsSharedPtrMessage* /*audio*/) +srs_error_t SrsRtcDummyBridger::on_audio(SrsSharedPtrMessage* audio) { - return srs_error_new(ERROR_RTC_DUMMY_BRIDGER, "no FFmpeg fit"); + if (impl_) { + return impl_->on_audio(audio); + } + return srs_success; } -srs_error_t SrsRtcDummyBridger::on_video(SrsSharedPtrMessage* /*video*/) +srs_error_t SrsRtcDummyBridger::on_video(SrsSharedPtrMessage* video) { - return srs_error_new(ERROR_RTC_DUMMY_BRIDGER, "no FFmpeg fit"); + if (impl_) { + return impl_->on_video(video); + } + return srs_success; } void SrsRtcDummyBridger::on_unpublish() { + if (impl_) { + impl_->on_unpublish(); + return; + } + rtc_->on_unpublish(); +} + +void SrsRtcDummyBridger::setup(ISrsSourceBridger* impl) +{ + srs_freep(impl_); + impl_ = impl; } SrsCodecPayload::SrsCodecPayload() diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index e2b7d5f2b..bdc841bbe 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -55,6 +55,7 @@ class SrsRtpNackForReceiver; class SrsJsonObject; class SrsRtcPlayStreamStatistic; class SrsErrorPithyPrint; +class SrsRtcDummyBridger; class SrsNtp { @@ -159,7 +160,7 @@ private: SrsRequest* req; ISrsRtcPublishStream* publish_stream_; // Transmux RTMP to RTC. - ISrsSourceBridger* bridger_; + SrsRtcDummyBridger* bridger_; // Steam description for this steam. SrsRtcStreamDescription* stream_desc_; private: @@ -264,14 +265,21 @@ private: class SrsRtcDummyBridger : public ISrsSourceBridger { +private: + SrsRtcStream* rtc_; + // The optional implementation bridger, ignore if NULL. + ISrsSourceBridger* impl_; public: - SrsRtcDummyBridger(); + SrsRtcDummyBridger(SrsRtcStream* s); virtual ~SrsRtcDummyBridger(); public: virtual srs_error_t on_publish(); virtual srs_error_t on_audio(SrsSharedPtrMessage* audio); virtual srs_error_t on_video(SrsSharedPtrMessage* video); virtual void on_unpublish(); +public: + // Setup a new implementation bridger, which might be NULL to free previous one. + void setup(ISrsSourceBridger* impl); }; // TODO: FIXME: Rename it. diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 603d1bab4..703765e60 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 59 +#define SRS_VERSION4_REVISION 61 #endif