From bd1752a4b2f37a519a12ac3bcf8b47692886d228 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:47:50 +0800 Subject: [PATCH] RTC: Fix TWCC send bug --- trunk/src/app/srs_app_rtc_conn.cpp | 26 ++++++----- trunk/src/kernel/srs_kernel_rtc_rtcp.cpp | 57 +++++++++++++++++------- trunk/src/kernel/srs_kernel_rtc_rtcp.hpp | 7 +-- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 7bdf38a3c..e5d013853 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1345,23 +1345,25 @@ srs_error_t SrsRtcPublishStream::send_periodic_twcc() ++_srs_pps_srtcps->sugar; - char pkt[kRtcpPacketSize]; - SrsBuffer *buffer = new SrsBuffer(pkt, sizeof(pkt)); - SrsAutoFree(SrsBuffer, buffer); + // limit the max count=1024 to avoid dead loop. + for (int i = 0; i < 1024 && rtcp_twcc_.need_feedback(); ++i) { + char pkt[kMaxUDPDataSize]; + SrsBuffer *buffer = new SrsBuffer(pkt, sizeof(pkt)); + SrsAutoFree(SrsBuffer, buffer); - rtcp_twcc_.set_feedback_count(twcc_fb_count_); - twcc_fb_count_++; + rtcp_twcc_.set_feedback_count(twcc_fb_count_); + twcc_fb_count_++; - if((err = rtcp_twcc_.encode(buffer)) != srs_success) { - return srs_error_wrap(err, "encode, count=%u", twcc_fb_count_); - } + if((err = rtcp_twcc_.encode(buffer)) != srs_success) { + return srs_error_wrap(err, "encode, count=%u", twcc_fb_count_); + } - int nb_protected_buf = buffer->pos(); - if ((err = session_->transport_->protect_rtcp(pkt, &nb_protected_buf)) != srs_success) { - return srs_error_wrap(err, "protect rtcp, size=%u", nb_protected_buf); + if((err = session_->send_rtcp(pkt, buffer->pos())) != srs_success) { + return srs_error_wrap(err, "send twcc, count=%u", twcc_fb_count_); + } } - return session_->sendonly_skt->sendto(pkt, nb_protected_buf, 0); + return err; } srs_error_t SrsRtcPublishStream::on_rtcp(SrsRtcpCommon* rtcp) diff --git a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp index fb91a5bc7..2552887fe 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp @@ -716,9 +716,9 @@ SrsRtcpTWCC::SrsRtcpTWCC(uint32_t sender_ssrc) : pkt_len(0) ssrc_ = sender_ssrc; media_ssrc_ = 0; base_sn_ = 0; - packet_count_ = 0; reference_time_ = 0; fb_pkt_count_ = 0; + next_base_sn_ = 0; } SrsRtcpTWCC::~SrsRtcpTWCC() @@ -731,6 +731,7 @@ void SrsRtcpTWCC::clear() pkt_deltas_.clear(); recv_packets_.clear(); recv_sns_.clear(); + next_base_sn_ = 0; } uint32_t SrsRtcpTWCC::get_media_ssrc() const @@ -751,11 +752,6 @@ uint8_t SrsRtcpTWCC::get_feedback_count() const { return fb_pkt_count_; } - -uint16_t SrsRtcpTWCC::get_packet_status_count() const -{ - return packet_count_; -} vector SrsRtcpTWCC::get_packet_chucks() const { @@ -776,11 +772,6 @@ void SrsRtcpTWCC::set_base_sn(uint16_t sn) base_sn_ = sn; } -void SrsRtcpTWCC::set_packet_status_count(uint16_t count) -{ - packet_count_ = count; -} - void SrsRtcpTWCC::set_reference_time(uint32_t time) { reference_time_ = time; @@ -865,7 +856,7 @@ srs_error_t SrsRtcpTWCC::decode(SrsBuffer *buffer) uint64_t SrsRtcpTWCC::nb_bytes() { - return kRtcpPacketSize; + return kMaxUDPDataSize; } srs_utime_t SrsRtcpTWCC::calculate_delta_us(srs_utime_t ts, srs_utime_t last) @@ -1057,7 +1048,9 @@ srs_error_t SrsRtcpTWCC::encode(SrsBuffer *buffer) err = do_encode(buffer); - clear(); + if (err != srs_success || next_base_sn_ == 0) { + clear(); + } return err; } @@ -1099,21 +1092,41 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) } pkt_len = kTwccFbPktHeaderSize; + set::iterator it_sn = recv_sns_.begin(); - base_sn_ = *it_sn; + if (!next_base_sn_) { + base_sn_ = *it_sn; + } else { + base_sn_ = next_base_sn_; + it_sn = recv_sns_.find(base_sn_); + } + map::iterator it_ts = recv_packets_.find(base_sn_); srs_utime_t ts = it_ts->second; + reference_time_ = (ts % kTwccFbReferenceTimeDivisor) / kTwccFbTimeMultiplier; srs_utime_t last_ts = (srs_utime_t)(reference_time_) * kTwccFbTimeMultiplier; + uint16_t last_sn = base_sn_; - packet_count_ = recv_packets_.size(); + uint16_t packet_count = 0; // encode chunk SrsRtcpTWCC::SrsRtcpTWCCChunk chunk; for(; it_sn != recv_sns_.end(); ++it_sn) { + // check whether exceed buffer len + // max recv_delta_size = 2 + if (pkt_len + 2 >= buffer->left()) { + break; + } + uint16_t current_sn = *it_sn; // calculate delta it_ts = recv_packets_.find(current_sn); + if (it_ts == recv_packets_.end()) { + continue; + } + + packet_count++; srs_utime_t delta_us = calculate_delta_us(it_ts->second, last_ts); int16_t delta = delta_us; if(delta != delta_us) { @@ -1124,7 +1137,7 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) // lost packet for(uint16_t lost_sn = last_sn + 1; lost_sn < current_sn; ++lost_sn) { process_pkt_chunk(chunk, 0); - packet_count_++; + packet_count++; } } @@ -1138,6 +1151,13 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) last_ts += delta * kTwccFbDeltaUnit; pkt_len += recv_delta_size; last_sn = current_sn; + + recv_packets_.erase(it_ts); + } + + next_base_sn_ = 0; + if (it_sn != recv_sns_.end()) { + next_base_sn_ = *it_sn; } if(0 < chunk.size) { @@ -1159,7 +1179,7 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) } buffer->write_4bytes(media_ssrc_); buffer->write_2bytes(base_sn_); - buffer->write_2bytes(packet_count_); + buffer->write_2bytes(packet_count); buffer->write_3bytes(reference_time_); buffer->write_1bytes(fb_pkt_count_); @@ -1181,6 +1201,9 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer) pkt_len++; } + encoded_chucks_.clear(); + pkt_deltas_.clear(); + return err; } diff --git a/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp index 279a08e27..b469b814a 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtcp.hpp @@ -36,6 +36,9 @@ const int kRtcpPacketSize = 1500; const uint8_t kRtcpVersion = 0x2; +// 1500 - 20(ip_header) - 8(udp_header) +const int kMaxUDPDataSize = 1472; + // RTCP Packet Types, @see http://www.networksorcery.com/enp/protocol/rtcp.htm enum SrsRtcpType { @@ -266,7 +269,6 @@ class SrsRtcpTWCC : public SrsRtcpCommon private: uint32_t media_ssrc_; uint16_t base_sn_; - uint16_t packet_count_; int32_t reference_time_; uint8_t fb_pkt_count_; std::vector encoded_chucks_; @@ -284,6 +286,7 @@ private: }; int pkt_len; + uint16_t next_base_sn_; private: void clear(); srs_utime_t calculate_delta_us(srs_utime_t ts, srs_utime_t last); @@ -302,7 +305,6 @@ public: uint32_t get_media_ssrc() const; uint16_t get_base_sn() const; - uint16_t get_packet_status_count() const; uint32_t get_reference_time() const; uint8_t get_feedback_count() const; std::vector get_packet_chucks() const; @@ -310,7 +312,6 @@ public: void set_media_ssrc(uint32_t ssrc); void set_base_sn(uint16_t sn); - void set_packet_status_count(uint16_t count); void set_reference_time(uint32_t time); void set_feedback_count(uint8_t count); void add_packet_chuck(uint16_t chuck);