Move rtp header extension length check from Packet::FindExtension to ExtensionT::Parse

to allow to read variable-length extensions.

BUG=webrtc:7433

Review-Url: https://codereview.webrtc.org/2801733002
Cr-Commit-Position: refs/heads/master@{#17554}
This commit is contained in:
danilchap
2017-04-06 01:03:53 -07:00
committed by Commit bot
parent ed6343d90a
commit 978504e25c
5 changed files with 51 additions and 45 deletions

View File

@ -35,8 +35,11 @@ constexpr RTPExtensionType AbsoluteSendTime::kId;
constexpr uint8_t AbsoluteSendTime::kValueSizeBytes;
constexpr const char* AbsoluteSendTime::kUri;
bool AbsoluteSendTime::Parse(const uint8_t* data, uint32_t* time_24bits) {
*time_24bits = ByteReader<uint32_t, 3>::ReadBigEndian(data);
bool AbsoluteSendTime::Parse(rtc::ArrayView<const uint8_t> data,
uint32_t* time_24bits) {
if (data.size() != 3)
return false;
*time_24bits = ByteReader<uint32_t, 3>::ReadBigEndian(data.data());
return true;
}
@ -61,9 +64,11 @@ constexpr RTPExtensionType AudioLevel::kId;
constexpr uint8_t AudioLevel::kValueSizeBytes;
constexpr const char* AudioLevel::kUri;
bool AudioLevel::Parse(const uint8_t* data,
bool AudioLevel::Parse(rtc::ArrayView<const uint8_t> data,
bool* voice_activity,
uint8_t* audio_level) {
if (data.size() != 1)
return false;
*voice_activity = (data[0] & 0x80) != 0;
*audio_level = data[0] & 0x7F;
return true;
@ -97,8 +102,11 @@ constexpr RTPExtensionType TransmissionOffset::kId;
constexpr uint8_t TransmissionOffset::kValueSizeBytes;
constexpr const char* TransmissionOffset::kUri;
bool TransmissionOffset::Parse(const uint8_t* data, int32_t* rtp_time) {
*rtp_time = ByteReader<int32_t, 3>::ReadBigEndian(data);
bool TransmissionOffset::Parse(rtc::ArrayView<const uint8_t> data,
int32_t* rtp_time) {
if (data.size() != 3)
return false;
*rtp_time = ByteReader<int32_t, 3>::ReadBigEndian(data.data());
return true;
}
@ -117,8 +125,11 @@ constexpr RTPExtensionType TransportSequenceNumber::kId;
constexpr uint8_t TransportSequenceNumber::kValueSizeBytes;
constexpr const char* TransportSequenceNumber::kUri;
bool TransportSequenceNumber::Parse(const uint8_t* data, uint16_t* value) {
*value = ByteReader<uint16_t>::ReadBigEndian(data);
bool TransportSequenceNumber::Parse(rtc::ArrayView<const uint8_t> data,
uint16_t* value) {
if (data.size() != 2)
return false;
*value = ByteReader<uint16_t>::ReadBigEndian(data.data());
return true;
}
@ -142,7 +153,10 @@ constexpr RTPExtensionType VideoOrientation::kId;
constexpr uint8_t VideoOrientation::kValueSizeBytes;
constexpr const char* VideoOrientation::kUri;
bool VideoOrientation::Parse(const uint8_t* data, VideoRotation* rotation) {
bool VideoOrientation::Parse(rtc::ArrayView<const uint8_t> data,
VideoRotation* rotation) {
if (data.size() != 1)
return false;
*rotation = ConvertCVOByteToVideoRotation(data[0]);
return true;
}
@ -152,7 +166,10 @@ bool VideoOrientation::Write(uint8_t* data, VideoRotation rotation) {
return true;
}
bool VideoOrientation::Parse(const uint8_t* data, uint8_t* value) {
bool VideoOrientation::Parse(rtc::ArrayView<const uint8_t> data,
uint8_t* value) {
if (data.size() != 1)
return false;
*value = data[0];
return true;
}
@ -171,10 +188,12 @@ constexpr RTPExtensionType PlayoutDelayLimits::kId;
constexpr uint8_t PlayoutDelayLimits::kValueSizeBytes;
constexpr const char* PlayoutDelayLimits::kUri;
bool PlayoutDelayLimits::Parse(const uint8_t* data,
bool PlayoutDelayLimits::Parse(rtc::ArrayView<const uint8_t> data,
PlayoutDelay* playout_delay) {
RTC_DCHECK(playout_delay);
uint32_t raw = ByteReader<uint32_t, 3>::ReadBigEndian(data);
if (data.size() != 3)
return false;
uint32_t raw = ByteReader<uint32_t, 3>::ReadBigEndian(data.data());
uint16_t min_raw = (raw >> 12);
uint16_t max_raw = (raw & 0xfff);
if (min_raw > max_raw)

View File

@ -13,6 +13,7 @@
#include <stdint.h>
#include "webrtc/api/video/video_rotation.h"
#include "webrtc/base/array_view.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
namespace webrtc {
@ -24,7 +25,7 @@ class AbsoluteSendTime {
static constexpr const char* kUri =
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
static bool Parse(const uint8_t* data, uint32_t* time_24bits);
static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
static bool Write(uint8_t* data, int64_t time_ms);
static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
@ -39,7 +40,7 @@ class AudioLevel {
static constexpr const char* kUri =
"urn:ietf:params:rtp-hdrext:ssrc-audio-level";
static bool Parse(const uint8_t* data,
static bool Parse(rtc::ArrayView<const uint8_t> data,
bool* voice_activity,
uint8_t* audio_level);
static bool Write(uint8_t* data, bool voice_activity, uint8_t audio_level);
@ -51,7 +52,7 @@ class TransmissionOffset {
static constexpr uint8_t kValueSizeBytes = 3;
static constexpr const char* kUri = "urn:ietf:params:rtp-hdrext:toffset";
static bool Parse(const uint8_t* data, int32_t* rtp_time);
static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
static bool Write(uint8_t* data, int32_t rtp_time);
};
@ -62,7 +63,7 @@ class TransportSequenceNumber {
static constexpr const char* kUri =
"http://www.ietf.org/id/"
"draft-holmer-rmcat-transport-wide-cc-extensions-01";
static bool Parse(const uint8_t* data, uint16_t* value);
static bool Parse(rtc::ArrayView<const uint8_t> data, uint16_t* value);
static bool Write(uint8_t* data, uint16_t value);
};
@ -72,9 +73,9 @@ class VideoOrientation {
static constexpr uint8_t kValueSizeBytes = 1;
static constexpr const char* kUri = "urn:3gpp:video-orientation";
static bool Parse(const uint8_t* data, VideoRotation* value);
static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
static bool Write(uint8_t* data, VideoRotation value);
static bool Parse(const uint8_t* data, uint8_t* value);
static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
static bool Write(uint8_t* data, uint8_t value);
};
@ -92,7 +93,8 @@ class PlayoutDelayLimits {
// Maximum playout delay value in milliseconds.
static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
static bool Parse(const uint8_t* data, PlayoutDelay* playout_delay);
static bool Parse(rtc::ArrayView<const uint8_t> data,
PlayoutDelay* playout_delay);
static bool Write(uint8_t* data, const PlayoutDelay& playout_delay);
};

View File

@ -533,27 +533,17 @@ bool Packet::ParseBuffer(const uint8_t* buffer, size_t size) {
return true;
}
bool Packet::FindExtension(ExtensionType type,
uint8_t length,
uint16_t* offset) const {
RTC_DCHECK(offset);
rtc::ArrayView<const uint8_t> Packet::FindExtension(ExtensionType type) const {
for (const ExtensionInfo& extension : extension_entries_) {
if (extension.type == type) {
if (extension.length == 0) {
// Extension is registered but not set.
return false;
return nullptr;
}
if (length != extension.length) {
LOG(LS_WARNING) << "Length mismatch for extension '" << type
<< "': expected " << static_cast<int>(length)
<< ", received " << static_cast<int>(extension.length);
return false;
}
*offset = extension.offset;
return true;
return rtc::MakeArrayView(data() + extension.offset, extension.length);
}
}
return false;
return nullptr;
}
rtc::ArrayView<uint8_t> Packet::AllocateExtension(ExtensionType type,

View File

@ -142,13 +142,9 @@ class Packet {
// but does not touch packet own buffer, leaving packet in invalid state.
bool ParseBuffer(const uint8_t* buffer, size_t size);
// Find an extension based on the type field of the parameter.
// If found, length field would be validated, the offset field will be set
// and true returned,
// otherwise the parameter will be unchanged and false is returned.
bool FindExtension(ExtensionType type,
uint8_t length,
uint16_t* offset) const;
// Find an extension |type|.
// Returns view of the raw extension or empty view on failure.
rtc::ArrayView<const uint8_t> FindExtension(ExtensionType type) const;
// Find or allocate an extension |type|. Returns view of size |length|
// to write raw extension to or an empty view on failure.
@ -174,16 +170,15 @@ class Packet {
template <typename Extension>
bool Packet::HasExtension() const {
uint16_t offset = 0;
return FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset);
return !FindExtension(Extension::kId).empty();
}
template <typename Extension, typename... Values>
bool Packet::GetExtension(Values... values) const {
uint16_t offset = 0;
if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
auto raw = FindExtension(Extension::kId);
if (raw.empty())
return false;
return Extension::Parse(data() + offset, values...);
return Extension::Parse(raw, values...);
}
template <typename Extension, typename... Values>

View File

@ -358,7 +358,7 @@ TEST(RtpPacketTest, ParseWithoutExtensionManager) {
int32_t time_offset = 0;
auto raw_extension = packet.GetRawExtension(kTransmissionOffsetExtensionId);
EXPECT_EQ(raw_extension.size(), TransmissionOffset::kValueSizeBytes);
EXPECT_TRUE(TransmissionOffset::Parse(raw_extension.data(), &time_offset));
EXPECT_TRUE(TransmissionOffset::Parse(raw_extension, &time_offset));
EXPECT_EQ(time_offset, kTimeOffset);
}