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/base/fileutils.h" 41 #include "talk/base/sigslotrepeater.h" 42 #include "talk/media/base/codec.h" 43 #include "talk/media/base/mediachannel.h" 44 #include "talk/media/base/mediacommon.h" 45 #include "talk/media/base/videocapturer.h" 46 #include "talk/media/base/videocommon.h" 47 #include "talk/media/base/videoprocessor.h" 48 #include "talk/media/base/voiceprocessor.h" 49 #include "talk/media/devices/devicemanager.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(talk_base::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 global video options. "options" are from VideoOptions, above. 95 virtual bool SetVideoOptions(const VideoOptions& options) = 0; 96 // Sets the value used by the echo canceller to offset delay values obtained 97 // from the OS. 98 virtual bool SetAudioDelayOffset(int offset) = 0; 99 // Sets the default (maximum) codec/resolution and encoder option to capture 100 // and encode video. 101 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) 102 = 0; 103 // Gets the default (maximum) codec/resolution and encoder option used to 104 // capture and encode video, as set by SetDefaultVideoEncoderConfig or the 105 // default from the video engine if not previously set. 106 virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const = 0; 107 108 // Device selection 109 // TODO(tschmelcher): Add method for selecting the soundclip device. 110 virtual bool SetSoundDevices(const Device* in_device, 111 const Device* out_device) = 0; 112 113 // Device configuration 114 // Gets the current speaker volume, as a value between 0 and 255. 115 virtual bool GetOutputVolume(int* level) = 0; 116 // Sets the current speaker volume, as a value between 0 and 255. 117 virtual bool SetOutputVolume(int level) = 0; 118 119 // Local monitoring 120 // Gets the current microphone level, as a value between 0 and 10. 121 virtual int GetInputLevel() = 0; 122 // Starts or stops the local microphone. Useful if local mic info is needed 123 // prior to a call being connected; the mic will be started automatically 124 // when a VoiceMediaChannel starts sending. 125 virtual bool SetLocalMonitor(bool enable) = 0; 126 // Installs a callback for raw frames from the local camera. 127 virtual bool SetLocalRenderer(VideoRenderer* renderer) = 0; 128 129 virtual const std::vector<AudioCodec>& audio_codecs() = 0; 130 virtual const std::vector<RtpHeaderExtension>& 131 audio_rtp_header_extensions() = 0; 132 virtual const std::vector<VideoCodec>& video_codecs() = 0; 133 virtual const std::vector<RtpHeaderExtension>& 134 video_rtp_header_extensions() = 0; 135 136 // Logging control 137 virtual void SetVoiceLogging(int min_sev, const char* filter) = 0; 138 virtual void SetVideoLogging(int min_sev, const char* filter) = 0; 139 140 // Starts AEC dump using existing file. 141 virtual bool StartAecDump(talk_base::PlatformFile file) = 0; 142 143 // Voice processors for effects. 144 virtual bool RegisterVoiceProcessor(uint32 ssrc, 145 VoiceProcessor* video_processor, 146 MediaProcessorDirection direction) = 0; 147 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 148 VoiceProcessor* video_processor, 149 MediaProcessorDirection direction) = 0; 150 151 virtual VideoFormat GetStartCaptureFormat() const = 0; 152 153 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& 154 SignalVideoCaptureStateChange() = 0; 155 }; 156 157 158 #if !defined(DISABLE_MEDIA_ENGINE_FACTORY) 159 class MediaEngineFactory { 160 public: 161 typedef cricket::MediaEngineInterface* (*MediaEngineCreateFunction)(); 162 // Creates a media engine, using either the compiled system default or the 163 // creation function specified in SetCreateFunction, if specified. 164 static MediaEngineInterface* Create(); 165 // Sets the function used when calling Create. If unset, the compiled system 166 // default will be used. Returns the old create function, or NULL if one 167 // wasn't set. Likewise, NULL can be used as the |function| parameter to 168 // reset to the default behavior. 169 static MediaEngineCreateFunction SetCreateFunction( 170 MediaEngineCreateFunction function); 171 private: 172 static MediaEngineCreateFunction create_function_; 173 }; 174 #endif 175 176 // CompositeMediaEngine constructs a MediaEngine from separate 177 // voice and video engine classes. 178 template<class VOICE, class VIDEO> 179 class CompositeMediaEngine : public MediaEngineInterface { 180 public: CompositeMediaEngine()181 CompositeMediaEngine() {} ~CompositeMediaEngine()182 virtual ~CompositeMediaEngine() {} Init(talk_base::Thread * worker_thread)183 virtual bool Init(talk_base::Thread* worker_thread) { 184 if (!voice_.Init(worker_thread)) 185 return false; 186 if (!video_.Init(worker_thread)) { 187 voice_.Terminate(); 188 return false; 189 } 190 SignalVideoCaptureStateChange().repeat(video_.SignalCaptureStateChange); 191 return true; 192 } Terminate()193 virtual void Terminate() { 194 video_.Terminate(); 195 voice_.Terminate(); 196 } 197 GetCapabilities()198 virtual int GetCapabilities() { 199 return (voice_.GetCapabilities() | video_.GetCapabilities()); 200 } CreateChannel()201 virtual VoiceMediaChannel *CreateChannel() { 202 return voice_.CreateChannel(); 203 } CreateVideoChannel(VoiceMediaChannel * channel)204 virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) { 205 return video_.CreateChannel(channel); 206 } CreateSoundclip()207 virtual SoundclipMedia *CreateSoundclip() { 208 return voice_.CreateSoundclip(); 209 } 210 GetAudioOptions()211 virtual AudioOptions GetAudioOptions() const { 212 return voice_.GetOptions(); 213 } SetAudioOptions(const AudioOptions & options)214 virtual bool SetAudioOptions(const AudioOptions& options) { 215 return voice_.SetOptions(options); 216 } SetVideoOptions(const VideoOptions & options)217 virtual bool SetVideoOptions(const VideoOptions& options) { 218 return video_.SetOptions(options); 219 } SetAudioDelayOffset(int offset)220 virtual bool SetAudioDelayOffset(int offset) { 221 return voice_.SetDelayOffset(offset); 222 } SetDefaultVideoEncoderConfig(const VideoEncoderConfig & config)223 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { 224 return video_.SetDefaultEncoderConfig(config); 225 } GetDefaultVideoEncoderConfig()226 virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const { 227 return video_.GetDefaultEncoderConfig(); 228 } 229 SetSoundDevices(const Device * in_device,const Device * out_device)230 virtual bool SetSoundDevices(const Device* in_device, 231 const Device* out_device) { 232 return voice_.SetDevices(in_device, out_device); 233 } 234 GetOutputVolume(int * level)235 virtual bool GetOutputVolume(int* level) { 236 return voice_.GetOutputVolume(level); 237 } SetOutputVolume(int level)238 virtual bool SetOutputVolume(int level) { 239 return voice_.SetOutputVolume(level); 240 } 241 GetInputLevel()242 virtual int GetInputLevel() { 243 return voice_.GetInputLevel(); 244 } SetLocalMonitor(bool enable)245 virtual bool SetLocalMonitor(bool enable) { 246 return voice_.SetLocalMonitor(enable); 247 } SetLocalRenderer(VideoRenderer * renderer)248 virtual bool SetLocalRenderer(VideoRenderer* renderer) { 249 return video_.SetLocalRenderer(renderer); 250 } 251 audio_codecs()252 virtual const std::vector<AudioCodec>& audio_codecs() { 253 return voice_.codecs(); 254 } audio_rtp_header_extensions()255 virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() { 256 return voice_.rtp_header_extensions(); 257 } video_codecs()258 virtual const std::vector<VideoCodec>& video_codecs() { 259 return video_.codecs(); 260 } video_rtp_header_extensions()261 virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() { 262 return video_.rtp_header_extensions(); 263 } 264 SetVoiceLogging(int min_sev,const char * filter)265 virtual void SetVoiceLogging(int min_sev, const char* filter) { 266 voice_.SetLogging(min_sev, filter); 267 } SetVideoLogging(int min_sev,const char * filter)268 virtual void SetVideoLogging(int min_sev, const char* filter) { 269 video_.SetLogging(min_sev, filter); 270 } 271 StartAecDump(talk_base::PlatformFile file)272 virtual bool StartAecDump(talk_base::PlatformFile file) { 273 return voice_.StartAecDump(file); 274 } 275 RegisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)276 virtual bool RegisterVoiceProcessor(uint32 ssrc, 277 VoiceProcessor* processor, 278 MediaProcessorDirection direction) { 279 return voice_.RegisterProcessor(ssrc, processor, direction); 280 } UnregisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)281 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 282 VoiceProcessor* processor, 283 MediaProcessorDirection direction) { 284 return voice_.UnregisterProcessor(ssrc, processor, direction); 285 } GetStartCaptureFormat()286 virtual VideoFormat GetStartCaptureFormat() const { 287 return video_.GetStartCaptureFormat(); 288 } 289 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& SignalVideoCaptureStateChange()290 SignalVideoCaptureStateChange() { 291 return signal_state_change_; 292 } 293 294 protected: 295 VOICE voice_; 296 VIDEO video_; 297 sigslot::repeater2<VideoCapturer*, CaptureState> signal_state_change_; 298 }; 299 300 // NullVoiceEngine can be used with CompositeMediaEngine in the case where only 301 // a video engine is desired. 302 class NullVoiceEngine { 303 public: Init(talk_base::Thread * worker_thread)304 bool Init(talk_base::Thread* worker_thread) { return true; } Terminate()305 void Terminate() {} GetCapabilities()306 int GetCapabilities() { return 0; } 307 // If you need this to return an actual channel, use FakeMediaEngine instead. CreateChannel()308 VoiceMediaChannel* CreateChannel() { 309 return NULL; 310 } CreateSoundclip()311 SoundclipMedia* CreateSoundclip() { 312 return NULL; 313 } SetDelayOffset(int offset)314 bool SetDelayOffset(int offset) { return true; } GetOptions()315 AudioOptions GetOptions() const { return AudioOptions(); } SetOptions(const AudioOptions & options)316 bool SetOptions(const AudioOptions& options) { return true; } SetDevices(const Device * in_device,const Device * out_device)317 bool SetDevices(const Device* in_device, const Device* out_device) { 318 return true; 319 } GetOutputVolume(int * level)320 bool GetOutputVolume(int* level) { 321 *level = 0; 322 return true; 323 } SetOutputVolume(int level)324 bool SetOutputVolume(int level) { return true; } GetInputLevel()325 int GetInputLevel() { return 0; } SetLocalMonitor(bool enable)326 bool SetLocalMonitor(bool enable) { return true; } codecs()327 const std::vector<AudioCodec>& codecs() { return codecs_; } rtp_header_extensions()328 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 329 return rtp_header_extensions_; 330 } SetLogging(int min_sev,const char * filter)331 void SetLogging(int min_sev, const char* filter) {} StartAecDump(talk_base::PlatformFile file)332 bool StartAecDump(talk_base::PlatformFile file) { return false; } RegisterProcessor(uint32 ssrc,VoiceProcessor * voice_processor,MediaProcessorDirection direction)333 bool RegisterProcessor(uint32 ssrc, 334 VoiceProcessor* voice_processor, 335 MediaProcessorDirection direction) { return true; } UnregisterProcessor(uint32 ssrc,VoiceProcessor * voice_processor,MediaProcessorDirection direction)336 bool UnregisterProcessor(uint32 ssrc, 337 VoiceProcessor* voice_processor, 338 MediaProcessorDirection direction) { return true; } 339 340 private: 341 std::vector<AudioCodec> codecs_; 342 std::vector<RtpHeaderExtension> rtp_header_extensions_; 343 }; 344 345 // NullVideoEngine can be used with CompositeMediaEngine in the case where only 346 // a voice engine is desired. 347 class NullVideoEngine { 348 public: Init(talk_base::Thread * worker_thread)349 bool Init(talk_base::Thread* worker_thread) { return true; } Terminate()350 void Terminate() {} GetCapabilities()351 int GetCapabilities() { return 0; } 352 // If you need this to return an actual channel, use FakeMediaEngine instead. CreateChannel(VoiceMediaChannel * voice_media_channel)353 VideoMediaChannel* CreateChannel( 354 VoiceMediaChannel* voice_media_channel) { 355 return NULL; 356 } SetOptions(const VideoOptions & options)357 bool SetOptions(const VideoOptions& options) { return true; } GetDefaultEncoderConfig()358 VideoEncoderConfig GetDefaultEncoderConfig() const { 359 return VideoEncoderConfig(); 360 } SetDefaultEncoderConfig(const VideoEncoderConfig & config)361 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { 362 return true; 363 } SetLocalRenderer(VideoRenderer * renderer)364 bool SetLocalRenderer(VideoRenderer* renderer) { return true; } codecs()365 const std::vector<VideoCodec>& codecs() { return codecs_; } rtp_header_extensions()366 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 367 return rtp_header_extensions_; 368 } SetLogging(int min_sev,const char * filter)369 void SetLogging(int min_sev, const char* filter) {} GetStartCaptureFormat()370 VideoFormat GetStartCaptureFormat() const { return VideoFormat(); } 371 372 sigslot::signal2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 373 private: 374 std::vector<VideoCodec> codecs_; 375 std::vector<RtpHeaderExtension> rtp_header_extensions_; 376 }; 377 378 typedef CompositeMediaEngine<NullVoiceEngine, NullVideoEngine> NullMediaEngine; 379 380 enum DataChannelType { 381 DCT_NONE = 0, 382 DCT_RTP = 1, 383 DCT_SCTP = 2 384 }; 385 386 class DataEngineInterface { 387 public: ~DataEngineInterface()388 virtual ~DataEngineInterface() {} 389 virtual DataMediaChannel* CreateChannel(DataChannelType type) = 0; 390 virtual const std::vector<DataCodec>& data_codecs() = 0; 391 }; 392 393 } // namespace cricket 394 395 #endif // TALK_MEDIA_BASE_MEDIAENGINE_H_ 396