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

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

Issue 1993113003: Refactor how padding is calculated. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 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
11 #include "webrtc/video/video_send_stream.h" 11 #include "webrtc/video/video_send_stream.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <sstream> 14 #include <sstream>
15 #include <string> 15 #include <string>
16 #include <utility>
16 #include <vector> 17 #include <vector>
17 18
18 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
19 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
20 #include "webrtc/base/trace_event.h" 21 #include "webrtc/base/trace_event.h"
21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
22 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" 23 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
23 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 24 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
24 #include "webrtc/modules/pacing/packet_router.h" 25 #include "webrtc/modules/pacing/packet_router.h"
25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
26 #include "webrtc/modules/utility/include/process_thread.h" 27 #include "webrtc/modules/utility/include/process_thread.h"
27 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 28 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
28 #include "webrtc/video/call_stats.h" 29 #include "webrtc/video/call_stats.h"
29 #include "webrtc/video/video_capture_input.h" 30 #include "webrtc/video/video_capture_input.h"
30 #include "webrtc/video/vie_remb.h" 31 #include "webrtc/video/vie_remb.h"
31 #include "webrtc/video_send_stream.h" 32 #include "webrtc/video_send_stream.h"
32 33
33 namespace webrtc { 34 namespace webrtc {
34 35
35 class RtcpIntraFrameObserver; 36 class RtcpIntraFrameObserver;
36 class TransportFeedbackObserver; 37 class TransportFeedbackObserver;
37 38
38 static const int kMinSendSidePacketHistorySize = 600; 39 static const int kMinSendSidePacketHistorySize = 600;
40 static const int kEncoderTimeOutMs = 2000;
39 41
40 namespace { 42 namespace {
41 43
42 std::vector<RtpRtcp*> CreateRtpRtcpModules( 44 std::vector<RtpRtcp*> CreateRtpRtcpModules(
43 Transport* outgoing_transport, 45 Transport* outgoing_transport,
44 RtcpIntraFrameObserver* intra_frame_callback, 46 RtcpIntraFrameObserver* intra_frame_callback,
45 RtcpBandwidthObserver* bandwidth_callback, 47 RtcpBandwidthObserver* bandwidth_callback,
46 TransportFeedbackObserver* transport_feedback_callback, 48 TransportFeedbackObserver* transport_feedback_callback,
47 RtcpRttStats* rtt_stats, 49 RtcpRttStats* rtt_stats,
48 RtpPacketSender* paced_sender, 50 RtpPacketSender* paced_sender,
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 } 339 }
338 if (video_codec.maxBitrate < kEncoderMinBitrateKbps) 340 if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
339 video_codec.maxBitrate = kEncoderMinBitrateKbps; 341 video_codec.maxBitrate = kEncoderMinBitrateKbps;
340 342
341 RTC_DCHECK_GT(streams[0].max_framerate, 0); 343 RTC_DCHECK_GT(streams[0].max_framerate, 0);
342 video_codec.maxFramerate = streams[0].max_framerate; 344 video_codec.maxFramerate = streams[0].max_framerate;
343 345
344 return video_codec; 346 return video_codec;
345 } 347 }
346 348
349 int CalulcateMaxPadBitrateBps(const VideoEncoderConfig& config,
350 bool pad_to_min_bitrate) {
351 int pad_up_to_bitrate_bps = 0;
352 // Calculate max padding bitrate for a multi layer codec.
353 if (config.streams.size() > 1) {
354 // Pad to min bitrate of the highest layer.
355 pad_up_to_bitrate_bps =
356 config.streams[config.streams.size() - 1].min_bitrate_bps;
357 // Add target_bitrate_bps of the lower layers.
358 for (size_t i = 0; i < config.streams.size() - 1; ++i)
359 pad_up_to_bitrate_bps += config.streams[i].target_bitrate_bps;
360 } else if (pad_to_min_bitrate) {
361 pad_up_to_bitrate_bps = config.streams[0].min_bitrate_bps;
362 }
363
364 pad_up_to_bitrate_bps =
365 std::max(pad_up_to_bitrate_bps, config.min_transmit_bitrate_bps);
366
367 return pad_up_to_bitrate_bps;
368 }
369
347 } // namespace 370 } // namespace
348 371
349 namespace internal { 372 namespace internal {
350 VideoSendStream::VideoSendStream( 373 VideoSendStream::VideoSendStream(
351 int num_cpu_cores, 374 int num_cpu_cores,
352 ProcessThread* module_process_thread, 375 ProcessThread* module_process_thread,
353 CallStats* call_stats, 376 CallStats* call_stats,
354 CongestionController* congestion_controller, 377 CongestionController* congestion_controller,
355 BitrateAllocator* bitrate_allocator, 378 BitrateAllocator* bitrate_allocator,
356 SendDelayStats* send_delay_stats, 379 SendDelayStats* send_delay_stats,
357 VieRemb* remb, 380 VieRemb* remb,
358 RtcEventLog* event_log, 381 RtcEventLog* event_log,
359 const VideoSendStream::Config& config, 382 const VideoSendStream::Config& config,
360 const VideoEncoderConfig& encoder_config, 383 const VideoEncoderConfig& encoder_config,
361 const std::map<uint32_t, RtpState>& suspended_ssrcs) 384 const std::map<uint32_t, RtpState>& suspended_ssrcs)
362 : stats_proxy_(Clock::GetRealTimeClock(), 385 : stats_proxy_(Clock::GetRealTimeClock(),
363 config, 386 config,
364 encoder_config.content_type), 387 encoder_config.content_type),
365 encoded_frame_proxy_(config.post_encode_callback), 388 encoded_frame_proxy_(config.post_encode_callback),
366 config_(config), 389 config_(config),
367 suspended_ssrcs_(suspended_ssrcs), 390 suspended_ssrcs_(suspended_ssrcs),
368 module_process_thread_(module_process_thread), 391 module_process_thread_(module_process_thread),
369 call_stats_(call_stats), 392 call_stats_(call_stats),
370 congestion_controller_(congestion_controller), 393 congestion_controller_(congestion_controller),
371 bitrate_allocator_(bitrate_allocator), 394 bitrate_allocator_(bitrate_allocator),
372 remb_(remb), 395 remb_(remb),
373 encoder_thread_(EncoderThreadFunction, this, "EncoderThread"), 396 encoder_thread_(EncoderThreadFunction, this, "EncoderThread"),
374 encoder_wakeup_event_(false, false), 397 encoder_wakeup_event_(false, false),
375 stop_encoder_thread_(0), 398 stop_encoder_thread_(0),
399 send_stream_registered_as_observer_(false),
376 overuse_detector_( 400 overuse_detector_(
377 Clock::GetRealTimeClock(), 401 Clock::GetRealTimeClock(),
378 GetCpuOveruseOptions(config.encoder_settings.full_overuse_time), 402 GetCpuOveruseOptions(config.encoder_settings.full_overuse_time),
379 this, 403 this,
380 config.post_encode_callback, 404 config.post_encode_callback,
381 &stats_proxy_), 405 &stats_proxy_),
382 vie_encoder_(num_cpu_cores, 406 vie_encoder_(num_cpu_cores,
383 module_process_thread_, 407 module_process_thread_,
384 &stats_proxy_, 408 &stats_proxy_,
385 &overuse_detector_, 409 &overuse_detector_,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 return false; 553 return false;
530 } 554 }
531 555
532 void VideoSendStream::EncoderProcess() { 556 void VideoSendStream::EncoderProcess() {
533 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder( 557 RTC_CHECK_EQ(0, vie_encoder_.RegisterExternalEncoder(
534 config_.encoder_settings.encoder, 558 config_.encoder_settings.encoder,
535 config_.encoder_settings.payload_type, 559 config_.encoder_settings.payload_type,
536 config_.encoder_settings.internal_source)); 560 config_.encoder_settings.internal_source));
537 561
538 while (true) { 562 while (true) {
539 encoder_wakeup_event_.Wait(rtc::Event::kForever); 563 // Wake up every kEncodeCheckForActivityPeriodMs to check if the encoder is
564 // active. If not, deregiser as BitrateAllocatorObserver.
stefan-webrtc 2016/06/10 13:54:13 deregister
perkj_webrtc 2016/06/14 10:58:02 Done.
565 const int kEncodeCheckForActivityPeriodMs = 1000;
566 encoder_wakeup_event_.Wait(kEncodeCheckForActivityPeriodMs);
540 if (rtc::AtomicOps::AcquireLoad(&stop_encoder_thread_)) 567 if (rtc::AtomicOps::AcquireLoad(&stop_encoder_thread_))
541 break; 568 break;
542 rtc::Optional<EncoderSettings> encoder_settings; 569 bool change_settings = false;
543 { 570 {
544 rtc::CritScope lock(&encoder_settings_crit_); 571 rtc::CritScope lock(&encoder_settings_crit_);
545 if (pending_encoder_settings_) { 572 if (pending_encoder_settings_) {
546 encoder_settings = pending_encoder_settings_; 573 std::swap(current_encoder_settings_, pending_encoder_settings_);
547 pending_encoder_settings_ = rtc::Optional<EncoderSettings>(); 574 pending_encoder_settings_.reset();
575 change_settings = true;
548 } 576 }
549 } 577 }
550 if (encoder_settings) { 578 if (change_settings) {
551 encoder_settings->video_codec.startBitrate = 579 current_encoder_settings_->video_codec.startBitrate =
552 bitrate_allocator_->AddObserver( 580 bitrate_allocator_->AddObserver(
553 this, encoder_settings->video_codec.minBitrate * 1000, 581 this, current_encoder_settings_->video_codec.minBitrate * 1000,
554 encoder_settings->video_codec.maxBitrate * 1000, 582 current_encoder_settings_->video_codec.maxBitrate * 1000,
583 CalulcateMaxPadBitrateBps(current_encoder_settings_->config,
584 config_.suspend_below_min_bitrate),
555 !config_.suspend_below_min_bitrate) / 585 !config_.suspend_below_min_bitrate) /
556 1000; 586 1000;
587 send_stream_registered_as_observer_ = true;
557 588
558 payload_router_.SetSendStreams(encoder_settings->streams); 589 payload_router_.SetSendStreams(current_encoder_settings_->config.streams);
559 vie_encoder_.SetEncoder(encoder_settings->video_codec, 590 vie_encoder_.SetEncoder(current_encoder_settings_->video_codec,
560 encoder_settings->min_transmit_bitrate_bps,
561 payload_router_.MaxPayloadLength()); 591 payload_router_.MaxPayloadLength());
562 592
563 // vie_encoder_.SetEncoder must be called before this. 593 // vie_encoder_.SetEncoder must be called before this.
564 if (config_.suspend_below_min_bitrate) 594 if (config_.suspend_below_min_bitrate)
565 video_sender_->SuspendBelowMinBitrate(); 595 video_sender_->SuspendBelowMinBitrate();
566 596
567 // Clear stats for disabled layers. 597 // Clear stats for disabled layers.
568 for (size_t i = encoder_settings->streams.size(); 598 for (size_t i = current_encoder_settings_->config.streams.size();
569 i < config_.rtp.ssrcs.size(); ++i) { 599 i < config_.rtp.ssrcs.size(); ++i) {
570 stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]); 600 stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]);
571 } 601 }
572 602
573 size_t number_of_temporal_layers = 603 size_t number_of_temporal_layers =
574 encoder_settings->streams.back() 604 current_encoder_settings_->config.streams.back()
575 .temporal_layer_thresholds_bps.size() + 605 .temporal_layer_thresholds_bps.size() +
576 1; 606 1;
577 protection_bitrate_calculator_.SetEncodingData( 607 protection_bitrate_calculator_.SetEncodingData(
578 encoder_settings->video_codec.startBitrate * 1000, 608 current_encoder_settings_->video_codec.startBitrate * 1000,
579 encoder_settings->video_codec.width, 609 current_encoder_settings_->video_codec.width,
580 encoder_settings->video_codec.height, 610 current_encoder_settings_->video_codec.height,
581 encoder_settings->video_codec.maxFramerate, number_of_temporal_layers, 611 current_encoder_settings_->video_codec.maxFramerate,
582 payload_router_.MaxPayloadLength()); 612 number_of_temporal_layers, payload_router_.MaxPayloadLength());
583 613
584 // We might've gotten new settings while configuring the encoder settings, 614 // We might've gotten new settings while configuring the encoder settings,
585 // restart from the top to see if that's the case before trying to encode 615 // restart from the top to see if that's the case before trying to encode
586 // a frame (which might correspond to the last frame size). 616 // a frame (which might correspond to the last frame size).
587 encoder_wakeup_event_.Set(); 617 encoder_wakeup_event_.Set();
588 continue; 618 continue;
589 } 619 }
590 620
591 VideoFrame frame; 621 VideoFrame frame;
592 if (input_.GetVideoFrame(&frame)) { 622 if (input_.GetVideoFrame(&frame)) {
593 // TODO(perkj): |pre_encode_callback| is only used by tests. Tests should 623 // TODO(perkj): |pre_encode_callback| is only used by tests. Tests should
594 // register as a sink to the VideoSource instead. 624 // register as a sink to the VideoSource instead.
595 if (config_.pre_encode_callback) { 625 if (config_.pre_encode_callback) {
596 config_.pre_encode_callback->OnFrame(frame); 626 config_.pre_encode_callback->OnFrame(frame);
597 } 627 }
598 vie_encoder_.EncodeVideoFrame(frame); 628 vie_encoder_.EncodeVideoFrame(frame);
599 } 629 }
630
631 // Check if the encoder has produced anything the last kEncoderTimeOutMs.
632 // If not, deregister as BitrateAllocatorObserver.
633 if (send_stream_registered_as_observer_ &&
mflodman 2016/06/13 05:02:43 Instead of having 'send_stream_registered_as_obser
perkj_webrtc 2016/06/14 10:58:02 discussed offline.
634 vie_encoder_.time_of_last_frame_activity_ms() <
635 rtc::TimeMillis() - kEncoderTimeOutMs) {
636 // The encoder has timed out.
637 LOG(LS_INFO) << "Encoder timed out.";
stefan-webrtc 2016/06/10 13:54:13 Do LOG_F or make it more clear why it has timed ou
perkj_webrtc 2016/06/14 10:58:02 Done.
638 bitrate_allocator_->RemoveObserver(this);
639 send_stream_registered_as_observer_ = false;
640 }
641 if (!send_stream_registered_as_observer_ &&
642 vie_encoder_.time_of_last_frame_activity_ms() >
643 rtc::TimeMillis() - kEncoderTimeOutMs) {
644 LOG(LS_INFO) << "Encoder is active.";
stefan-webrtc 2016/06/10 13:54:13 Same here.
perkj_webrtc 2016/06/14 10:58:02 Done.
645 bitrate_allocator_->AddObserver(
646 this, current_encoder_settings_->video_codec.minBitrate * 1000,
647 current_encoder_settings_->video_codec.maxBitrate * 1000,
648 CalulcateMaxPadBitrateBps(current_encoder_settings_->config,
649 config_.suspend_below_min_bitrate),
650 !config_.suspend_below_min_bitrate);
651 send_stream_registered_as_observer_ = true;
652 }
600 } 653 }
601 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type); 654 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
602 } 655 }
603 656
604 void VideoSendStream::ReconfigureVideoEncoder( 657 void VideoSendStream::ReconfigureVideoEncoder(
605 const VideoEncoderConfig& config) { 658 const VideoEncoderConfig& config) {
606 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder"); 659 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder");
607 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString(); 660 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString();
608 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size()); 661 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size());
609 VideoCodec video_codec = VideoEncoderConfigToVideoCodec( 662 VideoCodec video_codec = VideoEncoderConfigToVideoCodec(
610 config, config_.encoder_settings.payload_name, 663 config, config_.encoder_settings.payload_name,
611 config_.encoder_settings.payload_type); 664 config_.encoder_settings.payload_type);
612 { 665 {
613 rtc::CritScope lock(&encoder_settings_crit_); 666 rtc::CritScope lock(&encoder_settings_crit_);
614 pending_encoder_settings_ = rtc::Optional<EncoderSettings>( 667 pending_encoder_settings_.reset(new EncoderSettings({video_codec, config}));
615 {video_codec, config.min_transmit_bitrate_bps, config.streams});
616 } 668 }
617 encoder_wakeup_event_.Set(); 669 encoder_wakeup_event_.Set();
618 } 670 }
619 671
620 VideoSendStream::Stats VideoSendStream::GetStats() { 672 VideoSendStream::Stats VideoSendStream::GetStats() {
621 return stats_proxy_.GetStats(); 673 return stats_proxy_.GetStats();
622 } 674 }
623 675
624 void VideoSendStream::OveruseDetected() { 676 void VideoSendStream::OveruseDetected() {
625 if (config_.overuse_callback) 677 if (config_.overuse_callback)
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 return rtp_states; 836 return rtp_states;
785 } 837 }
786 838
787 void VideoSendStream::SignalNetworkState(NetworkState state) { 839 void VideoSendStream::SignalNetworkState(NetworkState state) {
788 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 840 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
789 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode 841 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode
790 : RtcpMode::kOff); 842 : RtcpMode::kOff);
791 } 843 }
792 } 844 }
793 845
794 int VideoSendStream::GetPaddingNeededBps() const {
795 return vie_encoder_.GetPaddingNeededBps();
796 }
797
798 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 846 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
799 uint8_t fraction_loss, 847 uint8_t fraction_loss,
800 int64_t rtt) { 848 int64_t rtt) {
801 payload_router_.SetTargetSendBitrate(bitrate_bps); 849 payload_router_.SetTargetSendBitrate(bitrate_bps);
802 // Get the encoder target rate. It is the estimated network rate - 850 // Get the encoder target rate. It is the estimated network rate -
803 // protection overhead. 851 // protection overhead.
804 uint32_t encoder_target_rate = protection_bitrate_calculator_.SetTargetRates( 852 uint32_t encoder_target_rate = protection_bitrate_calculator_.SetTargetRates(
805 bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt); 853 bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt);
806 854
807 vie_encoder_.OnBitrateUpdated(encoder_target_rate, fraction_loss, rtt); 855 vie_encoder_.OnBitrateUpdated(encoder_target_rate, fraction_loss, rtt);
(...skipping 17 matching lines...) Expand all
825 &module_nack_rate); 873 &module_nack_rate);
826 *sent_video_rate_bps += module_video_rate; 874 *sent_video_rate_bps += module_video_rate;
827 *sent_nack_rate_bps += module_nack_rate; 875 *sent_nack_rate_bps += module_nack_rate;
828 *sent_fec_rate_bps += module_fec_rate; 876 *sent_fec_rate_bps += module_fec_rate;
829 } 877 }
830 return 0; 878 return 0;
831 } 879 }
832 880
833 } // namespace internal 881 } // namespace internal
834 } // namespace webrtc 882 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698