Add write support for the RtpStreamId and RepairedRtpStreamId header extensions.
BUG=webrtc:7433
Review-Url: https://codereview.webrtc.org/2871813003
Cr-Commit-Position: refs/heads/master@{#18093}
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
index 13f488b..ba512ef 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -257,6 +257,13 @@
return true;
}
+bool RtpStreamId::Write(uint8_t* data, const StreamId& rsid) {
+ RTC_DCHECK_GE(rsid.size(), 1);
+ RTC_DCHECK_LE(rsid.size(), StreamId::kMaxSize);
+ memcpy(data, rsid.data(), rsid.size());
+ return true;
+}
+
bool RtpStreamId::Parse(rtc::ArrayView<const uint8_t> data, std::string* rsid) {
if (data.empty() || data[0] == 0) // Valid rsid can't be empty.
return false;
@@ -268,6 +275,13 @@
return true;
}
+bool RtpStreamId::Write(uint8_t* data, const std::string& rsid) {
+ RTC_DCHECK_GE(rsid.size(), 1);
+ RTC_DCHECK_LE(rsid.size(), StreamId::kMaxSize);
+ memcpy(data, rsid.data(), rsid.size());
+ return true;
+}
+
// RepairedRtpStreamId.
constexpr RTPExtensionType RepairedRtpStreamId::kId;
constexpr uint8_t RepairedRtpStreamId::kValueSizeBytes;
@@ -279,9 +293,25 @@
return RtpStreamId::Parse(data, rsid);
}
+size_t RepairedRtpStreamId::ValueSize(const StreamId& rsid) {
+ return RtpStreamId::ValueSize(rsid);
+}
+
+bool RepairedRtpStreamId::Write(uint8_t* data, const StreamId& rsid) {
+ return RtpStreamId::Write(data, rsid);
+}
+
bool RepairedRtpStreamId::Parse(rtc::ArrayView<const uint8_t> data,
std::string* rsid) {
return RtpStreamId::Parse(data, rsid);
}
+size_t RepairedRtpStreamId::ValueSize(const std::string& rsid) {
+ return RtpStreamId::ValueSize(rsid);
+}
+
+bool RepairedRtpStreamId::Write(uint8_t* data, const std::string& rsid) {
+ return RtpStreamId::Write(data, rsid);
+}
+
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h
index c60f290..df68b21 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -28,6 +28,7 @@
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
+ static size_t ValueSize(int64_t time_ms) { return kValueSizeBytes; }
static bool Write(uint8_t* data, int64_t time_ms);
static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
@@ -45,6 +46,9 @@
static bool Parse(rtc::ArrayView<const uint8_t> data,
bool* voice_activity,
uint8_t* audio_level);
+ static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
+ return kValueSizeBytes;
+ }
static bool Write(uint8_t* data, bool voice_activity, uint8_t audio_level);
};
@@ -55,6 +59,7 @@
static constexpr const char* kUri = "urn:ietf:params:rtp-hdrext:toffset";
static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
+ static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
static bool Write(uint8_t* data, int32_t rtp_time);
};
@@ -66,6 +71,7 @@
"http://www.ietf.org/id/"
"draft-holmer-rmcat-transport-wide-cc-extensions-01";
static bool Parse(rtc::ArrayView<const uint8_t> data, uint16_t* value);
+ static size_t ValueSize(uint16_t value) { return kValueSizeBytes; }
static bool Write(uint8_t* data, uint16_t value);
};
@@ -76,8 +82,10 @@
static constexpr const char* kUri = "urn:3gpp:video-orientation";
static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
+ static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
static bool Write(uint8_t* data, VideoRotation value);
static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
+ static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
static bool Write(uint8_t* data, uint8_t value);
};
@@ -97,6 +105,9 @@
static bool Parse(rtc::ArrayView<const uint8_t> data,
PlayoutDelay* playout_delay);
+ static size_t ValueSize(const PlayoutDelay&) {
+ return kValueSizeBytes;
+ }
static bool Write(uint8_t* data, const PlayoutDelay& playout_delay);
};
@@ -109,6 +120,9 @@
static bool Parse(rtc::ArrayView<const uint8_t> data,
VideoContentType* content_type);
+ static size_t ValueSize(VideoContentType) {
+ return kValueSizeBytes;
+ }
static bool Write(uint8_t* data, VideoContentType content_type);
};
@@ -121,8 +135,13 @@
static constexpr const char* kUri =
"urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
- static bool Parse(rtc::ArrayView<const uint8_t> data, StreamId* rid);
- static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* rid);
+ static bool Parse(rtc::ArrayView<const uint8_t> data, StreamId* rsid);
+ static size_t ValueSize(const StreamId& rsid) { return rsid.size(); }
+ static bool Write(uint8_t* data, const StreamId& rsid);
+
+ static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* rsid);
+ static size_t ValueSize(const std::string& rsid) { return rsid.size(); }
+ static bool Write(uint8_t* data, const std::string& rsid);
};
class RepairedRtpStreamId {
@@ -134,8 +153,13 @@
static constexpr const char* kUri =
"urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
- static bool Parse(rtc::ArrayView<const uint8_t> data, StreamId* rid);
- static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* rid);
+ static bool Parse(rtc::ArrayView<const uint8_t> data, StreamId* rsid);
+ static size_t ValueSize(const StreamId& rsid);
+ static bool Write(uint8_t* data, const StreamId& rsid);
+
+ static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* rsid);
+ static size_t ValueSize(const std::string& rsid);
+ static bool Write(uint8_t* data, const std::string& rsid);
};
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet.h b/webrtc/modules/rtp_rtcp/source/rtp_packet.h
index ca189db..0901fc2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet.h
@@ -183,7 +183,10 @@
template <typename Extension, typename... Values>
bool Packet::SetExtension(Values... values) {
- auto buffer = AllocateExtension(Extension::kId, Extension::kValueSizeBytes);
+ const size_t value_size = Extension::ValueSize(values...);
+ if (value_size == 0 || value_size > 16)
+ return false;
+ auto buffer = AllocateExtension(Extension::kId, value_size);
if (buffer.empty())
return false;
return Extension::Write(buffer.data(), values...);
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index bbe4080..001f06f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -28,15 +28,18 @@
constexpr uint32_t kTimestamp = 0x65431278;
constexpr uint8_t kTransmissionOffsetExtensionId = 1;
constexpr uint8_t kAudioLevelExtensionId = 9;
+constexpr uint8_t kRtpStreamIdExtensionId = 0xa;
constexpr int32_t kTimeOffset = 0x56ce;
constexpr bool kVoiceActive = true;
constexpr uint8_t kAudioLevel = 0x5a;
+constexpr char kStreamId[] = "streamid";
constexpr size_t kMaxPaddingSize = 224u;
// clang-format off
constexpr uint8_t kMinimumPacket[] = {
0x80, kPayloadType, 0x00, kSeqNum,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78};
+
constexpr uint8_t kPacketWithTO[] = {
0x90, kPayloadType, 0x00, kSeqNum,
0x65, 0x43, 0x12, 0x78,
@@ -52,6 +55,15 @@
0x12, 0x00, 0x56, 0xce,
0x90, 0x80|kAudioLevel, 0x00, 0x00};
+constexpr uint8_t kPacketWithRsid[] = {
+ 0x90, kPayloadType, 0x00, kSeqNum,
+ 0x65, 0x43, 0x12, 0x78,
+ 0x12, 0x34, 0x56, 0x78,
+ 0xbe, 0xde, 0x00, 0x03,
+ 0xa7, 's', 't', 'r',
+ 'e', 'a', 'm', 'i',
+ 'd' , 0x00, 0x00, 0x00};
+
constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
constexpr uint8_t kPacketPaddingSize = 8;
@@ -117,6 +129,34 @@
ElementsAreArray(packet.data(), packet.size()));
}
+TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
+ RtpPacketToSend::ExtensionManager extensions;
+ extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
+ RtpPacketToSend packet(&extensions);
+ packet.SetPayloadType(kPayloadType);
+ packet.SetSequenceNumber(kSeqNum);
+ packet.SetTimestamp(kTimestamp);
+ packet.SetSsrc(kSsrc);
+ packet.SetExtension<RtpStreamId>(kStreamId);
+ EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
+}
+
+TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
+ RtpPacketToSend::ExtensionManager extensions;
+ extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
+ RtpPacketToSend packet(&extensions);
+ EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
+}
+
+TEST(RtpPacketTest, TryToCreateWithLongRsid) {
+ RtpPacketToSend::ExtensionManager extensions;
+ constexpr char kLongStreamId[] = "LoooooooooongRsid";
+ ASSERT_EQ(strlen(kLongStreamId), 17u);
+ extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
+ RtpPacketToSend packet(&extensions);
+ EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
+}
+
TEST(RtpPacketTest, CreateWithExtensionsWithoutManager) {
RtpPacketToSend packet(nullptr);
packet.SetPayloadType(kPayloadType);