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

Side by Side Diff: webrtc/video/video_send_stream.cc

Issue 1757313002: Initialize/configure video encoders asychronously. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: merge switch blocks Created 4 years, 9 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
« no previous file with comments | « webrtc/video/video_send_stream.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 // out). This should effectively turn off CPU adaptations for systems that 141 // out). This should effectively turn off CPU adaptations for systems that
142 // remotely cope with the load right now. 142 // remotely cope with the load right now.
143 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { 143 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) {
144 CpuOveruseOptions options; 144 CpuOveruseOptions options;
145 if (full_overuse_time) { 145 if (full_overuse_time) {
146 options.low_encode_usage_threshold_percent = 150; 146 options.low_encode_usage_threshold_percent = 150;
147 options.high_encode_usage_threshold_percent = 200; 147 options.high_encode_usage_threshold_percent = 200;
148 } 148 }
149 return options; 149 return options;
150 } 150 }
151
152 VideoCodec VideoEncoderConfigToVideoCodec(const VideoEncoderConfig& config,
153 const std::string& payload_name,
154 int payload_type) {
155 const std::vector<VideoStream>& streams = config.streams;
156 static const int kEncoderMinBitrateKbps = 30;
157 RTC_DCHECK(!streams.empty());
158 RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0);
159
160 VideoCodec video_codec;
161 memset(&video_codec, 0, sizeof(video_codec));
162 video_codec.codecType = PayloadNameToCodecType(payload_name);
163
164 switch (config.content_type) {
165 case VideoEncoderConfig::ContentType::kRealtimeVideo:
166 video_codec.mode = kRealtimeVideo;
167 break;
168 case VideoEncoderConfig::ContentType::kScreen:
169 video_codec.mode = kScreensharing;
170 if (config.streams.size() == 1 &&
171 config.streams[0].temporal_layer_thresholds_bps.size() == 1) {
172 video_codec.targetBitrate =
173 config.streams[0].temporal_layer_thresholds_bps[0] / 1000;
174 }
175 break;
176 }
177
178 switch (video_codec.codecType) {
179 case kVideoCodecVP8: {
180 if (config.encoder_specific_settings) {
181 video_codec.codecSpecific.VP8 = *reinterpret_cast<const VideoCodecVP8*>(
182 config.encoder_specific_settings);
183 } else {
184 video_codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
185 }
186 video_codec.codecSpecific.VP8.numberOfTemporalLayers =
187 static_cast<unsigned char>(
188 streams.back().temporal_layer_thresholds_bps.size() + 1);
189 break;
190 }
191 case kVideoCodecVP9: {
192 if (config.encoder_specific_settings) {
193 video_codec.codecSpecific.VP9 = *reinterpret_cast<const VideoCodecVP9*>(
194 config.encoder_specific_settings);
195 if (video_codec.mode == kScreensharing) {
196 video_codec.codecSpecific.VP9.flexibleMode = true;
197 // For now VP9 screensharing use 1 temporal and 2 spatial layers.
198 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfTemporalLayers,
199 1);
200 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfSpatialLayers, 2);
201 }
202 } else {
203 video_codec.codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
204 }
205 video_codec.codecSpecific.VP9.numberOfTemporalLayers =
206 static_cast<unsigned char>(
207 streams.back().temporal_layer_thresholds_bps.size() + 1);
208 break;
209 }
210 case kVideoCodecH264: {
211 if (config.encoder_specific_settings) {
212 video_codec.codecSpecific.H264 =
213 *reinterpret_cast<const VideoCodecH264*>(
214 config.encoder_specific_settings);
215 } else {
216 video_codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
217 }
218 break;
219 }
220 default:
221 // TODO(pbos): Support encoder_settings codec-agnostically.
222 RTC_DCHECK(config.encoder_specific_settings == nullptr)
223 << "Encoder-specific settings for codec type not wired up.";
224 break;
225 }
226
227 strncpy(video_codec.plName, payload_name.c_str(), kPayloadNameSize - 1);
228 video_codec.plName[kPayloadNameSize - 1] = '\0';
229 video_codec.plType = payload_type;
230 video_codec.numberOfSimulcastStreams =
231 static_cast<unsigned char>(streams.size());
232 video_codec.minBitrate = streams[0].min_bitrate_bps / 1000;
233 if (video_codec.minBitrate < kEncoderMinBitrateKbps)
234 video_codec.minBitrate = kEncoderMinBitrateKbps;
235 RTC_DCHECK_LE(streams.size(), static_cast<size_t>(kMaxSimulcastStreams));
236 if (video_codec.codecType == kVideoCodecVP9) {
237 // If the vector is empty, bitrates will be configured automatically.
238 RTC_DCHECK(config.spatial_layers.empty() ||
239 config.spatial_layers.size() ==
240 video_codec.codecSpecific.VP9.numberOfSpatialLayers);
241 RTC_DCHECK_LE(video_codec.codecSpecific.VP9.numberOfSpatialLayers,
242 kMaxSimulcastStreams);
243 for (size_t i = 0; i < config.spatial_layers.size(); ++i)
244 video_codec.spatialLayers[i] = config.spatial_layers[i];
245 }
246 for (size_t i = 0; i < streams.size(); ++i) {
247 SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
248 RTC_DCHECK_GT(streams[i].width, 0u);
249 RTC_DCHECK_GT(streams[i].height, 0u);
250 RTC_DCHECK_GT(streams[i].max_framerate, 0);
251 // Different framerates not supported per stream at the moment.
252 RTC_DCHECK_EQ(streams[i].max_framerate, streams[0].max_framerate);
253 RTC_DCHECK_GE(streams[i].min_bitrate_bps, 0);
254 RTC_DCHECK_GE(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
255 RTC_DCHECK_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
256 RTC_DCHECK_GE(streams[i].max_qp, 0);
257
258 sim_stream->width = static_cast<uint16_t>(streams[i].width);
259 sim_stream->height = static_cast<uint16_t>(streams[i].height);
260 sim_stream->minBitrate = streams[i].min_bitrate_bps / 1000;
261 sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
262 sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
263 sim_stream->qpMax = streams[i].max_qp;
264 sim_stream->numberOfTemporalLayers = static_cast<unsigned char>(
265 streams[i].temporal_layer_thresholds_bps.size() + 1);
266
267 video_codec.width = std::max(video_codec.width,
268 static_cast<uint16_t>(streams[i].width));
269 video_codec.height = std::max(
270 video_codec.height, static_cast<uint16_t>(streams[i].height));
271 video_codec.minBitrate =
272 std::min(static_cast<uint16_t>(video_codec.minBitrate),
273 static_cast<uint16_t>(streams[i].min_bitrate_bps / 1000));
274 video_codec.maxBitrate += streams[i].max_bitrate_bps / 1000;
275 video_codec.qpMax = std::max(video_codec.qpMax,
276 static_cast<unsigned int>(streams[i].max_qp));
277 }
278
279 if (video_codec.maxBitrate == 0) {
280 // Unset max bitrate -> cap to one bit per pixel.
281 video_codec.maxBitrate =
282 (video_codec.width * video_codec.height * video_codec.maxFramerate) /
283 1000;
284 }
285 if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
286 video_codec.maxBitrate = kEncoderMinBitrateKbps;
287
288 RTC_DCHECK_GT(streams[0].max_framerate, 0);
289 video_codec.maxFramerate = streams[0].max_framerate;
290
291 return video_codec;
292 }
293
151 } // namespace 294 } // namespace
152 295
153 namespace internal { 296 namespace internal {
154 VideoSendStream::VideoSendStream( 297 VideoSendStream::VideoSendStream(
155 int num_cpu_cores, 298 int num_cpu_cores,
156 ProcessThread* module_process_thread, 299 ProcessThread* module_process_thread,
157 CallStats* call_stats, 300 CallStats* call_stats,
158 CongestionController* congestion_controller, 301 CongestionController* congestion_controller,
159 BitrateAllocator* bitrate_allocator, 302 BitrateAllocator* bitrate_allocator,
160 VieRemb* remb, 303 VieRemb* remb,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_); 422 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(&stats_proxy_);
280 rtp_rtcp->SetMaxTransferUnit(mtu); 423 rtp_rtcp->SetMaxTransferUnit(mtu);
281 rtp_rtcp->RegisterVideoSendPayload( 424 rtp_rtcp->RegisterVideoSendPayload(
282 config_.encoder_settings.payload_type, 425 config_.encoder_settings.payload_type,
283 config_.encoder_settings.payload_name.c_str()); 426 config_.encoder_settings.payload_name.c_str());
284 } 427 }
285 428
286 RTC_DCHECK(config.encoder_settings.encoder != nullptr); 429 RTC_DCHECK(config.encoder_settings.encoder != nullptr);
287 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0); 430 RTC_DCHECK_GE(config.encoder_settings.payload_type, 0);
288 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127); 431 RTC_DCHECK_LE(config.encoder_settings.payload_type, 127);
289 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder(
290 config.encoder_settings.encoder,
291 config.encoder_settings.payload_type,
292 config.encoder_settings.internal_source));
293
294 ReconfigureVideoEncoder(encoder_config); 432 ReconfigureVideoEncoder(encoder_config);
295 433
296 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_); 434 vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_);
297 435
298 if (config_.post_encode_callback) 436 if (config_.post_encode_callback)
299 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_); 437 vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
300 438
301 if (config_.suspend_below_min_bitrate) {
302 vcm_->SuspendBelowMinBitrate();
303 bitrate_allocator_->EnforceMinBitrate(false);
304 }
305
306 vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_); 439 vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_);
307 vie_channel_.RegisterSendBitrateObserver(&stats_proxy_); 440 vie_channel_.RegisterSendBitrateObserver(&stats_proxy_);
308 vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_); 441 vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_);
309 442
310 module_process_thread_->RegisterModule(&overuse_detector_); 443 module_process_thread_->RegisterModule(&overuse_detector_);
311 444
312 encoder_thread_.Start(); 445 encoder_thread_.Start();
313 encoder_thread_.SetPriority(rtc::kHighPriority); 446 encoder_thread_.SetPriority(rtc::kHighPriority);
314 } 447 }
315 448
316 VideoSendStream::~VideoSendStream() { 449 VideoSendStream::~VideoSendStream() {
317 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString(); 450 LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString();
318 451
319 bitrate_allocator_->RemoveObserver(this); 452 bitrate_allocator_->RemoveObserver(this);
320 Stop(); 453 Stop();
321 454
322 // Stop the encoder thread permanently. 455 // Stop the encoder thread permanently.
323 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1); 456 rtc::AtomicOps::ReleaseStore(&stop_encoder_thread_, 1);
324 encoder_wakeup_event_.Set(); 457 encoder_wakeup_event_.Set();
325 encoder_thread_.Stop(); 458 encoder_thread_.Stop();
326 459
327 module_process_thread_->DeRegisterModule(&overuse_detector_); 460 module_process_thread_->DeRegisterModule(&overuse_detector_);
328 vie_channel_.RegisterSendFrameCountObserver(nullptr); 461 vie_channel_.RegisterSendFrameCountObserver(nullptr);
329 vie_channel_.RegisterSendBitrateObserver(nullptr); 462 vie_channel_.RegisterSendBitrateObserver(nullptr);
330 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr); 463 vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr);
331 464
332 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
333
334 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver()); 465 call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
335 rtp_rtcp_modules_[0]->SetREMBStatus(false); 466 rtp_rtcp_modules_[0]->SetREMBStatus(false);
336 remb_->RemoveRembSender(rtp_rtcp_modules_[0]); 467 remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
337 468
338 // ViEChannel outlives ViEEncoder so remove encoder from feedback before 469 // ViEChannel outlives ViEEncoder so remove encoder from feedback before
339 // destruction. 470 // destruction.
340 encoder_feedback_.TearDown(); 471 encoder_feedback_.TearDown();
341 472
342 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream( 473 congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream(
343 vie_receiver_->GetRemoteSsrc()); 474 vie_receiver_->GetRemoteSsrc());
(...skipping 22 matching lines...) Expand all
366 vie_receiver_->StopReceive(); 497 vie_receiver_->StopReceive();
367 } 498 }
368 499
369 bool VideoSendStream::EncoderThreadFunction(void* obj) { 500 bool VideoSendStream::EncoderThreadFunction(void* obj) {
370 static_cast<VideoSendStream*>(obj)->EncoderProcess(); 501 static_cast<VideoSendStream*>(obj)->EncoderProcess();
371 // We're done, return false to abort. 502 // We're done, return false to abort.
372 return false; 503 return false;
373 } 504 }
374 505
375 void VideoSendStream::EncoderProcess() { 506 void VideoSendStream::EncoderProcess() {
507 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder(
508 config_.encoder_settings.encoder,
509 config_.encoder_settings.payload_type,
510 config_.encoder_settings.internal_source));
511
376 while (true) { 512 while (true) {
377 encoder_wakeup_event_.Wait(rtc::Event::kForever); 513 encoder_wakeup_event_.Wait(rtc::Event::kForever);
378 if (rtc::AtomicOps::AcquireLoad(&stop_encoder_thread_)) 514 if (rtc::AtomicOps::AcquireLoad(&stop_encoder_thread_))
379 return; 515 break;
516 rtc::Optional<EncoderSettings> encoder_settings;
517 {
518 rtc::CritScope lock(&encoder_settings_crit_);
519 if (pending_encoder_settings_) {
520 encoder_settings = pending_encoder_settings_;
521 pending_encoder_settings_ = rtc::Optional<EncoderSettings>();
522 }
523 }
524 if (encoder_settings) {
525 encoder_settings->video_codec.startBitrate =
526 bitrate_allocator_->AddObserver(
527 this, encoder_settings->video_codec.minBitrate * 1000,
528 encoder_settings->video_codec.maxBitrate * 1000) /
529 1000;
530 vie_encoder_.SetEncoder(encoder_settings->video_codec,
531 encoder_settings->min_transmit_bitrate_bps);
532 if (config_.suspend_below_min_bitrate) {
533 vcm_->SuspendBelowMinBitrate();
534 bitrate_allocator_->EnforceMinBitrate(false);
535 }
536 // We might've gotten new settings while configuring the encoder settings,
537 // restart from the top to see if that's the case before trying to encode
538 // a frame (which might correspond to the last frame size).
539 encoder_wakeup_event_.Set();
540 continue;
541 }
380 542
381 VideoFrame frame; 543 VideoFrame frame;
382 if (input_.GetVideoFrame(&frame)) 544 if (input_.GetVideoFrame(&frame))
383 vie_encoder_.EncodeVideoFrame(frame); 545 vie_encoder_.EncodeVideoFrame(frame);
384 } 546 }
547 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
385 } 548 }
386 549
387 void VideoSendStream::ReconfigureVideoEncoder( 550 void VideoSendStream::ReconfigureVideoEncoder(
388 const VideoEncoderConfig& config) { 551 const VideoEncoderConfig& config) {
389 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder"); 552 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder");
390 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString(); 553 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString();
391 const std::vector<VideoStream>& streams = config.streams; 554 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size());
392 static const int kEncoderMinBitrateKbps = 30; 555 VideoCodec video_codec = VideoEncoderConfigToVideoCodec(
393 RTC_DCHECK(!streams.empty()); 556 config, config_.encoder_settings.payload_name,
394 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), streams.size()); 557 config_.encoder_settings.payload_type);
395 RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0); 558 {
396 559 rtc::CritScope lock(&encoder_settings_crit_);
397 VideoCodec video_codec; 560 pending_encoder_settings_ = rtc::Optional<EncoderSettings>(
398 memset(&video_codec, 0, sizeof(video_codec)); 561 {video_codec, config.min_transmit_bitrate_bps});
399 video_codec.codecType =
400 PayloadNameToCodecType(config_.encoder_settings.payload_name);
401
402 switch (config.content_type) {
403 case VideoEncoderConfig::ContentType::kRealtimeVideo:
404 video_codec.mode = kRealtimeVideo;
405 break;
406 case VideoEncoderConfig::ContentType::kScreen:
407 video_codec.mode = kScreensharing;
408 if (config.streams.size() == 1 &&
409 config.streams[0].temporal_layer_thresholds_bps.size() == 1) {
410 video_codec.targetBitrate =
411 config.streams[0].temporal_layer_thresholds_bps[0] / 1000;
412 }
413 break;
414 } 562 }
415 563 encoder_wakeup_event_.Set();
416 if (video_codec.codecType == kVideoCodecVP8) {
417 video_codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
418 } else if (video_codec.codecType == kVideoCodecVP9) {
419 video_codec.codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
420 } else if (video_codec.codecType == kVideoCodecH264) {
421 video_codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
422 }
423
424 if (video_codec.codecType == kVideoCodecVP8) {
425 if (config.encoder_specific_settings != nullptr) {
426 video_codec.codecSpecific.VP8 = *reinterpret_cast<const VideoCodecVP8*>(
427 config.encoder_specific_settings);
428 }
429 video_codec.codecSpecific.VP8.numberOfTemporalLayers =
430 static_cast<unsigned char>(
431 streams.back().temporal_layer_thresholds_bps.size() + 1);
432 } else if (video_codec.codecType == kVideoCodecVP9) {
433 if (config.encoder_specific_settings != nullptr) {
434 video_codec.codecSpecific.VP9 = *reinterpret_cast<const VideoCodecVP9*>(
435 config.encoder_specific_settings);
436 if (video_codec.mode == kScreensharing) {
437 video_codec.codecSpecific.VP9.flexibleMode = true;
438 // For now VP9 screensharing use 1 temporal and 2 spatial layers.
439 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfTemporalLayers, 1);
440 RTC_DCHECK_EQ(video_codec.codecSpecific.VP9.numberOfSpatialLayers, 2);
441 }
442 }
443 video_codec.codecSpecific.VP9.numberOfTemporalLayers =
444 static_cast<unsigned char>(
445 streams.back().temporal_layer_thresholds_bps.size() + 1);
446 } else if (video_codec.codecType == kVideoCodecH264) {
447 if (config.encoder_specific_settings != nullptr) {
448 video_codec.codecSpecific.H264 = *reinterpret_cast<const VideoCodecH264*>(
449 config.encoder_specific_settings);
450 }
451 } else {
452 // TODO(pbos): Support encoder_settings codec-agnostically.
453 RTC_DCHECK(config.encoder_specific_settings == nullptr)
454 << "Encoder-specific settings for codec type not wired up.";
455 }
456
457 strncpy(video_codec.plName,
458 config_.encoder_settings.payload_name.c_str(),
459 kPayloadNameSize - 1);
460 video_codec.plName[kPayloadNameSize - 1] = '\0';
461 video_codec.plType = config_.encoder_settings.payload_type;
462 video_codec.numberOfSimulcastStreams =
463 static_cast<unsigned char>(streams.size());
464 video_codec.minBitrate = streams[0].min_bitrate_bps / 1000;
465 if (video_codec.minBitrate < kEncoderMinBitrateKbps)
466 video_codec.minBitrate = kEncoderMinBitrateKbps;
467 RTC_DCHECK_LE(streams.size(), static_cast<size_t>(kMaxSimulcastStreams));
468 if (video_codec.codecType == kVideoCodecVP9) {
469 // If the vector is empty, bitrates will be configured automatically.
470 RTC_DCHECK(config.spatial_layers.empty() ||
471 config.spatial_layers.size() ==
472 video_codec.codecSpecific.VP9.numberOfSpatialLayers);
473 RTC_DCHECK_LE(video_codec.codecSpecific.VP9.numberOfSpatialLayers,
474 kMaxSimulcastStreams);
475 for (size_t i = 0; i < config.spatial_layers.size(); ++i)
476 video_codec.spatialLayers[i] = config.spatial_layers[i];
477 }
478 for (size_t i = 0; i < streams.size(); ++i) {
479 SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
480 RTC_DCHECK_GT(streams[i].width, 0u);
481 RTC_DCHECK_GT(streams[i].height, 0u);
482 RTC_DCHECK_GT(streams[i].max_framerate, 0);
483 // Different framerates not supported per stream at the moment.
484 RTC_DCHECK_EQ(streams[i].max_framerate, streams[0].max_framerate);
485 RTC_DCHECK_GE(streams[i].min_bitrate_bps, 0);
486 RTC_DCHECK_GE(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
487 RTC_DCHECK_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
488 RTC_DCHECK_GE(streams[i].max_qp, 0);
489
490 sim_stream->width = static_cast<uint16_t>(streams[i].width);
491 sim_stream->height = static_cast<uint16_t>(streams[i].height);
492 sim_stream->minBitrate = streams[i].min_bitrate_bps / 1000;
493 sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
494 sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
495 sim_stream->qpMax = streams[i].max_qp;
496 sim_stream->numberOfTemporalLayers = static_cast<unsigned char>(
497 streams[i].temporal_layer_thresholds_bps.size() + 1);
498
499 video_codec.width = std::max(video_codec.width,
500 static_cast<uint16_t>(streams[i].width));
501 video_codec.height = std::max(
502 video_codec.height, static_cast<uint16_t>(streams[i].height));
503 video_codec.minBitrate =
504 std::min(static_cast<uint16_t>(video_codec.minBitrate),
505 static_cast<uint16_t>(streams[i].min_bitrate_bps / 1000));
506 video_codec.maxBitrate += streams[i].max_bitrate_bps / 1000;
507 video_codec.qpMax = std::max(video_codec.qpMax,
508 static_cast<unsigned int>(streams[i].max_qp));
509 }
510
511 if (video_codec.maxBitrate == 0) {
512 // Unset max bitrate -> cap to one bit per pixel.
513 video_codec.maxBitrate =
514 (video_codec.width * video_codec.height * video_codec.maxFramerate) /
515 1000;
516 }
517 if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
518 video_codec.maxBitrate = kEncoderMinBitrateKbps;
519
520 RTC_DCHECK_GT(streams[0].max_framerate, 0);
521 video_codec.maxFramerate = streams[0].max_framerate;
522
523 video_codec.startBitrate =
524 bitrate_allocator_->AddObserver(this,
525 video_codec.minBitrate * 1000,
526 video_codec.maxBitrate * 1000) / 1000;
527 vie_encoder_.SetEncoder(video_codec, config.min_transmit_bitrate_bps);
528 } 564 }
529 565
530 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { 566 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
531 return vie_receiver_->DeliverRtcp(packet, length); 567 return vie_receiver_->DeliverRtcp(packet, length);
532 } 568 }
533 569
534 VideoSendStream::Stats VideoSendStream::GetStats() { 570 VideoSendStream::Stats VideoSendStream::GetStats() {
535 return stats_proxy_.GetStats(); 571 return stats_proxy_.GetStats();
536 } 572 }
537 573
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 } 660 }
625 661
626 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 662 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
627 uint8_t fraction_loss, 663 uint8_t fraction_loss,
628 int64_t rtt) { 664 int64_t rtt) {
629 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt); 665 vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
630 } 666 }
631 667
632 } // namespace internal 668 } // namespace internal
633 } // namespace webrtc 669 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/video_send_stream.h ('k') | webrtc/video/video_send_stream_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698