Bug 911046 - Part 1: Support external codec in VideoConduit. r=jesup
authorJohn Lin <jolin@mozilla.com>
Mon, 21 Apr 2014 23:40:00 +0200
changeset 198001 29791e7f84ba8ba70e68cf3087a997425456b194
parent 198000 4672ae9dd0c8d06f410c20eabd0c0bc50c597e72
child 198002 5f761a1905ca31ae767aa25eeba3554658cf06c8
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs911046
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 911046 - Part 1: Support external codec in VideoConduit. r=jesup
media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.h
--- a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
+++ b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
@@ -157,16 +157,32 @@ public:
   virtual bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
                                    unsigned int* packetsSent,
                                    uint64_t* bytesSent) = 0;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaSessionConduit)
 
 };
 
+// Abstract base classes for external encoder/decoder.
+class VideoEncoder
+{
+public:
+  virtual ~VideoEncoder() {};
+
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoEncoder);
+};
+
+class VideoDecoder
+{
+public:
+  virtual ~VideoDecoder() {};
+
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoder);
+};
 
 /**
  * MediaSessionConduit for video
  * Refer to the comments on MediaSessionConduit above for overall
  * information
  */
 class VideoSessionConduit : public MediaSessionConduit
 {
@@ -236,16 +252,31 @@ public:
    * @param sendSessionConfig: CodecConfiguration
    * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting
    *        reception sub-system on the engine
    *
    */
   virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
                                 const std::vector<VideoCodecConfig* >& recvCodecConfigList) = 0;
 
+  /**
+   * Set an external encoder
+   * @param encoder
+   * @result: on success, we will use the specified encoder
+   */
+  virtual MediaConduitErrorCode SetExternalSendCodec(int pltype,
+                                                     VideoEncoder* encoder) = 0;
+
+  /**
+   * Set an external decoder
+   * @param decoder
+   * @result: on success, we will use the specified decoder
+   */
+  virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype,
+                                                     VideoDecoder* decoder) = 0;
 
   /**
    * These methods allow unit tests to double-check that the
    * max-fs and max-fr related settings are as expected.
    */
   virtual unsigned short SendingWidth() = 0;
 
   virtual unsigned short SendingHeight() = 0;
@@ -356,12 +387,8 @@ public:
     * @param id: id to be used for this rtp header extension
     * NOTE: See AudioConduit for more information
     */
   virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled, uint8_t id) = 0;
 
 };
 }
 #endif
-
-
-
-
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -120,16 +120,17 @@ WebrtcVideoConduit::~WebrtcVideoConduit(
     // We can't delete the VideoEngine until all these are released!
     // And we can't use a Scoped ptr, since the order is arbitrary
     mPtrViEBase = nullptr;
     mPtrViECapture = nullptr;
     mPtrViECodec = nullptr;
     mPtrViENetwork = nullptr;
     mPtrViERender = nullptr;
     mPtrRTP = nullptr;
+    mPtrExtCodec = nullptr;
 
     // only one opener can call Delete.  Have it be the last to close.
     if(mVideoEngine)
     {
       webrtc::VideoEngine::Delete(mVideoEngine);
     }
   }
 }
@@ -279,16 +280,23 @@ MediaConduitErrorCode WebrtcVideoConduit
   }
 
   if( !(mPtrRTP = webrtc::ViERTP_RTCP::GetInterface(mVideoEngine)))
   {
     CSFLogError(logTag, "%s Unable to get video RTCP interface ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
+  if ( !(mPtrExtCodec = webrtc::ViEExternalCodec::GetInterface(mVideoEngine)))
+  {
+    CSFLogError(logTag, "%s Unable to get external codec interface %d ",
+                __FUNCTION__, mPtrViEBase->LastError());
+    return kMediaConduitSessionNotInited;
+  }
+
   if (other) {
     mChannel = other->mChannel;
     mPtrExtCapture = other->mPtrExtCapture;
     mCapId = other->mCapId;
   } else {
     CSFLogDebug(logTag, "%s Engine Created: Init'ng the interfaces ",__FUNCTION__);
 
     if(mPtrViEBase->Init() == -1)
@@ -840,16 +848,35 @@ WebrtcVideoConduit::SelectSendResolution
       CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u",
                   __FUNCTION__, width, height);
     } // else no change; mSendingWidth likely was 0
   }
   return true;
 }
 
 MediaConduitErrorCode
+WebrtcVideoConduit::SetExternalSendCodec(int pltype,
+                                         VideoEncoder* encoder) {
+  int ret = mPtrExtCodec->RegisterExternalSendCodec(mChannel,
+                                                    pltype,
+                                                    static_cast<WebrtcVideoEncoder*>(encoder),
+                                                    false);
+  return ret ? kMediaConduitInvalidSendCodec : kMediaConduitNoError;
+}
+
+MediaConduitErrorCode
+WebrtcVideoConduit::SetExternalRecvCodec(int pltype,
+                                         VideoDecoder* decoder) {
+  int ret = mPtrExtCodec->RegisterExternalReceiveCodec(mChannel,
+                                                       pltype,
+                                                       static_cast<WebrtcVideoDecoder*>(decoder));
+  return ret ? kMediaConduitInvalidReceiveCodec : kMediaConduitNoError;
+}
+
+MediaConduitErrorCode
 WebrtcVideoConduit::SendVideoFrame(unsigned char* video_frame,
                                    unsigned int video_frame_length,
                                    unsigned short width,
                                    unsigned short height,
                                    VideoType video_type,
                                    uint64_t capture_time)
 {
   CSFLogDebug(logTag,  "%s ", __FUNCTION__);
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -7,39 +7,54 @@
 
 #include "mozilla/Attributes.h"
 
 #include "MediaConduitInterface.h"
 #include "MediaEngineWrapper.h"
 
 // Video Engine Includes
 #include "webrtc/common_types.h"
+#ifdef FF
+#undef FF // Avoid name collision between scoped_ptr.h and nsCRTGlue.h.
+#endif
+#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
 #include "webrtc/video_engine/include/vie_base.h"
 #include "webrtc/video_engine/include/vie_capture.h"
 #include "webrtc/video_engine/include/vie_codec.h"
+#include "webrtc/video_engine/include/vie_external_codec.h"
 #include "webrtc/video_engine/include/vie_render.h"
 #include "webrtc/video_engine/include/vie_network.h"
 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
 
 /** This file hosts several structures identifying different aspects
  * of a RTP Session.
  */
 
  using  webrtc::ViEBase;
  using  webrtc::ViENetwork;
  using  webrtc::ViECodec;
  using  webrtc::ViECapture;
  using  webrtc::ViERender;
  using  webrtc::ViEExternalCapture;
-
+ using  webrtc::ViEExternalCodec;
 
 namespace mozilla {
 
 class WebrtcAudioConduit;
 
+// Interface of external video encoder for WebRTC.
+class WebrtcVideoEncoder:public VideoEncoder
+                         ,public webrtc::VideoEncoder
+{};
+
+// Interface of external video decoder for WebRTC.
+class WebrtcVideoDecoder:public VideoDecoder
+                         ,public webrtc::VideoDecoder
+{};
+
 /**
  * Concrete class for Video session. Hooks up
  *  - media-source and target to external transport
  */
 class WebrtcVideoConduit:public VideoSessionConduit
                          ,public webrtc::Transport
                          ,public webrtc::ExternalRenderer
 {
@@ -122,16 +137,29 @@ public:
    */
   virtual MediaConduitErrorCode SendVideoFrame(unsigned char* video_frame,
                                                 unsigned int video_frame_length,
                                                 unsigned short width,
                                                 unsigned short height,
                                                 VideoType video_type,
                                                 uint64_t capture_time);
 
+  /**
+   * Set an external encoder object |encoder| to the payload type |pltype|
+   * for sender side codec.
+   */
+  virtual MediaConduitErrorCode SetExternalSendCodec(int pltype,
+                                                     VideoEncoder* encoder);
+
+  /**
+   * Set an external decoder object |decoder| to the payload type |pltype|
+   * for receiver side codec.
+   */
+  virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype,
+                                                     VideoDecoder* decoder);
 
 
   /**
    * Webrtc transport implementation to send and receive RTP packet.
    * VideoConduit registers itself as ExternalTransport to the VideoEngine
    */
   virtual int SendPacket(int channel, const void *data, int len) ;
 
@@ -260,16 +288,17 @@ private:
   mozilla::RefPtr<VideoRenderer> mRenderer;
 
   ScopedCustomReleasePtr<webrtc::ViEBase> mPtrViEBase;
   ScopedCustomReleasePtr<webrtc::ViECapture> mPtrViECapture;
   ScopedCustomReleasePtr<webrtc::ViECodec> mPtrViECodec;
   ScopedCustomReleasePtr<webrtc::ViENetwork> mPtrViENetwork;
   ScopedCustomReleasePtr<webrtc::ViERender> mPtrViERender;
   ScopedCustomReleasePtr<webrtc::ViERTP_RTCP> mPtrRTP;
+  ScopedCustomReleasePtr<webrtc::ViEExternalCodec> mPtrExtCodec;
 
   webrtc::ViEExternalCapture* mPtrExtCapture; // shared
 
   // Engine state we are concerned with.
   bool mEngineTransmitting; //If true ==> Transmit Sub-system is up and running
   bool mEngineReceiving;    // if true ==> Receive Sus-sysmtem up and running
 
   int mChannel; // Video Channel for this conduit