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