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 <climits> 36 #include <string> 37 #include <vector> 38 39 #include "talk/base/sigslotrepeater.h" 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 49 #if defined(GOOGLE_CHROME_BUILD) || defined(CHROMIUM_BUILD) 50 #define DISABLE_MEDIA_ENGINE_FACTORY 51 #endif 52 53 namespace cricket { 54 55 class VideoCapturer; 56 57 // MediaEngineInterface is an abstraction of a media engine which can be 58 // subclassed to support different media componentry backends. 59 // It supports voice and video operations in the same class to facilitate 60 // proper synchronization between both media types. 61 class MediaEngineInterface { 62 public: 63 // Bitmask flags for options that may be supported by the media engine 64 // implementation. This can be converted to and from an 65 // AudioOptions struct for backwards compatibility with calls that 66 // use flags until we transition to using structs everywhere. 67 enum AudioFlags { 68 // Audio processing that attempts to filter away the output signal from 69 // later inbound pickup. 70 ECHO_CANCELLATION = 1 << 0, 71 // Audio processing to adjust the sensitivity of the local mic dynamically. 72 AUTO_GAIN_CONTROL = 1 << 1, 73 // Audio processing to filter out background noise. 74 NOISE_SUPPRESSION = 1 << 2, 75 // Audio processing to remove background noise of lower frequencies. 76 HIGHPASS_FILTER = 1 << 3, 77 // A switch to swap which captured signal is left and right in stereo mode. 78 STEREO_FLIPPING = 1 << 4, 79 // Controls delegation echo cancellation to use the OS' facility. 80 SYSTEM_AEC_MODE = 1 << 5, 81 82 ALL_AUDIO_OPTIONS = (1 << 6) - 1, 83 DEFAULT_AUDIO_OPTIONS = ECHO_CANCELLATION | AUTO_GAIN_CONTROL | 84 NOISE_SUPPRESSION | HIGHPASS_FILTER, 85 }; 86 87 // Default value to be used for SetAudioDelayOffset(). 88 static const int kDefaultAudioDelayOffset; 89 90 virtual ~MediaEngineInterface() {} 91 92 // Initialization 93 // Starts the engine. 94 virtual bool Init(talk_base::Thread* worker_thread) = 0; 95 // Shuts down the engine. 96 virtual void Terminate() = 0; 97 // Returns what the engine is capable of, as a set of Capabilities, above. 98 virtual int GetCapabilities() = 0; 99 100 // MediaChannel creation 101 // Creates a voice media channel. Returns NULL on failure. 102 virtual VoiceMediaChannel *CreateChannel() = 0; 103 // Creates a video media channel, paired with the specified voice channel. 104 // Returns NULL on failure. 105 virtual VideoMediaChannel *CreateVideoChannel( 106 VoiceMediaChannel* voice_media_channel) = 0; 107 108 // Creates a soundclip object for playing sounds on. Returns NULL on failure. 109 virtual SoundclipMedia *CreateSoundclip() = 0; 110 111 // Configuration 112 // Sets global audio options. "options" are from AudioOptions, above. 113 virtual bool SetAudioOptions(int options) = 0; 114 // Sets global video options. "options" are from VideoOptions, above. 115 virtual bool SetVideoOptions(int options) = 0; 116 // Sets the value used by the echo canceller to offset delay values obtained 117 // from the OS. 118 virtual bool SetAudioDelayOffset(int offset) = 0; 119 // Sets the default (maximum) codec/resolution and encoder option to capture 120 // and encode video. 121 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) 122 = 0; 123 124 // Device selection 125 // TODO(tschmelcher): Add method for selecting the soundclip device. 126 virtual bool SetSoundDevices(const Device* in_device, 127 const Device* out_device) = 0; 128 129 // Device configuration 130 // Gets the current speaker volume, as a value between 0 and 255. 131 virtual bool GetOutputVolume(int* level) = 0; 132 // Sets the current speaker volume, as a value between 0 and 255. 133 virtual bool SetOutputVolume(int level) = 0; 134 135 // Local monitoring 136 // Gets the current microphone level, as a value between 0 and 10. 137 virtual int GetInputLevel() = 0; 138 // Starts or stops the local microphone. Useful if local mic info is needed 139 // prior to a call being connected; the mic will be started automatically 140 // when a VoiceMediaChannel starts sending. 141 virtual bool SetLocalMonitor(bool enable) = 0; 142 // Installs a callback for raw frames from the local camera. 143 virtual bool SetLocalRenderer(VideoRenderer* renderer) = 0; 144 145 virtual const std::vector<AudioCodec>& audio_codecs() = 0; 146 virtual const std::vector<RtpHeaderExtension>& 147 audio_rtp_header_extensions() = 0; 148 virtual const std::vector<VideoCodec>& video_codecs() = 0; 149 virtual const std::vector<RtpHeaderExtension>& 150 video_rtp_header_extensions() = 0; 151 152 // Logging control 153 virtual void SetVoiceLogging(int min_sev, const char* filter) = 0; 154 virtual void SetVideoLogging(int min_sev, const char* filter) = 0; 155 156 // Voice processors for effects. 157 virtual bool RegisterVoiceProcessor(uint32 ssrc, 158 VoiceProcessor* video_processor, 159 MediaProcessorDirection direction) = 0; 160 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 161 VoiceProcessor* video_processor, 162 MediaProcessorDirection direction) = 0; 163 164 virtual VideoFormat GetStartCaptureFormat() const = 0; 165 166 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& 167 SignalVideoCaptureStateChange() = 0; 168 }; 169 170 171 #if !defined(DISABLE_MEDIA_ENGINE_FACTORY) 172 class MediaEngineFactory { 173 public: 174 static MediaEngineInterface* Create(); 175 }; 176 #endif 177 178 // CompositeMediaEngine constructs a MediaEngine from separate 179 // voice and video engine classes. 180 template<class VOICE, class VIDEO> 181 class CompositeMediaEngine : public MediaEngineInterface { 182 public: 183 CompositeMediaEngine() {} 184 virtual ~CompositeMediaEngine() {} 185 virtual bool Init(talk_base::Thread* worker_thread) { 186 if (!voice_.Init(worker_thread)) 187 return false; 188 if (!video_.Init(worker_thread)) { 189 voice_.Terminate(); 190 return false; 191 } 192 SignalVideoCaptureStateChange().repeat(video_.SignalCaptureStateChange); 193 return true; 194 } 195 virtual void Terminate() { 196 video_.Terminate(); 197 voice_.Terminate(); 198 } 199 200 virtual int GetCapabilities() { 201 return (voice_.GetCapabilities() | video_.GetCapabilities()); 202 } 203 virtual VoiceMediaChannel *CreateChannel() { 204 return voice_.CreateChannel(); 205 } 206 virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) { 207 return video_.CreateChannel(channel); 208 } 209 virtual SoundclipMedia *CreateSoundclip() { 210 return voice_.CreateSoundclip(); 211 } 212 213 virtual bool SetAudioOptions(int o) { 214 return voice_.SetOptions(o); 215 } 216 virtual bool SetVideoOptions(int o) { 217 return video_.SetOptions(o); 218 } 219 virtual bool SetAudioDelayOffset(int offset) { 220 return voice_.SetDelayOffset(offset); 221 } 222 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) { 223 return video_.SetDefaultEncoderConfig(config); 224 } 225 226 virtual bool SetSoundDevices(const Device* in_device, 227 const Device* out_device) { 228 return voice_.SetDevices(in_device, out_device); 229 } 230 231 virtual bool GetOutputVolume(int* level) { 232 return voice_.GetOutputVolume(level); 233 } 234 virtual bool SetOutputVolume(int level) { 235 return voice_.SetOutputVolume(level); 236 } 237 238 virtual int GetInputLevel() { 239 return voice_.GetInputLevel(); 240 } 241 virtual bool SetLocalMonitor(bool enable) { 242 return voice_.SetLocalMonitor(enable); 243 } 244 virtual bool SetLocalRenderer(VideoRenderer* renderer) { 245 return video_.SetLocalRenderer(renderer); 246 } 247 248 virtual const std::vector<AudioCodec>& audio_codecs() { 249 return voice_.codecs(); 250 } 251 virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() { 252 return voice_.rtp_header_extensions(); 253 } 254 virtual const std::vector<VideoCodec>& video_codecs() { 255 return video_.codecs(); 256 } 257 virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() { 258 return video_.rtp_header_extensions(); 259 } 260 261 virtual void SetVoiceLogging(int min_sev, const char* filter) { 262 return voice_.SetLogging(min_sev, filter); 263 } 264 virtual void SetVideoLogging(int min_sev, const char* filter) { 265 return video_.SetLogging(min_sev, filter); 266 } 267 268 virtual bool RegisterVoiceProcessor(uint32 ssrc, 269 VoiceProcessor* processor, 270 MediaProcessorDirection direction) { 271 return voice_.RegisterProcessor(ssrc, processor, direction); 272 } 273 virtual bool UnregisterVoiceProcessor(uint32 ssrc, 274 VoiceProcessor* processor, 275 MediaProcessorDirection direction) { 276 return voice_.UnregisterProcessor(ssrc, processor, direction); 277 } 278 virtual VideoFormat GetStartCaptureFormat() const { 279 return video_.GetStartCaptureFormat(); 280 } 281 virtual sigslot::repeater2<VideoCapturer*, CaptureState>& 282 SignalVideoCaptureStateChange() { 283 return signal_state_change_; 284 } 285 286 protected: 287 VOICE voice_; 288 VIDEO video_; 289 sigslot::repeater2<VideoCapturer*, CaptureState> signal_state_change_; 290 }; 291 292 // NullVoiceEngine can be used with CompositeMediaEngine in the case where only 293 // a video engine is desired. 294 class NullVoiceEngine { 295 public: 296 bool Init(talk_base::Thread* worker_thread) { return true; } 297 void Terminate() {} 298 int GetCapabilities() { return 0; } 299 // If you need this to return an actual channel, use FakeMediaEngine instead. 300 VoiceMediaChannel* CreateChannel() { 301 return NULL; 302 } 303 SoundclipMedia* CreateSoundclip() { 304 return NULL; 305 } 306 bool SetDelayOffset(int offset) { return true; } 307 bool SetOptions(int opts) { return true; } 308 bool SetDevices(const Device* in_device, const Device* out_device) { 309 return true; 310 } 311 bool GetOutputVolume(int* level) { 312 *level = 0; 313 return true; 314 } 315 bool SetOutputVolume(int level) { return true; } 316 int GetInputLevel() { return 0; } 317 bool SetLocalMonitor(bool enable) { return true; } 318 const std::vector<AudioCodec>& codecs() { return codecs_; } 319 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 320 return rtp_header_extensions_; 321 } 322 void SetLogging(int min_sev, const char* filter) {} 323 bool RegisterProcessor(uint32 ssrc, 324 VoiceProcessor* voice_processor, 325 MediaProcessorDirection direction) { return true; } 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: 339 bool Init(talk_base::Thread* worker_thread) { return true; } 340 void Terminate() {} 341 int GetCapabilities() { return 0; } 342 // If you need this to return an actual channel, use FakeMediaEngine instead. 343 VideoMediaChannel* CreateChannel( 344 VoiceMediaChannel* voice_media_channel) { 345 return NULL; 346 } 347 bool SetOptions(int opts) { return true; } 348 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { 349 return true; 350 } 351 bool SetLocalRenderer(VideoRenderer* renderer) { return true; } 352 const std::vector<VideoCodec>& codecs() { return codecs_; } 353 const std::vector<RtpHeaderExtension>& rtp_header_extensions() { 354 return rtp_header_extensions_; 355 } 356 void SetLogging(int min_sev, const char* filter) {} 357 VideoFormat GetStartCaptureFormat() const { return VideoFormat(); } 358 359 sigslot::signal2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 360 private: 361 std::vector<VideoCodec> codecs_; 362 std::vector<RtpHeaderExtension> rtp_header_extensions_; 363 }; 364 365 typedef CompositeMediaEngine<NullVoiceEngine, NullVideoEngine> NullMediaEngine; 366 367 enum DataChannelType { 368 DCT_NONE = 0, 369 DCT_RTP = 1, 370 DCT_SCTP = 2 371 }; 372 373 class DataEngineInterface { 374 public: 375 virtual ~DataEngineInterface() {} 376 virtual DataMediaChannel* CreateChannel(DataChannelType type) = 0; 377 virtual const std::vector<DataCodec>& data_codecs() = 0; 378 }; 379 380 } // namespace cricket 381 382 #endif // TALK_MEDIA_BASE_MEDIAENGINE_H_ 383