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);
std::unique_ptr<FrameDependencyStructure> video_structure_;
SeqNumUnwrapper<uint16_t> rtp_sequence_number_unwrapper_;
SeqNumUnwrapper<uint16_t> frame_id_unwrapper_;
absl::optional<int64_t> video_structure_frame_id_;
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();
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);
ClearOldData(rtp_packet.SequenceNumber());
@ -163,8 +166,8 @@ RtpVideoFrameAssembler::Impl::AssembleFrames(
const video_coding::PacketBuffer::Packet& last_packet = *packet;
result.push_back(std::make_unique<RtpFrameObject>(
first_packet->seq_num, //
last_packet.seq_num, //
first_packet->seq_num(), //
last_packet.seq_num(), //
last_packet.marker_bit, //
/*times_nacked=*/0, //
/*first_packet_received_time=*/0, //

View File

@ -110,7 +110,7 @@ H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket(
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);
if (packet_slot != nullptr &&
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
// the 'buffer_'. Check that the `packet` sequence number match the expected
// unwrapped sequence number.
if (static_cast<uint16_t>(seq_num) != packet->seq_num) {
if (seq_num != packet->sequence_number) {
return result;
}

View File

@ -94,7 +94,6 @@ class H26xPacketBuffer {
std::array<std::unique_ptr<Packet>, kBufferSize> buffer_;
std::array<int64_t, kNumTrackedSequences> last_continuous_in_sequence_;
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
// ID.

View File

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

View File

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

View File

@ -34,6 +34,7 @@ class PacketBuffer {
struct Packet {
Packet() = default;
Packet(const RtpPacketReceived& rtp_packet,
int64_t sequence_number,
const RTPVideoHeader& video_header);
Packet(const Packet&) = delete;
Packet(Packet&&) = delete;
@ -51,13 +52,14 @@ class PacketBuffer {
bool is_last_packet_in_frame() const {
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.
// Set and used internally by the PacketBuffer.
bool continuous = false;
bool marker_bit = false;
uint8_t payload_type = 0;
uint16_t seq_num = 0;
int64_t sequence_number = 0;
uint32_t timestamp = 0;
int times_nacked = -1;

View File

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

View File

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

View File

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