Reduces locking in RtpSenderVideo.

This CL removes some unnecessary locking, since we are already
serialized by the lock in VideoStreamEncoder. A simple RaceChecker is
used to verify this.

We also remove the usage of RegisterPayloadType() and replace it with
a parameter in SendVideo instead. This way we are prepared for removing
the payload type map and lock entirely. Some usage still exists
downstream and needs to be removed before cleaning this up.

Bug: webrtc:10809
Change-Id: Ie90163f15d11c8843f3beaf9a0df0dd2a1fd5ce6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/154700
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29372}
This commit is contained in:
Erik Språng
2019-10-02 20:55:39 +02:00
committed by Commit Bot
parent f23131fdf2
commit 6cf554ecb4
9 changed files with 189 additions and 154 deletions

View File

@ -168,6 +168,7 @@ rtc_source_set("rtp_sender") {
"../system_wrappers:field_trial", "../system_wrappers:field_trial",
"//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/strings:strings",
"//third_party/abseil-cpp/absl/types:optional", "//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:variant", "//third_party/abseil-cpp/absl/types:variant",
] ]

View File

@ -16,6 +16,7 @@
#include <utility> #include <utility>
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/array_view.h" #include "api/array_view.h"
#include "api/transport/field_trial_based_config.h" #include "api/transport/field_trial_based_config.h"
#include "call/rtp_transport_controller_send_interface.h" #include "call/rtp_transport_controller_send_interface.h"
@ -205,6 +206,22 @@ DataRate CalculateOverheadRate(DataRate data_rate,
// rate here. // rate here.
return packet_rate.RoundUpTo(Frequency::hertz(1)) * overhead_per_packet; return packet_rate.RoundUpTo(Frequency::hertz(1)) * overhead_per_packet;
} }
absl::optional<VideoCodecType> GetVideoCodecType(const RtpConfig& config) {
absl::optional<VideoCodecType> video_type;
if (!config.raw_payload) {
if (absl::EqualsIgnoreCase(config.payload_name, "VP8")) {
video_type = kVideoCodecVP8;
} else if (absl::EqualsIgnoreCase(config.payload_name, "VP9")) {
video_type = kVideoCodecVP9;
} else if (absl::EqualsIgnoreCase(config.payload_name, "H264")) {
video_type = kVideoCodecH264;
} else {
video_type = kVideoCodecGeneric;
}
}
return video_type;
}
} // namespace } // namespace
RtpVideoSender::RtpVideoSender( RtpVideoSender::RtpVideoSender(
@ -255,6 +272,7 @@ RtpVideoSender::RtpVideoSender(
frame_encryptor, frame_encryptor,
crypto_options)), crypto_options)),
rtp_config_(rtp_config), rtp_config_(rtp_config),
codec_type_(GetVideoCodecType(rtp_config)),
transport_(transport), transport_(transport),
transport_overhead_bytes_per_packet_(0), transport_overhead_bytes_per_packet_(0),
overhead_bytes_per_packet_(0), overhead_bytes_per_packet_(0),
@ -319,9 +337,6 @@ RtpVideoSender::RtpVideoSender(
stream.rtp_rtcp->SetMaxRtpPacketSize(rtp_config_.max_packet_size); stream.rtp_rtcp->SetMaxRtpPacketSize(rtp_config_.max_packet_size);
stream.rtp_rtcp->RegisterSendPayloadFrequency(rtp_config_.payload_type, stream.rtp_rtcp->RegisterSendPayloadFrequency(rtp_config_.payload_type,
kVideoPayloadTypeFrequency); kVideoPayloadTypeFrequency);
stream.sender_video->RegisterPayloadType(rtp_config_.payload_type,
rtp_config_.payload_name,
rtp_config_.raw_payload);
} }
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic, // Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
// so enable that logic if either of those FEC schemes are enabled. // so enable that logic if either of those FEC schemes are enabled.
@ -432,8 +447,8 @@ EncodedImageCallback::Result RtpVideoSender::OnEncodedImage(
} }
bool send_result = rtp_streams_[stream_index].sender_video->SendVideo( bool send_result = rtp_streams_[stream_index].sender_video->SendVideo(
encoded_image._frameType, rtp_config_.payload_type, rtp_timestamp, encoded_image._frameType, rtp_config_.payload_type, codec_type_,
encoded_image.capture_time_ms_, encoded_image.data(), rtp_timestamp, encoded_image.capture_time_ms_, encoded_image.data(),
encoded_image.size(), fragmentation, &rtp_video_header, encoded_image.size(), fragmentation, &rtp_video_header,
expected_retransmission_time_ms); expected_retransmission_time_ms);
if (frame_count_observer_) { if (frame_count_observer_) {

View File

@ -186,6 +186,7 @@ class RtpVideoSender : public RtpVideoSenderInterface,
const std::vector<webrtc_internal_rtp_video_sender::RtpStreamSender> const std::vector<webrtc_internal_rtp_video_sender::RtpStreamSender>
rtp_streams_; rtp_streams_;
const RtpConfig rtp_config_; const RtpConfig rtp_config_;
const absl::optional<VideoCodecType> codec_type_;
RtpTransportControllerSendInterface* const transport_; RtpTransportControllerSendInterface* const transport_;
// When using the generic descriptor we want all simulcast streams to share // When using the generic descriptor we want all simulcast streams to share

View File

@ -151,8 +151,6 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
// single rtp_rtcp module for both send and receive side. // single rtp_rtcp module for both send and receive side.
rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc); rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc);
rtp_sender_video_->RegisterPayloadType(kPayloadType, "video",
/*raw_payload=*/false);
rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType); rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
transport_.SetSendModule(rtp_rtcp_module_.get()); transport_.SetSendModule(rtp_rtcp_module_.get());
media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver( media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver(
@ -209,9 +207,9 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90, EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90,
kPayloadType, false)); kPayloadType, false));
EXPECT_TRUE(rtp_sender_video_->SendVideo( EXPECT_TRUE(rtp_sender_video_->SendVideo(
VideoFrameType::kVideoFrameDelta, kPayloadType, timestamp, VideoFrameType::kVideoFrameDelta, kPayloadType,
timestamp / 90, payload_data, payload_data_length, nullptr, VideoCodecType::kVideoCodecGeneric, timestamp, timestamp / 90,
&video_header, 0)); payload_data, payload_data_length, nullptr, &video_header, 0));
// Min required delay until retransmit = 5 + RTT ms (RTT = 0). // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
fake_clock.AdvanceTimeMilliseconds(5); fake_clock.AdvanceTimeMilliseconds(5);
int length = BuildNackList(nack_list); int length = BuildNackList(nack_list);
@ -261,9 +259,9 @@ TEST_F(RtpRtcpRtxNackTest, LongNackList) {
EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90, EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90,
kPayloadType, false)); kPayloadType, false));
EXPECT_TRUE(rtp_sender_video_->SendVideo( EXPECT_TRUE(rtp_sender_video_->SendVideo(
VideoFrameType::kVideoFrameDelta, kPayloadType, timestamp, VideoFrameType::kVideoFrameDelta, kPayloadType,
timestamp / 90, payload_data, payload_data_length, nullptr, VideoCodecType::kVideoCodecGeneric, timestamp, timestamp / 90,
&video_header, 0)); payload_data, payload_data_length, nullptr, &video_header, 0));
// Prepare next frame. // Prepare next frame.
timestamp += 3000; timestamp += 3000;
fake_clock.AdvanceTimeMilliseconds(33); fake_clock.AdvanceTimeMilliseconds(33);

View File

@ -186,8 +186,6 @@ class RtpRtcpImplTest : public ::testing::Test {
codec_.plType = 100; codec_.plType = 100;
codec_.width = 320; codec_.width = 320;
codec_.height = 180; codec_.height = 180;
sender_video_->RegisterPayloadType(codec_.plType, "VP8",
/*raw_payload=*/false);
// Receive module. // Receive module.
EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false)); EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
@ -224,8 +222,9 @@ class RtpRtcpImplTest : public ::testing::Test {
const uint8_t payload[100] = {0}; const uint8_t payload[100] = {0};
EXPECT_TRUE(module->impl_->OnSendingRtpFrame(0, 0, codec_.plType, true)); EXPECT_TRUE(module->impl_->OnSendingRtpFrame(0, 0, codec_.plType, true));
EXPECT_TRUE(sender->SendVideo(VideoFrameType::kVideoFrameKey, codec_.plType, EXPECT_TRUE(sender->SendVideo(VideoFrameType::kVideoFrameKey, codec_.plType,
0, 0, payload, sizeof(payload), nullptr, VideoCodecType::kVideoCodecVP8, 0, 0, payload,
&rtp_video_header, 0)); sizeof(payload), nullptr, &rtp_video_header,
0));
} }
void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) { void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {

View File

@ -591,10 +591,8 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
false, FieldTrialBasedConfig()); false, FieldTrialBasedConfig());
const uint8_t kPayloadType = 127; const uint8_t kPayloadType = 127;
const char payload_name[] = "GENERIC"; const absl::optional<VideoCodecType> kCodecType =
VideoCodecType::kVideoCodecGeneric;
rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
/*raw_payload=*/false);
const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
RTPVideoHeader video_header; RTPVideoHeader video_header;
@ -607,7 +605,7 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
fake_clock_.AdvanceTimeMilliseconds(10); fake_clock_.AdvanceTimeMilliseconds(10);
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kPayloadType, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType,
capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms, capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
kPayloadData, sizeof(kPayloadData), nullptr, &video_header, kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
@ -619,7 +617,7 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
.Times(1); .Times(1);
fake_clock_.AdvanceTimeMilliseconds(10); fake_clock_.AdvanceTimeMilliseconds(10);
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kPayloadType, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType,
capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms, capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
kPayloadData, sizeof(kPayloadData), nullptr, &video_header, kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
@ -632,7 +630,7 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
.Times(1); .Times(1);
capture_time_ms = fake_clock_.TimeInMilliseconds(); capture_time_ms = fake_clock_.TimeInMilliseconds();
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kPayloadType, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType,
capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms, capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
kPayloadData, sizeof(kPayloadData), nullptr, &video_header, kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
@ -646,7 +644,7 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc)) EXPECT_CALL(send_side_delay_observer_, SendSideDelayUpdated(1, 1, 31, kSsrc))
.Times(1); .Times(1);
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kPayloadType, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType,
capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms, capture_time_ms * kCaptureTimeMsToRtpTimestamp, capture_time_ms,
kPayloadData, sizeof(kPayloadData), nullptr, &video_header, kPayloadData, sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
@ -1076,21 +1074,19 @@ TEST_P(RtpSenderTest, OnSendPacketNotUpdatedForRetransmits) {
} }
TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) { TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
const char payload_name[] = "GENERIC"; const uint8_t kPayloadType = 127;
const uint8_t payload_type = 127; const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
PlayoutDelayOracle playout_delay_oracle; PlayoutDelayOracle playout_delay_oracle;
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr, RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false, false, &playout_delay_oracle, nullptr, false, false,
false, FieldTrialBasedConfig()); false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
/*raw_payload=*/false);
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
// Send keyframe // Send keyframe
RTPVideoHeader video_header; RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload(); auto sent_payload = transport_.last_sent_packet().payload();
@ -1105,8 +1101,8 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
payload[4] = 13; payload[4] = 13;
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameDelta, kPayloadType, kCodecType, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
sent_payload = transport_.last_sent_packet().payload(); sent_payload = transport_.last_sent_packet().payload();
@ -1117,22 +1113,19 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
} }
TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) { TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
const char payload_name[] = "VP8"; const uint8_t kPayloadType = 111;
const uint8_t payload_type = 111;
const uint8_t payload[] = {11, 22, 33, 44, 55}; const uint8_t payload[] = {11, 22, 33, 44, 55};
PlayoutDelayOracle playout_delay_oracle; PlayoutDelayOracle playout_delay_oracle;
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr, RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false, false, &playout_delay_oracle, nullptr, false, false,
false, FieldTrialBasedConfig()); false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
/*raw_payload=*/true);
// Send a frame. // Send a frame.
RTPVideoHeader video_header; RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameKey, kPayloadType, absl::nullopt, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload(); auto sent_payload = transport_.last_sent_packet().payload();
@ -1142,6 +1135,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
TEST_P(RtpSenderTest, SendFlexfecPackets) { TEST_P(RtpSenderTest, SendFlexfecPackets) {
constexpr uint32_t kTimestamp = 1234; constexpr uint32_t kTimestamp = 1234;
constexpr int kMediaPayloadType = 127; constexpr int kMediaPayloadType = 127;
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
constexpr int kFlexfecPayloadType = 118; constexpr int kFlexfecPayloadType = 118;
const std::vector<RtpExtension> kNoRtpExtensions; const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes; const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
@ -1168,8 +1162,6 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
RTPSenderVideo rtp_sender_video( RTPSenderVideo rtp_sender_video(
&fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle, &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
nullptr, false, false, false, FieldTrialBasedConfig()); nullptr, false, false, false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
/*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet. // Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params; FecProtectionParams params;
@ -1200,9 +1192,10 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
}); });
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType,
fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData), kTimestamp, fake_clock_.TimeInMilliseconds(), kPayloadData,
nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs)); sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs));
ASSERT_TRUE(media_packet != nullptr); ASSERT_TRUE(media_packet != nullptr);
ASSERT_TRUE(fec_packet != nullptr); ASSERT_TRUE(fec_packet != nullptr);
@ -1227,6 +1220,7 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
constexpr uint32_t kTimestamp = 1234; constexpr uint32_t kTimestamp = 1234;
const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds(); const int64_t kCaptureTimeMs = fake_clock_.TimeInMilliseconds();
constexpr int kMediaPayloadType = 127; constexpr int kMediaPayloadType = 127;
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
constexpr int kFlexfecPayloadType = 118; constexpr int kFlexfecPayloadType = 118;
const std::vector<RtpExtension> kNoRtpExtensions; const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes; const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
@ -1253,8 +1247,6 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
RTPSenderVideo rtp_sender_video( RTPSenderVideo rtp_sender_video(
&fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle, &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
nullptr, false, false, false, FieldTrialBasedConfig()); nullptr, false, false, false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
/*raw_payload=*/false);
// Need extension to be registered for timing frames to be sent. // Need extension to be registered for timing frames to be sent.
ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension( ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@ -1289,8 +1281,8 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
.Times(0); // Not called because packet should not be protected. .Times(0); // Not called because packet should not be protected.
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType,
kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr, kTimestamp, kCaptureTimeMs, kPayloadData, sizeof(kPayloadData), nullptr,
&video_header, kDefaultExpectedRetransmissionTimeMs)); &video_header, kDefaultExpectedRetransmissionTimeMs));
EXPECT_TRUE( EXPECT_TRUE(
@ -1328,9 +1320,9 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
video_header.video_timing.flags = VideoSendTiming::kInvalid; video_header.video_timing.flags = VideoSendTiming::kInvalid;
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp + 1, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType,
kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData), nullptr, kTimestamp + 1, kCaptureTimeMs + 1, kPayloadData, sizeof(kPayloadData),
&video_header, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
ASSERT_TRUE(media_packet2 != nullptr); ASSERT_TRUE(media_packet2 != nullptr);
ASSERT_TRUE(fec_packet != nullptr); ASSERT_TRUE(fec_packet != nullptr);
@ -1353,6 +1345,7 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) { TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
constexpr uint32_t kTimestamp = 1234; constexpr uint32_t kTimestamp = 1234;
constexpr int kMediaPayloadType = 127; constexpr int kMediaPayloadType = 127;
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
constexpr int kFlexfecPayloadType = 118; constexpr int kFlexfecPayloadType = 118;
const std::vector<RtpExtension> kNoRtpExtensions; const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes; const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
@ -1377,8 +1370,6 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
RTPSenderVideo rtp_sender_video( RTPSenderVideo rtp_sender_video(
&fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle, &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
nullptr, false, false, false, FieldTrialBasedConfig()); nullptr, false, false, false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
/*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet. // Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params; FecProtectionParams params;
@ -1392,7 +1383,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
.Times(2); .Times(2);
RTPVideoHeader video_header; RTPVideoHeader video_header;
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType, kTimestamp,
fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData), fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData),
nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs));
@ -1620,6 +1611,7 @@ TEST_P(RtpSenderTestWithoutPacer,
TEST_P(RtpSenderTest, FecOverheadRate) { TEST_P(RtpSenderTest, FecOverheadRate) {
constexpr uint32_t kTimestamp = 1234; constexpr uint32_t kTimestamp = 1234;
constexpr int kMediaPayloadType = 127; constexpr int kMediaPayloadType = 127;
constexpr VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
constexpr int kFlexfecPayloadType = 118; constexpr int kFlexfecPayloadType = 118;
const std::vector<RtpExtension> kNoRtpExtensions; const std::vector<RtpExtension> kNoRtpExtensions;
const std::vector<RtpExtensionSize> kNoRtpExtensionSizes; const std::vector<RtpExtensionSize> kNoRtpExtensionSizes;
@ -1645,8 +1637,6 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
RTPSenderVideo rtp_sender_video( RTPSenderVideo rtp_sender_video(
&fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle, &fake_clock_, rtp_sender_.get(), &flexfec_sender, &playout_delay_oracle,
nullptr, false, false, false, FieldTrialBasedConfig()); nullptr, false, false, false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
/*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet. // Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params; FecProtectionParams params;
params.fec_rate = 15; params.fec_rate = 15;
@ -1663,9 +1653,10 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
RTPVideoHeader video_header; RTPVideoHeader video_header;
EXPECT_TRUE(rtp_sender_video.SendVideo( EXPECT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, kMediaPayloadType, kTimestamp, VideoFrameType::kVideoFrameKey, kMediaPayloadType, kCodecType,
fake_clock_.TimeInMilliseconds(), kPayloadData, sizeof(kPayloadData), kTimestamp, fake_clock_.TimeInMilliseconds(), kPayloadData,
nullptr, &video_header, kDefaultExpectedRetransmissionTimeMs)); sizeof(kPayloadData), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs));
fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs); fake_clock_.AdvanceTimeMilliseconds(kTimeBetweenPacketsMs);
} }
@ -1718,10 +1709,8 @@ TEST_P(RtpSenderTest, BitrateCallbacks) {
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr, RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false, false, &playout_delay_oracle, nullptr, false, false,
false, FieldTrialBasedConfig()); false, FieldTrialBasedConfig());
const char payload_name[] = "GENERIC"; const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
const uint8_t payload_type = 127; const uint8_t kPayloadType = 127;
rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
/*raw_payload=*/false);
// Simulate kNumPackets sent with kPacketInterval ms intervals, with the // Simulate kNumPackets sent with kPacketInterval ms intervals, with the
// number of packets selected so that we fill (but don't overflow) the one // number of packets selected so that we fill (but don't overflow) the one
@ -1744,8 +1733,8 @@ TEST_P(RtpSenderTest, BitrateCallbacks) {
RTPVideoHeader video_header; RTPVideoHeader video_header;
for (uint32_t i = 0; i < kNumPackets; ++i) { for (uint32_t i = 0; i < kNumPackets; ++i) {
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
fake_clock_.AdvanceTimeMilliseconds(kPacketInterval); fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
} }
@ -1801,14 +1790,12 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
const uint8_t kRedPayloadType = 96; const uint8_t kRedPayloadType = 96;
const uint8_t kUlpfecPayloadType = 97; const uint8_t kUlpfecPayloadType = 97;
const char payload_name[] = "GENERIC"; const uint8_t kPayloadType = 127;
const uint8_t payload_type = 127; const VideoCodecType kCodecType = VideoCodecType::kVideoCodecGeneric;
PlayoutDelayOracle playout_delay_oracle; PlayoutDelayOracle playout_delay_oracle;
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr, RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false, false, &playout_delay_oracle, nullptr, false, false,
false, FieldTrialBasedConfig()); false, FieldTrialBasedConfig());
rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
/*raw_payload=*/false);
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
rtp_sender_->SetStorePacketsStatus(true, 1); rtp_sender_->SetStorePacketsStatus(true, 1);
uint32_t ssrc = rtp_sender_->SSRC(); uint32_t ssrc = rtp_sender_->SSRC();
@ -1818,8 +1805,8 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
// Send a frame. // Send a frame.
RTPVideoHeader video_header; RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameKey, kPayloadType, kCodecType, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
StreamDataCounters expected; StreamDataCounters expected;
expected.transmitted.payload_bytes = 6; expected.transmitted.payload_bytes = 6;
@ -1861,8 +1848,8 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
fec_params.max_fec_frames = 1; fec_params.max_fec_frames = 1;
rtp_sender_video.SetFecParameters(fec_params, fec_params); rtp_sender_video.SetFecParameters(fec_params, fec_params);
ASSERT_TRUE(rtp_sender_video.SendVideo( ASSERT_TRUE(rtp_sender_video.SendVideo(
VideoFrameType::kVideoFrameDelta, payload_type, 1234, 4321, payload, VideoFrameType::kVideoFrameDelta, kPayloadType, kCodecType, 1234, 4321,
sizeof(payload), nullptr, &video_header, payload, sizeof(payload), nullptr, &video_header,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
expected.transmitted.payload_bytes = 40; expected.transmitted.payload_bytes = 40;
expected.transmitted.header_bytes = 60; expected.transmitted.header_bytes = 60;

View File

@ -259,12 +259,6 @@ void RTPSenderVideo::RegisterPayloadType(int8_t payload_type,
rtc::CritScope cs(&payload_type_crit_); rtc::CritScope cs(&payload_type_crit_);
payload_type_map_[payload_type] = video_type; payload_type_map_[payload_type] = video_type;
} }
// Backward compatibility for older receivers without temporal layer logic
if (absl::EqualsIgnoreCase(payload_name, "H264")) {
rtc::CritScope cs(&crit_);
retransmission_settings_ = kRetransmitBaseLayer | kRetransmitHigherLayers;
}
} }
void RTPSenderVideo::AppendAsRedMaybeWithUlpfec( void RTPSenderVideo::AppendAsRedMaybeWithUlpfec(
@ -462,8 +456,36 @@ bool RTPSenderVideo::SendVideo(
const RTPFragmentationHeader* fragmentation, const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header, const RTPVideoHeader* video_header,
absl::optional<int64_t> expected_retransmission_time_ms) { absl::optional<int64_t> expected_retransmission_time_ms) {
absl::optional<VideoCodecType> codec_type;
{
rtc::CritScope cs(&payload_type_crit_);
const auto it = payload_type_map_.find(payload_type);
if (it == payload_type_map_.end()) {
RTC_LOG(LS_ERROR) << "Payload type " << static_cast<int>(payload_type)
<< " not registered.";
return false;
}
codec_type = it->second;
}
return SendVideo(frame_type, payload_type, codec_type, rtp_timestamp,
capture_time_ms, payload_data, payload_size, fragmentation,
video_header, expected_retransmission_time_ms);
}
bool RTPSenderVideo::SendVideo(
VideoFrameType frame_type,
int8_t payload_type,
absl::optional<VideoCodecType> codec_type,
uint32_t rtp_timestamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header,
absl::optional<int64_t> expected_retransmission_time_ms) {
TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, "Send", "type", TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, "Send", "type",
FrameTypeToString(frame_type)); FrameTypeToString(frame_type));
RTC_CHECK_RUNS_SERIALIZED(&send_checker_);
if (frame_type == VideoFrameType::kEmptyFrame) if (frame_type == VideoFrameType::kEmptyFrame)
return true; return true;
@ -472,19 +494,19 @@ bool RTPSenderVideo::SendVideo(
return false; return false;
RTC_CHECK(video_header); RTC_CHECK(video_header);
size_t fec_packet_overhead; int32_t retransmission_settings = retransmission_settings_;
bool red_enabled; if (codec_type == VideoCodecType::kVideoCodecH264) {
int32_t retransmission_settings; // Backward compatibility for older receivers without temporal layer logic.
bool set_video_rotation; retransmission_settings = kRetransmitBaseLayer | kRetransmitHigherLayers;
bool set_color_space = false; }
bool set_frame_marking = bool set_frame_marking =
video_header->codec == kVideoCodecH264 && video_header->codec == kVideoCodecH264 &&
video_header->frame_marking.temporal_id != kNoTemporalIdx; video_header->frame_marking.temporal_id != kNoTemporalIdx;
const absl::optional<PlayoutDelay> playout_delay = const absl::optional<PlayoutDelay> playout_delay =
playout_delay_oracle_->PlayoutDelayToSend(video_header->playout_delay); playout_delay_oracle_->PlayoutDelayToSend(video_header->playout_delay);
{
rtc::CritScope cs(&crit_);
// According to // According to
// http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
// ts_126114v120700p.pdf Section 7.4.5: // ts_126114v120700p.pdf Section 7.4.5:
@ -497,7 +519,7 @@ bool RTPSenderVideo::SendVideo(
// value sent. // value sent.
// Set rotation when key frame or when changed (to follow standard). // Set rotation when key frame or when changed (to follow standard).
// Or when different from 0 (to follow current receiver implementation). // Or when different from 0 (to follow current receiver implementation).
set_video_rotation = frame_type == VideoFrameType::kVideoFrameKey || bool set_video_rotation = frame_type == VideoFrameType::kVideoFrameKey ||
video_header->rotation != last_rotation_ || video_header->rotation != last_rotation_ ||
video_header->rotation != kVideoRotation_0; video_header->rotation != kVideoRotation_0;
last_rotation_ = video_header->rotation; last_rotation_ = video_header->rotation;
@ -505,6 +527,7 @@ bool RTPSenderVideo::SendVideo(
// Send color space when changed or if the frame is a key frame. Keep // Send color space when changed or if the frame is a key frame. Keep
// sending color space information until the first base layer frame to // sending color space information until the first base layer frame to
// guarantee that the information is retrieved by the receiver. // guarantee that the information is retrieved by the receiver.
bool set_color_space;
if (video_header->color_space != last_color_space_) { if (video_header->color_space != last_color_space_) {
last_color_space_ = video_header->color_space; last_color_space_ = video_header->color_space;
set_color_space = true; set_color_space = true;
@ -512,11 +535,14 @@ bool RTPSenderVideo::SendVideo(
} else { } else {
set_color_space = frame_type == VideoFrameType::kVideoFrameKey || set_color_space = frame_type == VideoFrameType::kVideoFrameKey ||
transmit_color_space_next_frame_; transmit_color_space_next_frame_;
transmit_color_space_next_frame_ = transmit_color_space_next_frame_ transmit_color_space_next_frame_ =
? !IsBaseLayer(*video_header) transmit_color_space_next_frame_ ? !IsBaseLayer(*video_header) : false;
: false;
} }
size_t fec_packet_overhead;
bool red_enabled;
{
rtc::CritScope cs(&crit_);
// FEC settings. // FEC settings.
const FecProtectionParams& fec_params = const FecProtectionParams& fec_params =
frame_type == VideoFrameType::kVideoFrameKey ? key_fec_params_ frame_type == VideoFrameType::kVideoFrameKey ? key_fec_params_
@ -528,7 +554,6 @@ bool RTPSenderVideo::SendVideo(
fec_packet_overhead = CalculateFecPacketOverhead(); fec_packet_overhead = CalculateFecPacketOverhead();
red_enabled = this->red_enabled(); red_enabled = this->red_enabled();
retransmission_settings = retransmission_settings_;
} }
// Maximum size of packet including rtp headers. // Maximum size of packet including rtp headers.
@ -638,19 +663,8 @@ bool RTPSenderVideo::SendVideo(
<< "one is required since require_frame_encryptor is set"; << "one is required since require_frame_encryptor is set";
} }
absl::optional<VideoCodecType> type;
{
rtc::CritScope cs(&payload_type_crit_);
const auto it = payload_type_map_.find(payload_type);
if (it == payload_type_map_.end()) {
RTC_LOG(LS_ERROR) << "Payload type " << static_cast<int>(payload_type)
<< " not registered.";
return false;
}
type = it->second;
}
std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create( std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
type, rtc::MakeArrayView(payload_data, payload_size), limits, codec_type, rtc::MakeArrayView(payload_data, payload_size), limits,
*packetize_video_header, frame_type, fragmentation); *packetize_video_header, frame_type, fragmentation);
const uint8_t temporal_id = GetTemporalId(*video_header); const uint8_t temporal_id = GetTemporalId(*video_header);

View File

@ -29,6 +29,7 @@
#include "modules/rtp_rtcp/source/ulpfec_generator.h" #include "modules/rtp_rtcp/source/ulpfec_generator.h"
#include "rtc_base/critical_section.h" #include "rtc_base/critical_section.h"
#include "rtc_base/one_time_event.h" #include "rtc_base/one_time_event.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/rate_statistics.h" #include "rtc_base/rate_statistics.h"
#include "rtc_base/synchronization/sequence_checker.h" #include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/thread_annotations.h" #include "rtc_base/thread_annotations.h"
@ -67,6 +68,19 @@ class RTPSenderVideo {
virtual ~RTPSenderVideo(); virtual ~RTPSenderVideo();
// expected_retransmission_time_ms.has_value() -> retransmission allowed. // expected_retransmission_time_ms.has_value() -> retransmission allowed.
// Calls to this method is assumed to be externally serialized.
bool SendVideo(VideoFrameType frame_type,
int8_t payload_type,
absl::optional<VideoCodecType> codec_type,
uint32_t capture_timestamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* video_header,
absl::optional<int64_t> expected_retransmission_time_ms);
// TODO(bugs.webrtc.org/10809): Remove when downstream usage is gone.
bool SendVideo(VideoFrameType frame_type, bool SendVideo(VideoFrameType frame_type,
int8_t payload_type, int8_t payload_type,
uint32_t capture_timestamp, uint32_t capture_timestamp,
@ -77,6 +91,7 @@ class RTPSenderVideo {
const RTPVideoHeader* video_header, const RTPVideoHeader* video_header,
absl::optional<int64_t> expected_retransmission_time_ms); absl::optional<int64_t> expected_retransmission_time_ms);
// TODO(bugs.webrtc.org/10809): Remove when downstream usage is gone.
void RegisterPayloadType(int8_t payload_type, void RegisterPayloadType(int8_t payload_type,
absl::string_view payload_name, absl::string_view payload_name,
bool raw_payload); bool raw_payload);
@ -164,23 +179,28 @@ class RTPSenderVideo {
Clock* const clock_; Clock* const clock_;
// Maps payload type to codec type, for packetization. // Maps payload type to codec type, for packetization.
// TODO(nisse): Set on construction, to avoid lock. // TODO(bugs.webrtc.org/10809): Remove when downstream usage is gone.
rtc::CriticalSection payload_type_crit_; rtc::CriticalSection payload_type_crit_;
std::map<int8_t, absl::optional<VideoCodecType>> payload_type_map_ std::map<int8_t, absl::optional<VideoCodecType>> payload_type_map_
RTC_GUARDED_BY(payload_type_crit_); RTC_GUARDED_BY(payload_type_crit_);
// Should never be held when calling out of this class. const int32_t retransmission_settings_;
rtc::CriticalSection crit_;
// These members should only be accessed from within SendVideo() to avoid
// potential race conditions.
rtc::RaceChecker send_checker_;
VideoRotation last_rotation_ RTC_GUARDED_BY(send_checker_);
absl::optional<ColorSpace> last_color_space_ RTC_GUARDED_BY(send_checker_);
bool transmit_color_space_next_frame_ RTC_GUARDED_BY(send_checker_);
int32_t retransmission_settings_ RTC_GUARDED_BY(crit_);
VideoRotation last_rotation_ RTC_GUARDED_BY(crit_);
absl::optional<ColorSpace> last_color_space_ RTC_GUARDED_BY(crit_);
bool transmit_color_space_next_frame_ RTC_GUARDED_BY(crit_);
// Tracks the current request for playout delay limits from application // Tracks the current request for playout delay limits from application
// and decides whether the current RTP frame should include the playout // and decides whether the current RTP frame should include the playout
// delay extension on header. // delay extension on header.
PlayoutDelayOracle* const playout_delay_oracle_; PlayoutDelayOracle* const playout_delay_oracle_;
// Should never be held when calling out of this class.
rtc::CriticalSection crit_;
// Maps sent packets' sequence numbers to a tuple consisting of: // Maps sent packets' sequence numbers to a tuple consisting of:
// 1. The timestamp, without the randomizing offset mandated by the RFC. // 1. The timestamp, without the randomizing offset mandated by the RFC.
// 2. Whether the packet was the first in its frame. // 2. Whether the packet was the first in its frame.
@ -218,7 +238,7 @@ class RTPSenderVideo {
// If set to true will require all outgoing frames to pass through an // If set to true will require all outgoing frames to pass through an
// initialized frame_encryptor_ before being sent out of the network. // initialized frame_encryptor_ before being sent out of the network.
// Otherwise these payloads will be dropped. // Otherwise these payloads will be dropped.
bool require_frame_encryption_; const bool require_frame_encryption_;
// Set to true if the generic descriptor should be authenticated. // Set to true if the generic descriptor should be authenticated.
const bool generic_descriptor_auth_experiment_; const bool generic_descriptor_auth_experiment_;

View File

@ -47,6 +47,7 @@ enum : int { // The first valid value is 1.
}; };
constexpr int kPayload = 100; constexpr int kPayload = 100;
constexpr VideoCodecType kType = VideoCodecType::kVideoCodecGeneric;
constexpr uint32_t kTimestamp = 10; constexpr uint32_t kTimestamp = 10;
constexpr uint16_t kSeqNum = 33; constexpr uint16_t kSeqNum = 33;
constexpr uint32_t kSsrc = 725242; constexpr uint32_t kSsrc = 725242;
@ -153,9 +154,6 @@ class RtpSenderVideoTest : public ::testing::TestWithParam<bool> {
rtp_sender_video_(&fake_clock_, &rtp_sender_, nullptr, field_trials_) { rtp_sender_video_(&fake_clock_, &rtp_sender_, nullptr, field_trials_) {
rtp_sender_.SetSequenceNumber(kSeqNum); rtp_sender_.SetSequenceNumber(kSeqNum);
rtp_sender_.SetTimestampOffset(0); rtp_sender_.SetTimestampOffset(0);
rtp_sender_video_.RegisterPayloadType(kPayload, "generic",
/*raw_payload=*/false);
} }
void PopulateGenericFrameDescriptor(int version); void PopulateGenericFrameDescriptor(int version);
@ -180,7 +178,7 @@ TEST_P(RtpSenderVideoTest, KeyFrameHasCVO) {
RTPVideoHeader hdr; RTPVideoHeader hdr;
hdr.rotation = kVideoRotation_0; hdr.rotation = kVideoRotation_0;
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameKey, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameKey, kPayload, kType,
kTimestamp, 0, kFrame, sizeof(kFrame), nullptr, kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
&hdr, kDefaultExpectedRetransmissionTimeMs); &hdr, kDefaultExpectedRetransmissionTimeMs);
@ -206,7 +204,7 @@ TEST_P(RtpSenderVideoTest, TimingFrameHasPacketizationTimstampSet) {
hdr.video_timing.encode_finish_delta_ms = kEncodeFinishDeltaMs; hdr.video_timing.encode_finish_delta_ms = kEncodeFinishDeltaMs;
fake_clock_.AdvanceTimeMilliseconds(kPacketizationTimeMs); fake_clock_.AdvanceTimeMilliseconds(kPacketizationTimeMs);
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameKey, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameKey, kPayload, kType,
kTimestamp, kCaptureTimestamp, kFrame, kTimestamp, kCaptureTimestamp, kFrame,
sizeof(kFrame), nullptr, &hdr, sizeof(kFrame), nullptr, &hdr,
kDefaultExpectedRetransmissionTimeMs); kDefaultExpectedRetransmissionTimeMs);
@ -226,13 +224,14 @@ TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenChanged) {
RTPVideoHeader hdr; RTPVideoHeader hdr;
hdr.rotation = kVideoRotation_90; hdr.rotation = kVideoRotation_90;
EXPECT_TRUE(rtp_sender_video_.SendVideo( EXPECT_TRUE(rtp_sender_video_.SendVideo(
VideoFrameType::kVideoFrameKey, kPayload, kTimestamp, 0, kFrame, VideoFrameType::kVideoFrameKey, kPayload, kType, kTimestamp, 0, kFrame,
sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs)); sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
hdr.rotation = kVideoRotation_0; hdr.rotation = kVideoRotation_0;
EXPECT_TRUE(rtp_sender_video_.SendVideo( EXPECT_TRUE(rtp_sender_video_.SendVideo(
VideoFrameType::kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame, VideoFrameType::kVideoFrameDelta, kPayload, kType, kTimestamp + 1, 0,
sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs)); kFrame, sizeof(kFrame), nullptr, &hdr,
kDefaultExpectedRetransmissionTimeMs));
VideoRotation rotation; VideoRotation rotation;
EXPECT_TRUE( EXPECT_TRUE(
@ -248,12 +247,13 @@ TEST_P(RtpSenderVideoTest, DeltaFrameHasCVOWhenNonZero) {
RTPVideoHeader hdr; RTPVideoHeader hdr;
hdr.rotation = kVideoRotation_90; hdr.rotation = kVideoRotation_90;
EXPECT_TRUE(rtp_sender_video_.SendVideo( EXPECT_TRUE(rtp_sender_video_.SendVideo(
VideoFrameType::kVideoFrameKey, kPayload, kTimestamp, 0, kFrame, VideoFrameType::kVideoFrameKey, kPayload, kType, kTimestamp, 0, kFrame,
sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs)); sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs));
EXPECT_TRUE(rtp_sender_video_.SendVideo( EXPECT_TRUE(rtp_sender_video_.SendVideo(
VideoFrameType::kVideoFrameDelta, kPayload, kTimestamp + 1, 0, kFrame, VideoFrameType::kVideoFrameDelta, kPayload, kType, kTimestamp + 1, 0,
sizeof(kFrame), nullptr, &hdr, kDefaultExpectedRetransmissionTimeMs)); kFrame, sizeof(kFrame), nullptr, &hdr,
kDefaultExpectedRetransmissionTimeMs));
VideoRotation rotation; VideoRotation rotation;
EXPECT_TRUE( EXPECT_TRUE(
@ -278,7 +278,7 @@ TEST_P(RtpSenderVideoTest, CheckH264FrameMarking) {
hdr.frame_marking.temporal_id = kNoTemporalIdx; hdr.frame_marking.temporal_id = kNoTemporalIdx;
hdr.frame_marking.tl0_pic_idx = 99; hdr.frame_marking.tl0_pic_idx = 99;
hdr.frame_marking.base_layer_sync = true; hdr.frame_marking.base_layer_sync = true;
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, kType,
kTimestamp, 0, kFrame, sizeof(kFrame), &frag, kTimestamp, 0, kFrame, sizeof(kFrame), &frag,
&hdr, kDefaultExpectedRetransmissionTimeMs); &hdr, kDefaultExpectedRetransmissionTimeMs);
@ -287,7 +287,7 @@ TEST_P(RtpSenderVideoTest, CheckH264FrameMarking) {
transport_.last_sent_packet().GetExtension<FrameMarkingExtension>(&fm)); transport_.last_sent_packet().GetExtension<FrameMarkingExtension>(&fm));
hdr.frame_marking.temporal_id = 0; hdr.frame_marking.temporal_id = 0;
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, kType,
kTimestamp + 1, 0, kFrame, sizeof(kFrame), &frag, kTimestamp + 1, 0, kFrame, sizeof(kFrame), &frag,
&hdr, kDefaultExpectedRetransmissionTimeMs); &hdr, kDefaultExpectedRetransmissionTimeMs);
@ -529,7 +529,7 @@ void RtpSenderVideoTest::PopulateGenericFrameDescriptor(int version) {
generic.higher_spatial_layers.push_back(4); generic.higher_spatial_layers.push_back(4);
generic.dependencies.push_back(kFrameId - 1); generic.dependencies.push_back(kFrameId - 1);
generic.dependencies.push_back(kFrameId - 500); generic.dependencies.push_back(kFrameId - 500);
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, kType,
kTimestamp, 0, kFrame, sizeof(kFrame), nullptr, kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
&hdr, kDefaultExpectedRetransmissionTimeMs); &hdr, kDefaultExpectedRetransmissionTimeMs);
@ -583,10 +583,10 @@ void RtpSenderVideoTest::
vp8.keyIdx = 2; vp8.keyIdx = 2;
RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace(); RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
generic.frame_id = kFrameId; generic.frame_id = kFrameId;
rtp_sender_video_.RegisterPayloadType(kPayload, "vp8", /*raw_payload=*/false);
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload, rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload,
kTimestamp, 0, kFrame, sizeof(kFrame), nullptr, VideoCodecType::kVideoCodecVP8, kTimestamp, 0,
&hdr, kDefaultExpectedRetransmissionTimeMs); kFrame, sizeof(kFrame), nullptr, &hdr,
kDefaultExpectedRetransmissionTimeMs);
ASSERT_EQ(transport_.packets_sent(), 1); ASSERT_EQ(transport_.packets_sent(), 1);
// Expect only minimal 1-byte vp8 descriptor was generated. // Expect only minimal 1-byte vp8 descriptor was generated.