| /* | |
| * Copyright 2020 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #ifndef PC_SDP_OFFER_ANSWER_H_ | |
| #define PC_SDP_OFFER_ANSWER_H_ | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <functional> | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include <vector> | |
| #include "absl/functional/any_invocable.h" | |
| #include "absl/strings/string_view.h" | |
| #include "api/audio_options.h" | |
| #include "api/candidate.h" | |
| #include "api/environment/environment.h" | |
| #include "api/jsep.h" | |
| #include "api/media_stream_interface.h" | |
| #include "api/media_types.h" | |
| #include "api/peer_connection_interface.h" | |
| #include "api/rtc_error.h" | |
| #include "api/rtp_transceiver_direction.h" | |
| #include "api/rtp_transceiver_interface.h" | |
| #include "api/scoped_refptr.h" | |
| #include "api/sequence_checker.h" | |
| #include "api/set_local_description_observer_interface.h" | |
| #include "api/set_remote_description_observer_interface.h" | |
| #include "api/uma_metrics.h" | |
| #include "api/video/video_bitrate_allocator_factory.h" | |
| #include "call/payload_type.h" | |
| #include "media/base/media_channel.h" | |
| #include "media/base/media_engine.h" | |
| #include "media/base/stream_params.h" | |
| #include "p2p/base/port_allocator.h" | |
| #include "pc/codec_vendor.h" | |
| #include "pc/connection_context.h" | |
| #include "pc/data_channel_controller.h" | |
| #include "pc/jsep_transport_controller.h" | |
| #include "pc/media_options.h" | |
| #include "pc/media_session.h" | |
| #include "pc/media_stream_observer.h" | |
| #include "pc/rtp_receiver.h" | |
| #include "pc/rtp_transceiver.h" | |
| #include "pc/rtp_transmission_manager.h" | |
| #include "pc/sdp_payload_type_suggester.h" | |
| #include "pc/sdp_state_provider.h" | |
| #include "pc/session_description.h" | |
| #include "pc/stream_collection.h" | |
| #include "pc/transceiver_list.h" | |
| #include "pc/webrtc_session_description_factory.h" | |
| #include "rtc_base/containers/flat_map.h" | |
| #include "rtc_base/containers/flat_set.h" | |
| #include "rtc_base/operations_chain.h" | |
| #include "rtc_base/rtc_certificate_generator.h" | |
| #include "rtc_base/ssl_stream_adapter.h" | |
| #include "rtc_base/system/plan_b_only.h" | |
| #include "rtc_base/thread.h" | |
| #include "rtc_base/thread_annotations.h" | |
| #include "rtc_base/unique_id_generator.h" | |
| #include "rtc_base/weak_ptr.h" | |
| namespace webrtc { | |
| // SdpOfferAnswerHandler is a component | |
| // of the PeerConnection object as defined | |
| // by the PeerConnectionInterface API surface. | |
| // The class is responsible for the following: | |
| // - Parsing and interpreting SDP. | |
| // - Generating offers and answers based on the current state. | |
| // This class lives on the signaling thread. | |
| class SdpOfferAnswerHandler : public SdpStateProvider { | |
| public: | |
| ~SdpOfferAnswerHandler() override; | |
| // Creates an SdpOfferAnswerHandler. Modifies dependencies. | |
| static std::unique_ptr<SdpOfferAnswerHandler> Create( | |
| const Environment& env, | |
| PeerConnectionSdpMethods* pc, | |
| const PeerConnectionInterface::RTCConfiguration& configuration, | |
| std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator, | |
| std::unique_ptr<webrtc::VideoBitrateAllocatorFactory> | |
| video_bitrate_allocator_factory, | |
| ConnectionContext* context, | |
| CodecLookupHelper* codec_lookup_helper); | |
| void ResetSessionDescFactory() { | |
| RTC_DCHECK_RUN_ON(signaling_thread()); | |
| webrtc_session_desc_factory_.reset(); | |
| } | |
| const WebRtcSessionDescriptionFactory* webrtc_session_desc_factory() const { | |
| RTC_DCHECK_RUN_ON(signaling_thread()); | |
| return webrtc_session_desc_factory_.get(); | |
| } | |
| VideoBitrateAllocatorFactory* video_bitrate_allocator_factory() const { | |
| RTC_DCHECK_RUN_ON(signaling_thread()); | |
| return video_bitrate_allocator_factory_.get(); | |
| } | |
| const AudioOptions& audio_options() { return audio_options_; } | |
| const VideoOptions& video_options() { return video_options_; } | |
| // Change signaling state to Closed, and perform appropriate actions. | |
| void Close(); | |
| // Called as part of destroying the owning PeerConnection. | |
| void PrepareForShutdown(); | |
| // Implementation of SdpStateProvider | |
| PeerConnectionInterface::SignalingState signaling_state() const override; | |
| const SessionDescriptionInterface* local_description() const override; | |
| const SessionDescriptionInterface* remote_description() const override; | |
| const SessionDescriptionInterface* current_local_description() const override; | |
| const SessionDescriptionInterface* current_remote_description() | |
| const override; | |
| const SessionDescriptionInterface* pending_local_description() const override; | |
| const SessionDescriptionInterface* pending_remote_description() | |
| const override; | |
| bool NeedsIceRestart(const std::string& content_name) const override; | |
| bool IceRestartPending(const std::string& content_name) const override; | |
| std::optional<SSLRole> GetDtlsRole(const std::string& mid) const override; | |
| void RestartIce(); | |
| // JSEP01 | |
| void CreateOffer( | |
| CreateSessionDescriptionObserver* observer, | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& options); | |
| void CreateAnswer( | |
| CreateSessionDescriptionObserver* observer, | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& options); | |
| void SetLocalDescription( | |
| std::unique_ptr<SessionDescriptionInterface> desc, | |
| scoped_refptr<SetLocalDescriptionObserverInterface> observer); | |
| void SetLocalDescription( | |
| scoped_refptr<SetLocalDescriptionObserverInterface> observer); | |
| void SetLocalDescription( | |
| scoped_refptr<SetSessionDescriptionObserver> observer, | |
| std::unique_ptr<SessionDescriptionInterface> desc); | |
| void SetLocalDescription( | |
| scoped_refptr<SetSessionDescriptionObserver> observer); | |
| void SetRemoteDescription( | |
| std::unique_ptr<SessionDescriptionInterface> desc, | |
| scoped_refptr<SetRemoteDescriptionObserverInterface> observer); | |
| void SetRemoteDescription( | |
| scoped_refptr<SetSessionDescriptionObserver> observer, | |
| std::unique_ptr<SessionDescriptionInterface> desc); | |
| PeerConnectionInterface::RTCConfiguration GetConfiguration(); | |
| RTCError SetConfiguration( | |
| const PeerConnectionInterface::RTCConfiguration& configuration); | |
| bool AddIceCandidate(const IceCandidate* candidate); | |
| void AddIceCandidate(std::unique_ptr<IceCandidate> candidate, | |
| std::function<void(RTCError)> callback); | |
| bool RemoveIceCandidate(const IceCandidate* candidate); | |
| // Adds a locally generated candidate to the local description. | |
| void AddLocalIceCandidate(const IceCandidate* candidate); | |
| void RemoveLocalIceCandidates(absl::string_view mid, | |
| const std::vector<Candidate>& candidates); | |
| bool ShouldFireNegotiationNeededEvent(uint32_t event_id); | |
| PLAN_B_ONLY bool AddStream(MediaStreamInterface* local_stream); | |
| PLAN_B_ONLY void RemoveStream(MediaStreamInterface* local_stream); | |
| std::optional<bool> is_caller() const; | |
| bool HasNewIceCredentials(); | |
| void UpdateNegotiationNeeded(); | |
| void AllocateSctpSids(); | |
| // Based on the negotiation state, guess what the SSLRole might be without | |
| // directly getting the information from the transport. | |
| // This is used for allocating stream ids for data channels. | |
| // See also `InternalDataChannelInit::fallback_ssl_role`. | |
| std::optional<SSLRole> GuessSslRole() const; | |
| // Gathers tasks from all transceivers to tear down the state that | |
| // belongs to the network and worker threads. | |
| // The caller is responsible for invoking the callbacks on the correct threads | |
| // in the order 1st network thread, 2nd worker thread. | |
| void GetMediaChannelTeardownTasks( | |
| std::vector<absl::AnyInvocable<void() &&>>& network_tasks, | |
| std::vector<absl::AnyInvocable<void() &&>>& worker_tasks); | |
| PLAN_B_ONLY scoped_refptr<StreamCollectionInterface> local_streams(); | |
| PLAN_B_ONLY scoped_refptr<StreamCollectionInterface> remote_streams(); | |
| bool initial_offerer() { | |
| RTC_DCHECK_RUN_ON(signaling_thread()); | |
| if (initial_offerer_) { | |
| return *initial_offerer_; | |
| } | |
| return false; | |
| } | |
| SdpMungingType sdp_munging_type() const { return last_sdp_munging_type_; } | |
| void DisableSdpMungingChecksForTesting() { | |
| disable_sdp_munging_checks_ = true; | |
| } | |
| PayloadTypeSuggester* pt_suggester() { return &pt_suggester_; } | |
| private: | |
| class RemoteDescriptionOperation; | |
| class ImplicitCreateSessionDescriptionObserver; | |
| friend class ImplicitCreateSessionDescriptionObserver; | |
| class SetSessionDescriptionObserverAdapter; | |
| friend class SetSessionDescriptionObserverAdapter; | |
| enum class SessionError { | |
| kNone, // No error. | |
| kContent, // Error in BaseChannel SetLocalContent/SetRemoteContent. | |
| kTransport, // Error from the underlying transport. | |
| }; | |
| // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec. | |
| // It makes the next CreateOffer() produce new ICE credentials even if | |
| // RTCOfferAnswerOptions::ice_restart is false. | |
| // https://w3c.github.io/webrtc-pc/#dfn-localufragstoreplace | |
| // TODO(hbos): When JsepTransportController/JsepTransport supports rollback, | |
| // move this type of logic to JsepTransportController/JsepTransport. | |
| class LocalIceCredentialsToReplace; | |
| // Only called by the Create() function. | |
| explicit SdpOfferAnswerHandler(const Environment& env, | |
| PeerConnectionSdpMethods* pc, | |
| ConnectionContext* context); | |
| // Called from the `Create()` function. Can only be called | |
| // once. Modifies dependencies. | |
| void Initialize( | |
| const PeerConnectionInterface::RTCConfiguration& configuration, | |
| std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator, | |
| std::unique_ptr<webrtc::VideoBitrateAllocatorFactory> | |
| video_bitrate_allocator_factory, | |
| ConnectionContext* context, | |
| CodecLookupHelper* codec_lookup_helper); | |
| Thread* signaling_thread() const; | |
| Thread* network_thread() const; | |
| // Non-const versions of local_description()/remote_description(), for use | |
| // internally. | |
| SessionDescriptionInterface* mutable_local_description() | |
| RTC_RUN_ON(signaling_thread()) { | |
| return pending_local_description_ ? pending_local_description_.get() | |
| : current_local_description_.get(); | |
| } | |
| SessionDescriptionInterface* mutable_remote_description() | |
| RTC_RUN_ON(signaling_thread()) { | |
| return pending_remote_description_ ? pending_remote_description_.get() | |
| : current_remote_description_.get(); | |
| } | |
| // Synchronous implementations of SetLocalDescription/SetRemoteDescription | |
| // that return an RTCError instead of invoking a callback. | |
| RTCError ApplyLocalDescription( | |
| std::unique_ptr<SessionDescriptionInterface> desc, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid); | |
| void ApplyRemoteDescription( | |
| std::unique_ptr<RemoteDescriptionOperation> operation); | |
| RTCError ReplaceRemoteDescription( | |
| std::unique_ptr<SessionDescriptionInterface> desc, | |
| SdpType sdp_type, | |
| std::unique_ptr<SessionDescriptionInterface>* replaced_description) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Part of ApplyRemoteDescription steps specific to Unified Plan. | |
| void ApplyRemoteDescriptionUpdateTransceiverState(SdpType sdp_type); | |
| // Part of ApplyRemoteDescription steps specific to plan b. | |
| PLAN_B_ONLY void PlanBUpdateSendersAndReceivers( | |
| const ContentInfo* audio_content, | |
| const AudioContentDescription* audio_desc, | |
| const ContentInfo* video_content, | |
| const VideoContentDescription* video_desc); | |
| // Implementation of the offer/answer exchange operations. These are chained | |
| // onto the `operations_chain_` when the public CreateOffer(), CreateAnswer(), | |
| // SetLocalDescription() and SetRemoteDescription() methods are invoked. | |
| void DoCreateOffer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& options, | |
| scoped_refptr<CreateSessionDescriptionObserver> observer); | |
| void DoCreateAnswer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& options, | |
| scoped_refptr<CreateSessionDescriptionObserver> observer); | |
| void DoSetLocalDescription( | |
| std::unique_ptr<SessionDescriptionInterface> desc, | |
| scoped_refptr<SetLocalDescriptionObserverInterface> observer); | |
| void DoSetRemoteDescription( | |
| std::unique_ptr<RemoteDescriptionOperation> operation); | |
| // Called after a DoSetRemoteDescription operation completes. | |
| void SetRemoteDescriptionPostProcess(bool was_answer) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Update the state, signaling if necessary. | |
| void ChangeSignalingState( | |
| PeerConnectionInterface::SignalingState signaling_state); | |
| RTCError UpdateSessionState( | |
| SdpType type, | |
| ContentSource source, | |
| const SessionDescription* description, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid); | |
| bool IsUnifiedPlan() const; | |
| // Signals from MediaStreamObserver. | |
| PLAN_B_ONLY void OnAudioTrackAdded(AudioTrackInterface* track, | |
| MediaStreamInterface* stream) | |
| RTC_RUN_ON(signaling_thread()); | |
| PLAN_B_ONLY void OnAudioTrackRemoved(AudioTrackInterface* track, | |
| MediaStreamInterface* stream) | |
| RTC_RUN_ON(signaling_thread()); | |
| PLAN_B_ONLY void OnVideoTrackAdded(VideoTrackInterface* track, | |
| MediaStreamInterface* stream) | |
| RTC_RUN_ON(signaling_thread()); | |
| PLAN_B_ONLY void OnVideoTrackRemoved(VideoTrackInterface* track, | |
| MediaStreamInterface* stream) | |
| RTC_RUN_ON(signaling_thread()); | |
| // | desc_type | is the type of the description that caused the rollback. | |
| RTCError Rollback(SdpType desc_type); | |
| void OnOperationsChainEmpty(); | |
| // Runs the algorithm **set the associated remote streams** specified in | |
| // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams. | |
| void SetAssociatedRemoteStreams( | |
| scoped_refptr<RtpReceiverInternal> receiver, | |
| const std::vector<std::string>& stream_ids, | |
| std::vector<scoped_refptr<MediaStreamInterface>>* added_streams, | |
| std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams); | |
| bool CheckIfNegotiationIsNeeded(); | |
| void GenerateNegotiationNeededEvent(); | |
| // Helper method which verifies SDP. | |
| RTCError ValidateSessionDescription( | |
| const SessionDescriptionInterface* sdesc, | |
| ContentSource source, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Updates the local RtpTransceivers according to the JSEP rules. Called as | |
| // part of setting the local/remote description. | |
| RTCError UpdateTransceiversAndDataChannels( | |
| ContentSource source, | |
| const SessionDescriptionInterface& new_session, | |
| const SessionDescriptionInterface* old_local_description, | |
| const SessionDescriptionInterface* old_remote_description, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid); | |
| // Associate the given transceiver according to the JSEP rules. | |
| RTCErrorOr<scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>> | |
| AssociateTransceiver(ContentSource source, | |
| SdpType type, | |
| size_t mline_index, | |
| const ContentInfo& content, | |
| const ContentInfo* old_local_content, | |
| const ContentInfo* old_remote_content) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Returns the media section in the given session description that is | |
| // associated with the RtpTransceiver. Returns null if none found or this | |
| // RtpTransceiver is not associated. Logic varies depending on the | |
| // SdpSemantics specified in the configuration. | |
| const ContentInfo* FindMediaSectionForTransceiver( | |
| const RtpTransceiver* transceiver, | |
| const SessionDescriptionInterface* sdesc) const; | |
| // Either creates or destroys the transceiver's BaseChannel according to the | |
| // given media section. | |
| RTCError UpdateTransceiverChannel( | |
| scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>> | |
| transceiver, | |
| const ContentInfo& content, | |
| const ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread()); | |
| // Either creates or destroys the local data channel according to the given | |
| // media section. | |
| RTCError UpdateDataChannelTransport(ContentSource source, | |
| const ContentInfo& content, | |
| const ContentGroup* bundle_group) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Check if a call to SetLocalDescription is acceptable with a session | |
| // description of the given type. | |
| bool ExpectSetLocalDescription(SdpType type); | |
| // Check if a call to SetRemoteDescription is acceptable with a session | |
| // description of the given type. | |
| bool ExpectSetRemoteDescription(SdpType type); | |
| // The offer/answer machinery assumes the media section MID is present and | |
| // unique. To support legacy end points that do not supply a=mid lines, this | |
| // method will modify the session description to add MIDs generated according | |
| // to the SDP semantics. | |
| void FillInMissingRemoteMids(SessionDescription* remote_description); | |
| // Returns an RtpTransceiver, if available, that can be used to receive the | |
| // given media type according to JSEP rules. | |
| scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>> | |
| FindAvailableTransceiverToReceive(webrtc::MediaType media_type) const; | |
| // Returns a MediaSessionOptions struct with options decided by `options`, | |
| // the local MediaStreams and DataChannels. | |
| void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options); | |
| PLAN_B_ONLY void GetOptionsForPlanBOffer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread()); | |
| void GetOptionsForUnifiedPlanOffer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread()); | |
| // Returns a MediaSessionOptions struct with options decided by | |
| // `constraints`, the local MediaStreams and DataChannels. | |
| void GetOptionsForAnswer(const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options); | |
| PLAN_B_ONLY void GetOptionsForPlanBAnswer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread()); | |
| void GetOptionsForUnifiedPlanAnswer( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& | |
| offer_answer_options, | |
| MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread()); | |
| const char* SessionErrorToString(SessionError error) const; | |
| std::string GetSessionErrorMsg(); | |
| // Returns the last error in the session. See the enum above for details. | |
| SessionError session_error() const { | |
| RTC_DCHECK_RUN_ON(signaling_thread()); | |
| return session_error_; | |
| } | |
| const std::string& session_error_desc() const { return session_error_desc_; } | |
| RTCError HandleLegacyOfferOptions( | |
| const PeerConnectionInterface::RTCOfferAnswerOptions& options); | |
| void RemoveRecvDirectionFromReceivingTransceiversOfType( | |
| webrtc::MediaType media_type) RTC_RUN_ON(signaling_thread()); | |
| void AddUpToOneReceivingTransceiverOfType(webrtc::MediaType media_type); | |
| std::vector<scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>> | |
| GetReceivingTransceiversOfType(webrtc::MediaType media_type) | |
| RTC_RUN_ON(signaling_thread()); | |
| // Runs the algorithm specified in | |
| // https://w3c.github.io/webrtc-pc/#process-remote-track-removal | |
| // This method will update the following lists: | |
| // `remove_list` is the list of transceivers for which the receiving track is | |
| // being removed. | |
| // `removed_streams` is the list of streams which no longer have a receiving | |
| // track so should be removed. | |
| void ProcessRemovalOfRemoteTrack( | |
| const scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>> | |
| transceiver, | |
| std::vector<scoped_refptr<RtpTransceiverInterface>>* remove_list, | |
| std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams); | |
| void RemoveRemoteStreamsIfEmpty( | |
| const std::vector<scoped_refptr<MediaStreamInterface>>& remote_streams, | |
| std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams); | |
| // Remove all local and remote senders of type `media_type`. | |
| // Called when a media type is rejected (m-line set to port 0). | |
| PLAN_B_ONLY void RemoveSenders(webrtc::MediaType media_type); | |
| // Loops through the vector of `streams` and finds added and removed | |
| // StreamParams since last time this method was called. | |
| // For each new or removed StreamParam, OnLocalSenderSeen or | |
| // OnLocalSenderRemoved is invoked. | |
| PLAN_B_ONLY void UpdateLocalSendersPlanB( | |
| const std::vector<StreamParams>& streams, | |
| webrtc::MediaType media_type); | |
| // Makes sure a MediaStreamTrack is created for each StreamParam in `streams`, | |
| // and existing MediaStreamTracks are removed if there is no corresponding | |
| // StreamParam. If `default_track_needed` is true, a default MediaStreamTrack | |
| // is created if it doesn't exist; if false, it's removed if it exists. | |
| // `media_type` is the type of the `streams` and can be either audio or video. | |
| // If a new MediaStream is created it is added to `new_streams`. | |
| PLAN_B_ONLY void UpdateRemoteSendersListPlanB( | |
| const std::vector<StreamParams>& streams, | |
| bool default_track_needed, | |
| webrtc::MediaType media_type, | |
| StreamCollection* new_streams); | |
| // Enables media channels to allow sending of media. | |
| // This enables media to flow on all configured audio/video channels. | |
| void EnableSending(); | |
| // Push the media parts of the local or remote session description | |
| // down to all of the channels, and start SCTP if needed. | |
| RTCError PushdownMediaDescription( | |
| SdpType type, | |
| ContentSource source, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid); | |
| RTCError PushdownTransportDescription(ContentSource source, SdpType type); | |
| // Helper function to remove stopped transceivers. | |
| void RemoveStoppedTransceivers(); | |
| // Deletes the corresponding channel of contents that don't exist in `desc`. | |
| // `desc` can be null. This means that all channels are deleted. | |
| void RemoveUnusedChannels(const SessionDescription* desc); | |
| // Finds remote MediaStreams without any tracks and removes them from | |
| // `remote_streams_` and notifies the observer that the MediaStreams no longer | |
| // exist. | |
| void UpdateEndedRemoteMediaStreams(); | |
| // Uses all remote candidates in the currently set remote_description(). | |
| // If no remote description is currently set (nullptr), the return value will | |
| // be true. If `UseCandidate()` fails for any candidate in the remote | |
| // description, the return value will be false. | |
| bool UseCandidatesInRemoteDescription(); | |
| // Uses `candidate` in this session. | |
| bool UseCandidate(const IceCandidate* candidate); | |
| // Returns true if we are ready to push down the remote candidate. | |
| // `remote_desc` is the new remote description, or NULL if the current remote | |
| // description should be used. Output `valid` is true if the candidate media | |
| // index is valid. | |
| bool ReadyToUseRemoteCandidate(const IceCandidate* candidate, | |
| const SessionDescriptionInterface* remote_desc, | |
| bool* valid); | |
| RTCErrorOr<const ContentInfo*> FindContentInfo( | |
| const SessionDescriptionInterface* description, | |
| const IceCandidate* candidate) RTC_RUN_ON(signaling_thread()); | |
| // Functions for dealing with transports. | |
| // Note that cricket code uses the term "channel" for what other code | |
| // refers to as "transport". | |
| // Allocates media channels based on the `desc`. If `desc` doesn't have | |
| // the BUNDLE option, this method will disable BUNDLE in PortAllocator. | |
| // This method will also delete any existing media channels before creating. | |
| PLAN_B_ONLY RTCError CreateChannels(const SessionDescription& desc); | |
| // Generates MediaDescriptionOptions for the `session_opts` based on existing | |
| // local description or remote description. | |
| void GenerateMediaDescriptionOptions( | |
| const SessionDescriptionInterface* session_desc, | |
| RtpTransceiverDirection audio_direction, | |
| RtpTransceiverDirection video_direction, | |
| std::optional<size_t>* audio_index, | |
| std::optional<size_t>* video_index, | |
| std::optional<size_t>* data_index, | |
| MediaSessionOptions* session_options); | |
| // Generates the active MediaDescriptionOptions for the local data channel | |
| // given the specified MID. | |
| MediaDescriptionOptions GetMediaDescriptionOptionsForActiveData( | |
| absl::string_view mid) const; | |
| // Generates the rejected MediaDescriptionOptions for the local data channel | |
| // given the specified MID. | |
| MediaDescriptionOptions GetMediaDescriptionOptionsForRejectedData( | |
| absl::string_view mid) const; | |
| // Based on number of transceivers per media type, enabled or disable | |
| // payload type based demuxing in the affected channels. | |
| bool UpdatePayloadTypeDemuxingState( | |
| ContentSource source, | |
| const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid); | |
| // Updates the error state, signaling if necessary. | |
| void SetSessionError(SessionError error, const std::string& error_desc); | |
| // Implements AddIceCandidate without reporting usage, but returns the | |
| // particular success/error value that should be reported (and can be utilized | |
| // for other purposes). | |
| AddIceCandidateResult AddIceCandidateInternal(const IceCandidate* candidate); | |
| void ReportInitialSdpMunging(bool had_local_description, SdpType type); | |
| // Helper function to negotiate an SCTP m= line. | |
| void MaybeNegotiateSctp(MediaSessionOptions* session_options) | |
| RTC_RUN_ON(signaling_thread()); | |
| // ================================================================== | |
| // Access to pc_ variables | |
| const MediaEngineInterface* media_engine() const; | |
| TransceiverList* transceivers(); | |
| const TransceiverList* transceivers() const; | |
| DataChannelController* data_channel_controller(); | |
| const DataChannelController* data_channel_controller() const; | |
| PortAllocator* port_allocator(); | |
| const PortAllocator* port_allocator() const; | |
| RtpTransmissionManager* rtp_manager(); | |
| const RtpTransmissionManager* rtp_manager() const; | |
| JsepTransportController* transport_controller_s() | |
| RTC_RUN_ON(signaling_thread()); | |
| const JsepTransportController* transport_controller_s() const | |
| RTC_RUN_ON(signaling_thread()); | |
| JsepTransportController* transport_controller_n() | |
| RTC_RUN_ON(network_thread()); | |
| const JsepTransportController* transport_controller_n() const | |
| RTC_RUN_ON(network_thread()); | |
| // =================================================================== | |
| bool ConfiguredForMedia() const; | |
| const Environment& env_; | |
| PeerConnectionSdpMethods* const pc_; | |
| ConnectionContext* const context_; | |
| std::unique_ptr<WebRtcSessionDescriptionFactory> webrtc_session_desc_factory_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> current_local_description_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> pending_local_description_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> current_remote_description_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> pending_remote_description_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> last_created_offer_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<SessionDescriptionInterface> last_created_answer_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| SdpMungingType last_sdp_munging_type_ = SdpMungingType::kNoModification; | |
| PeerConnectionInterface::SignalingState signaling_state_ | |
| RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable; | |
| // Whether this peer is the caller. Set when the local description is applied. | |
| std::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread()); | |
| // Streams added via AddStream. | |
| const scoped_refptr<StreamCollection> local_streams_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| // Streams created as a result of SetRemoteDescription. | |
| const scoped_refptr<StreamCollection> remote_streams_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::vector<std::unique_ptr<MediaStreamObserver>> stream_observers_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| // The operations chain is used by the offer/answer exchange methods to ensure | |
| // they are executed in the right order. For example, if | |
| // SetRemoteDescription() is invoked while CreateOffer() is still pending, the | |
| // SRD operation will not start until CreateOffer() has completed. See | |
| // https://w3c.github.io/webrtc-pc/#dfn-operations-chain. | |
| scoped_refptr<OperationsChain> operations_chain_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| // One PeerConnection has only one RTCP CNAME. | |
| // https://tools.ietf.org/html/draft-ietf-rtcweb-rtp-usage-26#section-4.9 | |
| const std::string rtcp_cname_; | |
| // MIDs will be generated using this generator which will keep track of | |
| // all the MIDs that have been seen over the life of the PeerConnection. | |
| UniqueStringGenerator mid_generator_ RTC_GUARDED_BY(signaling_thread()); | |
| // List of content names for which the remote side triggered an ICE restart. | |
| flat_set<std::string> pending_ice_restarts_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| std::unique_ptr<LocalIceCredentialsToReplace> | |
| local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread()); | |
| bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false; | |
| bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false; | |
| uint32_t negotiation_needed_event_id_ RTC_GUARDED_BY(signaling_thread()) = 0; | |
| bool update_negotiation_needed_on_empty_chain_ | |
| RTC_GUARDED_BY(signaling_thread()) = false; | |
| // If PT demuxing is successfully negotiated one time we will allow PT | |
| // demuxing for the rest of the session so that PT-based apps default to PT | |
| // demuxing in follow-up O/A exchanges. | |
| bool pt_demuxing_has_been_used_audio_ RTC_GUARDED_BY(signaling_thread()) = | |
| false; | |
| bool pt_demuxing_has_been_used_video_ RTC_GUARDED_BY(signaling_thread()) = | |
| false; | |
| // In Unified Plan, if we encounter remote SDP that does not contain an a=msid | |
| // line we create and use a stream with a random ID for our receivers. This is | |
| // to support legacy endpoints that do not support the a=msid attribute (as | |
| // opposed to streamless tracks with "a=msid:-"). | |
| scoped_refptr<MediaStreamInterface> missing_msid_default_stream_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| SessionError session_error_ RTC_GUARDED_BY(signaling_thread()) = | |
| SessionError::kNone; | |
| std::string session_error_desc_ RTC_GUARDED_BY(signaling_thread()); | |
| // Member variables for caching global options. | |
| AudioOptions audio_options_ RTC_GUARDED_BY(signaling_thread()); | |
| VideoOptions video_options_ RTC_GUARDED_BY(signaling_thread()); | |
| // A video bitrate allocator factory. | |
| // This can be injected using the PeerConnectionDependencies, | |
| // or else the CreateBuiltinVideoBitrateAllocatorFactory() will be called. | |
| // Note that one can still choose to override this in a MediaEngine | |
| // if one wants too. | |
| std::unique_ptr<VideoBitrateAllocatorFactory> video_bitrate_allocator_factory_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| // Whether we are the initial offerer on the association. This | |
| // determines the SSL role. | |
| std::optional<bool> initial_offerer_ RTC_GUARDED_BY(signaling_thread()); | |
| // Whether SDP munging checks are enabled or not. | |
| // Some tests will be detected as SDP munging, so offer the option | |
| // to disable. | |
| bool disable_sdp_munging_checks_ = false; | |
| CodecLookupHelper* codec_lookup_helper_ = nullptr; | |
| // Whether the username fragment or the password of the SDP was munged. | |
| bool has_sdp_munged_ufrag_ = false; | |
| SdpPayloadTypeSuggester pt_suggester_; | |
| int max_sctp_streams_; | |
| WeakPtrFactory<SdpOfferAnswerHandler> weak_ptr_factory_ | |
| RTC_GUARDED_BY(signaling_thread()); | |
| }; | |
| } // namespace webrtc | |
| #endif // PC_SDP_OFFER_ANSWER_H_ |