OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 | 640 |
641 int ViEChannel::ReceiveDelay() const { | 641 int ViEChannel::ReceiveDelay() const { |
642 return vcm_->Delay(); | 642 return vcm_->Delay(); |
643 } | 643 } |
644 | 644 |
645 int32_t ViEChannel::WaitForKeyFrame(bool wait) { | 645 int32_t ViEChannel::WaitForKeyFrame(bool wait) { |
646 wait_for_key_frame_ = wait; | 646 wait_for_key_frame_ = wait; |
647 return 0; | 647 return 0; |
648 } | 648 } |
649 | 649 |
650 int32_t ViEChannel::SetSignalPacketLossStatus(bool enable, | |
651 bool only_key_frames) { | |
652 if (enable) { | |
653 if (only_key_frames) { | |
654 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false); | |
655 if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) { | |
656 return -1; | |
657 } | |
658 } else { | |
659 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false); | |
660 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) { | |
661 return -1; | |
662 } | |
663 } | |
664 } else { | |
665 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false); | |
666 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false); | |
667 } | |
668 return 0; | |
669 } | |
670 | |
671 void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { | 650 void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { |
672 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); | 651 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); |
673 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin(); | 652 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin(); |
674 it != simulcast_rtp_rtcp_.end(); | 653 it != simulcast_rtp_rtcp_.end(); |
675 it++) { | 654 it++) { |
676 RtpRtcp* rtp_rtcp = *it; | 655 RtpRtcp* rtp_rtcp = *it; |
677 rtp_rtcp->SetRTCPStatus(rtcp_mode); | 656 rtp_rtcp->SetRTCPStatus(rtcp_mode); |
678 } | 657 } |
679 rtp_rtcp_->SetRTCPStatus(rtcp_mode); | 658 rtp_rtcp_->SetRTCPStatus(rtcp_mode); |
680 } | 659 } |
681 | 660 |
682 int32_t ViEChannel::SetNACKStatus(const bool enable) { | 661 void ViEChannel::SetProtectionMode(bool enable_nack, |
683 // Update the decoding VCM. | 662 bool enable_fec, |
684 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { | 663 int payload_type_red, |
685 return -1; | 664 int payload_type_fec) { |
| 665 // Validate payload types. |
| 666 if (enable_fec) { |
| 667 DCHECK_GE(payload_type_red, 0); |
| 668 DCHECK_GE(payload_type_fec, 0); |
| 669 DCHECK_LE(payload_type_red, 127); |
| 670 DCHECK_LE(payload_type_fec, 127); |
| 671 } else { |
| 672 DCHECK_EQ(payload_type_red, -1); |
| 673 DCHECK_EQ(payload_type_fec, -1); |
| 674 // Set to valid uint8_ts to be castable later without signed overflows. |
| 675 payload_type_red = 0; |
| 676 payload_type_fec = 0; |
686 } | 677 } |
687 if (enable) { | 678 |
688 // Disable possible FEC. | 679 VCMVideoProtection protection_method; |
689 SetFECStatus(false, 0, 0); | 680 if (enable_nack) { |
| 681 protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack; |
| 682 } else { |
| 683 protection_method = kProtectionNone; |
690 } | 684 } |
691 // Update the decoding VCM. | 685 |
692 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { | 686 vcm_->SetVideoProtection(protection_method, true); |
693 return -1; | 687 |
| 688 // Set NACK. |
| 689 ProcessNACKRequest(enable_nack); |
| 690 |
| 691 // Set FEC. |
| 692 rtp_rtcp_->SetGenericFECStatus(enable_fec, |
| 693 static_cast<uint8_t>(payload_type_red), |
| 694 static_cast<uint8_t>(payload_type_fec)); |
| 695 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); |
| 696 for (RtpRtcp* rtp_rtcp : simulcast_rtp_rtcp_) { |
| 697 rtp_rtcp->SetGenericFECStatus(enable_fec, |
| 698 static_cast<uint8_t>(payload_type_red), |
| 699 static_cast<uint8_t>(payload_type_fec)); |
694 } | 700 } |
695 return ProcessNACKRequest(enable); | |
696 } | 701 } |
697 | 702 |
698 int32_t ViEChannel::ProcessNACKRequest(const bool enable) { | 703 void ViEChannel::ProcessNACKRequest(const bool enable) { |
699 if (enable) { | 704 if (enable) { |
700 // Turn on NACK. | 705 // Turn on NACK. |
701 if (rtp_rtcp_->RTCP() == kRtcpOff) { | 706 if (rtp_rtcp_->RTCP() == kRtcpOff) |
702 return -1; | 707 return; |
703 } | |
704 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); | 708 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); |
705 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_); | 709 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_); |
706 vcm_->RegisterPacketRequestCallback(this); | 710 vcm_->RegisterPacketRequestCallback(this); |
707 | 711 |
708 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); | 712 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); |
709 | 713 |
710 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin(); | 714 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin(); |
711 it != simulcast_rtp_rtcp_.end(); | 715 it != simulcast_rtp_rtcp_.end(); |
712 it++) { | 716 it++) { |
713 RtpRtcp* rtp_rtcp = *it; | 717 RtpRtcp* rtp_rtcp = *it; |
(...skipping 13 matching lines...) Expand all Loading... |
727 } | 731 } |
728 vcm_->RegisterPacketRequestCallback(NULL); | 732 vcm_->RegisterPacketRequestCallback(NULL); |
729 if (paced_sender_ == NULL) { | 733 if (paced_sender_ == NULL) { |
730 rtp_rtcp_->SetStorePacketsStatus(false, 0); | 734 rtp_rtcp_->SetStorePacketsStatus(false, 0); |
731 } | 735 } |
732 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); | 736 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); |
733 // When NACK is off, allow decoding with errors. Otherwise, the video | 737 // When NACK is off, allow decoding with errors. Otherwise, the video |
734 // will freeze, and will only recover with a complete key frame. | 738 // will freeze, and will only recover with a complete key frame. |
735 vcm_->SetDecodeErrorMode(kWithErrors); | 739 vcm_->SetDecodeErrorMode(kWithErrors); |
736 } | 740 } |
737 return 0; | |
738 } | |
739 | |
740 int32_t ViEChannel::SetFECStatus(const bool enable, | |
741 const unsigned char payload_typeRED, | |
742 const unsigned char payload_typeFEC) { | |
743 // Disable possible NACK. | |
744 if (enable) { | |
745 SetNACKStatus(false); | |
746 } | |
747 | |
748 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC); | |
749 } | 741 } |
750 | 742 |
751 bool ViEChannel::IsSendingFecEnabled() { | 743 bool ViEChannel::IsSendingFecEnabled() { |
752 bool fec_enabled = false; | 744 bool fec_enabled = false; |
753 uint8_t pltype_red = 0; | 745 uint8_t pltype_red = 0; |
754 uint8_t pltype_fec = 0; | 746 uint8_t pltype_fec = 0; |
755 rtp_rtcp_->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); | 747 rtp_rtcp_->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); |
756 if (fec_enabled) | 748 if (fec_enabled) |
757 return true; | 749 return true; |
758 | 750 |
759 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); | 751 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); |
760 for (auto* module : simulcast_rtp_rtcp_) { | 752 for (auto* module : simulcast_rtp_rtcp_) { |
761 module->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); | 753 module->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); |
762 if (fec_enabled) | 754 if (fec_enabled) |
763 return true; | 755 return true; |
764 } | 756 } |
765 return false; | 757 return false; |
766 } | 758 } |
767 | 759 |
768 int32_t ViEChannel::ProcessFECRequest( | |
769 const bool enable, | |
770 const unsigned char payload_typeRED, | |
771 const unsigned char payload_typeFEC) { | |
772 if (rtp_rtcp_->SetGenericFECStatus(enable, payload_typeRED, | |
773 payload_typeFEC) != 0) { | |
774 return -1; | |
775 } | |
776 CriticalSectionScoped cs(rtp_rtcp_cs_.get()); | |
777 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin(); | |
778 it != simulcast_rtp_rtcp_.end(); | |
779 it++) { | |
780 RtpRtcp* rtp_rtcp = *it; | |
781 rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC); | |
782 } | |
783 return 0; | |
784 } | |
785 | |
786 int32_t ViEChannel::SetHybridNACKFECStatus( | |
787 const bool enable, | |
788 const unsigned char payload_typeRED, | |
789 const unsigned char payload_typeFEC) { | |
790 if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) { | |
791 return -1; | |
792 } | |
793 | |
794 int32_t ret_val = 0; | |
795 ret_val = ProcessNACKRequest(enable); | |
796 if (ret_val < 0) { | |
797 return ret_val; | |
798 } | |
799 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC); | |
800 } | |
801 | |
802 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { | 760 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { |
803 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { | 761 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { |
804 LOG(LS_ERROR) << "Invalid send buffer value."; | 762 LOG(LS_ERROR) << "Invalid send buffer value."; |
805 return -1; | 763 return -1; |
806 } | 764 } |
807 if (target_delay_ms == 0) { | 765 if (target_delay_ms == 0) { |
808 // Real-time mode. | 766 // Real-time mode. |
809 nack_history_size_sender_ = kSendSidePacketHistorySize; | 767 nack_history_size_sender_ = kSendSidePacketHistorySize; |
810 } else { | 768 } else { |
811 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms); | 769 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms); |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 CriticalSectionScoped cs(callback_cs_.get()); | 1660 CriticalSectionScoped cs(callback_cs_.get()); |
1703 vcm_receive_stats_callback_ = receive_statistics_proxy; | 1661 vcm_receive_stats_callback_ = receive_statistics_proxy; |
1704 } | 1662 } |
1705 | 1663 |
1706 void ViEChannel::SetIncomingVideoStream( | 1664 void ViEChannel::SetIncomingVideoStream( |
1707 IncomingVideoStream* incoming_video_stream) { | 1665 IncomingVideoStream* incoming_video_stream) { |
1708 CriticalSectionScoped cs(callback_cs_.get()); | 1666 CriticalSectionScoped cs(callback_cs_.get()); |
1709 incoming_video_stream_ = incoming_video_stream; | 1667 incoming_video_stream_ = incoming_video_stream; |
1710 } | 1668 } |
1711 } // namespace webrtc | 1669 } // namespace webrtc |
OLD | NEW |