Home | History | Annotate | Download | only in webrtc
      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_WEBRTCVIDEOENGINE_H_
     29 #define TALK_MEDIA_WEBRTCVIDEOENGINE_H_
     30 
     31 #include <map>
     32 #include <vector>
     33 
     34 #include "talk/base/scoped_ptr.h"
     35 #include "talk/media/base/codec.h"
     36 #include "talk/media/base/videocommon.h"
     37 #include "talk/media/webrtc/webrtccommon.h"
     38 #include "talk/media/webrtc/webrtcexport.h"
     39 #include "talk/media/webrtc/webrtcvideoencoderfactory.h"
     40 #include "talk/session/media/channel.h"
     41 #include "webrtc/video_engine/include/vie_base.h"
     42 
     43 #if !defined(LIBPEERCONNECTION_LIB) && \
     44     !defined(LIBPEERCONNECTION_IMPLEMENTATION)
     45 #error "Bogus include."
     46 #endif
     47 
     48 namespace webrtc {
     49 class VideoCaptureModule;
     50 class VideoDecoder;
     51 class VideoEncoder;
     52 class VideoRender;
     53 class ViEExternalCapture;
     54 class ViERTP_RTCP;
     55 }
     56 
     57 namespace talk_base {
     58 class CpuMonitor;
     59 }  // namespace talk_base
     60 
     61 namespace cricket {
     62 
     63 class VideoCapturer;
     64 class VideoFrame;
     65 class VideoProcessor;
     66 class VideoRenderer;
     67 class ViETraceWrapper;
     68 class ViEWrapper;
     69 class VoiceMediaChannel;
     70 class WebRtcDecoderObserver;
     71 class WebRtcEncoderObserver;
     72 class WebRtcLocalStreamInfo;
     73 class WebRtcRenderAdapter;
     74 class WebRtcVideoChannelRecvInfo;
     75 class WebRtcVideoChannelSendInfo;
     76 class WebRtcVideoDecoderFactory;
     77 class WebRtcVideoEncoderFactory;
     78 class WebRtcVideoMediaChannel;
     79 class WebRtcVoiceEngine;
     80 
     81 struct CapturedFrame;
     82 struct Device;
     83 
     84 class WebRtcVideoEngine : public sigslot::has_slots<>,
     85                           public webrtc::TraceCallback,
     86                           public WebRtcVideoEncoderFactory::Observer {
     87  public:
     88   // Creates the WebRtcVideoEngine with internal VideoCaptureModule.
     89   WebRtcVideoEngine();
     90   // For testing purposes. Allows the WebRtcVoiceEngine,
     91   // ViEWrapper and CpuMonitor to be mocks.
     92   // TODO(juberti): Remove the 3-arg ctor once fake tracing is implemented.
     93   WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
     94                     ViEWrapper* vie_wrapper,
     95                     talk_base::CpuMonitor* cpu_monitor);
     96   WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
     97                     ViEWrapper* vie_wrapper,
     98                     ViETraceWrapper* tracing,
     99                     talk_base::CpuMonitor* cpu_monitor);
    100   ~WebRtcVideoEngine();
    101 
    102   // Basic video engine implementation.
    103   bool Init(talk_base::Thread* worker_thread);
    104   void Terminate();
    105 
    106   int GetCapabilities();
    107   bool SetOptions(const VideoOptions &options);
    108   bool SetDefaultEncoderConfig(const VideoEncoderConfig& config);
    109   VideoEncoderConfig GetDefaultEncoderConfig() const;
    110 
    111   WebRtcVideoMediaChannel* CreateChannel(VoiceMediaChannel* voice_channel);
    112 
    113   const std::vector<VideoCodec>& codecs() const;
    114   const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
    115   void SetLogging(int min_sev, const char* filter);
    116 
    117   bool SetLocalRenderer(VideoRenderer* renderer);
    118   sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange;
    119 
    120   // Set the VoiceEngine for A/V sync. This can only be called before Init.
    121   bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine);
    122   // Set a WebRtcVideoDecoderFactory for external decoding. Video engine does
    123   // not take the ownership of |decoder_factory|. The caller needs to make sure
    124   // that |decoder_factory| outlives the video engine.
    125   void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory);
    126   // Set a WebRtcVideoEncoderFactory for external encoding. Video engine does
    127   // not take the ownership of |encoder_factory|. The caller needs to make sure
    128   // that |encoder_factory| outlives the video engine.
    129   void SetExternalEncoderFactory(WebRtcVideoEncoderFactory* encoder_factory);
    130   // Enable the render module with timing control.
    131   bool EnableTimedRender();
    132 
    133   // Returns an external decoder for the given codec type. The return value
    134   // can be NULL if decoder factory is not given or it does not support the
    135   // codec type. The caller takes the ownership of the returned object.
    136   webrtc::VideoDecoder* CreateExternalDecoder(webrtc::VideoCodecType type);
    137   // Releases the decoder instance created by CreateExternalDecoder().
    138   void DestroyExternalDecoder(webrtc::VideoDecoder* decoder);
    139 
    140   // Returns an external encoder for the given codec type. The return value
    141   // can be NULL if encoder factory is not given or it does not support the
    142   // codec type. The caller takes the ownership of the returned object.
    143   webrtc::VideoEncoder* CreateExternalEncoder(webrtc::VideoCodecType type);
    144   // Releases the encoder instance created by CreateExternalEncoder().
    145   void DestroyExternalEncoder(webrtc::VideoEncoder* encoder);
    146 
    147   // Returns true if the codec type is supported by the external encoder.
    148   bool IsExternalEncoderCodecType(webrtc::VideoCodecType type) const;
    149 
    150   // Functions called by WebRtcVideoMediaChannel.
    151   talk_base::Thread* worker_thread() { return worker_thread_; }
    152   ViEWrapper* vie() { return vie_wrapper_.get(); }
    153   const VideoFormat& default_codec_format() const {
    154     return default_codec_format_;
    155   }
    156   int GetLastEngineError();
    157   bool FindCodec(const VideoCodec& in);
    158   bool CanSendCodec(const VideoCodec& in, const VideoCodec& current,
    159                     VideoCodec* out);
    160   void RegisterChannel(WebRtcVideoMediaChannel* channel);
    161   void UnregisterChannel(WebRtcVideoMediaChannel* channel);
    162   bool ConvertFromCricketVideoCodec(const VideoCodec& in_codec,
    163                                     webrtc::VideoCodec* out_codec);
    164   // Check whether the supplied trace should be ignored.
    165   bool ShouldIgnoreTrace(const std::string& trace);
    166   int GetNumOfChannels();
    167 
    168   VideoFormat GetStartCaptureFormat() const { return default_codec_format_; }
    169 
    170   talk_base::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); }
    171 
    172  protected:
    173   // When a video processor registers with the engine.
    174   // SignalMediaFrame will be invoked for every video frame.
    175   // See videoprocessor.h for param reference.
    176   sigslot::signal3<uint32, VideoFrame*, bool*> SignalMediaFrame;
    177 
    178  private:
    179   typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
    180   struct VideoCodecPref {
    181     const char* name;
    182     int payload_type;
    183     // For RTX, this field is the payload-type that RTX applies to.
    184     // For other codecs, it should be set to -1.
    185     int associated_payload_type;
    186     int pref;
    187   };
    188 
    189   static const VideoCodecPref kVideoCodecPrefs[];
    190   static const VideoFormatPod kVideoFormats[];
    191   static const VideoFormatPod kDefaultVideoFormat;
    192 
    193   void Construct(ViEWrapper* vie_wrapper,
    194                  ViETraceWrapper* tracing,
    195                  WebRtcVoiceEngine* voice_engine,
    196                  talk_base::CpuMonitor* cpu_monitor);
    197   bool SetDefaultCodec(const VideoCodec& codec);
    198   bool RebuildCodecList(const VideoCodec& max_codec);
    199   void SetTraceFilter(int filter);
    200   void SetTraceOptions(const std::string& options);
    201   bool InitVideoEngine();
    202 
    203   // webrtc::TraceCallback implementation.
    204   virtual void Print(webrtc::TraceLevel level, const char* trace, int length);
    205 
    206   // WebRtcVideoEncoderFactory::Observer implementation.
    207   virtual void OnCodecsAvailable();
    208 
    209   talk_base::Thread* worker_thread_;
    210   talk_base::scoped_ptr<ViEWrapper> vie_wrapper_;
    211   bool vie_wrapper_base_initialized_;
    212   talk_base::scoped_ptr<ViETraceWrapper> tracing_;
    213   WebRtcVoiceEngine* voice_engine_;
    214   talk_base::scoped_ptr<webrtc::VideoRender> render_module_;
    215   WebRtcVideoEncoderFactory* encoder_factory_;
    216   WebRtcVideoDecoderFactory* decoder_factory_;
    217   std::vector<VideoCodec> video_codecs_;
    218   std::vector<RtpHeaderExtension> rtp_header_extensions_;
    219   VideoFormat default_codec_format_;
    220 
    221   bool initialized_;
    222   talk_base::CriticalSection channels_crit_;
    223   VideoChannels channels_;
    224 
    225   bool capture_started_;
    226   int local_renderer_w_;
    227   int local_renderer_h_;
    228   VideoRenderer* local_renderer_;
    229 
    230   // Critical section to protect the media processor register/unregister
    231   // while processing a frame
    232   talk_base::CriticalSection signal_media_critical_;
    233 
    234   talk_base::scoped_ptr<talk_base::CpuMonitor> cpu_monitor_;
    235 };
    236 
    237 class WebRtcVideoMediaChannel : public talk_base::MessageHandler,
    238                                 public VideoMediaChannel,
    239                                 public webrtc::Transport {
    240  public:
    241   WebRtcVideoMediaChannel(WebRtcVideoEngine* engine,
    242                           VoiceMediaChannel* voice_channel);
    243   ~WebRtcVideoMediaChannel();
    244   bool Init();
    245 
    246   WebRtcVideoEngine* engine() { return engine_; }
    247   VoiceMediaChannel* voice_channel() { return voice_channel_; }
    248   int video_channel() const { return vie_channel_; }
    249   bool sending() const { return sending_; }
    250 
    251   // VideoMediaChannel implementation
    252   virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs);
    253   virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs);
    254   virtual bool GetSendCodec(VideoCodec* send_codec);
    255   virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format);
    256   virtual bool SetRender(bool render);
    257   virtual bool SetSend(bool send);
    258 
    259   virtual bool AddSendStream(const StreamParams& sp);
    260   virtual bool RemoveSendStream(uint32 ssrc);
    261   virtual bool AddRecvStream(const StreamParams& sp);
    262   virtual bool RemoveRecvStream(uint32 ssrc);
    263   virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
    264   virtual bool GetStats(VideoMediaInfo* info);
    265   virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer);
    266   virtual bool SendIntraFrame();
    267   virtual bool RequestIntraFrame();
    268 
    269   virtual void OnPacketReceived(talk_base::Buffer* packet,
    270                                 const talk_base::PacketTime& packet_time);
    271   virtual void OnRtcpReceived(talk_base::Buffer* packet,
    272                               const talk_base::PacketTime& packet_time);
    273   virtual void OnReadyToSend(bool ready);
    274   virtual bool MuteStream(uint32 ssrc, bool on);
    275   virtual bool SetRecvRtpHeaderExtensions(
    276       const std::vector<RtpHeaderExtension>& extensions);
    277   virtual bool SetSendRtpHeaderExtensions(
    278       const std::vector<RtpHeaderExtension>& extensions);
    279   virtual bool SetSendBandwidth(bool autobw, int bps);
    280   virtual bool SetOptions(const VideoOptions &options);
    281   virtual bool GetOptions(VideoOptions *options) const {
    282     *options = options_;
    283     return true;
    284   }
    285   virtual void SetInterface(NetworkInterface* iface);
    286   virtual void UpdateAspectRatio(int ratio_w, int ratio_h);
    287 
    288   // Public functions for use by tests and other specialized code.
    289   uint32 send_ssrc() const { return 0; }
    290   bool GetRenderer(uint32 ssrc, VideoRenderer** renderer);
    291   void SendFrame(VideoCapturer* capturer, const VideoFrame* frame);
    292   bool SendFrame(WebRtcVideoChannelSendInfo* channel_info,
    293                  const VideoFrame* frame, bool is_screencast);
    294 
    295   // Thunk functions for use with HybridVideoEngine
    296   void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) {
    297     SendFrame(0u, frame, capturer->IsScreencast());
    298   }
    299   void OnLocalFrameFormat(VideoCapturer* capturer, const VideoFormat* format) {
    300   }
    301 
    302   virtual void OnMessage(talk_base::Message* msg);
    303 
    304  protected:
    305   int GetLastEngineError() { return engine()->GetLastEngineError(); }
    306   virtual int SendPacket(int channel, const void* data, int len);
    307   virtual int SendRTCPPacket(int channel, const void* data, int len);
    308 
    309  private:
    310   typedef std::map<uint32, WebRtcVideoChannelRecvInfo*> RecvChannelMap;
    311   typedef std::map<uint32, WebRtcVideoChannelSendInfo*> SendChannelMap;
    312   typedef int (webrtc::ViERTP_RTCP::* ExtensionSetterFunction)(int, bool, int);
    313 
    314   enum MediaDirection { MD_RECV, MD_SEND, MD_SENDRECV };
    315 
    316   // Creates and initializes a ViE channel. When successful |channel_id| will
    317   // contain the new channel's ID. If |receiving| is true |ssrc| is the
    318   // remote ssrc. If |sending| is true the ssrc is local ssrc. If both
    319   // |receiving| and |sending| is true the ssrc must be 0 and the channel will
    320   // be created as a default channel. The ssrc must be different for receive
    321   // channels and it must be different for send channels. If the same SSRC is
    322   // being used for creating channel more than once, this function will fail
    323   // returning false.
    324   bool CreateChannel(uint32 ssrc_key, MediaDirection direction,
    325                      int* channel_id);
    326   bool ConfigureChannel(int channel_id, MediaDirection direction,
    327                         uint32 ssrc_key);
    328   bool ConfigureReceiving(int channel_id, uint32 remote_ssrc_key);
    329   bool ConfigureSending(int channel_id, uint32 local_ssrc_key);
    330   bool SetNackFec(int channel_id, int red_payload_type, int fec_payload_type,
    331                   bool nack_enabled);
    332   bool SetSendCodec(const webrtc::VideoCodec& codec, int min_bitrate,
    333                     int start_bitrate, int max_bitrate);
    334   bool SetSendCodec(WebRtcVideoChannelSendInfo* send_channel,
    335                     const webrtc::VideoCodec& codec, int min_bitrate,
    336                     int start_bitrate, int max_bitrate);
    337   void LogSendCodecChange(const std::string& reason);
    338   // Prepares the channel with channel id |info->channel_id()| to receive all
    339   // codecs in |receive_codecs_| and start receive packets.
    340   bool SetReceiveCodecs(WebRtcVideoChannelRecvInfo* info);
    341   // Returns the channel number that receives the stream with SSRC |ssrc|.
    342   int GetRecvChannelNum(uint32 ssrc);
    343   // Given captured video frame size, checks if we need to reset vie send codec.
    344   // |reset| is set to whether resetting has happened on vie or not.
    345   // Returns false on error.
    346   bool MaybeResetVieSendCodec(WebRtcVideoChannelSendInfo* send_channel,
    347                               int new_width, int new_height, bool is_screencast,
    348                               bool* reset);
    349   // Checks the current bitrate estimate and modifies the start bitrate
    350   // accordingly.
    351   void MaybeChangeStartBitrate(int channel_id, webrtc::VideoCodec* video_codec);
    352   // Helper function for starting the sending of media on all channels or
    353   // |channel_id|. Note that these two function do not change |sending_|.
    354   bool StartSend();
    355   bool StartSend(WebRtcVideoChannelSendInfo* send_channel);
    356   // Helper function for stop the sending of media on all channels or
    357   // |channel_id|. Note that these two function do not change |sending_|.
    358   bool StopSend();
    359   bool StopSend(WebRtcVideoChannelSendInfo* send_channel);
    360   bool SendIntraFrame(int channel_id);
    361 
    362   bool HasReadySendChannels();
    363 
    364   // Send channel key returns the key corresponding to the provided local SSRC
    365   // in |key|. The return value is true upon success.
    366   // If the local ssrc correspond to that of the default channel the key is 0.
    367   // For all other channels the returned key will be the same as the local ssrc.
    368   bool GetSendChannelKey(uint32 local_ssrc, uint32* key);
    369   WebRtcVideoChannelSendInfo* GetSendChannel(uint32 local_ssrc);
    370   // Creates a new unique key that can be used for inserting a new send channel
    371   // into |send_channels_|
    372   bool CreateSendChannelKey(uint32 local_ssrc, uint32* key);
    373   // Get the number of the send channels |capturer| registered with.
    374   int GetSendChannelNum(VideoCapturer* capturer);
    375 
    376   bool IsDefaultChannel(int channel_id) const {
    377     return channel_id == vie_channel_;
    378   }
    379   uint32 GetDefaultChannelSsrc();
    380 
    381   bool DeleteSendChannel(uint32 ssrc_key);
    382 
    383   bool InConferenceMode() const {
    384     return options_.conference_mode.GetWithDefaultIfUnset(false);
    385   }
    386   bool RemoveCapturer(uint32 ssrc);
    387 
    388 
    389   talk_base::MessageQueue* worker_thread() { return engine_->worker_thread(); }
    390   void QueueBlackFrame(uint32 ssrc, int64 timestamp, int framerate);
    391   void FlushBlackFrame(uint32 ssrc, int64 timestamp);
    392 
    393   void SetNetworkTransmissionState(bool is_transmitting);
    394 
    395   bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id,
    396                           const RtpHeaderExtension* extension);
    397   bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id,
    398                           const std::vector<RtpHeaderExtension>& extensions,
    399                           const char header_extension_uri[]);
    400 
    401   // Signal when cpu adaptation has no further scope to adapt.
    402   void OnCpuAdaptationUnable();
    403 
    404   // Set the local (send-side) RTX SSRC corresponding to primary_ssrc.
    405   bool SetLocalRtxSsrc(int channel_id, const StreamParams& send_params,
    406                        uint32 primary_ssrc, int stream_idx);
    407 
    408   // Connect |capturer| to WebRtcVideoMediaChannel if it is only registered
    409   // to one send channel, i.e. the first send channel.
    410   void MaybeConnectCapturer(VideoCapturer* capturer);
    411   // Disconnect |capturer| from WebRtcVideoMediaChannel if it is only registered
    412   // to one send channel, i.e. the last send channel.
    413   void MaybeDisconnectCapturer(VideoCapturer* capturer);
    414 
    415   // Global state.
    416   WebRtcVideoEngine* engine_;
    417   VoiceMediaChannel* voice_channel_;
    418   int vie_channel_;
    419   bool nack_enabled_;
    420   // Receiver Estimated Max Bitrate
    421   bool remb_enabled_;
    422   VideoOptions options_;
    423 
    424   // Global recv side state.
    425   // Note the default channel (vie_channel_), i.e. the send channel
    426   // corresponding to all the receive channels (this must be done for REMB to
    427   // work properly), resides in both recv_channels_ and send_channels_ with the
    428   // ssrc key 0.
    429   RecvChannelMap recv_channels_;  // Contains all receive channels.
    430   std::vector<webrtc::VideoCodec> receive_codecs_;
    431   bool render_started_;
    432   uint32 first_receive_ssrc_;
    433   std::vector<RtpHeaderExtension> receive_extensions_;
    434 
    435   // Global send side state.
    436   SendChannelMap send_channels_;
    437   talk_base::scoped_ptr<webrtc::VideoCodec> send_codec_;
    438   int send_rtx_type_;
    439   int send_red_type_;
    440   int send_fec_type_;
    441   int send_min_bitrate_;
    442   int send_start_bitrate_;
    443   int send_max_bitrate_;
    444   bool sending_;
    445   std::vector<RtpHeaderExtension> send_extensions_;
    446 
    447   // The aspect ratio that the channel desires. 0 means there is no desired
    448   // aspect ratio
    449   int ratio_w_;
    450   int ratio_h_;
    451 };
    452 
    453 }  // namespace cricket
    454 
    455 #endif  // TALK_MEDIA_WEBRTCVIDEOENGINE_H_
    456