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

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: Addressed review comments. 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
« 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
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, deregister as BitrateAllocatorObserver.
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 // Clear stats for disabled layers. 593 // Clear stats for disabled layers.
564 for (size_t i = encoder_settings->streams.size(); 594 for (size_t i = current_encoder_settings_->config.streams.size();
565 i < config_.rtp.ssrcs.size(); ++i) { 595 i < config_.rtp.ssrcs.size(); ++i) {
566 stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]); 596 stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]);
567 } 597 }
568 598
569 size_t number_of_temporal_layers = 599 size_t number_of_temporal_layers =
570 encoder_settings->streams.back() 600 current_encoder_settings_->config.streams.back()
571 .temporal_layer_thresholds_bps.size() + 601 .temporal_layer_thresholds_bps.size() +
572 1; 602 1;
573 protection_bitrate_calculator_.SetEncodingData( 603 protection_bitrate_calculator_.SetEncodingData(
574 encoder_settings->video_codec.startBitrate * 1000, 604 current_encoder_settings_->video_codec.startBitrate * 1000,
575 encoder_settings->video_codec.width, 605 current_encoder_settings_->video_codec.width,
576 encoder_settings->video_codec.height, 606 current_encoder_settings_->video_codec.height,
577 encoder_settings->video_codec.maxFramerate, number_of_temporal_layers, 607 current_encoder_settings_->video_codec.maxFramerate,
578 payload_router_.MaxPayloadLength()); 608 number_of_temporal_layers, payload_router_.MaxPayloadLength());
579 609
580 // We might've gotten new settings while configuring the encoder settings, 610 // We might've gotten new settings while configuring the encoder settings,
581 // restart from the top to see if that's the case before trying to encode 611 // restart from the top to see if that's the case before trying to encode
582 // a frame (which might correspond to the last frame size). 612 // a frame (which might correspond to the last frame size).
583 encoder_wakeup_event_.Set(); 613 encoder_wakeup_event_.Set();
584 continue; 614 continue;
585 } 615 }
586 616
587 VideoFrame frame; 617 VideoFrame frame;
588 if (input_.GetVideoFrame(&frame)) { 618 if (input_.GetVideoFrame(&frame)) {
589 // TODO(perkj): |pre_encode_callback| is only used by tests. Tests should 619 // TODO(perkj): |pre_encode_callback| is only used by tests. Tests should
590 // register as a sink to the VideoSource instead. 620 // register as a sink to the VideoSource instead.
591 if (config_.pre_encode_callback) { 621 if (config_.pre_encode_callback) {
592 config_.pre_encode_callback->OnFrame(frame); 622 config_.pre_encode_callback->OnFrame(frame);
593 } 623 }
594 vie_encoder_.EncodeVideoFrame(frame); 624 vie_encoder_.EncodeVideoFrame(frame);
595 } 625 }
626
627 // Check if the encoder has produced anything the last kEncoderTimeOutMs.
628 // If not, deregister as BitrateAllocatorObserver.
629 if (send_stream_registered_as_observer_ &&
630 vie_encoder_.time_of_last_frame_activity_ms() <
631 rtc::TimeMillis() - kEncoderTimeOutMs) {
632 // The encoder has timed out.
633 LOG_F(LS_INFO) << "Encoder timed out.";
634 bitrate_allocator_->RemoveObserver(this);
635 send_stream_registered_as_observer_ = false;
636 }
637 if (!send_stream_registered_as_observer_ &&
638 vie_encoder_.time_of_last_frame_activity_ms() >
639 rtc::TimeMillis() - kEncoderTimeOutMs) {
640 LOG_F(LS_INFO) << "Encoder is active.";
641 bitrate_allocator_->AddObserver(
642 this, current_encoder_settings_->video_codec.minBitrate * 1000,
643 current_encoder_settings_->video_codec.maxBitrate * 1000,
644 CalulcateMaxPadBitrateBps(current_encoder_settings_->config,
645 config_.suspend_below_min_bitrate),
646 !config_.suspend_below_min_bitrate);
647 send_stream_registered_as_observer_ = true;
648 }
596 } 649 }
597 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type); 650 vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
598 } 651 }
599 652
600 void VideoSendStream::ReconfigureVideoEncoder( 653 void VideoSendStream::ReconfigureVideoEncoder(
601 const VideoEncoderConfig& config) { 654 const VideoEncoderConfig& config) {
602 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder"); 655 TRACE_EVENT0("webrtc", "VideoSendStream::(Re)configureVideoEncoder");
603 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString(); 656 LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString();
604 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size()); 657 RTC_DCHECK_GE(config_.rtp.ssrcs.size(), config.streams.size());
605 VideoCodec video_codec = VideoEncoderConfigToVideoCodec( 658 VideoCodec video_codec = VideoEncoderConfigToVideoCodec(
606 config, config_.encoder_settings.payload_name, 659 config, config_.encoder_settings.payload_name,
607 config_.encoder_settings.payload_type); 660 config_.encoder_settings.payload_type);
608 { 661 {
609 rtc::CritScope lock(&encoder_settings_crit_); 662 rtc::CritScope lock(&encoder_settings_crit_);
610 pending_encoder_settings_ = rtc::Optional<EncoderSettings>( 663 pending_encoder_settings_.reset(new EncoderSettings({video_codec, config}));
611 {video_codec, config.min_transmit_bitrate_bps, config.streams});
612 } 664 }
613 encoder_wakeup_event_.Set(); 665 encoder_wakeup_event_.Set();
614 } 666 }
615 667
616 VideoSendStream::Stats VideoSendStream::GetStats() { 668 VideoSendStream::Stats VideoSendStream::GetStats() {
617 return stats_proxy_.GetStats(); 669 return stats_proxy_.GetStats();
618 } 670 }
619 671
620 void VideoSendStream::OveruseDetected() { 672 void VideoSendStream::OveruseDetected() {
621 if (config_.overuse_callback) 673 if (config_.overuse_callback)
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 return rtp_states; 832 return rtp_states;
781 } 833 }
782 834
783 void VideoSendStream::SignalNetworkState(NetworkState state) { 835 void VideoSendStream::SignalNetworkState(NetworkState state) {
784 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { 836 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
785 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode 837 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode
786 : RtcpMode::kOff); 838 : RtcpMode::kOff);
787 } 839 }
788 } 840 }
789 841
790 int VideoSendStream::GetPaddingNeededBps() const {
791 return vie_encoder_.GetPaddingNeededBps();
792 }
793
794 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps, 842 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
795 uint8_t fraction_loss, 843 uint8_t fraction_loss,
796 int64_t rtt) { 844 int64_t rtt) {
797 payload_router_.SetTargetSendBitrate(bitrate_bps); 845 payload_router_.SetTargetSendBitrate(bitrate_bps);
798 // Get the encoder target rate. It is the estimated network rate - 846 // Get the encoder target rate. It is the estimated network rate -
799 // protection overhead. 847 // protection overhead.
800 uint32_t encoder_target_rate = protection_bitrate_calculator_.SetTargetRates( 848 uint32_t encoder_target_rate = protection_bitrate_calculator_.SetTargetRates(
801 bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt); 849 bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt);
802 850
803 vie_encoder_.OnBitrateUpdated(encoder_target_rate, fraction_loss, rtt); 851 vie_encoder_.OnBitrateUpdated(encoder_target_rate, fraction_loss, rtt);
(...skipping 17 matching lines...) Expand all
821 &module_nack_rate); 869 &module_nack_rate);
822 *sent_video_rate_bps += module_video_rate; 870 *sent_video_rate_bps += module_video_rate;
823 *sent_nack_rate_bps += module_nack_rate; 871 *sent_nack_rate_bps += module_nack_rate;
824 *sent_fec_rate_bps += module_fec_rate; 872 *sent_fec_rate_bps += module_fec_rate;
825 } 873 }
826 return 0; 874 return 0;
827 } 875 }
828 876
829 } // namespace internal 877 } // namespace internal
830 } // namespace webrtc 878 } // 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