From 4ad4dd097505905e3e3904d289d20184b7833c58 Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 30 Sep 2022 19:36:20 +0800 Subject: [PATCH] RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71 --- trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_rtc_sdp.cpp | 60 ++++++++++++++++++++++++---- trunk/src/app/srs_app_rtc_sdp.hpp | 6 +++ trunk/src/core/srs_core_version5.hpp | 2 +- 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index c7ac344c9..1b85a3ba8 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2022-09-30, RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71 * v5.0, 2022-09-30, GB28181: Refine HTTP parser to support SIP. v5.0.70 * v5.0, 2022-09-30, Kernel: Support lazy sweeping simple GC. v5.0.69 * v5.0, 2022-09-30, HTTP: Support HTTP header in creating order. v5.0.68 diff --git a/trunk/src/app/srs_app_rtc_sdp.cpp b/trunk/src/app/srs_app_rtc_sdp.cpp index e74602bcd..9d71421fc 100644 --- a/trunk/src/app/srs_app_rtc_sdp.cpp +++ b/trunk/src/app/srs_app_rtc_sdp.cpp @@ -199,6 +199,17 @@ srs_error_t SrsSSRCInfo::encode(std::ostringstream& os) return srs_error_new(ERROR_RTC_SDP_DECODE, "invalid ssrc"); } + // See AnnexF at page 101 of https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89 + // Encode the bellow format: + // a=ssrc:0100008888 cname:0100008888 + // a=ssrc:0100008888 label:gb28181 + // As GB28181 format: + // y=0100008888 + if (label_ == "gb28181") { + os << "y=" << (cname_.empty() ? srs_fmt("%u", ssrc_) : cname_) << kCRLF; + return err; + } + os << "a=ssrc:" << ssrc_ << " cname:" << cname_ << kCRLF; if (!msid_.empty()) { os << "a=ssrc:" << ssrc_ << " msid:" << msid_; @@ -297,6 +308,8 @@ SrsMediaDesc::SrsMediaDesc(const std::string& type) recvonly_ = false; sendonly_ = false; inactive_ = false; + + connection_ = "c=IN IP4 0.0.0.0"; } SrsMediaDesc::~SrsMediaDesc() @@ -380,13 +393,13 @@ srs_error_t SrsMediaDesc::encode(std::ostringstream& os) os << kCRLF; // TODO:nettype and address type - os << "c=IN IP4 0.0.0.0" << kCRLF; + if (!connection_.empty()) os << connection_ << kCRLF; if ((err = session_info_.encode(os)) != srs_success) { return srs_error_wrap(err, "encode session info failed"); } - os << "a=mid:" << mid_ << kCRLF; + if (!mid_.empty()) os << "a=mid:" << mid_ << kCRLF; if (!msid_.empty()) { os << "a=msid:" << msid_; @@ -738,6 +751,8 @@ SrsSdp::SrsSdp() start_time_ = 0; end_time_ = 0; + + ice_lite_ = "a=ice-lite"; } SrsSdp::~SrsSdp() @@ -818,9 +833,12 @@ srs_error_t SrsSdp::encode(std::ostringstream& os) os << "v=" << version_ << kCRLF; os << "o=" << username_ << " " << session_id_ << " " << session_version_ << " " << nettype_ << " " << addrtype_ << " " << unicast_address_ << kCRLF; os << "s=" << session_name_ << kCRLF; + // Session level connection data, see https://www.ietf.org/rfc/rfc4566.html#section-5.7 + if (!connection_.empty()) os << connection_ << kCRLF; + // Timing, see https://www.ietf.org/rfc/rfc4566.html#section-5.9 os << "t=" << start_time_ << " " << end_time_ << kCRLF; // ice-lite is a minimal version of the ICE specification, intended for servers running on a public IP address. - os << "a=ice-lite" << kCRLF; + if (!ice_lite_.empty()) os << ice_lite_ << kCRLF; if (!groups_.empty()) { os << "a=group:" << group_policy_; @@ -830,11 +848,13 @@ srs_error_t SrsSdp::encode(std::ostringstream& os) os << kCRLF; } - os << "a=msid-semantic: " << msid_semantic_; - for (std::vector::iterator iter = msids_.begin(); iter != msids_.end(); ++iter) { - os << " " << *iter; + if (!msid_semantic_.empty() || !msids_.empty()) { + os << "a=msid-semantic: " << msid_semantic_; + for (std::vector::iterator iter = msids_.begin(); iter != msids_.end(); ++iter) { + os << " " << *iter; + } + os << kCRLF; } - os << kCRLF; if ((err = session_info_.encode(os)) != srs_success) { return srs_error_wrap(err, "encode session info failed"); @@ -976,6 +996,9 @@ srs_error_t SrsSdp::parse_line(const std::string& line) } return parse_attribute(content); } + case 'y': { + return parse_gb28181_ssrc(content); + } case 'm': { return parse_media_description(content); } @@ -1081,6 +1104,29 @@ srs_error_t SrsSdp::parse_attribute(const std::string& content) return err; } +srs_error_t SrsSdp::parse_gb28181_ssrc(const std::string& content) +{ + srs_error_t err = srs_success; + + // See AnnexF at page 101 of https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89 + // Convert SSRC of GB28181 from: + // y=0100008888 + // to standard format: + // a=ssrc:0100008888 cname:0100008888 + // a=ssrc:0100008888 label:gb28181 + string cname = srs_fmt("a=ssrc:%s cname:%s", content.c_str(), content.c_str()); + if ((err = media_descs_.back().parse_line(cname)) != srs_success) { + return srs_error_wrap(err, "parse gb %s cname", content.c_str()); + } + + string label = srs_fmt("a=ssrc:%s label:gb28181", content.c_str()); + if ((err = media_descs_.back().parse_line(label)) != srs_success) { + return srs_error_wrap(err, "parse gb %s label", content.c_str()); + } + + return err; +} + srs_error_t SrsSdp::parse_attr_group(const std::string& value) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_rtc_sdp.hpp b/trunk/src/app/srs_app_rtc_sdp.hpp index 448dc88e5..a132fa369 100644 --- a/trunk/src/app/srs_app_rtc_sdp.hpp +++ b/trunk/src/app/srs_app_rtc_sdp.hpp @@ -172,6 +172,7 @@ public: std::string msid_tracker_; std::string protos_; std::vector payload_types_; + std::string connection_; std::vector candidates_; std::vector ssrc_groups_; @@ -208,6 +209,7 @@ private: srs_error_t parse_session_name(const std::string& content); srs_error_t parse_timing(const std::string& content); srs_error_t parse_attribute(const std::string& content); + srs_error_t parse_gb28181_ssrc(const std::string& content); srs_error_t parse_media_description(const std::string& content); srs_error_t parse_attr_group(const std::string& content); private: @@ -231,6 +233,9 @@ public: int64_t start_time_; int64_t end_time_; + // Connection data, see https://www.ietf.org/rfc/rfc4566.html#section-5.7 + std::string connection_; + SrsSessionInfo session_info_; SrsSessionConfig session_config_; SrsSessionConfig session_negotiate_; @@ -238,6 +243,7 @@ public: std::vector groups_; std::string group_policy_; + std::string ice_lite_; std::string msid_semantic_; std::vector msids_; diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index eb2d9c323..22d993e86 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 70 +#define VERSION_REVISION 71 #endif