Skip to content

Commit bbcc356

Browse files
uysalereCommit Bot
authored and
Commit Bot
committed
Reland of Turn off error resilience for VP9 if no spatial or temporal layers are configured and NACK is enabl… (patchset #1 id:1 of https://codereview.webrtc.org/2995173002/ )
Reason for revert: Speculative revert didn't help, see for the actual reason https://bugs.chromium.org/p/chromium/issues/detail?id=756741. Original issue's description: > Revert of Turn off error resilience for VP9 if no spatial or temporal layers are configured and NACK is enabl… (patchset #2 id:20001 of https://codereview.webrtc.org/2925253002/ ) > > Reason for revert: > Failing WebRtcVideoQualityBrowserTest.MANUAL_TestVideoQualityVp* tests. > > Mac #19383-19392 > https://build.chromium.org/p/chromium.webrtc.fyi/builders/Mac%20Tester/builds/42197 > Win8 #19383-19385 > https://build.chromium.org/p/chromium.webrtc.fyi/builders/Win8%20Tester/builds/1496 > Win7 #19383-19385 > https://build.chromium.org/p/chromium.webrtc.fyi/builders/Win7%20Tester/builds/9807 > Win10 #19383-19385 > https://build.chromium.org/p/chromium.webrtc.fyi/builders/Win10%20Tester/builds/8452 > > Original issue's description: > > Turn off error resilience for VP9 if no spatial or temporal layers are configured and NACK is enabled. > > > > Error resilience is currently always enabled for VP9 which reduces quality. > > > > Reland of https://codereview.webrtc.org/2532053002 > > > > BUG=webrtc:6783 > > > > Review-Url: https://codereview.webrtc.org/2925253002 > > Cr-Commit-Position: refs/heads/master@{#19385} > > Committed: https://chromium.googlesource.com/external/webrtc/+/6b463faccbf145b54b8fb2666bfeab868256df08 > > [email protected],[email protected] > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:6783 > > Review-Url: https://codereview.webrtc.org/2995173002 > Cr-Commit-Position: refs/heads/master@{#19399} > Committed: https://chromium.googlesource.com/external/webrtc/+/7b532db9ad08a86678c85b67179b3c444ee0a8b2 [email protected],[email protected] # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:6783 Review-Url: https://codereview.webrtc.org/3002933002 Cr-Commit-Position: refs/heads/master@{#19402}
1 parent 1ea631f commit bbcc356

File tree

2 files changed

+121
-12
lines changed

2 files changed

+121
-12
lines changed

webrtc/modules/video_coding/video_codec_initializer.cc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
#include "webrtc/system_wrappers/include/clock.h"
2323

2424
namespace webrtc {
25+
namespace {
26+
bool TemporalLayersConfigured(const std::vector<VideoStream>& streams) {
27+
for (const VideoStream& stream : streams) {
28+
if (stream.temporal_layer_thresholds_bps.size() > 0)
29+
return true;
30+
}
31+
return false;
32+
}
33+
} // namespace
2534

2635
bool VideoCodecInitializer::SetupCodec(
2736
const VideoEncoderConfig& config,
@@ -121,12 +130,8 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
121130
*video_codec.VP8() = VideoEncoder::GetDefaultVp8Settings();
122131
video_codec.VP8()->numberOfTemporalLayers = static_cast<unsigned char>(
123132
streams.back().temporal_layer_thresholds_bps.size() + 1);
124-
bool temporal_layers_configured = false;
125-
for (const VideoStream& stream : streams) {
126-
if (stream.temporal_layer_thresholds_bps.size() > 0)
127-
temporal_layers_configured = true;
128-
}
129-
if (nack_enabled && !temporal_layers_configured) {
133+
134+
if (nack_enabled && !TemporalLayersConfigured(streams)) {
130135
LOG(LS_INFO) << "No temporal layers and nack enabled -> resilience off";
131136
video_codec.VP8()->resilience = kResilienceOff;
132137
}
@@ -144,6 +149,13 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec(
144149
}
145150
video_codec.VP9()->numberOfTemporalLayers = static_cast<unsigned char>(
146151
streams.back().temporal_layer_thresholds_bps.size() + 1);
152+
153+
if (nack_enabled && !TemporalLayersConfigured(streams) &&
154+
video_codec.VP9()->numberOfSpatialLayers == 1) {
155+
LOG(LS_INFO) << "No temporal or spatial layers and nack enabled -> "
156+
<< "resilience off";
157+
video_codec.VP9()->resilienceOn = false;
158+
}
147159
break;
148160
}
149161
case kVideoCodecH264: {

webrtc/video/video_stream_encoder_unittest.cc

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace {
3232
const int kMinPixelsPerFrame = 320 * 180;
3333
const int kMinFramerateFps = 2;
3434
const int64_t kFrameTimeoutMs = 100;
35+
const unsigned char kNumSlDummy = 0;
3536
} // namespace
3637

3738
namespace webrtc {
@@ -315,6 +316,7 @@ class VideoStreamEncoderTest : public ::testing::Test {
315316
void ResetEncoder(const std::string& payload_name,
316317
size_t num_streams,
317318
size_t num_temporal_layers,
319+
unsigned char num_spatial_layers,
318320
bool nack_enabled,
319321
bool screenshare) {
320322
video_send_config_.encoder_settings.payload_name = payload_name;
@@ -328,6 +330,13 @@ class VideoStreamEncoderTest : public ::testing::Test {
328330
video_encoder_config.content_type =
329331
screenshare ? VideoEncoderConfig::ContentType::kScreen
330332
: VideoEncoderConfig::ContentType::kRealtimeVideo;
333+
if (payload_name == "VP9") {
334+
VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
335+
vp9_settings.numberOfSpatialLayers = num_spatial_layers;
336+
video_encoder_config.encoder_specific_settings =
337+
new rtc::RefCountedObject<
338+
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
339+
}
331340
ConfigureEncoder(std::move(video_encoder_config), nack_enabled);
332341
}
333342

@@ -797,7 +806,7 @@ TEST_F(VideoStreamEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
797806
const bool kNackEnabled = true;
798807
const size_t kNumStreams = 1;
799808
const size_t kNumTl = 1;
800-
ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled, false);
809+
ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled, false);
801810
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
802811

803812
// Capture a frame and wait for it to synchronize with the encoder thread.
@@ -817,7 +826,7 @@ TEST_F(VideoStreamEncoderTest, Vp8ResilienceIsOffFor2S1TlWithNackEnabled) {
817826
const bool kNackEnabled = true;
818827
const size_t kNumStreams = 2;
819828
const size_t kNumTl = 1;
820-
ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled, false);
829+
ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled, false);
821830
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
822831

823832
// Capture a frame and wait for it to synchronize with the encoder thread.
@@ -837,7 +846,7 @@ TEST_F(VideoStreamEncoderTest, Vp8ResilienceIsOnFor1S1TLWithNackDisabled) {
837846
const bool kNackEnabled = false;
838847
const size_t kNumStreams = 1;
839848
const size_t kNumTl = 1;
840-
ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled, false);
849+
ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled, false);
841850
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
842851

843852
// Capture a frame and wait for it to synchronize with the encoder thread.
@@ -857,7 +866,7 @@ TEST_F(VideoStreamEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
857866
const bool kNackEnabled = true;
858867
const size_t kNumStreams = 1;
859868
const size_t kNumTl = 2;
860-
ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled, false);
869+
ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled, false);
861870
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
862871

863872
// Capture a frame and wait for it to synchronize with the encoder thread.
@@ -873,6 +882,94 @@ TEST_F(VideoStreamEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
873882
video_stream_encoder_->Stop();
874883
}
875884

885+
TEST_F(VideoStreamEncoderTest, Vp9ResilienceIsOffFor1SL1TLWithNackEnabled) {
886+
const bool kNackEnabled = true;
887+
const size_t kNumStreams = 1;
888+
const size_t kNumTl = 1;
889+
const unsigned char kNumSl = 1;
890+
ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled, false);
891+
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
892+
893+
// Capture a frame and wait for it to synchronize with the encoder thread.
894+
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
895+
sink_.WaitForEncodedFrame(1);
896+
// The encoder have been configured once when the first frame is received.
897+
EXPECT_EQ(1, sink_.number_of_reconfigurations());
898+
EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
899+
EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
900+
EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
901+
EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
902+
// Resilience is off for no spatial and temporal layers with nack on.
903+
EXPECT_FALSE(fake_encoder_.codec_config().VP9()->resilienceOn);
904+
video_stream_encoder_->Stop();
905+
}
906+
907+
TEST_F(VideoStreamEncoderTest, Vp9ResilienceIsOnFor1SL1TLWithNackDisabled) {
908+
const bool kNackEnabled = false;
909+
const size_t kNumStreams = 1;
910+
const size_t kNumTl = 1;
911+
const unsigned char kNumSl = 1;
912+
ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled, false);
913+
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
914+
915+
// Capture a frame and wait for it to synchronize with the encoder thread.
916+
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
917+
sink_.WaitForEncodedFrame(1);
918+
// The encoder have been configured once when the first frame is received.
919+
EXPECT_EQ(1, sink_.number_of_reconfigurations());
920+
EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
921+
EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
922+
EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
923+
EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
924+
// Resilience is on if nack is off.
925+
EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
926+
video_stream_encoder_->Stop();
927+
}
928+
929+
TEST_F(VideoStreamEncoderTest, Vp9ResilienceIsOnFor2SL1TLWithNackEnabled) {
930+
const bool kNackEnabled = true;
931+
const size_t kNumStreams = 1;
932+
const size_t kNumTl = 1;
933+
const unsigned char kNumSl = 2;
934+
ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled, false);
935+
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
936+
937+
// Capture a frame and wait for it to synchronize with the encoder thread.
938+
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
939+
sink_.WaitForEncodedFrame(1);
940+
// The encoder have been configured once when the first frame is received.
941+
EXPECT_EQ(1, sink_.number_of_reconfigurations());
942+
EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
943+
EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
944+
EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
945+
EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
946+
// Resilience is on for spatial layers.
947+
EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
948+
video_stream_encoder_->Stop();
949+
}
950+
951+
TEST_F(VideoStreamEncoderTest, Vp9ResilienceIsOnFor1SL2TLWithNackEnabled) {
952+
const bool kNackEnabled = true;
953+
const size_t kNumStreams = 1;
954+
const size_t kNumTl = 2;
955+
const unsigned char kNumSl = 1;
956+
ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled, false);
957+
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
958+
959+
// Capture a frame and wait for it to synchronize with the encoder thread.
960+
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
961+
sink_.WaitForEncodedFrame(1);
962+
// The encoder have been configured once when the first frame is received.
963+
EXPECT_EQ(1, sink_.number_of_reconfigurations());
964+
EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
965+
EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
966+
EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
967+
EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
968+
// Resilience is on for temporal layers.
969+
EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
970+
video_stream_encoder_->Stop();
971+
}
972+
876973
TEST_F(VideoStreamEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
877974
EXPECT_TRUE(video_source_.has_sinks());
878975
test::FrameForwarder new_video_source;
@@ -2461,7 +2558,7 @@ TEST_F(VideoStreamEncoderTest,
24612558
TEST_F(VideoStreamEncoderTest, FailingInitEncodeDoesntCauseCrash) {
24622559
fake_encoder_.ForceInitEncodeFailure(true);
24632560
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
2464-
ResetEncoder("VP8", 2, 1, true, false);
2561+
ResetEncoder("VP8", 2, 1, 1, true, false);
24652562
const int kFrameWidth = 1280;
24662563
const int kFrameHeight = 720;
24672564
video_source_.IncomingCapturedFrame(
@@ -2608,7 +2705,7 @@ TEST_F(VideoStreamEncoderTest, DoesntAdaptDownPastMinFramerate) {
26082705

26092706
// Reconfigure encoder with two temporal layers and screensharing, which will
26102707
// disable frame dropping and make testing easier.
2611-
ResetEncoder("VP8", 1, 2, true, true);
2708+
ResetEncoder("VP8", 1, 2, 1, true, true);
26122709

26132710
video_stream_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
26142711
video_stream_encoder_->SetSource(

0 commit comments

Comments
 (0)