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 #include "webrtc/video/video_send_stream.h" | 10 #include "webrtc/video/video_send_stream.h" |
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
925 encoded_image, codec_specific_info->codecType); | 925 encoded_image, codec_specific_info->codecType); |
926 RTC_DCHECK(ok); | 926 RTC_DCHECK(ok); |
927 } | 927 } |
928 } | 928 } |
929 | 929 |
930 return result; | 930 return result; |
931 } | 931 } |
932 | 932 |
933 void VideoSendStreamImpl::ConfigureProtection() { | 933 void VideoSendStreamImpl::ConfigureProtection() { |
934 RTC_DCHECK_RUN_ON(worker_queue_); | 934 RTC_DCHECK_RUN_ON(worker_queue_); |
935 // Enable NACK, FEC or both. | 935 |
936 const bool enable_protection_nack = config_->rtp.nack.rtp_history_ms > 0; | 936 const bool nack_enabled = config_->rtp.nack.rtp_history_ms > 0; |
937 const int red_payload_type = config_->rtp.ulpfec.red_payload_type; | 937 int red_payload_type = config_->rtp.ulpfec.red_payload_type; |
938 int ulpfec_payload_type = config_->rtp.ulpfec.ulpfec_payload_type; | 938 int ulpfec_payload_type = config_->rtp.ulpfec.ulpfec_payload_type; |
939 | |
940 // Shorthands. | |
941 auto IsRedEnabled = [&]() { return red_payload_type >= 0; }; | |
942 auto DisableRed = [&]() { red_payload_type = -1; }; | |
943 auto IsUlpfecEnabled = [&]() { return ulpfec_payload_type >= 0; }; | |
944 auto DisableUlpfec = [&]() { ulpfec_payload_type = -1; }; | |
945 | |
939 // Payload types without picture ID cannot determine that a stream is complete | 946 // Payload types without picture ID cannot determine that a stream is complete |
940 // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is | 947 // without retransmitting FEC, so using ULPFEC + NACK for H.264 (for instance) |
941 // a waste of bandwidth since FEC packets still have to be transmitted. Note | 948 // is a waste of bandwidth since FEC packets still have to be transmitted. |
942 // that this is not the case with FLEXFEC. | 949 // Note that this is not the case with FlexFEC. |
943 if (enable_protection_nack && | 950 if (nack_enabled && IsUlpfecEnabled() && |
944 !PayloadTypeSupportsSkippingFecPackets( | 951 !PayloadTypeSupportsSkippingFecPackets( |
945 config_->encoder_settings.payload_name)) { | 952 config_->encoder_settings.payload_name)) { |
946 LOG(LS_WARNING) << "Transmitting payload type without picture ID using" | 953 LOG(LS_WARNING) |
947 "NACK+FEC is a waste of bandwidth since FEC packets " | 954 << "Transmitting payload type without picture ID using " |
948 "also have to be retransmitted. Disabling FEC."; | 955 "NACK+ULPFEC is a waste of bandwidth since ULPFEC packets " |
949 ulpfec_payload_type = -1; | 956 "also have to be retransmitted. Disabling RED and ULPFEC."; |
957 DisableRed(); | |
958 DisableUlpfec(); | |
stefan-webrtc
2016/11/02 14:24:53
As discussed offline, this is not safe to do witho
brandtr
2016/11/03 12:02:48
Thanks for finding this!
I tried to compile all c
| |
950 } | 959 } |
951 | 960 |
952 // TODO(brandtr): Remove the workaround described below. | 961 // Verify payload types and disable RED/ULPFEC if the other one is disabled. |
953 // | 962 if (IsRedEnabled()) { |
954 // In theory, we should enable RED if and only if ULPFEC is also enabled, | |
955 // and vice versa. (We only support ULPFEC over RED, not multiplexed in any | |
956 // other way.) However, due to the RED/RTX workaround introduced here: | |
957 // https://codereview.webrtc.org/1649493004, we need to send media over RED | |
958 // (even if ULPFEC is disabled), whenever RED has been negotiated in the SDP. | |
959 // This is due to the associated payload type is hardcoded to be RED in the | |
960 // receiver, whenever RED appears in the SDP. If we would not send media over | |
961 // RED in this case, the RTX receiver would recover retransmitted packets | |
962 // using the wrong payload type. | |
963 | |
964 // Verify validity of provided payload types. | |
965 if (red_payload_type != -1) { | |
966 RTC_DCHECK_GE(red_payload_type, 0); | 963 RTC_DCHECK_GE(red_payload_type, 0); |
967 RTC_DCHECK_LE(red_payload_type, 127); | 964 RTC_DCHECK_LE(red_payload_type, 127); |
965 if (!IsUlpfecEnabled()) { | |
966 LOG(LS_WARNING) | |
967 << "RED is enabled but ULPFEC is disabled. Disabling RED."; | |
968 DisableRed(); | |
969 } | |
968 } | 970 } |
969 if (ulpfec_payload_type != -1) { | 971 if (IsUlpfecEnabled()) { |
970 RTC_DCHECK_GE(ulpfec_payload_type, 0); | 972 RTC_DCHECK_GE(ulpfec_payload_type, 0); |
971 RTC_DCHECK_LE(ulpfec_payload_type, 127); | 973 RTC_DCHECK_LE(ulpfec_payload_type, 127); |
974 if (!IsRedEnabled()) { | |
975 LOG(LS_WARNING) | |
976 << "ULPFEC is enabled but RED is disabled. Disabling ULPFEC."; | |
977 DisableUlpfec(); | |
978 } | |
972 } | 979 } |
973 | 980 |
974 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 981 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
975 // Set NACK. | 982 // Set NACK. |
976 rtp_rtcp->SetStorePacketsStatus( | 983 rtp_rtcp->SetStorePacketsStatus( |
977 enable_protection_nack || congestion_controller_->pacer(), | 984 nack_enabled || congestion_controller_->pacer(), |
978 kMinSendSidePacketHistorySize); | 985 kMinSendSidePacketHistorySize); |
979 // Set FEC. | 986 // Set RED/ULPFEC information. |
980 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 987 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
981 rtp_rtcp->SetUlpfecConfig(red_payload_type, ulpfec_payload_type); | 988 rtp_rtcp->SetUlpfecConfig(red_payload_type, ulpfec_payload_type); |
982 } | 989 } |
983 } | 990 } |
984 | 991 |
985 const bool enable_protection_fec = (ulpfec_payload_type != -1); | 992 protection_bitrate_calculator_.SetProtectionMethod(IsUlpfecEnabled(), |
986 protection_bitrate_calculator_.SetProtectionMethod(enable_protection_fec, | 993 nack_enabled); |
987 enable_protection_nack); | |
988 } | 994 } |
989 | 995 |
990 void VideoSendStreamImpl::ConfigureSsrcs() { | 996 void VideoSendStreamImpl::ConfigureSsrcs() { |
991 RTC_DCHECK_RUN_ON(worker_queue_); | 997 RTC_DCHECK_RUN_ON(worker_queue_); |
992 // Configure regular SSRCs. | 998 // Configure regular SSRCs. |
993 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) { | 999 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) { |
994 uint32_t ssrc = config_->rtp.ssrcs[i]; | 1000 uint32_t ssrc = config_->rtp.ssrcs[i]; |
995 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; | 1001 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i]; |
996 rtp_rtcp->SetSSRC(ssrc); | 1002 rtp_rtcp->SetSSRC(ssrc); |
997 | 1003 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1117 &module_nack_rate); | 1123 &module_nack_rate); |
1118 *sent_video_rate_bps += module_video_rate; | 1124 *sent_video_rate_bps += module_video_rate; |
1119 *sent_nack_rate_bps += module_nack_rate; | 1125 *sent_nack_rate_bps += module_nack_rate; |
1120 *sent_fec_rate_bps += module_fec_rate; | 1126 *sent_fec_rate_bps += module_fec_rate; |
1121 } | 1127 } |
1122 return 0; | 1128 return 0; |
1123 } | 1129 } |
1124 | 1130 |
1125 } // namespace internal | 1131 } // namespace internal |
1126 } // namespace webrtc | 1132 } // namespace webrtc |
OLD | NEW |