From 4c39cc7c2f6374145515e3a710423f34d8933e82 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 24 Mar 2021 12:29:17 +0800 Subject: [PATCH 1/3] RTC: Use fast parse TWCCID, ignore in packet parsing. 4.0.86 1. TWCC should not be passed from end to end. 2. Publisher TWCC information, should be ignore when pass to player 3. Player should regenerate its own TWCC. --- README.md | 1 + trunk/src/app/srs_app_rtc_conn.cpp | 2 +- trunk/src/core/srs_core_version4.hpp | 2 +- trunk/src/kernel/srs_kernel_rtc_rtp.cpp | 19 +++++++++++++------ trunk/src/kernel/srs_kernel_rtc_rtp.hpp | 8 +++++++- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e24dd9c03..89646ae61 100755 --- a/README.md +++ b/README.md @@ -190,6 +190,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 536ab2d10..4fdee4cf2 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 ddca1c39d..6a0585266 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#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_; } From 6c7e24fc6d8929122cb4cd96c0a2a2bdbb2c4be1 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 24 Mar 2021 15:21:40 +0800 Subject: [PATCH 2/3] RTC: Eliminate dead code, we nerver send offer --- trunk/src/app/srs_app_rtc_conn.cpp | 47 ------------------- trunk/src/app/srs_app_rtc_conn.hpp | 2 - trunk/src/app/srs_app_rtc_server.cpp | 70 ---------------------------- trunk/src/app/srs_app_rtc_server.hpp | 4 -- 4 files changed, 123 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 4fdee4cf2..5dceaabb8 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1856,53 +1856,6 @@ srs_error_t SrsRtcConnection::add_player(SrsRequest* req, const SrsSdp& remote_s return err; } -srs_error_t SrsRtcConnection::add_player2(SrsRequest* req, bool unified_plan, SrsSdp& local_sdp) -{ - srs_error_t err = srs_success; - - if (_srs_rtc_hijacker) { - if ((err = _srs_rtc_hijacker->on_before_play(this, req)) != srs_success) { - return srs_error_wrap(err, "before play"); - } - } - - std::map play_sub_relations; - if ((err = fetch_source_capability(req, play_sub_relations)) != srs_success) { - return srs_error_wrap(err, "play negotiate"); - } - - if (!play_sub_relations.size()) { - return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no play relations"); - } - - SrsRtcStreamDescription* stream_desc = new SrsRtcStreamDescription(); - SrsAutoFree(SrsRtcStreamDescription, stream_desc); - - std::map::iterator it = play_sub_relations.begin(); - while (it != play_sub_relations.end()) { - SrsRtcTrackDescription* track_desc = it->second; - - if (track_desc->type_ == "audio" || !stream_desc->audio_track_desc_) { - stream_desc->audio_track_desc_ = track_desc->copy(); - } - - if (track_desc->type_ == "video") { - stream_desc->video_track_descs_.push_back(track_desc->copy()); - } - ++it; - } - - if ((err = generate_play_local_sdp(req, local_sdp, stream_desc, unified_plan)) != srs_success) { - return srs_error_wrap(err, "generate local sdp"); - } - - if ((err = create_player(req, play_sub_relations)) != srs_success) { - return srs_error_wrap(err, "create player"); - } - - return err; -} - srs_error_t SrsRtcConnection::initialize(SrsRequest* r, bool dtls, bool srtp, string username) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 4f0373a46..767d6b0dd 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -475,8 +475,6 @@ public: public: srs_error_t add_publisher(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp); srs_error_t add_player(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp); - // server send offer sdp to client, local sdp derivate from source stream desc. - srs_error_t add_player2(SrsRequest* request, bool unified_plan, SrsSdp& local_sdp); public: // Before initialize, user must set the local SDP, which is used to inititlize DTLS. srs_error_t initialize(SrsRequest* r, bool dtls, bool srtp, std::string username); diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp index 9b0300682..6ca4cfbf4 100644 --- a/trunk/src/app/srs_app_rtc_server.cpp +++ b/trunk/src/app/srs_app_rtc_server.cpp @@ -624,76 +624,6 @@ srs_error_t SrsRtcServer::do_create_session( return err; } -srs_error_t SrsRtcServer::create_session2(SrsRequest* req, SrsSdp& local_sdp, const std::string& mock_eip, bool unified_plan, SrsRtcConnection** psession) -{ - srs_error_t err = srs_success; - - SrsContextId cid = _srs_context->get_id(); - - std::string local_pwd = srs_random_str(32); - // TODO: FIXME: Collision detect. - std::string local_ufrag = srs_random_str(8); - - SrsRtcConnection* session = new SrsRtcConnection(this, cid); - // first add player for negotiate local sdp media info - if ((err = session->add_player2(req, unified_plan, local_sdp)) != srs_success) { - srs_freep(session); - return srs_error_wrap(err, "add player2"); - } - *psession = session; - - local_sdp.set_dtls_role("actpass"); - local_sdp.set_ice_ufrag(local_ufrag); - local_sdp.set_ice_pwd(local_pwd); - local_sdp.set_fingerprint_algo("sha-256"); - local_sdp.set_fingerprint(_srs_rtc_dtls_certificate->get_fingerprint()); - - // We allows to mock the eip of server. - if (!mock_eip.empty()) { - string host; - int port = _srs_config->get_rtc_server_listen(); - srs_parse_hostport(mock_eip, host, port); - - local_sdp.add_candidate(host, port, "host"); - srs_trace("RTC: Use candidate mock_eip %s as %s:%d", mock_eip.c_str(), host.c_str(), port); - } else { - std::vector candidate_ips = get_candidate_ips(); - for (int i = 0; i < (int)candidate_ips.size(); ++i) { - local_sdp.add_candidate(candidate_ips[i], _srs_config->get_rtc_server_listen(), "host"); - } - srs_trace("RTC: Use candidates %s", srs_join_vector_string(candidate_ips, ", ").c_str()); - } - - session->set_local_sdp(local_sdp); - session->set_state(WAITING_ANSWER); - - return err; -} - -srs_error_t SrsRtcServer::setup_session2(SrsRtcConnection* session, SrsRequest* req, const SrsSdp& remote_sdp) -{ - srs_error_t err = srs_success; - - if (session->state() != WAITING_ANSWER) { - return err; - } - - // TODO: FIXME: Collision detect. - string username = session->get_local_sdp()->get_ice_ufrag() + ":" + remote_sdp.get_ice_ufrag(); - - if ((err = session->initialize(req, true, true, username)) != srs_success) { - return srs_error_wrap(err, "init"); - } - - // We allows username is optional, but it never empty here. - _srs_rtc_manager->add_with_name(username, session); - - session->set_remote_sdp(remote_sdp); - session->set_state(WAITING_STUN); - - return err; -} - SrsRtcConnection* SrsRtcServer::find_session_by_username(const std::string& username) { ISrsResource* conn = _srs_rtc_manager->find_by_name(username); diff --git a/trunk/src/app/srs_app_rtc_server.hpp b/trunk/src/app/srs_app_rtc_server.hpp index 0507666ea..ecae6d980 100644 --- a/trunk/src/app/srs_app_rtc_server.hpp +++ b/trunk/src/app/srs_app_rtc_server.hpp @@ -122,10 +122,6 @@ private: SrsRtcConnection* session, SrsRequest* req, const SrsSdp& remote_sdp, SrsSdp& local_sdp, const std::string& mock_eip, bool publish, bool dtls, bool srtp ); -public: - // We start offering, create_session2 to generate offer, setup_session2 to handle answer. - srs_error_t create_session2(SrsRequest* req, SrsSdp& local_sdp, const std::string& mock_eip, bool unified_plan, SrsRtcConnection** psession); - srs_error_t setup_session2(SrsRtcConnection* session, SrsRequest* req, const SrsSdp& remote_sdp); public: SrsRtcConnection* find_session_by_username(const std::string& ufrag); // interface ISrsHourGlass From 89f941fadc25d0c614994294df5518c5b50b5a70 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 24 Mar 2021 15:24:21 +0800 Subject: [PATCH 3/3] Refine version file --- trunk/src/core/srs_core.hpp | 3 --- trunk/src/core/srs_core_version4.hpp | 4 +++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 0fbe07c39..6eb1e2f2b 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -25,10 +25,7 @@ #define SRS_CORE_HPP // The version config. -#define VERSION_MAJOR 4 -#define VERSION_MINOR 0 #include -#define VERSION_REVISION SRS_VERSION4_REVISION // The macros generated by configure script. #include diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 6a0585266..ef82d1886 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,8 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 86 +#define VERSION_MAJOR 4 +#define VERSION_MINOR 0 +#define VERSION_REVISION 86 #endif