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

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

Issue 2434073003: Extract bitrate allocation of spatial/temporal layers out of codec impl. (Closed)
Patch Set: Addressed comments. Moved VideoCodec creation to factory class. Created 4 years, 1 month 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
11 11
12 #include <algorithm> // std::max 12 #include <algorithm> // std::max
13 13
14 #include "webrtc/base/checks.h" 14 #include "webrtc/base/checks.h"
15 #include "webrtc/base/logging.h" 15 #include "webrtc/base/logging.h"
16 #include "webrtc/common_types.h" 16 #include "webrtc/common_types.h"
17 #include "webrtc/common_video/include/video_bitrate_allocator.h"
stefan-webrtc 2016/11/02 10:26:36 Do you have to include both this one and default_v
sprang_webrtc 2016/11/02 13:28:33 I don't have to, but I think this follows the "inc
stefan-webrtc 2016/11/03 13:34:58 Acknowledged.
17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
19 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 20 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
19 #include "webrtc/modules/video_coding/encoded_frame.h" 21 #include "webrtc/modules/video_coding/encoded_frame.h"
22 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h"
20 #include "webrtc/modules/video_coding/utility/quality_scaler.h" 23 #include "webrtc/modules/video_coding/utility/quality_scaler.h"
21 #include "webrtc/modules/video_coding/video_coding_impl.h" 24 #include "webrtc/modules/video_coding/video_coding_impl.h"
22 #include "webrtc/system_wrappers/include/clock.h" 25 #include "webrtc/system_wrappers/include/clock.h"
23 26
24 namespace webrtc { 27 namespace webrtc {
25 namespace vcm { 28 namespace vcm {
26 29
27 VideoSender::VideoSender(Clock* clock, 30 VideoSender::VideoSender(Clock* clock,
28 EncodedImageCallback* post_encode_callback, 31 EncodedImageCallback* post_encode_callback,
29 VCMSendStatisticsCallback* send_stats_callback) 32 VCMSendStatisticsCallback* send_stats_callback)
30 : clock_(clock), 33 : clock_(clock),
31 _encoder(nullptr), 34 _encoder(nullptr),
32 _mediaOpt(clock_), 35 _mediaOpt(clock_),
33 _encodedFrameCallback(post_encode_callback, &_mediaOpt), 36 _encodedFrameCallback(post_encode_callback, &_mediaOpt),
34 send_stats_callback_(send_stats_callback), 37 send_stats_callback_(send_stats_callback),
35 _codecDataBase(&_encodedFrameCallback), 38 _codecDataBase(&_encodedFrameCallback),
36 frame_dropper_enabled_(true), 39 frame_dropper_enabled_(true),
37 _sendStatsTimer(1000, clock_), 40 _sendStatsTimer(1000, clock_),
38 current_codec_(), 41 current_codec_(),
39 encoder_params_({0, 0, 0, 0}), 42 encoder_params_({BitrateAllocation(), 0, 0, 0}),
40 encoder_has_internal_source_(false), 43 encoder_has_internal_source_(false),
41 next_frame_types_(1, kVideoFrameDelta) { 44 next_frame_types_(1, kVideoFrameDelta) {
42 _mediaOpt.Reset(); 45 _mediaOpt.Reset();
43 // 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
44 // 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
45 // one external project (diffractor). 48 // one external project (diffractor).
46 sequenced_checker_.Detach(); 49 sequenced_checker_.Detach();
47 } 50 }
48 51
49 VideoSender::~VideoSender() {} 52 VideoSender::~VideoSender() {}
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 168 }
166 169
167 // Get encode bitrate 170 // Get encode bitrate
168 int VideoSender::Bitrate(unsigned int* bitrate) const { 171 int VideoSender::Bitrate(unsigned int* bitrate) const {
169 RTC_DCHECK(sequenced_checker_.CalledSequentially()); 172 RTC_DCHECK(sequenced_checker_.CalledSequentially());
170 // Since we're running on the thread that's the only thread known to modify 173 // Since we're running on the thread that's the only thread known to modify
171 // the value of _encoder, we don't need to grab the lock here. 174 // the value of _encoder, we don't need to grab the lock here.
172 175
173 if (!_encoder) 176 if (!_encoder)
174 return VCM_UNINITIALIZED; 177 return VCM_UNINITIALIZED;
175 *bitrate = _encoder->GetEncoderParameters().target_bitrate; 178 *bitrate = _encoder->GetEncoderParameters().target_bitrate.get_sum_bps();
176 return 0; 179 return 0;
177 } 180 }
178 181
179 // Get encode frame rate 182 // Get encode frame rate
180 int VideoSender::FrameRate(unsigned int* framerate) const { 183 int VideoSender::FrameRate(unsigned int* framerate) const {
181 RTC_DCHECK(sequenced_checker_.CalledSequentially()); 184 RTC_DCHECK(sequenced_checker_.CalledSequentially());
182 // Since we're running on the thread that's the only thread known to modify 185 // Since we're running on the thread that's the only thread known to modify
183 // the value of _encoder, we don't need to grab the lock here. 186 // the value of _encoder, we don't need to grab the lock here.
184 187
185 if (!_encoder) 188 if (!_encoder)
186 return VCM_UNINITIALIZED; 189 return VCM_UNINITIALIZED;
187 190
188 *framerate = _encoder->GetEncoderParameters().input_frame_rate; 191 *framerate = _encoder->GetEncoderParameters().input_frame_rate;
189 return 0; 192 return 0;
190 } 193 }
191 194
192 int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, 195 int32_t VideoSender::SetChannelParameters(
193 uint8_t lossRate, 196 uint32_t target_bitrate_bps,
194 int64_t rtt) { 197 uint8_t lossRate,
195 uint32_t target_rate = 198 int64_t rtt,
196 _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt); 199 VideoBitrateAllocator* bitrate_allocator) {
stefan-webrtc 2016/11/02 10:26:36 Does this change on every channel parameter update
sprang_webrtc 2016/11/02 13:28:33 The bitrate_allocator is owned by ViEEncoder, and
stefan-webrtc 2016/11/03 13:34:58 Probably good, or perhaps you should pass in a Bit
sprang_webrtc 2016/11/03 14:36:59 The reason I pass down the allocator reference is
stefan-webrtc 2016/11/03 15:32:08 I don't know how, but I missed that.
200 uint32_t video_target_rate_bps =
201 _mediaOpt.SetTargetRates(target_bitrate_bps, lossRate, rtt);
202 uint32_t input_frame_rate = _mediaOpt.InputFrameRate();
203 BitrateAllocation bitrate_allocation;
204 if (bitrate_allocator) {
205 bitrate_allocation = bitrate_allocator->GetAllocation(video_target_rate_bps,
206 input_frame_rate);
207 } else {
208 DefaultVideoBitrateAllocator default_allocator(current_codec_);
209 bitrate_allocation = default_allocator.GetAllocation(video_target_rate_bps,
210 input_frame_rate);
211 }
197 212
198 uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); 213 EncoderParameters encoder_params = {bitrate_allocation, lossRate, rtt,
199
200 EncoderParameters encoder_params = {target_rate, lossRate, rtt,
201 input_frame_rate}; 214 input_frame_rate};
202 bool encoder_has_internal_source; 215 bool encoder_has_internal_source;
203 { 216 {
204 rtc::CritScope cs(&params_crit_); 217 rtc::CritScope cs(&params_crit_);
205 encoder_params_ = encoder_params; 218 encoder_params_ = encoder_params;
206 encoder_has_internal_source = encoder_has_internal_source_; 219 encoder_has_internal_source = encoder_has_internal_source_;
207 } 220 }
208 221
209 // For encoders with internal sources, we need to tell the encoder directly, 222 // For encoders with internal sources, we need to tell the encoder directly,
210 // instead of waiting for an AddVideoFrame that will never come (internal 223 // instead of waiting for an AddVideoFrame that will never come (internal
(...skipping 10 matching lines...) Expand all
221 234
222 void VideoSender::SetEncoderParameters(EncoderParameters params, 235 void VideoSender::SetEncoderParameters(EncoderParameters params,
223 bool has_internal_source) { 236 bool has_internal_source) {
224 // |target_bitrate == 0 | means that the network is down or the send pacer is 237 // |target_bitrate == 0 | means that the network is down or the send pacer is
225 // full. We currently only report this if the encoder has an internal source. 238 // full. We currently only report this if the encoder has an internal source.
226 // If the encoder does not have an internal source, higher levels are expected 239 // If the encoder does not have an internal source, higher levels are expected
227 // to not call AddVideoFrame. We do this since its unclear how current 240 // to not call AddVideoFrame. We do this since its unclear how current
228 // encoder implementations behave when given a zero target bitrate. 241 // encoder implementations behave when given a zero target bitrate.
229 // TODO(perkj): Make sure all known encoder implementations handle zero 242 // TODO(perkj): Make sure all known encoder implementations handle zero
230 // target bitrate and remove this check. 243 // target bitrate and remove this check.
231 if (!has_internal_source && params.target_bitrate == 0) 244 if (!has_internal_source && params.target_bitrate.get_sum_bps() == 0)
232 return; 245 return;
233 246
234 if (params.input_frame_rate == 0) { 247 if (params.input_frame_rate == 0) {
235 // No frame rate estimate available, use default. 248 // No frame rate estimate available, use default.
236 params.input_frame_rate = current_codec_.maxFramerate; 249 params.input_frame_rate = current_codec_.maxFramerate;
237 } 250 }
238 if (_encoder != nullptr) 251 if (_encoder != nullptr)
239 _encoder->SetEncoderParameters(params); 252 _encoder->SetEncoderParameters(params);
240 } 253 }
241 254
(...skipping 19 matching lines...) Expand all
261 encoder_params = encoder_params_; 274 encoder_params = encoder_params_;
262 next_frame_types = next_frame_types_; 275 next_frame_types = next_frame_types_;
263 encoder_has_internal_source = encoder_has_internal_source_; 276 encoder_has_internal_source = encoder_has_internal_source_;
264 } 277 }
265 rtc::CritScope lock(&encoder_crit_); 278 rtc::CritScope lock(&encoder_crit_);
266 if (_encoder == nullptr) 279 if (_encoder == nullptr)
267 return VCM_UNINITIALIZED; 280 return VCM_UNINITIALIZED;
268 SetEncoderParameters(encoder_params, encoder_has_internal_source); 281 SetEncoderParameters(encoder_params, encoder_has_internal_source);
269 if (_mediaOpt.DropFrame()) { 282 if (_mediaOpt.DropFrame()) {
270 LOG(LS_VERBOSE) << "Drop Frame " 283 LOG(LS_VERBOSE) << "Drop Frame "
271 << "target bitrate " << encoder_params.target_bitrate 284 << "target bitrate "
285 << encoder_params.target_bitrate.get_sum_bps()
272 << " loss rate " << encoder_params.loss_rate << " rtt " 286 << " loss rate " << encoder_params.loss_rate << " rtt "
273 << encoder_params.rtt << " input frame rate " 287 << encoder_params.rtt << " input frame rate "
274 << encoder_params.input_frame_rate; 288 << encoder_params.input_frame_rate;
275 _encoder->OnDroppedFrame(); 289 _encoder->OnDroppedFrame();
276 return VCM_OK; 290 return VCM_OK;
277 } 291 }
278 // TODO(pbos): Make sure setting send codec is synchronized with video 292 // TODO(pbos): Make sure setting send codec is synchronized with video
279 // processing so frame size always matches. 293 // processing so frame size always matches.
280 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(), 294 if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(),
281 videoFrame.height())) { 295 videoFrame.height())) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 } 364 }
351 365
352 int32_t VideoSender::EnableFrameDropper(bool enable) { 366 int32_t VideoSender::EnableFrameDropper(bool enable) {
353 rtc::CritScope lock(&encoder_crit_); 367 rtc::CritScope lock(&encoder_crit_);
354 frame_dropper_enabled_ = enable; 368 frame_dropper_enabled_ = enable;
355 _mediaOpt.EnableFrameDropper(enable); 369 _mediaOpt.EnableFrameDropper(enable);
356 return VCM_OK; 370 return VCM_OK;
357 } 371 }
358 } // namespace vcm 372 } // namespace vcm
359 } // namespace webrtc 373 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698