From a7a94f08857194aa80d8eb5efdb617f078d6b3a5 Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Tue, 30 Mar 2021 10:59:15 +0800 Subject: [PATCH] =?UTF-8?q?sdp=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=A7=BB=E5=8A=A8=E5=88=B0=E4=B8=BB=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/AAC.cpp | 2 +- src/Extension/Frame.cpp | 70 ++++++++++++++++++++++++++++++++--------- src/Extension/Frame.h | 19 +++++++++++ src/Extension/G711.cpp | 2 +- src/Extension/H264.cpp | 2 +- src/Extension/H265.cpp | 2 +- src/Extension/L16.cpp | 2 +- src/Extension/Opus.cpp | 2 +- webrtc/Sdp.cpp | 35 +++++++-------------- webrtc/Sdp.h | 3 +- 10 files changed, 93 insertions(+), 46 deletions(-) diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index d29ccc59..84308355 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -205,7 +205,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << " MPEG4-GENERIC/" << sample_rate << "/" << channels << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << sample_rate << "/" << channels << "\r\n"; string configStr; char buf[4] = {0}; diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index 39e04a45..aa005491 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -11,7 +11,7 @@ #include "Frame.h" #include "H264.h" #include "H265.h" - +#include "Common/Parser.h" using namespace std; using namespace toolkit; @@ -106,22 +106,10 @@ Frame::Ptr Frame::getCacheAbleFrame(const Frame::Ptr &frame){ return std::make_shared(frame); } -#define SWITCH_CASE(codec_id) case codec_id : return #codec_id -const char *getCodecName(CodecId codecId) { - switch (codecId) { - SWITCH_CASE(CodecH264); - SWITCH_CASE(CodecH265); - SWITCH_CASE(CodecAAC); - SWITCH_CASE(CodecG711A); - SWITCH_CASE(CodecG711U); - SWITCH_CASE(CodecOpus); - SWITCH_CASE(CodecL16); - default : return "unknown codec"; - } -} - TrackType getTrackType(CodecId codecId){ switch (codecId){ + case CodecVP8: + case CodecVP9: case CodecH264: case CodecH265: return TrackVideo; case CodecAAC: @@ -133,6 +121,58 @@ TrackType getTrackType(CodecId codecId){ } } +const char* getCodecName(CodecId codec){ + switch (codec) { + case CodecH264 : return "H264"; + case CodecH265 : return "H265"; + case CodecAAC : return "mpeg4-generic"; + case CodecG711A : return "PCMA"; + case CodecG711U : return "PCMU"; + case CodecOpus : return "opus"; + case CodecVP8 : return "VP8"; + case CodecVP9 : return "VP9"; + case CodecL16 : return "L16"; + default: return "invalid"; + } +} + +static map codec_map = { + {"H264", CodecH264}, + {"H265", CodecH265}, + {"mpeg4-generic", CodecAAC}, + {"PCMA", CodecG711A}, + {"PCMU", CodecG711U}, + {"opus", CodecOpus}, + {"VP8", CodecVP8}, + {"VP9", CodecVP9}, + {"L16", CodecL16} +}; + +CodecId getCodecId(const string &str){ + auto it = codec_map.find(str); + return it == codec_map.end() ? CodecInvalid : it->second; +} + +static map track_str_map = { + {"video", TrackVideo}, + {"audio", TrackAudio}, + {"application", TrackApplication} +}; + +TrackType getTrackType(const string &str) { + auto it = track_str_map.find(str); + return it == track_str_map.end() ? TrackInvalid : it->second; +} + +const char* getTrackString(TrackType type){ + switch (type) { + case TrackVideo : return "video"; + case TrackAudio : return "audio"; + case TrackApplication : return "application"; + default: return "invalid"; + } +} + const char *CodecInfo::getCodecName() { return mediakit::getCodecName(getCodecId()); } diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index afaa115a..1ad4734d 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -30,6 +30,8 @@ typedef enum { CodecG711U, CodecOpus, CodecL16, + CodecVP8, + CodecVP9, CodecMax = 0x7FFF } CodecId; @@ -42,6 +44,23 @@ typedef enum { TrackMax = 4 } TrackType; +/** + * 字符串转媒体类型转 + */ +TrackType getTrackType(const string &str); + +/** + * 媒体类型转字符串 + */ +const char* getTrackString(TrackType type); + +/** + * 根据SDP中描述获取codec_id + * @param str + * @return + */ +CodecId getCodecId(const string &str); + /** * 获取编码器名称 */ diff --git a/src/Extension/G711.cpp b/src/Extension/G711.cpp index da86d5a2..eab141ce 100644 --- a/src/Extension/G711.cpp +++ b/src/Extension/G711.cpp @@ -33,7 +33,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << sample_rate << "/" << channels << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } diff --git a/src/Extension/H264.cpp b/src/Extension/H264.cpp index b7bd1e29..04c638e1 100644 --- a/src/Extension/H264.cpp +++ b/src/Extension/H264.cpp @@ -235,7 +235,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << " H264/" << 90000 << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n"; _printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id="; char strTemp[1024]; diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index 48132a1d..27f12d1b 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -252,7 +252,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << " H265/" << 90000 << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n"; _printer << "a=fmtp:" << payload_type << " "; _printer << "sprop-vps="; _printer << encodeBase64(strVPS) << "; "; diff --git a/src/Extension/L16.cpp b/src/Extension/L16.cpp index e6c778ac..8194dfa3 100644 --- a/src/Extension/L16.cpp +++ b/src/Extension/L16.cpp @@ -33,7 +33,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << " L16/" << sample_rate << "/" << channels << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } diff --git a/src/Extension/Opus.cpp b/src/Extension/Opus.cpp index 275354cb..03e107a9 100644 --- a/src/Extension/Opus.cpp +++ b/src/Extension/Opus.cpp @@ -31,7 +31,7 @@ public: if (bitrate) { _printer << "b=AS:" << bitrate << "\r\n"; } - _printer << "a=rtpmap:" << payload_type << " opus/" << sample_rate << "/" << channels << "\r\n"; + _printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index e0b46367..d24d5a06 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -93,26 +93,6 @@ static bool registerAllItem(){ return true; } -static map track_str_map = { - {"video", TrackVideo}, - {"audio", TrackAudio}, - {"application", TrackApplication} -}; - -TrackType getTrackType(const string &str) { - auto it = track_str_map.find(str); - return it == track_str_map.end() ? TrackInvalid : it->second; -} - -const char* getTrackString(TrackType type){ - switch (type) { - case TrackVideo : return "video"; - case TrackAudio : return "audio"; - case TrackApplication : return "application"; - default: return "invalid"; - } -} - static map dtls_role_map = { {"active", DtlsRole::active}, {"passive", DtlsRole::passive}, @@ -1059,6 +1039,18 @@ const RtcCodecPlan *RtcMedia::getPlan(const char *codec) const{ return nullptr; } +const RtcCodecPlan *RtcMedia::getRelatedRtxPlan(uint8_t pt) const{ + for (auto &item : plan) { + if (strcasecmp(item.codec.data(), "rtx") == 0) { + auto apt = atoi(item.getFmtp("apt").data()); + if (pt == apt) { + return &item; + } + } + } + return nullptr; +} + void RtcMedia::checkValid() const{ CHECK(type != TrackInvalid); CHECK(!mid.empty()); @@ -1071,9 +1063,6 @@ void RtcMedia::checkValid() const{ if (rtx_plan) { //开启rtx后必须指定rtx_ssrc CHECK(!rtx_ssrc.empty() || !send_rtp); - auto apt = atoi(rtx_plan->getFmtp("apt").data()); - //开启rtx后必须指定其关联的其他的plan - CHECK(getPlan(apt)); } } diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 32c92cb6..51163e01 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -72,8 +72,6 @@ enum class SdpType { answer }; -TrackType getTrackType(const string &str); -const char* getTrackString(TrackType type); DtlsRole getDtlsRole(const string &str); const char* getDtlsRoleString(DtlsRole role); RtpDirection getRtpDirection(const string &str); @@ -591,6 +589,7 @@ public: void checkValid() const; const RtcCodecPlan *getPlan(uint8_t pt) const; const RtcCodecPlan *getPlan(const char *codec) const; + const RtcCodecPlan *getRelatedRtxPlan(uint8_t pt) const; }; class RtcSession{