From 4d5c7e0a7319c52ae2ac671de93e6f11f4d63d4b Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:21:19 +0800 Subject: [PATCH 1/5] RTC: Fix object cache bug, reset payload when recycle --- trunk/src/kernel/srs_kernel_rtc_rtp.cpp | 16 ++++++++++++++++ trunk/src/kernel/srs_kernel_rtc_rtp.hpp | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index 4b60ca353..d4f5d01a1 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -1078,6 +1078,12 @@ SrsRtpRawPayload::~SrsRtpRawPayload() { } +bool SrsRtpRawPayload::recycle() +{ + payload=NULL; nn_payload=0; + return true; +} + uint64_t SrsRtpRawPayload::nb_bytes() { return nn_payload; @@ -1538,6 +1544,16 @@ SrsRtpFUAPayload2::~SrsRtpFUAPayload2() { } +bool SrsRtpFUAPayload2::recycle() +{ + start = end = false; + nri = nalu_type = (SrsAvcNaluType)0; + + payload = NULL; + size = 0; + return true; +} + uint64_t SrsRtpFUAPayload2::nb_bytes() { return 2 + size; diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index 09ce5c716..2433e92cf 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -473,7 +473,7 @@ public: SrsRtpRawPayload(); virtual ~SrsRtpRawPayload(); public: - bool recycle() { return true; } + bool recycle(); // interface ISrsRtpPayloader public: virtual uint64_t nb_bytes(); @@ -573,7 +573,7 @@ public: SrsRtpFUAPayload2(); virtual ~SrsRtpFUAPayload2(); public: - bool recycle() { return true; } + bool recycle(); // interface ISrsRtpPayloader public: virtual uint64_t nb_bytes(); From f4b791a9d5e78e1259be39c3737adcbe38214862 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:22:07 +0800 Subject: [PATCH 2/5] Kernel: Never assert for SrsBuffer::require --- trunk/src/kernel/srs_kernel_buffer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trunk/src/kernel/srs_kernel_buffer.cpp b/trunk/src/kernel/srs_kernel_buffer.cpp index ff5cdbeb8..6e7e45754 100644 --- a/trunk/src/kernel/srs_kernel_buffer.cpp +++ b/trunk/src/kernel/srs_kernel_buffer.cpp @@ -99,7 +99,9 @@ bool SrsBuffer::empty() bool SrsBuffer::require(int required_size) { - srs_assert(required_size >= 0); + if (required_size < 0) { + return false; + } return required_size <= nb_bytes - (p - bytes); } From 7ac4a4f4ca260a895d2bb573f8f778d804b39c81 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:24:37 +0800 Subject: [PATCH 3/5] RTC: Fix audio track description bug --- trunk/src/app/srs_app_rtc_conn.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e28ab2f42..7bdf38a3c 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -941,7 +941,10 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcStreamDescripti req = r->copy(); - audio_tracks_.push_back(new SrsRtcAudioRecvTrack(session_, stream_desc->audio_track_desc_)); + if (stream_desc->audio_track_desc_) { + audio_tracks_.push_back(new SrsRtcAudioRecvTrack(session_, stream_desc->audio_track_desc_)); + } + for (int i = 0; i < (int)stream_desc->video_track_descs_.size(); ++i) { SrsRtcTrackDescription* desc = stream_desc->video_track_descs_.at(i); video_tracks_.push_back(new SrsRtcVideoRecvTrack(session_, desc)); @@ -1862,7 +1865,8 @@ srs_error_t SrsRtcConnection::add_player(SrsRequest* req, const SrsSdp& remote_s while (it != play_sub_relations.end()) { SrsRtcTrackDescription* track_desc = it->second; - if (track_desc->type_ == "audio" || !stream_desc->audio_track_desc_) { + // TODO: FIXME: we only support one audio track. + if (track_desc->type_ == "audio" && !stream_desc->audio_track_desc_) { stream_desc->audio_track_desc_ = track_desc->copy(); } From bd1752a4b2f37a519a12ac3bcf8b47692886d228 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:47:50 +0800 Subject: [PATCH 4/5] RTC: Fix TWCC send bug --- trunk/src/app/srs_app_rtc_conn.cpp | 28 ++++++------ trunk/src/kernel/srs_kernel_rtc_rtcp.cpp | 57 +++++++++++++++++------- trunk/src/kernel/srs_kernel_rtc_rtcp.hpp | 7 +-- 3 files changed, 59 insertions(+), 33 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_); + } + + if((err = session_->send_rtcp(pkt, buffer->pos())) != srs_success) { + return srs_error_wrap(err, "send twcc, 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); - } - - 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); From aa5d872b8c42bd5ef7eabc924771f274dad7cdab Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 1 Apr 2021 10:50:20 +0800 Subject: [PATCH 5/5] RTC: Refine TWCC and SDP exchange. 4.0.88 --- README.md | 3 ++- trunk/src/core/srs_core_version4.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ae624f9a0..81ba1ebd0 100755 --- a/README.md +++ b/README.md @@ -190,8 +190,9 @@ Other documents: ## V4 changes +* v4.0, 2021-04-01, RTC: Refine TWCC and SDP exchange. 4.0.88 * v4.0, 2021-03-24, RTC: Support WebRTC re-publish stream. 4.0.87 -* v4.0, 2021-03-24, RTC: Use fast parse TWCCID, ignore in packet parsing. 4.0.86 +* v4.0, 2021-03-24, RTC: Use fast parse TWCC-ID, ignore in packet parsing. 4.0.86 * v4.0, 2021-03-09, DTLS: Fix ARQ bug, use openssl timeout. 4.0.84 * v4.0, 2021-03-08, DTLS: Fix dead loop by duplicated Alert message. 4.0.83 * v4.0, 2021-03-08, Fix bug when client DTLS is passive. 4.0.82 diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 2add34d5b..42f973eaa 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -26,6 +26,6 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 87 +#define VERSION_REVISION 88 #endif