From 2e8a7be5eadf540f49382228399240a43d2fecca Mon Sep 17 00:00:00 2001
From: xia-chu <771730766@qq.com>
Date: Fri, 7 May 2021 12:00:26 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84rtp=20ext=E7=9B=B8=E5=85=B3?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
webrtc/RtpExt.cpp | 58 ++++++++++++++++++++++++++++++++++++++++-------
webrtc/RtpExt.h | 32 ++++++++++++++++++++++++--
2 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/webrtc/RtpExt.cpp b/webrtc/RtpExt.cpp
index 7fb69cd1..83ce7bbb 100644
--- a/webrtc/RtpExt.cpp
+++ b/webrtc/RtpExt.cpp
@@ -108,8 +108,8 @@ uint8_t *RtpExtTwoByte::getData() {
static constexpr uint16_t kOneByteHeader = 0xBEDE;
static constexpr uint16_t kTwoByteHeader = 0x1000;
-map RtpExt::getExtValue(const RtpHeader *header) {
- map ret;
+map RtpExt::getExtValue(const RtpHeader *header, const RtcMedia &media) {
+ map ret;
assert(header);
auto ext_size = header->getExtSize();
if (!ext_size) {
@@ -118,20 +118,20 @@ map RtpExt::getExtValue(const RtpHeader *header)
auto reserved = header->getExtReserved();
auto ptr = const_cast(header)->getExtData();
auto end = ptr + ext_size;
-
+ RtpExtType type;
if (reserved == kOneByteHeader) {
while (ptr < end) {
RtpExtOneByte *ext = reinterpret_cast(ptr);
- if (ext->getId() == 0) {
+ if (ext->getId() == (uint8_t) RtpExtType::padding) {
//padding,忽略
++ptr;
continue;
}
//15类型的rtp ext为保留
- CHECK(ext->getId() != 15);
+ CHECK(ext->getId() < (uint8_t) RtpExtType::reserved);
CHECK(reinterpret_cast(ext) + RtpExtOneByte::kMinSize <= end);
CHECK(ext->getData() + ext->getSize() <= end);
- ret.emplace(ext->getId(), string(reinterpret_cast(ext->getData()), ext->getSize()));
+ ret.emplace(ext->getId(), RtpExt(type, reinterpret_cast(ext->getData()), ext->getSize()));
ptr += RtpExtOneByte::kMinSize + ext->getSize();
}
return ret;
@@ -140,14 +140,16 @@ map RtpExt::getExtValue(const RtpHeader *header)
if ((reserved & 0xFFF0) >> 4 == kTwoByteHeader) {
while (ptr < end) {
RtpExtTwoByte *ext = reinterpret_cast(ptr);
- if (ext->getId() == 0) {
+ if (ext->getId() == (uint8_t) RtpExtType::padding) {
//padding,忽略
++ptr;
continue;
}
+ //15类型的rtp ext为保留
+ CHECK(ext->getId() < (uint8_t) RtpExtType::reserved);
CHECK(reinterpret_cast(ext) + RtpExtTwoByte::kMinSize <= end);
CHECK(ext->getData() + ext->getSize() <= end);
- ret.emplace(ext->getId(), string(reinterpret_cast(ext->getData()), ext->getSize()));
+ ret.emplace(ext->getId(), RtpExt(type, reinterpret_cast(ext->getData()), ext->getSize()));
ptr += RtpExtTwoByte::kMinSize + ext->getSize();
}
return ret;
@@ -155,3 +157,43 @@ map RtpExt::getExtValue(const RtpHeader *header)
return ret;
}
+
+#define RTP_EXT_MAP(XX) \
+ XX(RtpExtType::ssrc_audio_level, "urn:ietf:params:rtp-hdrext:ssrc-audio-level") \
+ XX(RtpExtType::abs_send_time, "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time") \
+ XX(RtpExtType::transport_cc, "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01") \
+ XX(RtpExtType::sdes_mid, "urn:ietf:params:rtp-hdrext:sdes:mid") \
+ XX(RtpExtType::sdes_rtp_stream_id, "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id") \
+ XX(RtpExtType::sdes_repaired_rtp_stream_id, "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id") \
+ XX(RtpExtType::video_timing, "http://www.webrtc.org/experiments/rtp-hdrext/video-timing") \
+ XX(RtpExtType::color_space, "http://www.webrtc.org/experiments/rtp-hdrext/color-space") \
+ XX(RtpExtType::video_content_type, "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type") \
+ XX(RtpExtType::playout_delay, "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay") \
+ XX(RtpExtType::video_orientation, "urn:3gpp:video-orientation") \
+ XX(RtpExtType::toffset, "urn:ietf:params:rtp-hdrext:toffset")
+
+#define XX(type, url) {type , url},
+static unordered_map s_type_to_url = {RTP_EXT_MAP(XX)};
+#undef XX
+
+
+#define XX(type, url) {url, type},
+static unordered_map s_url_to_type = {RTP_EXT_MAP(XX)};
+#undef XX
+
+RtpExtType RtpExt::getRtpExtType(const string &url) {
+ auto it = s_url_to_type.find(url);
+ if (it == s_url_to_type.end()) {
+ throw std::invalid_argument(string("未识别的rtp ext url类型:") + url);
+ }
+ return it->second;
+}
+
+const string &RtpExt::getRtpExtUrl(RtpExtType type) {
+ auto it = s_type_to_url.find(type);
+ if (it == s_type_to_url.end()) {
+ throw std::invalid_argument(string("未识别的rtp ext类型:") + to_string((int) type));
+ }
+ return it->second;
+}
+
diff --git a/webrtc/RtpExt.h b/webrtc/RtpExt.h
index 23c04d94..c89ee560 100644
--- a/webrtc/RtpExt.h
+++ b/webrtc/RtpExt.h
@@ -20,9 +20,37 @@
using namespace std;
using namespace mediakit;
-class RtpExt {
+enum class RtpExtType : uint8_t {
+ padding = 0,
+ ssrc_audio_level = 1,
+ abs_send_time = 2,
+ transport_cc = 3,
+ sdes_mid = 4,
+ sdes_rtp_stream_id = 5,
+ sdes_repaired_rtp_stream_id = 6,
+ video_timing = 7,
+ color_space = 8,
+ video_content_type = 11,
+ playout_delay = 12,
+ video_orientation = 13,
+ toffset = 14,
+ reserved = 15,
+};
+
+class RtcMedia;
+
+class RtpExt : public std::string {
public:
- static map getExtValue(const RtpHeader *header);
+ ~RtpExt() = default;
+ static map getExtValue(const RtpHeader *header, const RtcMedia &media);
+ static RtpExtType getRtpExtType(const string &url);
+ static const string& getRtpExtUrl(RtpExtType type);
+
+private:
+ RtpExt(RtpExtType type, const char *str, size_t size) : std::string(str, size), _type(type) {}
+
+private:
+ RtpExtType _type;
};