From 51a5e283fc08f231bb95e8a645865e0ee3ff5c82 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 28 Feb 2021 07:27:14 +0800 Subject: [PATCH] Perf: Avoid RTP packet copy for publisher NACK. --- trunk/src/app/srs_app_rtc_conn.cpp | 27 +++++++++++++++++---------- trunk/src/app/srs_app_rtc_conn.hpp | 2 +- trunk/src/app/srs_app_rtc_source.cpp | 23 +++++------------------ trunk/src/app/srs_app_rtc_source.hpp | 10 ++++------ 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 57a428e7d..9ede8164c 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -924,15 +924,6 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcStreamDescripti srs_trace("RTC publisher nack=%d, pt-drop=%u, twcc=%u/%d", nack_enabled_, pt_to_drop_, twcc_enabled_, twcc_id); - for (vector::iterator it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) { - SrsRtcAudioRecvTrack* track = *it; - track->set_nack_enabled(nack_enabled_); - } - for (vector::iterator it = video_tracks_.begin(); it != video_tracks_.end(); ++it) { - SrsRtcVideoRecvTrack* track = *it; - track->set_nack_enabled(nack_enabled_); - } - // Update stat for session. session_->stat_->nn_publishers++; @@ -1162,6 +1153,8 @@ srs_error_t SrsRtcPublishStream::on_rtp_plaintext(char* plaintext, int nb_plaint // Handle the packet. SrsBuffer buf(p, nb_plaintext); + + // @remark Note that the pkt might be set to NULL. err = do_on_rtp_plaintext(pkt, &buf); // Release the packet to cache. @@ -1170,7 +1163,7 @@ srs_error_t SrsRtcPublishStream::on_rtp_plaintext(char* plaintext, int nb_plaint return err; } -srs_error_t SrsRtcPublishStream::do_on_rtp_plaintext(SrsRtpPacket2* pkt, SrsBuffer* buf) +srs_error_t SrsRtcPublishStream::do_on_rtp_plaintext(SrsRtpPacket2*& pkt, SrsBuffer* buf) { srs_error_t err = srs_success; @@ -1206,6 +1199,20 @@ srs_error_t SrsRtcPublishStream::do_on_rtp_plaintext(SrsRtpPacket2* pkt, SrsBuff } } + // For NACK to handle packet. + // @remark Note that the pkt might be set to NULL. + if (nack_enabled_) { + if (audio_track) { + if ((err = audio_track->on_nack(&pkt)) != srs_success) { + return srs_error_wrap(err, "on nack"); + } + } else if (video_track) { + if ((err = video_track->on_nack(&pkt)) != srs_success) { + return srs_error_wrap(err, "on nack"); + } + } + } + return err; } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index f3aa8e2e4..eacc8e6e9 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -325,7 +325,7 @@ private: // @remark We copy the plaintext, user should free it. srs_error_t on_rtp_plaintext(char* plaintext, int nb_plaintext); private: - srs_error_t do_on_rtp_plaintext(SrsRtpPacket2* pkt, SrsBuffer* buf); + srs_error_t do_on_rtp_plaintext(SrsRtpPacket2*& pkt, SrsBuffer* buf); public: srs_error_t check_send_nacks(); public: diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index fb62a374c..c0c87785c 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1729,7 +1729,6 @@ SrsRtcRecvTrack::SrsRtcRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescripti session_ = session; track_desc_ = track_desc->copy(); statistic_ = new SrsRtcTrackStatistic(); - nack_enabled_ = false; if (is_audio) { rtp_queue_ = new SrsRtpRingBuffer(100); @@ -1750,11 +1749,6 @@ SrsRtcRecvTrack::~SrsRtcRecvTrack() srs_freep(statistic_); } -void SrsRtcRecvTrack::set_nack_enabled(bool v) -{ - nack_enabled_ = v; -} - bool SrsRtcRecvTrack::has_ssrc(uint32_t ssrc) { return track_desc_->has_ssrc(ssrc); @@ -1818,10 +1812,11 @@ std::string SrsRtcRecvTrack::get_track_id() return track_desc_->id_; } -srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket2* pkt) +srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket2** ppkt) { srs_error_t err = srs_success; + SrsRtpPacket2* pkt = *ppkt; uint16_t seq = pkt->header.get_sequence(); SrsRtpNackInfo* nack_info = nack_receiver_->find(seq); if (nack_info) { @@ -1842,7 +1837,9 @@ srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket2* pkt) } // insert into video_queue and audio_queue - rtp_queue_->set(seq, pkt->copy()); + // We directly use the pkt, never copy it, so we should set the pkt to NULL. + rtp_queue_->set(seq, pkt); + *ppkt = NULL; return err; } @@ -1893,11 +1890,6 @@ srs_error_t SrsRtcAudioRecvTrack::on_rtp(SrsRtcStream* source, SrsRtpPacket2* pk return srs_error_wrap(err, "source on rtp"); } - // For NACK to handle packet. - if (nack_enabled_ && (err = on_nack(pkt)) != srs_success) { - return srs_error_wrap(err, "on nack"); - } - return err; } @@ -1961,11 +1953,6 @@ srs_error_t SrsRtcVideoRecvTrack::on_rtp(SrsRtcStream* source, SrsRtpPacket2* pk return srs_error_wrap(err, "source on rtp"); } - // For NACK to handle packet. - if (nack_enabled_ && (err = on_nack(pkt)) != srs_success) { - return srs_error_wrap(err, "on nack"); - } - return err; } diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index a267adf57..aed39ec31 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -510,9 +510,6 @@ public: class SrsRtcRecvTrack { protected: - // Whether enabled nack. - bool nack_enabled_; - SrsRtcTrackDescription* track_desc_; SrsRtcTrackStatistic* statistic_; @@ -527,7 +524,6 @@ public: SrsRtcRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescription* stream_descs, bool is_audio); virtual ~SrsRtcRecvTrack(); public: - void set_nack_enabled(bool v); bool has_ssrc(uint32_t ssrc); uint32_t get_ssrc(); void update_rtt(int rtt); @@ -537,8 +533,10 @@ public: bool set_track_status(bool active); bool get_track_status(); std::string get_track_id(); -protected: - srs_error_t on_nack(SrsRtpPacket2* pkt); +public: + // Note that we can set the pkt to NULL to avoid copy, for example, if the NACK cache the pkt and + // set to NULL, nack nerver copy it but set the pkt to NULL. + srs_error_t on_nack(SrsRtpPacket2** ppkt); public: virtual srs_error_t on_rtp(SrsRtcStream* source, SrsRtpPacket2* pkt) = 0; virtual srs_error_t check_send_nacks() = 0;