Index: webrtc/media/engine/webrtcvideoengine2.cc |
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc |
index 3a3961c3980ef312d1af1ba26afb4a4ffa72875f..5176c115b70d8224978abad1c1555e327c9e39e6 100644 |
--- a/webrtc/media/engine/webrtcvideoengine2.cc |
+++ b/webrtc/media/engine/webrtcvideoengine2.cc |
@@ -14,7 +14,6 @@ |
#include <algorithm> |
#include <set> |
#include <string> |
-#include <utility> |
#include "webrtc/base/copyonwritebuffer.h" |
#include "webrtc/base/logging.h" |
@@ -323,83 +322,12 @@ |
} |
return 1; |
} |
- |
-class EncoderStreamFactory |
- : public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface { |
- public: |
- EncoderStreamFactory(std::string codec_name, |
- int max_qp, |
- int max_framerate, |
- bool is_screencast, |
- bool conference_mode) |
- : codec_name_(codec_name), |
- max_qp_(max_qp), |
- max_framerate_(max_framerate), |
- is_screencast_(is_screencast), |
- conference_mode_(conference_mode) {} |
- |
- private: |
- std::vector<webrtc::VideoStream> CreateEncoderStreams( |
- int width, |
- int height, |
- const webrtc::VideoEncoderConfig& encoder_config) override { |
- RTC_DCHECK(encoder_config.number_of_streams > 1 ? !is_screencast_ : true); |
- if (encoder_config.number_of_streams > 1) { |
- return GetSimulcastConfig(encoder_config.number_of_streams, width, height, |
- encoder_config.max_bitrate_bps, max_qp_, |
- max_framerate_); |
- } |
- |
- // For unset max bitrates set default bitrate for non-simulcast. |
- int max_bitrate_bps = |
- (encoder_config.max_bitrate_bps > 0) |
- ? encoder_config.max_bitrate_bps |
- : GetMaxDefaultVideoBitrateKbps(width, height) * 1000; |
- |
- webrtc::VideoStream stream; |
- stream.width = width; |
- stream.height = height; |
- stream.max_framerate = max_framerate_; |
- stream.min_bitrate_bps = kMinVideoBitrateKbps * 1000; |
- stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; |
- stream.max_qp = max_qp_; |
- |
- // Conference mode screencast uses 2 temporal layers split at 100kbit. |
- if (conference_mode_ && is_screencast_) { |
- ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); |
- // For screenshare in conference mode, tl0 and tl1 bitrates are |
- // piggybacked |
- // on the VideoCodec struct as target and max bitrates, respectively. |
- // See eg. webrtc::VP8EncoderImpl::SetRates(). |
- stream.target_bitrate_bps = config.tl0_bitrate_kbps * 1000; |
- stream.max_bitrate_bps = config.tl1_bitrate_kbps * 1000; |
- stream.temporal_layer_thresholds_bps.clear(); |
- stream.temporal_layer_thresholds_bps.push_back(config.tl0_bitrate_kbps * |
- 1000); |
- } |
- |
- if (CodecNamesEq(codec_name_, kVp9CodecName) && !is_screencast_) { |
- stream.temporal_layer_thresholds_bps.resize( |
- GetDefaultVp9TemporalLayers() - 1); |
- } |
- |
- std::vector<webrtc::VideoStream> streams; |
- streams.push_back(stream); |
- return streams; |
- } |
- |
- const std::string codec_name_; |
- const int max_qp_; |
- const int max_framerate_; |
- const bool is_screencast_; |
- const bool conference_mode_; |
-}; |
- |
} // namespace |
// Constants defined in webrtc/media/engine/constants.h |
// TODO(pbos): Move these to a separate constants.cc file. |
-const int kMinVideoBitrateKbps = 30; |
+const int kMinVideoBitrate = 30; |
+const int kStartVideoBitrate = 300; |
const int kVideoMtu = 1200; |
const int kVideoRtpBufferSize = 65536; |
@@ -470,10 +398,61 @@ |
return codecs; |
} |
+std::vector<webrtc::VideoStream> |
+WebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( |
+ const VideoCodec& codec, |
+ const VideoOptions& options, |
+ int max_bitrate_bps, |
+ size_t num_streams) { |
+ int max_qp = kDefaultQpMax; |
+ codec.GetParam(kCodecParamMaxQuantization, &max_qp); |
+ |
+ return GetSimulcastConfig( |
+ num_streams, codec.width, codec.height, max_bitrate_bps, max_qp, |
+ codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); |
+} |
+ |
+std::vector<webrtc::VideoStream> |
+WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( |
+ const VideoCodec& codec, |
+ const VideoOptions& options, |
+ int max_bitrate_bps, |
+ size_t num_streams) { |
+ int codec_max_bitrate_kbps; |
+ if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { |
+ max_bitrate_bps = codec_max_bitrate_kbps * 1000; |
+ } |
+ if (num_streams != 1) { |
+ return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps, |
+ num_streams); |
+ } |
+ |
+ // For unset max bitrates set default bitrate for non-simulcast. |
+ if (max_bitrate_bps <= 0) { |
+ max_bitrate_bps = |
+ GetMaxDefaultVideoBitrateKbps(codec.width, codec.height) * 1000; |
+ } |
+ |
+ webrtc::VideoStream stream; |
+ stream.width = codec.width; |
+ stream.height = codec.height; |
+ stream.max_framerate = |
+ codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; |
+ |
+ stream.min_bitrate_bps = kMinVideoBitrate * 1000; |
+ stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; |
+ |
+ int max_qp = kDefaultQpMax; |
+ codec.GetParam(kCodecParamMaxQuantization, &max_qp); |
+ stream.max_qp = max_qp; |
+ std::vector<webrtc::VideoStream> streams; |
+ streams.push_back(stream); |
+ return streams; |
+} |
+ |
rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> |
WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( |
const VideoCodec& codec) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
bool is_screencast = parameters_.options.is_screencast.value_or(false); |
// No automatic resizing when using simulcast or screencast. |
bool automatic_resize = |
@@ -1564,7 +1543,6 @@ |
: config(std::move(config)), |
options(options), |
max_bitrate_bps(max_bitrate_bps), |
- conference_mode(false), |
codec_settings(codec_settings) {} |
WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( |
@@ -1609,6 +1587,7 @@ |
encoder_sink_(nullptr), |
parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
+ pending_encoder_reconfiguration_(false), |
allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), |
sending_(false), |
last_frame_timestamp_us_(0) { |
@@ -1676,6 +1655,7 @@ |
last_frame_info_.height = video_frame.height(); |
last_frame_info_.rotation = video_frame.rotation(); |
last_frame_info_.is_texture = video_frame.is_texture(); |
+ pending_encoder_reconfiguration_ = true; |
LOG(LS_INFO) << "Video frame parameters changed: dimensions=" |
<< last_frame_info_.width << "x" << last_frame_info_.height |
@@ -1690,13 +1670,22 @@ |
last_frame_timestamp_us_ = video_frame.timestamp_us(); |
+ if (pending_encoder_reconfiguration_) { |
+ ReconfigureEncoder(); |
+ pending_encoder_reconfiguration_ = false; |
+ } |
+ |
+ // Not sending, abort after reconfiguration. Reconfiguration should still |
+ // occur to permit sending this input as quickly as possible once we start |
+ // sending (without having to reconfigure then). |
+ if (!sending_) { |
+ return; |
+ } |
+ |
++frame_count_; |
if (cpu_restricted_counter_ > 0) |
++cpu_restricted_frame_count_; |
- // Forward frame to the encoder regardless if we are sending or not. This is |
- // to ensure that the encoder can be reconfigured with the correct frame size |
- // as quickly as possible. |
encoder_sink_->OnFrame(video_frame); |
} |
@@ -1705,7 +1694,7 @@ |
const VideoOptions* options, |
rtc::VideoSourceInterface<cricket::VideoFrame>* source) { |
TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
// Ignore |options| pointer if |enable| is false. |
bool options_present = enable && options; |
@@ -1714,47 +1703,50 @@ |
DisconnectSource(); |
} |
- if (options_present) { |
- VideoOptions old_options = parameters_.options; |
- parameters_.options.SetAll(*options); |
- // If options has changed and SetCodec has been called. |
- if (parameters_.options != old_options && stream_) { |
- ReconfigureEncoder(); |
- } |
- } |
- |
- if (source_changing) { |
+ if (options_present || source_changing) { |
rtc::CritScope cs(&lock_); |
- if (source == nullptr && encoder_sink_ != nullptr && |
- last_frame_info_.width > 0) { |
- LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; |
- // Force this black frame not to be dropped due to timestamp order |
- // check. As IncomingCapturedFrame will drop the frame if this frame's |
- // timestamp is less than or equal to last frame's timestamp, it is |
- // necessary to give this black frame a larger timestamp than the |
- // previous one. |
- last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; |
- rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( |
- webrtc::I420Buffer::Create(last_frame_info_.width, |
- last_frame_info_.height)); |
- black_buffer->SetToBlack(); |
- |
- encoder_sink_->OnFrame(webrtc::VideoFrame( |
- black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); |
- } |
- source_ = source; |
- } |
- |
+ |
+ if (options_present) { |
+ VideoOptions old_options = parameters_.options; |
+ parameters_.options.SetAll(*options); |
+ // Reconfigure encoder settings on the next frame or stream |
+ // recreation if the options changed. |
+ if (parameters_.options != old_options) { |
+ pending_encoder_reconfiguration_ = true; |
+ } |
+ } |
+ |
+ if (source_changing) { |
+ if (source == nullptr && encoder_sink_ != nullptr) { |
+ LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; |
+ // Force this black frame not to be dropped due to timestamp order |
+ // check. As IncomingCapturedFrame will drop the frame if this frame's |
+ // timestamp is less than or equal to last frame's timestamp, it is |
+ // necessary to give this black frame a larger timestamp than the |
+ // previous one. |
+ last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; |
+ rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( |
+ webrtc::I420Buffer::Create(last_frame_info_.width, |
+ last_frame_info_.height)); |
+ black_buffer->SetToBlack(); |
+ |
+ encoder_sink_->OnFrame(webrtc::VideoFrame( |
+ black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); |
+ } |
+ source_ = source; |
+ } |
+ } |
+ |
+ // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
+ // that might cause a lock order inversion. |
if (source_changing && source_) { |
- // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
- // that might cause a lock order inversion. |
source_->AddOrUpdateSink(this, sink_wants_); |
} |
return true; |
} |
void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
if (source_ == nullptr) { |
return; |
} |
@@ -1789,7 +1781,6 @@ |
WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder |
WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( |
const VideoCodec& codec) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
webrtc::VideoCodecType type = CodecTypeFromName(codec.name); |
// Do not re-create encoders of the same type. |
@@ -1824,7 +1815,6 @@ |
void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( |
AllocatedEncoder* encoder) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
if (encoder->external) { |
external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); |
} |
@@ -1833,9 +1823,8 @@ |
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( |
const VideoCodecSettings& codec_settings) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); |
- RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u); |
+ RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); |
parameters_.config.encoder_settings.encoder = new_encoder.encoder; |
@@ -1876,38 +1865,41 @@ |
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( |
const ChangedSendParameters& params) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
- // |recreate_stream| means construction-time parameters have changed and the |
- // sending stream needs to be reset with the new config. |
- bool recreate_stream = false; |
- if (params.rtcp_mode) { |
- parameters_.config.rtp.rtcp_mode = *params.rtcp_mode; |
- recreate_stream = true; |
- } |
- if (params.rtp_header_extensions) { |
- parameters_.config.rtp.extensions = *params.rtp_header_extensions; |
- recreate_stream = true; |
- } |
- if (params.max_bandwidth_bps) { |
- parameters_.max_bitrate_bps = *params.max_bandwidth_bps; |
- ReconfigureEncoder(); |
- } |
- if (params.conference_mode) { |
- parameters_.conference_mode = *params.conference_mode; |
- } |
- |
- // Set codecs and options. |
- if (params.codec) { |
- SetCodec(*params.codec); |
- recreate_stream = false; // SetCodec has already recreated the stream. |
- } else if (params.conference_mode && parameters_.codec_settings) { |
- SetCodec(*parameters_.codec_settings); |
- recreate_stream = false; // SetCodec has already recreated the stream. |
- } |
- if (recreate_stream) { |
- LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; |
- RecreateWebRtcStream(); |
- } |
+ { |
+ rtc::CritScope cs(&lock_); |
+ // |recreate_stream| means construction-time parameters have changed and the |
+ // sending stream needs to be reset with the new config. |
+ bool recreate_stream = false; |
+ if (params.rtcp_mode) { |
+ parameters_.config.rtp.rtcp_mode = *params.rtcp_mode; |
+ recreate_stream = true; |
+ } |
+ if (params.rtp_header_extensions) { |
+ parameters_.config.rtp.extensions = *params.rtp_header_extensions; |
+ recreate_stream = true; |
+ } |
+ if (params.max_bandwidth_bps) { |
+ parameters_.max_bitrate_bps = *params.max_bandwidth_bps; |
+ pending_encoder_reconfiguration_ = true; |
+ } |
+ if (params.conference_mode) { |
+ parameters_.conference_mode = *params.conference_mode; |
+ } |
+ |
+ // Set codecs and options. |
+ if (params.codec) { |
+ SetCodec(*params.codec); |
+ recreate_stream = false; // SetCodec has already recreated the stream. |
+ } else if (params.conference_mode && parameters_.codec_settings) { |
+ SetCodec(*parameters_.codec_settings); |
+ recreate_stream = false; // SetCodec has already recreated the stream. |
+ } |
+ if (recreate_stream) { |
+ LOG(LS_INFO) |
+ << "RecreateWebRtcStream (send) because of SetSendParameters"; |
+ RecreateWebRtcStream(); |
+ } |
+ } // release |lock_| |
// |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
// that might cause a lock order inversion. |
@@ -1922,19 +1914,18 @@ |
bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( |
const webrtc::RtpParameters& new_parameters) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
if (!ValidateRtpParameters(new_parameters)) { |
return false; |
} |
- bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps != |
- rtp_parameters_.encodings[0].max_bitrate_bps; |
+ rtc::CritScope cs(&lock_); |
+ if (new_parameters.encodings[0].max_bitrate_bps != |
+ rtp_parameters_.encodings[0].max_bitrate_bps) { |
+ pending_encoder_reconfiguration_ = true; |
+ } |
rtp_parameters_ = new_parameters; |
// Codecs are currently handled at the WebRtcVideoChannel2 level. |
rtp_parameters_.codecs.clear(); |
- if (reconfigure_encoder) { |
- ReconfigureEncoder(); |
- } |
// Encoding may have been activated/deactivated. |
UpdateSendState(); |
return true; |
@@ -1942,7 +1933,7 @@ |
webrtc::RtpParameters |
WebRtcVideoChannel2::WebRtcVideoSendStream::GetRtpParameters() const { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ rtc::CritScope cs(&lock_); |
return rtp_parameters_; |
} |
@@ -1957,7 +1948,6 @@ |
} |
void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateSendState() { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
// TODO(deadbeef): Need to handle more than one encoding in the future. |
RTC_DCHECK(rtp_parameters_.encodings.size() == 1u); |
if (sending_ && rtp_parameters_.encodings[0].active) { |
@@ -1973,7 +1963,6 @@ |
webrtc::VideoEncoderConfig |
WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( |
const VideoCodec& codec) const { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
webrtc::VideoEncoderConfig encoder_config; |
bool is_screencast = parameters_.options.is_screencast.value_or(false); |
if (is_screencast) { |
@@ -1987,39 +1976,60 @@ |
webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; |
} |
+ // Restrict dimensions according to codec max. |
+ int width = last_frame_info_.width; |
+ int height = last_frame_info_.height; |
+ if (!is_screencast) { |
+ if (codec.width < width) |
+ width = codec.width; |
+ if (codec.height < height) |
+ height = codec.height; |
+ } |
+ |
+ VideoCodec clamped_codec = codec; |
+ clamped_codec.width = width; |
+ clamped_codec.height = height; |
+ |
// By default, the stream count for the codec configuration should match the |
// number of negotiated ssrcs. But if the codec is blacklisted for simulcast |
// or a screencast, only configure a single stream. |
- encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size(); |
+ size_t stream_count = parameters_.config.rtp.ssrcs.size(); |
if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) { |
- encoder_config.number_of_streams = 1; |
+ stream_count = 1; |
} |
int stream_max_bitrate = |
MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps, |
parameters_.max_bitrate_bps); |
- |
- int codec_max_bitrate_kbps; |
- if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { |
- stream_max_bitrate = codec_max_bitrate_kbps * 1000; |
- } |
- encoder_config.max_bitrate_bps = stream_max_bitrate; |
- |
- int max_qp = kDefaultQpMax; |
- codec.GetParam(kCodecParamMaxQuantization, &max_qp); |
- int max_framerate = |
- codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; |
- |
- encoder_config.video_stream_factory = |
- new rtc::RefCountedObject<EncoderStreamFactory>( |
- codec.name, max_qp, max_framerate, is_screencast, |
- parameters_.conference_mode); |
+ encoder_config.streams = CreateVideoStreams( |
+ clamped_codec, parameters_.options, stream_max_bitrate, stream_count); |
+ encoder_config.expect_encode_from_texture = last_frame_info_.is_texture; |
+ |
+ // Conference mode screencast uses 2 temporal layers split at 100kbit. |
+ if (parameters_.conference_mode && is_screencast && |
+ encoder_config.streams.size() == 1) { |
+ ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); |
+ |
+ // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked |
+ // on the VideoCodec struct as target and max bitrates, respectively. |
+ // See eg. webrtc::VP8EncoderImpl::SetRates(). |
+ encoder_config.streams[0].target_bitrate_bps = |
+ config.tl0_bitrate_kbps * 1000; |
+ encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; |
+ encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); |
+ encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( |
+ config.tl0_bitrate_kbps * 1000); |
+ } |
+ if (CodecNamesEq(codec.name, kVp9CodecName) && !is_screencast && |
+ encoder_config.streams.size() == 1) { |
+ encoder_config.streams[0].temporal_layer_thresholds_bps.resize( |
+ GetDefaultVp9TemporalLayers() - 1); |
+ } |
return encoder_config; |
} |
void WebRtcVideoChannel2::WebRtcVideoSendStream::ReconfigureEncoder() { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
- RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u); |
+ RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
RTC_CHECK(parameters_.codec_settings); |
VideoCodecSettings codec_settings = *parameters_.codec_settings; |
@@ -2038,7 +2048,7 @@ |
} |
void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ rtc::CritScope cs(&lock_); |
sending_ = send; |
UpdateSendState(); |
} |
@@ -2068,62 +2078,63 @@ |
this, load)); |
return; |
} |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
if (!source_) { |
return; |
} |
- |
- LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " |
- << (parameters_.options.is_screencast |
- ? (*parameters_.options.is_screencast ? "true" : "false") |
- : "unset"); |
- // Do not adapt resolution for screen content as this will likely result in |
- // blurry and unreadable text. |
- if (parameters_.options.is_screencast.value_or(false)) |
- return; |
- |
- rtc::Optional<int> max_pixel_count; |
- rtc::Optional<int> max_pixel_count_step_up; |
- if (load == kOveruse) { |
+ { |
rtc::CritScope cs(&lock_); |
- if (cpu_restricted_counter_ >= kMaxCpuDowngrades) { |
+ LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " |
+ << (parameters_.options.is_screencast |
+ ? (*parameters_.options.is_screencast ? "true" |
+ : "false") |
+ : "unset"); |
+ // Do not adapt resolution for screen content as this will likely result in |
+ // blurry and unreadable text. |
+ if (parameters_.options.is_screencast.value_or(false)) |
return; |
- } |
- // The input video frame size will have a resolution with less than or |
- // equal to |max_pixel_count| depending on how the source can scale the |
- // input frame size. |
- max_pixel_count = rtc::Optional<int>( |
- (last_frame_info_.height * last_frame_info_.width * 3) / 5); |
- // Increase |number_of_cpu_adapt_changes_| if |
- // sink_wants_.max_pixel_count will be changed since |
- // last time |source_->AddOrUpdateSink| was called. That is, this will |
- // result in a new request for the source to change resolution. |
- if (!sink_wants_.max_pixel_count || |
- *sink_wants_.max_pixel_count > *max_pixel_count) { |
- ++number_of_cpu_adapt_changes_; |
- ++cpu_restricted_counter_; |
- } |
- } else { |
- RTC_DCHECK(load == kUnderuse); |
- rtc::CritScope cs(&lock_); |
- // The input video frame size will have a resolution with "one step up" |
- // pixels than |max_pixel_count_step_up| where "one step up" depends on |
- // how the source can scale the input frame size. |
- max_pixel_count_step_up = |
- rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width); |
- // Increase |number_of_cpu_adapt_changes_| if |
- // sink_wants_.max_pixel_count_step_up will be changed since |
- // last time |source_->AddOrUpdateSink| was called. That is, this will |
- // result in a new request for the source to change resolution. |
- if (sink_wants_.max_pixel_count || |
- (sink_wants_.max_pixel_count_step_up && |
- *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) { |
- ++number_of_cpu_adapt_changes_; |
- --cpu_restricted_counter_; |
- } |
- } |
- sink_wants_.max_pixel_count = max_pixel_count; |
- sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up; |
+ |
+ rtc::Optional<int> max_pixel_count; |
+ rtc::Optional<int> max_pixel_count_step_up; |
+ if (load == kOveruse) { |
+ if (cpu_restricted_counter_ >= kMaxCpuDowngrades) { |
+ return; |
+ } |
+ // The input video frame size will have a resolution with less than or |
+ // equal to |max_pixel_count| depending on how the source can scale the |
+ // input frame size. |
+ max_pixel_count = rtc::Optional<int>( |
+ (last_frame_info_.height * last_frame_info_.width * 3) / 5); |
+ // Increase |number_of_cpu_adapt_changes_| if |
+ // sink_wants_.max_pixel_count will be changed since |
+ // last time |source_->AddOrUpdateSink| was called. That is, this will |
+ // result in a new request for the source to change resolution. |
+ if (!sink_wants_.max_pixel_count || |
+ *sink_wants_.max_pixel_count > *max_pixel_count) { |
+ ++number_of_cpu_adapt_changes_; |
+ ++cpu_restricted_counter_; |
+ } |
+ } else { |
+ RTC_DCHECK(load == kUnderuse); |
+ // The input video frame size will have a resolution with "one step up" |
+ // pixels than |max_pixel_count_step_up| where "one step up" depends on |
+ // how the source can scale the input frame size. |
+ max_pixel_count_step_up = |
+ rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width); |
+ // Increase |number_of_cpu_adapt_changes_| if |
+ // sink_wants_.max_pixel_count_step_up will be changed since |
+ // last time |source_->AddOrUpdateSink| was called. That is, this will |
+ // result in a new request for the source to change resolution. |
+ if (sink_wants_.max_pixel_count || |
+ (sink_wants_.max_pixel_count_step_up && |
+ *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) { |
+ ++number_of_cpu_adapt_changes_; |
+ --cpu_restricted_counter_; |
+ } |
+ } |
+ sink_wants_.max_pixel_count = max_pixel_count; |
+ sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up; |
+ } |
// |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
// that might cause a lock order inversion. |
source_->AddOrUpdateSink(this, sink_wants_); |
@@ -2132,17 +2143,21 @@ |
VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( |
bool log_stats) { |
VideoSenderInfo info; |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
- for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
- info.add_ssrc(ssrc); |
- |
- if (parameters_.codec_settings) |
- info.codec_name = parameters_.codec_settings->codec.name; |
- |
- if (stream_ == NULL) |
- return info; |
- |
- webrtc::VideoSendStream::Stats stats = stream_->GetStats(); |
+ webrtc::VideoSendStream::Stats stats; |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
+ { |
+ rtc::CritScope cs(&lock_); |
+ for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
+ info.add_ssrc(ssrc); |
+ |
+ if (parameters_.codec_settings) |
+ info.codec_name = parameters_.codec_settings->codec.name; |
+ |
+ if (stream_ == NULL) |
+ return info; |
+ |
+ stats = stream_->GetStats(); |
+ } |
if (log_stats) |
LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); |
@@ -2203,7 +2218,7 @@ |
void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( |
BandwidthEstimationInfo* bwe_info) { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
+ rtc::CritScope cs(&lock_); |
if (stream_ == NULL) { |
return; |
} |
@@ -2219,7 +2234,6 @@ |
} |
void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { |
- RTC_DCHECK_RUN_ON(&thread_checker_); |
if (stream_ != NULL) { |
call_->DestroyVideoSendStream(stream_); |
} |
@@ -2243,6 +2257,7 @@ |
stream_->SetSource(this); |
parameters_.encoder_config.encoder_specific_settings = NULL; |
+ pending_encoder_reconfiguration_ = false; |
// Call stream_->Start() if necessary conditions are met. |
UpdateSendState(); |