1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef PC_TRANSCEIVER_LIST_H_ 12*d9f75844SAndroid Build Coastguard Worker #define PC_TRANSCEIVER_LIST_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <algorithm> 17*d9f75844SAndroid Build Coastguard Worker #include <map> 18*d9f75844SAndroid Build Coastguard Worker #include <string> 19*d9f75844SAndroid Build Coastguard Worker #include <vector> 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 22*d9f75844SAndroid Build Coastguard Worker #include "api/media_types.h" 23*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h" 24*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h" 25*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_sender_interface.h" 26*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h" 27*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 28*d9f75844SAndroid Build Coastguard Worker #include "pc/rtp_transceiver.h" 29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h" 31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker typedef rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>> 36*d9f75844SAndroid Build Coastguard Worker RtpTransceiverProxyRefPtr; 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker // Captures partial state to be used for rollback. Applicable only in 39*d9f75844SAndroid Build Coastguard Worker // Unified Plan. 40*d9f75844SAndroid Build Coastguard Worker class TransceiverStableState { 41*d9f75844SAndroid Build Coastguard Worker public: TransceiverStableState()42*d9f75844SAndroid Build Coastguard Worker TransceiverStableState() {} 43*d9f75844SAndroid Build Coastguard Worker void set_newly_created(); 44*d9f75844SAndroid Build Coastguard Worker void SetMSectionIfUnset(absl::optional<std::string> mid, 45*d9f75844SAndroid Build Coastguard Worker absl::optional<size_t> mline_index); 46*d9f75844SAndroid Build Coastguard Worker void SetRemoteStreamIds(const std::vector<std::string>& ids); 47*d9f75844SAndroid Build Coastguard Worker void SetInitSendEncodings( 48*d9f75844SAndroid Build Coastguard Worker const std::vector<RtpEncodingParameters>& encodings); SetFiredDirection(absl::optional<RtpTransceiverDirection> fired_direction)49*d9f75844SAndroid Build Coastguard Worker void SetFiredDirection( 50*d9f75844SAndroid Build Coastguard Worker absl::optional<RtpTransceiverDirection> fired_direction) { 51*d9f75844SAndroid Build Coastguard Worker fired_direction_ = fired_direction; 52*d9f75844SAndroid Build Coastguard Worker } mid()53*d9f75844SAndroid Build Coastguard Worker absl::optional<std::string> mid() const { return mid_; } mline_index()54*d9f75844SAndroid Build Coastguard Worker absl::optional<size_t> mline_index() const { return mline_index_; } remote_stream_ids()55*d9f75844SAndroid Build Coastguard Worker absl::optional<std::vector<std::string>> remote_stream_ids() const { 56*d9f75844SAndroid Build Coastguard Worker return remote_stream_ids_; 57*d9f75844SAndroid Build Coastguard Worker } init_send_encodings()58*d9f75844SAndroid Build Coastguard Worker absl::optional<std::vector<RtpEncodingParameters>> init_send_encodings() 59*d9f75844SAndroid Build Coastguard Worker const { 60*d9f75844SAndroid Build Coastguard Worker return init_send_encodings_; 61*d9f75844SAndroid Build Coastguard Worker } has_m_section()62*d9f75844SAndroid Build Coastguard Worker bool has_m_section() const { return has_m_section_; } newly_created()63*d9f75844SAndroid Build Coastguard Worker bool newly_created() const { return newly_created_; } did_set_fired_direction()64*d9f75844SAndroid Build Coastguard Worker bool did_set_fired_direction() const { return fired_direction_.has_value(); } 65*d9f75844SAndroid Build Coastguard Worker // Because fired_direction() is nullable, did_set_fired_direction() is used to 66*d9f75844SAndroid Build Coastguard Worker // distinguish beteen "no value" and "null value". fired_direction()67*d9f75844SAndroid Build Coastguard Worker absl::optional<RtpTransceiverDirection> fired_direction() const { 68*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(did_set_fired_direction()); 69*d9f75844SAndroid Build Coastguard Worker return fired_direction_.value(); 70*d9f75844SAndroid Build Coastguard Worker } 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Worker private: 73*d9f75844SAndroid Build Coastguard Worker absl::optional<std::string> mid_; 74*d9f75844SAndroid Build Coastguard Worker absl::optional<size_t> mline_index_; 75*d9f75844SAndroid Build Coastguard Worker absl::optional<std::vector<std::string>> remote_stream_ids_; 76*d9f75844SAndroid Build Coastguard Worker absl::optional<std::vector<RtpEncodingParameters>> init_send_encodings_; 77*d9f75844SAndroid Build Coastguard Worker // Indicates that mid value from stable state has been captured and 78*d9f75844SAndroid Build Coastguard Worker // that rollback has to restore the transceiver. Also protects against 79*d9f75844SAndroid Build Coastguard Worker // subsequent overwrites. 80*d9f75844SAndroid Build Coastguard Worker bool has_m_section_ = false; 81*d9f75844SAndroid Build Coastguard Worker // Indicates that the transceiver was created as part of applying a 82*d9f75844SAndroid Build Coastguard Worker // description to track potential need for removing transceiver during 83*d9f75844SAndroid Build Coastguard Worker // rollback. 84*d9f75844SAndroid Build Coastguard Worker bool newly_created_ = false; 85*d9f75844SAndroid Build Coastguard Worker // `fired_direction_` is nullable, so an optional of an optional is used to 86*d9f75844SAndroid Build Coastguard Worker // distinguish between null and not set (sorry if this hurts your eyes). 87*d9f75844SAndroid Build Coastguard Worker absl::optional<absl::optional<RtpTransceiverDirection>> fired_direction_; 88*d9f75844SAndroid Build Coastguard Worker }; 89*d9f75844SAndroid Build Coastguard Worker 90*d9f75844SAndroid Build Coastguard Worker // This class encapsulates the active list of transceivers on a 91*d9f75844SAndroid Build Coastguard Worker // PeerConnection, and offers convenient functions on that list. 92*d9f75844SAndroid Build Coastguard Worker // It is a single-thread class; all operations must be performed 93*d9f75844SAndroid Build Coastguard Worker // on the same thread. 94*d9f75844SAndroid Build Coastguard Worker class TransceiverList { 95*d9f75844SAndroid Build Coastguard Worker public: 96*d9f75844SAndroid Build Coastguard Worker // Returns a copy of the currently active list of transceivers. The 97*d9f75844SAndroid Build Coastguard Worker // list consists of rtc::scoped_refptrs, which will keep the transceivers 98*d9f75844SAndroid Build Coastguard Worker // from being deallocated, even if they are removed from the TransceiverList. List()99*d9f75844SAndroid Build Coastguard Worker std::vector<RtpTransceiverProxyRefPtr> List() const { 100*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 101*d9f75844SAndroid Build Coastguard Worker return transceivers_; 102*d9f75844SAndroid Build Coastguard Worker } 103*d9f75844SAndroid Build Coastguard Worker // As above, but does not check thread ownership. Unsafe. 104*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/12692): Refactor and remove UnsafeList()105*d9f75844SAndroid Build Coastguard Worker std::vector<RtpTransceiverProxyRefPtr> UnsafeList() const { 106*d9f75844SAndroid Build Coastguard Worker return transceivers_; 107*d9f75844SAndroid Build Coastguard Worker } 108*d9f75844SAndroid Build Coastguard Worker 109*d9f75844SAndroid Build Coastguard Worker // Returns a list of the internal() pointers of the currently active list 110*d9f75844SAndroid Build Coastguard Worker // of transceivers. These raw pointers are not thread-safe, so need to 111*d9f75844SAndroid Build Coastguard Worker // be consumed on the same thread. 112*d9f75844SAndroid Build Coastguard Worker std::vector<RtpTransceiver*> ListInternal() const; 113*d9f75844SAndroid Build Coastguard Worker Add(RtpTransceiverProxyRefPtr transceiver)114*d9f75844SAndroid Build Coastguard Worker void Add(RtpTransceiverProxyRefPtr transceiver) { 115*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 116*d9f75844SAndroid Build Coastguard Worker transceivers_.push_back(transceiver); 117*d9f75844SAndroid Build Coastguard Worker } Remove(RtpTransceiverProxyRefPtr transceiver)118*d9f75844SAndroid Build Coastguard Worker void Remove(RtpTransceiverProxyRefPtr transceiver) { 119*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 120*d9f75844SAndroid Build Coastguard Worker transceivers_.erase( 121*d9f75844SAndroid Build Coastguard Worker std::remove(transceivers_.begin(), transceivers_.end(), transceiver), 122*d9f75844SAndroid Build Coastguard Worker transceivers_.end()); 123*d9f75844SAndroid Build Coastguard Worker } 124*d9f75844SAndroid Build Coastguard Worker RtpTransceiverProxyRefPtr FindBySender( 125*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<RtpSenderInterface> sender) const; 126*d9f75844SAndroid Build Coastguard Worker RtpTransceiverProxyRefPtr FindByMid(const std::string& mid) const; 127*d9f75844SAndroid Build Coastguard Worker RtpTransceiverProxyRefPtr FindByMLineIndex(size_t mline_index) const; 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker // Find or create the stable state for a transceiver. StableState(RtpTransceiverProxyRefPtr transceiver)130*d9f75844SAndroid Build Coastguard Worker TransceiverStableState* StableState(RtpTransceiverProxyRefPtr transceiver) { 131*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 132*d9f75844SAndroid Build Coastguard Worker return &(transceiver_stable_states_by_transceivers_[transceiver]); 133*d9f75844SAndroid Build Coastguard Worker } 134*d9f75844SAndroid Build Coastguard Worker DiscardStableStates()135*d9f75844SAndroid Build Coastguard Worker void DiscardStableStates() { 136*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 137*d9f75844SAndroid Build Coastguard Worker transceiver_stable_states_by_transceivers_.clear(); 138*d9f75844SAndroid Build Coastguard Worker } 139*d9f75844SAndroid Build Coastguard Worker StableStates()140*d9f75844SAndroid Build Coastguard Worker std::map<RtpTransceiverProxyRefPtr, TransceiverStableState>& StableStates() { 141*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 142*d9f75844SAndroid Build Coastguard Worker return transceiver_stable_states_by_transceivers_; 143*d9f75844SAndroid Build Coastguard Worker } 144*d9f75844SAndroid Build Coastguard Worker 145*d9f75844SAndroid Build Coastguard Worker private: 146*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; 147*d9f75844SAndroid Build Coastguard Worker std::vector<RtpTransceiverProxyRefPtr> transceivers_; 148*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/12692): Add RTC_GUARDED_BY(sequence_checker_); 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker // Holds changes made to transceivers during applying descriptors for 151*d9f75844SAndroid Build Coastguard Worker // potential rollback. Gets cleared once signaling state goes to stable. 152*d9f75844SAndroid Build Coastguard Worker std::map<RtpTransceiverProxyRefPtr, TransceiverStableState> 153*d9f75844SAndroid Build Coastguard Worker transceiver_stable_states_by_transceivers_ 154*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_); 155*d9f75844SAndroid Build Coastguard Worker // Holds remote stream ids for transceivers from stable state. 156*d9f75844SAndroid Build Coastguard Worker std::map<RtpTransceiverProxyRefPtr, std::vector<std::string>> 157*d9f75844SAndroid Build Coastguard Worker remote_stream_ids_by_transceivers_ RTC_GUARDED_BY(sequence_checker_); 158*d9f75844SAndroid Build Coastguard Worker }; 159*d9f75844SAndroid Build Coastguard Worker 160*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 161*d9f75844SAndroid Build Coastguard Worker 162*d9f75844SAndroid Build Coastguard Worker #endif // PC_TRANSCEIVER_LIST_H_ 163