diff --git a/README.md b/README.md index 5a7f7a13d..1101d38f4 100755 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ Other documents: ## V4 changes +* v4.0, 2021-03-24, RTC: Use fast parse TWCCID, 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/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index b31eec2e3..02cc6f5ac 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1122,7 +1122,7 @@ srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data) // 2. Server may send multiple duplicated NACK to client, and got more than one ARQ packet, which also fail SRTP. // so, we must parse the header before SRTP unprotect(which may fail and drop packet). uint16_t twcc_sn = 0; - if ((err = srs_rtp_fast_parse_twcc(data, nb_data, &extension_types_, twcc_sn)) == srs_success) { + if ((err = srs_rtp_fast_parse_twcc(data, nb_data, twcc_id_, twcc_sn)) == srs_success) { if((err = on_twcc(twcc_sn)) != srs_success) { return srs_error_wrap(err, "on twcc"); } diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 0e7f31831..e3c8a3820 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 SRS_VERSION4_REVISION 85 +#define SRS_VERSION4_REVISION 86 #endif diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index 30d42e017..f65e42653 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -80,7 +80,7 @@ uint8_t srs_rtp_fast_parse_pt(char* buf, int size) } return buf[1] & 0x7f; } -srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, SrsRtpExtensionTypes* ext_types, uint16_t& twcc_sn) +srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, uint8_t twcc_id, uint16_t& twcc_sn) { srs_error_t err = srs_success; @@ -129,8 +129,7 @@ srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, SrsRtpExtensionTypes* e uint8_t id = (v & 0xF0) >>4; uint8_t len = (v & 0x0F) + 1; - SrsRtpExtensionType xtype = ext_types->get_type(id); - if(xtype == kRtpExtensionTransportSequenceNumber) { + if(id == twcc_id) { twcc_sn = ntohs(*((uint16_t*)buf)); return err; } else { @@ -348,6 +347,7 @@ SrsRtpExtensions::SrsRtpExtensions() { types_ = NULL; has_ext_ = false; + decode_twcc_extension_ = false; } SrsRtpExtensions::~SrsRtpExtensions() @@ -415,10 +415,17 @@ srs_error_t SrsRtpExtensions::decode_0xbede(SrsBuffer* buf) SrsRtpExtensionType xtype = types_? types_->get_type(id) : kRtpExtensionNone; if (xtype == kRtpExtensionTransportSequenceNumber) { - if ((err = twcc_.decode(buf)) != srs_success) { - return srs_error_wrap(err, "decode twcc extension"); + if (decode_twcc_extension_) { + if ((err = twcc_.decode(buf)) != srs_success) { + return srs_error_wrap(err, "decode twcc extension"); + } + has_ext_ = true; + } else { + if (!buf->require(len+1+1)) { + return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", len+1+1); + } + buf->skip(len + 1 + 1); } - has_ext_ = true; } else if (xtype == kRtpExtensionAudioLevel) { if((err = audio_level_.decode(buf)) != srs_success) { return srs_error_wrap(err, "decode audio level extension"); diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index 5c29d67b5..7b1fe5d24 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -64,7 +64,7 @@ class SrsRtpExtensionTypes; // Fast parse the SSRC from RTP packet. Return 0 if invalid. uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size); uint8_t srs_rtp_fast_parse_pt(char* buf, int size); -srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, SrsRtpExtensionTypes* types, uint16_t& twcc_sn); +srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, uint8_t twcc_id, uint16_t& twcc_sn); // The "distance" between two uint16 number, for example: // distance(prev_value=3, value=5) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)5) === -2 @@ -177,6 +177,8 @@ class SrsRtpExtensions// : public ISrsCodec { private: bool has_ext_; + // by default, twcc isnot decoded. Because it is decoded by fast function(srs_rtp_fast_parse_twcc) + bool decode_twcc_extension_; private: // The extension types is used to decode the packet, which is reference to // the types in publish stream. @@ -188,6 +190,7 @@ public: SrsRtpExtensions(); virtual ~SrsRtpExtensions(); public: + void enable_twcc_decode() { decode_twcc_extension_ = true; } // SrsRtpExtensions::enable_twcc_decode inline bool exists() { return has_ext_; } // SrsRtpExtensions::exists void set_types_(SrsRtpExtensionTypes* types); srs_error_t get_twcc_sequence_number(uint16_t& twcc_sn); @@ -229,6 +232,7 @@ public: virtual srs_error_t encode(SrsBuffer* buf); virtual uint64_t nb_bytes(); public: + void enable_twcc_decode() { extensions_.enable_twcc_decode(); } // SrsRtpHeader::enable_twcc_decode void set_marker(bool v); bool get_marker() const; void set_payload_type(uint8_t v); @@ -326,6 +330,8 @@ public: // Copy the RTP packet. virtual SrsRtpPacket2* copy(); public: + // Parse the TWCC extension, ignore by default. + void enable_twcc_decode() { header.enable_twcc_decode(); } // SrsRtpPacket2::enable_twcc_decode // Get and set the payload of packet. void set_payload(ISrsRtpPayloader* p, SrsRtpPacketPayloadType pt) { payload_ = p; payload_type_ = pt; } ISrsRtpPayloader* payload() { return payload_; }