Skeleton for registering external encoders/decoders.

R=pthatcher@webrtc.org
BUG=1788

Review URL: https://webrtc-codereview.appspot.com/31429005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7270 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcmediaengine.cc b/talk/media/webrtc/webrtcmediaengine.cc
index 67bea0c..cf0fcdf 100644
--- a/talk/media/webrtc/webrtcmediaengine.cc
+++ b/talk/media/webrtc/webrtcmediaengine.cc
@@ -64,6 +64,8 @@
                      WebRtcVideoEncoderFactory* encoder_factory,
                      WebRtcVideoDecoderFactory* decoder_factory) {
     voice_.SetAudioDeviceModule(adm, adm_sc);
+    video_.SetExternalDecoderFactory(decoder_factory);
+    video_.SetExternalEncoderFactory(encoder_factory);
     video_.SetVoiceEngine(&voice_);
   }
 };
@@ -83,7 +85,6 @@
         adm, adm_sc, encoder_factory, decoder_factory);
   }
 #endif // WEBRTC_CHROMIUM_BUILD
-  // This is just to get a diff to run pulse.
   return new cricket::WebRtcMediaEngine(
       adm, adm_sc, encoder_factory, decoder_factory);
 }
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index f7bd8e2..31f6070 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -284,7 +284,9 @@
                             FOURCC_ANY),
       initialized_(false),
       cpu_monitor_(new rtc::CpuMonitor(NULL)),
-      channel_factory_(NULL) {
+      channel_factory_(NULL),
+      external_decoder_factory_(NULL),
+      external_encoder_factory_(NULL) {
   LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()";
   rtp_header_extensions_.push_back(
       RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension,
@@ -393,6 +395,30 @@
   }
 }
 
+void WebRtcVideoEngine2::SetExternalDecoderFactory(
+    WebRtcVideoDecoderFactory* decoder_factory) {
+  external_decoder_factory_ = decoder_factory;
+}
+
+void WebRtcVideoEngine2::SetExternalEncoderFactory(
+    WebRtcVideoEncoderFactory* encoder_factory) {
+  if (external_encoder_factory_ == encoder_factory) {
+    return;
+  }
+  if (external_encoder_factory_) {
+    external_encoder_factory_->RemoveObserver(this);
+  }
+  external_encoder_factory_ = encoder_factory;
+  if (external_encoder_factory_) {
+    external_encoder_factory_->AddObserver(this);
+  }
+
+  // Invoke OnCodecAvailable() here in case the list of codecs is already
+  // available when the encoder factory is installed. If not the encoder
+  // factory will invoke the callback later when the codecs become available.
+  OnCodecsAvailable();
+}
+
 bool WebRtcVideoEngine2::EnableTimedRender() {
   // TODO(pbos): Figure out whether this can be removed.
   return true;
@@ -480,6 +506,9 @@
   return &default_video_encoder_factory_;
 }
 
+void WebRtcVideoEngine2::OnCodecsAvailable() {
+  // TODO(pbos): Implement.
+}
 // Thin map between VideoFrame and an existing webrtc::I420VideoFrame
 // to avoid having to copy the rendered VideoFrame prematurely.
 // This implementation is only safe to use in a const context and should never
diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h
index 8e22516..a1b953b 100644
--- a/talk/media/webrtc/webrtcvideoengine2.h
+++ b/talk/media/webrtc/webrtcvideoengine2.h
@@ -34,6 +34,8 @@
 
 #include "talk/media/base/mediaengine.h"
 #include "talk/media/webrtc/webrtcvideochannelfactory.h"
+#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
+#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
 #include "webrtc/base/cpumonitor.h"
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/common_video/interface/i420_video_frame.h"
@@ -65,14 +67,13 @@
 class VideoProcessor;
 class VideoRenderer;
 class VoiceMediaChannel;
-class WebRtcVideoChannel2;
 class WebRtcDecoderObserver;
 class WebRtcEncoderObserver;
 class WebRtcLocalStreamInfo;
 class WebRtcRenderAdapter;
+class WebRtcVideoChannel2;
 class WebRtcVideoChannelRecvInfo;
 class WebRtcVideoChannelSendInfo;
-class WebRtcVideoDecoderFactory;
 class WebRtcVoiceEngine;
 
 struct CapturedFrame;
@@ -129,7 +130,8 @@
 };
 
 // WebRtcVideoEngine2 is used for the new native WebRTC Video API (webrtc:1667).
-class WebRtcVideoEngine2 : public sigslot::has_slots<> {
+class WebRtcVideoEngine2 : public sigslot::has_slots<>,
+                           public WebRtcVideoEncoderFactory::Observer {
  public:
   // Creates the WebRtcVideoEngine2 with internal VideoCaptureModule.
   WebRtcVideoEngine2();
@@ -152,6 +154,16 @@
   const std::vector<RtpHeaderExtension>& rtp_header_extensions() const;
   void SetLogging(int min_sev, const char* filter);
 
+  // Set a WebRtcVideoDecoderFactory for external decoding. Video engine does
+  // not take the ownership of |decoder_factory|. The caller needs to make sure
+  // that |decoder_factory| outlives the video engine.
+  void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory);
+  // Set a WebRtcVideoEncoderFactory for external encoding. Video engine does
+  // not take the ownership of |encoder_factory|. The caller needs to make sure
+  // that |encoder_factory| outlives the video engine.
+  virtual void SetExternalEncoderFactory(
+      WebRtcVideoEncoderFactory* encoder_factory);
+
   bool EnableTimedRender();
   // This is currently ignored.
   sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange;
@@ -173,6 +185,8 @@
   virtual WebRtcVideoEncoderFactory2* GetVideoEncoderFactory();
 
  private:
+  virtual void OnCodecsAvailable() OVERRIDE;
+
   rtc::Thread* worker_thread_;
   WebRtcVoiceEngine* voice_engine_;
   std::vector<VideoCodec> video_codecs_;
@@ -188,6 +202,9 @@
   rtc::scoped_ptr<rtc::CpuMonitor> cpu_monitor_;
   WebRtcVideoChannelFactory* channel_factory_;
   WebRtcVideoEncoderFactory2 default_video_encoder_factory_;
+
+  WebRtcVideoDecoderFactory* external_decoder_factory_;
+  WebRtcVideoEncoderFactory* external_encoder_factory_;
 };
 
 class WebRtcVideoChannel2 : public rtc::MessageHandler,