From ef7228cfa00cd6eb72754e923b1ac7348c1dfb22 Mon Sep 17 00:00:00 2001 From: sprang Date: Wed, 5 Aug 2015 02:01:29 -0700 Subject: [PATCH] Selectable number of TL screenshare loopback test. Also contains some tweaks to make a single TL perform better. BUG= Review URL: https://codereview.webrtc.org/1242043002 Cr-Commit-Position: refs/heads/master@{#9676} --- .../codecs/vp8/screenshare_layers.cc | 23 ++++++++++-------- .../codecs/vp8/screenshare_layers_unittest.cc | 5 ++-- webrtc/video/screenshare_loopback.cc | 24 +++++++++++++++---- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc index ecaf3dd4a5..f94dd55e1c 100644 --- a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc +++ b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc @@ -132,13 +132,17 @@ bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, int target_bitrate_kbps = bitrate_kbps; if (cfg != nullptr) { - // Calculate a codec target bitrate. This may be higher than TL0, gaining - // quality at the expense of frame rate at TL0. Constraints: - // - TL0 frame rate should not be less than framerate / kMaxTL0FpsReduction. - // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate. - target_bitrate_kbps = - std::min(bitrate_kbps * kMaxTL0FpsReduction, - max_bitrate_kbps / kAcceptableTargetOvershoot); + if (number_of_temporal_layers_ > 1) { + // Calculate a codec target bitrate. This may be higher than TL0, gaining + // quality at the expense of frame rate at TL0. Constraints: + // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction. + // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate. + target_bitrate_kbps = + std::min(bitrate_kbps * kMaxTL0FpsReduction, + max_bitrate_kbps / kAcceptableTargetOvershoot); + + cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps); + } // Don't reconfigure qp limits during quality boost frames. if (layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) { @@ -152,8 +156,6 @@ bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100); layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100); } - - cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps); } int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate); @@ -169,6 +171,7 @@ void ScreenshareLayers::FrameEncoded(unsigned int size, layers_[active_layer_].state = TemporalLayer::State::kDropped; return; } + if (layers_[active_layer_].state == TemporalLayer::State::kDropped) { layers_[active_layer_].state = TemporalLayer::State::kQualityBoost; } @@ -241,7 +244,7 @@ bool ScreenshareLayers::TimeToSync(int64_t timestamp) const { } bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { - if (max_qp_ == -1) + if (max_qp_ == -1 || number_of_temporal_layers_ <= 1) return false; // If layer is in the quality boost state (following a dropped frame), update diff --git a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc index 198be2a09f..628e336568 100644 --- a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc @@ -112,15 +112,16 @@ TEST_F(ScreenshareLayerTest, 1Layer) { CodecSpecificInfoVP8 vp8_info; // One layer screenshare should not use the frame dropper as all frames will // belong to the base layer. + const int kSingleLayerFlags = 0; flags = layers_->EncodeFlags(timestamp); - EXPECT_EQ(0, flags); + EXPECT_EQ(kSingleLayerFlags, flags); layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); EXPECT_EQ(static_cast(kNoTemporalIdx), vp8_info.temporalIdx); EXPECT_FALSE(vp8_info.layerSync); EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); flags = layers_->EncodeFlags(timestamp); - EXPECT_EQ(0, flags); + EXPECT_EQ(kSingleLayerFlags, flags); timestamp += kTimestampDelta5Fps; layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); EXPECT_EQ(static_cast(kNoTemporalIdx), vp8_info.temporalIdx); diff --git a/webrtc/video/screenshare_loopback.cc b/webrtc/video/screenshare_loopback.cc index 8f0ab63da5..4a13629734 100644 --- a/webrtc/video/screenshare_loopback.cc +++ b/webrtc/video/screenshare_loopback.cc @@ -73,6 +73,11 @@ size_t MaxBitrate() { return static_cast(FLAGS_tl1_bitrate); } +DEFINE_int32(num_temporal_layers, 2, "Number of temporal layers to use."); +int NumTemporalLayers() { + return static_cast(FLAGS_num_temporal_layers); +} + DEFINE_int32(min_transmit_bitrate, 400, "Min transmit bitrate incl. padding."); int MinTransmitBitrate() { return FLAGS_min_transmit_bitrate; @@ -128,15 +133,20 @@ DEFINE_string( class ScreenshareLoopback : public test::Loopback { public: explicit ScreenshareLoopback(const Config& config) : Loopback(config) { + CHECK_GE(config.num_temporal_layers, 1u); + CHECK_LE(config.num_temporal_layers, 2u); + vp8_settings_ = VideoEncoder::GetDefaultVp8Settings(); vp8_settings_.denoisingOn = false; vp8_settings_.frameDroppingOn = false; - vp8_settings_.numberOfTemporalLayers = 2; + vp8_settings_.numberOfTemporalLayers = + static_cast(config.num_temporal_layers); vp9_settings_ = VideoEncoder::GetDefaultVp9Settings(); vp9_settings_.denoisingOn = false; vp9_settings_.frameDroppingOn = false; - vp9_settings_.numberOfTemporalLayers = 2; + vp9_settings_.numberOfTemporalLayers = + static_cast(config.num_temporal_layers); } virtual ~ScreenshareLoopback() {} @@ -146,10 +156,13 @@ class ScreenshareLoopback : public test::Loopback { VideoStream* stream = &encoder_config.streams[0]; encoder_config.content_type = VideoEncoderConfig::ContentType::kScreen; encoder_config.min_transmit_bitrate_bps = flags::MinTransmitBitrate(); + int num_temporal_layers; if (config_.codec == "VP8") { encoder_config.encoder_specific_settings = &vp8_settings_; + num_temporal_layers = vp8_settings_.numberOfTemporalLayers; } else if (config_.codec == "VP9") { encoder_config.encoder_specific_settings = &vp9_settings_; + num_temporal_layers = vp9_settings_.numberOfTemporalLayers; } else { RTC_NOTREACHED() << "Codec not supported!"; abort(); @@ -157,7 +170,10 @@ class ScreenshareLoopback : public test::Loopback { stream->temporal_layer_thresholds_bps.clear(); stream->target_bitrate_bps = static_cast(config_.start_bitrate_kbps) * 1000; - stream->temporal_layer_thresholds_bps.push_back(stream->target_bitrate_bps); + if (num_temporal_layers == 2) { + stream->temporal_layer_thresholds_bps.push_back( + stream->target_bitrate_bps); + } return encoder_config; } @@ -202,7 +218,7 @@ void Loopback() { flags::MaxBitrate(), flags::MinTransmitBitrate(), flags::Codec(), - 0, // Default number of temporal layers. + flags::NumTemporalLayers(), flags::LossPercent(), flags::LinkCapacity(), flags::QueueSize(),