Fork VCMPacket for PacketBuffer into own struct

it is easier to reduce and eliminate it when it is not bound to legacy video code

Bug: webrtc:10979
Change-Id: I517e298501b3358a914a23ddce40fcb3075d672d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/159707
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29821}
This commit is contained in:
Danil Chapovalov
2019-11-14 14:57:33 +01:00
committed by Commit Bot
parent acdc22d784
commit aa3f5da8dc
8 changed files with 167 additions and 122 deletions

View File

@ -44,7 +44,6 @@ rtc_library("nack_module") {
]
deps = [
":packet",
"..:module_api",
"../../api/units:time_delta",
"../../api/units:timestamp",
@ -58,24 +57,6 @@ rtc_library("nack_module") {
]
}
rtc_library("packet") {
visibility = [ "*" ]
sources = [
"packet.cc",
"packet.h",
]
deps = [
"..:module_api",
"../../:webrtc_common",
"../../api:rtp_headers",
"../../api:rtp_packet_info",
"../../api/video:video_frame_type",
"../rtp_rtcp:rtp_rtcp_format",
"../rtp_rtcp:rtp_video_header",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("video_coding") {
visibility = [ "*" ]
deps = [
@ -140,7 +121,6 @@ rtc_library("video_coding") {
deps += [
":codec_globals_headers",
":encoded_frame",
":packet",
":video_codec_interface",
":video_coding_utility",
":webrtc_vp9_helpers",
@ -148,6 +128,7 @@ rtc_library("video_coding") {
"..:module_api_public",
"../../api:fec_controller_api",
"../../api:rtp_headers",
"../../api:rtp_packet_info",
"../../api/units:data_rate",
"../../api/units:time_delta",
"../../api/video:builtin_video_bitrate_allocator_factory",
@ -215,6 +196,8 @@ rtc_library("video_coding_legacy") {
"jitter_buffer.cc",
"jitter_buffer.h",
"jitter_buffer_common.h",
"packet.cc",
"packet.h",
"receiver.cc",
"receiver.h",
"session_info.cc",
@ -226,14 +209,16 @@ rtc_library("video_coding_legacy") {
deps = [
":codec_globals_headers",
":encoded_frame",
":packet",
":video_codec_interface",
":video_coding",
"..:module_api",
"..:module_api_public",
"../../:webrtc_common",
"../../api:rtp_headers",
"../../api:rtp_packet_info",
"../../api/video:encoded_image",
"../../api/video:video_frame",
"../../api/video:video_frame_type",
"../../api/video:video_rtp_headers",
"../../api/video_codecs:video_codecs_api",
"../../common_video",
@ -244,6 +229,8 @@ rtc_library("video_coding_legacy") {
"../../rtc_base/synchronization:sequence_checker",
"../../system_wrappers",
"../../system_wrappers:event_wrapper",
"../rtp_rtcp:rtp_rtcp_format",
"../rtp_rtcp:rtp_video_header",
"../utility",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
@ -874,7 +861,6 @@ if (rtc_include_tests) {
":codec_globals_headers",
":encoded_frame",
":nack_module",
":packet",
":simulcast_test_fixture_impl",
":video_codec_interface",
":video_codecs_test_framework",

View File

@ -20,8 +20,11 @@
#include "absl/types/variant.h"
#include "api/array_view.h"
#include "api/rtp_packet_info.h"
#include "api/video/encoded_frame.h"
#include "common_video/h264/h264_common.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/frame_object.h"
@ -34,6 +37,24 @@
namespace webrtc {
namespace video_coding {
PacketBuffer::Packet::Packet(const RtpPacketReceived& rtp_packet,
const RTPVideoHeader& video_header,
int64_t ntp_time_ms,
int64_t receive_time_ms)
: marker_bit(rtp_packet.Marker()),
payload_type(rtp_packet.PayloadType()),
seq_num(rtp_packet.SequenceNumber()),
timestamp(rtp_packet.Timestamp()),
ntp_time_ms(ntp_time_ms),
times_nacked(-1),
video_header(video_header),
packet_info(rtp_packet.Ssrc(),
rtp_packet.Csrcs(),
rtp_packet.Timestamp(),
/*audio_level=*/absl::nullopt,
rtp_packet.GetExtension<AbsoluteCaptureTimeExtension>(),
receive_time_ms) {}
PacketBuffer::PacketBuffer(Clock* clock,
size_t start_buffer_size,
size_t max_buffer_size)
@ -55,11 +76,12 @@ PacketBuffer::~PacketBuffer() {
Clear();
}
PacketBuffer::InsertResult PacketBuffer::InsertPacket(VCMPacket* packet) {
PacketBuffer::InsertResult PacketBuffer::InsertPacket(
PacketBuffer::Packet* packet) {
PacketBuffer::InsertResult result;
rtc::CritScope lock(&crit_);
uint16_t seq_num = packet->seqNum;
uint16_t seq_num = packet->seq_num;
size_t index = seq_num % buffer_.size();
if (!first_packet_received_) {
@ -69,8 +91,8 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(VCMPacket* packet) {
// If we have explicitly cleared past this packet then it's old,
// don't insert it, just silently ignore it.
if (is_cleared_to_first_seq_num_) {
delete[] packet->dataPtr;
packet->dataPtr = nullptr;
delete[] packet->data;
packet->data = nullptr;
return result;
}
@ -79,9 +101,9 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(VCMPacket* packet) {
if (buffer_[index].used) {
// Duplicate packet, just delete the payload.
if (buffer_[index].seq_num() == packet->seqNum) {
delete[] packet->dataPtr;
packet->dataPtr = nullptr;
if (buffer_[index].seq_num() == packet->seq_num) {
delete[] packet->data;
packet->data = nullptr;
return result;
}
@ -96,26 +118,26 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(VCMPacket* packet) {
// new keyframe is needed.
RTC_LOG(LS_WARNING) << "Clear PacketBuffer and request key frame.";
Clear();
delete[] packet->dataPtr;
packet->dataPtr = nullptr;
delete[] packet->data;
packet->data = nullptr;
result.buffer_cleared = true;
return result;
}
}
StoredPacket& new_entry = buffer_[index];
new_entry.continuous = false;
new_entry.used = true;
new_entry.data = *packet;
packet->dataPtr = nullptr;
UpdateMissingPackets(packet->seqNum);
int64_t now_ms = clock_->TimeInMilliseconds();
last_received_packet_ms_ = now_ms;
if (packet->video_header.frame_type == VideoFrameType::kVideoFrameKey)
last_received_keyframe_packet_ms_ = now_ms;
StoredPacket& new_entry = buffer_[index];
new_entry.continuous = false;
new_entry.used = true;
new_entry.data = std::move(*packet);
packet->data = nullptr;
UpdateMissingPackets(seq_num);
result.frames = FindFrames(seq_num);
return result;
}
@ -140,8 +162,8 @@ void PacketBuffer::ClearTo(uint16_t seq_num) {
for (size_t i = 0; i < iterations; ++i) {
size_t index = first_seq_num_ % buffer_.size();
if (AheadOf<uint16_t>(seq_num, buffer_[index].seq_num())) {
delete[] buffer_[index].data.dataPtr;
buffer_[index].data.dataPtr = nullptr;
delete[] buffer_[index].data.data;
buffer_[index].data.data = nullptr;
buffer_[index].used = false;
}
++first_seq_num_;
@ -167,8 +189,8 @@ void PacketBuffer::ClearInterval(uint16_t start_seq_num,
for (size_t i = 0; i < iterations; ++i) {
size_t index = seq_num % buffer_.size();
RTC_DCHECK_EQ(buffer_[index].seq_num(), seq_num);
delete[] buffer_[index].data.dataPtr;
buffer_[index].data.dataPtr = nullptr;
delete[] buffer_[index].data.data;
buffer_[index].data.data = nullptr;
buffer_[index].used = false;
++seq_num;
@ -178,8 +200,8 @@ void PacketBuffer::ClearInterval(uint16_t start_seq_num,
void PacketBuffer::Clear() {
rtc::CritScope lock(&crit_);
for (StoredPacket& entry : buffer_) {
delete[] entry.data.dataPtr;
entry.data.dataPtr = nullptr;
delete[] entry.data.data;
entry.data.data = nullptr;
entry.used = false;
}
@ -220,7 +242,7 @@ bool PacketBuffer::ExpandBufferSize() {
std::vector<StoredPacket> new_buffer(new_size);
for (StoredPacket& entry : buffer_) {
if (entry.used) {
new_buffer[entry.seq_num() % new_size] = entry;
new_buffer[entry.seq_num() % new_size] = std::move(entry);
}
}
buffer_ = std::move(new_buffer);
@ -403,15 +425,15 @@ std::unique_ptr<RtpFrameObject> PacketBuffer::AssembleFrame(
packet_infos.reserve(num_packets);
for (uint16_t seq_num = first_seq_num; seq_num != end_seq_num; ++seq_num) {
const VCMPacket& packet = GetPacket(seq_num);
const Packet& packet = GetPacket(seq_num);
max_nack_count = std::max(max_nack_count, packet.timesNacked);
max_nack_count = std::max(max_nack_count, packet.times_nacked);
min_recv_time =
std::min(min_recv_time, packet.packet_info.receive_time_ms());
max_recv_time =
std::max(max_recv_time, packet.packet_info.receive_time_ms());
frame_size += packet.sizeBytes;
payloads.emplace_back(packet.dataPtr, packet.sizeBytes);
frame_size += packet.size_bytes;
payloads.emplace_back(packet.data, packet.size_bytes);
packet_infos.push_back(packet.packet_info);
}
@ -424,19 +446,19 @@ std::unique_ptr<RtpFrameObject> PacketBuffer::AssembleFrame(
}
RTC_DCHECK_EQ(write_at - bitstream->data(), bitstream->size());
const VCMPacket& first_packet = GetPacket(first_seq_num);
const VCMPacket& last_packet = GetPacket(last_seq_num);
const Packet& first_packet = GetPacket(first_seq_num);
const Packet& last_packet = GetPacket(last_seq_num);
return std::make_unique<RtpFrameObject>(
first_seq_num, //
last_seq_num, //
last_packet.markerBit, //
last_packet.marker_bit, //
max_nack_count, //
min_recv_time, //
max_recv_time, //
first_packet.timestamp, //
first_packet.ntp_time_ms_, //
first_packet.ntp_time_ms, //
last_packet.video_header.video_timing, //
first_packet.payloadType, //
first_packet.payload_type, //
first_packet.codec(), //
last_packet.video_header.rotation, //
last_packet.video_header.content_type, //
@ -447,7 +469,7 @@ std::unique_ptr<RtpFrameObject> PacketBuffer::AssembleFrame(
std::move(bitstream));
}
const VCMPacket& PacketBuffer::GetPacket(uint16_t seq_num) const {
const PacketBuffer::Packet& PacketBuffer::GetPacket(uint16_t seq_num) const {
const StoredPacket& entry = buffer_[seq_num % buffer_.size()];
RTC_DCHECK(entry.used);
RTC_DCHECK_EQ(seq_num, entry.seq_num());

View File

@ -17,9 +17,12 @@
#include <vector>
#include "absl/base/attributes.h"
#include "api/rtp_packet_info.h"
#include "api/video/encoded_image.h"
#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "modules/video_coding/frame_object.h"
#include "modules/video_coding/packet.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/numerics/sequence_number_util.h"
#include "rtc_base/thread_annotations.h"
@ -30,6 +33,45 @@ namespace video_coding {
class PacketBuffer {
public:
struct Packet {
Packet() = default;
Packet(const RtpPacketReceived& rtp_packet,
const RTPVideoHeader& video_header,
int64_t ntp_time_ms,
int64_t receive_time_ms);
Packet(const Packet&) = delete;
Packet(Packet&&) = default;
Packet& operator=(const Packet&) = delete;
Packet& operator=(Packet&&) = default;
~Packet() = default;
VideoCodecType codec() const { return video_header.codec; }
int width() const { return video_header.width; }
int height() const { return video_header.height; }
bool is_first_packet_in_frame() const {
return video_header.is_first_packet_in_frame;
}
bool is_last_packet_in_frame() const {
return video_header.is_last_packet_in_frame;
}
bool marker_bit = false;
uint8_t payload_type = 0;
uint16_t seq_num = 0;
uint32_t timestamp = 0;
// NTP time of the capture time in local timebase in milliseconds.
int64_t ntp_time_ms = -1;
int times_nacked = -1;
const uint8_t* data = nullptr;
size_t size_bytes = 0;
RTPVideoHeader video_header;
absl::optional<RtpGenericFrameDescriptor> generic_descriptor;
RtpPacketInfo packet_info;
};
struct InsertResult {
std::vector<std::unique_ptr<RtpFrameObject>> frames;
// Indicates if the packet buffer was cleared, which means that a key
@ -43,7 +85,7 @@ class PacketBuffer {
// The PacketBuffer will always take ownership of the |packet.dataPtr| when
// this function is called.
InsertResult InsertPacket(VCMPacket* packet) ABSL_MUST_USE_RESULT;
InsertResult InsertPacket(Packet* packet) ABSL_MUST_USE_RESULT;
InsertResult InsertPadding(uint16_t seq_num) ABSL_MUST_USE_RESULT;
void ClearTo(uint16_t seq_num);
void Clear();
@ -54,7 +96,7 @@ class PacketBuffer {
private:
struct StoredPacket {
uint16_t seq_num() const { return data.seqNum; }
uint16_t seq_num() const { return data.seq_num; }
// If this is the first packet of the frame.
bool frame_begin() const { return data.is_first_packet_in_frame(); }
@ -68,7 +110,7 @@ class PacketBuffer {
// If all its previous packets have been inserted into the packet buffer.
bool continuous = false;
VCMPacket data;
Packet data;
};
Clock* const clock_;
@ -90,7 +132,7 @@ class PacketBuffer {
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
// Get the packet with sequence number |seq_num|.
const VCMPacket& GetPacket(uint16_t seq_num) const
const Packet& GetPacket(uint16_t seq_num) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
// Clears the packet buffer from |start_seq_num| to |stop_seq_num| where the

View File

@ -112,17 +112,17 @@ class PacketBufferTest : public ::testing::Test {
int data_size = 0, // size of data
uint8_t* data = nullptr, // data pointer
uint32_t timestamp = 123u) { // rtp timestamp
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.codec = kVideoCodecGeneric;
packet.timestamp = timestamp;
packet.seqNum = seq_num;
packet.seq_num = seq_num;
packet.video_header.frame_type = keyframe == kKeyFrame
? VideoFrameType::kVideoFrameKey
: VideoFrameType::kVideoFrameDelta;
packet.video_header.is_first_packet_in_frame = first == kFirst;
packet.video_header.is_last_packet_in_frame = last == kLast;
packet.sizeBytes = data_size;
packet.dataPtr = data;
packet.size_bytes = data_size;
packet.data = data;
return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
}
@ -183,28 +183,28 @@ TEST_F(PacketBufferTest, InsertOldPackets) {
TEST_F(PacketBufferTest, NackCount) {
const uint16_t seq_num = Rand();
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.codec = kVideoCodecGeneric;
packet.seqNum = seq_num;
packet.seq_num = seq_num;
packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
packet.video_header.is_first_packet_in_frame = true;
packet.video_header.is_last_packet_in_frame = false;
packet.timesNacked = 0;
packet.times_nacked = 0;
IgnoreResult(packet_buffer_.InsertPacket(&packet));
packet.seqNum++;
packet.seq_num++;
packet.video_header.is_first_packet_in_frame = false;
packet.timesNacked = 1;
packet.times_nacked = 1;
IgnoreResult(packet_buffer_.InsertPacket(&packet));
packet.seqNum++;
packet.timesNacked = 3;
packet.seq_num++;
packet.times_nacked = 3;
IgnoreResult(packet_buffer_.InsertPacket(&packet));
packet.seqNum++;
packet.seq_num++;
packet.video_header.is_last_packet_in_frame = true;
packet.timesNacked = 1;
packet.times_nacked = 1;
auto frames = packet_buffer_.InsertPacket(&packet).frames;
ASSERT_THAT(frames, SizeIs(1));
@ -494,11 +494,11 @@ class PacketBufferH264Test : public PacketBufferTest {
uint8_t* data = nullptr, // data pointer
uint32_t width = 0, // width of frame (SPS/IDR)
uint32_t height = 0) { // height of frame (SPS/IDR)
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.codec = kVideoCodecH264;
auto& h264_header =
packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
packet.seqNum = seq_num;
packet.seq_num = seq_num;
packet.timestamp = timestamp;
if (keyframe == kKeyFrame) {
if (sps_pps_idr_is_keyframe_) {
@ -515,8 +515,8 @@ class PacketBufferH264Test : public PacketBufferTest {
packet.video_header.height = height;
packet.video_header.is_first_packet_in_frame = first == kFirst;
packet.video_header.is_last_packet_in_frame = last == kLast;
packet.sizeBytes = data_size;
packet.dataPtr = data;
packet.size_bytes = data_size;
packet.data = data;
return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
}
@ -531,11 +531,11 @@ class PacketBufferH264Test : public PacketBufferTest {
uint8_t* data = nullptr, // data pointer
uint32_t width = 0, // width of frame (SPS/IDR)
uint32_t height = 0) { // height of frame (SPS/IDR)
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.codec = kVideoCodecH264;
auto& h264_header =
packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
packet.seqNum = seq_num;
packet.seq_num = seq_num;
packet.timestamp = timestamp;
// this should be the start of frame.
@ -546,8 +546,8 @@ class PacketBufferH264Test : public PacketBufferTest {
h264_header.nalus_length = 1;
packet.video_header.is_first_packet_in_frame = true;
packet.video_header.is_last_packet_in_frame = false;
packet.sizeBytes = 0;
packet.dataPtr = nullptr;
packet.size_bytes = 0;
packet.data = nullptr;
IgnoreResult(packet_buffer_.InsertPacket(&packet));
// insert IDR
return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp,
@ -608,17 +608,16 @@ TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
uint8_t* data = new uint8_t[sizeof(data_data)];
memcpy(data, data_data, sizeof(data_data));
VCMPacket packet;
PacketBuffer::Packet packet;
auto& h264_header =
packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
h264_header.nalus_length = 1;
h264_header.nalus[0].type = H264::NaluType::kIdr;
h264_header.packetization_type = kH264SingleNalu;
packet.seqNum = seq_num;
packet.seq_num = seq_num;
packet.video_header.codec = kVideoCodecH264;
packet.insertStartCode = true;
packet.dataPtr = data;
packet.sizeBytes = sizeof(data_data);
packet.data = data;
packet.size_bytes = sizeof(data_data);
packet.video_header.is_first_packet_in_frame = true;
packet.video_header.is_last_packet_in_frame = true;
auto frames = packet_buffer_.InsertPacket(&packet).frames;
@ -785,16 +784,16 @@ TEST_F(PacketBufferTest, PacketTimestamps) {
}
TEST_F(PacketBufferTest, IncomingCodecChange) {
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.is_first_packet_in_frame = true;
packet.video_header.is_last_packet_in_frame = true;
packet.sizeBytes = 0;
packet.dataPtr = nullptr;
packet.size_bytes = 0;
packet.data = nullptr;
packet.video_header.codec = kVideoCodecVP8;
packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
packet.timestamp = 1;
packet.seqNum = 1;
packet.seq_num = 1;
packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(1));
@ -803,30 +802,30 @@ TEST_F(PacketBufferTest, IncomingCodecChange) {
packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
h264_header.nalus_length = 1;
packet.timestamp = 3;
packet.seqNum = 3;
packet.seq_num = 3;
EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
packet.video_header.codec = kVideoCodecVP8;
packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
packet.timestamp = 2;
packet.seqNum = 2;
packet.seq_num = 2;
packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(2));
}
TEST_F(PacketBufferTest, TooManyNalusInPacket) {
VCMPacket packet;
PacketBuffer::Packet packet;
packet.video_header.codec = kVideoCodecH264;
packet.timestamp = 1;
packet.seqNum = 1;
packet.seq_num = 1;
packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
packet.video_header.is_first_packet_in_frame = true;
packet.video_header.is_last_packet_in_frame = true;
auto& h264_header =
packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
h264_header.nalus_length = kMaxNalusPerPacket;
packet.sizeBytes = 0;
packet.dataPtr = nullptr;
packet.size_bytes = 0;
packet.data = nullptr;
EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
}
@ -886,13 +885,13 @@ class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
: PacketBufferH264Test(sps_pps_idr_is_keyframe) {
packet_.video_header.codec = kVideoCodecH264;
packet_.seqNum = kSeqNum;
packet_.seq_num = kSeqNum;
packet_.video_header.is_first_packet_in_frame = true;
packet_.video_header.is_last_packet_in_frame = true;
}
VCMPacket packet_;
PacketBuffer::Packet packet_;
};
class PacketBufferH264IdrIsKeyframeTest