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