1 /* 2 * Copyright 2015 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 // This file contains classes that implement RtpSenderInterface. 12 // An RtpSender associates a MediaStreamTrackInterface with an underlying 13 // transport (provided by AudioProviderInterface/VideoProviderInterface) 14 15 #ifndef PC_RTP_SENDER_H_ 16 #define PC_RTP_SENDER_H_ 17 18 #include <stddef.h> 19 #include <stdint.h> 20 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 #include "absl/types/optional.h" 26 #include "api/crypto/frame_encryptor_interface.h" 27 #include "api/dtls_transport_interface.h" 28 #include "api/dtmf_sender_interface.h" 29 #include "api/frame_transformer_interface.h" 30 #include "api/media_stream_interface.h" 31 #include "api/media_types.h" 32 #include "api/rtc_error.h" 33 #include "api/rtp_parameters.h" 34 #include "api/rtp_sender_interface.h" 35 #include "api/scoped_refptr.h" 36 #include "api/sequence_checker.h" 37 #include "media/base/audio_source.h" 38 #include "media/base/media_channel.h" 39 #include "pc/dtmf_sender.h" 40 #include "pc/legacy_stats_collector_interface.h" 41 #include "rtc_base/checks.h" 42 #include "rtc_base/synchronization/mutex.h" 43 #include "rtc_base/thread.h" 44 #include "rtc_base/thread_annotations.h" 45 46 namespace webrtc { 47 48 bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters); 49 50 // Internal interface used by PeerConnection. 51 class RtpSenderInternal : public RtpSenderInterface { 52 public: 53 // Sets the underlying MediaEngine channel associated with this RtpSender. 54 // A VoiceMediaChannel should be used for audio RtpSenders and 55 // a VideoMediaChannel should be used for video RtpSenders. 56 // Must call SetMediaChannel(nullptr) before the media channel is destroyed. 57 virtual void SetMediaChannel(cricket::MediaChannel* media_channel) = 0; 58 59 // Used to set the SSRC of the sender, once a local description has been set. 60 // If `ssrc` is 0, this indiates that the sender should disconnect from the 61 // underlying transport (this occurs if the sender isn't seen in a local 62 // description). 63 virtual void SetSsrc(uint32_t ssrc) = 0; 64 65 virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0; 66 virtual void set_init_send_encodings( 67 const std::vector<RtpEncodingParameters>& init_send_encodings) = 0; 68 virtual void set_transport( 69 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) = 0; 70 71 virtual void Stop() = 0; 72 73 // `GetParameters` and `SetParameters` operate with a transactional model. 74 // Allow access to get/set parameters without invalidating transaction id. 75 virtual RtpParameters GetParametersInternal() const = 0; 76 virtual void SetParametersInternal(const RtpParameters& parameters, 77 SetParametersCallback, 78 bool blocking) = 0; 79 80 // GetParameters and SetParameters will remove deactivated simulcast layers 81 // and restore them on SetParameters. This is probably a Bad Idea, but we 82 // do not know who depends on this behavior 83 virtual RtpParameters GetParametersInternalWithAllLayers() const = 0; 84 virtual RTCError SetParametersInternalWithAllLayers( 85 const RtpParameters& parameters) = 0; 86 87 // Additional checks that are specific to the Sender type CheckSVCParameters(const RtpParameters & parameters)88 virtual RTCError CheckSVCParameters(const RtpParameters& parameters) { 89 return webrtc::RTCError::OK(); 90 } 91 92 // Returns an ID that changes every time SetTrack() is called, but 93 // otherwise remains constant. Used to generate IDs for stats. 94 // The special value zero means that no track is attached. 95 virtual int AttachmentId() const = 0; 96 97 // Disables the layers identified by the specified RIDs. 98 // If the specified list is empty, this is a no-op. 99 virtual RTCError DisableEncodingLayers( 100 const std::vector<std::string>& rid) = 0; 101 102 virtual void SetTransceiverAsStopped() = 0; 103 104 // Used by the owning transceiver to inform the sender on the currently 105 // selected codecs. 106 virtual void SetVideoCodecPreferences( 107 std::vector<cricket::VideoCodec> codec_preferences) = 0; 108 }; 109 110 // Shared implementation for RtpSenderInternal interface. 111 class RtpSenderBase : public RtpSenderInternal, public ObserverInterface { 112 public: 113 class SetStreamsObserver { 114 public: 115 virtual ~SetStreamsObserver() = default; 116 virtual void OnSetStreams() = 0; 117 }; 118 119 // Sets the underlying MediaEngine channel associated with this RtpSender. 120 // A VoiceMediaChannel should be used for audio RtpSenders and 121 // a VideoMediaChannel should be used for video RtpSenders. 122 // Must call SetMediaChannel(nullptr) before the media channel is destroyed. 123 void SetMediaChannel(cricket::MediaChannel* media_channel) override; 124 125 bool SetTrack(MediaStreamTrackInterface* track) override; track()126 rtc::scoped_refptr<MediaStreamTrackInterface> track() const override { 127 // This method is currently called from the worker thread by 128 // RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n. 129 // RTC_DCHECK_RUN_ON(signaling_thread_); 130 return track_; 131 } 132 133 RtpParameters GetParameters() const override; 134 RTCError SetParameters(const RtpParameters& parameters) override; 135 void SetParametersAsync(const RtpParameters& parameters, 136 SetParametersCallback callback) override; 137 138 // `GetParameters` and `SetParameters` operate with a transactional model. 139 // Allow access to get/set parameters without invalidating transaction id. 140 RtpParameters GetParametersInternal() const override; 141 void SetParametersInternal(const RtpParameters& parameters, 142 SetParametersCallback callback = nullptr, 143 bool blocking = true) override; 144 RTCError CheckSetParameters(const RtpParameters& parameters); 145 RtpParameters GetParametersInternalWithAllLayers() const override; 146 RTCError SetParametersInternalWithAllLayers( 147 const RtpParameters& parameters) override; 148 149 // Used to set the SSRC of the sender, once a local description has been set. 150 // If `ssrc` is 0, this indiates that the sender should disconnect from the 151 // underlying transport (this occurs if the sender isn't seen in a local 152 // description). 153 void SetSsrc(uint32_t ssrc) override; ssrc()154 uint32_t ssrc() const override { 155 // This method is currently called from the worker thread by 156 // RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n. 157 // RTC_DCHECK_RUN_ON(signaling_thread_); 158 return ssrc_; 159 } 160 stream_ids()161 std::vector<std::string> stream_ids() const override { 162 RTC_DCHECK_RUN_ON(signaling_thread_); 163 return stream_ids_; 164 } set_stream_ids(const std::vector<std::string> & stream_ids)165 void set_stream_ids(const std::vector<std::string>& stream_ids) override { 166 stream_ids_ = stream_ids; 167 } 168 void SetStreams(const std::vector<std::string>& stream_ids) override; 169 id()170 std::string id() const override { return id_; } 171 set_init_send_encodings(const std::vector<RtpEncodingParameters> & init_send_encodings)172 void set_init_send_encodings( 173 const std::vector<RtpEncodingParameters>& init_send_encodings) override { 174 init_parameters_.encodings = init_send_encodings; 175 } init_send_encodings()176 std::vector<RtpEncodingParameters> init_send_encodings() const override { 177 RTC_DCHECK_RUN_ON(signaling_thread_); 178 return init_parameters_.encodings; 179 } 180 set_transport(rtc::scoped_refptr<DtlsTransportInterface> dtls_transport)181 void set_transport( 182 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) override { 183 dtls_transport_ = dtls_transport; 184 } dtls_transport()185 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const override { 186 RTC_DCHECK_RUN_ON(signaling_thread_); 187 return dtls_transport_; 188 } 189 190 void SetFrameEncryptor( 191 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) override; 192 GetFrameEncryptor()193 rtc::scoped_refptr<FrameEncryptorInterface> GetFrameEncryptor() 194 const override { 195 return frame_encryptor_; 196 } 197 198 void Stop() override; 199 200 // Returns an ID that changes every time SetTrack() is called, but 201 // otherwise remains constant. Used to generate IDs for stats. 202 // The special value zero means that no track is attached. AttachmentId()203 int AttachmentId() const override { return attachment_id_; } 204 205 // Disables the layers identified by the specified RIDs. 206 // If the specified list is empty, this is a no-op. 207 RTCError DisableEncodingLayers(const std::vector<std::string>& rid) override; 208 209 void SetEncoderToPacketizerFrameTransformer( 210 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) override; 211 212 void SetEncoderSelector( 213 std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> 214 encoder_selector) override; 215 216 void SetEncoderSelectorOnChannel(); 217 SetTransceiverAsStopped()218 void SetTransceiverAsStopped() override { 219 RTC_DCHECK_RUN_ON(signaling_thread_); 220 is_transceiver_stopped_ = true; 221 } 222 SetVideoCodecPreferences(std::vector<cricket::VideoCodec> codec_preferences)223 void SetVideoCodecPreferences( 224 std::vector<cricket::VideoCodec> codec_preferences) override { 225 video_codec_preferences_ = codec_preferences; 226 } 227 228 protected: 229 // If `set_streams_observer` is not null, it is invoked when SetStreams() 230 // is called. `set_streams_observer` is not owned by this object. If not 231 // null, it must be valid at least until this sender becomes stopped. 232 RtpSenderBase(rtc::Thread* worker_thread, 233 const std::string& id, 234 SetStreamsObserver* set_streams_observer); 235 // TODO(bugs.webrtc.org/8694): Since SSRC == 0 is technically valid, figure 236 // out some other way to test if we have a valid SSRC. can_send_track()237 bool can_send_track() const { return track_ && ssrc_; } 238 239 virtual std::string track_kind() const = 0; 240 241 // Enable sending on the media channel. 242 virtual void SetSend() = 0; 243 // Disable sending on the media channel. 244 virtual void ClearSend() = 0; 245 246 // Template method pattern to allow subclasses to add custom behavior for 247 // when tracks are attached, detached, and for adding tracks to statistics. AttachTrack()248 virtual void AttachTrack() {} DetachTrack()249 virtual void DetachTrack() {} AddTrackToStats()250 virtual void AddTrackToStats() {} RemoveTrackFromStats()251 virtual void RemoveTrackFromStats() {} 252 253 rtc::Thread* const signaling_thread_; 254 rtc::Thread* const worker_thread_; 255 uint32_t ssrc_ = 0; 256 bool stopped_ RTC_GUARDED_BY(signaling_thread_) = false; 257 bool is_transceiver_stopped_ RTC_GUARDED_BY(signaling_thread_) = false; 258 int attachment_id_ = 0; 259 const std::string id_; 260 261 std::vector<std::string> stream_ids_; 262 RtpParameters init_parameters_; 263 std::vector<cricket::VideoCodec> video_codec_preferences_; 264 265 // TODO(tommi): `media_channel_` and several other member variables in this 266 // class (ssrc_, stopped_, etc) are accessed from more than one thread without 267 // a guard or lock. Internally there are also several Invoke()s that we could 268 // remove since the upstream code may already be performing several operations 269 // on the worker thread. 270 cricket::MediaChannel* media_channel_ = nullptr; 271 rtc::scoped_refptr<MediaStreamTrackInterface> track_; 272 273 rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_; 274 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_; 275 // `last_transaction_id_` is used to verify that `SetParameters` is receiving 276 // the parameters object that was last returned from `GetParameters`. 277 // As such, it is used for internal verification and is not observable by the 278 // the client. It is marked as mutable to enable `GetParameters` to be a 279 // const method. 280 mutable absl::optional<std::string> last_transaction_id_; 281 std::vector<std::string> disabled_rids_; 282 283 SetStreamsObserver* set_streams_observer_ = nullptr; 284 285 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer_; 286 std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> 287 encoder_selector_; 288 }; 289 290 // LocalAudioSinkAdapter receives data callback as a sink to the local 291 // AudioTrack, and passes the data to the sink of AudioSource. 292 class LocalAudioSinkAdapter : public AudioTrackSinkInterface, 293 public cricket::AudioSource { 294 public: 295 LocalAudioSinkAdapter(); 296 virtual ~LocalAudioSinkAdapter(); 297 298 private: 299 // AudioSinkInterface implementation. 300 void OnData(const void* audio_data, 301 int bits_per_sample, 302 int sample_rate, 303 size_t number_of_channels, 304 size_t number_of_frames, 305 absl::optional<int64_t> absolute_capture_timestamp_ms) override; 306 307 // AudioSinkInterface implementation. OnData(const void * audio_data,int bits_per_sample,int sample_rate,size_t number_of_channels,size_t number_of_frames)308 void OnData(const void* audio_data, 309 int bits_per_sample, 310 int sample_rate, 311 size_t number_of_channels, 312 size_t number_of_frames) override { 313 OnData(audio_data, bits_per_sample, sample_rate, number_of_channels, 314 number_of_frames, 315 /*absolute_capture_timestamp_ms=*/absl::nullopt); 316 } 317 318 // AudioSinkInterface implementation. NumPreferredChannels()319 int NumPreferredChannels() const override { return num_preferred_channels_; } 320 321 // cricket::AudioSource implementation. 322 void SetSink(cricket::AudioSource::Sink* sink) override; 323 324 cricket::AudioSource::Sink* sink_; 325 // Critical section protecting `sink_`. 326 Mutex lock_; 327 int num_preferred_channels_ = -1; 328 }; 329 330 class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase { 331 public: 332 // Construct an RtpSender for audio with the given sender ID. 333 // The sender is initialized with no track to send and no associated streams. 334 // StatsCollector provided so that Add/RemoveLocalAudioTrack can be called 335 // at the appropriate times. 336 // If `set_streams_observer` is not null, it is invoked when SetStreams() 337 // is called. `set_streams_observer` is not owned by this object. If not 338 // null, it must be valid at least until this sender becomes stopped. 339 static rtc::scoped_refptr<AudioRtpSender> Create( 340 rtc::Thread* worker_thread, 341 const std::string& id, 342 LegacyStatsCollectorInterface* stats, 343 SetStreamsObserver* set_streams_observer); 344 virtual ~AudioRtpSender(); 345 346 // DtmfSenderProvider implementation. 347 bool CanInsertDtmf() override; 348 bool InsertDtmf(int code, int duration) override; 349 350 // ObserverInterface implementation. 351 void OnChanged() override; 352 media_type()353 cricket::MediaType media_type() const override { 354 return cricket::MEDIA_TYPE_AUDIO; 355 } track_kind()356 std::string track_kind() const override { 357 return MediaStreamTrackInterface::kAudioKind; 358 } 359 360 rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override; 361 RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override; 362 363 protected: 364 AudioRtpSender(rtc::Thread* worker_thread, 365 const std::string& id, 366 LegacyStatsCollectorInterface* legacy_stats, 367 SetStreamsObserver* set_streams_observer); 368 369 void SetSend() override; 370 void ClearSend() override; 371 372 // Hooks to allow custom logic when tracks are attached and detached. 373 void AttachTrack() override; 374 void DetachTrack() override; 375 void AddTrackToStats() override; 376 void RemoveTrackFromStats() override; 377 378 private: voice_media_channel()379 cricket::VoiceMediaChannel* voice_media_channel() { 380 return static_cast<cricket::VoiceMediaChannel*>(media_channel_); 381 } audio_track()382 rtc::scoped_refptr<AudioTrackInterface> audio_track() const { 383 return rtc::scoped_refptr<AudioTrackInterface>( 384 static_cast<AudioTrackInterface*>(track_.get())); 385 } 386 387 LegacyStatsCollectorInterface* legacy_stats_ = nullptr; 388 rtc::scoped_refptr<DtmfSender> dtmf_sender_; 389 rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender_proxy_; 390 bool cached_track_enabled_ = false; 391 392 // Used to pass the data callback from the `track_` to the other end of 393 // cricket::AudioSource. 394 std::unique_ptr<LocalAudioSinkAdapter> sink_adapter_; 395 }; 396 397 class VideoRtpSender : public RtpSenderBase { 398 public: 399 // Construct an RtpSender for video with the given sender ID. 400 // The sender is initialized with no track to send and no associated streams. 401 // If `set_streams_observer` is not null, it is invoked when SetStreams() 402 // is called. `set_streams_observer` is not owned by this object. If not 403 // null, it must be valid at least until this sender becomes stopped. 404 static rtc::scoped_refptr<VideoRtpSender> Create( 405 rtc::Thread* worker_thread, 406 const std::string& id, 407 SetStreamsObserver* set_streams_observer); 408 virtual ~VideoRtpSender(); 409 410 // ObserverInterface implementation 411 void OnChanged() override; 412 media_type()413 cricket::MediaType media_type() const override { 414 return cricket::MEDIA_TYPE_VIDEO; 415 } track_kind()416 std::string track_kind() const override { 417 return MediaStreamTrackInterface::kVideoKind; 418 } 419 420 rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override; 421 RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override; 422 423 RTCError CheckSVCParameters(const RtpParameters& parameters) override; 424 425 protected: 426 VideoRtpSender(rtc::Thread* worker_thread, 427 const std::string& id, 428 SetStreamsObserver* set_streams_observer); 429 430 void SetSend() override; 431 void ClearSend() override; 432 433 // Hook to allow custom logic when tracks are attached. 434 void AttachTrack() override; 435 436 private: video_media_channel()437 cricket::VideoMediaChannel* video_media_channel() { 438 return static_cast<cricket::VideoMediaChannel*>(media_channel_); 439 } video_track()440 rtc::scoped_refptr<VideoTrackInterface> video_track() const { 441 return rtc::scoped_refptr<VideoTrackInterface>( 442 static_cast<VideoTrackInterface*>(track_.get())); 443 } 444 445 VideoTrackInterface::ContentHint cached_track_content_hint_ = 446 VideoTrackInterface::ContentHint::kNone; 447 }; 448 449 } // namespace webrtc 450 451 #endif // PC_RTP_SENDER_H_ 452