From e2bdacb337caf453076e1147ea46d4ff9e364002 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 19 Jan 2021 17:05:40 +0800 Subject: [PATCH] RTC: Extract NACK handler from stream to track. --- trunk/src/app/srs_app_rtc_conn.cpp | 93 ++++++++-------------------- trunk/src/app/srs_app_rtc_conn.hpp | 1 - trunk/src/app/srs_app_rtc_source.cpp | 28 ++++++++- trunk/src/app/srs_app_rtc_source.hpp | 2 +- 4 files changed, 55 insertions(+), 69 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index f339d707e..915313f07 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -675,53 +675,6 @@ srs_error_t SrsRtcPlayStream::send_packets(SrsRtcStream* source, const vector& pkts, uint32_t ssrc, uint16_t seq) -{ - for (map::iterator it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) { - SrsRtcAudioSendTrack* track = it->second; - - // If track is inactive, not process nack request. - if (!track->get_track_status()){ - continue; - } - - if (!track->has_ssrc(ssrc)) { - continue; - } - - // update recv nack statistic - track->on_recv_nack(); - - SrsRtpPacket2* pkt = track->fetch_rtp_packet(seq); - if (pkt != NULL) { - pkts.push_back(pkt); - } - return; - } - - for (map::iterator it = video_tracks_.begin(); it != video_tracks_.end(); ++it) { - SrsRtcVideoSendTrack* track = it->second; - - // If track is inactive, not process nack request. - if (!track->get_track_status()){ - continue; - } - - if (!track->has_ssrc(ssrc)) { - continue; - } - - // update recv nack statistic - track->on_recv_nack(); - - SrsRtpPacket2* pkt = track->fetch_rtp_packet(seq); - if (pkt != NULL) { - pkts.push_back(pkt); - } - return; - } -} - void SrsRtcPlayStream::set_all_tracks_status(bool status) { std::ostringstream merged_log; @@ -811,36 +764,44 @@ srs_error_t SrsRtcPlayStream::on_rtcp_nack(SrsRtcpNack* rtcp) { srs_error_t err = srs_success; + uint32_t ssrc = rtcp->get_media_ssrc(); + // If NACK disabled, print a log. if (!nack_enabled_) { vector sns = rtcp->get_lost_sns(); - srs_trace("RTC NACK ssrc=%u, seq=%s, ignored", rtcp->get_media_ssrc(), srs_join_vector_string(sns, ",").c_str()); + srs_trace("RTC NACK ssrc=%u, seq=%s, ignored", ssrc, srs_join_vector_string(sns, ",").c_str()); return err; } - // TODO: FIXME: Support ARQ. - vector resend_pkts; + SrsRtcSendTrack* target = NULL; + // Try audio track first. + for (map::iterator it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) { + SrsRtcAudioSendTrack* track = it->second; + if (!track->get_track_status() || !track->has_ssrc(ssrc)) { + continue; + } - vector sns = rtcp->get_lost_sns(); - for(int i = 0; i < (int)sns.size(); ++i) { - uint16_t seq = sns.at(i); - nack_fetch(resend_pkts, rtcp->get_media_ssrc(), seq); + target = track; + break; } - - for (int i = 0; i < (int)resend_pkts.size(); ++i) { - SrsRtpPacket2* pkt = resend_pkts[i]; - info.nn_bytes += pkt->nb_bytes(); - - uint32_t nn = 0; - if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { - srs_trace("RTC NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header.get_sequence(), - pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count, pkt->nb_bytes()); + // If not found, try video track. + for (map::iterator it = video_tracks_.begin(); !target && it != video_tracks_.end(); ++it) { + SrsRtcVideoSendTrack* track = it->second; + if (!track->get_track_status() || !track->has_ssrc(ssrc)) { + continue; } + + target = track; + break; + } + // Error if no track. + if (!target) { + return srs_error_new(ERROR_RTC_NO_TRACK, "no track for %u ssrc", ssrc); } - // By default, we send packets by sendmmsg. - if ((err = session_->do_send_packets(resend_pkts, info)) != srs_success) { - return srs_error_wrap(err, "raw send"); + vector seqs = rtcp->get_lost_sns(); + if((err = target->on_recv_nack(seqs, info)) != srs_success) { + return srs_error_wrap(err, "track response nack. id:%s, ssrc=%u", target->get_track_id().c_str(), ssrc); } session_->stat_->nn_nack++; diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 8b7e2f9cc..724c1f0ab 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -289,7 +289,6 @@ public: virtual srs_error_t cycle(); private: srs_error_t send_packets(SrsRtcStream* source, const std::vector& pkts, SrsRtcPlayStreamStatistic& info); - void nack_fetch(std::vector& pkts, uint32_t ssrc, uint16_t seq); public: // Directly set the status of track, generally for init to set the default value. void set_all_tracks_status(bool status); diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 9213d2676..a77975b98 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -2016,11 +2016,37 @@ std::string SrsRtcSendTrack::get_track_id() return track_desc_->id_; } -void SrsRtcSendTrack::on_recv_nack() +srs_error_t SrsRtcSendTrack::on_recv_nack(const vector& lost_seqs, SrsRtcPlayStreamStatistic& info) { + srs_error_t err = srs_success; + SrsRtcTrackStatistic* statistic = statistic_; statistic->nacks++; + + vector resend_pkts; + for(int i = 0; i < (int)lost_seqs.size(); ++i) { + uint16_t seq = lost_seqs.at(i); + SrsRtpPacket2* pkt = fetch_rtp_packet(seq); + if (pkt == NULL) { + continue; + } + resend_pkts.push_back(pkt); + + info.nn_bytes += pkt->nb_bytes(); + uint32_t nn = 0; + if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { + srs_trace("RTC NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header.get_sequence(), + pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count, pkt->nb_bytes()); + } + } + + // By default, we send packets by sendmmsg. + if ((err = session_->do_send_packets(resend_pkts, info)) != srs_success) { + return srs_error_wrap(err, "raw send"); + } + + return err; } SrsRtcAudioSendTrack::SrsRtcAudioSendTrack(SrsRtcConnection* session, SrsRtcTrackDescription* track_desc) diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index 78564b30c..31125865b 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -582,7 +582,7 @@ public: public: virtual srs_error_t on_rtp(SrsRtpPacket2* pkt, SrsRtcPlayStreamStatistic& info) = 0; virtual srs_error_t on_rtcp(SrsRtpPacket2* pkt) = 0; - virtual void on_recv_nack(); + virtual srs_error_t on_recv_nack(const std::vector& lost_seqs, SrsRtcPlayStreamStatistic& info); }; class SrsRtcAudioSendTrack : public SrsRtcSendTrack