From f63441413d62f1914f554c48c4a5a316e3df4cc5 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 28 Feb 2021 18:51:27 +0800 Subject: [PATCH] RTC: Support disable the NACK no-copy, enable copy by default --- trunk/conf/full.conf | 3 +++ trunk/src/app/srs_app_config.cpp | 22 ++++++++++++++++++++ trunk/src/app/srs_app_config.hpp | 1 + trunk/src/app/srs_app_rtc_conn.cpp | 30 ++++++++++++++++++++++++++-- trunk/src/app/srs_app_rtc_conn.hpp | 2 ++ trunk/src/app/srs_app_rtc_source.cpp | 18 +++++++++++++---- trunk/src/app/srs_app_rtc_source.hpp | 13 ++++++++++-- 7 files changed, 81 insertions(+), 8 deletions(-) diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 8cdbe363e..fa30db474 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -578,6 +578,9 @@ vhost rtc.vhost.srs.com { # Whether support NACK. # default: on enabled on; + # Whether directly use the packet, avoid copy. + # default: off + no_copy off; } # For TWCC. twcc { diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 164def7ef..fa16cc1aa 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -5249,6 +5249,28 @@ bool SrsConfig::get_rtc_nack_enabled(string vhost) return SRS_CONF_PERFER_TRUE(conf->arg0()); } +bool SrsConfig::get_rtc_nack_no_copy(string vhost) +{ + static bool DEFAULT = false; + + SrsConfDirective* conf = get_vhost(vhost); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("nack"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("no_copy"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return SRS_CONF_PERFER_FALSE(conf->arg0()); +} + bool SrsConfig::get_rtc_twcc_enabled(string vhost) { static bool DEFAULT = true; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index a027e5f2f..31e174dc2 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -563,6 +563,7 @@ public: std::string get_rtc_dtls_version(std::string vhost); int get_rtc_drop_for_pt(std::string vhost); bool get_rtc_nack_enabled(std::string vhost); + bool get_rtc_nack_no_copy(std::string vhost); bool get_rtc_twcc_enabled(std::string vhost); // vhost specified section diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 68a581460..f0c9d18e6 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -381,6 +381,7 @@ SrsRtcPlayStream::SrsRtcPlayStream(SrsRtcConnection* s, const SrsContextId& cid) realtime = true; nack_enabled_ = false; + nack_no_copy_ = false; _srs_config->subscribe(this); timer_ = new SrsHourGlass("play", this, 1000 * SRS_UTIME_MILLISECONDS); @@ -446,7 +447,19 @@ srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::mapget_rtc_nack_enabled(req->vhost); - srs_trace("RTC player nack=%d", nack_enabled_); + nack_no_copy_ = _srs_config->get_rtc_nack_no_copy(req->vhost); + srs_trace("RTC player nack=%d, nnc=%d", nack_enabled_, nack_no_copy_); + + // Setup tracks. + for (map::iterator it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) { + SrsRtcAudioSendTrack* track = it->second; + track->set_nack_no_copy(nack_no_copy_); + } + + for (map::iterator it = video_tracks_.begin(); it != video_tracks_.end(); ++it) { + SrsRtcVideoSendTrack* track = it->second; + track->set_nack_no_copy(nack_no_copy_); + } // Update stat for session. session_->stat_->nn_subscribers++; @@ -849,6 +862,7 @@ SrsRtcPublishStream::SrsRtcPublishStream(SrsRtcConnection* session, const SrsCon source = NULL; nn_simulate_nack_drop = 0; nack_enabled_ = false; + nack_no_copy_ = false; pt_to_drop_ = 0; nn_audio_frames = 0; @@ -923,10 +937,22 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcStreamDescripti } nack_enabled_ = _srs_config->get_rtc_nack_enabled(req->vhost); + nack_no_copy_ = _srs_config->get_rtc_nack_no_copy(req->vhost); pt_to_drop_ = (uint16_t)_srs_config->get_rtc_drop_for_pt(req->vhost); twcc_enabled_ = _srs_config->get_rtc_twcc_enabled(req->vhost); - srs_trace("RTC publisher nack=%d, pt-drop=%u, twcc=%u/%d", nack_enabled_, pt_to_drop_, twcc_enabled_, twcc_id); + srs_trace("RTC publisher nack=%d, nnc=%d, pt-drop=%u, twcc=%u/%d", nack_enabled_, nack_no_copy_, pt_to_drop_, twcc_enabled_, twcc_id); + + // Setup tracks. + for (int i = 0; i < (int)audio_tracks_.size(); i++) { + SrsRtcAudioRecvTrack* track = audio_tracks_.at(i); + track->set_nack_no_copy(nack_no_copy_); + } + + for (int i = 0; i < (int)video_tracks_.size(); i++) { + SrsRtcVideoRecvTrack* track = video_tracks_.at(i); + track->set_nack_no_copy(nack_no_copy_); + } // Update stat for session. session_->stat_->nn_publishers++; diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 4d662320b..4f0373a46 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -233,6 +233,7 @@ private: bool realtime; // Whether enabled nack. bool nack_enabled_; + bool nack_no_copy_; private: // Whether palyer started. bool is_started; @@ -287,6 +288,7 @@ private: uint16_t pt_to_drop_; // Whether enabled nack. bool nack_enabled_; + bool nack_no_copy_; bool twcc_enabled_; private: bool request_keyframe_; diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 429b949c7..cc328b176 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1729,6 +1729,7 @@ SrsRtcRecvTrack::SrsRtcRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescripti session_ = session; track_desc_ = track_desc->copy(); statistic_ = new SrsRtcTrackStatistic(); + nack_no_copy_ = false; if (is_audio) { rtp_queue_ = new SrsRtpRingBuffer(100); @@ -1838,8 +1839,12 @@ srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket2** ppkt) // insert into video_queue and audio_queue // We directly use the pkt, never copy it, so we should set the pkt to NULL. - rtp_queue_->set(seq, pkt); - *ppkt = NULL; + if (nack_no_copy_) { + rtp_queue_->set(seq, pkt); + *ppkt = NULL; + } else { + rtp_queue_->set(seq, pkt->copy()); + } return err; } @@ -1983,6 +1988,7 @@ SrsRtcSendTrack::SrsRtcSendTrack(SrsRtcConnection* session, SrsRtcTrackDescripti session_ = session; track_desc_ = track_desc->copy(); statistic_ = new SrsRtcTrackStatistic(); + nack_no_copy_ = false; if (is_audio) { rtp_queue_ = new SrsRtpRingBuffer(100); @@ -2058,8 +2064,12 @@ srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket2** ppkt) // insert into video_queue and audio_queue // We directly use the pkt, never copy it, so we should set the pkt to NULL. - rtp_queue_->set(seq, pkt); - *ppkt = NULL; + if (nack_no_copy_) { + rtp_queue_->set(seq, pkt); + *ppkt = NULL; + } else { + rtp_queue_->set(seq, pkt->copy()); + } return err; } diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index db187faf6..8f29946f3 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -512,11 +512,14 @@ class SrsRtcRecvTrack protected: SrsRtcTrackDescription* track_desc_; SrsRtcTrackStatistic* statistic_; - +protected: SrsRtcConnection* session_; SrsRtpRingBuffer* rtp_queue_; SrsRtpNackForReceiver* nack_receiver_; - +private: + // By config, whether no copy. + bool nack_no_copy_; +protected: // send report ntp and received time. SrsNtp last_sender_report_ntp; uint64_t last_sender_report_sys_time; @@ -524,6 +527,8 @@ public: SrsRtcRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescription* stream_descs, bool is_audio); virtual ~SrsRtcRecvTrack(); public: + // SrsRtcSendTrack::set_nack_no_copy + void set_nack_no_copy(bool v) { nack_no_copy_ = v; } bool has_ssrc(uint32_t ssrc); uint32_t get_ssrc(); void update_rtt(int rtt); @@ -580,12 +585,16 @@ protected: // NACK ARQ ring buffer. SrsRtpRingBuffer* rtp_queue_; private: + // By config, whether no copy. + bool nack_no_copy_; // The pithy print for special stage. SrsErrorPithyPrint* nack_epp; public: SrsRtcSendTrack(SrsRtcConnection* session, SrsRtcTrackDescription* track_desc, bool is_audio); virtual ~SrsRtcSendTrack(); public: + // SrsRtcSendTrack::set_nack_no_copy + void set_nack_no_copy(bool v) { nack_no_copy_ = v; } bool has_ssrc(uint32_t ssrc); SrsRtpPacket2* fetch_rtp_packet(uint16_t seq); bool set_track_status(bool active);