1 /* 2 * Copyright 2012 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 interfaces for MediaStream, MediaTrack and MediaSource. 12 // These interfaces are used for implementing MediaStream and MediaTrack as 13 // defined in http://dev.w3.org/2011/webrtc/editor/webrtc.html#stream-api. These 14 // interfaces must be used only with PeerConnection. 15 16 #ifndef API_MEDIA_STREAM_INTERFACE_H_ 17 #define API_MEDIA_STREAM_INTERFACE_H_ 18 19 #include <stddef.h> 20 21 #include <string> 22 #include <vector> 23 24 #include "absl/types/optional.h" 25 #include "api/audio_options.h" 26 #include "api/scoped_refptr.h" 27 #include "api/video/recordable_encoded_frame.h" 28 #include "api/video/video_frame.h" 29 #include "api/video/video_sink_interface.h" 30 #include "api/video/video_source_interface.h" 31 #include "api/video_track_source_constraints.h" 32 #include "modules/audio_processing/include/audio_processing_statistics.h" 33 #include "rtc_base/ref_count.h" 34 #include "rtc_base/system/rtc_export.h" 35 36 namespace webrtc { 37 38 // Generic observer interface. 39 class ObserverInterface { 40 public: 41 virtual void OnChanged() = 0; 42 43 protected: ~ObserverInterface()44 virtual ~ObserverInterface() {} 45 }; 46 47 class NotifierInterface { 48 public: 49 virtual void RegisterObserver(ObserverInterface* observer) = 0; 50 virtual void UnregisterObserver(ObserverInterface* observer) = 0; 51 ~NotifierInterface()52 virtual ~NotifierInterface() {} 53 }; 54 55 // Base class for sources. A MediaStreamTrack has an underlying source that 56 // provides media. A source can be shared by multiple tracks. 57 class RTC_EXPORT MediaSourceInterface : public rtc::RefCountInterface, 58 public NotifierInterface { 59 public: 60 enum SourceState { kInitializing, kLive, kEnded, kMuted }; 61 62 virtual SourceState state() const = 0; 63 64 virtual bool remote() const = 0; 65 66 protected: 67 ~MediaSourceInterface() override = default; 68 }; 69 70 // C++ version of MediaStreamTrack. 71 // See: https://www.w3.org/TR/mediacapture-streams/#mediastreamtrack 72 class RTC_EXPORT MediaStreamTrackInterface : public rtc::RefCountInterface, 73 public NotifierInterface { 74 public: 75 enum TrackState { 76 kLive, 77 kEnded, 78 }; 79 80 static const char* const kAudioKind; 81 static const char* const kVideoKind; 82 83 // The kind() method must return kAudioKind only if the object is a 84 // subclass of AudioTrackInterface, and kVideoKind only if the 85 // object is a subclass of VideoTrackInterface. It is typically used 86 // to protect a static_cast<> to the corresponding subclass. 87 virtual std::string kind() const = 0; 88 89 // Track identifier. 90 virtual std::string id() const = 0; 91 92 // A disabled track will produce silence (if audio) or black frames (if 93 // video). Can be disabled and re-enabled. 94 virtual bool enabled() const = 0; 95 virtual bool set_enabled(bool enable) = 0; 96 97 // Live or ended. A track will never be live again after becoming ended. 98 virtual TrackState state() const = 0; 99 100 protected: 101 ~MediaStreamTrackInterface() override = default; 102 }; 103 104 // VideoTrackSourceInterface is a reference counted source used for 105 // VideoTracks. The same source can be used by multiple VideoTracks. 106 // VideoTrackSourceInterface is designed to be invoked on the signaling thread 107 // except for rtc::VideoSourceInterface<VideoFrame> methods that will be invoked 108 // on the worker thread via a VideoTrack. A custom implementation of a source 109 // can inherit AdaptedVideoTrackSource instead of directly implementing this 110 // interface. 111 class VideoTrackSourceInterface : public MediaSourceInterface, 112 public rtc::VideoSourceInterface<VideoFrame> { 113 public: 114 struct Stats { 115 // Original size of captured frame, before video adaptation. 116 int input_width; 117 int input_height; 118 }; 119 120 // Indicates that parameters suitable for screencasts should be automatically 121 // applied to RtpSenders. 122 // TODO(perkj): Remove these once all known applications have moved to 123 // explicitly setting suitable parameters for screencasts and don't need this 124 // implicit behavior. 125 virtual bool is_screencast() const = 0; 126 127 // Indicates that the encoder should denoise video before encoding it. 128 // If it is not set, the default configuration is used which is different 129 // depending on video codec. 130 // TODO(perkj): Remove this once denoising is done by the source, and not by 131 // the encoder. 132 virtual absl::optional<bool> needs_denoising() const = 0; 133 134 // Returns false if no stats are available, e.g, for a remote source, or a 135 // source which has not seen its first frame yet. 136 // 137 // Implementation should avoid blocking. 138 virtual bool GetStats(Stats* stats) = 0; 139 140 // Returns true if encoded output can be enabled in the source. 141 virtual bool SupportsEncodedOutput() const = 0; 142 143 // Reliably cause a key frame to be generated in encoded output. 144 // TODO(bugs.webrtc.org/11115): find optimal naming. 145 virtual void GenerateKeyFrame() = 0; 146 147 // Add an encoded video sink to the source and additionally cause 148 // a key frame to be generated from the source. The sink will be 149 // invoked from a decoder queue. 150 virtual void AddEncodedSink( 151 rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) = 0; 152 153 // Removes an encoded video sink from the source. 154 virtual void RemoveEncodedSink( 155 rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) = 0; 156 157 // Notify about constraints set on the source. The information eventually gets 158 // routed to attached sinks via VideoSinkInterface<>::OnConstraintsChanged. 159 // The call is expected to happen on the network thread. 160 // TODO(crbug/1255737): make pure virtual once downstream project adapts. ProcessConstraints(const webrtc::VideoTrackSourceConstraints & constraints)161 virtual void ProcessConstraints( 162 const webrtc::VideoTrackSourceConstraints& constraints) {} 163 164 protected: 165 ~VideoTrackSourceInterface() override = default; 166 }; 167 168 // VideoTrackInterface is designed to be invoked on the signaling thread except 169 // for rtc::VideoSourceInterface<VideoFrame> methods that must be invoked 170 // on the worker thread. 171 // PeerConnectionFactory::CreateVideoTrack can be used for creating a VideoTrack 172 // that ensures thread safety and that all methods are called on the right 173 // thread. 174 class RTC_EXPORT VideoTrackInterface 175 : public MediaStreamTrackInterface, 176 public rtc::VideoSourceInterface<VideoFrame> { 177 public: 178 // Video track content hint, used to override the source is_screencast 179 // property. 180 // See https://crbug.com/653531 and https://w3c.github.io/mst-content-hint. 181 enum class ContentHint { kNone, kFluid, kDetailed, kText }; 182 183 // Register a video sink for this track. Used to connect the track to the 184 // underlying video engine. AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame> * sink,const rtc::VideoSinkWants & wants)185 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink, 186 const rtc::VideoSinkWants& wants) override {} RemoveSink(rtc::VideoSinkInterface<VideoFrame> * sink)187 void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {} 188 189 virtual VideoTrackSourceInterface* GetSource() const = 0; 190 191 virtual ContentHint content_hint() const; set_content_hint(ContentHint hint)192 virtual void set_content_hint(ContentHint hint) {} 193 194 protected: 195 ~VideoTrackInterface() override = default; 196 }; 197 198 // Interface for receiving audio data from a AudioTrack. 199 class AudioTrackSinkInterface { 200 public: OnData(const void * audio_data,int bits_per_sample,int sample_rate,size_t number_of_channels,size_t number_of_frames)201 virtual void OnData(const void* audio_data, 202 int bits_per_sample, 203 int sample_rate, 204 size_t number_of_channels, 205 size_t number_of_frames) { 206 RTC_DCHECK_NOTREACHED() << "This method must be overridden, or not used."; 207 } 208 209 // In this method, `absolute_capture_timestamp_ms`, when available, is 210 // supposed to deliver the timestamp when this audio frame was originally 211 // captured. This timestamp MUST be based on the same clock as 212 // rtc::TimeMillis(). OnData(const void * audio_data,int bits_per_sample,int sample_rate,size_t number_of_channels,size_t number_of_frames,absl::optional<int64_t> absolute_capture_timestamp_ms)213 virtual void OnData(const void* audio_data, 214 int bits_per_sample, 215 int sample_rate, 216 size_t number_of_channels, 217 size_t number_of_frames, 218 absl::optional<int64_t> absolute_capture_timestamp_ms) { 219 // TODO(bugs.webrtc.org/10739): Deprecate the old OnData and make this one 220 // pure virtual. 221 return OnData(audio_data, bits_per_sample, sample_rate, number_of_channels, 222 number_of_frames); 223 } 224 225 // Returns the number of channels encoded by the sink. This can be less than 226 // the number_of_channels if down-mixing occur. A value of -1 means an unknown 227 // number. NumPreferredChannels()228 virtual int NumPreferredChannels() const { return -1; } 229 230 protected: ~AudioTrackSinkInterface()231 virtual ~AudioTrackSinkInterface() {} 232 }; 233 234 // AudioSourceInterface is a reference counted source used for AudioTracks. 235 // The same source can be used by multiple AudioTracks. 236 class RTC_EXPORT AudioSourceInterface : public MediaSourceInterface { 237 public: 238 class AudioObserver { 239 public: 240 virtual void OnSetVolume(double volume) = 0; 241 242 protected: ~AudioObserver()243 virtual ~AudioObserver() {} 244 }; 245 246 // TODO(deadbeef): Makes all the interfaces pure virtual after they're 247 // implemented in chromium. 248 249 // Sets the volume of the source. `volume` is in the range of [0, 10]. 250 // TODO(tommi): This method should be on the track and ideally volume should 251 // be applied in the track in a way that does not affect clones of the track. SetVolume(double volume)252 virtual void SetVolume(double volume) {} 253 254 // Registers/unregisters observers to the audio source. RegisterAudioObserver(AudioObserver * observer)255 virtual void RegisterAudioObserver(AudioObserver* observer) {} UnregisterAudioObserver(AudioObserver * observer)256 virtual void UnregisterAudioObserver(AudioObserver* observer) {} 257 258 // TODO(tommi): Make pure virtual. AddSink(AudioTrackSinkInterface * sink)259 virtual void AddSink(AudioTrackSinkInterface* sink) {} RemoveSink(AudioTrackSinkInterface * sink)260 virtual void RemoveSink(AudioTrackSinkInterface* sink) {} 261 262 // Returns options for the AudioSource. 263 // (for some of the settings this approach is broken, e.g. setting 264 // audio network adaptation on the source is the wrong layer of abstraction). 265 virtual const cricket::AudioOptions options() const; 266 }; 267 268 // Interface of the audio processor used by the audio track to collect 269 // statistics. 270 class AudioProcessorInterface : public rtc::RefCountInterface { 271 public: 272 struct AudioProcessorStatistics { 273 bool typing_noise_detected = false; 274 AudioProcessingStats apm_statistics; 275 }; 276 277 // Get audio processor statistics. The `has_remote_tracks` argument should be 278 // set if there are active remote tracks (this would usually be true during 279 // a call). If there are no remote tracks some of the stats will not be set by 280 // the AudioProcessor, because they only make sense if there is at least one 281 // remote track. 282 virtual AudioProcessorStatistics GetStats(bool has_remote_tracks) = 0; 283 284 protected: 285 ~AudioProcessorInterface() override = default; 286 }; 287 288 class RTC_EXPORT AudioTrackInterface : public MediaStreamTrackInterface { 289 public: 290 // TODO(deadbeef): Figure out if the following interface should be const or 291 // not. 292 virtual AudioSourceInterface* GetSource() const = 0; 293 294 // Add/Remove a sink that will receive the audio data from the track. 295 virtual void AddSink(AudioTrackSinkInterface* sink) = 0; 296 virtual void RemoveSink(AudioTrackSinkInterface* sink) = 0; 297 298 // Get the signal level from the audio track. 299 // Return true on success, otherwise false. 300 // TODO(deadbeef): Change the interface to int GetSignalLevel() and pure 301 // virtual after it's implemented in chromium. 302 virtual bool GetSignalLevel(int* level); 303 304 // Get the audio processor used by the audio track. Return null if the track 305 // does not have any processor. 306 // TODO(deadbeef): Make the interface pure virtual. 307 virtual rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor(); 308 309 protected: 310 ~AudioTrackInterface() override = default; 311 }; 312 313 typedef std::vector<rtc::scoped_refptr<AudioTrackInterface> > AudioTrackVector; 314 typedef std::vector<rtc::scoped_refptr<VideoTrackInterface> > VideoTrackVector; 315 316 // C++ version of https://www.w3.org/TR/mediacapture-streams/#mediastream. 317 // 318 // A major difference is that remote audio/video tracks (received by a 319 // PeerConnection/RtpReceiver) are not synchronized simply by adding them to 320 // the same stream; a session description with the correct "a=msid" attributes 321 // must be pushed down. 322 // 323 // Thus, this interface acts as simply a container for tracks. 324 class MediaStreamInterface : public rtc::RefCountInterface, 325 public NotifierInterface { 326 public: 327 virtual std::string id() const = 0; 328 329 virtual AudioTrackVector GetAudioTracks() = 0; 330 virtual VideoTrackVector GetVideoTracks() = 0; 331 virtual rtc::scoped_refptr<AudioTrackInterface> FindAudioTrack( 332 const std::string& track_id) = 0; 333 virtual rtc::scoped_refptr<VideoTrackInterface> FindVideoTrack( 334 const std::string& track_id) = 0; 335 336 // Takes ownership of added tracks. 337 // Note: Default implementations are for avoiding link time errors in 338 // implementations that mock this API. 339 // TODO(bugs.webrtc.org/13980): Remove default implementations. AddTrack(rtc::scoped_refptr<AudioTrackInterface> track)340 virtual bool AddTrack(rtc::scoped_refptr<AudioTrackInterface> track) { 341 RTC_CHECK_NOTREACHED(); 342 } AddTrack(rtc::scoped_refptr<VideoTrackInterface> track)343 virtual bool AddTrack(rtc::scoped_refptr<VideoTrackInterface> track) { 344 RTC_CHECK_NOTREACHED(); 345 } RemoveTrack(rtc::scoped_refptr<AudioTrackInterface> track)346 virtual bool RemoveTrack(rtc::scoped_refptr<AudioTrackInterface> track) { 347 RTC_CHECK_NOTREACHED(); 348 } RemoveTrack(rtc::scoped_refptr<VideoTrackInterface> track)349 virtual bool RemoveTrack(rtc::scoped_refptr<VideoTrackInterface> track) { 350 RTC_CHECK_NOTREACHED(); 351 } 352 // Deprecated: Should use scoped_refptr versions rather than pointers. AddTrack(AudioTrackInterface * track)353 [[deprecated("Pass a scoped_refptr")]] virtual bool AddTrack( 354 AudioTrackInterface* track) { 355 return AddTrack(rtc::scoped_refptr<AudioTrackInterface>(track)); 356 } AddTrack(VideoTrackInterface * track)357 [[deprecated("Pass a scoped_refptr")]] virtual bool AddTrack( 358 VideoTrackInterface* track) { 359 return AddTrack(rtc::scoped_refptr<VideoTrackInterface>(track)); 360 } RemoveTrack(AudioTrackInterface * track)361 [[deprecated("Pass a scoped_refptr")]] virtual bool RemoveTrack( 362 AudioTrackInterface* track) { 363 return RemoveTrack(rtc::scoped_refptr<AudioTrackInterface>(track)); 364 } RemoveTrack(VideoTrackInterface * track)365 [[deprecated("Pass a scoped_refptr")]] virtual bool RemoveTrack( 366 VideoTrackInterface* track) { 367 return RemoveTrack(rtc::scoped_refptr<VideoTrackInterface>(track)); 368 } 369 370 protected: 371 ~MediaStreamInterface() override = default; 372 }; 373 374 } // namespace webrtc 375 376 #endif // API_MEDIA_STREAM_INTERFACE_H_ 377