1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_MEDIA_BASE_MEDIAENGINE_H_ 29 #define TALK_MEDIA_BASE_MEDIAENGINE_H_ 30 31 #ifdef OSX 32 #include <CoreAudio/CoreAudio.h> 33 #endif 34 35 #include <limits.h> 36 37 #include <string> 38 #include <vector> 39 40 #include "talk/media/base/codec.h" 41 #include "talk/media/base/mediachannel.h" 42 #include "talk/media/base/mediacommon.h" 43 #include "talk/media/base/videocapturer.h" 44 #include "talk/media/base/videocommon.h" 45 #include "talk/media/base/videoprocessor.h" 46 #include "talk/media/base/voiceprocessor.h" 47 #include "talk/media/devices/devicemanager.h" 48 #include "webrtc/base/fileutils.h" 49 #include "webrtc/base/sigslotrepeater.h" 50 51 #if defined(GOOGLE_CHROME_BUILD) || defined(CHROMIUM_BUILD) 52 #define DISABLE_MEDIA_ENGINE_FACTORY 53 #endif 54 55 namespace cricket { 56 57 class VideoCapturer; 58 59 // MediaEngineInterface is an abstraction of a media engine which can be 60 // subclassed to support different media componentry backends. 61 // It supports voice and video operations in the same class to facilitate 62 // proper synchronization between both media types. 63 class MediaEngineInterface { 64 public: 65 // Default value to be used for SetAudioDelayOffset(). 66 static const int kDefaultAudioDelayOffset; 67 ~MediaEngineInterface()68 virtual ~MediaEngineInterface() {} 69 70 // Initialization 71 // Starts the engine. 72 virtual bool Init(rtc::Thread* worker_thread) = 0; 73 // Shuts down the engine. 74 virtual void Terminate() = 0; 75 // Returns what the engine is capable of, as a set of Capabilities, above. 76 virtual int GetCapabilities() = 0; 77 78 // MediaChannel creation 79 // Creates a voice media channel. Returns NULL on failure. 80 virtual VoiceMediaChannel *CreateChannel() = 0; 81 // Creates a video media channel, paired with the specified voice channel. 82 // Returns NULL on failure. 83 virtual VideoMediaChannel *CreateVideoChannel( 84 VoiceMediaChannel* voice_media_channel) = 0; 85 86 // Creates a soundclip object for playing sounds on. Returns NULL on failure. 87 virtual SoundclipMedia *CreateSoundclip() = 0; 88 89 // Configuration 90 // Gets global audio options. 91 virtual AudioOptions GetAudioOptions() const = 0; 92 // Sets global audio options. "options" are from AudioOptions, above. 93 virtual bool SetAudioOptions(const AudioOptions& options) = 0; 94 // Sets the value used by the echo canceller to offset delay values obtained 95 // from the OS. 96 virtual bool SetAudioDelayOffset(int offset) = 0; 97 // Sets the default (maximum) codec/resolution and encoder option to capture 98 // and encode video. 99 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) 100 = 0; 101 // Gets the default (maximum) codec/resolution and encoder option used to 102 // capture and encode video, as set by SetDefaultVideoEncoderConfig or the 103 // default from the video engine if not previously set. 104 virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const = 0; 105 106 // Device selection 107 // TODO(tschmelcher): Add method for selecting the soundclip device. 108 virtual bool SetSoundDevices(const Device* in_device, 109 const Device* out_device) = 0; 110 111 // Device configuration 112 // Gets the current speaker volume, as a value between 0 and 255. 113 virtual bool GetOutputVolume(int* level) = 0; 114 // Sets the current speaker volume, as a value between 0 and 255. 115 virtual bool SetOutputVolume(int level) = 0; 116 117 // Local monitoring 118 // Gets the current microphone level, as a value between 0 and 10. 119 virtual int GetInputLevel() = 0; 120 // Starts or stops the local microphone. Useful if local mic info is needed 121 // prior to a call being connected; the mic will be started automatically 122 // when a VoiceMediaChannel starts sending. 123 virtual bool SetLocalMonitor(bool enable) = 0; 124 // Installs a callback for raw frames from the local camera. 125 126 virtual const std::vector<AudioCodec>& audio_codecs() = 0; 127 virtual const std::vector<RtpHeaderExtension>& 128 audio_rtp_header_extensions() = 0; 129 virtual const std::vector<VideoCodec>& video_codecs() = 0; 130 virtual const std::vector<RtpHeaderExtension>& 131 video_rtp_header_extensions() = 0; 132 133 // Logging control 134 virtual void SetVoiceLogging(int min_sev, const char* filter) = 0; 135 virtual void SetVideoLogging(int min_sev, const char* filter) = 0; 136 137 // Starts AEC dump using existing file. 138 virtual bool StartAecDump(rtc::PlatformFile file) = 0; 139 140 // Voice processors for effects. 141 virtual bool RegisterVoiceProcessor(uint32 ssrc, 142 VoiceProcessor* video_processor, 143 MediaProcessorDirection direction) = 0; 144 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 145 VoiceProcessor* video_processor, 146 MediaProcessorDirection direction) = 0; 147 148 virtual VideoFormat GetStartCaptureFormat() const = 0; 149 150 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& 151 SignalVideoCaptureStateChange() = 0; 152 }; 153 154 155 #if !defined(DISABLE_MEDIA_ENGINE_FACTORY) 156 class MediaEngineFactory { 157 public: 158 typedef cricket::MediaEngineInterface* (*MediaEngineCreateFunction)(); 159 // Creates a media engine, using either the compiled system default or the 160 // creation function specified in SetCreateFunction, if specified. 161 static MediaEngineInterface* Create(); 162 // Sets the function used when calling Create. If unset, the compiled system 163 // default will be used. Returns the old create function, or NULL if one 164 // wasn't set. Likewise, NULL can be used as the |function| parameter to 165 // reset to the default behavior. 166 static MediaEngineCreateFunction SetCreateFunction( 167 MediaEngineCreateFunction function); 168 private: 169 static MediaEngineCreateFunction create_function_; 170 }; 171 #endif 172 173 // CompositeMediaEngine constructs a MediaEngine from separate 174 // voice and video engine classes. 175 template<class VOICE, class VIDEO> 176 class CompositeMediaEngine : public MediaEngineInterface { 177 public: CompositeMediaEngine()178 CompositeMediaEngine() {} ~CompositeMediaEngine()179 virtual ~CompositeMediaEngine() {} Init(rtc::Thread * worker_thread)180 virtual bool Init(rtc::Thread* worker_thread) { 181 if (!voice_.Init(worker_thread)) 182 return false; 183 if (!video_.Init(worker_thread)) { 184 voice_.Terminate(); 185 return false; 186 } 187 SignalVideoCaptureStateChange().repeat(video_.SignalCaptureStateChange); 188 return true; 189 } Terminate()190 virtual void Terminate() { 191 video_.Terminate(); 192 voice_.Terminate(); 193 } 194 GetCapabilities()195 virtual int GetCapabilities() { 196 return (voice_.GetCapabilities() | video_.GetCapabilities()); 197 } CreateChannel()198 virtual VoiceMediaChannel *CreateChannel() { 199 return voice_.CreateChannel(); 200 } CreateVideoChannel(VoiceMediaChannel * channel)201 virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) { 202 return video_.CreateChannel(channel); 203 } CreateSoundclip()204 virtual SoundclipMedia *CreateSoundclip() { 205 return voice_.CreateSoundclip(); 206 } 207 GetAudioOptions()208 virtual AudioOptions GetAudioOptions() const { 209 return voice_.GetOptions(); 210 } SetAudioOptions(const AudioOptions & options)211 virtual bool SetAudioOptions(const AudioOptions& options) { 212 return voice_.SetOptions(options); 213 } SetAudioDelayOffset(int offset)214 virtual bool SetAudioDelayOffset(int offset) { 215 return voice_.SetDelayOffset(offset); 216 } SetDefaultVideoEncoderConfig(const VideoEncoderConfig & config)217 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { 218 return video_.SetDefaultEncoderConfig(config); 219 } GetDefaultVideoEncoderConfig()220 virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const { 221 return video_.GetDefaultEncoderConfig(); 222 } 223 SetSoundDevices(const Device * in_device,const Device * out_device)224 virtual bool SetSoundDevices(const Device* in_device, 225 const Device* out_device) { 226 return voice_.SetDevices(in_device, out_device); 227 } 228 GetOutputVolume(int * level)229 virtual bool GetOutputVolume(int* level) { 230 return voice_.GetOutputVolume(level); 231 } SetOutputVolume(int level)232 virtual bool SetOutputVolume(int level) { 233 return voice_.SetOutputVolume(level); 234 } 235 GetInputLevel()236 virtual int GetInputLevel() { 237 return voice_.GetInputLevel(); 238 } SetLocalMonitor(bool enable)239 virtual bool SetLocalMonitor(bool enable) { 240 return voice_.SetLocalMonitor(enable); 241 } audio_codecs()242 virtual const std::vector<AudioCodec>& audio_codecs() { 243 return voice_.codecs(); 244 } audio_rtp_header_extensions()245 virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() { 246 return voice_.rtp_header_extensions(); 247 } video_codecs()248 virtual const std::vector<VideoCodec>& video_codecs() { 249 return video_.codecs(); 250 } video_rtp_header_extensions()251 virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() { 252 return video_.rtp_header_extensions(); 253 } 254 SetVoiceLogging(int min_sev,const char * filter)255 virtual void SetVoiceLogging(int min_sev, const char* filter) { 256 voice_.SetLogging(min_sev, filter); 257 } SetVideoLogging(int min_sev,const char * filter)258 virtual void SetVideoLogging(int min_sev, const char* filter) { 259 video_.SetLogging(min_sev, filter); 260 } 261 StartAecDump(rtc::PlatformFile file)262 virtual bool StartAecDump(rtc::PlatformFile file) { 263 return voice_.StartAecDump(file); 264 } 265 RegisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)266 virtual bool RegisterVoiceProcessor(uint32 ssrc, 267 VoiceProcessor* processor, 268 MediaProcessorDirection direction) { 269 return voice_.RegisterProcessor(ssrc, processor, direction); 270 } UnregisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)271 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 272 VoiceProcessor* processor, 273 MediaProcessorDirection direction) { 274 return voice_.UnregisterProcessor(ssrc, processor, direction); 275 } GetStartCaptureFormat()276 virtual VideoFormat GetStartCaptureFormat() const { 277 return video_.GetStartCaptureFormat(); 278 } 279 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& SignalVideoCaptureStateChange()280 SignalVideoCaptureStateChange() { 281 return signal_state_change_; 282 } 283 284 protected: 285 VOICE voice_; 286 VIDEO video_; 287 sigslot::repeater2<VideoCapturer*, CaptureState> signal_state_change_; 288 }; 289 290 // NullVoiceEngine can be used with CompositeMediaEngine in the case where only 291 // a video engine is desired. 292 class NullVoiceEngine { 293 public: Init(rtc::Thread * worker_thread)294 bool Init(rtc::Thread* worker_thread) { return true; } Terminate()295 void Terminate() {} GetCapabilities()296 int GetCapabilities() { return 0; } 297 // If you need this to return an actual channel, use FakeMediaEngine instead. CreateChannel()298 VoiceMediaChannel* CreateChannel() { 299 return NULL; 300 } CreateSoundclip()301 SoundclipMedia* CreateSoundclip() { 302 return NULL; 303 } SetDelayOffset(int offset)304 bool SetDelayOffset(int offset) { return true; } GetOptions()305 AudioOptions GetOptions() const { return AudioOptions(); } SetOptions(const AudioOptions & options)306 bool SetOptions(const AudioOptions& options) { return true; } SetDevices(const Device * in_device,const Device * out_device)307 bool SetDevices(const Device* in_device, const Device* out_device) { 308 return true; 309 } GetOutputVolume(int * level)310 bool GetOutputVolume(int* level) { 311 *level = 0; 312 return true; 313 } SetOutputVolume(int level)314 bool SetOutputVolume(int level) { return true; } GetInputLevel()315 int GetInputLevel() { return 0; } SetLocalMonitor(bool enable)316 bool SetLocalMonitor(bool enable) { return true; } codecs()317 const std::vector<AudioCodec>& codecs() { return codecs_; } rtp_header_extensions()318 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 319 return rtp_header_extensions_; 320 } SetLogging(int min_sev,const char * filter)321 void SetLogging(int min_sev, const char* filter) {} StartAecDump(rtc::PlatformFile file)322 bool StartAecDump(rtc::PlatformFile file) { return false; } RegisterProcessor(uint32 ssrc,VoiceProcessor * voice_processor,MediaProcessorDirection direction)323 bool RegisterProcessor(uint32 ssrc, 324 VoiceProcessor* voice_processor, 325 MediaProcessorDirection direction) { return true; } UnregisterProcessor(uint32 ssrc,VoiceProcessor * voice_processor,MediaProcessorDirection direction)326 bool UnregisterProcessor(uint32 ssrc, 327 VoiceProcessor* voice_processor, 328 MediaProcessorDirection direction) { return true; } 329 330 private: 331 std::vector<AudioCodec> codecs_; 332 std::vector<RtpHeaderExtension> rtp_header_extensions_; 333 }; 334 335 // NullVideoEngine can be used with CompositeMediaEngine in the case where only 336 // a voice engine is desired. 337 class NullVideoEngine { 338 public: Init(rtc::Thread * worker_thread)339 bool Init(rtc::Thread* worker_thread) { return true; } Terminate()340 void Terminate() {} GetCapabilities()341 int GetCapabilities() { return 0; } 342 // If you need this to return an actual channel, use FakeMediaEngine instead. CreateChannel(VoiceMediaChannel * voice_media_channel)343 VideoMediaChannel* CreateChannel( 344 VoiceMediaChannel* voice_media_channel) { 345 return NULL; 346 } SetOptions(const VideoOptions & options)347 bool SetOptions(const VideoOptions& options) { return true; } GetDefaultEncoderConfig()348 VideoEncoderConfig GetDefaultEncoderConfig() const { 349 return VideoEncoderConfig(); 350 } SetDefaultEncoderConfig(const VideoEncoderConfig & config)351 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { 352 return true; 353 } codecs()354 const std::vector<VideoCodec>& codecs() { return codecs_; } rtp_header_extensions()355 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 356 return rtp_header_extensions_; 357 } SetLogging(int min_sev,const char * filter)358 void SetLogging(int min_sev, const char* filter) {} GetStartCaptureFormat()359 VideoFormat GetStartCaptureFormat() const { return VideoFormat(); } 360 361 sigslot::signal2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 362 private: 363 std::vector<VideoCodec> codecs_; 364 std::vector<RtpHeaderExtension> rtp_header_extensions_; 365 }; 366 367 typedef CompositeMediaEngine<NullVoiceEngine, NullVideoEngine> NullMediaEngine; 368 369 enum DataChannelType { 370 DCT_NONE = 0, 371 DCT_RTP = 1, 372 DCT_SCTP = 2 373 }; 374 375 class DataEngineInterface { 376 public: ~DataEngineInterface()377 virtual ~DataEngineInterface() {} 378 virtual DataMediaChannel* CreateChannel(DataChannelType type) = 0; 379 virtual const std::vector<DataCodec>& data_codecs() = 0; 380 }; 381 382 } // namespace cricket 383 384 #endif // TALK_MEDIA_BASE_MEDIAENGINE_H_ 385