OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 25 matching lines...) Expand all Loading... |
36 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 36 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
37 #include "webrtc/media/engine/webrtcvoiceengine.h" | 37 #include "webrtc/media/engine/webrtcvoiceengine.h" |
38 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" | 38 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" |
39 #include "webrtc/system_wrappers/include/field_trial.h" | 39 #include "webrtc/system_wrappers/include/field_trial.h" |
40 | 40 |
41 using DegradationPreference = webrtc::VideoSendStream::DegradationPreference; | 41 using DegradationPreference = webrtc::VideoSendStream::DegradationPreference; |
42 | 42 |
43 namespace cricket { | 43 namespace cricket { |
44 namespace { | 44 namespace { |
45 // If this field trial is enabled, we will enable sending FlexFEC and disable | 45 // If this field trial is enabled, we will enable sending FlexFEC and disable |
46 // sending ULPFEC whenever the former has been negotiated. | 46 // sending ULPFEC whenever the former has been negotiated in the SDPs. |
47 // FlexFEC can only be negotiated when the "flexfec-03" SDP codec is enabled, | |
48 // which is done by enabling the "WebRTC-FlexFEC-03-Advertised" field trial; see | |
49 // internalencoderfactory.cc. | |
50 bool IsFlexfecFieldTrialEnabled() { | 47 bool IsFlexfecFieldTrialEnabled() { |
51 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); | 48 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); |
52 } | 49 } |
53 | 50 |
| 51 // If this field trial is enabled, the "flexfec-03" codec may have been |
| 52 // advertised as being supported in the local SDP. That means that we must be |
| 53 // ready to receive FlexFEC packets. See internalencoderfactory.cc. |
| 54 bool IsFlexfecAdvertisedFieldTrialEnabled() { |
| 55 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); |
| 56 } |
| 57 |
54 // If this field trial is enabled, we will report VideoContentType RTP extension | 58 // If this field trial is enabled, we will report VideoContentType RTP extension |
55 // in capabilities (thus, it will end up in the default SDP and extension will | 59 // in capabilities (thus, it will end up in the default SDP and extension will |
56 // be sent for all key-frames). | 60 // be sent for all key-frames). |
57 bool IsVideoContentTypeExtensionFieldTrialEnabled() { | 61 bool IsVideoContentTypeExtensionFieldTrialEnabled() { |
58 return webrtc::field_trial::IsEnabled("WebRTC-VideoContentTypeExtension"); | 62 return webrtc::field_trial::IsEnabled("WebRTC-VideoContentTypeExtension"); |
59 } | 63 } |
60 | 64 |
61 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. | 65 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. |
62 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { | 66 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { |
63 public: | 67 public: |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 | 702 |
699 bool WebRtcVideoChannel2::GetChangedSendParameters( | 703 bool WebRtcVideoChannel2::GetChangedSendParameters( |
700 const VideoSendParameters& params, | 704 const VideoSendParameters& params, |
701 ChangedSendParameters* changed_params) const { | 705 ChangedSendParameters* changed_params) const { |
702 if (!ValidateCodecFormats(params.codecs) || | 706 if (!ValidateCodecFormats(params.codecs) || |
703 !ValidateRtpExtensions(params.extensions)) { | 707 !ValidateRtpExtensions(params.extensions)) { |
704 return false; | 708 return false; |
705 } | 709 } |
706 | 710 |
707 // Select one of the remote codecs that will be used as send codec. | 711 // Select one of the remote codecs that will be used as send codec. |
708 const rtc::Optional<VideoCodecSettings> selected_send_codec = | 712 rtc::Optional<VideoCodecSettings> selected_send_codec = |
709 SelectSendVideoCodec(MapCodecs(params.codecs)); | 713 SelectSendVideoCodec(MapCodecs(params.codecs)); |
710 | 714 |
711 if (!selected_send_codec) { | 715 if (!selected_send_codec) { |
712 LOG(LS_ERROR) << "No video codecs supported."; | 716 LOG(LS_ERROR) << "No video codecs supported."; |
713 return false; | 717 return false; |
714 } | 718 } |
715 | 719 |
| 720 // Never enable sending FlexFEC, unless we are in the experiment. |
| 721 if (!IsFlexfecFieldTrialEnabled()) { |
| 722 if (selected_send_codec->flexfec_payload_type != -1) { |
| 723 LOG(LS_INFO) << "Remote supports flexfec-03, but we will not send since " |
| 724 << "WebRTC-FlexFEC-03 field trial is not enabled."; |
| 725 } |
| 726 selected_send_codec->flexfec_payload_type = -1; |
| 727 } |
| 728 |
716 if (!send_codec_ || *selected_send_codec != *send_codec_) | 729 if (!send_codec_ || *selected_send_codec != *send_codec_) |
717 changed_params->codec = selected_send_codec; | 730 changed_params->codec = selected_send_codec; |
718 | 731 |
719 // Handle RTP header extensions. | 732 // Handle RTP header extensions. |
720 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( | 733 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( |
721 params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true); | 734 params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true); |
722 if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) { | 735 if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) { |
723 changed_params->rtp_header_extensions = | 736 changed_params->rtp_header_extensions = |
724 rtc::Optional<std::vector<webrtc::RtpExtension>>(filtered_extensions); | 737 rtc::Optional<std::vector<webrtc::RtpExtension>>(filtered_extensions); |
725 } | 738 } |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 | 1276 |
1264 config->rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; | 1277 config->rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; |
1265 config->rtp.transport_cc = | 1278 config->rtp.transport_cc = |
1266 send_codec_ ? HasTransportCc(send_codec_->codec) : false; | 1279 send_codec_ ? HasTransportCc(send_codec_->codec) : false; |
1267 | 1280 |
1268 sp.GetFidSsrc(ssrc, &config->rtp.rtx_ssrc); | 1281 sp.GetFidSsrc(ssrc, &config->rtp.rtx_ssrc); |
1269 | 1282 |
1270 config->rtp.extensions = recv_rtp_extensions_; | 1283 config->rtp.extensions = recv_rtp_extensions_; |
1271 | 1284 |
1272 // TODO(brandtr): Generalize when we add support for multistream protection. | 1285 // TODO(brandtr): Generalize when we add support for multistream protection. |
1273 if (sp.GetFecFrSsrc(ssrc, &flexfec_config->remote_ssrc)) { | 1286 if (IsFlexfecAdvertisedFieldTrialEnabled() && |
| 1287 sp.GetFecFrSsrc(ssrc, &flexfec_config->remote_ssrc)) { |
1274 flexfec_config->protected_media_ssrcs = {ssrc}; | 1288 flexfec_config->protected_media_ssrcs = {ssrc}; |
1275 flexfec_config->local_ssrc = config->rtp.local_ssrc; | 1289 flexfec_config->local_ssrc = config->rtp.local_ssrc; |
1276 flexfec_config->rtcp_mode = config->rtp.rtcp_mode; | 1290 flexfec_config->rtcp_mode = config->rtp.rtcp_mode; |
1277 // TODO(brandtr): We should be spec-compliant and set |transport_cc| here | 1291 // TODO(brandtr): We should be spec-compliant and set |transport_cc| here |
1278 // based on the rtcp-fb for the FlexFEC codec, not the media codec. | 1292 // based on the rtcp-fb for the FlexFEC codec, not the media codec. |
1279 flexfec_config->transport_cc = config->rtp.transport_cc; | 1293 flexfec_config->transport_cc = config->rtp.transport_cc; |
1280 flexfec_config->rtp_header_extensions = config->rtp.extensions; | 1294 flexfec_config->rtp_header_extensions = config->rtp.extensions; |
1281 } | 1295 } |
1282 } | 1296 } |
1283 | 1297 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 | 1613 |
1600 // FlexFEC SSRCs. | 1614 // FlexFEC SSRCs. |
1601 // TODO(brandtr): This code needs to be generalized when we add support for | 1615 // TODO(brandtr): This code needs to be generalized when we add support for |
1602 // multistream protection. | 1616 // multistream protection. |
1603 if (IsFlexfecFieldTrialEnabled()) { | 1617 if (IsFlexfecFieldTrialEnabled()) { |
1604 uint32_t flexfec_ssrc; | 1618 uint32_t flexfec_ssrc; |
1605 bool flexfec_enabled = false; | 1619 bool flexfec_enabled = false; |
1606 for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) { | 1620 for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) { |
1607 if (sp.GetFecFrSsrc(primary_ssrc, &flexfec_ssrc)) { | 1621 if (sp.GetFecFrSsrc(primary_ssrc, &flexfec_ssrc)) { |
1608 if (flexfec_enabled) { | 1622 if (flexfec_enabled) { |
1609 LOG(LS_INFO) << "Multiple FlexFEC streams proposed by remote, but " | 1623 LOG(LS_INFO) << "Multiple FlexFEC streams in local SDP, but " |
1610 "our implementation only supports a single FlexFEC " | 1624 "our implementation only supports a single FlexFEC " |
1611 "stream. Will not enable FlexFEC for proposed " | 1625 "stream. Will not enable FlexFEC for proposed " |
1612 "stream with SSRC: " | 1626 "stream with SSRC: " |
1613 << flexfec_ssrc << "."; | 1627 << flexfec_ssrc << "."; |
1614 continue; | 1628 continue; |
1615 } | 1629 } |
1616 | 1630 |
1617 flexfec_enabled = true; | 1631 flexfec_enabled = true; |
1618 parameters_.config.rtp.flexfec.ssrc = flexfec_ssrc; | 1632 parameters_.config.rtp.flexfec.ssrc = flexfec_ssrc; |
1619 parameters_.config.rtp.flexfec.protected_media_ssrcs = {primary_ssrc}; | 1633 parameters_.config.rtp.flexfec.protected_media_ssrcs = {primary_ssrc}; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 if (new_encoder.external) { | 1788 if (new_encoder.external) { |
1775 webrtc::VideoCodecType type = | 1789 webrtc::VideoCodecType type = |
1776 webrtc::PayloadNameToCodecType(codec_settings.codec.name) | 1790 webrtc::PayloadNameToCodecType(codec_settings.codec.name) |
1777 .value_or(webrtc::kVideoCodecUnknown); | 1791 .value_or(webrtc::kVideoCodecUnknown); |
1778 parameters_.config.encoder_settings.internal_source = | 1792 parameters_.config.encoder_settings.internal_source = |
1779 external_encoder_factory_->EncoderTypeHasInternalSource(type); | 1793 external_encoder_factory_->EncoderTypeHasInternalSource(type); |
1780 } else { | 1794 } else { |
1781 parameters_.config.encoder_settings.internal_source = false; | 1795 parameters_.config.encoder_settings.internal_source = false; |
1782 } | 1796 } |
1783 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; | 1797 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; |
1784 if (IsFlexfecFieldTrialEnabled()) { | 1798 parameters_.config.rtp.flexfec.payload_type = |
1785 parameters_.config.rtp.flexfec.payload_type = | 1799 codec_settings.flexfec_payload_type; |
1786 codec_settings.flexfec_payload_type; | |
1787 } | |
1788 | 1800 |
1789 // Set RTX payload type if RTX is enabled. | 1801 // Set RTX payload type if RTX is enabled. |
1790 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { | 1802 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { |
1791 if (codec_settings.rtx_payload_type == -1) { | 1803 if (codec_settings.rtx_payload_type == -1) { |
1792 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 1804 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
1793 "payload type. Ignoring."; | 1805 "payload type. Ignoring."; |
1794 parameters_.config.rtp.rtx.ssrcs.clear(); | 1806 parameters_.config.rtp.rtx.ssrcs.clear(); |
1795 } else { | 1807 } else { |
1796 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; | 1808 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; |
1797 } | 1809 } |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2595 rtx_mapping[video_codecs[i].codec.id] != | 2607 rtx_mapping[video_codecs[i].codec.id] != |
2596 ulpfec_config.red_payload_type) { | 2608 ulpfec_config.red_payload_type) { |
2597 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2609 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
2598 } | 2610 } |
2599 } | 2611 } |
2600 | 2612 |
2601 return video_codecs; | 2613 return video_codecs; |
2602 } | 2614 } |
2603 | 2615 |
2604 } // namespace cricket | 2616 } // namespace cricket |
OLD | NEW |