diff --git a/api/rtp_parameters.h b/api/rtp_parameters.h index 5afb806f62..f831e51f68 100644 --- a/api/rtp_parameters.h +++ b/api/rtp_parameters.h @@ -222,7 +222,7 @@ struct RTC_EXPORT RtpHeaderExtensionCapability { bool preferred_encrypt = false; // The direction of the extension. The kStopped value is only used with - // RtpTransceiverInterface::HeaderExtensionsToOffer() and + // RtpTransceiverInterface::header_extensions_offered() and // SetOfferedRtpHeaderExtensions(). RtpTransceiverDirection direction = RtpTransceiverDirection::kSendRecv; diff --git a/api/rtp_transceiver_interface.cc b/api/rtp_transceiver_interface.cc index e795e51dfb..d4e2b26e33 100644 --- a/api/rtp_transceiver_interface.cc +++ b/api/rtp_transceiver_interface.cc @@ -41,10 +41,4 @@ RtpTransceiverInterface::HeaderExtensionsToOffer() const { return {}; } -webrtc::RTCError RtpTransceiverInterface::SetOfferedRtpHeaderExtensions( - rtc::ArrayView - header_extensions_to_offer) { - return webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION); -} - } // namespace webrtc diff --git a/api/rtp_transceiver_interface.h b/api/rtp_transceiver_interface.h index 13277d9a50..9dbafd46ec 100644 --- a/api/rtp_transceiver_interface.h +++ b/api/rtp_transceiver_interface.h @@ -133,13 +133,6 @@ class RTC_EXPORT RtpTransceiverInterface : public rtc::RefCountInterface { virtual std::vector HeaderExtensionsToOffer() const; - // The SetOfferedRtpHeaderExtensions method modifies the next SDP negotiation - // so that it negotiates use of header extensions which are not kStopped. - // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface - virtual webrtc::RTCError SetOfferedRtpHeaderExtensions( - rtc::ArrayView - header_extensions_to_offer); - protected: ~RtpTransceiverInterface() override = default; }; diff --git a/pc/media_session.cc b/pc/media_session.cc index 68733a47f4..6bf31364a4 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -55,29 +55,6 @@ void GetSupportedSdesCryptoSuiteNames( } } -cricket::RtpHeaderExtensions RtpHeaderExtensionsFromCapabilities( - const std::vector& capabilities) { - cricket::RtpHeaderExtensions exts; - for (const auto& extension_with_direction : capabilities) { - exts.emplace_back(extension_with_direction.uri, - extension_with_direction.preferred_id.value_or(1)); - } - return exts; -} - -std::vector -UnstoppedRtpHeaderExtensionCapabilities( - std::vector capabilities) { - capabilities.erase( - std::remove_if( - capabilities.begin(), capabilities.end(), - [](const webrtc::RtpHeaderExtensionCapability& capability) { - return capability.direction == RtpTransceiverDirection::kStopped; - }), - capabilities.end()); - return capabilities; -} - } // namespace namespace cricket { @@ -656,22 +633,7 @@ static bool CreateContentOffer( if (offer->type() == cricket::MEDIA_TYPE_VIDEO) { offer->set_rtcp_reduced_size(true); } - - // Build the vector of header extensions with directions for this - // media_description's options. - RtpHeaderExtensions extensions; - for (auto extension_with_id : rtp_extensions) { - for (const auto& extension : UnstoppedRtpHeaderExtensionCapabilities( - media_description_options.header_extensions)) { - if (extension_with_id.uri == extension.uri) { - // TODO(crbug.com/1051821): Configure the extension direction from - // the information in the media_description_options extension - // capability. - extensions.push_back(extension_with_id); - } - } - } - offer->set_rtp_header_extensions(extensions); + offer->set_rtp_header_extensions(rtp_extensions); AddSimulcastToMediaDescription(media_description_options, offer); @@ -1203,7 +1165,7 @@ static bool CreateMediaContentAnswer( const MediaSessionOptions& session_options, const SecurePolicy& sdes_policy, const CryptoParamsVec* current_cryptos, - const RtpHeaderExtensions& local_rtp_extensions, + const RtpHeaderExtensions& local_rtp_extenstions, UniqueRandomIdGenerator* ssrc_generator, bool enable_encrypted_rtp_header_extensions, StreamParamsVec* current_streams, @@ -1212,7 +1174,7 @@ static bool CreateMediaContentAnswer( answer->set_extmap_allow_mixed_enum(offer->extmap_allow_mixed_enum()); RtpHeaderExtensions negotiated_rtp_extensions; NegotiateRtpHeaderExtensions( - local_rtp_extensions, offer->rtp_header_extensions(), + local_rtp_extenstions, offer->rtp_header_extensions(), enable_encrypted_rtp_header_extensions, &negotiated_rtp_extensions); answer->set_rtp_header_extensions(negotiated_rtp_extensions); @@ -1390,8 +1352,12 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( : MediaSessionDescriptionFactory(transport_desc_factory, ssrc_generator) { channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_); channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_); + audio_rtp_extensions_ = + channel_manager->GetDefaultEnabledAudioRtpHeaderExtensions(); channel_manager->GetSupportedVideoSendCodecs(&video_send_codecs_); channel_manager->GetSupportedVideoReceiveCodecs(&video_recv_codecs_); + video_rtp_extensions_ = + channel_manager->GetDefaultEnabledVideoRtpHeaderExtensions(); channel_manager->GetSupportedDataCodecs(&rtp_data_codecs_); ComputeAudioCodecsIntersectionAndUnion(); ComputeVideoCodecsIntersectionAndUnion(); @@ -1454,11 +1420,22 @@ static void RemoveUnifiedPlanExtensions(RtpHeaderExtensions* extensions) { } RtpHeaderExtensions -MediaSessionDescriptionFactory::filtered_rtp_header_extensions( - RtpHeaderExtensions extensions) const { +MediaSessionDescriptionFactory::audio_rtp_header_extensions() const { + RtpHeaderExtensions extensions = audio_rtp_extensions_; if (!is_unified_plan_) { RemoveUnifiedPlanExtensions(&extensions); } + + return extensions; +} + +RtpHeaderExtensions +MediaSessionDescriptionFactory::video_rtp_header_extensions() const { + RtpHeaderExtensions extensions = video_rtp_extensions_; + if (!is_unified_plan_) { + RemoveUnifiedPlanExtensions(&extensions); + } + return extensions; } @@ -1494,10 +1471,11 @@ std::unique_ptr MediaSessionDescriptionFactory::CreateOffer( StripCNCodecs(&offer_audio_codecs); } - AudioVideoRtpHeaderExtensions extensions_with_ids = - GetOfferedRtpHeaderExtensionsWithIds( - current_active_contents, session_options.offer_extmap_allow_mixed, - session_options.media_description_options); + RtpHeaderExtensions audio_rtp_extensions; + RtpHeaderExtensions video_rtp_extensions; + GetRtpHdrExtsToOffer(current_active_contents, + session_options.offer_extmap_allow_mixed, + &audio_rtp_extensions, &video_rtp_extensions); auto offer = std::make_unique(); @@ -1517,20 +1495,18 @@ std::unique_ptr MediaSessionDescriptionFactory::CreateOffer( } switch (media_description_options.type) { case MEDIA_TYPE_AUDIO: - if (!AddAudioContentForOffer(media_description_options, session_options, - current_content, current_description, - extensions_with_ids.audio, - offer_audio_codecs, ¤t_streams, - offer.get(), &ice_credentials)) { + if (!AddAudioContentForOffer( + media_description_options, session_options, current_content, + current_description, audio_rtp_extensions, offer_audio_codecs, + ¤t_streams, offer.get(), &ice_credentials)) { return nullptr; } break; case MEDIA_TYPE_VIDEO: - if (!AddVideoContentForOffer(media_description_options, session_options, - current_content, current_description, - extensions_with_ids.video, - offer_video_codecs, ¤t_streams, - offer.get(), &ice_credentials)) { + if (!AddVideoContentForOffer( + media_description_options, session_options, current_content, + current_description, video_rtp_extensions, offer_video_codecs, + ¤t_streams, offer.get(), &ice_credentials)) { return nullptr; } break; @@ -1665,16 +1641,13 @@ MediaSessionDescriptionFactory::CreateAnswer( msection_index < current_description->contents().size()) { current_content = ¤t_description->contents()[msection_index]; } - RtpHeaderExtensions header_extensions = RtpHeaderExtensionsFromCapabilities( - UnstoppedRtpHeaderExtensionCapabilities( - media_description_options.header_extensions)); switch (media_description_options.type) { case MEDIA_TYPE_AUDIO: if (!AddAudioContentForAnswer( media_description_options, session_options, offer_content, offer, current_content, current_description, - bundle_transport.get(), answer_audio_codecs, header_extensions, - ¤t_streams, answer.get(), &ice_credentials)) { + bundle_transport.get(), answer_audio_codecs, ¤t_streams, + answer.get(), &ice_credentials)) { return nullptr; } break; @@ -1682,8 +1655,8 @@ MediaSessionDescriptionFactory::CreateAnswer( if (!AddVideoContentForAnswer( media_description_options, session_options, offer_content, offer, current_content, current_description, - bundle_transport.get(), answer_video_codecs, header_extensions, - ¤t_streams, answer.get(), &ice_credentials)) { + bundle_transport.get(), answer_video_codecs, ¤t_streams, + answer.get(), &ice_credentials)) { return nullptr; } break; @@ -1976,12 +1949,11 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( &used_pltypes); } -MediaSessionDescriptionFactory::AudioVideoRtpHeaderExtensions -MediaSessionDescriptionFactory::GetOfferedRtpHeaderExtensionsWithIds( +void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( const std::vector& current_active_contents, bool extmap_allow_mixed, - const std::vector& media_description_options) - const { + RtpHeaderExtensions* offer_audio_extensions, + RtpHeaderExtensions* offer_video_extensions) const { // All header extensions allocated from the same range to avoid potential // issues when using BUNDLE. @@ -1995,7 +1967,6 @@ MediaSessionDescriptionFactory::GetOfferedRtpHeaderExtensionsWithIds( RtpHeaderExtensions all_regular_extensions; RtpHeaderExtensions all_encrypted_extensions; - AudioVideoRtpHeaderExtensions offered_extensions; // First - get all extensions from the current description if the media type // is used. // Add them to |used_ids| so the local ids are not reused if a new media @@ -2004,42 +1975,36 @@ MediaSessionDescriptionFactory::GetOfferedRtpHeaderExtensionsWithIds( if (IsMediaContentOfType(content, MEDIA_TYPE_AUDIO)) { const AudioContentDescription* audio = content->media_description()->as_audio(); - MergeRtpHdrExts(audio->rtp_header_extensions(), &offered_extensions.audio, + MergeRtpHdrExts(audio->rtp_header_extensions(), offer_audio_extensions, &all_regular_extensions, &all_encrypted_extensions, &used_ids); } else if (IsMediaContentOfType(content, MEDIA_TYPE_VIDEO)) { const VideoContentDescription* video = content->media_description()->as_video(); - MergeRtpHdrExts(video->rtp_header_extensions(), &offered_extensions.video, + MergeRtpHdrExts(video->rtp_header_extensions(), offer_video_extensions, &all_regular_extensions, &all_encrypted_extensions, &used_ids); } } - // Add all encountered header extensions in the media description options that - // are not in the current description. - for (const auto& entry : media_description_options) { - RtpHeaderExtensions filtered_extensions = filtered_rtp_header_extensions( - RtpHeaderExtensionsFromCapabilities(entry.header_extensions)); - if (entry.type == MEDIA_TYPE_AUDIO) - MergeRtpHdrExts(filtered_extensions, &offered_extensions.audio, - &all_regular_extensions, &all_encrypted_extensions, - &used_ids); - else if (entry.type == MEDIA_TYPE_VIDEO) - MergeRtpHdrExts(filtered_extensions, &offered_extensions.video, - &all_regular_extensions, &all_encrypted_extensions, - &used_ids); - } + // Add our default RTP header extensions that are not in the current + // description. + MergeRtpHdrExts(audio_rtp_header_extensions(), offer_audio_extensions, + &all_regular_extensions, &all_encrypted_extensions, + &used_ids); + MergeRtpHdrExts(video_rtp_header_extensions(), offer_video_extensions, + &all_regular_extensions, &all_encrypted_extensions, + &used_ids); + // TODO(jbauch): Support adding encrypted header extensions to existing // sessions. if (enable_encrypted_rtp_header_extensions_ && current_active_contents.empty()) { - AddEncryptedVersionsOfHdrExts(&offered_extensions.audio, + AddEncryptedVersionsOfHdrExts(offer_audio_extensions, &all_encrypted_extensions, &used_ids); - AddEncryptedVersionsOfHdrExts(&offered_extensions.video, + AddEncryptedVersionsOfHdrExts(offer_video_extensions, &all_encrypted_extensions, &used_ids); } - return offered_extensions; } bool MediaSessionDescriptionFactory::AddTransportOffer( @@ -2414,7 +2379,6 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( const SessionDescription* current_description, const TransportInfo* bundle_transport, const AudioCodecs& audio_codecs, - const RtpHeaderExtensions& default_audio_rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { @@ -2487,9 +2451,9 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( if (!CreateMediaContentAnswer( offer_audio_description, media_description_options, session_options, sdes_policy, GetCryptos(current_content), - filtered_rtp_header_extensions(default_audio_rtp_header_extensions), - ssrc_generator_, enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, audio_answer.get())) { + audio_rtp_header_extensions(), ssrc_generator_, + enable_encrypted_rtp_header_extensions_, current_streams, + bundle_enabled, audio_answer.get())) { return false; // Fails the session setup. } @@ -2525,7 +2489,6 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( const SessionDescription* current_description, const TransportInfo* bundle_transport, const VideoCodecs& video_codecs, - const RtpHeaderExtensions& default_video_rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { @@ -2606,9 +2569,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( if (!CreateMediaContentAnswer( offer_video_description, media_description_options, session_options, sdes_policy, GetCryptos(current_content), - filtered_rtp_header_extensions(default_video_rtp_header_extensions), - ssrc_generator_, enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, video_answer.get())) { + video_rtp_header_extensions(), ssrc_generator_, + enable_encrypted_rtp_header_extensions_, current_streams, + bundle_enabled, video_answer.get())) { return false; // Failed the sessin setup. } bool secure = bundle_transport ? bundle_transport->description.secure() diff --git a/pc/media_session.h b/pc/media_session.h index e93bbcfc5d..ef83834318 100644 --- a/pc/media_session.h +++ b/pc/media_session.h @@ -79,7 +79,6 @@ struct MediaDescriptionOptions { std::vector sender_options; std::vector codec_preferences; absl::optional alt_protocol; - std::vector header_extensions; private: // Doesn't DCHECK on |type|. @@ -148,13 +147,19 @@ class MediaSessionDescriptionFactory { const AudioCodecs& audio_recv_codecs() const; void set_audio_codecs(const AudioCodecs& send_codecs, const AudioCodecs& recv_codecs); + void set_audio_rtp_header_extensions(const RtpHeaderExtensions& extensions) { + audio_rtp_extensions_ = extensions; + } + RtpHeaderExtensions audio_rtp_header_extensions() const; const VideoCodecs& video_sendrecv_codecs() const; const VideoCodecs& video_send_codecs() const; const VideoCodecs& video_recv_codecs() const; void set_video_codecs(const VideoCodecs& send_codecs, const VideoCodecs& recv_codecs); - RtpHeaderExtensions filtered_rtp_header_extensions( - RtpHeaderExtensions extensions) const; + void set_video_rtp_header_extensions(const RtpHeaderExtensions& extensions) { + video_rtp_extensions_ = extensions; + } + RtpHeaderExtensions video_rtp_header_extensions() const; const RtpDataCodecs& rtp_data_codecs() const { return rtp_data_codecs_; } void set_rtp_data_codecs(const RtpDataCodecs& codecs) { rtp_data_codecs_ = codecs; @@ -179,11 +184,6 @@ class MediaSessionDescriptionFactory { const SessionDescription* current_description) const; private: - struct AudioVideoRtpHeaderExtensions { - RtpHeaderExtensions audio; - RtpHeaderExtensions video; - }; - const AudioCodecs& GetAudioCodecsForOffer( const webrtc::RtpTransceiverDirection& direction) const; const AudioCodecs& GetAudioCodecsForAnswer( @@ -205,11 +205,11 @@ class MediaSessionDescriptionFactory { AudioCodecs* audio_codecs, VideoCodecs* video_codecs, RtpDataCodecs* rtp_data_codecs) const; - AudioVideoRtpHeaderExtensions GetOfferedRtpHeaderExtensionsWithIds( + void GetRtpHdrExtsToOffer( const std::vector& current_active_contents, bool extmap_allow_mixed, - const std::vector& media_description_options) - const; + RtpHeaderExtensions* audio_extensions, + RtpHeaderExtensions* video_extensions) const; bool AddTransportOffer(const std::string& content_name, const TransportOptions& transport_options, const SessionDescription* current_desc, @@ -293,7 +293,6 @@ class MediaSessionDescriptionFactory { const SessionDescription* current_description, const TransportInfo* bundle_transport, const AudioCodecs& audio_codecs, - const RtpHeaderExtensions& default_audio_rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const; @@ -307,7 +306,6 @@ class MediaSessionDescriptionFactory { const SessionDescription* current_description, const TransportInfo* bundle_transport, const VideoCodecs& video_codecs, - const RtpHeaderExtensions& default_video_rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const; @@ -336,12 +334,14 @@ class MediaSessionDescriptionFactory { AudioCodecs audio_sendrecv_codecs_; // Union of send and recv. AudioCodecs all_audio_codecs_; + RtpHeaderExtensions audio_rtp_extensions_; VideoCodecs video_send_codecs_; VideoCodecs video_recv_codecs_; // Intersection of send and recv. VideoCodecs video_sendrecv_codecs_; // Union of send and recv. VideoCodecs all_video_codecs_; + RtpHeaderExtensions video_rtp_extensions_; RtpDataCodecs rtp_data_codecs_; // This object is not owned by the channel so it must outlive it. rtc::UniqueRandomIdGenerator* const ssrc_generator_; diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc index 654284ac50..8b5e32054c 100644 --- a/pc/media_session_unittest.cc +++ b/pc/media_session_unittest.cc @@ -754,10 +754,13 @@ class MediaSessionDescriptionFactoryTest : public ::testing::Test { const cricket::RtpHeaderExtensions& expectedAnswer) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions(offered, offered, &opts); + f1_.set_audio_rtp_header_extensions(offered); + f1_.set_video_rtp_header_extensions(offered); + f2_.set_audio_rtp_header_extensions(local); + f2_.set_video_rtp_header_extensions(local); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); ASSERT_TRUE(offer.get() != NULL); - SetAudioVideoRtpHeaderExtensions(local, local, &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -769,38 +772,6 @@ class MediaSessionDescriptionFactoryTest : public ::testing::Test { GetFirstVideoContentDescription(answer.get())->rtp_header_extensions()); } - std::vector - HeaderExtensionCapabilitiesFromRtpExtensions( - cricket::RtpHeaderExtensions extensions) { - std::vector capabilities; - for (const auto& extension : extensions) { - webrtc::RtpHeaderExtensionCapability capability( - extension.uri, extension.id, - webrtc::RtpTransceiverDirection::kSendRecv); - capabilities.push_back(capability); - } - return capabilities; - } - - void SetAudioVideoRtpHeaderExtensions(cricket::RtpHeaderExtensions audio_exts, - cricket::RtpHeaderExtensions video_exts, - MediaSessionOptions* opts) { - auto audio_caps = HeaderExtensionCapabilitiesFromRtpExtensions(audio_exts); - auto video_caps = HeaderExtensionCapabilitiesFromRtpExtensions(video_exts); - for (auto& entry : opts->media_description_options) { - switch (entry.type) { - case MEDIA_TYPE_AUDIO: - entry.header_extensions = audio_caps; - break; - case MEDIA_TYPE_VIDEO: - entry.header_extensions = video_caps; - break; - default: - break; - } - } - } - protected: UniqueRandomIdGenerator ssrc_generator1; UniqueRandomIdGenerator ssrc_generator2; @@ -1688,13 +1659,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, AudioOfferAnswerWithCryptoDisabled) { TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithRtpExtensions) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension1), - MAKE_VECTOR(kVideoRtpExtension1), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); + f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); + f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2)); std::unique_ptr offer = f1_.CreateOffer(opts, NULL); ASSERT_TRUE(offer.get() != NULL); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension2), - MAKE_VECTOR(kVideoRtpExtension2), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -1743,21 +1714,21 @@ TEST_F(MediaSessionDescriptionFactoryTest, MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions( - MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00), - MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00), &opts); + const auto offered = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f1_.set_audio_rtp_header_extensions(offered); + f1_.set_video_rtp_header_extensions(offered); + const auto local = MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01); + f2_.set_audio_rtp_header_extensions(local); + f2_.set_video_rtp_header_extensions(local); std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); - SetAudioVideoRtpHeaderExtensions( - MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), - MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(), - ElementsAreArray(kRtpExtensionGenericFrameDescriptorUri00)); + ElementsAreArray(offered)); EXPECT_THAT( GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(), - ElementsAreArray(kRtpExtensionGenericFrameDescriptorUri00)); + ElementsAreArray(offered)); } TEST_F(MediaSessionDescriptionFactoryTest, @@ -1765,18 +1736,21 @@ TEST_F(MediaSessionDescriptionFactoryTest, MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions( - MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00), - MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00), &opts); + const auto offered = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f1_.set_audio_rtp_header_extensions(offered); + f1_.set_video_rtp_header_extensions(offered); + const auto local = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f2_.set_audio_rtp_header_extensions(local); + f2_.set_video_rtp_header_extensions(local); std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(), - ElementsAreArray(kRtpExtensionGenericFrameDescriptorUri00)); + ElementsAreArray(offered)); EXPECT_THAT( GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(), - ElementsAreArray(kRtpExtensionGenericFrameDescriptorUri00)); + ElementsAreArray(offered)); } TEST_F(MediaSessionDescriptionFactoryTest, @@ -1785,10 +1759,10 @@ TEST_F(MediaSessionDescriptionFactoryTest, AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); RtpExtension offer_dd(RtpExtension::kDependencyDescriptorUri, 7); - SetAudioVideoRtpHeaderExtensions({}, {offer_dd}, &opts); - std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); RtpExtension local_tsn(RtpExtension::kTransportSequenceNumberUri, 5); - SetAudioVideoRtpHeaderExtensions({}, {local_tsn}, &opts); + f1_.set_video_rtp_header_extensions({offer_dd}); + f2_.set_video_rtp_header_extensions({local_tsn}); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( @@ -1803,9 +1777,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtension offer_dd(RtpExtension::kDependencyDescriptorUri, 7); RtpExtension local_dd(RtpExtension::kDependencyDescriptorUri, 5); - SetAudioVideoRtpHeaderExtensions({}, {offer_dd}, &opts); + f1_.set_video_rtp_header_extensions({offer_dd}); + f2_.set_video_rtp_header_extensions({local_dd}); std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); - SetAudioVideoRtpHeaderExtensions({}, {local_dd}, &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( @@ -1822,10 +1796,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 7)}; const cricket::RtpHeaderExtensions local_extensions = { RtpExtension(RtpExtension::kTransportSequenceNumberUri, 5)}; - SetAudioVideoRtpHeaderExtensions(offered_extensions, offered_extensions, - &opts); + f1_.set_video_rtp_header_extensions(offered_extensions); + f1_.set_audio_rtp_header_extensions(offered_extensions); + f2_.set_video_rtp_header_extensions(local_extensions); + f2_.set_audio_rtp_header_extensions(local_extensions); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); - SetAudioVideoRtpHeaderExtensions(local_extensions, local_extensions, &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( @@ -1845,10 +1821,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 7)}; const cricket::RtpHeaderExtensions local_extensions = { RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 5)}; - SetAudioVideoRtpHeaderExtensions(offered_extensions, offered_extensions, - &opts); + f1_.set_video_rtp_header_extensions(offered_extensions); + f1_.set_audio_rtp_header_extensions(offered_extensions); + f2_.set_video_rtp_header_extensions(local_extensions); + f2_.set_audio_rtp_header_extensions(local_extensions); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); - SetAudioVideoRtpHeaderExtensions(local_extensions, local_extensions, &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( @@ -1868,10 +1846,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtension(RtpExtension::kTransportSequenceNumberUri, 7)}; const cricket::RtpHeaderExtensions local_extensions = { RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 5)}; - SetAudioVideoRtpHeaderExtensions(offered_extensions, offered_extensions, - &opts); + f1_.set_video_rtp_header_extensions(offered_extensions); + f1_.set_audio_rtp_header_extensions(offered_extensions); + f2_.set_video_rtp_header_extensions(local_extensions); + f2_.set_audio_rtp_header_extensions(local_extensions); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); - SetAudioVideoRtpHeaderExtensions(local_extensions, local_extensions, &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, nullptr); EXPECT_THAT( @@ -1882,123 +1862,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, IsEmpty()); } -TEST_F(MediaSessionDescriptionFactoryTest, OffersUnstoppedExtensions) { - MediaSessionOptions opts; - AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", - RtpTransceiverDirection::kSendRecv, kActive, - &opts); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 1, - RtpTransceiverDirection::kStopped), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kSendOnly), - webrtc::RtpHeaderExtensionCapability("uri3", 5, - RtpTransceiverDirection::kRecvOnly)}; - AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video1", - RtpTransceiverDirection::kSendRecv, kActive, - &opts); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 1, - RtpTransceiverDirection::kSendRecv), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kStopped), - webrtc::RtpHeaderExtensionCapability("uri3", 5, - RtpTransceiverDirection::kRecvOnly)}; - AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video2", - RtpTransceiverDirection::kSendRecv, kActive, - &opts); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 1, - RtpTransceiverDirection::kSendRecv), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kRecvOnly), - webrtc::RtpHeaderExtensionCapability("uri3", 5, - RtpTransceiverDirection::kStopped)}; - auto offer = f1_.CreateOffer(opts, nullptr); - EXPECT_THAT( - offer->contents(), - ElementsAre( - Property(&ContentInfo::media_description, - Pointee(Property( - &MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri2"), - Field(&RtpExtension::uri, "uri3"))))), - Property(&ContentInfo::media_description, - Pointee(Property( - &MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri1"), - Field(&RtpExtension::uri, "uri3"))))), - Property(&ContentInfo::media_description, - Pointee(Property( - &MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri1"), - Field(&RtpExtension::uri, "uri2"))))))); -} - -TEST_F(MediaSessionDescriptionFactoryTest, AnswersUnstoppedExtensions) { - MediaSessionOptions opts; - AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", - RtpTransceiverDirection::kSendRecv, kActive, - &opts); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 4, - RtpTransceiverDirection::kStopped), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kSendOnly), - webrtc::RtpHeaderExtensionCapability("uri3", 2, - RtpTransceiverDirection::kRecvOnly), - webrtc::RtpHeaderExtensionCapability("uri4", 1, - RtpTransceiverDirection::kSendRecv)}; - auto offer = f1_.CreateOffer(opts, nullptr); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 4, - RtpTransceiverDirection::kSendOnly), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kRecvOnly), - webrtc::RtpHeaderExtensionCapability("uri3", 2, - RtpTransceiverDirection::kStopped), - webrtc::RtpHeaderExtensionCapability("uri4", 1, - RtpTransceiverDirection::kSendRecv)}; - auto answer = f2_.CreateAnswer(offer.get(), opts, nullptr); - EXPECT_THAT( - answer->contents(), - ElementsAre(Property( - &ContentInfo::media_description, - Pointee(Property(&MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri2"), - Field(&RtpExtension::uri, "uri4"))))))); -} - -TEST_F(MediaSessionDescriptionFactoryTest, - AppendsUnstoppedExtensionsToCurrentDescription) { - MediaSessionOptions opts; - AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", - RtpTransceiverDirection::kSendRecv, kActive, - &opts); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 1, - RtpTransceiverDirection::kSendRecv)}; - auto offer = f1_.CreateOffer(opts, nullptr); - opts.media_description_options.back().header_extensions = { - webrtc::RtpHeaderExtensionCapability("uri1", 2, - RtpTransceiverDirection::kSendRecv), - webrtc::RtpHeaderExtensionCapability("uri2", 3, - RtpTransceiverDirection::kRecvOnly), - webrtc::RtpHeaderExtensionCapability("uri3", 5, - RtpTransceiverDirection::kStopped), - webrtc::RtpHeaderExtensionCapability("uri4", 6, - RtpTransceiverDirection::kSendRecv)}; - auto offer2 = f1_.CreateOffer(opts, offer.get()); - EXPECT_THAT( - offer2->contents(), - ElementsAre(Property( - &ContentInfo::media_description, - Pointee(Property(&MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri1"), - Field(&RtpExtension::uri, "uri2"), - Field(&RtpExtension::uri, "uri4"))))))); -} - TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithEncryptedRtpExtensionsBoth) { MediaSessionOptions opts; @@ -2007,12 +1870,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, f1_.set_enable_encrypted_rtp_header_extensions(true); f2_.set_enable_encrypted_rtp_header_extensions(true); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension1), - MAKE_VECTOR(kVideoRtpExtension1), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); + f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); + f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); ASSERT_TRUE(offer.get() != NULL); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension2), - MAKE_VECTOR(kVideoRtpExtension2), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -2037,12 +1901,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, f1_.set_enable_encrypted_rtp_header_extensions(true); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension1), - MAKE_VECTOR(kVideoRtpExtension1), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); + f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); + f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); ASSERT_TRUE(offer.get() != NULL); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension2), - MAKE_VECTOR(kVideoRtpExtension2), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -2067,12 +1932,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, f2_.set_enable_encrypted_rtp_header_extensions(true); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension1), - MAKE_VECTOR(kVideoRtpExtension1), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); + f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); + f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); ASSERT_TRUE(offer.get() != NULL); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension2), - MAKE_VECTOR(kVideoRtpExtension2), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -3474,11 +3340,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension1), - MAKE_VECTOR(kVideoRtpExtension1), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension1)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension1)); + f2_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension2)); + f2_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension2)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension2), - MAKE_VECTOR(kVideoRtpExtension2), &opts); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), opts, NULL); @@ -3529,8 +3396,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtensionIdReused) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - SetAudioVideoRtpHeaderExtensions(MAKE_VECTOR(kAudioRtpExtension3), - MAKE_VECTOR(kVideoRtpExtension3), &opts); + f1_.set_audio_rtp_header_extensions(MAKE_VECTOR(kAudioRtpExtension3)); + f1_.set_video_rtp_header_extensions(MAKE_VECTOR(kVideoRtpExtension3)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); // Since the audio extensions used ID 3 for "both_audio_and_video", so should @@ -3567,9 +3435,11 @@ TEST_F(MediaSessionDescriptionFactoryTest, RtpExtensionIdReusedEncrypted) { f1_.set_enable_encrypted_rtp_header_extensions(true); f2_.set_enable_encrypted_rtp_header_extensions(true); - SetAudioVideoRtpHeaderExtensions( - MAKE_VECTOR(kAudioRtpExtension3ForEncryption), - MAKE_VECTOR(kVideoRtpExtension3ForEncryption), &opts); + f1_.set_audio_rtp_header_extensions( + MAKE_VECTOR(kAudioRtpExtension3ForEncryption)); + f1_.set_video_rtp_header_extensions( + MAKE_VECTOR(kVideoRtpExtension3ForEncryption)); + std::unique_ptr offer = f1_.CreateOffer(opts, NULL); // The extensions that are shared between audio and video should use the same diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index c46eaa2b9e..e581ac0534 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -5020,21 +5020,21 @@ void PeerConnection::GetOptionsForPlanBOffer( // Add audio/video/data m= sections to the end if needed. if (!audio_index && offer_new_audio_description) { - cricket::MediaDescriptionOptions options( - cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO, - RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false); - options.header_extensions = - channel_manager()->GetSupportedAudioRtpHeaderExtensions(); - session_options->media_description_options.push_back(options); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions( + cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO, + RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), + false)); + audio_index = session_options->media_description_options.size() - 1; } if (!video_index && offer_new_video_description) { - cricket::MediaDescriptionOptions options( - cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO, - RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false); - options.header_extensions = - channel_manager()->GetSupportedVideoRtpHeaderExtensions(); - session_options->media_description_options.push_back(options); + session_options->media_description_options.push_back( + cricket::MediaDescriptionOptions( + cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO, + RtpTransceiverDirectionFromSendRecv(send_video, recv_video), + false)); + video_index = session_options->media_description_options.size() - 1; } if (!data_index && offer_new_data_description) { @@ -5066,8 +5066,6 @@ GetMediaDescriptionOptionsForTransceiver( transceiver->stopped()); media_description_options.codec_preferences = transceiver->codec_preferences(); - media_description_options.header_extensions = - transceiver->HeaderExtensionsToOffer(); // This behavior is specified in JSEP. The gist is that: // 1. The MSID is included if the RtpTransceiver's direction is sendonly or // sendrecv. @@ -5399,8 +5397,6 @@ void PeerConnection::GenerateMediaDescriptionOptions( stopped)); *audio_index = session_options->media_description_options.size() - 1; } - session_options->media_description_options.back().header_extensions = - channel_manager()->GetSupportedAudioRtpHeaderExtensions(); } else if (IsVideoContent(&content)) { // If we already have an video m= section, reject this extra one. if (*video_index) { @@ -5416,8 +5412,6 @@ void PeerConnection::GenerateMediaDescriptionOptions( stopped)); *video_index = session_options->media_description_options.size() - 1; } - session_options->media_description_options.back().header_extensions = - channel_manager()->GetSupportedVideoRtpHeaderExtensions(); } else { RTC_DCHECK(IsDataContent(&content)); // If we already have an data m= section, reject this extra one. diff --git a/pc/peer_connection_header_extension_unittest.cc b/pc/peer_connection_header_extension_unittest.cc index 62fda59212..3f44d4f877 100644 --- a/pc/peer_connection_header_extension_unittest.cc +++ b/pc/peer_connection_header_extension_unittest.cc @@ -33,31 +33,16 @@ class PeerConnectionHeaderExtensionTest : public ::testing::TestWithParam< std::tuple> { protected: - PeerConnectionHeaderExtensionTest() - : extensions_( - {RtpHeaderExtensionCapability("uri1", - 1, - RtpTransceiverDirection::kStopped), - RtpHeaderExtensionCapability("uri2", - 2, - RtpTransceiverDirection::kSendOnly), - RtpHeaderExtensionCapability("uri3", - 3, - RtpTransceiverDirection::kRecvOnly), - RtpHeaderExtensionCapability( - "uri4", - 4, - RtpTransceiverDirection::kSendRecv)}) {} - std::unique_ptr CreatePeerConnection( cricket::MediaType media_type, - absl::optional semantics) { + absl::optional semantics, + std::vector extensions) { auto voice = std::make_unique(); auto video = std::make_unique(); if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO) - voice->SetRtpHeaderExtensions(extensions_); + voice->SetRtpHeaderExtensions(extensions); else - video->SetRtpHeaderExtensions(extensions_); + video->SetRtpHeaderExtensions(extensions); auto media_engine = std::make_unique( std::move(voice), std::move(video)); PeerConnectionFactoryDependencies factory_dependencies; @@ -86,8 +71,6 @@ class PeerConnectionHeaderExtensionTest return std::make_unique(pc_factory, pc, std::move(observer)); } - - std::vector extensions_; }; TEST_P(PeerConnectionHeaderExtensionTest, TransceiverOffersHeaderExtensions) { @@ -96,10 +79,19 @@ TEST_P(PeerConnectionHeaderExtensionTest, TransceiverOffersHeaderExtensions) { std::tie(media_type, semantics) = GetParam(); if (semantics != SdpSemantics::kUnifiedPlan) return; + std::vector extensions( + {RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kStopped), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kSendOnly), + RtpHeaderExtensionCapability("uri3", 3, + RtpTransceiverDirection::kRecvOnly), + RtpHeaderExtensionCapability("uri4", 4, + RtpTransceiverDirection::kSendRecv)}); std::unique_ptr wrapper = - CreatePeerConnection(media_type, semantics); + CreatePeerConnection(media_type, semantics, extensions); auto transceiver = wrapper->AddTransceiver(media_type); - EXPECT_EQ(transceiver->HeaderExtensionsToOffer(), extensions_); + EXPECT_EQ(transceiver->HeaderExtensionsToOffer(), extensions); } TEST_P(PeerConnectionHeaderExtensionTest, @@ -107,14 +99,20 @@ TEST_P(PeerConnectionHeaderExtensionTest, cricket::MediaType media_type; SdpSemantics semantics; std::tie(media_type, semantics) = GetParam(); - std::unique_ptr wrapper = - CreatePeerConnection(media_type, semantics); + std::unique_ptr wrapper = CreatePeerConnection( + media_type, semantics, + std::vector( + {RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kSendRecv), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kStopped), + RtpHeaderExtensionCapability("uri3", 3, + RtpTransceiverDirection::kRecvOnly)})); EXPECT_THAT(wrapper->pc_factory() ->GetRtpSenderCapabilities(media_type) .header_extensions, - ElementsAre(Field(&RtpHeaderExtensionCapability::uri, "uri2"), - Field(&RtpHeaderExtensionCapability::uri, "uri3"), - Field(&RtpHeaderExtensionCapability::uri, "uri4"))); + ElementsAre(Field(&RtpHeaderExtensionCapability::uri, "uri1"), + Field(&RtpHeaderExtensionCapability::uri, "uri3"))); EXPECT_EQ(wrapper->pc_factory() ->GetRtpReceiverCapabilities(media_type) .header_extensions, @@ -123,49 +121,6 @@ TEST_P(PeerConnectionHeaderExtensionTest, .header_extensions); } -TEST_P(PeerConnectionHeaderExtensionTest, OffersUnstoppedDefaultExtensions) { - cricket::MediaType media_type; - SdpSemantics semantics; - std::tie(media_type, semantics) = GetParam(); - if (semantics != SdpSemantics::kUnifiedPlan) - return; - std::unique_ptr wrapper = - CreatePeerConnection(media_type, semantics); - auto transceiver = wrapper->AddTransceiver(media_type); - auto session_description = wrapper->CreateOffer(); - EXPECT_THAT(session_description->description() - ->contents()[0] - .media_description() - ->rtp_header_extensions(), - ElementsAre(Field(&RtpExtension::uri, "uri2"), - Field(&RtpExtension::uri, "uri3"), - Field(&RtpExtension::uri, "uri4"))); -} - -TEST_P(PeerConnectionHeaderExtensionTest, OffersUnstoppedModifiedExtensions) { - cricket::MediaType media_type; - SdpSemantics semantics; - std::tie(media_type, semantics) = GetParam(); - if (semantics != SdpSemantics::kUnifiedPlan) - return; - std::unique_ptr wrapper = - CreatePeerConnection(media_type, semantics); - auto transceiver = wrapper->AddTransceiver(media_type); - auto modified_extensions = transceiver->HeaderExtensionsToOffer(); - modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv; - modified_extensions[3].direction = RtpTransceiverDirection::kStopped; - EXPECT_TRUE( - transceiver->SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - auto session_description = wrapper->CreateOffer(); - EXPECT_THAT(session_description->description() - ->contents()[0] - .media_description() - ->rtp_header_extensions(), - ElementsAre(Field(&RtpExtension::uri, "uri1"), - Field(&RtpExtension::uri, "uri2"), - Field(&RtpExtension::uri, "uri3"))); -} - INSTANTIATE_TEST_SUITE_P( , PeerConnectionHeaderExtensionTest, diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index b4e500bbc8..d6e5ff46a1 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -114,7 +114,7 @@ RtpTransceiver::RtpTransceiver( : unified_plan_(true), media_type_(sender->media_type()), channel_manager_(channel_manager), - header_extensions_to_offer_(std::move(header_extensions_offered)) { + HeaderExtensionsToOffer_(std::move(header_extensions_offered)) { RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || media_type_ == cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); @@ -356,51 +356,7 @@ RTCError RtpTransceiver::SetCodecPreferences( std::vector RtpTransceiver::HeaderExtensionsToOffer() const { - return header_extensions_to_offer_; -} - -RTCError RtpTransceiver::SetOfferedRtpHeaderExtensions( - rtc::ArrayView - header_extensions_to_offer) { - for (const auto& entry : header_extensions_to_offer) { - // Handle unsupported requests for mandatory extensions as per - // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface. - // Note: - // - We do not handle setOfferedRtpHeaderExtensions algorithm step 2.1, - // this has to be checked on a higher level. We naturally error out - // in the handling of Step 2.2 if an unset URI is encountered. - - // Step 2.2. - // Handle unknown extensions. - auto it = std::find_if( - header_extensions_to_offer_.begin(), header_extensions_to_offer_.end(), - [&entry](const auto& offered) { return entry.uri == offered.uri; }); - if (it == header_extensions_to_offer_.end()) { - return RTCError(RTCErrorType::INVALID_PARAMETER, - "Attempted to modify an unoffered extension."); - } - - // Step 2.4-2.5. - // - Use of the transceiver interface indicates unified plan is in effect, - // hence the MID extension needs to be enabled. - // - Also handle the mandatory video orientation extensions. - if ((entry.uri == RtpExtension::kMidUri || - entry.uri == RtpExtension::kVideoRotationUri) && - entry.direction != RtpTransceiverDirection::kSendRecv) { - return RTCError(RTCErrorType::INVALID_MODIFICATION, - "Attempted to stop a mandatory extension."); - } - } - - // Apply mutation after error checking. - for (const auto& entry : header_extensions_to_offer) { - auto it = std::find_if( - header_extensions_to_offer_.begin(), header_extensions_to_offer_.end(), - [&entry](const auto& offered) { return entry.uri == offered.uri; }); - it->direction = entry.direction; - } - - return RTCError::OK(); + return HeaderExtensionsToOffer_; } } // namespace webrtc diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h index be46ccfd5c..0668447b9f 100644 --- a/pc/rtp_transceiver.h +++ b/pc/rtp_transceiver.h @@ -195,9 +195,6 @@ class RtpTransceiver final } std::vector HeaderExtensionsToOffer() const override; - RTCError SetOfferedRtpHeaderExtensions( - rtc::ArrayView - header_extensions_to_offer) override; private: void OnFirstPacketReceived(cricket::ChannelInterface* channel); @@ -223,7 +220,7 @@ class RtpTransceiver final cricket::ChannelInterface* channel_ = nullptr; cricket::ChannelManager* channel_manager_ = nullptr; std::vector codec_preferences_; - std::vector header_extensions_to_offer_; + std::vector HeaderExtensionsToOffer_; }; BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver) @@ -244,9 +241,6 @@ PROXY_METHOD1(webrtc::RTCError, PROXY_CONSTMETHOD0(std::vector, codec_preferences) PROXY_CONSTMETHOD0(std::vector, HeaderExtensionsToOffer) -PROXY_METHOD1(webrtc::RTCError, - SetOfferedRtpHeaderExtensions, - rtc::ArrayView) END_PROXY_MAP() } // namespace webrtc diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc index e3f05c4dd9..5e345739f1 100644 --- a/pc/rtp_transceiver_unittest.cc +++ b/pc/rtp_transceiver_unittest.cc @@ -25,7 +25,6 @@ using ::testing::ElementsAre; using ::testing::Eq; using ::testing::Field; using ::testing::Not; -using ::testing::Property; using ::testing::Return; using ::testing::ReturnRef; @@ -79,95 +78,27 @@ TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) { EXPECT_EQ(nullptr, transceiver.channel()); } -class RtpTransceiverTestForHeaderExtensions : public ::testing::Test { - public: - RtpTransceiverTestForHeaderExtensions() - : channel_manager_(std::make_unique(), - std::make_unique(), - rtc::Thread::Current(), - rtc::Thread::Current()), - extensions_( - {RtpHeaderExtensionCapability("uri1", - 1, - RtpTransceiverDirection::kSendOnly), - RtpHeaderExtensionCapability("uri2", - 2, - RtpTransceiverDirection::kRecvOnly), - RtpHeaderExtensionCapability(RtpExtension::kMidUri, - 3, - RtpTransceiverDirection::kSendRecv), - RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri, - 4, - RtpTransceiverDirection::kSendRecv)}), - transceiver_(RtpSenderProxyWithInternal::Create( - rtc::Thread::Current(), - new rtc::RefCountedObject()), - RtpReceiverProxyWithInternal::Create( - rtc::Thread::Current(), - new rtc::RefCountedObject()), - &channel_manager_, - extensions_) {} - - cricket::ChannelManager channel_manager_; - std::vector extensions_; - RtpTransceiver transceiver_; -}; - -TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) { - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_); -} - -TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) { - auto modified_extensions = extensions_; - modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly; - EXPECT_TRUE( - transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions); - modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly; - EXPECT_TRUE( - transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions); - modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv; - EXPECT_TRUE( - transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions); - modified_extensions[0].direction = RtpTransceiverDirection::kInactive; - EXPECT_TRUE( - transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions); -} - -TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) { - auto modified_extensions = extensions_; - modified_extensions[0].direction = RtpTransceiverDirection::kStopped; - EXPECT_TRUE( - transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions).ok()); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), modified_extensions); -} - -TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsUnsupportedExtension) { - std::vector modified_extensions( - {RtpHeaderExtensionCapability("uri3", 1, - RtpTransceiverDirection::kSendRecv)}); - EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions), - Property(&RTCError::type, RTCErrorType::INVALID_PARAMETER)); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_); -} - -TEST_F(RtpTransceiverTestForHeaderExtensions, - RejectsStoppedMandatoryExtensions) { - std::vector modified_extensions = extensions_; - // Attempting to stop the mandatory MID extension. - modified_extensions[2].direction = RtpTransceiverDirection::kStopped; - EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions), - Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION)); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_); - modified_extensions = extensions_; - // Attempting to stop the mandatory video orientation extension. - modified_extensions[3].direction = RtpTransceiverDirection::kStopped; - EXPECT_THAT(transceiver_.SetOfferedRtpHeaderExtensions(modified_extensions), - Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION)); - EXPECT_EQ(transceiver_.HeaderExtensionsToOffer(), extensions_); +TEST(RtpTransceiverTest, + InitsWithChannelManagerRtpHeaderExtensionCapabilities) { + cricket::ChannelManager channel_manager( + std::make_unique(), + std::make_unique(), rtc::Thread::Current(), + rtc::Thread::Current()); + std::vector extensions({ + RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kSendRecv), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kRecvOnly), + }); + RtpTransceiver transceiver( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), + new rtc::RefCountedObject()), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), + new rtc::RefCountedObject()), + &channel_manager, extensions); + EXPECT_EQ(transceiver.HeaderExtensionsToOffer(), extensions); } } // namespace webrtc