diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 42f86cf70..f7b72048d 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1272,6 +1272,11 @@ void SrsRtcPublishStream::request_keyframe(uint32_t ssrc) session_->stat_->nn_pli++; } +void SrsRtcPublishStream::on_consumers_finished() +{ + session_->on_consumers_finished(req->get_stream_url()); +} + srs_error_t SrsRtcPublishStream::notify(int type, srs_utime_t interval, srs_utime_t tick) { srs_error_t err = srs_success; @@ -1863,6 +1868,13 @@ srs_error_t SrsRtcConnection::on_rtcp_feedback_remb(SrsRtcpPsfbCommon *rtcp) return srs_success; } +void SrsRtcConnection::on_consumers_finished(std::string url) +{ + if (hijacker_) { + hijacker_->on_consumers_finished(url); + } +} + void SrsRtcConnection::set_hijacker(ISrsRtcConnectionHijacker* h) { hijacker_ = h; diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 98e22c866..c2a037a4b 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -321,6 +321,7 @@ private: srs_error_t on_rtcp_xr(SrsRtcpXr* rtcp); public: void request_keyframe(uint32_t ssrc); + void on_consumers_finished(); // interface ISrsHourGlass public: virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick); @@ -362,6 +363,8 @@ public: virtual ~ISrsRtcConnectionHijacker(); public: virtual srs_error_t on_dtls_done() = 0; + // Notify when all consumers of publisher(specified by url) is finished. + virtual void on_consumers_finished(std::string url) = 0; }; // A RTC Peer Connection, SDP level object. @@ -450,6 +453,8 @@ private: public: srs_error_t on_rtcp_feedback_twcc(char* buf, int nb_buf); srs_error_t on_rtcp_feedback_remb(SrsRtcpPsfbCommon *rtcp); +public: + void on_consumers_finished(std::string url); void set_hijacker(ISrsRtcConnectionHijacker* h); public: srs_error_t on_connection_established(); diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 8b9b8e1b8..452083fc6 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -406,6 +406,11 @@ void SrsRtcStream::on_consumer_destroy(SrsRtcConsumer* consumer) if (it != consumers.end()) { consumers.erase(it); } + + // When all consumers finished, notify publisher to handle it. + if (publish_stream_ && consumers.empty()) { + publish_stream_->on_consumers_finished(); + } } bool SrsRtcStream::can_publish() diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index 005a875a4..09893c6a1 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -129,7 +129,10 @@ public: ISrsRtcPublishStream(); virtual ~ISrsRtcPublishStream(); public: + // Request keyframe(PLI) from publisher, for fresh consumer. virtual void request_keyframe(uint32_t ssrc) = 0; + // Notify publisher that all consumers is finished. + virtual void on_consumers_finished() = 0; }; // A Source is a stream, to publish and to play with, binding to SrsRtcPublishStream and SrsRtcPlayStream.