OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |