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 <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 
     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:
    178   CompositeMediaEngine() {}
    179   virtual ~CompositeMediaEngine() {}
    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   }
    190   virtual void Terminate() {
    191     video_.Terminate();
    192     voice_.Terminate();
    193   }
    194 
    195   virtual int GetCapabilities() {
    196     return (voice_.GetCapabilities() | video_.GetCapabilities());
    197   }
    198   virtual VoiceMediaChannel *CreateChannel() {
    199     return voice_.CreateChannel();
    200   }
    201   virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) {
    202     return video_.CreateChannel(channel);
    203   }
    204   virtual SoundclipMedia *CreateSoundclip() {
    205     return voice_.CreateSoundclip();
    206   }
    207 
    208   virtual AudioOptions GetAudioOptions() const {
    209     return voice_.GetOptions();
    210   }
    211   virtual bool SetAudioOptions(const AudioOptions& options) {
    212     return voice_.SetOptions(options);
    213   }
    214   virtual bool SetAudioDelayOffset(int offset) {
    215     return voice_.SetDelayOffset(offset);
    216   }
    217   virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
    218     return video_.SetDefaultEncoderConfig(config);
    219   }
    220   virtual VideoEncoderConfig GetDefaultVideoEncoderConfig() const {
    221     return video_.GetDefaultEncoderConfig();
    222   }
    223 
    224   virtual bool SetSoundDevices(const Device* in_device,
    225                                const Device* out_device) {
    226     return voice_.SetDevices(in_device, out_device);
    227   }
    228 
    229   virtual bool GetOutputVolume(int* level) {
    230     return voice_.GetOutputVolume(level);
    231   }
    232   virtual bool SetOutputVolume(int level) {
    233     return voice_.SetOutputVolume(level);
    234   }
    235 
    236   virtual int GetInputLevel() {
    237     return voice_.GetInputLevel();
    238   }
    239   virtual bool SetLocalMonitor(bool enable) {
    240     return voice_.SetLocalMonitor(enable);
    241   }
    242   virtual const std::vector<AudioCodec>& audio_codecs() {
    243     return voice_.codecs();
    244   }
    245   virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() {
    246     return voice_.rtp_header_extensions();
    247   }
    248   virtual const std::vector<VideoCodec>& video_codecs() {
    249     return video_.codecs();
    250   }
    251   virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() {
    252     return video_.rtp_header_extensions();
    253   }
    254 
    255   virtual void SetVoiceLogging(int min_sev, const char* filter) {
    256     voice_.SetLogging(min_sev, filter);
    257   }
    258   virtual void SetVideoLogging(int min_sev, const char* filter) {
    259     video_.SetLogging(min_sev, filter);
    260   }
    261 
    262   virtual bool StartAecDump(rtc::PlatformFile file) {
    263     return voice_.StartAecDump(file);
    264   }
    265 
    266   virtual bool RegisterVoiceProcessor(uint32 ssrc,
    267                                       VoiceProcessor* processor,
    268                                       MediaProcessorDirection direction) {
    269     return voice_.RegisterProcessor(ssrc, processor, direction);
    270   }
    271   virtual bool UnregisterVoiceProcessor(uint32 ssrc,
    272                                         VoiceProcessor* processor,
    273                                         MediaProcessorDirection direction) {
    274     return voice_.UnregisterProcessor(ssrc, processor, direction);
    275   }
    276   virtual VideoFormat GetStartCaptureFormat() const {
    277     return video_.GetStartCaptureFormat();
    278   }
    279   virtual sigslot::repeater2<VideoCapturer*, CaptureState>&
    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:
    294   bool Init(rtc::Thread* worker_thread) { return true; }
    295   void Terminate() {}
    296   int GetCapabilities() { return 0; }
    297   // If you need this to return an actual channel, use FakeMediaEngine instead.
    298   VoiceMediaChannel* CreateChannel() {
    299     return NULL;
    300   }
    301   SoundclipMedia* CreateSoundclip() {
    302     return NULL;
    303   }
    304   bool SetDelayOffset(int offset) { return true; }
    305   AudioOptions GetOptions() const { return AudioOptions(); }
    306   bool SetOptions(const AudioOptions& options) { return true; }
    307   bool SetDevices(const Device* in_device, const Device* out_device) {
    308     return true;
    309   }
    310   bool GetOutputVolume(int* level) {
    311     *level = 0;
    312     return true;
    313   }
    314   bool SetOutputVolume(int level) { return true; }
    315   int GetInputLevel() { return 0; }
    316   bool SetLocalMonitor(bool enable) { return true; }
    317   const std::vector<AudioCodec>& codecs() { return codecs_; }
    318   const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
    319     return rtp_header_extensions_;
    320   }
    321   void SetLogging(int min_sev, const char* filter) {}
    322   bool StartAecDump(rtc::PlatformFile file) { return false; }
    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(rtc::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(const VideoOptions& options) { return true; }
    348   VideoEncoderConfig GetDefaultEncoderConfig() const {
    349     return VideoEncoderConfig();
    350   }
    351   bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) {
    352     return true;
    353   }
    354   const std::vector<VideoCodec>& codecs() { return codecs_; }
    355   const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
    356     return rtp_header_extensions_;
    357   }
    358   void SetLogging(int min_sev, const char* filter) {}
    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:
    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