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 |
11 #include "webrtc/media/engine/webrtcvideoengine.h" | 11 #include "webrtc/media/engine/webrtcvideoengine.h" |
12 | 12 |
13 #include <stdio.h> | 13 #include <stdio.h> |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <set> | 15 #include <set> |
16 #include <string> | 16 #include <string> |
17 #include <utility> | 17 #include <utility> |
18 | 18 |
19 #include "webrtc/api/video/i420_buffer.h" | 19 #include "webrtc/api/video/i420_buffer.h" |
20 #include "webrtc/api/video_codecs/video_decoder.h" | 20 #include "webrtc/api/video_codecs/video_decoder.h" |
21 #include "webrtc/api/video_codecs/video_encoder.h" | 21 #include "webrtc/api/video_codecs/video_encoder.h" |
22 #include "webrtc/call/call.h" | 22 #include "webrtc/call/call.h" |
23 #include "webrtc/common_video/h264/profile_level_id.h" | 23 #include "webrtc/common_video/h264/profile_level_id.h" |
| 24 #include "webrtc/media/base/codec.h" |
24 #include "webrtc/media/engine/constants.h" | 25 #include "webrtc/media/engine/constants.h" |
25 #include "webrtc/media/engine/internaldecoderfactory.h" | 26 #include "webrtc/media/engine/internaldecoderfactory.h" |
26 #include "webrtc/media/engine/internalencoderfactory.h" | 27 #include "webrtc/media/engine/internalencoderfactory.h" |
27 #include "webrtc/media/engine/simulcast.h" | 28 #include "webrtc/media/engine/simulcast.h" |
28 #include "webrtc/media/engine/simulcast_encoder_adapter.h" | 29 #include "webrtc/media/engine/simulcast_encoder_adapter.h" |
29 #include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h" | 30 #include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h" |
30 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" | 31 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" |
31 #include "webrtc/media/engine/webrtcmediaengine.h" | 32 #include "webrtc/media/engine/webrtcmediaengine.h" |
32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
33 #include "webrtc/media/engine/webrtcvoiceengine.h" | 34 #include "webrtc/media/engine/webrtcvoiceengine.h" |
| 35 #include "webrtc/modules/video_coding/codecs/stereo/include/stereo_decoder_adapt
er.h" |
| 36 #include "webrtc/modules/video_coding/codecs/stereo/include/stereo_encoder_adapt
er.h" |
34 #include "webrtc/rtc_base/copyonwritebuffer.h" | 37 #include "webrtc/rtc_base/copyonwritebuffer.h" |
35 #include "webrtc/rtc_base/logging.h" | 38 #include "webrtc/rtc_base/logging.h" |
36 #include "webrtc/rtc_base/stringutils.h" | 39 #include "webrtc/rtc_base/stringutils.h" |
37 #include "webrtc/rtc_base/timeutils.h" | 40 #include "webrtc/rtc_base/timeutils.h" |
38 #include "webrtc/rtc_base/trace_event.h" | 41 #include "webrtc/rtc_base/trace_event.h" |
39 #include "webrtc/system_wrappers/include/field_trial.h" | 42 #include "webrtc/system_wrappers/include/field_trial.h" |
40 | 43 |
41 using DegradationPreference = webrtc::VideoSendStream::DegradationPreference; | 44 using DegradationPreference = webrtc::VideoSendStream::DegradationPreference; |
42 | 45 |
43 namespace cricket { | 46 namespace cricket { |
(...skipping 11 matching lines...) Expand all Loading... |
55 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); | 58 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); |
56 } | 59 } |
57 | 60 |
58 // If this field trial is enabled, we will report VideoContentType RTP extension | 61 // If this field trial is enabled, we will report VideoContentType RTP extension |
59 // in capabilities (thus, it will end up in the default SDP and extension will | 62 // in capabilities (thus, it will end up in the default SDP and extension will |
60 // be sent for all key-frames). | 63 // be sent for all key-frames). |
61 bool IsVideoContentTypeExtensionFieldTrialEnabled() { | 64 bool IsVideoContentTypeExtensionFieldTrialEnabled() { |
62 return webrtc::field_trial::IsEnabled("WebRTC-VideoContentTypeExtension"); | 65 return webrtc::field_trial::IsEnabled("WebRTC-VideoContentTypeExtension"); |
63 } | 66 } |
64 | 67 |
| 68 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. |
| 69 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { |
| 70 public: |
| 71 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned |
| 72 // by e.g. PeerConnectionFactory. |
| 73 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory, |
| 74 const cricket::VideoCodec& codec) |
| 75 : factory_(factory), codec_(codec) {} |
| 76 virtual ~EncoderFactoryAdapter() {} |
| 77 |
| 78 // Implement webrtc::VideoEncoderFactory. |
| 79 webrtc::VideoEncoder* Create() override { |
| 80 return factory_->CreateVideoEncoder(codec_); |
| 81 } |
| 82 |
| 83 void Destroy(webrtc::VideoEncoder* encoder) override { |
| 84 return factory_->DestroyVideoEncoder(encoder); |
| 85 } |
| 86 |
| 87 private: |
| 88 cricket::WebRtcVideoEncoderFactory* const factory_; |
| 89 const cricket::VideoCodec codec_; |
| 90 }; |
| 91 |
65 // An encoder factory that wraps Create requests for simulcastable codec types | 92 // An encoder factory that wraps Create requests for simulcastable codec types |
66 // with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type | 93 // with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type |
67 // requests are just passed through to the contained encoder factory. | 94 // requests are just passed through to the contained encoder factory. |
68 class WebRtcSimulcastEncoderFactory | 95 class WebRtcSimulcastEncoderFactory |
69 : public cricket::WebRtcVideoEncoderFactory { | 96 : public cricket::WebRtcVideoEncoderFactory { |
70 public: | 97 public: |
71 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is | 98 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is |
72 // owned by e.g. PeerConnectionFactory. | 99 // owned by e.g. PeerConnectionFactory. |
73 explicit WebRtcSimulcastEncoderFactory( | 100 explicit WebRtcSimulcastEncoderFactory( |
74 cricket::WebRtcVideoEncoderFactory* factory) | 101 cricket::WebRtcVideoEncoderFactory* factory) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 delete encoder; | 151 delete encoder; |
125 } | 152 } |
126 | 153 |
127 private: | 154 private: |
128 cricket::WebRtcVideoEncoderFactory* factory_; | 155 cricket::WebRtcVideoEncoderFactory* factory_; |
129 // A list of encoders that were created without being wrapped in a | 156 // A list of encoders that were created without being wrapped in a |
130 // SimulcastEncoderAdapter. | 157 // SimulcastEncoderAdapter. |
131 std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; | 158 std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; |
132 }; | 159 }; |
133 | 160 |
| 161 // An encoder factory that wraps Create requests for all codec types |
| 162 // with a webrtc::StereoEncoderAdapter. |
| 163 class WebRtcStereoEncoderFactory : public cricket::WebRtcVideoEncoderFactory { |
| 164 public: |
| 165 explicit WebRtcStereoEncoderFactory( |
| 166 cricket::WebRtcVideoEncoderFactory* factory) |
| 167 : factory_(factory) {} |
| 168 |
| 169 webrtc::VideoEncoder* CreateVideoEncoder( |
| 170 const cricket::VideoCodec& codec) override { |
| 171 RTC_DCHECK(factory_ != NULL); |
| 172 return new webrtc::StereoEncoderAdapter( |
| 173 new EncoderFactoryAdapter(factory_, codec)); |
| 174 } |
| 175 |
| 176 const std::vector<cricket::VideoCodec>& supported_codecs() const override { |
| 177 return factory_->supported_codecs(); |
| 178 } |
| 179 |
| 180 bool EncoderTypeHasInternalSource( |
| 181 webrtc::VideoCodecType type) const override { |
| 182 return factory_->EncoderTypeHasInternalSource(type); |
| 183 } |
| 184 |
| 185 void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { |
| 186 delete encoder; |
| 187 } |
| 188 |
| 189 private: |
| 190 cricket::WebRtcVideoEncoderFactory* factory_; |
| 191 }; |
| 192 |
| 193 // Wrap cricket::WebRtcVideoDecoderFactory as a webrtc::VideoDecoderFactory. |
| 194 class DecoderFactoryAdapter : public webrtc::VideoDecoderFactory { |
| 195 public: |
| 196 // DecoderFactoryAdapter doesn't take ownership of |factory|. |
| 197 explicit DecoderFactoryAdapter(cricket::WebRtcVideoDecoderFactory* factory, |
| 198 webrtc::VideoCodecType type, |
| 199 VideoDecoderParams* params) |
| 200 : factory_(factory), type_(type) { |
| 201 if (params) { |
| 202 params_.reset(new VideoDecoderParams(*params)); |
| 203 } |
| 204 } |
| 205 virtual ~DecoderFactoryAdapter() {} |
| 206 |
| 207 // Implement webrtc::VideoDecoderFactory. |
| 208 webrtc::VideoDecoder* Create() override { |
| 209 RTC_DCHECK(factory_); |
| 210 if (params_) |
| 211 return factory_->CreateVideoDecoderWithParams(type_, *params_); |
| 212 else |
| 213 return factory_->CreateVideoDecoder(type_); |
| 214 } |
| 215 |
| 216 void Destroy(webrtc::VideoDecoder* decoder) override { |
| 217 return factory_->DestroyVideoDecoder(decoder); |
| 218 } |
| 219 |
| 220 private: |
| 221 cricket::WebRtcVideoDecoderFactory* const factory_; |
| 222 const webrtc::VideoCodecType type_; |
| 223 std::unique_ptr<VideoDecoderParams> params_; |
| 224 }; |
| 225 |
| 226 // A decoder factory that wraps Create requests for all codec types |
| 227 // with a webrtc::StereoDecoderAdapter. |
| 228 class WebRtcStereoDecoderFactory : public cricket::WebRtcVideoDecoderFactory { |
| 229 public: |
| 230 explicit WebRtcStereoDecoderFactory( |
| 231 cricket::WebRtcVideoDecoderFactory* factory) |
| 232 : factory_(factory) {} |
| 233 |
| 234 webrtc::VideoDecoder* CreateVideoDecoder( |
| 235 webrtc::VideoCodecType type) override { |
| 236 RTC_DCHECK(factory_ != NULL); |
| 237 return new webrtc::StereoDecoderAdapter( |
| 238 new DecoderFactoryAdapter(factory_, webrtc::kVideoCodecVP9, nullptr)); |
| 239 } |
| 240 |
| 241 webrtc::VideoDecoder* CreateVideoDecoderWithParams( |
| 242 webrtc::VideoCodecType type, |
| 243 VideoDecoderParams params) override { |
| 244 RTC_DCHECK(factory_ != NULL); |
| 245 return new webrtc::StereoDecoderAdapter( |
| 246 new DecoderFactoryAdapter(factory_, webrtc::kVideoCodecVP9, ¶ms)); |
| 247 } |
| 248 |
| 249 void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override { |
| 250 delete decoder; |
| 251 } |
| 252 |
| 253 private: |
| 254 cricket::WebRtcVideoDecoderFactory* factory_; |
| 255 }; |
| 256 |
134 void AddDefaultFeedbackParams(VideoCodec* codec) { | 257 void AddDefaultFeedbackParams(VideoCodec* codec) { |
135 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); | 258 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); |
136 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); | 259 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); |
137 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); | 260 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); |
138 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); | 261 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); |
139 codec->AddFeedbackParam( | 262 codec->AddFeedbackParam( |
140 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | 263 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); |
141 } | 264 } |
142 | 265 |
143 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { | 266 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 CodecNamesEq(codec.name, kVp9CodecName) || | 642 CodecNamesEq(codec.name, kVp9CodecName) || |
520 CodecNamesEq(codec.name, kH264CodecName) || | 643 CodecNamesEq(codec.name, kH264CodecName) || |
521 CodecNamesEq(codec.name, kRedCodecName)) { | 644 CodecNamesEq(codec.name, kRedCodecName)) { |
522 const rtc::Optional<int> rtx_payload_type = | 645 const rtc::Optional<int> rtx_payload_type = |
523 NextFreePayloadType(*unified_codecs); | 646 NextFreePayloadType(*unified_codecs); |
524 if (!rtx_payload_type) | 647 if (!rtx_payload_type) |
525 return; | 648 return; |
526 unified_codecs->push_back( | 649 unified_codecs->push_back( |
527 VideoCodec::CreateRtxCodec(*rtx_payload_type, codec.id)); | 650 VideoCodec::CreateRtxCodec(*rtx_payload_type, codec.id)); |
528 } | 651 } |
| 652 |
| 653 if (CodecNamesEq(codec.name, kVp9CodecName)) { |
| 654 const rtc::Optional<int> stereo_payload_type = |
| 655 NextFreePayloadType(*unified_codecs); |
| 656 if (!stereo_payload_type) |
| 657 return; |
| 658 unified_codecs->push_back( |
| 659 VideoCodec::CreateStereoCodec(*stereo_payload_type, codec)); |
| 660 } |
529 } | 661 } |
530 } | 662 } |
531 | 663 |
532 static std::vector<VideoCodec> GetSupportedCodecs( | 664 static std::vector<VideoCodec> GetSupportedCodecs( |
533 const WebRtcVideoEncoderFactory* external_encoder_factory) { | 665 const WebRtcVideoEncoderFactory* external_encoder_factory) { |
534 const std::vector<VideoCodec> internal_codecs = | 666 const std::vector<VideoCodec> internal_codecs = |
535 InternalEncoderFactory().supported_codecs(); | 667 InternalEncoderFactory().supported_codecs(); |
536 LOG(LS_INFO) << "Internally supported codecs: " | 668 LOG(LS_INFO) << "Internally supported codecs: " |
537 << CodecVectorToString(internal_codecs); | 669 << CodecVectorToString(internal_codecs); |
538 | 670 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 delete kv.second; | 709 delete kv.second; |
578 for (auto& kv : receive_streams_) | 710 for (auto& kv : receive_streams_) |
579 delete kv.second; | 711 delete kv.second; |
580 } | 712 } |
581 | 713 |
582 rtc::Optional<WebRtcVideoChannel::VideoCodecSettings> | 714 rtc::Optional<WebRtcVideoChannel::VideoCodecSettings> |
583 WebRtcVideoChannel::SelectSendVideoCodec( | 715 WebRtcVideoChannel::SelectSendVideoCodec( |
584 const std::vector<VideoCodecSettings>& remote_mapped_codecs) const { | 716 const std::vector<VideoCodecSettings>& remote_mapped_codecs) const { |
585 const std::vector<VideoCodec> local_supported_codecs = | 717 const std::vector<VideoCodec> local_supported_codecs = |
586 GetSupportedCodecs(external_encoder_factory_); | 718 GetSupportedCodecs(external_encoder_factory_); |
| 719 |
587 // Select the first remote codec that is supported locally. | 720 // Select the first remote codec that is supported locally. |
588 for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) { | 721 for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) { |
| 722 // HARDCODE TO ALPHA |
| 723 if (!cricket::VideoCodec::IsStereoCodec(remote_mapped_codec.codec)) |
| 724 continue; |
589 // For H264, we will limit the encode level to the remote offered level | 725 // For H264, we will limit the encode level to the remote offered level |
590 // regardless if level asymmetry is allowed or not. This is strictly not | 726 // regardless if level asymmetry is allowed or not. This is strictly not |
591 // following the spec in https://tools.ietf.org/html/rfc6184#section-8.2.2 | 727 // following the spec in https://tools.ietf.org/html/rfc6184#section-8.2.2 |
592 // since we should limit the encode level to the lower of local and remote | 728 // since we should limit the encode level to the lower of local and remote |
593 // level when level asymmetry is not allowed. | 729 // level when level asymmetry is not allowed. |
594 if (FindMatchingCodec(local_supported_codecs, remote_mapped_codec.codec)) | 730 if (FindMatchingCodec(local_supported_codecs, remote_mapped_codec.codec)) |
595 return rtc::Optional<VideoCodecSettings>(remote_mapped_codec); | 731 return rtc::Optional<VideoCodecSettings>(remote_mapped_codec); |
596 } | 732 } |
597 // No remote codec was supported. | 733 // No remote codec was supported. |
598 return rtc::Optional<VideoCodecSettings>(); | 734 return rtc::Optional<VideoCodecSettings>(); |
599 } | 735 } |
600 | 736 |
| 737 rtc::Optional<WebRtcVideoChannel::VideoCodecSettings> |
| 738 WebRtcVideoChannel::SelectStereoAssociatedVideoCodec( |
| 739 const std::vector<VideoCodecSettings>& remote_mapped_codecs) const { |
| 740 const std::vector<VideoCodec> local_supported_codecs = |
| 741 GetSupportedCodecs(external_encoder_factory_); |
| 742 |
| 743 // Select the first remote codec that is supported locally. |
| 744 for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) { |
| 745 // HARDCODE TO VP9 |
| 746 if (!CodecNamesEq(remote_mapped_codec.codec.name.c_str(), kVp9CodecName)) |
| 747 continue; |
| 748 if (!cricket::VideoCodec::IsStereoCodec(remote_mapped_codec.codec) && |
| 749 FindMatchingCodec(local_supported_codecs, remote_mapped_codec.codec)) |
| 750 return rtc::Optional<VideoCodecSettings>(remote_mapped_codec); |
| 751 } |
| 752 return rtc::Optional<VideoCodecSettings>(); |
| 753 } |
| 754 |
601 bool WebRtcVideoChannel::NonFlexfecReceiveCodecsHaveChanged( | 755 bool WebRtcVideoChannel::NonFlexfecReceiveCodecsHaveChanged( |
602 std::vector<VideoCodecSettings> before, | 756 std::vector<VideoCodecSettings> before, |
603 std::vector<VideoCodecSettings> after) { | 757 std::vector<VideoCodecSettings> after) { |
604 if (before.size() != after.size()) { | 758 if (before.size() != after.size()) { |
605 return true; | 759 return true; |
606 } | 760 } |
607 | 761 |
608 // The receive codec order doesn't matter, so we sort the codecs before | 762 // The receive codec order doesn't matter, so we sort the codecs before |
609 // comparing. This is necessary because currently the | 763 // comparing. This is necessary because currently the |
610 // only way to change the send codec is to munge SDP, which causes | 764 // only way to change the send codec is to munge SDP, which causes |
(...skipping 26 matching lines...) Expand all Loading... |
637 | 791 |
638 // Select one of the remote codecs that will be used as send codec. | 792 // Select one of the remote codecs that will be used as send codec. |
639 rtc::Optional<VideoCodecSettings> selected_send_codec = | 793 rtc::Optional<VideoCodecSettings> selected_send_codec = |
640 SelectSendVideoCodec(MapCodecs(params.codecs)); | 794 SelectSendVideoCodec(MapCodecs(params.codecs)); |
641 | 795 |
642 if (!selected_send_codec) { | 796 if (!selected_send_codec) { |
643 LOG(LS_ERROR) << "No video codecs supported."; | 797 LOG(LS_ERROR) << "No video codecs supported."; |
644 return false; | 798 return false; |
645 } | 799 } |
646 | 800 |
| 801 if (VideoCodec::IsStereoCodec(selected_send_codec->codec)) { |
| 802 rtc::Optional<VideoCodecSettings> associated_codec_settings = |
| 803 SelectStereoAssociatedVideoCodec(MapCodecs(params.codecs)); |
| 804 LOG(LS_ERROR) << __func__ << associated_codec_settings->codec.ToString(); |
| 805 if (!associated_codec_settings) { |
| 806 LOG(LS_ERROR) |
| 807 << "Stereo codec is not associated with any supported codec."; |
| 808 return false; |
| 809 } |
| 810 associated_codec_settings->stereo_codec.emplace(selected_send_codec->codec); |
| 811 selected_send_codec = associated_codec_settings; |
| 812 } |
| 813 |
647 // Never enable sending FlexFEC, unless we are in the experiment. | 814 // Never enable sending FlexFEC, unless we are in the experiment. |
648 if (!IsFlexfecFieldTrialEnabled()) { | 815 if (!IsFlexfecFieldTrialEnabled()) { |
649 if (selected_send_codec->flexfec_payload_type != -1) { | 816 if (selected_send_codec->flexfec_payload_type != -1) { |
650 LOG(LS_INFO) << "Remote supports flexfec-03, but we will not send since " | 817 LOG(LS_INFO) << "Remote supports flexfec-03, but we will not send since " |
651 << "WebRTC-FlexFEC-03 field trial is not enabled."; | 818 << "WebRTC-FlexFEC-03 field trial is not enabled."; |
652 } | 819 } |
653 selected_send_codec->flexfec_payload_type = -1; | 820 selected_send_codec->flexfec_payload_type = -1; |
654 } | 821 } |
655 | 822 |
656 if (!send_codec_ || *selected_send_codec != *send_codec_) | 823 if (!send_codec_ || *selected_send_codec != *send_codec_) |
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 } | 1832 } |
1666 return degradation_preference; | 1833 return degradation_preference; |
1667 } | 1834 } |
1668 | 1835 |
1669 const std::vector<uint32_t>& | 1836 const std::vector<uint32_t>& |
1670 WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { | 1837 WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { |
1671 return ssrcs_; | 1838 return ssrcs_; |
1672 } | 1839 } |
1673 | 1840 |
1674 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder | 1841 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder |
| 1842 WebRtcVideoChannel::WebRtcVideoSendStream::CreateStereoVideoEncoder( |
| 1843 const VideoCodec& codec) { |
| 1844 WebRtcStereoEncoderFactory* stereo_factory = |
| 1845 new WebRtcStereoEncoderFactory(internal_encoder_factory_.get()); |
| 1846 stereo_encoder_factory_.reset(stereo_factory); |
| 1847 return AllocatedEncoder(stereo_factory->CreateVideoEncoder(codec), codec, |
| 1848 false /* is_external */); |
| 1849 } |
| 1850 |
| 1851 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder |
1675 WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( | 1852 WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( |
1676 const VideoCodec& codec, | 1853 const VideoCodec& codec, |
1677 bool force_encoder_allocation) { | 1854 bool force_encoder_allocation) { |
1678 RTC_DCHECK_RUN_ON(&thread_checker_); | 1855 RTC_DCHECK_RUN_ON(&thread_checker_); |
1679 // Do not re-create encoders of the same type. | 1856 // Do not re-create encoders of the same type. |
1680 if (!force_encoder_allocation && codec == allocated_encoder_.codec && | 1857 if (!force_encoder_allocation && codec == allocated_encoder_.codec && |
1681 allocated_encoder_.encoder != nullptr) { | 1858 allocated_encoder_.encoder != nullptr) { |
1682 return allocated_encoder_; | 1859 return allocated_encoder_; |
1683 } | 1860 } |
1684 | 1861 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 delete encoder->encoder; | 1900 delete encoder->encoder; |
1724 } | 1901 } |
1725 | 1902 |
1726 void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( | 1903 void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( |
1727 const VideoCodecSettings& codec_settings, | 1904 const VideoCodecSettings& codec_settings, |
1728 bool force_encoder_allocation) { | 1905 bool force_encoder_allocation) { |
1729 RTC_DCHECK_RUN_ON(&thread_checker_); | 1906 RTC_DCHECK_RUN_ON(&thread_checker_); |
1730 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); | 1907 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); |
1731 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0); | 1908 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0); |
1732 | 1909 |
| 1910 const bool is_stereo_codec = codec_settings.stereo_codec.has_value(); |
1733 AllocatedEncoder new_encoder = | 1911 AllocatedEncoder new_encoder = |
1734 CreateVideoEncoder(codec_settings.codec, force_encoder_allocation); | 1912 is_stereo_codec |
| 1913 ? CreateStereoVideoEncoder(codec_settings.codec) |
| 1914 : CreateVideoEncoder(codec_settings.codec, force_encoder_allocation); |
| 1915 VideoCodec payload_codec = is_stereo_codec |
| 1916 ? codec_settings.stereo_codec.value() |
| 1917 : codec_settings.codec; |
| 1918 |
1735 parameters_.config.encoder_settings.encoder = new_encoder.encoder; | 1919 parameters_.config.encoder_settings.encoder = new_encoder.encoder; |
| 1920 parameters_.config.encoder_settings.payload_name = payload_codec.name; |
| 1921 parameters_.config.encoder_settings.payload_type = payload_codec.id; |
| 1922 parameters_.config.encoder_settings.stereo_associated_payload_name = |
| 1923 codec_settings.codec.name; |
1736 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; | 1924 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; |
1737 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; | |
1738 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; | |
1739 if (new_encoder.external) { | 1925 if (new_encoder.external) { |
1740 webrtc::VideoCodecType type = | 1926 webrtc::VideoCodecType type = |
1741 webrtc::PayloadNameToCodecType(codec_settings.codec.name) | 1927 webrtc::PayloadNameToCodecType(codec_settings.codec.name) |
1742 .value_or(webrtc::kVideoCodecUnknown); | 1928 .value_or(webrtc::kVideoCodecUnknown); |
1743 parameters_.config.encoder_settings.internal_source = | 1929 parameters_.config.encoder_settings.internal_source = |
1744 external_encoder_factory_->EncoderTypeHasInternalSource(type); | 1930 external_encoder_factory_->EncoderTypeHasInternalSource(type); |
1745 } else { | 1931 } else { |
1746 parameters_.config.encoder_settings.internal_source = false; | 1932 parameters_.config.encoder_settings.internal_source = false; |
1747 } | 1933 } |
1748 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; | 1934 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 } | 2168 } |
1983 } | 2169 } |
1984 | 2170 |
1985 VideoSenderInfo WebRtcVideoChannel::WebRtcVideoSendStream::GetVideoSenderInfo( | 2171 VideoSenderInfo WebRtcVideoChannel::WebRtcVideoSendStream::GetVideoSenderInfo( |
1986 bool log_stats) { | 2172 bool log_stats) { |
1987 VideoSenderInfo info; | 2173 VideoSenderInfo info; |
1988 RTC_DCHECK_RUN_ON(&thread_checker_); | 2174 RTC_DCHECK_RUN_ON(&thread_checker_); |
1989 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) | 2175 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
1990 info.add_ssrc(ssrc); | 2176 info.add_ssrc(ssrc); |
1991 | 2177 |
| 2178 // TODO(emircan): Add stereo codec case. |
1992 if (parameters_.codec_settings) { | 2179 if (parameters_.codec_settings) { |
1993 info.codec_name = parameters_.codec_settings->codec.name; | 2180 info.codec_name = parameters_.codec_settings->codec.name; |
1994 info.codec_payload_type = rtc::Optional<int>( | 2181 info.codec_payload_type = rtc::Optional<int>( |
1995 parameters_.codec_settings->codec.id); | 2182 parameters_.codec_settings->codec.id); |
1996 } | 2183 } |
1997 | 2184 |
1998 if (stream_ == NULL) | 2185 if (stream_ == NULL) |
1999 return info; | 2186 return info; |
2000 | 2187 |
2001 webrtc::VideoSendStream::Stats stats = stream_->GetStats(); | 2188 webrtc::VideoSendStream::Stats stats = stream_->GetStats(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2118 const std::vector<VideoCodecSettings>& recv_codecs, | 2305 const std::vector<VideoCodecSettings>& recv_codecs, |
2119 const webrtc::FlexfecReceiveStream::Config& flexfec_config) | 2306 const webrtc::FlexfecReceiveStream::Config& flexfec_config) |
2120 : call_(call), | 2307 : call_(call), |
2121 stream_params_(sp), | 2308 stream_params_(sp), |
2122 stream_(NULL), | 2309 stream_(NULL), |
2123 default_stream_(default_stream), | 2310 default_stream_(default_stream), |
2124 config_(std::move(config)), | 2311 config_(std::move(config)), |
2125 flexfec_config_(flexfec_config), | 2312 flexfec_config_(flexfec_config), |
2126 flexfec_stream_(nullptr), | 2313 flexfec_stream_(nullptr), |
2127 external_decoder_factory_(external_decoder_factory), | 2314 external_decoder_factory_(external_decoder_factory), |
| 2315 internal_decoder_factory_(new InternalDecoderFactory()), |
2128 sink_(NULL), | 2316 sink_(NULL), |
2129 first_frame_timestamp_(-1), | 2317 first_frame_timestamp_(-1), |
2130 estimated_remote_start_ntp_time_ms_(0) { | 2318 estimated_remote_start_ntp_time_ms_(0) { |
2131 config_.renderer = this; | 2319 config_.renderer = this; |
2132 std::vector<AllocatedDecoder> old_decoders; | 2320 std::vector<AllocatedDecoder> old_decoders; |
2133 ConfigureCodecs(recv_codecs, &old_decoders); | 2321 ConfigureCodecs(recv_codecs, &old_decoders); |
2134 ConfigureFlexfecCodec(flexfec_config.payload_type); | 2322 ConfigureFlexfecCodec(flexfec_config.payload_type); |
2135 MaybeRecreateWebRtcFlexfecStream(); | 2323 MaybeRecreateWebRtcFlexfecStream(); |
2136 RecreateWebRtcVideoStream(); | 2324 RecreateWebRtcVideoStream(); |
2137 RTC_DCHECK(old_decoders.empty()); | 2325 RTC_DCHECK(old_decoders.empty()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2172 | 2360 |
2173 if (primary_ssrcs.empty()) { | 2361 if (primary_ssrcs.empty()) { |
2174 LOG(LS_WARNING) << "Empty primary ssrcs vector, returning empty optional"; | 2362 LOG(LS_WARNING) << "Empty primary ssrcs vector, returning empty optional"; |
2175 return rtc::Optional<uint32_t>(); | 2363 return rtc::Optional<uint32_t>(); |
2176 } else { | 2364 } else { |
2177 return rtc::Optional<uint32_t>(primary_ssrcs[0]); | 2365 return rtc::Optional<uint32_t>(primary_ssrcs[0]); |
2178 } | 2366 } |
2179 } | 2367 } |
2180 | 2368 |
2181 WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder | 2369 WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder |
| 2370 WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateStereoVideoDecoder( |
| 2371 const VideoCodec& codec) { |
| 2372 LOG(LS_ERROR) << __func__; |
| 2373 webrtc::VideoCodecType type = webrtc::PayloadNameToCodecType(codec.name) |
| 2374 .value_or(webrtc::kVideoCodecUnknown); |
| 2375 stereo_decoder_factory_.reset( |
| 2376 new WebRtcStereoDecoderFactory(internal_decoder_factory_.get())); |
| 2377 return AllocatedDecoder(stereo_decoder_factory_->CreateVideoDecoderWithParams( |
| 2378 type, {stream_params_.id}), |
| 2379 type, false /* is_external */); |
| 2380 } |
| 2381 |
| 2382 WebRtcVideoChannel::WebRtcVideoReceiveStream::AllocatedDecoder |
2182 WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( | 2383 WebRtcVideoChannel::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( |
2183 std::vector<AllocatedDecoder>* old_decoders, | 2384 std::vector<AllocatedDecoder>* old_decoders, |
2184 const VideoCodec& codec) { | 2385 const VideoCodec& codec) { |
2185 webrtc::VideoCodecType type = webrtc::PayloadNameToCodecType(codec.name) | 2386 webrtc::VideoCodecType type = webrtc::PayloadNameToCodecType(codec.name) |
2186 .value_or(webrtc::kVideoCodecUnknown); | 2387 .value_or(webrtc::kVideoCodecUnknown); |
2187 | 2388 |
2188 for (size_t i = 0; i < old_decoders->size(); ++i) { | 2389 for (size_t i = 0; i < old_decoders->size(); ++i) { |
2189 if ((*old_decoders)[i].type == type) { | 2390 if ((*old_decoders)[i].type == type) { |
2190 AllocatedDecoder decoder = (*old_decoders)[i]; | 2391 AllocatedDecoder decoder = (*old_decoders)[i]; |
2191 (*old_decoders)[i] = old_decoders->back(); | 2392 (*old_decoders)[i] = old_decoders->back(); |
(...skipping 17 matching lines...) Expand all Loading... |
2209 type, false /* is_external */); | 2410 type, false /* is_external */); |
2210 } | 2411 } |
2211 | 2412 |
2212 void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( | 2413 void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( |
2213 const std::vector<VideoCodecSettings>& recv_codecs, | 2414 const std::vector<VideoCodecSettings>& recv_codecs, |
2214 std::vector<AllocatedDecoder>* old_decoders) { | 2415 std::vector<AllocatedDecoder>* old_decoders) { |
2215 *old_decoders = allocated_decoders_; | 2416 *old_decoders = allocated_decoders_; |
2216 allocated_decoders_.clear(); | 2417 allocated_decoders_.clear(); |
2217 config_.decoders.clear(); | 2418 config_.decoders.clear(); |
2218 for (size_t i = 0; i < recv_codecs.size(); ++i) { | 2419 for (size_t i = 0; i < recv_codecs.size(); ++i) { |
| 2420 const bool is_stereo_codec = |
| 2421 cricket::VideoCodec::IsStereoCodec(recv_codecs[i].codec); |
2219 AllocatedDecoder allocated_decoder = | 2422 AllocatedDecoder allocated_decoder = |
2220 CreateOrReuseVideoDecoder(old_decoders, recv_codecs[i].codec); | 2423 is_stereo_codec |
| 2424 ? CreateStereoVideoDecoder(recv_codecs[i].codec) |
| 2425 : CreateOrReuseVideoDecoder(old_decoders, recv_codecs[i].codec); |
2221 allocated_decoders_.push_back(allocated_decoder); | 2426 allocated_decoders_.push_back(allocated_decoder); |
2222 | 2427 |
2223 webrtc::VideoReceiveStream::Decoder decoder; | 2428 webrtc::VideoReceiveStream::Decoder decoder; |
2224 decoder.decoder = allocated_decoder.decoder; | 2429 decoder.decoder = allocated_decoder.decoder; |
2225 decoder.payload_type = recv_codecs[i].codec.id; | 2430 decoder.payload_type = recv_codecs[i].codec.id; |
2226 decoder.payload_name = recv_codecs[i].codec.name; | 2431 decoder.payload_name = recv_codecs[i].codec.name; |
2227 decoder.codec_params = recv_codecs[i].codec.params; | 2432 decoder.codec_params = recv_codecs[i].codec.params; |
2228 config_.decoders.push_back(decoder); | 2433 config_.decoders.push_back(decoder); |
2229 } | 2434 } |
2230 | 2435 |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2641 stream.temporal_layer_thresholds_bps.resize(GetDefaultVp9TemporalLayers() - | 2846 stream.temporal_layer_thresholds_bps.resize(GetDefaultVp9TemporalLayers() - |
2642 1); | 2847 1); |
2643 } | 2848 } |
2644 | 2849 |
2645 std::vector<webrtc::VideoStream> streams; | 2850 std::vector<webrtc::VideoStream> streams; |
2646 streams.push_back(stream); | 2851 streams.push_back(stream); |
2647 return streams; | 2852 return streams; |
2648 } | 2853 } |
2649 | 2854 |
2650 } // namespace cricket | 2855 } // namespace cricket |
OLD | NEW |