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