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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc

Issue 2434073003: Extract bitrate allocation of spatial/temporal layers out of codec impl. (Closed)
Patch Set: Updated tl listener registration. Fixed tests. Created 4 years, 2 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) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 VP8Encoder* VP8Encoder::Create() { 105 VP8Encoder* VP8Encoder::Create() {
106 return new VP8EncoderImpl(); 106 return new VP8EncoderImpl();
107 } 107 }
108 108
109 VP8Decoder* VP8Decoder::Create() { 109 VP8Decoder* VP8Decoder::Create() {
110 return new VP8DecoderImpl(); 110 return new VP8DecoderImpl();
111 } 111 }
112 112
113 VP8EncoderImpl::VP8EncoderImpl() 113 VP8EncoderImpl::VP8EncoderImpl()
114 : encoded_complete_callback_(nullptr), 114 : encoded_complete_callback_(nullptr),
115 rate_allocator_(new SimulcastRateAllocator(codec_)), 115 fallback_rate_allocator_(new SimulcastRateAllocator(codec_)),
116 inited_(false), 116 inited_(false),
117 timestamp_(0), 117 timestamp_(0),
118 feedback_mode_(false), 118 feedback_mode_(false),
119 qp_max_(56), // Setting for max quantizer. 119 qp_max_(56), // Setting for max quantizer.
120 cpu_speed_default_(-6), 120 cpu_speed_default_(-6),
121 rc_max_intra_target_(0), 121 rc_max_intra_target_(0),
122 token_partitions_(VP8_ONE_TOKENPARTITION), 122 token_partitions_(VP8_ONE_TOKENPARTITION),
123 down_scale_requested_(false), 123 down_scale_requested_(false),
124 down_scale_bitrate_(0), 124 down_scale_bitrate_(0),
125 key_frame_request_(kMaxSimulcastStreams, false), 125 key_frame_request_(kMaxSimulcastStreams, false),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 send_stream_.clear(); 162 send_stream_.clear();
163 cpu_speed_.clear(); 163 cpu_speed_.clear();
164 while (!raw_images_.empty()) { 164 while (!raw_images_.empty()) {
165 vpx_img_free(&raw_images_.back()); 165 vpx_img_free(&raw_images_.back());
166 raw_images_.pop_back(); 166 raw_images_.pop_back();
167 } 167 }
168 while (!temporal_layers_.empty()) { 168 while (!temporal_layers_.empty()) {
169 delete temporal_layers_.back(); 169 delete temporal_layers_.back();
170 temporal_layers_.pop_back(); 170 temporal_layers_.pop_back();
171 } 171 }
172 fallback_rate_allocator_.reset();
172 inited_ = false; 173 inited_ = false;
173 return ret_val; 174 return ret_val;
174 } 175 }
175 176
176 int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit, 177 int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
177 uint32_t new_framerate) { 178 uint32_t new_framerate) {
178 if (!inited_) { 179 if (!fallback_rate_allocator_.get())
180 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; // Indicate !initiated_.
181
182 // TODO(sprang): Remove this fallback path.
183 return SetRateAllocation(fallback_rate_allocator_->GetAllocation(
184 new_bitrate_kbit * 1000, new_framerate),
185 new_framerate);
186 }
187
188 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate,
189 uint32_t new_framerate) {
190 if (!inited_)
179 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 191 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
180 } 192
181 if (encoders_[0].err) { 193 if (encoders_[0].err)
182 return WEBRTC_VIDEO_CODEC_ERROR; 194 return WEBRTC_VIDEO_CODEC_ERROR;
183 } 195
184 if (new_framerate < 1) { 196 if (new_framerate < 1)
197 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
198
199 // At this point, bitrate allocation should already match codec settings.
200 if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate)
201 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
202
203 if (bitrate.get_sum_kbps() < codec_.minBitrate)
204 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
205
206 if (codec_.numberOfSimulcastStreams > 0 &&
perkj_webrtc 2016/10/21 08:24:29 dont' we always set this to at least 1.
sprang_webrtc 2016/10/25 10:44:25 I don't think so. At least there seem to be many t
207 bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) {
185 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 208 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
186 } 209 }
187 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) { 210
188 new_bitrate_kbit = codec_.maxBitrate;
189 }
190 if (new_bitrate_kbit < codec_.minBitrate) {
191 new_bitrate_kbit = codec_.minBitrate;
192 }
193 if (codec_.numberOfSimulcastStreams > 0 &&
194 new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) {
195 new_bitrate_kbit = codec_.simulcastStream[0].minBitrate;
196 }
197 codec_.maxFramerate = new_framerate; 211 codec_.maxFramerate = new_framerate;
198 212
199 if (encoders_.size() == 1) { 213 if (encoders_.size() == 1) {
200 // 1:1. 214 // 1:1.
201 // Calculate a rough limit for when to trigger a potental down scale. 215 // Calculate a rough limit for when to trigger a potental down scale.
202 uint32_t k_pixels_per_frame = codec_.width * codec_.height / 1000; 216 uint32_t k_pixels_per_frame = codec_.width * codec_.height / 1000;
203 // TODO(pwestin): we currently lack CAMA, this is a temporary fix to work 217 // TODO(pwestin): we currently lack CAMA, this is a temporary fix to work
204 // around the current limitations. 218 // around the current limitations.
205 // Only trigger keyframes if we are allowed to scale down. 219 // Only trigger keyframes if we are allowed to scale down.
206 if (configurations_[0].rc_resize_allowed) { 220 if (configurations_[0].rc_resize_allowed) {
207 if (!down_scale_requested_) { 221 if (!down_scale_requested_) {
208 if (k_pixels_per_frame > new_bitrate_kbit) { 222 if (k_pixels_per_frame > bitrate.get_sum_kbps()) {
209 down_scale_requested_ = true; 223 down_scale_requested_ = true;
210 down_scale_bitrate_ = new_bitrate_kbit; 224 down_scale_bitrate_ = bitrate.get_sum_kbps();
211 key_frame_request_[0] = true; 225 key_frame_request_[0] = true;
212 } 226 }
213 } else { 227 } else {
214 if (new_bitrate_kbit > (2 * down_scale_bitrate_) || 228 if (bitrate.get_sum_kbps() > (2 * down_scale_bitrate_) ||
215 new_bitrate_kbit < (down_scale_bitrate_ / 2)) { 229 bitrate.get_sum_kbps() < (down_scale_bitrate_ / 2)) {
216 down_scale_requested_ = false; 230 down_scale_requested_ = false;
217 } 231 }
218 } 232 }
219 } 233 }
220 } else { 234 } else {
221 // If we have more than 1 stream, reduce the qp_max for the low resolution 235 // If we have more than 1 stream, reduce the qp_max for the low resolution
222 // stream if frame rate is not too low. The trade-off with lower qp_max is 236 // stream if frame rate is not too low. The trade-off with lower qp_max is
223 // possibly more dropped frames, so we only do this if the frame rate is 237 // possibly more dropped frames, so we only do this if the frame rate is
224 // above some threshold (base temporal layer is down to 1/4 for 3 layers). 238 // above some threshold (base temporal layer is down to 1/4 for 3 layers).
225 // We may want to condition this on bitrate later. 239 // We may want to condition this on bitrate later.
226 if (new_framerate > 20) { 240 if (new_framerate > 20) {
227 configurations_[encoders_.size() - 1].rc_max_quantizer = 45; 241 configurations_[encoders_.size() - 1].rc_max_quantizer = 45;
228 } else { 242 } else {
229 // Go back to default value set in InitEncode. 243 // Go back to default value set in InitEncode.
230 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_; 244 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_;
231 } 245 }
232 } 246 }
233 247
234 std::vector<uint32_t> stream_bitrates =
235 rate_allocator_->GetAllocation(new_bitrate_kbit);
236 size_t stream_idx = encoders_.size() - 1; 248 size_t stream_idx = encoders_.size() - 1;
237 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { 249 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
250 unsigned int target_bitrate_kbps =
251 bitrate.get_spatial_layer_sum(stream_idx) / 1000;
252
238 if (encoders_.size() > 1) 253 if (encoders_.size() > 1)
239 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 254 SetStreamState(target_bitrate_kbps > 0, stream_idx);
240 255
241 unsigned int target_bitrate = stream_bitrates[stream_idx]; 256 configurations_[i].rc_target_bitrate = target_bitrate_kbps;
242 unsigned int max_bitrate = codec_.maxBitrate; 257 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]);
243 int framerate = new_framerate; 258
244 // TODO(holmer): This is a temporary hack for screensharing, where we
245 // interpret the startBitrate as the encoder target bitrate. This is
246 // to allow for a different max bitrate, so if the codec can't meet
247 // the target we still allow it to overshoot up to the max before dropping
248 // frames. This hack should be improved.
249 if (codec_.targetBitrate > 0 &&
250 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 ||
251 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
252 int tl0_bitrate = std::min(codec_.targetBitrate, target_bitrate);
253 max_bitrate = std::min(codec_.maxBitrate, target_bitrate);
254 target_bitrate = tl0_bitrate;
255 }
256 configurations_[i].rc_target_bitrate = target_bitrate;
257 temporal_layers_[stream_idx]->ConfigureBitrates(
258 target_bitrate, max_bitrate, framerate, &configurations_[i]);
259 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { 259 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) {
260 return WEBRTC_VIDEO_CODEC_ERROR; 260 return WEBRTC_VIDEO_CODEC_ERROR;
261 } 261 }
262 } 262 }
263 quality_scaler_.ReportFramerate(new_framerate); 263 quality_scaler_.ReportFramerate(new_framerate);
264 return WEBRTC_VIDEO_CODEC_OK; 264 return WEBRTC_VIDEO_CODEC_OK;
265 } 265 }
266 266
267 void VP8EncoderImpl::OnDroppedFrame() { 267 void VP8EncoderImpl::OnDroppedFrame() {
268 if (quality_scaler_enabled_) 268 if (quality_scaler_enabled_)
269 quality_scaler_.ReportDroppedFrame(); 269 quality_scaler_.ReportDroppedFrame();
270 } 270 }
271 271
272 const char* VP8EncoderImpl::ImplementationName() const { 272 const char* VP8EncoderImpl::ImplementationName() const {
273 return "libvpx"; 273 return "libvpx";
274 } 274 }
275 275
276 void VP8EncoderImpl::SetStreamState(bool send_stream, 276 void VP8EncoderImpl::SetStreamState(bool send_stream,
277 int stream_idx) { 277 int stream_idx) {
278 if (send_stream && !send_stream_[stream_idx]) { 278 if (send_stream && !send_stream_[stream_idx]) {
279 // Need a key frame if we have not sent this stream before. 279 // Need a key frame if we have not sent this stream before.
280 key_frame_request_[stream_idx] = true; 280 key_frame_request_[stream_idx] = true;
281 } 281 }
282 send_stream_[stream_idx] = send_stream; 282 send_stream_[stream_idx] = send_stream;
283 } 283 }
284 284
285 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, 285 void VP8EncoderImpl::SetupTemporalLayers(int num_streams,
286 int num_temporal_layers, 286 int num_temporal_layers,
287 const VideoCodec& codec) { 287 const VideoCodec& codec,
288 TemporalLayersFactory default_factory; 288 SimulcastRateAllocator* allocator) {
289 RTC_DCHECK(codec.codecSpecific.VP8.tl_factory != nullptr);
289 const TemporalLayersFactory* tl_factory = codec.codecSpecific.VP8.tl_factory; 290 const TemporalLayersFactory* tl_factory = codec.codecSpecific.VP8.tl_factory;
290 if (!tl_factory)
291 tl_factory = &default_factory;
292 if (num_streams == 1) { 291 if (num_streams == 1) {
293 if (codec.mode == kScreensharing) { 292 temporal_layers_.push_back(
294 // Special mode when screensharing on a single stream. 293 tl_factory->Create(0, num_temporal_layers, rand()));
295 temporal_layers_.push_back(new ScreenshareLayers( 294 allocator->OnTemporalLayersCreated(0, temporal_layers_.back());
296 num_temporal_layers, rand(), webrtc::Clock::GetRealTimeClock()));
297 } else {
298 temporal_layers_.push_back(
299 tl_factory->Create(num_temporal_layers, rand()));
300 }
301 } else { 295 } else {
302 for (int i = 0; i < num_streams; ++i) { 296 for (int i = 0; i < num_streams; ++i) {
303 // TODO(andresp): crash if layers is invalid. 297 // TODO(andresp): crash if layers is invalid.
perkj_webrtc 2016/10/21 08:24:28 fix or remove this todo?
sprang_webrtc 2016/10/25 10:44:25 Done.
304 int layers = codec.simulcastStream[i].numberOfTemporalLayers; 298 int layers = std::max(static_cast<uint8_t>(1),
305 if (layers < 1) 299 codec.simulcastStream[i].numberOfTemporalLayers);
306 layers = 1; 300 temporal_layers_.push_back(tl_factory->Create(i, layers, rand()));
307 temporal_layers_.push_back(tl_factory->Create(layers, rand())); 301 allocator->OnTemporalLayersCreated(i, temporal_layers_.back());
308 } 302 }
309 } 303 }
310 } 304 }
311 305
312 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, 306 int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
313 int number_of_cores, 307 int number_of_cores,
314 size_t /*maxPayloadSize */) { 308 size_t /*maxPayloadSize */) {
315 if (inst == NULL) { 309 if (inst == NULL) {
316 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 310 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
317 } 311 }
(...skipping 30 matching lines...) Expand all
348 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 342 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
349 } 343 }
350 344
351 int num_temporal_layers = 345 int num_temporal_layers =
352 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers 346 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers
353 : inst->codecSpecific.VP8.numberOfTemporalLayers; 347 : inst->codecSpecific.VP8.numberOfTemporalLayers;
354 348
355 // TODO(andresp): crash if num temporal layers is bananas. 349 // TODO(andresp): crash if num temporal layers is bananas.
356 if (num_temporal_layers < 1) 350 if (num_temporal_layers < 1)
357 num_temporal_layers = 1; 351 num_temporal_layers = 1;
358 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst); 352
353 fallback_rate_allocator_.reset(new SimulcastRateAllocator(*inst));
354 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst,
355 fallback_rate_allocator_.get());
359 356
360 feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn; 357 feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn;
361
362 timestamp_ = 0; 358 timestamp_ = 0;
363 codec_ = *inst; 359 codec_ = *inst;
364 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
365 360
366 // Code expects simulcastStream resolutions to be correct, make sure they are 361 // Code expects simulcastStream resolutions to be correct, make sure they are
367 // filled even when there are no simulcast layers. 362 // filled even when there are no simulcast layers.
368 if (codec_.numberOfSimulcastStreams == 0) { 363 if (codec_.numberOfSimulcastStreams == 0) {
369 codec_.simulcastStream[0].width = codec_.width; 364 codec_.simulcastStream[0].width = codec_.width;
370 codec_.simulcastStream[0].height = codec_.height; 365 codec_.simulcastStream[0].height = codec_.height;
371 } 366 }
372 367
373 picture_id_.resize(number_of_streams); 368 picture_id_.resize(number_of_streams);
374 last_key_frame_picture_id_.resize(number_of_streams); 369 last_key_frame_picture_id_.resize(number_of_streams);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 // TODO(fbarchard): Consider number of Simulcast layers. 502 // TODO(fbarchard): Consider number of Simulcast layers.
508 configurations_[0].g_threads = NumberOfThreads( 503 configurations_[0].g_threads = NumberOfThreads(
509 configurations_[0].g_w, configurations_[0].g_h, number_of_cores); 504 configurations_[0].g_w, configurations_[0].g_h, number_of_cores);
510 505
511 // Creating a wrapper to the image - setting image data to NULL. 506 // Creating a wrapper to the image - setting image data to NULL.
512 // Actual pointer will be set in encode. Setting align to 1, as it 507 // Actual pointer will be set in encode. Setting align to 1, as it
513 // is meaningless (no memory allocation is done here). 508 // is meaningless (no memory allocation is done here).
514 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1, 509 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1,
515 NULL); 510 NULL);
516 511
517 if (encoders_.size() == 1) { 512 // Note the order we use is different from webm, we have lowest resolution
518 configurations_[0].rc_target_bitrate = inst->startBitrate; 513 // at position 0 and they have highest resolution at position 0.
519 temporal_layers_[0]->ConfigureBitrates(inst->startBitrate, inst->maxBitrate, 514 int stream_idx = encoders_.size() - 1;
520 inst->maxFramerate, 515 std::vector<uint32_t> stream_bitrates;
521 &configurations_[0]); 516 BitrateAllocation allocation = fallback_rate_allocator_->GetAllocation(
522 } else { 517 inst->startBitrate * 1000, inst->maxFramerate);
523 // Note the order we use is different from webm, we have lowest resolution 518 for (int i = 0; i == 0 || i < inst->numberOfSimulcastStreams; ++i) {
524 // at position 0 and they have highest resolution at position 0. 519 uint32_t bitrate = allocation.get_spatial_layer_sum(i) / 1000;
525 int stream_idx = encoders_.size() - 1; 520 stream_bitrates.push_back(bitrate);
526 std::vector<uint32_t> stream_bitrates = 521 }
527 rate_allocator_->GetAllocation(inst->startBitrate); 522
523 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx];
524 temporal_layers_[stream_idx]->OnRatesUpdated(
525 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate);
526 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[0]);
527 --stream_idx;
528 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) {
529 memcpy(&configurations_[i], &configurations_[0],
530 sizeof(configurations_[0]));
531
532 configurations_[i].g_w = inst->simulcastStream[stream_idx].width;
533 configurations_[i].g_h = inst->simulcastStream[stream_idx].height;
534
535 // Use 1 thread for lower resolutions.
536 configurations_[i].g_threads = 1;
537
538 // Setting alignment to 32 - as that ensures at least 16 for all
539 // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for
540 // the y plane, but only half of it to the u and v planes.
541 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420,
542 inst->simulcastStream[stream_idx].width,
543 inst->simulcastStream[stream_idx].height, kVp832ByteAlign);
528 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 544 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
529 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx]; 545 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx];
530 temporal_layers_[stream_idx]->ConfigureBitrates( 546 temporal_layers_[stream_idx]->OnRatesUpdated(
531 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate, 547 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate);
532 &configurations_[0]); 548 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]);
533 --stream_idx;
534 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) {
535 memcpy(&configurations_[i], &configurations_[0],
536 sizeof(configurations_[0]));
537
538 configurations_[i].g_w = inst->simulcastStream[stream_idx].width;
539 configurations_[i].g_h = inst->simulcastStream[stream_idx].height;
540
541 // Use 1 thread for lower resolutions.
542 configurations_[i].g_threads = 1;
543
544 // Setting alignment to 32 - as that ensures at least 16 for all
545 // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for
546 // the y plane, but only half of it to the u and v planes.
547 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420,
548 inst->simulcastStream[stream_idx].width,
549 inst->simulcastStream[stream_idx].height, kVp832ByteAlign);
550 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
551 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx];
552 temporal_layers_[stream_idx]->ConfigureBitrates(
553 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate,
554 &configurations_[i]);
555 }
556 } 549 }
557 550
558 rps_.Init(); 551 rps_.Init();
559 quality_scaler_.Init(codec_.codecType, codec_.startBitrate, codec_.width, 552 quality_scaler_.Init(codec_.codecType, codec_.startBitrate, codec_.width,
560 codec_.height, codec_.maxFramerate); 553 codec_.height, codec_.maxFramerate);
561 554
562 // Only apply scaling to improve for single-layer streams. The scaling metrics 555 // Only apply scaling to improve for single-layer streams. The scaling metrics
563 // use frame drops as a signal and is only applicable when we drop frames. 556 // use frame drops as a signal and is only applicable when we drop frames.
564 quality_scaler_enabled_ = encoders_.size() == 1 && 557 quality_scaler_enabled_ = encoders_.size() == 1 &&
565 configurations_[0].rc_dropframe_thresh > 0 && 558 configurations_[0].rc_dropframe_thresh > 0 &&
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 return -1; 1312 return -1;
1320 } 1313 }
1321 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != 1314 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) !=
1322 VPX_CODEC_OK) { 1315 VPX_CODEC_OK) {
1323 return -1; 1316 return -1;
1324 } 1317 }
1325 return 0; 1318 return 0;
1326 } 1319 }
1327 1320
1328 } // namespace webrtc 1321 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698