diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h index 9d54256b6b..1401c2bdf4 100644 --- a/api/video_codecs/video_encoder.h +++ b/api/video_codecs/video_encoder.h @@ -330,6 +330,9 @@ class RTC_EXPORT VideoEncoder { Capabilities capabilities; int number_of_cores; size_t max_payload_size; + // Experimental API - currently only supported by LibvpxVp8Encoder. + // If set, limits the number of encoder threads. + absl::optional encoder_thread_limit; }; static VideoCodecVP8 GetDefaultVp8Settings(); diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index e29dce7b60..20bfc65dff 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -609,6 +609,12 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, // TODO(fbarchard): Consider number of Simulcast layers. vpx_configs_[0].g_threads = NumberOfThreads( vpx_configs_[0].g_w, vpx_configs_[0].g_h, settings.number_of_cores); + if (settings.encoder_thread_limit.has_value()) { + RTC_DCHECK_GE(settings.encoder_thread_limit.value(), 1); + vpx_configs_[0].g_threads = std::min( + vpx_configs_[0].g_threads, + static_cast(settings.encoder_thread_limit.value())); + } // Creating a wrapper to the image - setting image data to NULL. // Actual pointer will be set in encode. Setting align to 1, as it diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 176b3a1992..e5d6df396d 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -526,6 +526,13 @@ absl::optional ParseVp9LowTierCoreCountThreshold( return max_core_count.Get(); } +absl::optional ParseEncoderThreadLimit(const FieldTrialsView& trials) { + FieldTrialOptional encoder_thread_limit("encoder_thread_limit"); + ParseFieldTrial({&encoder_thread_limit}, + trials.Lookup("WebRTC-VideoEncoderSettings")); + return encoder_thread_limit.GetOptional(); +} + absl::optional MergeRestrictions( const std::vector>& list) { absl::optional return_value; @@ -718,6 +725,7 @@ VideoStreamEncoder::VideoStreamEncoder( kSwitchEncoderOnInitializationFailuresFieldTrial)), vp9_low_tier_core_threshold_( ParseVp9LowTierCoreCountThreshold(field_trials)), + experimental_encoder_thread_limit_(ParseEncoderThreadLimit(field_trials)), encoder_queue_(std::move(encoder_queue)) { TRACE_EVENT0("webrtc", "VideoStreamEncoder::VideoStreamEncoder"); RTC_DCHECK_RUN_ON(worker_queue_); @@ -1274,10 +1282,10 @@ void VideoStreamEncoder::ReconfigureEncoder() { const size_t max_data_payload_length = max_data_payload_length_ > 0 ? max_data_payload_length_ : kDefaultPayloadSize; - if (encoder_->InitEncode( - &send_codec_, - VideoEncoder::Settings(settings_.capabilities, number_of_cores_, - max_data_payload_length)) != 0) { + VideoEncoder::Settings settings = VideoEncoder::Settings( + settings_.capabilities, number_of_cores_, max_data_payload_length); + settings.encoder_thread_limit = experimental_encoder_thread_limit_; + if (encoder_->InitEncode(&send_codec_, settings) != 0) { RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with " "codec type: " << CodecTypeToPayloadString(send_codec_.codecType) diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h index ccff3ffefd..7724026b5f 100644 --- a/video/video_stream_encoder.h +++ b/video/video_stream_encoder.h @@ -463,6 +463,7 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, bool switch_encoder_on_init_failures_; const absl::optional vp9_low_tier_core_threshold_; + const absl::optional experimental_encoder_thread_limit_; // These are copies of restrictions (glorified max_pixel_count) set by // a) OnVideoSourceRestrictionsUpdated