From 2b56e959eafbaa3fcc4c5d0b84aaab3420365beb Mon Sep 17 00:00:00 2001 From: chundonglinlin Date: Wed, 1 Mar 2023 09:00:45 +0800 Subject: [PATCH 1/4] HEVC: webrtc support hevc by parse sdp phase in safari. --- trunk/src/app/srs_app_rtc_conn.cpp | 105 +++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index b26dfa16a2..ff97e237d5 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2674,6 +2674,92 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc track_desc->set_codec_payload((SrsCodecPayload*)video_payload); break; } + } else if (remote_media_desc.is_video() && ruc->codec_ == "hevc") { + srs_trace("remote_media_desc.is_video"); + std::vector payloads = remote_media_desc.find_media_with_encoding_name("H265"); + if (payloads.empty()) { + return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no found valid H.265 payload type"); + } + + std::deque backup_payloads; + for (int j = 0; j < (int)payloads.size(); j++) { + const SrsMediaPayloadType& payload = payloads.at(j); + if (payload.format_specific_param_.empty()) { + backup_payloads.push_front(payload); + continue; + } + + H264SpecificParam h264_param; + if ((err = srs_parse_h264_fmtp(payload.format_specific_param_, h264_param)) != srs_success) { + srs_error_reset(err); continue; + } + + // If not exists 42e01f, we pick up any profile such as 42001f. + bool profile_matched = (!has_42e01f || h264_param.profile_level_id == "42e01f"); + + // Try to pick the "best match" H.264 payload type. + if (profile_matched && h264_param.packetization_mode == "1" && h264_param.level_asymmerty_allow == "1") { + // if the playload is opus, and the encoding_param_ is channel + SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_); + video_payload->set_h264_param_desc(payload.format_specific_param_); + + // TODO: FIXME: Only support some transport algorithms. + for (int k = 0; k < (int)payload.rtcp_fb_.size(); ++k) { + const string& rtcp_fb = payload.rtcp_fb_.at(k); + + if (nack_enabled) { + if (rtcp_fb == "nack" || rtcp_fb == "nack pli") { + video_payload->rtcp_fbs_.push_back(rtcp_fb); + } + } + + if (twcc_enabled && remote_twcc_id) { + if (rtcp_fb == "transport-cc") { + video_payload->rtcp_fbs_.push_back(rtcp_fb); + } + } + } + + track_desc->type_ = "video"; + track_desc->set_codec_payload((SrsCodecPayload*)video_payload); + // Only choose first match H.265 payload type. + break; + } + + backup_payloads.push_back(payload); + } + + // Try my best to pick at least one media payload type. + if (!track_desc->media_ && !backup_payloads.empty()) { + const SrsMediaPayloadType& payload = backup_payloads.front(); + + // if the playload is opus, and the encoding_param_ is channel + SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_); + + // TODO: FIXME: Only support some transport algorithms. + for (int k = 0; k < (int)payload.rtcp_fb_.size(); ++k) { + const string& rtcp_fb = payload.rtcp_fb_.at(k); + + if (nack_enabled) { + if (rtcp_fb == "nack" || rtcp_fb == "nack pli") { + video_payload->rtcp_fbs_.push_back(rtcp_fb); + } + } + + if (twcc_enabled && remote_twcc_id) { + if (rtcp_fb == "transport-cc") { + video_payload->rtcp_fbs_.push_back(rtcp_fb); + } + } + } + + track_desc->type_ = "video"; + track_desc->set_codec_payload((SrsCodecPayload*)video_payload); + srs_warn("choose backup H.265 payload type=%d", payload.payload_type_); + } + + // TODO: FIXME: Support RRTR? + //local_media_desc.payload_types_.back().rtcp_fb_.push_back("rrtr"); } else if (remote_media_desc.is_video()) { std::vector payloads = remote_media_desc.find_media_with_encoding_name("H264"); if (payloads.empty()) { @@ -3020,6 +3106,25 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig* ruc, s // @see https://bugs.chromium.org/p/webrtc/issues/detail?id=13166 track_descs = source->get_track_desc("video", "AV1X"); } + } else if (remote_media_desc.is_video() && ruc->codec_ == "hevc") { + std::vector payloads = remote_media_desc.find_media_with_encoding_name("H265"); + if (payloads.empty()) { + return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found h265 payload type"); + } + + remote_payload = payloads.at(0); + for (int j = 0; j < (int)payloads.size(); j++) { + const SrsMediaPayloadType& payload = payloads.at(j); + + // If exists 42e01f profile, choose it; otherwise, use the first payload. + // TODO: FIME: Should check packetization-mode=1 also. + if (!has_42e01f || srs_sdp_has_h264_profile(payload, "42e01f")) { + remote_payload = payload; + break; + } + } + + track_descs = source->get_track_desc("video", "H265"); } else if (remote_media_desc.is_video()) { // TODO: check opus format specific param vector payloads = remote_media_desc.find_media_with_encoding_name("H264"); From c0271ffd1dc31fcbaef9c94cf0f067f3f7185af7 Mon Sep 17 00:00:00 2001 From: chundonglinlin Date: Sun, 5 Mar 2023 10:51:47 +0800 Subject: [PATCH 2/4] Remove invalid log. --- trunk/src/app/srs_app_rtc_conn.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index ff97e237d5..11aa567ba1 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2675,7 +2675,6 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc break; } } else if (remote_media_desc.is_video() && ruc->codec_ == "hevc") { - srs_trace("remote_media_desc.is_video"); std::vector payloads = remote_media_desc.find_media_with_encoding_name("H265"); if (payloads.empty()) { return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no found valid H.265 payload type"); From 83d0b33e69f6e11e1f37e5e0ed0a250a3baea20f Mon Sep 17 00:00:00 2001 From: chundonglinlin Date: Mon, 6 Mar 2023 11:48:28 +0800 Subject: [PATCH 3/4] Add comment for webrtc H265. --- trunk/src/app/srs_app_rtc_conn.cpp | 70 +++--------------------------- 1 file changed, 6 insertions(+), 64 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 11aa567ba1..f296bd278b 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2680,59 +2680,12 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no found valid H.265 payload type"); } - std::deque backup_payloads; + // TODO: FIXME: pick up a profile for HEVC. + // @see https://www.rfc-editor.org/rfc/rfc7798#section-7.2.1 for (int j = 0; j < (int)payloads.size(); j++) { const SrsMediaPayloadType& payload = payloads.at(j); - if (payload.format_specific_param_.empty()) { - backup_payloads.push_front(payload); - continue; - } - - H264SpecificParam h264_param; - if ((err = srs_parse_h264_fmtp(payload.format_specific_param_, h264_param)) != srs_success) { - srs_error_reset(err); continue; - } - - // If not exists 42e01f, we pick up any profile such as 42001f. - bool profile_matched = (!has_42e01f || h264_param.profile_level_id == "42e01f"); - - // Try to pick the "best match" H.264 payload type. - if (profile_matched && h264_param.packetization_mode == "1" && h264_param.level_asymmerty_allow == "1") { - // if the playload is opus, and the encoding_param_ is channel - SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_); - video_payload->set_h264_param_desc(payload.format_specific_param_); - - // TODO: FIXME: Only support some transport algorithms. - for (int k = 0; k < (int)payload.rtcp_fb_.size(); ++k) { - const string& rtcp_fb = payload.rtcp_fb_.at(k); - - if (nack_enabled) { - if (rtcp_fb == "nack" || rtcp_fb == "nack pli") { - video_payload->rtcp_fbs_.push_back(rtcp_fb); - } - } - - if (twcc_enabled && remote_twcc_id) { - if (rtcp_fb == "transport-cc") { - video_payload->rtcp_fbs_.push_back(rtcp_fb); - } - } - } - - track_desc->type_ = "video"; - track_desc->set_codec_payload((SrsCodecPayload*)video_payload); - // Only choose first match H.265 payload type. - break; - } - - backup_payloads.push_back(payload); - } - - // Try my best to pick at least one media payload type. - if (!track_desc->media_ && !backup_payloads.empty()) { - const SrsMediaPayloadType& payload = backup_payloads.front(); - // if the playload is opus, and the encoding_param_ is channel + // Generate video payload for hevc. SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_); // TODO: FIXME: Only support some transport algorithms. @@ -2744,7 +2697,6 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc video_payload->rtcp_fbs_.push_back(rtcp_fb); } } - if (twcc_enabled && remote_twcc_id) { if (rtcp_fb == "transport-cc") { video_payload->rtcp_fbs_.push_back(rtcp_fb); @@ -2754,11 +2706,8 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc track_desc->type_ = "video"; track_desc->set_codec_payload((SrsCodecPayload*)video_payload); - srs_warn("choose backup H.265 payload type=%d", payload.payload_type_); + break; } - - // TODO: FIXME: Support RRTR? - //local_media_desc.payload_types_.back().rtcp_fb_.push_back("rrtr"); } else if (remote_media_desc.is_video()) { std::vector payloads = remote_media_desc.find_media_with_encoding_name("H264"); if (payloads.empty()) { @@ -3112,16 +3061,9 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig* ruc, s } remote_payload = payloads.at(0); - for (int j = 0; j < (int)payloads.size(); j++) { - const SrsMediaPayloadType& payload = payloads.at(j); - // If exists 42e01f profile, choose it; otherwise, use the first payload. - // TODO: FIME: Should check packetization-mode=1 also. - if (!has_42e01f || srs_sdp_has_h264_profile(payload, "42e01f")) { - remote_payload = payload; - break; - } - } + // TODO: FIXME: pick up a profile for HEVC. + // @see https://www.rfc-editor.org/rfc/rfc7798#section-7.2.1 track_descs = source->get_track_desc("video", "H265"); } else if (remote_media_desc.is_video()) { From c888a88b4efe8d20cc0fbfab84b780f2aeb65d8c Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 7 Mar 2023 20:13:17 +0800 Subject: [PATCH 4/4] Update to v6.0.34 --- trunk/doc/CHANGELOG.md | 1 + trunk/src/core/srs_core_version6.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 27971a27a2..ba643fe448 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -8,6 +8,7 @@ The changelog for SRS. ## SRS 6.0 Changelog +* v6.0, 2023-03-07, Merge [#3441](https://github.com/ossrs/srs/pull/3441): HEVC: webrtc support hevc on safari. v6.0.34 (#3441) * v6.0, 2023-03-07, Merge [#3446](https://github.com/ossrs/srs/pull/3446): WebRTC: Warning if no ideal profile. v6.0.33 (#3446) * v6.0, 2023-03-06, Merge [#3445](https://github.com/ossrs/srs/pull/3445): Support configure for generic linux. v6.0.32 (#3445) * v6.0, 2023-03-04, Merge [#3105](https://github.com/ossrs/srs/pull/3105): Kickoff publisher when stream is idle, which means no players. v6.0.31 (#3105) diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp index d5ec73ef19..7a17a24376 100644 --- a/trunk/src/core/srs_core_version6.hpp +++ b/trunk/src/core/srs_core_version6.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 6 #define VERSION_MINOR 0 -#define VERSION_REVISION 33 +#define VERSION_REVISION 34 #endif