In RtpVideoStreamReceiver do not rely on RTP sequence number unwrap to be stable

Currently this class assumed that if the same RTP sequence number is unwrapped again result would be the same.
That might not be true when several packets were inserted in between these two calls and unwrapper changed its state

This CL propose instead to unwrap once, and save the result in the intermediate struct.
To minimize the change and the risk, only redundant unwrapping is replaced to use unwrapped sequence number

Bug: webrtc:353565743
Change-Id: I8a18c8c206a0e16010951cabcf81dd9cb1588eda
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/357660
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42662}
This commit is contained in:
Danil Chapovalov 2024-07-22 15:25:11 +02:00 committed by WebRTC LUCI CQ
parent 36b548b31a
commit ac15a137ac
10 changed files with 93 additions and 84 deletions

View File

@ -83,6 +83,7 @@ class RtpVideoFrameAssembler::Impl {
void ClearOldData(uint16_t incoming_seq_num); void ClearOldData(uint16_t incoming_seq_num);
std::unique_ptr<FrameDependencyStructure> video_structure_; std::unique_ptr<FrameDependencyStructure> video_structure_;
SeqNumUnwrapper<uint16_t> rtp_sequence_number_unwrapper_;
SeqNumUnwrapper<uint16_t> frame_id_unwrapper_; SeqNumUnwrapper<uint16_t> frame_id_unwrapper_;
absl::optional<int64_t> video_structure_frame_id_; absl::optional<int64_t> video_structure_frame_id_;
std::unique_ptr<VideoRtpDepacketizer> depacketizer_; std::unique_ptr<VideoRtpDepacketizer> depacketizer_;
@ -124,7 +125,9 @@ RtpVideoFrameAssembler::FrameVector RtpVideoFrameAssembler::Impl::InsertPacket(
parsed_payload->video_header.is_last_packet_in_frame |= rtp_packet.Marker(); parsed_payload->video_header.is_last_packet_in_frame |= rtp_packet.Marker();
auto packet = std::make_unique<video_coding::PacketBuffer::Packet>( auto packet = std::make_unique<video_coding::PacketBuffer::Packet>(
rtp_packet, parsed_payload->video_header); rtp_packet,
rtp_sequence_number_unwrapper_.Unwrap(rtp_packet.SequenceNumber()),
parsed_payload->video_header);
packet->video_payload = std::move(parsed_payload->video_payload); packet->video_payload = std::move(parsed_payload->video_payload);
ClearOldData(rtp_packet.SequenceNumber()); ClearOldData(rtp_packet.SequenceNumber());
@ -163,8 +166,8 @@ RtpVideoFrameAssembler::Impl::AssembleFrames(
const video_coding::PacketBuffer::Packet& last_packet = *packet; const video_coding::PacketBuffer::Packet& last_packet = *packet;
result.push_back(std::make_unique<RtpFrameObject>( result.push_back(std::make_unique<RtpFrameObject>(
first_packet->seq_num, // first_packet->seq_num(), //
last_packet.seq_num, // last_packet.seq_num(), //
last_packet.marker_bit, // last_packet.marker_bit, //
/*times_nacked=*/0, // /*times_nacked=*/0, //
/*first_packet_received_time=*/0, // /*first_packet_received_time=*/0, //

View File

@ -110,7 +110,7 @@ H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket(
InsertResult result; InsertResult result;
int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(packet->seq_num); int64_t unwrapped_seq_num = packet->sequence_number;
auto& packet_slot = GetPacket(unwrapped_seq_num); auto& packet_slot = GetPacket(unwrapped_seq_num);
if (packet_slot != nullptr && if (packet_slot != nullptr &&
AheadOrAt(packet_slot->timestamp, packet->timestamp)) { AheadOrAt(packet_slot->timestamp, packet->timestamp)) {
@ -174,7 +174,7 @@ H26xPacketBuffer::InsertResult H26xPacketBuffer::FindFrames(
// Packets that were never assembled into a completed frame will stay in // Packets that were never assembled into a completed frame will stay in
// the 'buffer_'. Check that the `packet` sequence number match the expected // the 'buffer_'. Check that the `packet` sequence number match the expected
// unwrapped sequence number. // unwrapped sequence number.
if (static_cast<uint16_t>(seq_num) != packet->seq_num) { if (seq_num != packet->sequence_number) {
return result; return result;
} }

View File

@ -94,7 +94,6 @@ class H26xPacketBuffer {
std::array<std::unique_ptr<Packet>, kBufferSize> buffer_; std::array<std::unique_ptr<Packet>, kBufferSize> buffer_;
std::array<int64_t, kNumTrackedSequences> last_continuous_in_sequence_; std::array<int64_t, kNumTrackedSequences> last_continuous_in_sequence_;
int64_t last_continuous_in_sequence_index_ = 0; int64_t last_continuous_in_sequence_index_ = 0;
SeqNumUnwrapper<uint16_t> seq_num_unwrapper_;
// Map from pps_pic_parameter_set_id to the PPS payload associated with this // Map from pps_pic_parameter_set_id to the PPS payload associated with this
// ID. // ID.

View File

@ -76,7 +76,7 @@ class H264Packet {
H264Packet& Marker(); H264Packet& Marker();
H264Packet& AsFirstFragment(); H264Packet& AsFirstFragment();
H264Packet& Time(uint32_t rtp_timestamp); H264Packet& Time(uint32_t rtp_timestamp);
H264Packet& SeqNum(uint16_t rtp_seq_num); H264Packet& SeqNum(int64_t rtp_seq_num);
std::unique_ptr<H26xPacketBuffer::Packet> Build(); std::unique_ptr<H26xPacketBuffer::Packet> Build();
@ -97,7 +97,7 @@ class H264Packet {
bool first_fragment_ = false; bool first_fragment_ = false;
bool marker_bit_ = false; bool marker_bit_ = false;
uint32_t rtp_timestamp_ = 0; uint32_t rtp_timestamp_ = 0;
uint16_t rtp_seq_num_ = 0; int64_t rtp_seq_num_ = 0;
std::vector<std::vector<uint8_t>> nalu_payloads_; std::vector<std::vector<uint8_t>> nalu_payloads_;
}; };
@ -174,7 +174,7 @@ H264Packet& H264Packet::Time(uint32_t rtp_timestamp) {
return *this; return *this;
} }
H264Packet& H264Packet::SeqNum(uint16_t rtp_seq_num) { H264Packet& H264Packet::SeqNum(int64_t rtp_seq_num) {
rtp_seq_num_ = rtp_seq_num; rtp_seq_num_ = rtp_seq_num;
return *this; return *this;
} }
@ -209,7 +209,7 @@ std::unique_ptr<H26xPacketBuffer::Packet> H264Packet::Build() {
res->marker_bit = marker_bit_; res->marker_bit = marker_bit_;
res->video_header = video_header_; res->video_header = video_header_;
res->timestamp = rtp_timestamp_; res->timestamp = rtp_timestamp_;
res->seq_num = rtp_seq_num_; res->sequence_number = rtp_seq_num_;
res->video_header.codec = kVideoCodecH264; res->video_header.codec = kVideoCodecH264;
return res; return res;
@ -263,7 +263,7 @@ class H265Packet {
H265Packet& Marker(); H265Packet& Marker();
H265Packet& AsFirstFragment(); H265Packet& AsFirstFragment();
H265Packet& Time(uint32_t rtp_timestamp); H265Packet& Time(uint32_t rtp_timestamp);
H265Packet& SeqNum(uint16_t rtp_seq_num); H265Packet& SeqNum(int64_t rtp_seq_num);
std::unique_ptr<H26xPacketBuffer::Packet> Build(); std::unique_ptr<H26xPacketBuffer::Packet> Build();
@ -329,7 +329,7 @@ std::unique_ptr<H26xPacketBuffer::Packet> H265Packet::Build() {
res->marker_bit = marker_bit_; res->marker_bit = marker_bit_;
res->video_header = video_header_; res->video_header = video_header_;
res->timestamp = rtp_timestamp_; res->timestamp = rtp_timestamp_;
res->seq_num = rtp_seq_num_; res->sequence_number = rtp_seq_num_;
res->video_header.codec = kVideoCodecH265; res->video_header.codec = kVideoCodecH265;
res->video_payload = rtc::CopyOnWriteBuffer(); res->video_payload = rtc::CopyOnWriteBuffer();
for (const auto& payload : nalu_payloads_) { for (const auto& payload : nalu_payloads_) {
@ -349,7 +349,7 @@ H265Packet& H265Packet::Time(uint32_t rtp_timestamp) {
return *this; return *this;
} }
H265Packet& H265Packet::SeqNum(uint16_t rtp_seq_num) { H265Packet& H265Packet::SeqNum(int64_t rtp_seq_num) {
rtp_seq_num_ = rtp_seq_num; rtp_seq_num_ = rtp_seq_num;
return *this; return *this;
} }
@ -924,11 +924,14 @@ TEST(H26xPacketBufferTest, RtpSeqNumWrap) {
H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build()));
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(
H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); H264Packet(kH264FuA).Idr().SeqNum(0x1'0000).Time(0).Build()));
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264FuA)
.InsertPacket( .Idr()
H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) .SeqNum(0x1'0001)
.Time(0)
.Marker()
.Build())
.packets, .packets,
SizeIs(3)); SizeIs(3));
} }

View File

@ -35,13 +35,18 @@ namespace webrtc {
namespace video_coding { namespace video_coding {
PacketBuffer::Packet::Packet(const RtpPacketReceived& rtp_packet, PacketBuffer::Packet::Packet(const RtpPacketReceived& rtp_packet,
int64_t sequence_number,
const RTPVideoHeader& video_header) const RTPVideoHeader& video_header)
: marker_bit(rtp_packet.Marker()), : marker_bit(rtp_packet.Marker()),
payload_type(rtp_packet.PayloadType()), payload_type(rtp_packet.PayloadType()),
seq_num(rtp_packet.SequenceNumber()), sequence_number(sequence_number),
timestamp(rtp_packet.Timestamp()), timestamp(rtp_packet.Timestamp()),
times_nacked(-1), times_nacked(-1),
video_header(video_header) {} video_header(video_header) {
// Unwrapped sequence number should match the original wrapped one.
RTC_DCHECK_EQ(static_cast<uint16_t>(sequence_number),
rtp_packet.SequenceNumber());
}
PacketBuffer::PacketBuffer(size_t start_buffer_size, size_t max_buffer_size) PacketBuffer::PacketBuffer(size_t start_buffer_size, size_t max_buffer_size)
: max_size_(max_buffer_size), : max_size_(max_buffer_size),
@ -64,7 +69,7 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(
std::unique_ptr<PacketBuffer::Packet> packet) { std::unique_ptr<PacketBuffer::Packet> packet) {
PacketBuffer::InsertResult result; PacketBuffer::InsertResult result;
uint16_t seq_num = packet->seq_num; uint16_t seq_num = packet->seq_num();
size_t index = seq_num % buffer_.size(); size_t index = seq_num % buffer_.size();
if (!first_packet_received_) { if (!first_packet_received_) {
@ -89,7 +94,7 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(
if (buffer_[index] != nullptr) { if (buffer_[index] != nullptr) {
// Duplicate packet, just delete the payload. // Duplicate packet, just delete the payload.
if (buffer_[index]->seq_num == packet->seq_num) { if (buffer_[index]->seq_num() == packet->seq_num()) {
return result; return result;
} }
@ -140,7 +145,7 @@ void PacketBuffer::ClearTo(uint16_t seq_num) {
size_t iterations = std::min(diff, buffer_.size()); size_t iterations = std::min(diff, buffer_.size());
for (size_t i = 0; i < iterations; ++i) { for (size_t i = 0; i < iterations; ++i) {
auto& stored = buffer_[first_seq_num_ % buffer_.size()]; auto& stored = buffer_[first_seq_num_ % buffer_.size()];
if (stored != nullptr && AheadOf<uint16_t>(seq_num, stored->seq_num)) { if (stored != nullptr && AheadOf<uint16_t>(seq_num, stored->seq_num())) {
stored = nullptr; stored = nullptr;
} }
++first_seq_num_; ++first_seq_num_;
@ -201,7 +206,7 @@ bool PacketBuffer::ExpandBufferSize() {
std::vector<std::unique_ptr<Packet>> new_buffer(new_size); std::vector<std::unique_ptr<Packet>> new_buffer(new_size);
for (std::unique_ptr<Packet>& entry : buffer_) { for (std::unique_ptr<Packet>& entry : buffer_) {
if (entry != nullptr) { if (entry != nullptr) {
new_buffer[entry->seq_num % new_size] = std::move(entry); new_buffer[entry->seq_num() % new_size] = std::move(entry);
} }
} }
buffer_ = std::move(new_buffer); buffer_ = std::move(new_buffer);
@ -217,13 +222,13 @@ bool PacketBuffer::PotentialNewFrame(uint16_t seq_num) const {
if (entry == nullptr) if (entry == nullptr)
return false; return false;
if (entry->seq_num != seq_num) if (entry->seq_num() != seq_num)
return false; return false;
if (entry->is_first_packet_in_frame()) if (entry->is_first_packet_in_frame())
return true; return true;
if (prev_entry == nullptr) if (prev_entry == nullptr)
return false; return false;
if (prev_entry->seq_num != static_cast<uint16_t>(entry->seq_num - 1)) if (prev_entry->seq_num() != static_cast<uint16_t>(entry->seq_num() - 1))
return false; return false;
if (prev_entry->timestamp != entry->timestamp) if (prev_entry->timestamp != entry->timestamp)
return false; return false;
@ -381,7 +386,7 @@ std::vector<std::unique_ptr<PacketBuffer::Packet>> PacketBuffer::FindFrames(
for (uint16_t i = start_seq_num; i != end_seq_num; ++i) { for (uint16_t i = start_seq_num; i != end_seq_num; ++i) {
std::unique_ptr<Packet>& packet = buffer_[i % buffer_.size()]; std::unique_ptr<Packet>& packet = buffer_[i % buffer_.size()];
RTC_DCHECK(packet); RTC_DCHECK(packet);
RTC_DCHECK_EQ(i, packet->seq_num); RTC_DCHECK_EQ(i, packet->seq_num());
// Ensure frame boundary flags are properly set. // Ensure frame boundary flags are properly set.
packet->video_header.is_first_packet_in_frame = (i == start_seq_num); packet->video_header.is_first_packet_in_frame = (i == start_seq_num);
packet->video_header.is_last_packet_in_frame = (i == seq_num); packet->video_header.is_last_packet_in_frame = (i == seq_num);

View File

@ -34,6 +34,7 @@ class PacketBuffer {
struct Packet { struct Packet {
Packet() = default; Packet() = default;
Packet(const RtpPacketReceived& rtp_packet, Packet(const RtpPacketReceived& rtp_packet,
int64_t sequence_number,
const RTPVideoHeader& video_header); const RTPVideoHeader& video_header);
Packet(const Packet&) = delete; Packet(const Packet&) = delete;
Packet(Packet&&) = delete; Packet(Packet&&) = delete;
@ -51,13 +52,14 @@ class PacketBuffer {
bool is_last_packet_in_frame() const { bool is_last_packet_in_frame() const {
return video_header.is_last_packet_in_frame; return video_header.is_last_packet_in_frame;
} }
uint16_t seq_num() const { return static_cast<uint16_t>(sequence_number); }
// If all its previous packets have been inserted into the packet buffer. // If all its previous packets have been inserted into the packet buffer.
// Set and used internally by the PacketBuffer. // Set and used internally by the PacketBuffer.
bool continuous = false; bool continuous = false;
bool marker_bit = false; bool marker_bit = false;
uint8_t payload_type = 0; uint8_t payload_type = 0;
uint16_t seq_num = 0; int64_t sequence_number = 0;
uint32_t timestamp = 0; uint32_t timestamp = 0;
int times_nacked = -1; int times_nacked = -1;

View File

@ -49,7 +49,7 @@ std::vector<uint16_t> StartSeqNums(
for (const auto& packet : packets) { for (const auto& packet : packets) {
EXPECT_EQ(frame_boundary, packet->is_first_packet_in_frame()); EXPECT_EQ(frame_boundary, packet->is_first_packet_in_frame());
if (packet->is_first_packet_in_frame()) { if (packet->is_first_packet_in_frame()) {
result.push_back(packet->seq_num); result.push_back(packet->seq_num());
} }
frame_boundary = packet->is_last_packet_in_frame(); frame_boundary = packet->is_last_packet_in_frame();
} }
@ -85,11 +85,11 @@ void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
for (const auto& packet : result.packets) { for (const auto& packet : result.packets) {
if (packet->is_first_packet_in_frame() && if (packet->is_first_packet_in_frame() &&
packet->is_last_packet_in_frame()) { packet->is_last_packet_in_frame()) {
*os << "{sn: " << packet->seq_num << " }"; *os << "{sn: " << packet->seq_num() << " }";
} else if (packet->is_first_packet_in_frame()) { } else if (packet->is_first_packet_in_frame()) {
*os << "{sn: [" << packet->seq_num << "-"; *os << "{sn: [" << packet->seq_num() << "-";
} else if (packet->is_last_packet_in_frame()) { } else if (packet->is_last_packet_in_frame()) {
*os << packet->seq_num << "] }, "; *os << packet->seq_num() << "] }, ";
} }
} }
*os << " }"; *os << " }";
@ -108,7 +108,7 @@ class PacketBufferTest : public ::testing::Test {
enum IsFirst { kFirst, kNotFirst }; enum IsFirst { kFirst, kNotFirst };
enum IsLast { kLast, kNotLast }; enum IsLast { kLast, kNotLast };
PacketBufferInsertResult Insert(uint16_t seq_num, // packet sequence number PacketBufferInsertResult Insert(int64_t seq_num, // packet sequence number
IsKeyFrame keyframe, // is keyframe IsKeyFrame keyframe, // is keyframe
IsFirst first, // is first packet of frame IsFirst first, // is first packet of frame
IsLast last, // is last packet of frame IsLast last, // is last packet of frame
@ -117,7 +117,7 @@ class PacketBufferTest : public ::testing::Test {
auto packet = std::make_unique<PacketBuffer::Packet>(); auto packet = std::make_unique<PacketBuffer::Packet>();
packet->video_header.codec = kVideoCodecGeneric; packet->video_header.codec = kVideoCodecGeneric;
packet->timestamp = timestamp; packet->timestamp = timestamp;
packet->seq_num = seq_num; packet->sequence_number = seq_num;
packet->video_header.frame_type = keyframe == kKeyFrame packet->video_header.frame_type = keyframe == kKeyFrame
? VideoFrameType::kVideoFrameKey ? VideoFrameType::kVideoFrameKey
: VideoFrameType::kVideoFrameDelta; : VideoFrameType::kVideoFrameDelta;
@ -134,12 +134,12 @@ class PacketBufferTest : public ::testing::Test {
}; };
TEST_F(PacketBufferTest, InsertOnePacket) { TEST_F(PacketBufferTest, InsertOnePacket) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1)); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
} }
TEST_F(PacketBufferTest, InsertMultiplePackets) { TEST_F(PacketBufferTest, InsertMultiplePackets) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1)); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).packets, SizeIs(1)); EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).packets, SizeIs(1)); EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
@ -147,7 +147,7 @@ TEST_F(PacketBufferTest, InsertMultiplePackets) {
} }
TEST_F(PacketBufferTest, InsertDuplicatePacket) { TEST_F(PacketBufferTest, InsertDuplicatePacket) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty()); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty()); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).packets, EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).packets,
@ -156,14 +156,14 @@ TEST_F(PacketBufferTest, InsertDuplicatePacket) {
TEST_F(PacketBufferTest, SeqNumWrapOneFrame) { TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
Insert(0xFFFF, kKeyFrame, kFirst, kNotLast); Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast), EXPECT_THAT(Insert(0x1'0000, kKeyFrame, kNotFirst, kLast),
StartSeqNumsAre(0xFFFF)); StartSeqNumsAre(0xFFFF));
} }
TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) { TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast), EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
StartSeqNumsAre(0xFFFF)); StartSeqNumsAre(0xFFFF));
EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0)); EXPECT_THAT(Insert(0x1'0000, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
} }
TEST_F(PacketBufferTest, InsertOldPackets) { TEST_F(PacketBufferTest, InsertOldPackets) {
@ -181,7 +181,7 @@ TEST_F(PacketBufferTest, InsertOldPackets) {
} }
TEST_F(PacketBufferTest, FrameSize) { TEST_F(PacketBufferTest, FrameSize) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
uint8_t data1[5] = {}; uint8_t data1[5] = {};
uint8_t data2[5] = {}; uint8_t data2[5] = {};
uint8_t data3[5] = {}; uint8_t data3[5] = {};
@ -198,7 +198,7 @@ TEST_F(PacketBufferTest, FrameSize) {
} }
TEST_F(PacketBufferTest, ExpandBuffer) { TEST_F(PacketBufferTest, ExpandBuffer) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
Insert(seq_num, kKeyFrame, kFirst, kNotLast); Insert(seq_num, kKeyFrame, kFirst, kNotLast);
for (int i = 1; i < kStartSize; ++i) for (int i = 1; i < kStartSize; ++i)
@ -212,7 +212,7 @@ TEST_F(PacketBufferTest, ExpandBuffer) {
} }
TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) { TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
Insert(seq_num, kKeyFrame, kFirst, kNotLast); Insert(seq_num, kKeyFrame, kFirst, kNotLast);
for (int i = 1; i < kStartSize; ++i) for (int i = 1; i < kStartSize; ++i)
@ -222,7 +222,7 @@ TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
} }
TEST_F(PacketBufferTest, ExpandBufferOverflow) { TEST_F(PacketBufferTest, ExpandBufferOverflow) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared); EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
for (int i = 1; i < kMaxSize; ++i) for (int i = 1; i < kMaxSize; ++i)
@ -236,13 +236,13 @@ TEST_F(PacketBufferTest, ExpandBufferOverflow) {
} }
TEST_F(PacketBufferTest, OnePacketOneFrame) { TEST_F(PacketBufferTest, OnePacketOneFrame) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast), EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
StartSeqNumsAre(seq_num)); StartSeqNumsAre(seq_num));
} }
TEST_F(PacketBufferTest, TwoPacketsTwoFrames) { TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast), EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
StartSeqNumsAre(seq_num)); StartSeqNumsAre(seq_num));
@ -251,7 +251,7 @@ TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
} }
TEST_F(PacketBufferTest, TwoPacketsOneFrames) { TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty()); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast), EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
@ -259,7 +259,7 @@ TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
} }
TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) { TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty()); EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).packets, EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).packets,
@ -269,7 +269,7 @@ TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
} }
TEST_F(PacketBufferTest, Frames) { TEST_F(PacketBufferTest, Frames) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast), EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
StartSeqNumsAre(seq_num)); StartSeqNumsAre(seq_num));
@ -282,7 +282,7 @@ TEST_F(PacketBufferTest, Frames) {
} }
TEST_F(PacketBufferTest, ClearSinglePacket) { TEST_F(PacketBufferTest, ClearSinglePacket) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
for (int i = 0; i < kMaxSize; ++i) for (int i = 0; i < kMaxSize; ++i)
Insert(seq_num + i, kDeltaFrame, kFirst, kLast); Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
@ -322,7 +322,7 @@ TEST_F(PacketBufferTest, DontClearNewerPacket) {
} }
TEST_F(PacketBufferTest, OneIncompleteFrame) { TEST_F(PacketBufferTest, OneIncompleteFrame) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets, EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
IsEmpty()); IsEmpty());
@ -333,7 +333,7 @@ TEST_F(PacketBufferTest, OneIncompleteFrame) {
} }
TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) { TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
for (int i = 1; i < kMaxSize - 1; ++i) for (int i = 1; i < kMaxSize - 1; ++i)
Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast); Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
@ -344,7 +344,7 @@ TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
} }
TEST_F(PacketBufferTest, FramesReordered) { TEST_F(PacketBufferTest, FramesReordered) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast), EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
StartSeqNumsAre(seq_num + 1)); StartSeqNumsAre(seq_num + 1));
@ -357,14 +357,13 @@ TEST_F(PacketBufferTest, FramesReordered) {
} }
TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) { TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
uint16_t kFirstSeqNum = 0; int64_t kFirstSeqNum = 0;
uint32_t kTimestampDelta = 100; uint32_t kTimestampDelta = 100;
uint32_t timestamp = 10000; uint32_t timestamp = 10000;
uint16_t seq_num = kFirstSeqNum; int64_t seq_num = kFirstSeqNum;
// Loop until seq_num wraps around. // Loop until seq_num wraps around.
SeqNumUnwrapper<uint16_t> unwrapper; while (seq_num < std::numeric_limits<uint16_t>::max()) {
while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp); Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp); Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
@ -399,7 +398,7 @@ class PacketBufferH264Test : public PacketBufferTest {
} }
PacketBufferInsertResult InsertH264( PacketBufferInsertResult InsertH264(
uint16_t seq_num, // packet sequence number int64_t seq_num, // packet sequence number
IsKeyFrame keyframe, // is keyframe IsKeyFrame keyframe, // is keyframe
IsFirst first, // is first packet of frame IsFirst first, // is first packet of frame
IsLast last, // is last packet of frame IsLast last, // is last packet of frame
@ -412,7 +411,7 @@ class PacketBufferH264Test : public PacketBufferTest {
packet->video_header.codec = kVideoCodecH264; packet->video_header.codec = kVideoCodecH264;
auto& h264_header = auto& h264_header =
packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
packet->seq_num = seq_num; packet->sequence_number = seq_num;
packet->timestamp = timestamp; packet->timestamp = timestamp;
if (keyframe == kKeyFrame) { if (keyframe == kKeyFrame) {
if (sps_pps_idr_is_keyframe_) { if (sps_pps_idr_is_keyframe_) {
@ -437,7 +436,7 @@ class PacketBufferH264Test : public PacketBufferTest {
} }
PacketBufferInsertResult InsertH264KeyFrameWithAud( PacketBufferInsertResult InsertH264KeyFrameWithAud(
uint16_t seq_num, // packet sequence number int64_t seq_num, // packet sequence number
IsKeyFrame keyframe, // is keyframe IsKeyFrame keyframe, // is keyframe
IsFirst first, // is first packet of frame IsFirst first, // is first packet of frame
IsLast last, // is last packet of frame IsLast last, // is last packet of frame
@ -449,7 +448,7 @@ class PacketBufferH264Test : public PacketBufferTest {
packet->video_header.codec = kVideoCodecH264; packet->video_header.codec = kVideoCodecH264;
auto& h264_header = auto& h264_header =
packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
packet->seq_num = seq_num; packet->sequence_number = seq_num;
packet->timestamp = timestamp; packet->timestamp = timestamp;
// this should be the start of frame. // this should be the start of frame.
@ -515,7 +514,7 @@ TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
} }
TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) { TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
uint16_t seq_num = Rand(); int64_t seq_num = Rand();
rtc::CopyOnWriteBuffer data = "some plain old data"; rtc::CopyOnWriteBuffer data = "some plain old data";
auto packet = std::make_unique<PacketBuffer::Packet>(); auto packet = std::make_unique<PacketBuffer::Packet>();
@ -523,7 +522,7 @@ TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
h264_header.nalus = {{H264::NaluType::kIdr}}; h264_header.nalus = {{H264::NaluType::kIdr}};
h264_header.packetization_type = kH264SingleNalu; h264_header.packetization_type = kH264SingleNalu;
packet->seq_num = seq_num; packet->sequence_number = seq_num;
packet->video_header.codec = kVideoCodecH264; packet->video_header.codec = kVideoCodecH264;
packet->video_payload = data; packet->video_payload = data;
packet->video_header.is_first_packet_in_frame = true; packet->video_header.is_first_packet_in_frame = true;
@ -531,12 +530,12 @@ TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
auto frames = packet_buffer_.InsertPacket(std::move(packet)).packets; auto frames = packet_buffer_.InsertPacket(std::move(packet)).packets;
ASSERT_THAT(frames, SizeIs(1)); ASSERT_THAT(frames, SizeIs(1));
EXPECT_EQ(frames[0]->seq_num, seq_num); EXPECT_EQ(frames[0]->sequence_number, seq_num);
EXPECT_EQ(frames[0]->video_payload, data); EXPECT_EQ(frames[0]->video_payload, data);
} }
TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) { TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
uint16_t seq_num = 100; int64_t seq_num = 100;
uint8_t data[] = "some plain old data"; uint8_t data[] = "some plain old data";
uint32_t width = 640; uint32_t width = 640;
uint32_t height = 360; uint32_t height = 360;
@ -552,7 +551,7 @@ TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
} }
TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) { TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
uint16_t seq_num = 100; int64_t seq_num = 100;
uint8_t data[] = "some plain old data"; uint8_t data[] = "some plain old data";
uint32_t width = 640; uint32_t width = 640;
uint32_t height = 360; uint32_t height = 360;
@ -568,7 +567,7 @@ TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
} }
TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) { TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
Insert(seq_num, kKeyFrame, kFirst, kNotLast); Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast); Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
@ -584,7 +583,7 @@ TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
} }
TEST_F(PacketBufferTest, Clear) { TEST_F(PacketBufferTest, Clear) {
const uint16_t seq_num = Rand(); const int64_t seq_num = Rand();
Insert(seq_num, kKeyFrame, kFirst, kNotLast); Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast); Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
@ -626,7 +625,7 @@ TEST_F(PacketBufferTest, IncomingCodecChange) {
packet->video_header.codec = kVideoCodecVP8; packet->video_header.codec = kVideoCodecVP8;
packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
packet->timestamp = 1; packet->timestamp = 1;
packet->seq_num = 1; packet->sequence_number = 1;
packet->video_header.frame_type = VideoFrameType::kVideoFrameKey; packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets, EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
SizeIs(1)); SizeIs(1));
@ -639,7 +638,7 @@ TEST_F(PacketBufferTest, IncomingCodecChange) {
packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
h264_header.nalus.resize(1); h264_header.nalus.resize(1);
packet->timestamp = 3; packet->timestamp = 3;
packet->seq_num = 3; packet->sequence_number = 3;
packet->video_header.frame_type = VideoFrameType::kVideoFrameKey; packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets, EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
IsEmpty()); IsEmpty());
@ -650,7 +649,7 @@ TEST_F(PacketBufferTest, IncomingCodecChange) {
packet->video_header.codec = kVideoCodecVP8; packet->video_header.codec = kVideoCodecVP8;
packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>(); packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
packet->timestamp = 2; packet->timestamp = 2;
packet->seq_num = 2; packet->sequence_number = 2;
packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta; packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets, EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
SizeIs(2)); SizeIs(2));
@ -725,7 +724,7 @@ TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnReorderedPadding) {
class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test { class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
protected: protected:
const uint16_t kSeqNum = 5; const int64_t kSeqNum = 5;
explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe) explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
: PacketBufferH264Test(sps_pps_idr_is_keyframe) {} : PacketBufferH264Test(sps_pps_idr_is_keyframe) {}
@ -733,7 +732,7 @@ class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
std::unique_ptr<PacketBuffer::Packet> CreatePacket() { std::unique_ptr<PacketBuffer::Packet> CreatePacket() {
auto packet = std::make_unique<PacketBuffer::Packet>(); auto packet = std::make_unique<PacketBuffer::Packet>();
packet->video_header.codec = kVideoCodecH264; packet->video_header.codec = kVideoCodecH264;
packet->seq_num = kSeqNum; packet->sequence_number = kSeqNum;
packet->video_header.is_first_packet_in_frame = true; packet->video_header.is_first_packet_in_frame = true;
packet->video_header.is_last_packet_in_frame = true; packet->video_header.is_last_packet_in_frame = true;

View File

@ -514,12 +514,12 @@ bool RtpVideoStreamReceiver2::OnReceivedPayloadData(
int times_nacked) { int times_nacked) {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_); RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
auto packet =
std::make_unique<video_coding::PacketBuffer::Packet>(rtp_packet, video);
int64_t unwrapped_rtp_seq_num = int64_t unwrapped_rtp_seq_num =
rtp_seq_num_unwrapper_.Unwrap(rtp_packet.SequenceNumber()); rtp_seq_num_unwrapper_.Unwrap(rtp_packet.SequenceNumber());
auto packet = std::make_unique<video_coding::PacketBuffer::Packet>(
rtp_packet, unwrapped_rtp_seq_num, video);
RtpPacketInfo& packet_info = RtpPacketInfo& packet_info =
packet_infos_ packet_infos_
.emplace(unwrapped_rtp_seq_num, .emplace(unwrapped_rtp_seq_num,
@ -638,7 +638,7 @@ bool RtpVideoStreamReceiver2::OnReceivedPayloadData(
packet->times_nacked = times_nacked; packet->times_nacked = times_nacked;
if (codec_payload.size() == 0) { if (codec_payload.size() == 0) {
NotifyReceiverOfEmptyPacket(packet->seq_num); NotifyReceiverOfEmptyPacket(packet->seq_num());
rtcp_feedback_buffer_.SendBufferedRtcpFeedback(); rtcp_feedback_buffer_.SendBufferedRtcpFeedback();
return false; return false;
} }
@ -769,8 +769,7 @@ void RtpVideoStreamReceiver2::OnInsertedPacket(
// PacketBuffer promisses frame boundaries are correctly set on each // PacketBuffer promisses frame boundaries are correctly set on each
// packet. Document that assumption with the DCHECKs. // packet. Document that assumption with the DCHECKs.
RTC_DCHECK_EQ(frame_boundary, packet->is_first_packet_in_frame()); RTC_DCHECK_EQ(frame_boundary, packet->is_first_packet_in_frame());
int64_t unwrapped_rtp_seq_num = int64_t unwrapped_rtp_seq_num = packet->sequence_number;
rtp_seq_num_unwrapper_.Unwrap(packet->seq_num);
RTC_DCHECK_GT(packet_infos_.count(unwrapped_rtp_seq_num), 0); RTC_DCHECK_GT(packet_infos_.count(unwrapped_rtp_seq_num), 0);
RtpPacketInfo& packet_info = packet_infos_[unwrapped_rtp_seq_num]; RtpPacketInfo& packet_info = packet_infos_[unwrapped_rtp_seq_num];
if (packet->is_first_packet_in_frame()) { if (packet->is_first_packet_in_frame()) {
@ -801,8 +800,8 @@ void RtpVideoStreamReceiver2::OnInsertedPacket(
const video_coding::PacketBuffer::Packet& last_packet = *packet; const video_coding::PacketBuffer::Packet& last_packet = *packet;
OnAssembledFrame(std::make_unique<RtpFrameObject>( OnAssembledFrame(std::make_unique<RtpFrameObject>(
first_packet->seq_num, // first_packet->seq_num(), //
last_packet.seq_num, // last_packet.seq_num(), //
last_packet.marker_bit, // last_packet.marker_bit, //
max_nack_count, // max_nack_count, //
min_recv_time, // min_recv_time, //

View File

@ -280,8 +280,7 @@ void VideoReceiveStream2::RegisterWithTransport(
// Register with RtpStreamReceiverController. // Register with RtpStreamReceiverController.
media_receiver_ = receiver_controller->CreateReceiver( media_receiver_ = receiver_controller->CreateReceiver(
remote_ssrc(), &rtp_video_stream_receiver_); remote_ssrc(), &rtp_video_stream_receiver_);
if (rtx_ssrc()) { if (rtx_ssrc() && rtx_receive_stream_ != nullptr) {
RTC_DCHECK(rtx_receive_stream_);
rtx_receiver_ = receiver_controller->CreateReceiver( rtx_receiver_ = receiver_controller->CreateReceiver(
rtx_ssrc(), rtx_receive_stream_.get()); rtx_ssrc(), rtx_receive_stream_.get());
} }