Cleanup RtpPacketizerGeneric
merge SetPayloadData into constructor. Reuse payload size split function Bug: webrtc:9680 Change-Id: If8de22b2fc39c0bdf6d60154ecaaf19e2dccdcc9 Reviewed-on: https://webrtc-review.googlesource.com/97640 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24598}
This commit is contained in:

committed by
Commit Bot

parent
8a7916b3f8
commit
af8c03673b
@ -53,11 +53,8 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
|
||||
return std::move(packetizer);
|
||||
}
|
||||
default: {
|
||||
auto packetizer = absl::make_unique<RtpPacketizerGeneric>(
|
||||
rtp_video_header, frame_type, limits.max_payload_len,
|
||||
limits.last_packet_reduction_len);
|
||||
packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
|
||||
return std::move(packetizer);
|
||||
return absl::make_unique<RtpPacketizerGeneric>(
|
||||
payload, limits, rtp_video_header, frame_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,121 +21,70 @@ static const size_t kGenericHeaderLength = 1;
|
||||
static const size_t kExtendedHeaderLength = 2;
|
||||
|
||||
RtpPacketizerGeneric::RtpPacketizerGeneric(
|
||||
rtc::ArrayView<const uint8_t> payload,
|
||||
PayloadSizeLimits limits,
|
||||
const RTPVideoHeader& rtp_video_header,
|
||||
FrameType frame_type,
|
||||
size_t max_payload_len,
|
||||
size_t last_packet_reduction_len)
|
||||
: picture_id_(rtp_video_header.generic
|
||||
? absl::optional<uint16_t>(
|
||||
rtp_video_header.generic->frame_id & 0x7FFF)
|
||||
: absl::nullopt),
|
||||
payload_data_(nullptr),
|
||||
payload_size_(0),
|
||||
max_payload_len_(max_payload_len - kGenericHeaderLength -
|
||||
(picture_id_.has_value() ? kExtendedHeaderLength : 0)),
|
||||
last_packet_reduction_len_(last_packet_reduction_len),
|
||||
frame_type_(frame_type),
|
||||
num_packets_left_(0),
|
||||
num_larger_packets_(0) {}
|
||||
FrameType frame_type)
|
||||
: remaining_payload_(payload) {
|
||||
BuildHeader(rtp_video_header, frame_type);
|
||||
|
||||
RtpPacketizerGeneric::~RtpPacketizerGeneric() {}
|
||||
|
||||
size_t RtpPacketizerGeneric::SetPayloadData(
|
||||
const uint8_t* payload_data,
|
||||
size_t payload_size,
|
||||
const RTPFragmentationHeader* fragmentation) {
|
||||
payload_data_ = payload_data;
|
||||
payload_size_ = payload_size;
|
||||
|
||||
// Fragment packets such that they are almost the same size, even accounting
|
||||
// for larger header in the last packet.
|
||||
// Since we are given how much extra space is occupied by the longer header
|
||||
// in the last packet, we can pretend that RTP headers are the same, but
|
||||
// there's last_packet_reduction_len_ virtual payload, to be put at the end of
|
||||
// the last packet.
|
||||
//
|
||||
size_t total_bytes = payload_size_ + last_packet_reduction_len_;
|
||||
|
||||
// Minimum needed number of packets to fit payload and virtual payload in the
|
||||
// last packet.
|
||||
num_packets_left_ = (total_bytes + max_payload_len_ - 1) / max_payload_len_;
|
||||
// Given number of packets, calculate average size rounded down.
|
||||
payload_len_per_packet_ = total_bytes / num_packets_left_;
|
||||
// If we can't divide everything perfectly evenly, we put 1 extra byte in some
|
||||
// last packets: 14 bytes in 4 packets would be split as 3+3+4+4.
|
||||
num_larger_packets_ = total_bytes % num_packets_left_;
|
||||
RTC_DCHECK_LE(payload_len_per_packet_, max_payload_len_);
|
||||
|
||||
generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit;
|
||||
if (frame_type_ == kVideoFrameKey) {
|
||||
generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
|
||||
}
|
||||
if (picture_id_.has_value()) {
|
||||
generic_header_ |= RtpFormatVideoGeneric::kExtendedHeaderBit;
|
||||
limits.max_payload_len -= header_size_;
|
||||
payload_sizes_ = SplitAboutEqually(payload.size(), limits);
|
||||
current_packet_ = payload_sizes_.begin();
|
||||
}
|
||||
|
||||
return num_packets_left_;
|
||||
}
|
||||
RtpPacketizerGeneric::~RtpPacketizerGeneric() = default;
|
||||
|
||||
size_t RtpPacketizerGeneric::NumPackets() const {
|
||||
return num_packets_left_;
|
||||
return payload_sizes_.end() - current_packet_;
|
||||
}
|
||||
|
||||
bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
|
||||
RTC_DCHECK(packet);
|
||||
if (num_packets_left_ == 0)
|
||||
if (current_packet_ == payload_sizes_.end())
|
||||
return false;
|
||||
// Last larger_packets_ packets are 1 byte larger than previous packets.
|
||||
// Increase per packet payload once needed.
|
||||
if (num_packets_left_ == num_larger_packets_)
|
||||
++payload_len_per_packet_;
|
||||
size_t next_packet_payload_len = payload_len_per_packet_;
|
||||
if (payload_size_ <= next_packet_payload_len) {
|
||||
// Whole payload fits into this packet.
|
||||
next_packet_payload_len = payload_size_;
|
||||
if (num_packets_left_ == 2) {
|
||||
// This is the penultimate packet. Leave at least 1 payload byte for the
|
||||
// last packet.
|
||||
--next_packet_payload_len;
|
||||
RTC_DCHECK_GT(next_packet_payload_len, 0);
|
||||
}
|
||||
}
|
||||
RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_);
|
||||
|
||||
size_t total_length = next_packet_payload_len + kGenericHeaderLength +
|
||||
(picture_id_.has_value() ? kExtendedHeaderLength : 0);
|
||||
uint8_t* out_ptr = packet->AllocatePayload(total_length);
|
||||
size_t next_packet_payload_len = *current_packet_;
|
||||
|
||||
// Put generic header in packet.
|
||||
out_ptr[0] = generic_header_;
|
||||
out_ptr += kGenericHeaderLength;
|
||||
uint8_t* out_ptr =
|
||||
packet->AllocatePayload(header_size_ + next_packet_payload_len);
|
||||
RTC_CHECK(out_ptr);
|
||||
|
||||
if (picture_id_.has_value()) {
|
||||
WriteExtendedHeader(out_ptr);
|
||||
out_ptr += kExtendedHeaderLength;
|
||||
}
|
||||
memcpy(out_ptr, header_, header_size_);
|
||||
memcpy(out_ptr + header_size_, remaining_payload_.data(),
|
||||
next_packet_payload_len);
|
||||
|
||||
// Remove first-packet bit, following packets are intermediate.
|
||||
generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
|
||||
header_[0] &= ~RtpFormatVideoGeneric::kFirstPacketBit;
|
||||
|
||||
remaining_payload_ = remaining_payload_.subview(next_packet_payload_len);
|
||||
|
||||
++current_packet_;
|
||||
|
||||
// Put payload in packet.
|
||||
memcpy(out_ptr, payload_data_, next_packet_payload_len);
|
||||
payload_data_ += next_packet_payload_len;
|
||||
payload_size_ -= next_packet_payload_len;
|
||||
--num_packets_left_;
|
||||
// Packets left to produce and data left to split should end at the same time.
|
||||
RTC_DCHECK_EQ(num_packets_left_ == 0, payload_size_ == 0);
|
||||
|
||||
packet->SetMarker(payload_size_ == 0);
|
||||
RTC_DCHECK_EQ(current_packet_ == payload_sizes_.end(),
|
||||
remaining_payload_.empty());
|
||||
|
||||
packet->SetMarker(remaining_payload_.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
void RtpPacketizerGeneric::WriteExtendedHeader(uint8_t* out_ptr) {
|
||||
// Store bottom 15 bits of the the sequence number. Only 15 bits are used for
|
||||
// compatibility with other packetizer implemenetations that also use 15 bits.
|
||||
out_ptr[0] = (*picture_id_ >> 8) & 0x7F;
|
||||
out_ptr[1] = *picture_id_ & 0xFF;
|
||||
void RtpPacketizerGeneric::BuildHeader(const RTPVideoHeader& rtp_video_header,
|
||||
FrameType frame_type) {
|
||||
header_size_ = kGenericHeaderLength;
|
||||
header_[0] = RtpFormatVideoGeneric::kFirstPacketBit;
|
||||
if (frame_type == kVideoFrameKey) {
|
||||
header_[0] |= RtpFormatVideoGeneric::kKeyFrameBit;
|
||||
}
|
||||
if (rtp_video_header.generic.has_value()) {
|
||||
// Store bottom 15 bits of the the picture id. Only 15 bits are used for
|
||||
// compatibility with other packetizer implemenetations.
|
||||
uint16_t picture_id = rtp_video_header.generic->frame_id & 0x7FFF;
|
||||
header_[0] |= RtpFormatVideoGeneric::kExtendedHeaderBit;
|
||||
header_[1] = (picture_id >> 8) & 0x7F;
|
||||
header_[2] = picture_id & 0xFF;
|
||||
header_size_ += kExtendedHeaderLength;
|
||||
}
|
||||
}
|
||||
|
||||
RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default;
|
||||
|
@ -10,8 +10,9 @@
|
||||
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
|
||||
#define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VIDEO_GENERIC_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/array_view.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/rtp_rtcp/source/rtp_format.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
@ -29,18 +30,13 @@ class RtpPacketizerGeneric : public RtpPacketizer {
|
||||
public:
|
||||
// Initialize with payload from encoder.
|
||||
// The payload_data must be exactly one encoded generic frame.
|
||||
RtpPacketizerGeneric(const RTPVideoHeader& rtp_video_header,
|
||||
FrameType frametype,
|
||||
size_t max_payload_len,
|
||||
size_t last_packet_reduction_len);
|
||||
RtpPacketizerGeneric(rtc::ArrayView<const uint8_t> payload,
|
||||
PayloadSizeLimits limits,
|
||||
const RTPVideoHeader& rtp_video_header,
|
||||
FrameType frametype);
|
||||
|
||||
~RtpPacketizerGeneric() override;
|
||||
|
||||
// Returns total number of packets to be generated.
|
||||
size_t SetPayloadData(const uint8_t* payload_data,
|
||||
size_t payload_size,
|
||||
const RTPFragmentationHeader* fragmentation);
|
||||
|
||||
size_t NumPackets() const override;
|
||||
|
||||
// Get the next payload with generic payload header.
|
||||
@ -49,20 +45,15 @@ class RtpPacketizerGeneric : public RtpPacketizer {
|
||||
bool NextPacket(RtpPacketToSend* packet) override;
|
||||
|
||||
private:
|
||||
const absl::optional<uint16_t> picture_id_;
|
||||
const uint8_t* payload_data_;
|
||||
size_t payload_size_;
|
||||
const size_t max_payload_len_;
|
||||
const size_t last_packet_reduction_len_;
|
||||
FrameType frame_type_;
|
||||
size_t payload_len_per_packet_;
|
||||
uint8_t generic_header_;
|
||||
// Number of packets yet to be retrieved by NextPacket() call.
|
||||
size_t num_packets_left_;
|
||||
// Number of packets, which will be 1 byte more than the rest.
|
||||
size_t num_larger_packets_;
|
||||
// Fills header_ and header_size_ members.
|
||||
void BuildHeader(const RTPVideoHeader& rtp_video_header,
|
||||
FrameType frame_type);
|
||||
|
||||
void WriteExtendedHeader(uint8_t* out_ptr);
|
||||
uint8_t header_[3];
|
||||
size_t header_size_;
|
||||
rtc::ArrayView<const uint8_t> remaining_payload_;
|
||||
std::vector<size_t> payload_sizes_;
|
||||
std::vector<size_t>::const_iterator current_packet_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerGeneric);
|
||||
};
|
||||
|
@ -29,10 +29,9 @@ using ::testing::Each;
|
||||
using ::testing::ElementsAreArray;
|
||||
using ::testing::Le;
|
||||
using ::testing::SizeIs;
|
||||
using ::testing::Contains;
|
||||
|
||||
const size_t kMaxPayloadSize = 1200;
|
||||
|
||||
uint8_t kTestPayload[kMaxPayloadSize];
|
||||
constexpr RtpPacketizer::PayloadSizeLimits kNoSizeLimits;
|
||||
|
||||
std::vector<size_t> NextPacketFillPayloadSizes(
|
||||
RtpPacketizerGeneric* packetizer) {
|
||||
@ -44,185 +43,100 @@ std::vector<size_t> NextPacketFillPayloadSizes(
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t GetEffectivePacketsSizeDifference(std::vector<size_t>* payload_sizes,
|
||||
size_t last_packet_reduction_len) {
|
||||
// Account for larger last packet header.
|
||||
payload_sizes->back() += last_packet_reduction_len;
|
||||
auto minmax =
|
||||
std::minmax_element(payload_sizes->begin(), payload_sizes->end());
|
||||
// MAX-MIN
|
||||
size_t difference = *minmax.second - *minmax.first;
|
||||
// Revert temporary changes.
|
||||
payload_sizes->back() -= last_packet_reduction_len;
|
||||
return difference;
|
||||
TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSize) {
|
||||
const size_t kPayloadSize = 50;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 6;
|
||||
RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
|
||||
kVideoFrameKey);
|
||||
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
|
||||
EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSize) {
|
||||
const size_t kPayloadSize = 50;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, AllPacketsMayBeEqualAndRespectMaxPayloadSize) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
const size_t kPayloadSize = 13;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
AllPacketsMayBeEqual_RespectsLastPacketReductionLength) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
const size_t kPayloadSize = 13;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
AllPacketsMayBeEqual_MakesPacketsAlmostEqualInSize) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
const size_t kPayloadSize = 13;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
size_t sizes_difference = GetEffectivePacketsSizeDifference(
|
||||
&payload_sizes, kLastPacketReductionLen);
|
||||
EXPECT_LE(sizes_difference, 1u);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
AllPacketsMayBeEqual_GeneratesMinimumNumberOfPackets) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 3;
|
||||
const size_t kPayloadSize = 13;
|
||||
// Computed by hand. 3 packets would have capacity 3*(6-1)-3=12 (max length -
|
||||
// generic header lengh for each packet minus last packet reduction).
|
||||
// 4 packets is enough for kPayloadSize.
|
||||
const size_t kMinNumPackets = 4;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_EQ(num_packets, kMinNumPackets);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, SomePacketsAreSmaller_RespectsMaxPayloadSize) {
|
||||
const size_t kMaxPayloadLen = 8;
|
||||
const size_t kLastPacketReductionLen = 5;
|
||||
const size_t kPayloadSize = 28;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_THAT(payload_sizes, Each(Le(kMaxPayloadLen)));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
SomePacketsAreSmaller_RespectsLastPacketReductionLength) {
|
||||
const size_t kMaxPayloadLen = 8;
|
||||
const size_t kLastPacketReductionLen = 5;
|
||||
const size_t kPayloadSize = 28;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_LE(payload_sizes.back(), kMaxPayloadLen - kLastPacketReductionLen);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
SomePacketsAreSmaller_MakesPacketsAlmostEqualInSize) {
|
||||
const size_t kMaxPayloadLen = 8;
|
||||
const size_t kLastPacketReductionLen = 5;
|
||||
const size_t kPayloadSize = 28;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
size_t sizes_difference = GetEffectivePacketsSizeDifference(
|
||||
&payload_sizes, kLastPacketReductionLen);
|
||||
EXPECT_LE(sizes_difference, 1u);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric,
|
||||
SomePacketsAreSmaller_GeneratesMinimumNumberOfPackets) {
|
||||
const size_t kMaxPayloadLen = 8;
|
||||
const size_t kLastPacketReductionLen = 5;
|
||||
const size_t kPayloadSize = 28;
|
||||
// Computed by hand. 4 packets would have capacity 4*(8-1)-5=23 (max length -
|
||||
// generic header lengh for each packet minus last packet reduction).
|
||||
// 5 packets is enough for kPayloadSize.
|
||||
const size_t kMinNumPackets = 5;
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
size_t num_packets =
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
EXPECT_THAT(payload_sizes, SizeIs(num_packets));
|
||||
|
||||
EXPECT_EQ(num_packets, kMinNumPackets);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, HasFrameIdWritesExtendedHeader) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 6;
|
||||
RtpPacketizerGeneric packetizer(kPayload, limits, RTPVideoHeader(),
|
||||
kVideoFrameKey);
|
||||
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
|
||||
// With kPayloadSize > max_payload_len^2, there should be packets that use
|
||||
// all the payload, otherwise it is possible to use less packets.
|
||||
EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, WritesExtendedHeaderWhenPictureIdIsSet) {
|
||||
const size_t kPayloadSize = 13;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.generic.emplace().frame_id = 37;
|
||||
RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
|
||||
kVideoFrameKey);
|
||||
|
||||
RtpPacketToSend packet(nullptr);
|
||||
packetizer.NextPacket(&packet);
|
||||
ASSERT_TRUE(packetizer.NextPacket(&packet));
|
||||
|
||||
rtc::ArrayView<const uint8_t> payload = packet.payload();
|
||||
EXPECT_EQ(payload.size(), 3 + kPayloadSize);
|
||||
EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
|
||||
// Frame id is 37.
|
||||
EXPECT_EQ(0u, payload[1]);
|
||||
EXPECT_EQ(37u, payload[2]);
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, RespectsMaxPayloadSizeWithExtendedHeader) {
|
||||
const size_t kPayloadSize = 50;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 6;
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.generic.emplace().frame_id = 37;
|
||||
RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
|
||||
kVideoFrameKey);
|
||||
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
|
||||
EXPECT_THAT(payload_sizes, Each(Le(limits.max_payload_len)));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, UsesMaxPayloadSizeWithExtendedHeader) {
|
||||
const size_t kPayloadSize = 50;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 6;
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.generic.emplace().frame_id = 37;
|
||||
RtpPacketizerGeneric packetizer(kPayload, limits, rtp_video_header,
|
||||
kVideoFrameKey);
|
||||
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
|
||||
|
||||
// With kPayloadSize > max_payload_len^2, there should be packets that use
|
||||
// all the payload, otherwise it is possible to use less packets.
|
||||
EXPECT_THAT(payload_sizes, Contains(limits.max_payload_len));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
const size_t kPayloadSize = 13;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.generic.emplace().frame_id = 0x8137;
|
||||
RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, rtp_video_header,
|
||||
kVideoFrameKey);
|
||||
|
||||
RtpPacketToSend packet(nullptr);
|
||||
packetizer.NextPacket(&packet);
|
||||
ASSERT_TRUE(packetizer.NextPacket(&packet));
|
||||
|
||||
rtc::ArrayView<const uint8_t> payload = packet.payload();
|
||||
EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
|
||||
@ -232,16 +146,14 @@ TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerVideoGeneric, NoFrameIdDoesNotWriteExtendedHeader) {
|
||||
const size_t kMaxPayloadLen = 6;
|
||||
const size_t kLastPacketReductionLen = 2;
|
||||
const size_t kPayloadSize = 13;
|
||||
const uint8_t kPayload[kPayloadSize] = {};
|
||||
|
||||
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
|
||||
kMaxPayloadLen, kLastPacketReductionLen);
|
||||
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
|
||||
RtpPacketizerGeneric packetizer(kPayload, kNoSizeLimits, RTPVideoHeader(),
|
||||
kVideoFrameKey);
|
||||
|
||||
RtpPacketToSend packet(nullptr);
|
||||
packetizer.NextPacket(&packet);
|
||||
ASSERT_TRUE(packetizer.NextPacket(&packet));
|
||||
|
||||
rtc::ArrayView<const uint8_t> payload = packet.payload();
|
||||
EXPECT_FALSE(payload[0] & 0x04);
|
||||
@ -270,4 +182,5 @@ TEST(RtpDepacketizerVideoGeneric, ExtendedHeaderParsesFrameId) {
|
||||
EXPECT_EQ(0x1337, parsed_payload.video_header().generic->frame_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user