| Index: webrtc/modules/video_coding/main/source/video_sender.cc
|
| diff --git a/webrtc/modules/video_coding/main/source/video_sender.cc b/webrtc/modules/video_coding/main/source/video_sender.cc
|
| index 9b855da16a4cfc6402795770a7205455cc4a69e6..fb04b0e871eb7b412aade36f4bfdc79bd5ba4804 100644
|
| --- a/webrtc/modules/video_coding/main/source/video_sender.cc
|
| +++ b/webrtc/modules/video_coding/main/source/video_sender.cc
|
| @@ -42,6 +42,7 @@ VideoSender::VideoSender(Clock* clock,
|
| current_codec_(),
|
| qm_settings_callback_(qm_settings_callback),
|
| protection_callback_(nullptr) {
|
| + encoder_params_ = {0, 0, 0, 0, false};
|
| // Allow VideoSender to be created on one thread but used on another, post
|
| // construction. This is currently how this class is being used by at least
|
| // one external project (diffractor).
|
| @@ -67,6 +68,14 @@ int32_t VideoSender::Process() {
|
| }
|
| }
|
|
|
| + {
|
| + rtc::CritScope cs(¶ms_lock_);
|
| + // Force an encoder parameters update, so that incoming frame rate is
|
| + // updated even if bandwidth hasn't changed.
|
| + encoder_params_.input_frame_rate = _mediaOpt.InputFrameRate();
|
| + encoder_params_.updated = true;
|
| + }
|
| +
|
| return returnValue;
|
| }
|
|
|
| @@ -216,27 +225,42 @@ int VideoSender::FrameRate(unsigned int* framerate) const {
|
| int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate,
|
| uint8_t lossRate,
|
| int64_t rtt) {
|
| - // TODO(tommi,mflodman): This method is called on the network thread via the
|
| - // OnNetworkChanged event (ViEEncoder::OnNetworkChanged). Could we instead
|
| - // post the updated information to the encoding thread and not grab a lock
|
| - // here? This effectively means that the network thread will be blocked for
|
| - // as much as frame encoding period.
|
| -
|
| - uint32_t target_rate = _mediaOpt.SetTargetRates(target_bitrate,
|
| - lossRate,
|
| - rtt,
|
| - protection_callback_,
|
| - qm_settings_callback_);
|
| + uint32_t target_rate =
|
| + _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt,
|
| + protection_callback_, qm_settings_callback_);
|
| +
|
| uint32_t input_frame_rate = _mediaOpt.InputFrameRate();
|
|
|
| + rtc::CritScope cs(¶ms_lock_);
|
| + encoder_params_ =
|
| + EncoderParameters{target_rate, lossRate, rtt, input_frame_rate, true};
|
| +
|
| + return VCM_OK;
|
| +}
|
| +
|
| +int32_t VideoSender::UpdateEncoderParameters() {
|
| + EncoderParameters params;
|
| + {
|
| + rtc::CritScope cs(¶ms_lock_);
|
| + params = encoder_params_;
|
| + encoder_params_.updated = false;
|
| + }
|
| +
|
| + if (!params.updated || params.target_bitrate == 0)
|
| + return VCM_OK;
|
| +
|
| CriticalSectionScoped sendCs(_sendCritSect);
|
| int32_t ret = VCM_UNINITIALIZED;
|
| static_assert(VCM_UNINITIALIZED < 0, "VCM_UNINITIALIZED must be negative.");
|
|
|
| + if (params.input_frame_rate == 0) {
|
| + // No frame rate estimate available, use default.
|
| + params.input_frame_rate = current_codec_.maxFramerate;
|
| + }
|
| if (_encoder != nullptr) {
|
| - ret = _encoder->SetChannelParameters(lossRate, rtt);
|
| + ret = _encoder->SetChannelParameters(params.loss_rate, params.rtt);
|
| if (ret >= 0) {
|
| - ret = _encoder->SetRates(target_rate, input_frame_rate);
|
| + ret = _encoder->SetRates(params.target_bitrate, params.input_frame_rate);
|
| }
|
| }
|
| return ret;
|
| @@ -300,6 +324,7 @@ void VideoSender::SetVideoProtection(bool enable,
|
| int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame,
|
| const VideoContentMetrics* contentMetrics,
|
| const CodecSpecificInfo* codecSpecificInfo) {
|
| + UpdateEncoderParameters();
|
| CriticalSectionScoped cs(_sendCritSect);
|
| if (_encoder == nullptr) {
|
| return VCM_UNINITIALIZED;
|
|
|