blob: 88ddfe0332f5d116d0f2a08ccd1f9af4328b320f [file] [log] [blame]
/*
* 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 <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_options.h"
#include "api/candidate.h"
#include "api/jsep.h"
#include "api/jsep_ice_candidate.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 "media/base/media_channel.h"
#include "media/base/stream_params.h"
#include "p2p/base/port_allocator.h"
#include "pc/connection_context.h"
#include "pc/data_channel_controller.h"
#include "pc/jsep_transport_controller.h"
#include "pc/media_session.h"
#include "pc/media_stream_observer.h"
#include "pc/peer_connection_internal.h"
#include "pc/rtp_receiver.h"
#include "pc/rtp_transceiver.h"
#include "pc/rtp_transmission_manager.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/checks.h"
#include "rtc_base/operations_chain.h"
#include "rtc_base/ssl_stream_adapter.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();
// Creates an SdpOfferAnswerHandler. Modifies dependencies.
static std::unique_ptr<SdpOfferAnswerHandler> Create(
PeerConnectionSdpMethods* pc,
const PeerConnectionInterface::RTCConfiguration& configuration,
PeerConnectionDependencies& dependencies,
ConnectionContext* context);
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();
}
// 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;
absl::optional<rtc::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,
rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer);
void SetLocalDescription(
rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer);
void SetLocalDescription(SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc);
void SetLocalDescription(SetSessionDescriptionObserver* observer);
void SetRemoteDescription(
std::unique_ptr<SessionDescriptionInterface> desc,
rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer);
void SetRemoteDescription(SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc);
PeerConnectionInterface::RTCConfiguration GetConfiguration();
RTCError SetConfiguration(
const PeerConnectionInterface::RTCConfiguration& configuration);
bool AddIceCandidate(const IceCandidateInterface* candidate);
void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,
std::function<void(RTCError)> callback);
bool RemoveIceCandidates(const std::vector<cricket::Candidate>& candidates);
// Adds a locally generated candidate to the local description.
void AddLocalIceCandidate(const JsepIceCandidate* candidate);
void RemoveLocalIceCandidates(
const std::vector<cricket::Candidate>& candidates);
bool ShouldFireNegotiationNeededEvent(uint32_t event_id);
bool AddStream(MediaStreamInterface* local_stream);
void RemoveStream(MediaStreamInterface* local_stream);
absl::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`.
absl::optional<rtc::SSLRole> GuessSslRole() const;
// Destroys all media BaseChannels.
void DestroyMediaChannels();
rtc::scoped_refptr<StreamCollectionInterface> local_streams();
rtc::scoped_refptr<StreamCollectionInterface> remote_streams();
bool initial_offerer() {
RTC_DCHECK_RUN_ON(signaling_thread());
if (initial_offerer_) {
return *initial_offerer_;
}
return false;
}
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(PeerConnectionSdpMethods* pc,
ConnectionContext* context);
// Called from the `Create()` function. Can only be called
// once. Modifies dependencies.
void Initialize(
const PeerConnectionInterface::RTCConfiguration& configuration,
PeerConnectionDependencies& dependencies,
ConnectionContext* context);
rtc::Thread* signaling_thread() const;
rtc::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 std::map<std::string, const cricket::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.
void PlanBUpdateSendersAndReceivers(
const cricket::ContentInfo* audio_content,
const cricket::AudioContentDescription* audio_desc,
const cricket::ContentInfo* video_content,
const cricket::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,
rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
void DoCreateAnswer(
const PeerConnectionInterface::RTCOfferAnswerOptions& options,
rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
void DoSetLocalDescription(
std::unique_ptr<SessionDescriptionInterface> desc,
rtc::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,
cricket::ContentSource source,
const cricket::SessionDescription* description,
const std::map<std::string, const cricket::ContentGroup*>&
bundle_groups_by_mid);
bool IsUnifiedPlan() const RTC_RUN_ON(signaling_thread());
// Signals from MediaStreamObserver.
void OnAudioTrackAdded(AudioTrackInterface* track,
MediaStreamInterface* stream)
RTC_RUN_ON(signaling_thread());
void OnAudioTrackRemoved(AudioTrackInterface* track,
MediaStreamInterface* stream)
RTC_RUN_ON(signaling_thread());
void OnVideoTrackAdded(VideoTrackInterface* track,
MediaStreamInterface* stream)
RTC_RUN_ON(signaling_thread());
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(
rtc::scoped_refptr<RtpReceiverInternal> receiver,
const std::vector<std::string>& stream_ids,
std::vector<rtc::scoped_refptr<MediaStreamInterface>>* added_streams,
std::vector<rtc::scoped_refptr<MediaStreamInterface>>* removed_streams);
bool CheckIfNegotiationIsNeeded();
void GenerateNegotiationNeededEvent();
// Helper method which verifies SDP.
RTCError ValidateSessionDescription(
const SessionDescriptionInterface* sdesc,
cricket::ContentSource source,
const std::map<std::string, const cricket::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(
cricket::ContentSource source,
const SessionDescriptionInterface& new_session,
const SessionDescriptionInterface* old_local_description,
const SessionDescriptionInterface* old_remote_description,
const std::map<std::string, const cricket::ContentGroup*>&
bundle_groups_by_mid);
// Associate the given transceiver according to the JSEP rules.
RTCErrorOr<
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
AssociateTransceiver(cricket::ContentSource source,
SdpType type,
size_t mline_index,
const cricket::ContentInfo& content,
const cricket::ContentInfo* old_local_content,
const cricket::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 cricket::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(
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
transceiver,
const cricket::ContentInfo& content,
const cricket::ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread());
// Either creates or destroys the local data channel according to the given
// media section.
RTCError UpdateDataChannelTransport(cricket::ContentSource source,
const cricket::ContentInfo& content,
const cricket::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(cricket::SessionDescription* remote_description);
// Returns an RtpTransceiver, if available, that can be used to receive the
// given media type according to JSEP rules.
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
FindAvailableTransceiverToReceive(cricket::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,
cricket::MediaSessionOptions* session_options);
void GetOptionsForPlanBOffer(
const PeerConnectionInterface::RTCOfferAnswerOptions&
offer_answer_options,
cricket::MediaSessionOptions* session_options)
RTC_RUN_ON(signaling_thread());
void GetOptionsForUnifiedPlanOffer(
const PeerConnectionInterface::RTCOfferAnswerOptions&
offer_answer_options,
cricket::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,
cricket::MediaSessionOptions* session_options);
void GetOptionsForPlanBAnswer(
const PeerConnectionInterface::RTCOfferAnswerOptions&
offer_answer_options,
cricket::MediaSessionOptions* session_options)
RTC_RUN_ON(signaling_thread());
void GetOptionsForUnifiedPlanAnswer(
const PeerConnectionInterface::RTCOfferAnswerOptions&
offer_answer_options,
cricket::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(
cricket::MediaType media_type) RTC_RUN_ON(signaling_thread());
void AddUpToOneReceivingTransceiverOfType(cricket::MediaType media_type);
std::vector<
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
GetReceivingTransceiversOfType(cricket::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 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
transceiver,
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>* remove_list,
std::vector<rtc::scoped_refptr<MediaStreamInterface>>* removed_streams);
void RemoveRemoteStreamsIfEmpty(
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
remote_streams,
std::vector<rtc::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).
void RemoveSenders(cricket::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.
void UpdateLocalSenders(const std::vector<cricket::StreamParams>& streams,
cricket::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`.
void UpdateRemoteSendersList(
const std::vector<cricket::StreamParams>& streams,
bool default_track_needed,
cricket::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,
cricket::ContentSource source,
const std::map<std::string, const cricket::ContentGroup*>&
bundle_groups_by_mid);
RTCError PushdownTransportDescription(cricket::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 cricket::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 IceCandidateInterface* 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 IceCandidateInterface* candidate,
const SessionDescriptionInterface* remote_desc,
bool* valid);
RTCErrorOr<const cricket::ContentInfo*> FindContentInfo(
const SessionDescriptionInterface* description,
const IceCandidateInterface* 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.
RTCError CreateChannels(const cricket::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,
absl::optional<size_t>* audio_index,
absl::optional<size_t>* video_index,
absl::optional<size_t>* data_index,
cricket::MediaSessionOptions* session_options);
// Generates the active MediaDescriptionOptions for the local data channel
// given the specified MID.
cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForActiveData(
const std::string& mid) const;
// Generates the rejected MediaDescriptionOptions for the local data channel
// given the specified MID.
cricket::MediaDescriptionOptions GetMediaDescriptionOptionsForRejectedData(
const std::string& mid) const;
// Based on number of transceivers per media type, enabled or disable
// payload type based demuxing in the affected channels.
bool UpdatePayloadTypeDemuxingState(
cricket::ContentSource source,
const std::map<std::string, const cricket::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 IceCandidateInterface* candidate);
// ==================================================================
// Access to pc_ variables
cricket::MediaEngineInterface* media_engine() const;
TransceiverList* transceivers();
const TransceiverList* transceivers() const;
DataChannelController* data_channel_controller();
const DataChannelController* data_channel_controller() const;
cricket::PortAllocator* port_allocator();
const cricket::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());
// ===================================================================
const cricket::AudioOptions& audio_options() { return audio_options_; }
const cricket::VideoOptions& video_options() { return video_options_; }
bool ConfiguredForMedia() const;
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());
PeerConnectionInterface::SignalingState signaling_state_
RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable;
// Whether this peer is the caller. Set when the local description is applied.
absl::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread());
// Streams added via AddStream.
const rtc::scoped_refptr<StreamCollection> local_streams_
RTC_GUARDED_BY(signaling_thread());
// Streams created as a result of SetRemoteDescription.
const rtc::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.
rtc::scoped_refptr<rtc::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.
rtc::UniqueStringGenerator mid_generator_ RTC_GUARDED_BY(signaling_thread());
// List of content names for which the remote side triggered an ICE restart.
std::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:-").
rtc::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.
cricket::AudioOptions audio_options_ RTC_GUARDED_BY(signaling_thread());
cricket::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.
absl::optional<bool> initial_offerer_ RTC_GUARDED_BY(signaling_thread());
rtc::WeakPtrFactory<SdpOfferAnswerHandler> weak_ptr_factory_
RTC_GUARDED_BY(signaling_thread());
};
} // namespace webrtc
#endif // PC_SDP_OFFER_ANSWER_H_