Home | History | Annotate | Download | only in base
      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