[rtcp] Fir/Sli/Rpsi updated not to use RTCPUtility
BUG=webrtc:5260 Review-Url: https://codereview.webrtc.org/2023803002 Cr-Commit-Position: refs/heads/master@{#12965}
This commit is contained in:
@ -13,11 +13,11 @@
|
|||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||||
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
constexpr uint8_t Fir::kFeedbackMessageType;
|
||||||
// RFC 4585: Feedback format.
|
// RFC 4585: Feedback format.
|
||||||
// Common packet format:
|
// Common packet format:
|
||||||
//
|
//
|
||||||
@ -43,26 +43,26 @@ namespace rtcp {
|
|||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
// | Seq nr. | Reserved = 0 |
|
// | Seq nr. | Reserved = 0 |
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
bool Fir::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
|
bool Fir::Parse(const CommonHeader& packet) {
|
||||||
RTC_CHECK(header.packet_type == kPacketType);
|
RTC_DCHECK_EQ(packet.type(), kPacketType);
|
||||||
RTC_CHECK(header.count_or_format == kFeedbackMessageType);
|
RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
|
||||||
|
|
||||||
// The FCI field MUST contain one or more FIR entries.
|
// The FCI field MUST contain one or more FIR entries.
|
||||||
if (header.payload_size_bytes < kCommonFeedbackLength + kFciLength) {
|
if (packet.payload_size_bytes() < kCommonFeedbackLength + kFciLength) {
|
||||||
LOG(LS_WARNING) << "Packet is too small to be a valid FIR packet.";
|
LOG(LS_WARNING) << "Packet is too small to be a valid FIR packet.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((header.payload_size_bytes - kCommonFeedbackLength) % kFciLength != 0) {
|
if ((packet.payload_size_bytes() - kCommonFeedbackLength) % kFciLength != 0) {
|
||||||
LOG(LS_WARNING) << "Invalid size for a valid FIR packet.";
|
LOG(LS_WARNING) << "Invalid size for a valid FIR packet.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseCommonFeedback(payload);
|
ParseCommonFeedback(packet.payload());
|
||||||
|
|
||||||
size_t number_of_fci_items =
|
size_t number_of_fci_items =
|
||||||
(header.payload_size_bytes - kCommonFeedbackLength) / kFciLength;
|
(packet.payload_size_bytes() - kCommonFeedbackLength) / kFciLength;
|
||||||
const uint8_t* next_fci = payload + kCommonFeedbackLength;
|
const uint8_t* next_fci = packet.payload() + kCommonFeedbackLength;
|
||||||
items_.resize(number_of_fci_items);
|
items_.resize(number_of_fci_items);
|
||||||
for (Request& request : items_) {
|
for (Request& request : items_) {
|
||||||
request.ssrc = ByteReader<uint32_t>::ReadBigEndian(next_fci);
|
request.ssrc = ByteReader<uint32_t>::ReadBigEndian(next_fci);
|
||||||
@ -88,7 +88,7 @@ bool Fir::Create(uint8_t* packet,
|
|||||||
CreateCommonFeedback(packet + *index);
|
CreateCommonFeedback(packet + *index);
|
||||||
*index += kCommonFeedbackLength;
|
*index += kCommonFeedbackLength;
|
||||||
|
|
||||||
const uint32_t kReserved = 0;
|
constexpr uint32_t kReserved = 0;
|
||||||
for (const Request& request : items_) {
|
for (const Request& request : items_) {
|
||||||
ByteWriter<uint32_t>::WriteBigEndian(packet + *index, request.ssrc);
|
ByteWriter<uint32_t>::WriteBigEndian(packet + *index, request.ssrc);
|
||||||
ByteWriter<uint8_t>::WriteBigEndian(packet + *index + 4, request.seq_nr);
|
ByteWriter<uint8_t>::WriteBigEndian(packet + *index + 4, request.seq_nr);
|
||||||
|
|||||||
@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
class CommonHeader;
|
||||||
// Full intra request (FIR) (RFC 5104).
|
// Full intra request (FIR) (RFC 5104).
|
||||||
class Fir : public Psfb {
|
class Fir : public Psfb {
|
||||||
public:
|
public:
|
||||||
static const uint8_t kFeedbackMessageType = 4;
|
static constexpr uint8_t kFeedbackMessageType = 4;
|
||||||
struct Request {
|
struct Request {
|
||||||
Request() : ssrc(0), seq_nr(0) {}
|
Request() : ssrc(0), seq_nr(0) {}
|
||||||
Request(uint32_t ssrc, uint8_t seq_nr) : ssrc(ssrc), seq_nr(seq_nr) {}
|
Request(uint32_t ssrc, uint8_t seq_nr) : ssrc(ssrc), seq_nr(seq_nr) {}
|
||||||
@ -34,8 +34,7 @@ class Fir : public Psfb {
|
|||||||
~Fir() override {}
|
~Fir() override {}
|
||||||
|
|
||||||
// Parse assumes header is already parsed and validated.
|
// Parse assumes header is already parsed and validated.
|
||||||
bool Parse(const RTCPUtility::RtcpCommonHeader& header,
|
bool Parse(const CommonHeader& packet);
|
||||||
const uint8_t* payload); // Size of the payload is in the header.
|
|
||||||
|
|
||||||
void WithRequestTo(uint32_t ssrc, uint8_t seq_num) {
|
void WithRequestTo(uint32_t ssrc, uint8_t seq_num) {
|
||||||
items_.push_back(Request(ssrc, seq_num));
|
items_.push_back(Request(ssrc, seq_num));
|
||||||
@ -49,7 +48,7 @@ class Fir : public Psfb {
|
|||||||
RtcpPacket::PacketReadyCallback* callback) const override;
|
RtcpPacket::PacketReadyCallback* callback) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t kFciLength = 8;
|
static constexpr size_t kFciLength = 8;
|
||||||
size_t BlockLength() const override {
|
size_t BlockLength() const override {
|
||||||
return kHeaderLength + kCommonFeedbackLength + kFciLength * items_.size();
|
return kHeaderLength + kCommonFeedbackLength + kFciLength * items_.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "webrtc/test/rtcp_packet_parser.h"
|
||||||
|
|
||||||
using testing::AllOf;
|
using testing::AllOf;
|
||||||
using testing::ElementsAre;
|
using testing::ElementsAre;
|
||||||
@ -20,32 +21,24 @@ using testing::Eq;
|
|||||||
using testing::Field;
|
using testing::Field;
|
||||||
using testing::make_tuple;
|
using testing::make_tuple;
|
||||||
using webrtc::rtcp::Fir;
|
using webrtc::rtcp::Fir;
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
using webrtc::RTCPUtility::RtcpParseCommonHeader;
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const uint32_t kSenderSsrc = 0x12345678;
|
constexpr uint32_t kSenderSsrc = 0x12345678;
|
||||||
const uint32_t kRemoteSsrc = 0x23456789;
|
constexpr uint32_t kRemoteSsrc = 0x23456789;
|
||||||
const uint8_t kSeqNr = 13;
|
constexpr uint8_t kSeqNr = 13;
|
||||||
// Manually created Fir packet matching constants above.
|
// Manually created Fir packet matching constants above.
|
||||||
const uint8_t kPacket[] = {0x84, 206, 0x00, 0x04,
|
constexpr uint8_t kPacket[] = {0x84, 206, 0x00, 0x04,
|
||||||
0x12, 0x34, 0x56, 0x78,
|
0x12, 0x34, 0x56, 0x78,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x23, 0x45, 0x67, 0x89,
|
0x23, 0x45, 0x67, 0x89,
|
||||||
0x0d, 0x00, 0x00, 0x00};
|
0x0d, 0x00, 0x00, 0x00};
|
||||||
|
} // namespace
|
||||||
bool ParseFir(const uint8_t* buffer, size_t length, Fir* fir) {
|
|
||||||
RtcpCommonHeader header;
|
|
||||||
EXPECT_TRUE(RtcpParseCommonHeader(buffer, length, &header));
|
|
||||||
EXPECT_THAT(header.BlockSize(), Eq(length));
|
|
||||||
return fir->Parse(header, buffer + RtcpCommonHeader::kHeaderSizeBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(RtcpPacketFirTest, Parse) {
|
TEST(RtcpPacketFirTest, Parse) {
|
||||||
Fir mutable_parsed;
|
Fir mutable_parsed;
|
||||||
EXPECT_TRUE(ParseFir(kPacket, sizeof(kPacket), &mutable_parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(kPacket, &mutable_parsed));
|
||||||
const Fir& parsed = mutable_parsed; // Read values from constant object.
|
const Fir& parsed = mutable_parsed; // Read values from constant object.
|
||||||
|
|
||||||
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
||||||
@ -73,7 +66,7 @@ TEST(RtcpPacketFirTest, TwoFciEntries) {
|
|||||||
|
|
||||||
rtc::Buffer packet = fir.Build();
|
rtc::Buffer packet = fir.Build();
|
||||||
Fir parsed;
|
Fir parsed;
|
||||||
EXPECT_TRUE(ParseFir(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
|
|
||||||
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
||||||
EXPECT_THAT(parsed.requests(),
|
EXPECT_THAT(parsed.requests(),
|
||||||
@ -84,42 +77,23 @@ TEST(RtcpPacketFirTest, TwoFciEntries) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(RtcpPacketFirTest, ParseFailsOnZeroFciEntries) {
|
TEST(RtcpPacketFirTest, ParseFailsOnZeroFciEntries) {
|
||||||
Fir fir;
|
constexpr uint8_t kPacketWithoutFci[] = {0x84, 206, 0x00, 0x02,
|
||||||
fir.From(kSenderSsrc);
|
0x12, 0x34, 0x56, 0x78,
|
||||||
fir.WithRequestTo(kRemoteSsrc, kSeqNr);
|
0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
rtc::Buffer packet = fir.Build();
|
|
||||||
|
|
||||||
RtcpCommonHeader header;
|
|
||||||
RtcpParseCommonHeader(packet.data(), packet.size(), &header);
|
|
||||||
ASSERT_EQ(16u, header.payload_size_bytes); // Common: 8, 1xfci: 8.
|
|
||||||
header.payload_size_bytes = 8; // Common: 8, 0xfcis.
|
|
||||||
|
|
||||||
Fir parsed;
|
Fir parsed;
|
||||||
EXPECT_FALSE(parsed.Parse(
|
EXPECT_FALSE(test::ParseSinglePacket(kPacketWithoutFci, &parsed));
|
||||||
header, packet.data() + RtcpCommonHeader::kHeaderSizeBytes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RtcpPacketFirTest, ParseFailsOnFractionalFciEntries) {
|
TEST(RtcpPacketFirTest, ParseFailsOnFractionalFciEntries) {
|
||||||
Fir fir;
|
constexpr uint8_t kPacketWithOneAndHalfFci[] = {0x84, 206, 0x00, 0x05,
|
||||||
fir.From(kSenderSsrc);
|
0x12, 0x34, 0x56, 0x78,
|
||||||
fir.WithRequestTo(kRemoteSsrc, kSeqNr);
|
0x00, 0x00, 0x00, 0x00,
|
||||||
fir.WithRequestTo(kRemoteSsrc + 1, kSeqNr + 1);
|
0x23, 0x45, 0x67, 0x89,
|
||||||
|
0x0d, 0x00, 0x00, 0x00,
|
||||||
|
'h', 'a', 'l', 'f'};
|
||||||
|
|
||||||
rtc::Buffer packet = fir.Build();
|
Fir parsed;
|
||||||
|
EXPECT_FALSE(test::ParseSinglePacket(kPacketWithOneAndHalfFci, &parsed));
|
||||||
RtcpCommonHeader header;
|
|
||||||
RtcpParseCommonHeader(packet.data(), packet.size(), &header);
|
|
||||||
ASSERT_EQ(24u, header.payload_size_bytes); // Common: 8, 2xfcis: 16.
|
|
||||||
|
|
||||||
const uint8_t* payload = packet.data() + RtcpCommonHeader::kHeaderSizeBytes;
|
|
||||||
Fir good;
|
|
||||||
EXPECT_TRUE(good.Parse(header, payload));
|
|
||||||
for (size_t i = 1; i < 8; ++i) {
|
|
||||||
header.payload_size_bytes = 16 + i;
|
|
||||||
Fir bad;
|
|
||||||
EXPECT_FALSE(bad.Parse(header, payload));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
constexpr uint8_t Psfb::kPacketType;
|
||||||
|
constexpr size_t Psfb::kCommonFeedbackLength;
|
||||||
// RFC 4585: Feedback format.
|
// RFC 4585: Feedback format.
|
||||||
//
|
//
|
||||||
// Common packet format:
|
// Common packet format:
|
||||||
|
|||||||
@ -22,10 +22,10 @@ namespace rtcp {
|
|||||||
// RFC 4585, Section 6.3.
|
// RFC 4585, Section 6.3.
|
||||||
class Psfb : public RtcpPacket {
|
class Psfb : public RtcpPacket {
|
||||||
public:
|
public:
|
||||||
static const uint8_t kPacketType = 206;
|
static constexpr uint8_t kPacketType = 206;
|
||||||
|
|
||||||
Psfb() : sender_ssrc_(0), media_ssrc_(0) {}
|
Psfb() : sender_ssrc_(0), media_ssrc_(0) {}
|
||||||
virtual ~Psfb() {}
|
~Psfb() override {}
|
||||||
|
|
||||||
void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
|
void From(uint32_t ssrc) { sender_ssrc_ = ssrc; }
|
||||||
void To(uint32_t ssrc) { media_ssrc_ = ssrc; }
|
void To(uint32_t ssrc) { media_ssrc_ = ssrc; }
|
||||||
@ -34,7 +34,7 @@ class Psfb : public RtcpPacket {
|
|||||||
uint32_t media_ssrc() const { return media_ssrc_; }
|
uint32_t media_ssrc() const { return media_ssrc_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const size_t kCommonFeedbackLength = 8;
|
static constexpr size_t kCommonFeedbackLength = 8;
|
||||||
void ParseCommonFeedback(const uint8_t* payload);
|
void ParseCommonFeedback(const uint8_t* payload);
|
||||||
void CreateCommonFeedback(uint8_t* payload) const;
|
void CreateCommonFeedback(uint8_t* payload) const;
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,14 @@
|
|||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||||
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
|
||||||
|
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
using webrtc::RtpUtility::Word32Align;
|
using webrtc::RtpUtility::Word32Align;
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
constexpr uint8_t Rpsi::kFeedbackMessageType;
|
||||||
// RFC 4585: Feedback format.
|
// RFC 4585: Feedback format.
|
||||||
// Reference picture selection indication (RPSI) (RFC 4585).
|
// Reference picture selection indication (RPSI) (RFC 4585).
|
||||||
//
|
//
|
||||||
@ -39,11 +40,11 @@ namespace rtcp {
|
|||||||
// : defined per codec ... | Padding (0) |
|
// : defined per codec ... | Padding (0) |
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
namespace {
|
namespace {
|
||||||
const size_t kPaddingSizeOffset = 8;
|
constexpr size_t kPaddingSizeOffset = 8;
|
||||||
const size_t kPayloadTypeOffset = 9;
|
constexpr size_t kPayloadTypeOffset = 9;
|
||||||
const size_t kBitStringOffset = 10;
|
constexpr size_t kBitStringOffset = 10;
|
||||||
|
|
||||||
const size_t kPidBits = 7;
|
constexpr size_t kPidBits = 7;
|
||||||
// Calculates number of bytes required to store given picture id.
|
// Calculates number of bytes required to store given picture id.
|
||||||
uint8_t RequiredBytes(uint64_t picture_id) {
|
uint8_t RequiredBytes(uint64_t picture_id) {
|
||||||
uint8_t required_bytes = 0;
|
uint8_t required_bytes = 0;
|
||||||
@ -62,34 +63,33 @@ Rpsi::Rpsi()
|
|||||||
picture_id_(0),
|
picture_id_(0),
|
||||||
block_length_(CalculateBlockLength(1)) {}
|
block_length_(CalculateBlockLength(1)) {}
|
||||||
|
|
||||||
bool Rpsi::Parse(const RTCPUtility::RtcpCommonHeader& header,
|
bool Rpsi::Parse(const CommonHeader& packet) {
|
||||||
const uint8_t* payload) {
|
RTC_DCHECK_EQ(packet.type(), kPacketType);
|
||||||
RTC_CHECK(header.packet_type == kPacketType);
|
RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
|
||||||
RTC_CHECK(header.count_or_format == kFeedbackMessageType);
|
|
||||||
|
|
||||||
if (header.payload_size_bytes < kCommonFeedbackLength + 4) {
|
if (packet.payload_size_bytes() < kCommonFeedbackLength + 4) {
|
||||||
LOG(LS_WARNING) << "Packet is too small to be a valid RPSI packet.";
|
LOG(LS_WARNING) << "Packet is too small to be a valid RPSI packet.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseCommonFeedback(payload);
|
ParseCommonFeedback(packet.payload());
|
||||||
|
|
||||||
uint8_t padding_bits = payload[kPaddingSizeOffset];
|
uint8_t padding_bits = packet.payload()[kPaddingSizeOffset];
|
||||||
if (padding_bits % 8 != 0) {
|
if (padding_bits % 8 != 0) {
|
||||||
LOG(LS_WARNING) << "Unknown rpsi packet with fractional number of bytes.";
|
LOG(LS_WARNING) << "Unknown rpsi packet with fractional number of bytes.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t padding_bytes = padding_bits / 8;
|
size_t padding_bytes = padding_bits / 8;
|
||||||
if (padding_bytes + kBitStringOffset >= header.payload_size_bytes) {
|
if (padding_bytes + kBitStringOffset >= packet.payload_size_bytes()) {
|
||||||
LOG(LS_WARNING) << "Too many padding bytes in a RPSI packet.";
|
LOG(LS_WARNING) << "Too many padding bytes in a RPSI packet.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t padding_offset = header.payload_size_bytes - padding_bytes;
|
size_t padding_offset = packet.payload_size_bytes() - padding_bytes;
|
||||||
payload_type_ = payload[kPayloadTypeOffset] & 0x7f;
|
payload_type_ = packet.payload()[kPayloadTypeOffset] & 0x7f;
|
||||||
picture_id_ = 0;
|
picture_id_ = 0;
|
||||||
for (size_t pos = kBitStringOffset; pos < padding_offset; ++pos) {
|
for (size_t pos = kBitStringOffset; pos < padding_offset; ++pos) {
|
||||||
picture_id_ <<= kPidBits;
|
picture_id_ <<= kPidBits;
|
||||||
picture_id_ |= (payload[pos] & 0x7f);
|
picture_id_ |= (packet.payload()[pos] & 0x7f);
|
||||||
}
|
}
|
||||||
// Required bytes might become less than came in the packet.
|
// Required bytes might become less than came in the packet.
|
||||||
block_length_ = CalculateBlockLength(RequiredBytes(picture_id_));
|
block_length_ = CalculateBlockLength(RequiredBytes(picture_id_));
|
||||||
@ -123,7 +123,7 @@ bool Rpsi::Create(uint8_t* packet,
|
|||||||
0x80 | static_cast<uint8_t>(picture_id_ >> (i * kPidBits));
|
0x80 | static_cast<uint8_t>(picture_id_ >> (i * kPidBits));
|
||||||
}
|
}
|
||||||
packet[(*index)++] = static_cast<uint8_t>(picture_id_ & 0x7f);
|
packet[(*index)++] = static_cast<uint8_t>(picture_id_ & 0x7f);
|
||||||
const uint8_t kPadding = 0;
|
constexpr uint8_t kPadding = 0;
|
||||||
for (size_t i = 0; i < padding_bytes; ++i)
|
for (size_t i = 0; i < padding_bytes; ++i)
|
||||||
packet[(*index)++] = kPadding;
|
packet[(*index)++] = kPadding;
|
||||||
RTC_CHECK_EQ(*index, index_end);
|
RTC_CHECK_EQ(*index, index_end);
|
||||||
|
|||||||
@ -14,21 +14,21 @@
|
|||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/base/constructormagic.h"
|
#include "webrtc/base/constructormagic.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
class CommonHeader;
|
||||||
|
|
||||||
// Reference picture selection indication (RPSI) (RFC 4585).
|
// Reference picture selection indication (RPSI) (RFC 4585).
|
||||||
// Assumes native bit string stores PictureId (VP8, VP9).
|
// Assumes native bit string stores PictureId (VP8, VP9).
|
||||||
class Rpsi : public Psfb {
|
class Rpsi : public Psfb {
|
||||||
public:
|
public:
|
||||||
static const uint8_t kFeedbackMessageType = 3;
|
static constexpr uint8_t kFeedbackMessageType = 3;
|
||||||
Rpsi();
|
Rpsi();
|
||||||
~Rpsi() override {}
|
~Rpsi() override {}
|
||||||
|
|
||||||
// Parse assumes header is already parsed and validated.
|
// Parse assumes header is already parsed and validated.
|
||||||
bool Parse(const RTCPUtility::RtcpCommonHeader& header,
|
bool Parse(const CommonHeader& packet);
|
||||||
const uint8_t* payload); // Size of the payload is in the header.
|
|
||||||
|
|
||||||
void WithPayloadType(uint8_t payload);
|
void WithPayloadType(uint8_t payload);
|
||||||
void WithPictureId(uint64_t picture_id);
|
void WithPictureId(uint64_t picture_id);
|
||||||
|
|||||||
@ -12,13 +12,11 @@
|
|||||||
|
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/test/rtcp_packet_parser.h"
|
||||||
|
|
||||||
using testing::ElementsAreArray;
|
using testing::ElementsAreArray;
|
||||||
using testing::make_tuple;
|
using testing::make_tuple;
|
||||||
using webrtc::rtcp::Rpsi;
|
using webrtc::rtcp::Rpsi;
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
using webrtc::RTCPUtility::RtcpParseCommonHeader;
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -33,23 +31,11 @@ const uint8_t kPacket[] = {0x83, 206, 0x00, 0x04,
|
|||||||
0x23, 0x45, 0x67, 0x89,
|
0x23, 0x45, 0x67, 0x89,
|
||||||
24, 100, 0xc1, 0xc2,
|
24, 100, 0xc1, 0xc2,
|
||||||
0x43, 0, 0, 0};
|
0x43, 0, 0, 0};
|
||||||
|
|
||||||
bool ParseRpsi(const uint8_t* buffer, size_t length, Rpsi* rpsi) {
|
|
||||||
RtcpCommonHeader header;
|
|
||||||
EXPECT_TRUE(RtcpParseCommonHeader(buffer, length, &header));
|
|
||||||
EXPECT_EQ(length, header.BlockSize());
|
|
||||||
return rpsi->Parse(header, buffer + RtcpCommonHeader::kHeaderSizeBytes);
|
|
||||||
}
|
|
||||||
// Testing function when test only interested if parse is successful.
|
|
||||||
bool ParseRpsi(const uint8_t* buffer, size_t length) {
|
|
||||||
Rpsi rpsi;
|
|
||||||
return ParseRpsi(buffer, length, &rpsi);
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(RtcpPacketRpsiTest, Parse) {
|
TEST(RtcpPacketRpsiTest, Parse) {
|
||||||
Rpsi mutable_parsed;
|
Rpsi mutable_parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(kPacket, sizeof(kPacket), &mutable_parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(kPacket, &mutable_parsed));
|
||||||
const Rpsi& parsed = mutable_parsed; // Read values from constant object.
|
const Rpsi& parsed = mutable_parsed; // Read values from constant object.
|
||||||
|
|
||||||
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
||||||
@ -77,9 +63,10 @@ TEST(RtcpPacketRpsiTest, ParseFailsOnTooSmallPacket) {
|
|||||||
rpsi.To(kRemoteSsrc);
|
rpsi.To(kRemoteSsrc);
|
||||||
|
|
||||||
rtc::Buffer packet = rpsi.Build();
|
rtc::Buffer packet = rpsi.Build();
|
||||||
packet.data()[3]--; // Reduce size field by one word (4 bytes).
|
packet[3]--; // Reduce size field by one word (4 bytes).
|
||||||
|
packet.SetSize(packet.size() - 4);
|
||||||
|
|
||||||
EXPECT_FALSE(ParseRpsi(packet.data(), packet.size() - 4));
|
EXPECT_FALSE(test::ParseSinglePacket(packet, &rpsi));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RtcpPacketRpsiTest, ParseFailsOnFractionalPaddingBytes) {
|
TEST(RtcpPacketRpsiTest, ParseFailsOnFractionalPaddingBytes) {
|
||||||
@ -90,11 +77,11 @@ TEST(RtcpPacketRpsiTest, ParseFailsOnFractionalPaddingBytes) {
|
|||||||
rtc::Buffer packet = rpsi.Build();
|
rtc::Buffer packet = rpsi.Build();
|
||||||
uint8_t* padding_bits = packet.data() + 12;
|
uint8_t* padding_bits = packet.data() + 12;
|
||||||
uint8_t saved_padding_bits = *padding_bits;
|
uint8_t saved_padding_bits = *padding_bits;
|
||||||
ASSERT_TRUE(ParseRpsi(packet.data(), packet.size()));
|
ASSERT_TRUE(test::ParseSinglePacket(packet, &rpsi));
|
||||||
|
|
||||||
for (uint8_t i = 1; i < 8; ++i) {
|
for (uint8_t i = 1; i < 8; ++i) {
|
||||||
*padding_bits = saved_padding_bits + i;
|
*padding_bits = saved_padding_bits + i;
|
||||||
EXPECT_FALSE(ParseRpsi(packet.data(), packet.size()));
|
EXPECT_FALSE(test::ParseSinglePacket(packet, &rpsi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +92,10 @@ TEST(RtcpPacketRpsiTest, ParseFailsOnTooBigPadding) {
|
|||||||
rpsi.WithPictureId(1); // Small picture id that occupy just 1 byte.
|
rpsi.WithPictureId(1); // Small picture id that occupy just 1 byte.
|
||||||
rtc::Buffer packet = rpsi.Build();
|
rtc::Buffer packet = rpsi.Build();
|
||||||
uint8_t* padding_bits = packet.data() + 12;
|
uint8_t* padding_bits = packet.data() + 12;
|
||||||
ASSERT_TRUE(ParseRpsi(packet.data(), packet.size()));
|
ASSERT_TRUE(test::ParseSinglePacket(packet, &rpsi));
|
||||||
|
|
||||||
*padding_bits += 8;
|
*padding_bits += 8;
|
||||||
EXPECT_FALSE(ParseRpsi(packet.data(), packet.size()));
|
EXPECT_FALSE(test::ParseSinglePacket(packet, &rpsi));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For raw rpsi packet extract how many bytes are used to store picture_id.
|
// For raw rpsi packet extract how many bytes are used to store picture_id.
|
||||||
@ -131,7 +118,7 @@ TEST(RtcpPacketRpsiTest, WithOneByteNativeString) {
|
|||||||
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
||||||
|
|
||||||
Rpsi parsed;
|
Rpsi parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
EXPECT_EQ(kPictureId, parsed.picture_id());
|
EXPECT_EQ(kPictureId, parsed.picture_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +133,7 @@ TEST(RtcpPacketRpsiTest, WithTwoByteNativeString) {
|
|||||||
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
||||||
|
|
||||||
Rpsi parsed;
|
Rpsi parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
EXPECT_EQ(kPictureId, parsed.picture_id());
|
EXPECT_EQ(kPictureId, parsed.picture_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +148,7 @@ TEST(RtcpPacketRpsiTest, WithThreeByteNativeString) {
|
|||||||
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
||||||
|
|
||||||
Rpsi parsed;
|
Rpsi parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
EXPECT_EQ(kPictureId, parsed.picture_id());
|
EXPECT_EQ(kPictureId, parsed.picture_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +163,7 @@ TEST(RtcpPacketRpsiTest, WithFourByteNativeString) {
|
|||||||
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
||||||
|
|
||||||
Rpsi parsed;
|
Rpsi parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
EXPECT_EQ(kPictureId, parsed.picture_id());
|
EXPECT_EQ(kPictureId, parsed.picture_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +179,7 @@ TEST(RtcpPacketRpsiTest, WithMaxPictureId) {
|
|||||||
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
EXPECT_EQ(kNumberOfValidBytes, UsedBytes(packet));
|
||||||
|
|
||||||
Rpsi parsed;
|
Rpsi parsed;
|
||||||
EXPECT_TRUE(ParseRpsi(packet.data(), packet.size(), &parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(packet, &parsed));
|
||||||
EXPECT_EQ(kPictureId, parsed.picture_id());
|
EXPECT_EQ(kPictureId, parsed.picture_id());
|
||||||
}
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -13,11 +13,11 @@
|
|||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||||
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
constexpr uint8_t Sli::kFeedbackMessageType;
|
||||||
// RFC 4585: Feedback format.
|
// RFC 4585: Feedback format.
|
||||||
//
|
//
|
||||||
// Common packet format:
|
// Common packet format:
|
||||||
@ -58,24 +58,24 @@ void Sli::Macroblocks::Create(uint8_t* buffer) const {
|
|||||||
ByteWriter<uint32_t>::WriteBigEndian(buffer, item_);
|
ByteWriter<uint32_t>::WriteBigEndian(buffer, item_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sli::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
|
bool Sli::Parse(const CommonHeader& packet) {
|
||||||
RTC_DCHECK(header.packet_type == kPacketType);
|
RTC_DCHECK_EQ(packet.type(), kPacketType);
|
||||||
RTC_DCHECK(header.count_or_format == kFeedbackMessageType);
|
RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
|
||||||
|
|
||||||
if (header.payload_size_bytes <
|
if (packet.payload_size_bytes() <
|
||||||
kCommonFeedbackLength + Macroblocks::kLength) {
|
kCommonFeedbackLength + Macroblocks::kLength) {
|
||||||
LOG(LS_WARNING) << "Packet is too small to be a valid SLI packet";
|
LOG(LS_WARNING) << "Packet is too small to be a valid SLI packet";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t number_of_items =
|
size_t number_of_items =
|
||||||
(header.payload_size_bytes - kCommonFeedbackLength) /
|
(packet.payload_size_bytes() - kCommonFeedbackLength) /
|
||||||
Macroblocks::kLength;
|
Macroblocks::kLength;
|
||||||
|
|
||||||
ParseCommonFeedback(payload);
|
ParseCommonFeedback(packet.payload());
|
||||||
items_.resize(number_of_items);
|
items_.resize(number_of_items);
|
||||||
|
|
||||||
const uint8_t* next_item = payload + kCommonFeedbackLength;
|
const uint8_t* next_item = packet.payload() + kCommonFeedbackLength;
|
||||||
for (Macroblocks& item : items_) {
|
for (Macroblocks& item : items_) {
|
||||||
item.Parse(next_item);
|
item.Parse(next_item);
|
||||||
next_item += Macroblocks::kLength;
|
next_item += Macroblocks::kLength;
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
|
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
|
||||||
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
|
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_PACKET_SLI_H_
|
||||||
|
|
||||||
@ -17,18 +16,18 @@
|
|||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/base/constructormagic.h"
|
#include "webrtc/base/constructormagic.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/psfb.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace rtcp {
|
namespace rtcp {
|
||||||
|
class CommonHeader;
|
||||||
|
|
||||||
// Slice loss indication (SLI) (RFC 4585).
|
// Slice loss indication (SLI) (RFC 4585).
|
||||||
class Sli : public Psfb {
|
class Sli : public Psfb {
|
||||||
public:
|
public:
|
||||||
static const uint8_t kFeedbackMessageType = 2;
|
static constexpr uint8_t kFeedbackMessageType = 2;
|
||||||
class Macroblocks {
|
class Macroblocks {
|
||||||
public:
|
public:
|
||||||
static const size_t kLength = 4;
|
static constexpr size_t kLength = 4;
|
||||||
Macroblocks() : item_(0) {}
|
Macroblocks() : item_(0) {}
|
||||||
Macroblocks(uint8_t picture_id, uint16_t first, uint16_t number);
|
Macroblocks(uint8_t picture_id, uint16_t first, uint16_t number);
|
||||||
~Macroblocks() {}
|
~Macroblocks() {}
|
||||||
@ -45,11 +44,10 @@ class Sli : public Psfb {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Sli() {}
|
Sli() {}
|
||||||
virtual ~Sli() {}
|
~Sli() override {}
|
||||||
|
|
||||||
// Parse assumes header is already parsed and validated.
|
// Parse assumes header is already parsed and validated.
|
||||||
bool Parse(const RTCPUtility::RtcpCommonHeader& header,
|
bool Parse(const CommonHeader& packet);
|
||||||
const uint8_t* payload); // Size of the payload is in the header.
|
|
||||||
|
|
||||||
void WithPictureId(uint8_t picture_id,
|
void WithPictureId(uint8_t picture_id,
|
||||||
uint16_t first_macroblock = 0,
|
uint16_t first_macroblock = 0,
|
||||||
|
|||||||
@ -12,42 +12,33 @@
|
|||||||
|
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "webrtc/test/rtcp_packet_parser.h"
|
||||||
|
|
||||||
using testing::ElementsAreArray;
|
using testing::ElementsAreArray;
|
||||||
using testing::make_tuple;
|
using testing::make_tuple;
|
||||||
using webrtc::rtcp::Sli;
|
using webrtc::rtcp::Sli;
|
||||||
using webrtc::RTCPUtility::RtcpCommonHeader;
|
|
||||||
using webrtc::RTCPUtility::RtcpParseCommonHeader;
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
constexpr uint32_t kSenderSsrc = 0x12345678;
|
||||||
|
constexpr uint32_t kRemoteSsrc = 0x23456789;
|
||||||
|
|
||||||
const uint32_t kSenderSsrc = 0x12345678;
|
constexpr uint8_t kPictureId = 0x3f;
|
||||||
const uint32_t kRemoteSsrc = 0x23456789;
|
constexpr uint16_t kFirstMb = 0x1e61;
|
||||||
|
constexpr uint16_t kNumberOfMb = 0x1a0a;
|
||||||
const uint8_t kPictureId = 0x3f;
|
constexpr uint32_t kSliItem = (static_cast<uint32_t>(kFirstMb) << 19) |
|
||||||
const uint16_t kFirstMb = 0x1e61;
|
|
||||||
const uint16_t kNumberOfMb = 0x1a0a;
|
|
||||||
const uint32_t kSliItem = (static_cast<uint32_t>(kFirstMb) << 19) |
|
|
||||||
(static_cast<uint32_t>(kNumberOfMb) << 6) |
|
(static_cast<uint32_t>(kNumberOfMb) << 6) |
|
||||||
static_cast<uint32_t>(kPictureId);
|
static_cast<uint32_t>(kPictureId);
|
||||||
|
|
||||||
// Manually created Sli packet matching constants above.
|
// Manually created Sli packet matching constants above.
|
||||||
const uint8_t kPacket[] = {0x82, 206, 0x00, 0x03,
|
constexpr uint8_t kPacket[] = {0x82, 206, 0x00, 0x03,
|
||||||
0x12, 0x34, 0x56, 0x78,
|
0x12, 0x34, 0x56, 0x78,
|
||||||
0x23, 0x45, 0x67, 0x89,
|
0x23, 0x45, 0x67, 0x89,
|
||||||
(kSliItem >> 24) & 0xff,
|
(kSliItem >> 24) & 0xff,
|
||||||
(kSliItem >> 16) & 0xff,
|
(kSliItem >> 16) & 0xff,
|
||||||
(kSliItem >> 8) & 0xff,
|
(kSliItem >> 8) & 0xff,
|
||||||
kSliItem & 0xff};
|
kSliItem & 0xff};
|
||||||
const size_t kPacketLength = sizeof(kPacket);
|
} // namespace
|
||||||
|
|
||||||
bool ParseSli(const uint8_t* buffer, size_t length, Sli* sli) {
|
|
||||||
RtcpCommonHeader header;
|
|
||||||
EXPECT_TRUE(RtcpParseCommonHeader(buffer, length, &header));
|
|
||||||
EXPECT_EQ(length, header.BlockSize());
|
|
||||||
return sli->Parse(header, buffer + RtcpCommonHeader::kHeaderSizeBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(RtcpPacketSliTest, Create) {
|
TEST(RtcpPacketSliTest, Create) {
|
||||||
Sli sli;
|
Sli sli;
|
||||||
@ -63,7 +54,7 @@ TEST(RtcpPacketSliTest, Create) {
|
|||||||
|
|
||||||
TEST(RtcpPacketSliTest, Parse) {
|
TEST(RtcpPacketSliTest, Parse) {
|
||||||
Sli mutable_parsed;
|
Sli mutable_parsed;
|
||||||
EXPECT_TRUE(ParseSli(kPacket, kPacketLength, &mutable_parsed));
|
EXPECT_TRUE(test::ParseSinglePacket(kPacket, &mutable_parsed));
|
||||||
const Sli& parsed = mutable_parsed; // Read values from constant object.
|
const Sli& parsed = mutable_parsed; // Read values from constant object.
|
||||||
|
|
||||||
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
|
||||||
@ -81,10 +72,10 @@ TEST(RtcpPacketSliTest, ParseFailsOnTooSmallPacket) {
|
|||||||
sli.WithPictureId(kPictureId, kFirstMb, kNumberOfMb);
|
sli.WithPictureId(kPictureId, kFirstMb, kNumberOfMb);
|
||||||
|
|
||||||
rtc::Buffer packet = sli.Build();
|
rtc::Buffer packet = sli.Build();
|
||||||
packet.data()[3]--; // Decrease size by 1 word (4 bytes).
|
packet[3]--; // Decrease size by 1 word (4 bytes).
|
||||||
|
packet.SetSize(packet.size() - 4);
|
||||||
|
|
||||||
EXPECT_FALSE(ParseSli(packet.data(), packet.size() - 4, &sli));
|
EXPECT_FALSE(test::ParseSinglePacket(packet, &sli));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Reference in New Issue
Block a user