1 /* 2 * Copyright 2017 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_RTP_TRANSCEIVER_H_ 12 #define PC_RTP_TRANSCEIVER_H_ 13 14 #include <string> 15 #include <vector> 16 17 #include "api/rtp_transceiver_interface.h" 18 #include "pc/channel_interface.h" 19 #include "pc/channel_manager.h" 20 #include "pc/rtp_receiver.h" 21 #include "pc/rtp_sender.h" 22 23 namespace webrtc { 24 25 // Implementation of the public RtpTransceiverInterface. 26 // 27 // The RtpTransceiverInterface is only intended to be used with a PeerConnection 28 // that enables Unified Plan SDP. Thus, the methods that only need to implement 29 // public API features and are not used internally can assume exactly one sender 30 // and receiver. 31 // 32 // Since the RtpTransceiver is used internally by PeerConnection for tracking 33 // RtpSenders, RtpReceivers, and BaseChannels, and PeerConnection needs to be 34 // backwards compatible with Plan B SDP, this implementation is more flexible 35 // than that required by the WebRTC specification. 36 // 37 // With Plan B SDP, an RtpTransceiver can have any number of senders and 38 // receivers which map to a=ssrc lines in the m= section. 39 // With Unified Plan SDP, an RtpTransceiver will have exactly one sender and one 40 // receiver which are encapsulated by the m= section. 41 // 42 // This class manages the RtpSenders, RtpReceivers, and BaseChannel associated 43 // with this m= section. Since the transceiver, senders, and receivers are 44 // reference counted and can be referenced from JavaScript (in Chromium), these 45 // objects must be ready to live for an arbitrary amount of time. The 46 // BaseChannel is not reference counted and is owned by the ChannelManager, so 47 // the PeerConnection must take care of creating/deleting the BaseChannel and 48 // setting the channel reference in the transceiver to null when it has been 49 // deleted. 50 // 51 // The RtpTransceiver is specialized to either audio or video according to the 52 // MediaType specified in the constructor. Audio RtpTransceivers will have 53 // AudioRtpSenders, AudioRtpReceivers, and a VoiceChannel. Video RtpTransceivers 54 // will have VideoRtpSenders, VideoRtpReceivers, and a VideoChannel. 55 class RtpTransceiver final 56 : public rtc::RefCountedObject<RtpTransceiverInterface>, 57 public sigslot::has_slots<> { 58 public: 59 // Construct a Plan B-style RtpTransceiver with no senders, receivers, or 60 // channel set. 61 // |media_type| specifies the type of RtpTransceiver (and, by transitivity, 62 // the type of senders, receivers, and channel). Can either by audio or video. 63 explicit RtpTransceiver(cricket::MediaType media_type); 64 // Construct a Unified Plan-style RtpTransceiver with the given sender and 65 // receiver. The media type will be derived from the media types of the sender 66 // and receiver. The sender and receiver should have the same media type. 67 // |HeaderExtensionsToOffer| is used for initializing the return value of 68 // HeaderExtensionsToOffer(). 69 RtpTransceiver( 70 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender, 71 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>> 72 receiver, 73 cricket::ChannelManager* channel_manager, 74 std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer); 75 ~RtpTransceiver() override; 76 77 // Returns the Voice/VideoChannel set for this transceiver. May be null if 78 // the transceiver is not in the currently set local/remote description. channel()79 cricket::ChannelInterface* channel() const { return channel_; } 80 81 // Sets the Voice/VideoChannel. The caller must pass in the correct channel 82 // implementation based on the type of the transceiver. 83 void SetChannel(cricket::ChannelInterface* channel); 84 85 // Adds an RtpSender of the appropriate type to be owned by this transceiver. 86 // Must not be null. 87 void AddSender( 88 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender); 89 90 // Removes the given RtpSender. Returns false if the sender is not owned by 91 // this transceiver. 92 bool RemoveSender(RtpSenderInterface* sender); 93 94 // Returns a vector of the senders owned by this transceiver. 95 std::vector<rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>> senders()96 senders() const { 97 return senders_; 98 } 99 100 // Adds an RtpReceiver of the appropriate type to be owned by this 101 // transceiver. Must not be null. 102 void AddReceiver( 103 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>> 104 receiver); 105 106 // Removes the given RtpReceiver. Returns false if the sender is not owned by 107 // this transceiver. 108 bool RemoveReceiver(RtpReceiverInterface* receiver); 109 110 // Returns a vector of the receivers owned by this transceiver. 111 std::vector< 112 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>> receivers()113 receivers() const { 114 return receivers_; 115 } 116 117 // Returns the backing object for the transceiver's Unified Plan sender. 118 rtc::scoped_refptr<RtpSenderInternal> sender_internal() const; 119 120 // Returns the backing object for the transceiver's Unified Plan receiver. 121 rtc::scoped_refptr<RtpReceiverInternal> receiver_internal() const; 122 123 // RtpTransceivers are not associated until they have a corresponding media 124 // section set in SetLocalDescription or SetRemoteDescription. Therefore, 125 // when setting a local offer we need a way to remember which transceiver was 126 // used to create which media section in the offer. Storing the mline index 127 // in CreateOffer is specified in JSEP to allow us to do that. mline_index()128 absl::optional<size_t> mline_index() const { return mline_index_; } set_mline_index(absl::optional<size_t> mline_index)129 void set_mline_index(absl::optional<size_t> mline_index) { 130 mline_index_ = mline_index; 131 } 132 133 // Sets the MID for this transceiver. If the MID is not null, then the 134 // transceiver is considered "associated" with the media section that has the 135 // same MID. set_mid(const absl::optional<std::string> & mid)136 void set_mid(const absl::optional<std::string>& mid) { mid_ = mid; } 137 138 // Sets the intended direction for this transceiver. Intended to be used 139 // internally over SetDirection since this does not trigger a negotiation 140 // needed callback. set_direction(RtpTransceiverDirection direction)141 void set_direction(RtpTransceiverDirection direction) { 142 direction_ = direction; 143 } 144 145 // Sets the current direction for this transceiver as negotiated in an offer/ 146 // answer exchange. The current direction is null before an answer with this 147 // transceiver has been set. 148 void set_current_direction(RtpTransceiverDirection direction); 149 150 // Sets the fired direction for this transceiver. The fired direction is null 151 // until SetRemoteDescription is called or an answer is set (either local or 152 // remote). 153 void set_fired_direction(RtpTransceiverDirection direction); 154 155 // According to JSEP rules for SetRemoteDescription, RtpTransceivers can be 156 // reused only if they were added by AddTrack. set_created_by_addtrack(bool created_by_addtrack)157 void set_created_by_addtrack(bool created_by_addtrack) { 158 created_by_addtrack_ = created_by_addtrack; 159 } 160 // If AddTrack has been called then transceiver can't be removed during 161 // rollback. set_reused_for_addtrack(bool reused_for_addtrack)162 void set_reused_for_addtrack(bool reused_for_addtrack) { 163 reused_for_addtrack_ = reused_for_addtrack; 164 } 165 created_by_addtrack()166 bool created_by_addtrack() const { return created_by_addtrack_; } 167 reused_for_addtrack()168 bool reused_for_addtrack() const { return reused_for_addtrack_; } 169 170 // Returns true if this transceiver has ever had the current direction set to 171 // sendonly or sendrecv. has_ever_been_used_to_send()172 bool has_ever_been_used_to_send() const { 173 return has_ever_been_used_to_send_; 174 } 175 176 // Fired when the RtpTransceiver state changes such that negotiation is now 177 // needed (e.g., in response to a direction change). 178 sigslot::signal0<> SignalNegotiationNeeded; 179 180 // RtpTransceiverInterface implementation. 181 cricket::MediaType media_type() const override; 182 absl::optional<std::string> mid() const override; 183 rtc::scoped_refptr<RtpSenderInterface> sender() const override; 184 rtc::scoped_refptr<RtpReceiverInterface> receiver() const override; 185 bool stopped() const override; 186 RtpTransceiverDirection direction() const override; 187 void SetDirection(RtpTransceiverDirection new_direction) override; 188 absl::optional<RtpTransceiverDirection> current_direction() const override; 189 absl::optional<RtpTransceiverDirection> fired_direction() const override; 190 void Stop() override; 191 RTCError SetCodecPreferences( 192 rtc::ArrayView<RtpCodecCapability> codecs) override; codec_preferences()193 std::vector<RtpCodecCapability> codec_preferences() const override { 194 return codec_preferences_; 195 } 196 std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer() 197 const override; 198 RTCError SetOfferedRtpHeaderExtensions( 199 rtc::ArrayView<const RtpHeaderExtensionCapability> 200 header_extensions_to_offer) override; 201 202 private: 203 void OnFirstPacketReceived(cricket::ChannelInterface* channel); 204 205 const bool unified_plan_; 206 const cricket::MediaType media_type_; 207 std::vector<rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>> 208 senders_; 209 std::vector< 210 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>> 211 receivers_; 212 213 bool stopped_ = false; 214 RtpTransceiverDirection direction_ = RtpTransceiverDirection::kInactive; 215 absl::optional<RtpTransceiverDirection> current_direction_; 216 absl::optional<RtpTransceiverDirection> fired_direction_; 217 absl::optional<std::string> mid_; 218 absl::optional<size_t> mline_index_; 219 bool created_by_addtrack_ = false; 220 bool reused_for_addtrack_ = false; 221 bool has_ever_been_used_to_send_ = false; 222 223 cricket::ChannelInterface* channel_ = nullptr; 224 cricket::ChannelManager* channel_manager_ = nullptr; 225 std::vector<RtpCodecCapability> codec_preferences_; 226 std::vector<RtpHeaderExtensionCapability> header_extensions_to_offer_; 227 }; 228 229 BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver) 230 PROXY_SIGNALING_THREAD_DESTRUCTOR() 231 PROXY_CONSTMETHOD0(cricket::MediaType, media_type) 232 PROXY_CONSTMETHOD0(absl::optional<std::string>, mid) 233 PROXY_CONSTMETHOD0(rtc::scoped_refptr<RtpSenderInterface>, sender) 234 PROXY_CONSTMETHOD0(rtc::scoped_refptr<RtpReceiverInterface>, receiver) 235 PROXY_CONSTMETHOD0(bool, stopped) 236 PROXY_CONSTMETHOD0(RtpTransceiverDirection, direction) 237 PROXY_METHOD1(void, SetDirection, RtpTransceiverDirection) 238 PROXY_CONSTMETHOD0(absl::optional<RtpTransceiverDirection>, current_direction) 239 PROXY_CONSTMETHOD0(absl::optional<RtpTransceiverDirection>, fired_direction) 240 PROXY_METHOD0(void, Stop) 241 PROXY_METHOD1(webrtc::RTCError, 242 SetCodecPreferences, 243 rtc::ArrayView<RtpCodecCapability>) 244 PROXY_CONSTMETHOD0(std::vector<RtpCodecCapability>, codec_preferences) 245 PROXY_CONSTMETHOD0(std::vector<RtpHeaderExtensionCapability>, 246 HeaderExtensionsToOffer) 247 PROXY_METHOD1(webrtc::RTCError, 248 SetOfferedRtpHeaderExtensions, 249 rtc::ArrayView<const RtpHeaderExtensionCapability>) 250 END_PROXY_MAP() 251 252 } // namespace webrtc 253 254 #endif // PC_RTP_TRANSCEIVER_H_ 255