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}
This commit is contained in:
erikvarga 2017-05-11 02:36:32 -07:00 committed by Commit bot
parent 198a9300cd
commit e6b16194c7
4 changed files with 102 additions and 5 deletions

View File

@ -257,6 +257,13 @@ bool RtpStreamId::Parse(rtc::ArrayView<const uint8_t> data, StreamId* rsid) {
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 @@ bool RtpStreamId::Parse(rtc::ArrayView<const uint8_t> data, std::string* rsid) {
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 @@ bool RepairedRtpStreamId::Parse(rtc::ArrayView<const uint8_t> data,
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

View File

@ -28,6 +28,7 @@ class AbsoluteSendTime {
"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 @@ class AudioLevel {
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 @@ class TransmissionOffset {
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 @@ class TransportSequenceNumber {
"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 @@ class VideoOrientation {
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 @@ class PlayoutDelayLimits {
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 @@ class VideoContentTypeExtension {
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 @@ class RtpStreamId {
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 @@ class RepairedRtpStreamId {
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

View File

@ -183,7 +183,10 @@ bool Packet::GetExtension(Values... values) const {
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...);

View File

@ -28,15 +28,18 @@ constexpr uint16_t kSeqNum = 88;
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 @@ constexpr uint8_t kPacketWithTOAndAL[] = {
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 @@ TEST(RtpPacketTest, CreateWith2Extensions) {
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);