Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(835)

Side by Side Diff: webrtc/modules/video_coding/main/source/video_sender.cc

Issue 1180623005: Update encoder settings periodically, not only on new bandwidth estimate (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 24 matching lines...) Expand all
35 _encodedFrameCallback(post_encode_callback), 35 _encodedFrameCallback(post_encode_callback),
36 _nextFrameTypes(1, kVideoFrameDelta), 36 _nextFrameTypes(1, kVideoFrameDelta),
37 _mediaOpt(clock_), 37 _mediaOpt(clock_),
38 _sendStatsCallback(nullptr), 38 _sendStatsCallback(nullptr),
39 _codecDataBase(encoder_rate_observer), 39 _codecDataBase(encoder_rate_observer),
40 frame_dropper_enabled_(true), 40 frame_dropper_enabled_(true),
41 _sendStatsTimer(1000, clock_), 41 _sendStatsTimer(1000, clock_),
42 current_codec_(), 42 current_codec_(),
43 qm_settings_callback_(qm_settings_callback), 43 qm_settings_callback_(qm_settings_callback),
44 protection_callback_(nullptr) { 44 protection_callback_(nullptr) {
45 encoder_params_ = {0, 0, 0, 0, false};
45 // Allow VideoSender to be created on one thread but used on another, post 46 // Allow VideoSender to be created on one thread but used on another, post
46 // construction. This is currently how this class is being used by at least 47 // construction. This is currently how this class is being used by at least
47 // one external project (diffractor). 48 // one external project (diffractor).
48 _mediaOpt.EnableQM(qm_settings_callback_ != nullptr); 49 _mediaOpt.EnableQM(qm_settings_callback_ != nullptr);
49 _mediaOpt.Reset(); 50 _mediaOpt.Reset();
50 main_thread_.DetachFromThread(); 51 main_thread_.DetachFromThread();
51 } 52 }
52 53
53 VideoSender::~VideoSender() { 54 VideoSender::~VideoSender() {
54 delete _sendCritSect; 55 delete _sendCritSect;
55 } 56 }
56 57
57 int32_t VideoSender::Process() { 58 int32_t VideoSender::Process() {
58 int32_t returnValue = VCM_OK; 59 int32_t returnValue = VCM_OK;
59 60
60 if (_sendStatsTimer.TimeUntilProcess() == 0) { 61 if (_sendStatsTimer.TimeUntilProcess() == 0) {
61 _sendStatsTimer.Processed(); 62 _sendStatsTimer.Processed();
62 CriticalSectionScoped cs(process_crit_sect_.get()); 63 CriticalSectionScoped cs(process_crit_sect_.get());
63 if (_sendStatsCallback != nullptr) { 64 if (_sendStatsCallback != nullptr) {
64 uint32_t bitRate = _mediaOpt.SentBitRate(); 65 uint32_t bitRate = _mediaOpt.SentBitRate();
65 uint32_t frameRate = _mediaOpt.SentFrameRate(); 66 uint32_t frameRate = _mediaOpt.SentFrameRate();
66 _sendStatsCallback->SendStatistics(bitRate, frameRate); 67 _sendStatsCallback->SendStatistics(bitRate, frameRate);
67 } 68 }
68 } 69 }
69 70
71 {
72 rtc::CritScope cs(&params_lock_);
73 // Force an encoder parameters update, so that incoming frame rate is
74 // updated even if bandwidth hasn't changed.
75 encoder_params_.input_frame_rate = _mediaOpt.InputFrameRate();
76 encoder_params_.updated = true;
77 }
78
70 return returnValue; 79 return returnValue;
71 } 80 }
72 81
73 int64_t VideoSender::TimeUntilNextProcess() { 82 int64_t VideoSender::TimeUntilNextProcess() {
74 return _sendStatsTimer.TimeUntilProcess(); 83 return _sendStatsTimer.TimeUntilProcess();
75 } 84 }
76 85
77 // Register the send codec to be used. 86 // Register the send codec to be used.
78 int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec, 87 int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec,
79 uint32_t numberOfCores, 88 uint32_t numberOfCores,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (!_encoder) { 218 if (!_encoder) {
210 return VCM_UNINITIALIZED; 219 return VCM_UNINITIALIZED;
211 } 220 }
212 *framerate = _encoder->FrameRate(); 221 *framerate = _encoder->FrameRate();
213 return 0; 222 return 0;
214 } 223 }
215 224
216 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, 225 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate,
217 uint8_t lossRate, 226 uint8_t lossRate,
218 int64_t rtt) { 227 int64_t rtt) {
219 // TODO(tommi,mflodman): This method is called on the network thread via the 228 uint32_t target_rate =
220 // OnNetworkChanged event (ViEEncoder::OnNetworkChanged). Could we instead 229 _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt,
221 // post the updated information to the encoding thread and not grab a lock 230 protection_callback_, qm_settings_callback_);
222 // here? This effectively means that the network thread will be blocked for
223 // as much as frame encoding period.
224 231
225 uint32_t target_rate = _mediaOpt.SetTargetRates(target_bitrate,
226 lossRate,
227 rtt,
228 protection_callback_,
229 qm_settings_callback_);
230 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); 232 uint32_t input_frame_rate = _mediaOpt.InputFrameRate();
231 233
234 rtc::CritScope cs(&params_lock_);
235 encoder_params_ =
236 EncoderParameters{target_rate, lossRate, rtt, input_frame_rate, true};
237
238 return VCM_OK;
239 }
240
241 int32_t VideoSender::UpdateEncoderParameters() {
242 EncoderParameters params;
243 {
244 rtc::CritScope cs(&params_lock_);
245 params = encoder_params_;
246 encoder_params_.updated = false;
247 }
248
249 if (!params.updated || params.target_bitrate == 0)
250 return VCM_OK;
251
232 CriticalSectionScoped sendCs(_sendCritSect); 252 CriticalSectionScoped sendCs(_sendCritSect);
233 int32_t ret = VCM_UNINITIALIZED; 253 int32_t ret = VCM_UNINITIALIZED;
234 static_assert(VCM_UNINITIALIZED < 0, "VCM_UNINITIALIZED must be negative."); 254 static_assert(VCM_UNINITIALIZED < 0, "VCM_UNINITIALIZED must be negative.");
235 255
256 if (params.input_frame_rate == 0) {
257 // No frame rate estimate available, use default.
258 params.input_frame_rate = current_codec_.maxFramerate;
259 }
236 if (_encoder != nullptr) { 260 if (_encoder != nullptr) {
237 ret = _encoder->SetChannelParameters(lossRate, rtt); 261 ret = _encoder->SetChannelParameters(params.loss_rate, params.rtt);
238 if (ret >= 0) { 262 if (ret >= 0) {
239 ret = _encoder->SetRates(target_rate, input_frame_rate); 263 ret = _encoder->SetRates(params.target_bitrate, params.input_frame_rate);
240 } 264 }
241 } 265 }
242 return ret; 266 return ret;
243 } 267 }
244 268
245 int32_t VideoSender::RegisterTransportCallback( 269 int32_t VideoSender::RegisterTransportCallback(
246 VCMPacketizationCallback* transport) { 270 VCMPacketizationCallback* transport) {
247 CriticalSectionScoped cs(_sendCritSect); 271 CriticalSectionScoped cs(_sendCritSect);
248 _encodedFrameCallback.SetMediaOpt(&_mediaOpt); 272 _encodedFrameCallback.SetMediaOpt(&_mediaOpt);
249 _encodedFrameCallback.SetTransportCallback(transport); 273 _encodedFrameCallback.SetTransportCallback(transport);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 case kProtectionKeyOnLoss: 317 case kProtectionKeyOnLoss:
294 case kProtectionKeyOnKeyLoss: 318 case kProtectionKeyOnKeyLoss:
295 // Ignore receiver modes. 319 // Ignore receiver modes.
296 return; 320 return;
297 } 321 }
298 } 322 }
299 // Add one raw video frame to the encoder, blocking. 323 // Add one raw video frame to the encoder, blocking.
300 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame, 324 int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame,
301 const VideoContentMetrics* contentMetrics, 325 const VideoContentMetrics* contentMetrics,
302 const CodecSpecificInfo* codecSpecificInfo) { 326 const CodecSpecificInfo* codecSpecificInfo) {
327 UpdateEncoderParameters();
303 CriticalSectionScoped cs(_sendCritSect); 328 CriticalSectionScoped cs(_sendCritSect);
304 if (_encoder == nullptr) { 329 if (_encoder == nullptr) {
305 return VCM_UNINITIALIZED; 330 return VCM_UNINITIALIZED;
306 } 331 }
307 // TODO(holmer): Add support for dropping frames per stream. Currently we 332 // TODO(holmer): Add support for dropping frames per stream. Currently we
308 // only have one frame dropper for all streams. 333 // only have one frame dropper for all streams.
309 if (_nextFrameTypes[0] == kFrameEmpty) { 334 if (_nextFrameTypes[0] == kFrameEmpty) {
310 return VCM_OK; 335 return VCM_OK;
311 } 336 }
312 if (_mediaOpt.DropFrame()) { 337 if (_mediaOpt.DropFrame()) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 int window_bps = std::max(threshold_bps / 10, 10000); 403 int window_bps = std::max(threshold_bps / 10, 10000);
379 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps); 404 _mediaOpt.SuspendBelowMinBitrate(threshold_bps, window_bps);
380 } 405 }
381 406
382 bool VideoSender::VideoSuspended() const { 407 bool VideoSender::VideoSuspended() const {
383 CriticalSectionScoped cs(_sendCritSect); 408 CriticalSectionScoped cs(_sendCritSect);
384 return _mediaOpt.IsVideoSuspended(); 409 return _mediaOpt.IsVideoSuspended();
385 } 410 }
386 } // namespace vcm 411 } // namespace vcm
387 } // namespace webrtc 412 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698