From cc5dee0abf64e235b8081d5ff7a9e1bdc2696cae Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Thu, 15 Apr 2021 19:35:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96sdp=20fmtp=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webrtc/Sdp.cpp | 46 ++++++++++++++++++++-------------------------- webrtc/Sdp.h | 6 ++++-- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index 89065ecc..69feb7de 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -9,7 +9,6 @@ */ #include "Sdp.h" -#include "Common/Parser.h" #include "Rtsp/Rtsp.h" #include using namespace mediakit; @@ -610,12 +609,12 @@ void SdpAttrFmtp::parse(const string &str) { trim(item); auto pos = item.find('='); if(pos == string::npos){ - arr.emplace_back(std::make_pair(item, "")); + fmtp.emplace(std::make_pair(item, "")); } else { - arr.emplace_back(std::make_pair(item.substr(0, pos), item.substr(pos + 1))); + fmtp.emplace(std::make_pair(item.substr(0, pos), item.substr(pos + 1))); } } - if (arr.empty()) { + if (fmtp.empty()) { SDP_THROW(); } } @@ -624,7 +623,7 @@ string SdpAttrFmtp::toString() const { if (value.empty()) { value = to_string(pt); int i = 0; - for (auto &pr : arr) { + for (auto &pr : fmtp) { value += (i++ ? ';' : ' '); value += pr.first + "=" + pr.second; } @@ -918,7 +917,7 @@ void RtcSession::loadFrom(const string &str, bool check) { auto fmtp_it = fmtp_map.find(pt); if (fmtp_it != fmtp_map.end()) { - plan.fmtp = fmtp_it->second.arr; + plan.fmtp = fmtp_it->second.fmtp; } for (auto rtpfb_it = rtcpfb_map.find(pt); rtpfb_it != rtcpfb_map.end() && rtpfb_it->second.pt == pt; ++rtpfb_it) { @@ -1088,7 +1087,7 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{ if (!p.fmtp.empty()) { auto fmtp = std::make_shared(); fmtp->pt = p.pt; - fmtp->arr = p.fmtp; + fmtp->fmtp = p.fmtp; sdp_media.items.emplace_back(wrapSdpAttr(std::move(fmtp))); } } @@ -1255,12 +1254,14 @@ void RtcConfigure::RtcTrackConfigure::setDefaultSetting(TrackType type){ ice_renomination = false; switch (type) { case TrackAudio: { - preferred_codec = {CodecAAC, CodecOpus, CodecG711U, CodecG711A}; + //此处调整偏好的编码格式优先级 + preferred_codec = {CodecAAC, CodecG711U, CodecG711A, CodecOpus}; rtcp_fb = {"transport-cc"}; extmap = {"1 urn:ietf:params:rtp-hdrext:ssrc-audio-level"}; break; } case TrackVideo: { + //此处调整偏好的编码格式优先级 preferred_codec = {CodecH264, CodecH265}; rtcp_fb = {"nack", "ccm fir", "nack pli", "goog-remb", "transport-cc"}; extmap = {"2 urn:ietf:params:rtp-hdrext:toffset", @@ -1441,6 +1442,7 @@ RETRY: //添加媒体plan answer_media.plan.emplace_back(*offer_plan_ptr); + onSelectPlan(answer_media.plan.back(), codec); //添加rtx,red,ulpfec plan if (configure.support_red || configure.support_rtx || configure.support_ulpfec) { @@ -1535,14 +1537,6 @@ void RtcConfigure::setPlayRtspInfo(const string &sdp){ } } -static map toMap(const vector > &fmt) { - map ret; - for (auto &pr : fmt) { - ret.emplace(pr); - } - return ret; -} - static const string kProfile{"profile-level-id"}; static const string kMode{"packetization-mode"}; @@ -1555,21 +1549,21 @@ bool RtcConfigure::onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec){ return true; } if (_rtsp_video_plan && codec == CodecH264 && getCodecId(_rtsp_video_plan->codec) == CodecH264) { - //h264时,匹配packetization-mode和profile-level-id - auto rtc_fmt_map = toMap(plan.fmtp); - auto rtsp_fmt_map = toMap(_rtsp_video_plan->fmtp); - auto &profile = rtsp_fmt_map[kProfile]; - if (!profile.empty() && strcasecmp(profile.data(), rtc_fmt_map[kProfile].data())) { + //h264时,profile-level-id + if (strcasecmp(_rtsp_video_plan->fmtp[kProfile].data(), const_cast(plan).fmtp[kProfile].data())) { //profile-level-id 不匹配 return false; } - auto &mode = rtsp_fmt_map[kMode]; - if (!mode.empty() && atoi(mode.data()) != atoi(rtc_fmt_map[kMode].data())) { - //packetization-mode不匹配 - return false; - } return true; } return true; } + +void RtcConfigure::onSelectPlan(RtcCodecPlan &plan, CodecId codec){ + if (_rtsp_video_plan && codec == CodecH264 && getCodecId(_rtsp_video_plan->codec) == CodecH264) { + //h264时,设置packetization-mod为一致 + auto mode = _rtsp_video_plan->fmtp[kMode]; + plan.fmtp[kMode] = mode.empty() ? "0" : mode; + } +} diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 9247018a..272d6dd9 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -15,6 +15,7 @@ #include #include "assert.h" #include "Extension/Frame.h" +#include "Common/Parser.h" using namespace std; using namespace mediakit; @@ -372,7 +373,7 @@ class SdpAttrFmtp : public SdpItem { public: //fmtp:96 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f uint8_t pt; - vector > arr; + map fmtp; void parse(const string &str) override; string toString() const override; const char* getKey() const override { return "fmtp";} @@ -589,7 +590,7 @@ public: uint32_t channel = 0; //rtcp反馈 vector rtcp_fb; - vector > fmtp; + map fmtp; string getFmtp(const char *key) const; }; @@ -715,6 +716,7 @@ public: private: void matchMedia(shared_ptr &ret, TrackType type, const vector &medias, const RtcTrackConfigure &configure); bool onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec); + void onSelectPlan(RtcCodecPlan &plan, CodecId codec); private: RtcCodecPlan::Ptr _rtsp_video_plan;