mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Cleans up code related to legacy pre-pacing fec generation.
Bug: webrtc:11340 Change-Id: If3493db9fafdd3ad041f78999e304c8714be517f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186562 Reviewed-by: Sebastian Jansson <srte@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32349}
This commit is contained in:
parent
0d1b044db8
commit
b6477858ac
9 changed files with 27 additions and 167 deletions
|
@ -197,7 +197,6 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
|
||||||
FrameEncryptorInterface* frame_encryptor,
|
FrameEncryptorInterface* frame_encryptor,
|
||||||
const CryptoOptions& crypto_options,
|
const CryptoOptions& crypto_options,
|
||||||
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
|
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
|
||||||
bool use_deferred_fec,
|
|
||||||
const WebRtcKeyValueConfig& trials) {
|
const WebRtcKeyValueConfig& trials) {
|
||||||
RTC_DCHECK_GT(rtp_config.ssrcs.size(), 0);
|
RTC_DCHECK_GT(rtp_config.ssrcs.size(), 0);
|
||||||
|
|
||||||
|
@ -245,9 +244,6 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
|
||||||
std::unique_ptr<VideoFecGenerator> fec_generator =
|
std::unique_ptr<VideoFecGenerator> fec_generator =
|
||||||
MaybeCreateFecGenerator(clock, rtp_config, suspended_ssrcs, i, trials);
|
MaybeCreateFecGenerator(clock, rtp_config, suspended_ssrcs, i, trials);
|
||||||
configuration.fec_generator = fec_generator.get();
|
configuration.fec_generator = fec_generator.get();
|
||||||
if (!use_deferred_fec) {
|
|
||||||
video_config.fec_generator = fec_generator.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
configuration.rtx_send_ssrc =
|
configuration.rtx_send_ssrc =
|
||||||
rtp_config.GetRtxSsrcAssociatedWithMediaSsrc(rtp_config.ssrcs[i]);
|
rtp_config.GetRtxSsrcAssociatedWithMediaSsrc(rtp_config.ssrcs[i]);
|
||||||
|
@ -335,9 +331,6 @@ RtpVideoSender::RtpVideoSender(
|
||||||
field_trials_.Lookup("WebRTC-SendSideBwe-WithOverhead"),
|
field_trials_.Lookup("WebRTC-SendSideBwe-WithOverhead"),
|
||||||
"Enabled")),
|
"Enabled")),
|
||||||
has_packet_feedback_(TransportSeqNumExtensionConfigured(rtp_config)),
|
has_packet_feedback_(TransportSeqNumExtensionConfigured(rtp_config)),
|
||||||
use_deferred_fec_(!absl::StartsWith(
|
|
||||||
field_trials_.Lookup("WebRTC-DeferredFecGeneration"),
|
|
||||||
"Disabled")),
|
|
||||||
active_(false),
|
active_(false),
|
||||||
module_process_thread_(nullptr),
|
module_process_thread_(nullptr),
|
||||||
suspended_ssrcs_(std::move(suspended_ssrcs)),
|
suspended_ssrcs_(std::move(suspended_ssrcs)),
|
||||||
|
@ -356,7 +349,6 @@ RtpVideoSender::RtpVideoSender(
|
||||||
frame_encryptor,
|
frame_encryptor,
|
||||||
crypto_options,
|
crypto_options,
|
||||||
std::move(frame_transformer),
|
std::move(frame_transformer),
|
||||||
use_deferred_fec_,
|
|
||||||
field_trials_)),
|
field_trials_)),
|
||||||
rtp_config_(rtp_config),
|
rtp_config_(rtp_config),
|
||||||
codec_type_(GetVideoCodecType(rtp_config)),
|
codec_type_(GetVideoCodecType(rtp_config)),
|
||||||
|
@ -844,7 +836,6 @@ int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
|
||||||
*sent_nack_rate_bps = 0;
|
*sent_nack_rate_bps = 0;
|
||||||
*sent_fec_rate_bps = 0;
|
*sent_fec_rate_bps = 0;
|
||||||
for (const RtpStreamSender& stream : rtp_streams_) {
|
for (const RtpStreamSender& stream : rtp_streams_) {
|
||||||
if (use_deferred_fec_) {
|
|
||||||
stream.rtp_rtcp->SetFecProtectionParams(*delta_params, *key_params);
|
stream.rtp_rtcp->SetFecProtectionParams(*delta_params, *key_params);
|
||||||
|
|
||||||
auto send_bitrate = stream.rtp_rtcp->GetSendRates();
|
auto send_bitrate = stream.rtp_rtcp->GetSendRates();
|
||||||
|
@ -853,17 +844,6 @@ int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
|
||||||
send_bitrate[RtpPacketMediaType::kForwardErrorCorrection].bps();
|
send_bitrate[RtpPacketMediaType::kForwardErrorCorrection].bps();
|
||||||
*sent_nack_rate_bps +=
|
*sent_nack_rate_bps +=
|
||||||
send_bitrate[RtpPacketMediaType::kRetransmission].bps();
|
send_bitrate[RtpPacketMediaType::kRetransmission].bps();
|
||||||
} else {
|
|
||||||
if (stream.fec_generator) {
|
|
||||||
stream.fec_generator->SetProtectionParameters(*delta_params,
|
|
||||||
*key_params);
|
|
||||||
*sent_fec_rate_bps += stream.fec_generator->CurrentFecRate().bps();
|
|
||||||
}
|
|
||||||
*sent_video_rate_bps += stream.sender_video->VideoBitrateSent();
|
|
||||||
*sent_nack_rate_bps +=
|
|
||||||
stream.rtp_rtcp->GetSendRates()[RtpPacketMediaType::kRetransmission]
|
|
||||||
.bps<uint32_t>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,6 @@ class RtpVideoSender : public RtpVideoSenderInterface,
|
||||||
const FieldTrialBasedConfig field_trials_;
|
const FieldTrialBasedConfig field_trials_;
|
||||||
const bool send_side_bwe_with_overhead_;
|
const bool send_side_bwe_with_overhead_;
|
||||||
const bool has_packet_feedback_;
|
const bool has_packet_feedback_;
|
||||||
const bool use_deferred_fec_;
|
|
||||||
|
|
||||||
// TODO(holmer): Remove mutex_ once RtpVideoSender runs on the
|
// TODO(holmer): Remove mutex_ once RtpVideoSender runs on the
|
||||||
// transport task queue.
|
// transport task queue.
|
||||||
|
|
|
@ -2106,10 +2106,7 @@ TEST_P(PacingControllerTest, PaddingTargetAccountsForPaddingRate) {
|
||||||
AdvanceTimeAndProcess();
|
AdvanceTimeAndProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(PacingControllerTest, SendsDeferredFecPackets) {
|
TEST_P(PacingControllerTest, SendsFecPackets) {
|
||||||
ScopedFieldTrials trial("WebRTC-DeferredFecGeneration/Enabled/");
|
|
||||||
SetUp();
|
|
||||||
|
|
||||||
const uint32_t kSsrc = 12345;
|
const uint32_t kSsrc = 12345;
|
||||||
const uint32_t kFlexSsrc = 54321;
|
const uint32_t kFlexSsrc = 54321;
|
||||||
uint16_t sequence_number = 1234;
|
uint16_t sequence_number = 1234;
|
||||||
|
|
|
@ -101,11 +101,7 @@ RtpSenderEgress::RtpSenderEgress(const RtpRtcpInterface::Configuration& config,
|
||||||
is_audio_(config.audio),
|
is_audio_(config.audio),
|
||||||
#endif
|
#endif
|
||||||
need_rtp_packet_infos_(config.need_rtp_packet_infos),
|
need_rtp_packet_infos_(config.need_rtp_packet_infos),
|
||||||
fec_generator_(!IsTrialSetTo(config.field_trials,
|
fec_generator_(config.fec_generator),
|
||||||
"WebRTC-DeferredFecGeneration",
|
|
||||||
"Disabled")
|
|
||||||
? config.fec_generator
|
|
||||||
: nullptr),
|
|
||||||
transport_feedback_observer_(config.transport_feedback_callback),
|
transport_feedback_observer_(config.transport_feedback_callback),
|
||||||
send_side_delay_observer_(config.send_side_delay_observer),
|
send_side_delay_observer_(config.send_side_delay_observer),
|
||||||
send_packet_observer_(config.send_packet_observer),
|
send_packet_observer_(config.send_packet_observer),
|
||||||
|
@ -176,7 +172,7 @@ void RtpSenderEgress::SendPacket(RtpPacketToSend* packet,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fec_generator_ && packet->fec_protect_packet()) {
|
if (fec_generator_ && packet->fec_protect_packet()) {
|
||||||
// Deferred fec generation is used, add packet to generator.
|
// This packet should be protected by FEC, add it to packet generator.
|
||||||
RTC_DCHECK(fec_generator_);
|
RTC_DCHECK(fec_generator_);
|
||||||
RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kVideo);
|
RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kVideo);
|
||||||
absl::optional<std::pair<FecProtectionParams, FecProtectionParams>>
|
absl::optional<std::pair<FecProtectionParams, FecProtectionParams>>
|
||||||
|
|
|
@ -143,10 +143,8 @@ MATCHER_P(SameRtcEventTypeAs, value, "") {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestConfig {
|
struct TestConfig {
|
||||||
TestConfig(bool with_overhead, bool deferred_fec)
|
explicit TestConfig(bool with_overhead) : with_overhead(with_overhead) {}
|
||||||
: with_overhead(with_overhead), deferred_fec(deferred_fec) {}
|
|
||||||
bool with_overhead = false;
|
bool with_overhead = false;
|
||||||
bool deferred_fec = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockRtpPacketPacer : public RtpPacketSender {
|
class MockRtpPacketPacer : public RtpPacketSender {
|
||||||
|
@ -283,12 +281,10 @@ class FieldTrialConfig : public WebRtcKeyValueConfig {
|
||||||
public:
|
public:
|
||||||
FieldTrialConfig()
|
FieldTrialConfig()
|
||||||
: overhead_enabled_(false),
|
: overhead_enabled_(false),
|
||||||
deferred_fec_(false),
|
|
||||||
max_padding_factor_(1200) {}
|
max_padding_factor_(1200) {}
|
||||||
~FieldTrialConfig() override {}
|
~FieldTrialConfig() override {}
|
||||||
|
|
||||||
void SetOverHeadEnabled(bool enabled) { overhead_enabled_ = enabled; }
|
void SetOverHeadEnabled(bool enabled) { overhead_enabled_ = enabled; }
|
||||||
void UseDeferredFec(bool enabled) { deferred_fec_ = enabled; }
|
|
||||||
void SetMaxPaddingFactor(double factor) { max_padding_factor_ = factor; }
|
void SetMaxPaddingFactor(double factor) { max_padding_factor_ = factor; }
|
||||||
|
|
||||||
std::string Lookup(absl::string_view key) const override {
|
std::string Lookup(absl::string_view key) const override {
|
||||||
|
@ -299,15 +295,12 @@ class FieldTrialConfig : public WebRtcKeyValueConfig {
|
||||||
return ssb.str();
|
return ssb.str();
|
||||||
} else if (key == "WebRTC-SendSideBwe-WithOverhead") {
|
} else if (key == "WebRTC-SendSideBwe-WithOverhead") {
|
||||||
return overhead_enabled_ ? "Enabled" : "Disabled";
|
return overhead_enabled_ ? "Enabled" : "Disabled";
|
||||||
} else if (key == "WebRTC-DeferredFecGeneration") {
|
|
||||||
return deferred_fec_ ? "Enabled" : "Disabled";
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool overhead_enabled_;
|
bool overhead_enabled_;
|
||||||
bool deferred_fec_;
|
|
||||||
double max_padding_factor_;
|
double max_padding_factor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -329,7 +322,6 @@ class RtpSenderTest : public ::testing::TestWithParam<TestConfig> {
|
||||||
clock_),
|
clock_),
|
||||||
kMarkerBit(true) {
|
kMarkerBit(true) {
|
||||||
field_trials_.SetOverHeadEnabled(GetParam().with_overhead);
|
field_trials_.SetOverHeadEnabled(GetParam().with_overhead);
|
||||||
field_trials_.UseDeferredFec(GetParam().deferred_fec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUp() override { SetUpRtpSender(true, false, false); }
|
void SetUp() override { SetUpRtpSender(true, false, false); }
|
||||||
|
@ -1339,9 +1331,6 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
|
||||||
RTPSenderVideo::Config video_config;
|
RTPSenderVideo::Config video_config;
|
||||||
video_config.clock = clock_;
|
video_config.clock = clock_;
|
||||||
video_config.rtp_sender = rtp_sender();
|
video_config.rtp_sender = rtp_sender();
|
||||||
if (!GetParam().deferred_fec) {
|
|
||||||
video_config.fec_generator = &flexfec_sender;
|
|
||||||
}
|
|
||||||
video_config.fec_type = flexfec_sender.GetFecType();
|
video_config.fec_type = flexfec_sender.GetFecType();
|
||||||
video_config.fec_overhead_bytes = flexfec_sender.MaxPacketOverhead();
|
video_config.fec_overhead_bytes = flexfec_sender.MaxPacketOverhead();
|
||||||
video_config.fec_type = flexfec_sender.GetFecType();
|
video_config.fec_type = flexfec_sender.GetFecType();
|
||||||
|
@ -1369,7 +1358,7 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
|
||||||
EXPECT_EQ(packet->Ssrc(), kSsrc);
|
EXPECT_EQ(packet->Ssrc(), kSsrc);
|
||||||
EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
|
EXPECT_EQ(packet->SequenceNumber(), kSeqNum);
|
||||||
media_packet = std::move(packet);
|
media_packet = std::move(packet);
|
||||||
if (GetParam().deferred_fec) {
|
|
||||||
// Simulate RtpSenderEgress adding packet to fec generator.
|
// Simulate RtpSenderEgress adding packet to fec generator.
|
||||||
flexfec_sender.AddPacketAndGenerateFec(*media_packet);
|
flexfec_sender.AddPacketAndGenerateFec(*media_packet);
|
||||||
auto fec_packets = flexfec_sender.GetFecPackets();
|
auto fec_packets = flexfec_sender.GetFecPackets();
|
||||||
|
@ -1378,7 +1367,6 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
|
||||||
EXPECT_EQ(fec_packet->packet_type(),
|
EXPECT_EQ(fec_packet->packet_type(),
|
||||||
RtpPacketMediaType::kForwardErrorCorrection);
|
RtpPacketMediaType::kForwardErrorCorrection);
|
||||||
EXPECT_EQ(fec_packet->Ssrc(), kFlexFecSsrc);
|
EXPECT_EQ(fec_packet->Ssrc(), kFlexFecSsrc);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(packet->packet_type(),
|
EXPECT_EQ(packet->packet_type(),
|
||||||
RtpPacketMediaType::kForwardErrorCorrection);
|
RtpPacketMediaType::kForwardErrorCorrection);
|
||||||
|
@ -1440,9 +1428,6 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
|
||||||
RTPSenderVideo::Config video_config;
|
RTPSenderVideo::Config video_config;
|
||||||
video_config.clock = clock_;
|
video_config.clock = clock_;
|
||||||
video_config.rtp_sender = rtp_sender();
|
video_config.rtp_sender = rtp_sender();
|
||||||
if (!GetParam().deferred_fec) {
|
|
||||||
video_config.fec_generator = &flexfec_sender;
|
|
||||||
}
|
|
||||||
video_config.fec_type = flexfec_sender.GetFecType();
|
video_config.fec_type = flexfec_sender.GetFecType();
|
||||||
video_config.fec_overhead_bytes = flexfec_sender_.MaxPacketOverhead();
|
video_config.fec_overhead_bytes = flexfec_sender_.MaxPacketOverhead();
|
||||||
video_config.field_trials = &field_trials;
|
video_config.field_trials = &field_trials;
|
||||||
|
@ -1453,11 +1438,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
|
||||||
params.fec_rate = 15;
|
params.fec_rate = 15;
|
||||||
params.max_fec_frames = 1;
|
params.max_fec_frames = 1;
|
||||||
params.fec_mask_type = kFecMaskRandom;
|
params.fec_mask_type = kFecMaskRandom;
|
||||||
if (GetParam().deferred_fec) {
|
rtp_egress()->SetFecProtectionParameters(params, params);
|
||||||
rtp_egress()->SetFecProtectionParameters(params, params);
|
|
||||||
} else {
|
|
||||||
flexfec_sender.SetProtectionParameters(params, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_CALL(mock_rtc_event_log_,
|
EXPECT_CALL(mock_rtc_event_log_,
|
||||||
LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
|
LogProxy(SameRtcEventTypeAs(RtcEvent::Type::RtpPacketOutgoing)))
|
||||||
|
@ -1768,9 +1749,6 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||||
RTPSenderVideo::Config video_config;
|
RTPSenderVideo::Config video_config;
|
||||||
video_config.clock = clock_;
|
video_config.clock = clock_;
|
||||||
video_config.rtp_sender = rtp_sender();
|
video_config.rtp_sender = rtp_sender();
|
||||||
if (!GetParam().deferred_fec) {
|
|
||||||
video_config.fec_generator = &flexfec_sender;
|
|
||||||
}
|
|
||||||
video_config.fec_type = flexfec_sender.GetFecType();
|
video_config.fec_type = flexfec_sender.GetFecType();
|
||||||
video_config.fec_overhead_bytes = flexfec_sender.MaxPacketOverhead();
|
video_config.fec_overhead_bytes = flexfec_sender.MaxPacketOverhead();
|
||||||
video_config.field_trials = &field_trials;
|
video_config.field_trials = &field_trials;
|
||||||
|
@ -1780,11 +1758,7 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||||
params.fec_rate = 15;
|
params.fec_rate = 15;
|
||||||
params.max_fec_frames = 1;
|
params.max_fec_frames = 1;
|
||||||
params.fec_mask_type = kFecMaskRandom;
|
params.fec_mask_type = kFecMaskRandom;
|
||||||
if (GetParam().deferred_fec) {
|
rtp_egress()->SetFecProtectionParameters(params, params);
|
||||||
rtp_egress()->SetFecProtectionParameters(params, params);
|
|
||||||
} else {
|
|
||||||
flexfec_sender.SetProtectionParameters(params, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t kNumMediaPackets = 10;
|
constexpr size_t kNumMediaPackets = 10;
|
||||||
constexpr size_t kNumFecPackets = kNumMediaPackets;
|
constexpr size_t kNumFecPackets = kNumMediaPackets;
|
||||||
|
@ -1806,7 +1780,6 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||||
constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
|
constexpr size_t kPacketLength = kRtpHeaderLength + kFlexfecHeaderLength +
|
||||||
kGenericCodecHeaderLength + kPayloadLength;
|
kGenericCodecHeaderLength + kPayloadLength;
|
||||||
|
|
||||||
if (GetParam().deferred_fec) {
|
|
||||||
EXPECT_NEAR(
|
EXPECT_NEAR(
|
||||||
kNumFecPackets * kPacketLength * 8 /
|
kNumFecPackets * kPacketLength * 8 /
|
||||||
(kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
|
(kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
|
||||||
|
@ -1814,11 +1787,6 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||||
->GetSendRates()[RtpPacketMediaType::kForwardErrorCorrection]
|
->GetSendRates()[RtpPacketMediaType::kForwardErrorCorrection]
|
||||||
.bps<double>(),
|
.bps<double>(),
|
||||||
500);
|
500);
|
||||||
} else {
|
|
||||||
EXPECT_NEAR(kNumFecPackets * kPacketLength * 8 /
|
|
||||||
(kNumFecPackets * kTimeBetweenPacketsMs / 1000.0f),
|
|
||||||
flexfec_sender.CurrentFecRate().bps<double>(), 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTest, BitrateCallbacks) {
|
TEST_P(RtpSenderTest, BitrateCallbacks) {
|
||||||
|
@ -1970,9 +1938,6 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacksUlpfec) {
|
||||||
video_config.rtp_sender = rtp_sender();
|
video_config.rtp_sender = rtp_sender();
|
||||||
video_config.field_trials = &field_trials_;
|
video_config.field_trials = &field_trials_;
|
||||||
video_config.red_payload_type = kRedPayloadType;
|
video_config.red_payload_type = kRedPayloadType;
|
||||||
if (!GetParam().deferred_fec) {
|
|
||||||
video_config.fec_generator = &ulpfec_generator;
|
|
||||||
}
|
|
||||||
video_config.fec_type = ulpfec_generator.GetFecType();
|
video_config.fec_type = ulpfec_generator.GetFecType();
|
||||||
video_config.fec_overhead_bytes = ulpfec_generator.MaxPacketOverhead();
|
video_config.fec_overhead_bytes = ulpfec_generator.MaxPacketOverhead();
|
||||||
RTPSenderVideo rtp_sender_video(video_config);
|
RTPSenderVideo rtp_sender_video(video_config);
|
||||||
|
@ -1989,11 +1954,7 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacksUlpfec) {
|
||||||
fec_params.fec_mask_type = kFecMaskRandom;
|
fec_params.fec_mask_type = kFecMaskRandom;
|
||||||
fec_params.fec_rate = 1;
|
fec_params.fec_rate = 1;
|
||||||
fec_params.max_fec_frames = 1;
|
fec_params.max_fec_frames = 1;
|
||||||
if (GetParam().deferred_fec) {
|
rtp_egress()->SetFecProtectionParameters(fec_params, fec_params);
|
||||||
rtp_egress()->SetFecProtectionParameters(fec_params, fec_params);
|
|
||||||
} else {
|
|
||||||
ulpfec_generator.SetProtectionParameters(fec_params, fec_params);
|
|
||||||
}
|
|
||||||
video_header.frame_type = VideoFrameType::kVideoFrameDelta;
|
video_header.frame_type = VideoFrameType::kVideoFrameDelta;
|
||||||
ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
|
ASSERT_TRUE(rtp_sender_video.SendVideo(kPayloadType, kCodecType, 1234, 4321,
|
||||||
payload, video_header,
|
payload, video_header,
|
||||||
|
@ -2823,11 +2784,6 @@ TEST_P(RtpSenderTest, IgnoresNackAfterDisablingMedia) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTest, DoesntFecProtectRetransmissions) {
|
TEST_P(RtpSenderTest, DoesntFecProtectRetransmissions) {
|
||||||
if (!GetParam().deferred_fec) {
|
|
||||||
// This test make sense only for deferred fec generation.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up retranmission without RTX, so that a plain copy of the old packet is
|
// Set up retranmission without RTX, so that a plain copy of the old packet is
|
||||||
// re-sent instead.
|
// re-sent instead.
|
||||||
const int64_t kRtt = 10;
|
const int64_t kRtt = 10;
|
||||||
|
@ -2864,16 +2820,12 @@ TEST_P(RtpSenderTest, DoesntFecProtectRetransmissions) {
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
|
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
|
||||||
RtpSenderTest,
|
RtpSenderTest,
|
||||||
::testing::Values(TestConfig{false, false},
|
::testing::Values(TestConfig{false},
|
||||||
TestConfig{false, true},
|
TestConfig{true}));
|
||||||
TestConfig{true, false},
|
|
||||||
TestConfig{false, false}));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
|
INSTANTIATE_TEST_SUITE_P(WithAndWithoutOverhead,
|
||||||
RtpSenderTestWithoutPacer,
|
RtpSenderTestWithoutPacer,
|
||||||
::testing::Values(TestConfig{false, false},
|
::testing::Values(TestConfig{false},
|
||||||
TestConfig{false, true},
|
TestConfig{true}));
|
||||||
TestConfig{true, false},
|
|
||||||
TestConfig{false, false}));
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -144,10 +144,8 @@ RTPSenderVideo::RTPSenderVideo(const Config& config)
|
||||||
playout_delay_pending_(false),
|
playout_delay_pending_(false),
|
||||||
forced_playout_delay_(LoadVideoPlayoutDelayOverride(config.field_trials)),
|
forced_playout_delay_(LoadVideoPlayoutDelayOverride(config.field_trials)),
|
||||||
red_payload_type_(config.red_payload_type),
|
red_payload_type_(config.red_payload_type),
|
||||||
fec_generator_(config.fec_generator),
|
|
||||||
fec_type_(config.fec_type),
|
fec_type_(config.fec_type),
|
||||||
fec_overhead_bytes_(config.fec_overhead_bytes),
|
fec_overhead_bytes_(config.fec_overhead_bytes),
|
||||||
video_bitrate_(1000, RateStatistics::kBpsScale),
|
|
||||||
packetization_overhead_bitrate_(1000, RateStatistics::kBpsScale),
|
packetization_overhead_bitrate_(1000, RateStatistics::kBpsScale),
|
||||||
frame_encryptor_(config.frame_encryptor),
|
frame_encryptor_(config.frame_encryptor),
|
||||||
require_frame_encryption_(config.require_frame_encryption),
|
require_frame_encryption_(config.require_frame_encryption),
|
||||||
|
@ -179,27 +177,11 @@ RTPSenderVideo::~RTPSenderVideo() {
|
||||||
void RTPSenderVideo::LogAndSendToNetwork(
|
void RTPSenderVideo::LogAndSendToNetwork(
|
||||||
std::vector<std::unique_ptr<RtpPacketToSend>> packets,
|
std::vector<std::unique_ptr<RtpPacketToSend>> packets,
|
||||||
size_t unpacketized_payload_size) {
|
size_t unpacketized_payload_size) {
|
||||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
||||||
#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
|
|
||||||
if (fec_generator_) {
|
|
||||||
uint32_t fec_rate_kbps = fec_generator_->CurrentFecRate().kbps();
|
|
||||||
for (const auto& packet : packets) {
|
|
||||||
if (packet->packet_type() ==
|
|
||||||
RtpPacketMediaType::kForwardErrorCorrection) {
|
|
||||||
const uint32_t ssrc = packet->Ssrc();
|
|
||||||
BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "VideoFecBitrate_kbps", now_ms,
|
|
||||||
fec_rate_kbps, ssrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexLock lock(&stats_mutex_);
|
MutexLock lock(&stats_mutex_);
|
||||||
size_t packetized_payload_size = 0;
|
size_t packetized_payload_size = 0;
|
||||||
for (const auto& packet : packets) {
|
for (const auto& packet : packets) {
|
||||||
if (*packet->packet_type() == RtpPacketMediaType::kVideo) {
|
if (*packet->packet_type() == RtpPacketMediaType::kVideo) {
|
||||||
video_bitrate_.Update(packet->size(), now_ms);
|
|
||||||
packetized_payload_size += packet->payload_size();
|
packetized_payload_size += packet->payload_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,9 +431,15 @@ bool RTPSenderVideo::SendVideo(
|
||||||
video_header.generic->frame_id, video_header.generic->chain_diffs);
|
video_header.generic->frame_id, video_header.generic->chain_diffs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t temporal_id = GetTemporalId(video_header);
|
||||||
|
// No FEC protection for upper temporal layers, if used.
|
||||||
|
const bool use_fec = fec_type_.has_value() &&
|
||||||
|
(temporal_id == 0 || temporal_id == kNoTemporalIdx);
|
||||||
|
|
||||||
// Maximum size of packet including rtp headers.
|
// Maximum size of packet including rtp headers.
|
||||||
// Extra space left in case packet will be resent using fec or rtx.
|
// Extra space left in case packet will be resent using fec or rtx.
|
||||||
int packet_capacity = rtp_sender_->MaxRtpPacketSize() - FecPacketOverhead() -
|
int packet_capacity = rtp_sender_->MaxRtpPacketSize() -
|
||||||
|
(use_fec ? FecPacketOverhead() : 0) -
|
||||||
(rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0);
|
(rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0);
|
||||||
|
|
||||||
std::unique_ptr<RtpPacketToSend> single_packet =
|
std::unique_ptr<RtpPacketToSend> single_packet =
|
||||||
|
@ -511,8 +499,8 @@ bool RTPSenderVideo::SendVideo(
|
||||||
first_packet->HasExtension<RtpGenericFrameDescriptorExtension00>() ||
|
first_packet->HasExtension<RtpGenericFrameDescriptorExtension00>() ||
|
||||||
first_packet->HasExtension<RtpDependencyDescriptorExtension>();
|
first_packet->HasExtension<RtpDependencyDescriptorExtension>();
|
||||||
|
|
||||||
// Minimization of the vp8 descriptor may erase temporal_id, so save it.
|
// Minimization of the vp8 descriptor may erase temporal_id, so use
|
||||||
const uint8_t temporal_id = GetTemporalId(video_header);
|
// |temporal_id| rather than reference |video_header| beyond this point.
|
||||||
if (has_generic_descriptor) {
|
if (has_generic_descriptor) {
|
||||||
MinimizeDescriptor(&video_header);
|
MinimizeDescriptor(&video_header);
|
||||||
}
|
}
|
||||||
|
@ -605,18 +593,11 @@ bool RTPSenderVideo::SendVideo(
|
||||||
packet->set_packetization_finish_time_ms(clock_->TimeInMilliseconds());
|
packet->set_packetization_finish_time_ms(clock_->TimeInMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
// No FEC protection for upper temporal layers, if used.
|
packet->set_fec_protect_packet(use_fec);
|
||||||
if (fec_type_.has_value() &&
|
|
||||||
(temporal_id == 0 || temporal_id == kNoTemporalIdx)) {
|
|
||||||
if (fec_generator_) {
|
|
||||||
fec_generator_->AddPacketAndGenerateFec(*packet);
|
|
||||||
} else {
|
|
||||||
// Deferred FEC generation, just mark packet.
|
|
||||||
packet->set_fec_protect_packet(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (red_enabled()) {
|
if (red_enabled()) {
|
||||||
|
// TODO(sprang): Consider packetizing directly into packets with the RED
|
||||||
|
// header already in place, to avoid this copy.
|
||||||
std::unique_ptr<RtpPacketToSend> red_packet(new RtpPacketToSend(*packet));
|
std::unique_ptr<RtpPacketToSend> red_packet(new RtpPacketToSend(*packet));
|
||||||
BuildRedPayload(*packet, red_packet.get());
|
BuildRedPayload(*packet, red_packet.get());
|
||||||
red_packet->SetPayloadType(*red_payload_type_);
|
red_packet->SetPayloadType(*red_payload_type_);
|
||||||
|
@ -643,19 +624,6 @@ bool RTPSenderVideo::SendVideo(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fec_generator_) {
|
|
||||||
// Fetch any FEC packets generated from the media frame and add them to
|
|
||||||
// the list of packets to send.
|
|
||||||
auto fec_packets = fec_generator_->GetFecPackets();
|
|
||||||
const bool generate_sequence_numbers = !fec_generator_->FecSsrc();
|
|
||||||
for (auto& fec_packet : fec_packets) {
|
|
||||||
if (generate_sequence_numbers) {
|
|
||||||
rtp_sender_->AssignSequenceNumber(fec_packet.get());
|
|
||||||
}
|
|
||||||
rtp_packets.emplace_back(std::move(fec_packet));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogAndSendToNetwork(std::move(rtp_packets), payload.size());
|
LogAndSendToNetwork(std::move(rtp_packets), payload.size());
|
||||||
|
|
||||||
// Update details about the last sent frame.
|
// Update details about the last sent frame.
|
||||||
|
@ -704,11 +672,6 @@ bool RTPSenderVideo::SendEncodedImage(
|
||||||
expected_retransmission_time_ms);
|
expected_retransmission_time_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RTPSenderVideo::VideoBitrateSent() const {
|
|
||||||
MutexLock lock(&stats_mutex_);
|
|
||||||
return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t RTPSenderVideo::PacketizationOverheadBps() const {
|
uint32_t RTPSenderVideo::PacketizationOverheadBps() const {
|
||||||
MutexLock lock(&stats_mutex_);
|
MutexLock lock(&stats_mutex_);
|
||||||
return packetization_overhead_bitrate_.Rate(clock_->TimeInMilliseconds())
|
return packetization_overhead_bitrate_.Rate(clock_->TimeInMilliseconds())
|
||||||
|
|
|
@ -70,8 +70,6 @@ class RTPSenderVideo {
|
||||||
// expected to outlive the RTPSenderVideo object they are passed to.
|
// expected to outlive the RTPSenderVideo object they are passed to.
|
||||||
Clock* clock = nullptr;
|
Clock* clock = nullptr;
|
||||||
RTPSender* rtp_sender = nullptr;
|
RTPSender* rtp_sender = nullptr;
|
||||||
FlexfecSender* flexfec_sender = nullptr;
|
|
||||||
VideoFecGenerator* fec_generator = nullptr;
|
|
||||||
// Some FEC data is duplicated here in preparation of moving FEC to
|
// Some FEC data is duplicated here in preparation of moving FEC to
|
||||||
// the egress stage.
|
// the egress stage.
|
||||||
absl::optional<VideoFecGenerator::FecType> fec_type;
|
absl::optional<VideoFecGenerator::FecType> fec_type;
|
||||||
|
@ -122,11 +120,11 @@ class RTPSenderVideo {
|
||||||
void SetVideoStructureUnderLock(
|
void SetVideoStructureUnderLock(
|
||||||
const FrameDependencyStructure* video_structure);
|
const FrameDependencyStructure* video_structure);
|
||||||
|
|
||||||
uint32_t VideoBitrateSent() const;
|
|
||||||
|
|
||||||
// Returns the current packetization overhead rate, in bps. Note that this is
|
// Returns the current packetization overhead rate, in bps. Note that this is
|
||||||
// the payload overhead, eg the VP8 payload headers, not the RTP headers
|
// the payload overhead, eg the VP8 payload headers, not the RTP headers
|
||||||
// or extension/
|
// or extension/
|
||||||
|
// TODO(sprang): Consider moving this to RtpSenderEgress so it's in the same
|
||||||
|
// place as the other rate stats.
|
||||||
uint32_t PacketizationOverheadBps() const;
|
uint32_t PacketizationOverheadBps() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -197,13 +195,10 @@ class RTPSenderVideo {
|
||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
|
|
||||||
const absl::optional<int> red_payload_type_;
|
const absl::optional<int> red_payload_type_;
|
||||||
VideoFecGenerator* const fec_generator_;
|
|
||||||
absl::optional<VideoFecGenerator::FecType> fec_type_;
|
absl::optional<VideoFecGenerator::FecType> fec_type_;
|
||||||
const size_t fec_overhead_bytes_; // Per packet max FEC overhead.
|
const size_t fec_overhead_bytes_; // Per packet max FEC overhead.
|
||||||
|
|
||||||
mutable Mutex stats_mutex_;
|
mutable Mutex stats_mutex_;
|
||||||
// Bitrate used for video payload and RTP headers.
|
|
||||||
RateStatistics video_bitrate_ RTC_GUARDED_BY(stats_mutex_);
|
|
||||||
RateStatistics packetization_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_);
|
RateStatistics packetization_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_);
|
||||||
|
|
||||||
std::map<int, TemporalLayerStats> frame_stats_by_temporal_layer_
|
std::map<int, TemporalLayerStats> frame_stats_by_temporal_layer_
|
||||||
|
|
|
@ -123,13 +123,11 @@ class TestRtpSenderVideo : public RTPSenderVideo {
|
||||||
public:
|
public:
|
||||||
TestRtpSenderVideo(Clock* clock,
|
TestRtpSenderVideo(Clock* clock,
|
||||||
RTPSender* rtp_sender,
|
RTPSender* rtp_sender,
|
||||||
FlexfecSender* flexfec_sender,
|
|
||||||
const WebRtcKeyValueConfig& field_trials)
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: RTPSenderVideo([&] {
|
: RTPSenderVideo([&] {
|
||||||
Config config;
|
Config config;
|
||||||
config.clock = clock;
|
config.clock = clock;
|
||||||
config.rtp_sender = rtp_sender;
|
config.rtp_sender = rtp_sender;
|
||||||
config.fec_generator = flexfec_sender;
|
|
||||||
config.field_trials = &field_trials;
|
config.field_trials = &field_trials;
|
||||||
return config;
|
return config;
|
||||||
}()) {}
|
}()) {}
|
||||||
|
@ -186,7 +184,6 @@ class RtpSenderVideoTest : public ::testing::TestWithParam<bool> {
|
||||||
rtp_sender_video_(
|
rtp_sender_video_(
|
||||||
std::make_unique<TestRtpSenderVideo>(&fake_clock_,
|
std::make_unique<TestRtpSenderVideo>(&fake_clock_,
|
||||||
rtp_module_->RtpSender(),
|
rtp_module_->RtpSender(),
|
||||||
nullptr,
|
|
||||||
field_trials_)) {
|
field_trials_)) {
|
||||||
rtp_module_->SetSequenceNumber(kSeqNum);
|
rtp_module_->SetSequenceNumber(kSeqNum);
|
||||||
rtp_module_->SetStartTimestamp(0);
|
rtp_module_->SetStartTimestamp(0);
|
||||||
|
@ -859,7 +856,7 @@ TEST_P(RtpSenderVideoTest, AbsoluteCaptureTime) {
|
||||||
TEST_P(RtpSenderVideoTest, AbsoluteCaptureTimeWithCaptureClockOffset) {
|
TEST_P(RtpSenderVideoTest, AbsoluteCaptureTimeWithCaptureClockOffset) {
|
||||||
field_trials_.set_include_capture_clock_offset(true);
|
field_trials_.set_include_capture_clock_offset(true);
|
||||||
rtp_sender_video_ = std::make_unique<TestRtpSenderVideo>(
|
rtp_sender_video_ = std::make_unique<TestRtpSenderVideo>(
|
||||||
&fake_clock_, rtp_module_->RtpSender(), nullptr, field_trials_);
|
&fake_clock_, rtp_module_->RtpSender(), field_trials_);
|
||||||
|
|
||||||
constexpr int64_t kAbsoluteCaptureTimestampMs = 12345678;
|
constexpr int64_t kAbsoluteCaptureTimestampMs = 12345678;
|
||||||
uint8_t kFrame[kMaxPacketLength];
|
uint8_t kFrame[kMaxPacketLength];
|
||||||
|
|
|
@ -171,25 +171,6 @@ TEST(VideoStreamTest, SendsFecWithFlexFec) {
|
||||||
EXPECT_GT(video_stats.substreams.begin()->second.rtp_stats.fec.packets, 0u);
|
EXPECT_GT(video_stats.substreams.begin()->second.rtp_stats.fec.packets, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoStreamTest, SendsFecWithDeferredFlexFec) {
|
|
||||||
ScopedFieldTrials trial("WebRTC-DeferredFecGeneration/Enabled/");
|
|
||||||
Scenario s;
|
|
||||||
auto route =
|
|
||||||
s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
|
|
||||||
{s.CreateSimulationNode([](NetworkSimulationConfig* c) {
|
|
||||||
c->loss_rate = 0.1;
|
|
||||||
c->delay = TimeDelta::Millis(100);
|
|
||||||
})},
|
|
||||||
s.CreateClient("callee", CallClientConfig()),
|
|
||||||
{s.CreateSimulationNode(NetworkSimulationConfig())});
|
|
||||||
auto video = s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
|
|
||||||
c->stream.use_flexfec = true;
|
|
||||||
});
|
|
||||||
s.RunFor(TimeDelta::Seconds(5));
|
|
||||||
VideoSendStream::Stats video_stats = video->send()->GetStats();
|
|
||||||
EXPECT_GT(video_stats.substreams.begin()->second.rtp_stats.fec.packets, 0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VideoStreamTest, ResolutionAdaptsToAvailableBandwidth) {
|
TEST(VideoStreamTest, ResolutionAdaptsToAvailableBandwidth) {
|
||||||
// Declared before scenario to avoid use after free.
|
// Declared before scenario to avoid use after free.
|
||||||
std::atomic<size_t> num_qvga_frames_(0);
|
std::atomic<size_t> num_qvga_frames_(0);
|
||||||
|
|
Loading…
Reference in a new issue