优化sdp fmtp字段处理逻辑

This commit is contained in:
xia-chu 2021-04-15 19:35:25 +08:00
parent 46e3538dca
commit cc5dee0abf
2 changed files with 24 additions and 28 deletions

View File

@ -9,7 +9,6 @@
*/ */
#include "Sdp.h" #include "Sdp.h"
#include "Common/Parser.h"
#include "Rtsp/Rtsp.h" #include "Rtsp/Rtsp.h"
#include <inttypes.h> #include <inttypes.h>
using namespace mediakit; using namespace mediakit;
@ -610,12 +609,12 @@ void SdpAttrFmtp::parse(const string &str) {
trim(item); trim(item);
auto pos = item.find('='); auto pos = item.find('=');
if(pos == string::npos){ if(pos == string::npos){
arr.emplace_back(std::make_pair(item, "")); fmtp.emplace(std::make_pair(item, ""));
} else { } 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(); SDP_THROW();
} }
} }
@ -624,7 +623,7 @@ string SdpAttrFmtp::toString() const {
if (value.empty()) { if (value.empty()) {
value = to_string(pt); value = to_string(pt);
int i = 0; int i = 0;
for (auto &pr : arr) { for (auto &pr : fmtp) {
value += (i++ ? ';' : ' '); value += (i++ ? ';' : ' ');
value += pr.first + "=" + pr.second; value += pr.first + "=" + pr.second;
} }
@ -918,7 +917,7 @@ void RtcSession::loadFrom(const string &str, bool check) {
auto fmtp_it = fmtp_map.find(pt); auto fmtp_it = fmtp_map.find(pt);
if (fmtp_it != fmtp_map.end()) { 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); for (auto rtpfb_it = rtcpfb_map.find(pt);
rtpfb_it != rtcpfb_map.end() && rtpfb_it->second.pt == pt; ++rtpfb_it) { 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()) { if (!p.fmtp.empty()) {
auto fmtp = std::make_shared<SdpAttrFmtp>(); auto fmtp = std::make_shared<SdpAttrFmtp>();
fmtp->pt = p.pt; fmtp->pt = p.pt;
fmtp->arr = p.fmtp; fmtp->fmtp = p.fmtp;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(fmtp))); sdp_media.items.emplace_back(wrapSdpAttr(std::move(fmtp)));
} }
} }
@ -1255,12 +1254,14 @@ void RtcConfigure::RtcTrackConfigure::setDefaultSetting(TrackType type){
ice_renomination = false; ice_renomination = false;
switch (type) { switch (type) {
case TrackAudio: { case TrackAudio: {
preferred_codec = {CodecAAC, CodecOpus, CodecG711U, CodecG711A}; //此处调整偏好的编码格式优先级
preferred_codec = {CodecAAC, CodecG711U, CodecG711A, CodecOpus};
rtcp_fb = {"transport-cc"}; rtcp_fb = {"transport-cc"};
extmap = {"1 urn:ietf:params:rtp-hdrext:ssrc-audio-level"}; extmap = {"1 urn:ietf:params:rtp-hdrext:ssrc-audio-level"};
break; break;
} }
case TrackVideo: { case TrackVideo: {
//此处调整偏好的编码格式优先级
preferred_codec = {CodecH264, CodecH265}; preferred_codec = {CodecH264, CodecH265};
rtcp_fb = {"nack", "ccm fir", "nack pli", "goog-remb", "transport-cc"}; rtcp_fb = {"nack", "ccm fir", "nack pli", "goog-remb", "transport-cc"};
extmap = {"2 urn:ietf:params:rtp-hdrext:toffset", extmap = {"2 urn:ietf:params:rtp-hdrext:toffset",
@ -1441,6 +1442,7 @@ RETRY:
//添加媒体plan //添加媒体plan
answer_media.plan.emplace_back(*offer_plan_ptr); answer_media.plan.emplace_back(*offer_plan_ptr);
onSelectPlan(answer_media.plan.back(), codec);
//添加rtx,red,ulpfec plan //添加rtx,red,ulpfec plan
if (configure.support_red || configure.support_rtx || configure.support_ulpfec) { if (configure.support_red || configure.support_rtx || configure.support_ulpfec) {
@ -1535,14 +1537,6 @@ void RtcConfigure::setPlayRtspInfo(const string &sdp){
} }
} }
static map<string, string, StrCaseCompare> toMap(const vector<std::pair<string/*key*/, string/*value*/> > &fmt) {
map<string, string, StrCaseCompare> ret;
for (auto &pr : fmt) {
ret.emplace(pr);
}
return ret;
}
static const string kProfile{"profile-level-id"}; static const string kProfile{"profile-level-id"};
static const string kMode{"packetization-mode"}; static const string kMode{"packetization-mode"};
@ -1555,21 +1549,21 @@ bool RtcConfigure::onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec){
return true; return true;
} }
if (_rtsp_video_plan && codec == CodecH264 && getCodecId(_rtsp_video_plan->codec) == CodecH264) { if (_rtsp_video_plan && codec == CodecH264 && getCodecId(_rtsp_video_plan->codec) == CodecH264) {
//h264时匹配packetization-mode和profile-level-id //h264时profile-level-id
auto rtc_fmt_map = toMap(plan.fmtp); if (strcasecmp(_rtsp_video_plan->fmtp[kProfile].data(), const_cast<RtcCodecPlan &>(plan).fmtp[kProfile].data())) {
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())) {
//profile-level-id 不匹配 //profile-level-id 不匹配
return false; 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;
} }
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;
}
}

View File

@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include "assert.h" #include "assert.h"
#include "Extension/Frame.h" #include "Extension/Frame.h"
#include "Common/Parser.h"
using namespace std; using namespace std;
using namespace mediakit; using namespace mediakit;
@ -372,7 +373,7 @@ class SdpAttrFmtp : public SdpItem {
public: public:
//fmtp:96 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f //fmtp:96 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
uint8_t pt; uint8_t pt;
vector<std::pair<string, string> > arr; map<string/*key*/, string/*value*/, StrCaseCompare> fmtp;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() const override { return "fmtp";} const char* getKey() const override { return "fmtp";}
@ -589,7 +590,7 @@ public:
uint32_t channel = 0; uint32_t channel = 0;
//rtcp反馈 //rtcp反馈
vector<string> rtcp_fb; vector<string> rtcp_fb;
vector<std::pair<string/*key*/, string/*value*/> > fmtp; map<string/*key*/, string/*value*/, StrCaseCompare> fmtp;
string getFmtp(const char *key) const; string getFmtp(const char *key) const;
}; };
@ -715,6 +716,7 @@ public:
private: private:
void matchMedia(shared_ptr<RtcSession> &ret, TrackType type, const vector<RtcMedia> &medias, const RtcTrackConfigure &configure); void matchMedia(shared_ptr<RtcSession> &ret, TrackType type, const vector<RtcMedia> &medias, const RtcTrackConfigure &configure);
bool onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec); bool onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec);
void onSelectPlan(RtcCodecPlan &plan, CodecId codec);
private: private:
RtcCodecPlan::Ptr _rtsp_video_plan; RtcCodecPlan::Ptr _rtsp_video_plan;