Cleanup RtpPacketizer interface

merge construction and call to SetPayloadData
Add NumPackets instead of SetPayloadData
Remove virtual ToString() as unused
move CHECK(rtp_video_header) from RtpPacketizer::Create to RtpSenderVideo::SendVideo

Bug: webrtc:9680
Change-Id: I074644e048c797eb836f79979df363fe1ea0075e
Reviewed-on: https://webrtc-review.googlesource.com/96543
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24474}
This commit is contained in:
Danil Chapovalov
2018-08-28 19:45:31 +02:00
committed by Commit Bot
parent 2a4906532f
commit f7f8a1f176
12 changed files with 127 additions and 110 deletions

View File

@ -12,40 +12,56 @@
#include <utility>
#include "absl/memory/memory.h"
#include "modules/rtp_rtcp/source/rtp_format_h264.h"
#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
namespace webrtc {
RtpPacketizer* RtpPacketizer::Create(VideoCodecType type,
size_t max_payload_len,
size_t last_packet_reduction_len,
const RTPVideoHeader* rtp_video_header,
FrameType frame_type) {
RTC_CHECK(rtp_video_header);
std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
VideoCodecType type,
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
const RTPVideoHeader& rtp_video_header,
FrameType frame_type,
const RTPFragmentationHeader* fragmentation) {
switch (type) {
case kVideoCodecH264: {
const auto& h264 =
absl::get<RTPVideoHeaderH264>(rtp_video_header->video_type_header);
return new RtpPacketizerH264(max_payload_len, last_packet_reduction_len,
h264.packetization_mode);
absl::get<RTPVideoHeaderH264>(rtp_video_header.video_type_header);
auto packetizer = absl::make_unique<RtpPacketizerH264>(
limits.max_payload_len, limits.last_packet_reduction_len,
h264.packetization_mode);
packetizer->SetPayloadData(payload.data(), payload.size(), fragmentation);
return std::move(packetizer);
}
case kVideoCodecVP8: {
const auto& vp8 =
absl::get<RTPVideoHeaderVP8>(rtp_video_header.video_type_header);
auto packetizer = absl::make_unique<RtpPacketizerVp8>(
vp8, limits.max_payload_len, limits.last_packet_reduction_len);
packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
return std::move(packetizer);
}
case kVideoCodecVP8:
return new RtpPacketizerVp8(rtp_video_header->vp8(), max_payload_len,
last_packet_reduction_len);
case kVideoCodecVP9: {
const auto& vp9 =
absl::get<RTPVideoHeaderVP9>(rtp_video_header->video_type_header);
return new RtpPacketizerVp9(vp9, max_payload_len,
last_packet_reduction_len);
absl::get<RTPVideoHeaderVP9>(rtp_video_header.video_type_header);
auto packetizer = absl::make_unique<RtpPacketizerVp9>(
vp9, limits.max_payload_len, limits.last_packet_reduction_len);
packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
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);
}
default:
return new RtpPacketizerGeneric(*rtp_video_header, frame_type,
max_payload_len,
last_packet_reduction_len);
}
return nullptr;
}
RtpDepacketizer* RtpDepacketizer::Create(VideoCodecType type) {

View File

@ -11,8 +11,10 @@
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
#include <memory>
#include <string>
#include "api/array_view.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -23,26 +25,28 @@ class RtpPacketToSend;
class RtpPacketizer {
public:
static RtpPacketizer* Create(VideoCodecType type,
size_t max_payload_len,
size_t last_packet_reduction_len,
const RTPVideoHeader* rtp_video_header,
FrameType frame_type);
struct PayloadSizeLimits {
size_t max_payload_len = 1200;
size_t last_packet_reduction_len = 0;
};
static std::unique_ptr<RtpPacketizer> Create(
VideoCodecType type,
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
const RTPVideoHeader& rtp_video_header,
FrameType frame_type,
const RTPFragmentationHeader* fragmentation);
virtual ~RtpPacketizer() {}
virtual ~RtpPacketizer() = default;
// Returns total number of packets which would be produced by the packetizer.
virtual size_t SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) = 0;
// Returns number of remaining packets to produce by the packetizer.
virtual size_t NumPackets() const = 0;
// Get the next payload with payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
virtual bool NextPacket(RtpPacketToSend* packet) = 0;
virtual std::string ToString() = 0;
};
// TODO(sprang): Update the depacketizer to return a std::unqie_ptr with a copy

View File

@ -182,6 +182,10 @@ size_t RtpPacketizerH264::SetPayloadData(
return num_packets_left_;
}
size_t RtpPacketizerH264::NumPackets() const {
return num_packets_left_;
}
bool RtpPacketizerH264::GeneratePackets() {
for (size_t i = 0; i < input_fragments_.size();) {
switch (packetization_mode_) {
@ -408,10 +412,6 @@ void RtpPacketizerH264::NextFragmentPacket(RtpPacketToSend* rtp_packet) {
packets_.pop();
}
std::string RtpPacketizerH264::ToString() {
return "RtpPacketizerH264";
}
RtpDepacketizerH264::RtpDepacketizerH264() : offset_(0), length_(0) {}
RtpDepacketizerH264::~RtpDepacketizerH264() {}

View File

@ -34,15 +34,15 @@ class RtpPacketizerH264 : public RtpPacketizer {
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation);
size_t NumPackets() const override;
// Get the next payload with H264 payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* rtp_packet) override;
std::string ToString() override;
private:
// Input fragments (NAL units), with an optionally owned temporary buffer,
// used in case the fragment gets modified.

View File

@ -16,7 +16,7 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "modules/rtp_rtcp/source/rtp_format_h264.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -68,14 +68,12 @@ void CreateThreeFragments(RTPFragmentationHeader* fragmentation,
kNalHeaderSize + frameSize - payloadOffset;
}
RtpPacketizer* CreateH264Packetizer(H264PacketizationMode mode,
size_t max_payload_size,
size_t last_packet_reduction) {
RTPVideoHeader header;
header.video_type_header.emplace<RTPVideoHeaderH264>().packetization_mode =
mode;
return RtpPacketizer::Create(kVideoCodecH264, max_payload_size,
last_packet_reduction, &header, kEmptyFrame);
std::unique_ptr<RtpPacketizerH264> CreateH264Packetizer(
H264PacketizationMode mode,
size_t max_payload_size,
size_t last_packet_reduction) {
return absl::make_unique<RtpPacketizerH264>(max_payload_size,
last_packet_reduction, mode);
}
void VerifyFua(size_t fua_index,
@ -118,7 +116,7 @@ void TestFua(size_t frame_size,
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = frame_size;
std::unique_ptr<RtpPacketizer> packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
max_payload_size, last_packet_reduction));
EXPECT_EQ(
@ -191,7 +189,7 @@ TEST_P(RtpPacketizerH264ModeTest, TestSingleNalu) {
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = sizeof(frame);
std::unique_ptr<RtpPacketizer> packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(1u,
packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation));
@ -218,7 +216,7 @@ TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) {
frame[fragmentation.fragmentationOffset[0]] = 0x01;
frame[fragmentation.fragmentationOffset[1]] = 0x01;
std::unique_ptr<RtpPacketizer> packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@ -251,7 +249,7 @@ TEST(RtpPacketizerH264Test, TestStapA) {
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(1u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@ -286,7 +284,7 @@ TEST(RtpPacketizerH264Test, TestStapARespectsPacketReduction) {
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
std::unique_ptr<RtpPacketizer> packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kMaxPayloadSize, kLastPacketReduction));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@ -323,7 +321,7 @@ TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) {
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
@ -352,7 +350,7 @@ TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@ -397,7 +395,7 @@ TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
frame[nalu_offset + j] = i + j;
}
}
std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(3u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@ -486,7 +484,7 @@ TEST(RtpPacketizerH264Test, SendOverlongDataInPacketizationMode0) {
// Set NAL headers.
frame[fragmentation.fragmentationOffset[0]] = 0x01;
std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
EXPECT_EQ(0u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
}
@ -524,16 +522,16 @@ class RtpPacketizerH264TestSpsRewriting : public ::testing::Test {
protected:
rtc::Buffer in_buffer_;
RTPFragmentationHeader fragmentation_header_;
std::unique_ptr<RtpPacketizer> packetizer_;
std::unique_ptr<RtpPacketizerH264> packetizer_;
};
TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
const size_t kHeaderOverhead = kFuAHeaderSize + 1;
// Set size to fragment SPS into two FU-A packets.
packetizer_.reset(
packetizer_ =
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0));
sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0);
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);
@ -564,9 +562,8 @@ TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) {
sizeof(kIdrTwo) + (kLengthFieldLength * 3);
// Set size to include SPS and the rest of the packets in a Stap-A package.
packetizer_.reset(CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kExpectedTotalSize + kHeaderOverhead,
0));
packetizer_ = CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kExpectedTotalSize + kHeaderOverhead, 0);
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);

View File

@ -77,6 +77,10 @@ size_t RtpPacketizerGeneric::SetPayloadData(
return num_packets_left_;
}
size_t RtpPacketizerGeneric::NumPackets() const {
return num_packets_left_;
}
bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
RTC_DCHECK(packet);
if (num_packets_left_ == 0)
@ -127,10 +131,6 @@ bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
return true;
}
std::string RtpPacketizerGeneric::ToString() {
return "RtpPacketizerGeneric";
}
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.

View File

@ -39,15 +39,15 @@ class RtpPacketizerGeneric : public RtpPacketizer {
// Returns total number of packets to be generated.
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation);
size_t NumPackets() const override;
// Get the next payload with generic payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* packet) override;
std::string ToString() override;
private:
const absl::optional<uint16_t> picture_id_;
const uint8_t* payload_data_;

View File

@ -184,6 +184,10 @@ size_t RtpPacketizerVp8::SetPayloadData(
return packets_.size();
}
size_t RtpPacketizerVp8::NumPackets() const {
return packets_.size();
}
bool RtpPacketizerVp8::NextPacket(RtpPacketToSend* packet) {
RTC_DCHECK(packet);
if (packets_.empty()) {
@ -204,10 +208,6 @@ bool RtpPacketizerVp8::NextPacket(RtpPacketToSend* packet) {
return true;
}
std::string RtpPacketizerVp8::ToString() {
return "RtpPacketizerVp8";
}
int RtpPacketizerVp8::GeneratePackets() {
if (max_payload_len_ < vp8_fixed_payload_descriptor_bytes_ +
PayloadDescriptorExtraLength() + 1 +

View File

@ -48,15 +48,15 @@ class RtpPacketizerVp8 : public RtpPacketizer {
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation);
size_t NumPackets() const override;
// Get the next payload with VP8 payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* packet) override;
std::string ToString() override;
private:
typedef struct {
size_t payload_start_pos;

View File

@ -471,10 +471,6 @@ RtpPacketizerVp9::RtpPacketizerVp9(const RTPVideoHeaderVP9& hdr,
RtpPacketizerVp9::~RtpPacketizerVp9() {}
std::string RtpPacketizerVp9::ToString() {
return "RtpPacketizerVp9";
}
size_t RtpPacketizerVp9::SetPayloadData(
const uint8_t* payload,
size_t payload_size,
@ -485,6 +481,10 @@ size_t RtpPacketizerVp9::SetPayloadData(
return packets_.size();
}
size_t RtpPacketizerVp9::NumPackets() const {
return packets_.size();
}
// Splits payload in minimal number of roughly equal in size packets.
void RtpPacketizerVp9::GeneratePackets() {
if (max_payload_length_ < PayloadDescriptorLength(hdr_) + 1) {

View File

@ -38,12 +38,12 @@ class RtpPacketizerVp9 : public RtpPacketizer {
~RtpPacketizerVp9() override;
std::string ToString() override;
// The payload data must be one encoded VP9 layer frame.
size_t SetPayloadData(const uint8_t* payload,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation);
size_t NumPackets() const override;
// Gets the next payload with VP9 payload header.
// Write payload and set marker bit of the |packet|.

View File

@ -280,6 +280,7 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
int64_t expected_retransmission_time_ms) {
if (payload_size == 0)
return false;
RTC_CHECK(video_header);
// Create header that will be reused in all packets.
std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket();
@ -303,24 +304,22 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
// packet in each group of packets which make up another type of frame
// (e.g. a P-Frame) only if the current value is different from the previous
// value sent.
if (video_header) {
// Set rotation when key frame or when changed (to follow standard).
// Or when different from 0 (to follow current receiver implementation).
VideoRotation current_rotation = video_header->rotation;
if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ ||
current_rotation != kVideoRotation_0)
last_packet->SetExtension<VideoOrientation>(current_rotation);
last_rotation_ = current_rotation;
// Report content type only for key frames.
if (frame_type == kVideoFrameKey &&
video_header->content_type != VideoContentType::UNSPECIFIED) {
last_packet->SetExtension<VideoContentTypeExtension>(
video_header->content_type);
}
if (video_header->video_timing.flags != VideoSendTiming::kInvalid) {
last_packet->SetExtension<VideoTimingExtension>(
video_header->video_timing);
}
// Set rotation when key frame or when changed (to follow standard).
// Or when different from 0 (to follow current receiver implementation).
VideoRotation current_rotation = video_header->rotation;
if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ ||
current_rotation != kVideoRotation_0)
last_packet->SetExtension<VideoOrientation>(current_rotation);
last_rotation_ = current_rotation;
// Report content type only for key frames.
if (frame_type == kVideoFrameKey &&
video_header->content_type != VideoContentType::UNSPECIFIED) {
last_packet->SetExtension<VideoContentTypeExtension>(
video_header->content_type);
}
if (video_header->video_timing.flags != VideoSendTiming::kInvalid) {
last_packet->SetExtension<VideoTimingExtension>(
video_header->video_timing);
}
// FEC settings.
@ -347,16 +346,17 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
size_t last_packet_reduction_len =
last_packet->headers_size() - rtp_header->headers_size();
std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create(
video_type, max_data_payload_length, last_packet_reduction_len,
video_header, frame_type));
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = max_data_payload_length;
limits.last_packet_reduction_len = last_packet_reduction_len;
std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
video_type, rtc::MakeArrayView(payload_data, payload_size), limits,
*video_header, frame_type, fragmentation);
const uint8_t temporal_id =
video_header ? GetTemporalId(*video_header) : kNoTemporalIdx;
const uint8_t temporal_id = GetTemporalId(*video_header);
StorageType storage = GetStorageType(temporal_id, retransmission_settings,
expected_retransmission_time_ms);
size_t num_packets =
packetizer->SetPayloadData(payload_data, payload_size, fragmentation);
size_t num_packets = packetizer->NumPackets();
if (num_packets == 0)
return false;