Chromium Code Reviews| Index: webrtc/media/engine/webrtcvideoengine2.cc |
| diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc |
| index 0a7bfb8bf8d86d2cd596426be6eb1e64dfc6fad7..6550e7bf55e48e2b298978826974c9223c62c200 100644 |
| --- a/webrtc/media/engine/webrtcvideoengine2.cc |
| +++ b/webrtc/media/engine/webrtcvideoengine2.cc |
| @@ -14,6 +14,7 @@ |
| #include <algorithm> |
| #include <set> |
| #include <string> |
| +#include <utility> |
| #include "webrtc/base/copyonwritebuffer.h" |
| #include "webrtc/base/logging.h" |
| @@ -322,12 +323,82 @@ int GetDefaultVp9TemporalLayers() { |
| } |
| 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), |
|
mflodman
2016/09/27 11:28:00
We could replace 'is_screencast_' and 'conference_
perkj_webrtc
2016/09/27 13:45:17
On line 380 |is_screencast_| is used on its own to
mflodman
2016/09/28 13:17:07
Right, I missed that one!
|
| + conference_mode_(conference_mode) {} |
| + |
| + private: |
| + std::vector<webrtc::VideoStream> CreateEncoderStreams( |
| + int width, |
| + int height, |
| + const webrtc::VideoEncoderConfig& encoder_config) override { |
| + 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 kMinVideoBitrate = 30; |
| -const int kStartVideoBitrate = 300; |
| +const int kMinVideoBitrateKbps = 30; |
| const int kVideoMtu = 1200; |
| const int kVideoRtpBufferSize = 65536; |
| @@ -398,60 +469,9 @@ std::vector<VideoCodec> DefaultVideoCodecList() { |
| 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; |
| -} |
| - |
| void* 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 = |
| @@ -1539,6 +1559,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: |
| : config(std::move(config)), |
| options(options), |
| max_bitrate_bps(max_bitrate_bps), |
| + conference_mode(false), |
| codec_settings(codec_settings) {} |
| WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( |
| @@ -1583,7 +1604,6 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( |
| 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) { |
| @@ -1651,7 +1671,6 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( |
| 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 |
| @@ -1666,22 +1685,13 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( |
| 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); |
| } |
| @@ -1690,7 +1700,7 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( |
| const VideoOptions* options, |
| rtc::VideoSourceInterface<cricket::VideoFrame>* source) { |
| TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); |
| - RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| // Ignore |options| pointer if |enable| is false. |
| bool options_present = enable && options; |
| @@ -1699,50 +1709,47 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( |
| DisconnectSource(); |
| } |
| - if (options_present || source_changing) { |
| - rtc::CritScope cs(&lock_); |
| - |
| - 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 (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 (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; |
| + if (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; |
| } |
| - // |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(thread_checker_.CalledOnValidThread()); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| if (source_ == nullptr) { |
| return; |
| } |
| @@ -1777,6 +1784,7 @@ webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { |
| 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. |
| @@ -1811,6 +1819,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( |
| AllocatedEncoder* encoder) { |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| if (encoder->external) { |
| external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); |
| } |
| @@ -1819,8 +1828,9 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( |
| const VideoCodecSettings& codec_settings) { |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); |
| - RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
| + RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u); |
| AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); |
| parameters_.config.encoder_settings.encoder = new_encoder.encoder; |
| @@ -1861,41 +1871,38 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( |
| const ChangedSendParameters& params) { |
| - { |
| - 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; |
| - } |
| + 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(); |
| - } |
| - } // release |lock_| |
| + // 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(); |
| + } |
| // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
| // that might cause a lock order inversion. |
| @@ -1910,18 +1917,19 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( |
| bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( |
| const webrtc::RtpParameters& new_parameters) { |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| if (!ValidateRtpParameters(new_parameters)) { |
| return false; |
| } |
| - rtc::CritScope cs(&lock_); |
| - if (new_parameters.encodings[0].max_bitrate_bps != |
| - rtp_parameters_.encodings[0].max_bitrate_bps) { |
| - pending_encoder_reconfiguration_ = true; |
| - } |
| + bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps != |
| + rtp_parameters_.encodings[0].max_bitrate_bps; |
| 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; |
| @@ -1929,7 +1937,7 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( |
| webrtc::RtpParameters |
| WebRtcVideoChannel2::WebRtcVideoSendStream::GetRtpParameters() const { |
| - rtc::CritScope cs(&lock_); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| return rtp_parameters_; |
| } |
| @@ -1944,6 +1952,7 @@ bool WebRtcVideoChannel2::WebRtcVideoSendStream::ValidateRtpParameters( |
| } |
| 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) { |
| @@ -1959,6 +1968,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateSendState() { |
| 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) { |
| @@ -1972,60 +1982,39 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( |
| 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. |
| - size_t stream_count = parameters_.config.rtp.ssrcs.size(); |
| + encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size(); |
| if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) { |
| - stream_count = 1; |
| + encoder_config.number_of_streams = 1; |
| } |
| int stream_max_bitrate = |
| MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps, |
| parameters_.max_bitrate_bps); |
| - 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); |
| + |
| + 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.encoder_stream_factory = |
| + new rtc::RefCountedObject<EncoderStreamFactory>( |
| + codec.name, max_qp, max_framerate, is_screencast, |
| + parameters_.conference_mode); |
| return encoder_config; |
| } |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::ReconfigureEncoder() { |
| - RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| + RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u); |
| RTC_CHECK(parameters_.codec_settings); |
| VideoCodecSettings codec_settings = *parameters_.codec_settings; |
| @@ -2044,7 +2033,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::ReconfigureEncoder() { |
| } |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { |
| - rtc::CritScope cs(&lock_); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| sending_ = send; |
| UpdateSendState(); |
| } |
| @@ -2074,63 +2063,62 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { |
| this, load)); |
| return; |
| } |
| - RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| 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_); |
| - 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)) |
| + if (cpu_restricted_counter_ >= kMaxCpuDowngrades) { |
| return; |
| - |
| - 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; |
| + // 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; |
| // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
| // that might cause a lock order inversion. |
| source_->AddOrUpdateSink(this, sink_wants_); |
| @@ -2139,21 +2127,17 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { |
| VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( |
| bool log_stats) { |
| VideoSenderInfo info; |
| - 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); |
| + 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 (parameters_.codec_settings) |
| + info.codec_name = parameters_.codec_settings->codec.name; |
| - if (stream_ == NULL) |
| - return info; |
| + if (stream_ == NULL) |
| + return info; |
| - stats = stream_->GetStats(); |
| - } |
| + webrtc::VideoSendStream::Stats stats = stream_->GetStats(); |
| if (log_stats) |
| LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); |
| @@ -2214,7 +2198,7 @@ VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( |
| BandwidthEstimationInfo* bwe_info) { |
| - rtc::CritScope cs(&lock_); |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| if (stream_ == NULL) { |
| return; |
| } |
| @@ -2230,6 +2214,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( |
| } |
| void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { |
| + RTC_DCHECK_RUN_ON(&thread_checker_); |
| if (stream_ != NULL) { |
| call_->DestroyVideoSendStream(stream_); |
| } |
| @@ -2253,7 +2238,6 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { |
| stream_->SetSource(this); |
| parameters_.encoder_config.encoder_specific_settings = NULL; |
| - pending_encoder_reconfiguration_ = false; |
| // Call stream_->Start() if necessary conditions are met. |
| UpdateSendState(); |