From 1acdc748ac440f6bd045ddb796e087884eccf041 Mon Sep 17 00:00:00 2001 From: Rasmus Brandt Date: Tue, 21 Jan 2020 14:50:54 +0100 Subject: [PATCH] Split up EncoderStreamFactory::CreateEncoderStreams in two. Motivation: https://google.github.io/styleguide/cppguide.html#Write_Short_Functions This is a pure clean up CL, that should have no functional implications. Bug: webrtc:11297 Change-Id: I077a8b52254a936b61d1fda94e8cfc39e8cf1294 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166883 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Rasmus Brandt Cr-Commit-Position: refs/heads/master@{#30337} --- media/engine/webrtc_video_engine.cc | 209 +++++++++++++++------------- media/engine/webrtc_video_engine.h | 13 ++ 2 files changed, 129 insertions(+), 93 deletions(-) diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index a2944d5a9a..b17938b014 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -3105,7 +3105,6 @@ std::vector EncoderStreamFactory::CreateEncoderStreams( RTC_DCHECK_GT(encoder_config.number_of_streams, 0); RTC_DCHECK_GE(encoder_config.simulcast_layers.size(), encoder_config.number_of_streams); - std::vector layers; const absl::optional experimental_min_bitrate = GetExperimentalMinVideoBitrate(encoder_config.codec_type); @@ -3114,100 +3113,22 @@ std::vector EncoderStreamFactory::CreateEncoderStreams( ((absl::EqualsIgnoreCase(codec_name_, kVp8CodecName) || absl::EqualsIgnoreCase(codec_name_, kH264CodecName)) && is_screenshare_ && conference_mode_)) { - const bool temporal_layers_supported = - absl::EqualsIgnoreCase(codec_name_, kVp8CodecName) || - absl::EqualsIgnoreCase(codec_name_, kH264CodecName); - // Use legacy simulcast screenshare if conference mode is explicitly enabled - // or use the regular simulcast configuration path which is generic. - layers = GetSimulcastConfig(encoder_config.number_of_streams, width, height, - encoder_config.bitrate_priority, max_qp_, - is_screenshare_ && conference_mode_, - temporal_layers_supported); - // Allow an experiment to override the minimum bitrate for the lowest - // spatial layer. The experiment's configuration has the lowest priority. - if (experimental_min_bitrate) { - layers[0].min_bitrate_bps = - rtc::saturated_cast(experimental_min_bitrate->bps()); - } - // Update the active simulcast layers and configured bitrates. - bool is_highest_layer_max_bitrate_configured = false; - const bool has_scale_resolution_down_by = absl::c_any_of( - encoder_config.simulcast_layers, [](const webrtc::VideoStream& layer) { - return layer.scale_resolution_down_by != -1.; - }); - const int normalized_width = - NormalizeSimulcastSize(width, encoder_config.number_of_streams); - const int normalized_height = - NormalizeSimulcastSize(height, encoder_config.number_of_streams); - for (size_t i = 0; i < layers.size(); ++i) { - layers[i].active = encoder_config.simulcast_layers[i].active; - // Update with configured num temporal layers if supported by codec. - if (encoder_config.simulcast_layers[i].num_temporal_layers && - IsTemporalLayersSupported(codec_name_)) { - layers[i].num_temporal_layers = - *encoder_config.simulcast_layers[i].num_temporal_layers; - } - if (encoder_config.simulcast_layers[i].max_framerate > 0) { - layers[i].max_framerate = - encoder_config.simulcast_layers[i].max_framerate; - } - if (has_scale_resolution_down_by) { - const double scale_resolution_down_by = std::max( - encoder_config.simulcast_layers[i].scale_resolution_down_by, 1.0); - layers[i].width = std::max( - static_cast(normalized_width / scale_resolution_down_by), - kMinLayerSize); - layers[i].height = std::max( - static_cast(normalized_height / scale_resolution_down_by), - kMinLayerSize); - } - // Update simulcast bitrates with configured min and max bitrate. - if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0) { - layers[i].min_bitrate_bps = - encoder_config.simulcast_layers[i].min_bitrate_bps; - } - if (encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { - layers[i].max_bitrate_bps = - encoder_config.simulcast_layers[i].max_bitrate_bps; - } - if (encoder_config.simulcast_layers[i].target_bitrate_bps > 0) { - layers[i].target_bitrate_bps = - encoder_config.simulcast_layers[i].target_bitrate_bps; - } - if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0 && - encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { - // Min and max bitrate are configured. - // Set target to 3/4 of the max bitrate (or to max if below min). - if (encoder_config.simulcast_layers[i].target_bitrate_bps <= 0) - layers[i].target_bitrate_bps = layers[i].max_bitrate_bps * 3 / 4; - if (layers[i].target_bitrate_bps < layers[i].min_bitrate_bps) - layers[i].target_bitrate_bps = layers[i].max_bitrate_bps; - } else if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0) { - // Only min bitrate is configured, make sure target/max are above min. - layers[i].target_bitrate_bps = - std::max(layers[i].target_bitrate_bps, layers[i].min_bitrate_bps); - layers[i].max_bitrate_bps = - std::max(layers[i].max_bitrate_bps, layers[i].min_bitrate_bps); - } else if (encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { - // Only max bitrate is configured, make sure min/target are below max. - layers[i].min_bitrate_bps = - std::min(layers[i].min_bitrate_bps, layers[i].max_bitrate_bps); - layers[i].target_bitrate_bps = - std::min(layers[i].target_bitrate_bps, layers[i].max_bitrate_bps); - } - if (i == layers.size() - 1) { - is_highest_layer_max_bitrate_configured = - encoder_config.simulcast_layers[i].max_bitrate_bps > 0; - } - } - if (!is_screenshare_ && !is_highest_layer_max_bitrate_configured) { - // No application-configured maximum for the largest layer. - // If there is bitrate leftover, give it to the largest layer. - BoostMaxSimulcastLayer(encoder_config.max_bitrate_bps, &layers); - } - return layers; + return CreateSimulcastOrConfereceModeScreenshareStreams( + width, height, encoder_config, experimental_min_bitrate); } + return CreateDefaultVideoStreams(width, height, encoder_config, + experimental_min_bitrate); +} + +std::vector +EncoderStreamFactory::CreateDefaultVideoStreams( + int width, + int height, + const webrtc::VideoEncoderConfig& encoder_config, + const absl::optional& experimental_min_bitrate) const { + std::vector layers; + // For unset max bitrates set default bitrate for non-simulcast. int max_bitrate_bps = (encoder_config.max_bitrate_bps > 0) @@ -3280,4 +3201,106 @@ std::vector EncoderStreamFactory::CreateEncoderStreams( return layers; } +std::vector +EncoderStreamFactory::CreateSimulcastOrConfereceModeScreenshareStreams( + int width, + int height, + const webrtc::VideoEncoderConfig& encoder_config, + const absl::optional& experimental_min_bitrate) const { + std::vector layers; + + const bool temporal_layers_supported = + absl::EqualsIgnoreCase(codec_name_, kVp8CodecName) || + absl::EqualsIgnoreCase(codec_name_, kH264CodecName); + // Use legacy simulcast screenshare if conference mode is explicitly enabled + // or use the regular simulcast configuration path which is generic. + layers = GetSimulcastConfig(encoder_config.number_of_streams, width, height, + encoder_config.bitrate_priority, max_qp_, + is_screenshare_ && conference_mode_, + temporal_layers_supported); + // Allow an experiment to override the minimum bitrate for the lowest + // spatial layer. The experiment's configuration has the lowest priority. + if (experimental_min_bitrate) { + layers[0].min_bitrate_bps = + rtc::saturated_cast(experimental_min_bitrate->bps()); + } + // Update the active simulcast layers and configured bitrates. + bool is_highest_layer_max_bitrate_configured = false; + const bool has_scale_resolution_down_by = absl::c_any_of( + encoder_config.simulcast_layers, [](const webrtc::VideoStream& layer) { + return layer.scale_resolution_down_by != -1.; + }); + const int normalized_width = + NormalizeSimulcastSize(width, encoder_config.number_of_streams); + const int normalized_height = + NormalizeSimulcastSize(height, encoder_config.number_of_streams); + for (size_t i = 0; i < layers.size(); ++i) { + layers[i].active = encoder_config.simulcast_layers[i].active; + // Update with configured num temporal layers if supported by codec. + if (encoder_config.simulcast_layers[i].num_temporal_layers && + IsTemporalLayersSupported(codec_name_)) { + layers[i].num_temporal_layers = + *encoder_config.simulcast_layers[i].num_temporal_layers; + } + if (encoder_config.simulcast_layers[i].max_framerate > 0) { + layers[i].max_framerate = + encoder_config.simulcast_layers[i].max_framerate; + } + if (has_scale_resolution_down_by) { + const double scale_resolution_down_by = std::max( + encoder_config.simulcast_layers[i].scale_resolution_down_by, 1.0); + layers[i].width = std::max( + static_cast(normalized_width / scale_resolution_down_by), + kMinLayerSize); + layers[i].height = std::max( + static_cast(normalized_height / scale_resolution_down_by), + kMinLayerSize); + } + // Update simulcast bitrates with configured min and max bitrate. + if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0) { + layers[i].min_bitrate_bps = + encoder_config.simulcast_layers[i].min_bitrate_bps; + } + if (encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { + layers[i].max_bitrate_bps = + encoder_config.simulcast_layers[i].max_bitrate_bps; + } + if (encoder_config.simulcast_layers[i].target_bitrate_bps > 0) { + layers[i].target_bitrate_bps = + encoder_config.simulcast_layers[i].target_bitrate_bps; + } + if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0 && + encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { + // Min and max bitrate are configured. + // Set target to 3/4 of the max bitrate (or to max if below min). + if (encoder_config.simulcast_layers[i].target_bitrate_bps <= 0) + layers[i].target_bitrate_bps = layers[i].max_bitrate_bps * 3 / 4; + if (layers[i].target_bitrate_bps < layers[i].min_bitrate_bps) + layers[i].target_bitrate_bps = layers[i].max_bitrate_bps; + } else if (encoder_config.simulcast_layers[i].min_bitrate_bps > 0) { + // Only min bitrate is configured, make sure target/max are above min. + layers[i].target_bitrate_bps = + std::max(layers[i].target_bitrate_bps, layers[i].min_bitrate_bps); + layers[i].max_bitrate_bps = + std::max(layers[i].max_bitrate_bps, layers[i].min_bitrate_bps); + } else if (encoder_config.simulcast_layers[i].max_bitrate_bps > 0) { + // Only max bitrate is configured, make sure min/target are below max. + layers[i].min_bitrate_bps = + std::min(layers[i].min_bitrate_bps, layers[i].max_bitrate_bps); + layers[i].target_bitrate_bps = + std::min(layers[i].target_bitrate_bps, layers[i].max_bitrate_bps); + } + if (i == layers.size() - 1) { + is_highest_layer_max_bitrate_configured = + encoder_config.simulcast_layers[i].max_bitrate_bps > 0; + } + } + if (!is_screenshare_ && !is_highest_layer_max_bitrate_configured) { + // No application-configured maximum for the largest layer. + // If there is bitrate leftover, give it to the largest layer. + BoostMaxSimulcastLayer(encoder_config.max_bitrate_bps, &layers); + } + return layers; +} + } // namespace cricket diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 9e0ede95a7..d5ed95b7f0 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -612,6 +612,19 @@ class EncoderStreamFactory int height, const webrtc::VideoEncoderConfig& encoder_config) override; + std::vector CreateDefaultVideoStreams( + int width, + int height, + const webrtc::VideoEncoderConfig& encoder_config, + const absl::optional& experimental_min_bitrate) const; + + std::vector + CreateSimulcastOrConfereceModeScreenshareStreams( + int width, + int height, + const webrtc::VideoEncoderConfig& encoder_config, + const absl::optional& experimental_min_bitrate) const; + const std::string codec_name_; const int max_qp_; const bool is_screenshare_;