Bug 797671: cleanup from importing webrtc.org update r=ted,glandium (Part is bug 778801 r=derf)
authorRandell Jesup <rjesup@jesup.org>
Thu, 04 Oct 2012 12:09:35 -0400
changeset 115579 7dda68e6ffbaa817b881d75c097fe1a7fffd0078
parent 115578 174d772e83f42e84c3ba97b8fbb9c937cba027a9
child 115580 61dbc8b4ca76a46d9cee120fdf187c10bbcca367
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersted, glandium, derf
bugs797671, 778801
milestone18.0a1
Bug 797671: cleanup from importing webrtc.org update r=ted,glandium (Part is bug 778801 r=derf)
configure.in
content/media/webrtc/MediaEngine.h
content/media/webrtc/MediaEngineDefault.cpp
content/media/webrtc/MediaEngineDefault.h
content/media/webrtc/MediaEngineWebRTC.cpp
content/media/webrtc/MediaEngineWebRTC.h
content/media/webrtc/MediaEngineWebRTCVideo.cpp
layout/media/Makefile.in
layout/media/symbols.def.in
media/webrtc/shared_libs.mk
media/webrtc/trunk/src/modules/modules.gyp
media/webrtc/webrtc-config.mk
media/webrtc/webrtc_config.gypi
media/webrtc/webrtc_update.sh
media/webrtc/webrtc_version.h
toolkit/library/Makefile.in
--- a/configure.in
+++ b/configure.in
@@ -2972,19 +2972,21 @@ freebsd*|openbsd*)
     ;;
 esac
 MOZ_CHECK_COMMON_HEADERS
 
 dnl These are all the places some variant of statfs can be hiding.
 MOZ_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
 
 dnl Quota support
+MOZ_CHECK_HEADERS(sys/quota.h sys/sysmacros.h)
+MOZ_CHECK_HEADERS([linux/quota.h],,,[#include <sys/socket.h>])
+
 dnl SCTP support - needs various network include headers
-MOZ_CHECK_HEADERS(sys/quota.h sys/sysmacros.h)
-MOZ_CHECK_HEADERS([linux/quota.h linux/if_addr.h linux/rtnetlink.h],,,[#include <sys/socket.h>])
+MOZ_CHECK_HEADERS([linux/if_addr.h linux/rtnetlink.h],,,[#include <sys/socket.h>])
 
 MOZ_CHECK_HEADERS(sys/types.h netinet/in.h byteswap.h)
 
 dnl Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
 AC_CACHE_CHECK(for sockaddr_in.sin_len,
                    ac_cv_sockaddr_in_sin_len,
                    [AC_TRY_COMPILE([#ifdef HAVE_SYS_TYPES_H
                                     #include <sys/types.h>
@@ -2993,17 +2995,17 @@ AC_CACHE_CHECK(for sockaddr_in.sin_len,
                                     struct sockaddr_in x;
                                     void *foo = (void*) &x.sin_len;],
                                    [],
                                    [ac_cv_sockaddr_in_sin_len=true],
                                    [ac_cv_sockaddr_in_sin_len=false])])
 if test "$ac_cv_sockaddr_in_sin_len" = true ; then
   AC_DEFINE(HAVE_SIN_LEN)
 dnl HAVE_CONN_LEN must be the same as HAVE_SIN_LEN (and HAVE_SIN6_LEN too)
-  AC_DEFINE(HAVE_CONN_LEN)
+  AC_DEFINE(HAVE_SCONN_LEN)
 fi
 
 AC_CACHE_CHECK(for sockaddr_in6.sin6_len,
                ac_cv_sockaddr_in6_sin6_len,
                [AC_TRY_COMPILE([#ifdef HAVE_SYS_TYPES_H
                                 #include <sys/types.h>
                                 #endif
                                 #include <netinet/in.h>
@@ -3011,16 +3013,31 @@ AC_CACHE_CHECK(for sockaddr_in6.sin6_len
                                 void *foo = (void*) &x.sin6_len;],
                                [],
                                [ac_cv_sockaddr_in6_sin6_len=true],
                                [ac_cv_sockaddr_in6_sin6_len=false])])
 if test "$ac_cv_sockaddr_in6_sin6_len" = true ; then
   AC_DEFINE(HAVE_SIN6_LEN)
 fi
 
+AC_CACHE_CHECK(for sockaddr.sa_len,
+               ac_cv_sockaddr_sa_len,
+               [AC_TRY_COMPILE([#ifdef HAVE_SYS_TYPES_H
+                                #include <sys/types.h>
+                                #endif
+                                #include <sys/socket.h>
+                                struct sockaddr x;
+                                void *foo = (void*) &x.sa_len;],
+                               [],
+                               [ac_cv_sockaddr_sa_len=true],
+                               [ac_cv_sockaddr_sa_len=false])])
+if test "$ac_cv_sockaddr_sa_len" = true ; then
+  AC_DEFINE(HAVE_SA_LEN)
+fi
+
 dnl Check whether the compiler supports the new-style C++ standard
 dnl library headers (i.e. <new>) or needs the old "new.h"
 AC_LANG_CPLUSPLUS
 NEW_H=new.h
 MOZ_CHECK_HEADER(new, [NEW_H=new])
 AC_DEFINE_UNQUOTED(NEW_H, <$NEW_H>)
 AC_LANG_C
 
@@ -4220,18 +4237,20 @@ MOZ_TREMOR=
 MOZ_WAVE=1
 MOZ_SAMPLE_TYPE_FLOAT32=
 MOZ_SAMPLE_TYPE_S16=
 MOZ_MEDIA=
 MOZ_OPUS=1
 MOZ_WEBM=1
 MOZ_DASH=
 MOZ_WEBRTC=1
+MOZ_PEERCONNECTION=
 MOZ_SRTP=
 MOZ_WEBRTC_SIGNALING=
+MOZ_WEBRTC_IN_LIBXUL=
 MOZ_SCTP=
 MOZ_MEDIA_PLUGINS=
 MOZ_MEDIA_NAVIGATOR=
 MOZ_OMX_PLUGIN=
 MOZ_VP8=
 MOZ_VP8_ERROR_CONCEALMENT=
 MOZ_VP8_ENCODER=
 VPX_AS=
@@ -5218,23 +5237,35 @@ MOZ_ARG_DISABLE_BOOL(webrtc,
 
 if test -n "$MOZ_WEBRTC"; then
     AC_DEFINE(MOZ_WEBRTC)
     MOZ_MEDIA=1
     MOZ_RAW=1
     MOZ_VP8=1
     MOZ_VP8_ENCODER=1
     MOZ_VP8_ERROR_CONCEALMENT=1
+dnl enable once Signaling lands
+dnl MOZ_WEBRTC_SIGNALING=1
+dnl AC_DEFINE(MOZ_WEBRTC_SIGNALING)
+    if test "${OS_TARGET}" = "WINNT"; then
+        MOZ_WEBRTC_IN_LIBXUL=1
+    fi
+dnl enable once PeerConnection lands
+dnl MOZ_PEERCONNECTION=1
+dnl AC_DEFINE(MOZ_PEERCONNECTION)
     MOZ_SCTP=1
     MOZ_SRTP=1
     AC_DEFINE(MOZ_SCTP)
     AC_DEFINE(MOZ_SRTP)
 fi
 
 AC_SUBST(MOZ_WEBRTC)
+AC_SUBST(MOZ_WEBRTC_SIGNALING)
+AC_SUBST(MOZ_PEERCONNECTION)
+AC_SUBST(MOZ_WEBRTC_IN_LIBXUL)
 AC_SUBST(MOZ_SCTP)
 AC_SUBST(MOZ_SRTP)
 
 case "$target_cpu" in
 arm*)
     MOZ_SAMPLE_TYPE_S16=1
     AC_DEFINE(MOZ_SAMPLE_TYPE_S16)
     AC_SUBST(MOZ_SAMPLE_TYPE_S16)
@@ -8813,36 +8844,49 @@ if test "${OS_TARGET}" = "WINNT"; then
       OS_BITS=32
    fi
    EXTRA_GYP_DEFINES="-D MSVS_VERSION=${_MSVS_VERSION} -D MSVS_OS_BITS=${OS_BITS}"
 fi
 
 if test -n "$MOZ_WEBRTC"; then
    AC_MSG_RESULT("generating WebRTC Makefiles...")
 
-   GYP_WEBRTC_OPTIONS="--format=mozmake -D build_with_mozilla=1 -D enable_protobuf=0 -D include_internal_video_render=0 ${EXTRA_GYP_DEFINES} --depth=${srcdir}/media/webrtc/trunk --toplevel-dir=${srcdir} -G OBJDIR=${_objdir}"
+   WEBRTC_CONFIG="-D build_with_mozilla=1 --include ${srcdir}/media/webrtc/webrtc_config.gypi"
+
+   GYP_WEBRTC_OPTIONS="--format=mozmake ${WEBRTC_CONFIG} ${EXTRA_GYP_DEFINES} --depth=${srcdir}/media/webrtc/trunk --toplevel-dir=${srcdir} -G OBJDIR=${_objdir}"
 
    $PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
      $GYP_WEBRTC_OPTIONS \
      --generator-output=${_objdir}/media/webrtc/trunk \
      ${srcdir}/media/webrtc/trunk/peerconnection.gyp
    if test "$?" != 0; then
       AC_MSG_ERROR([failed to generate WebRTC Makefiles])
    fi
 
    # XXX disable until we land the tranche with signaling
    if test -n "$MOZ_WEBRTC_SIGNALING"; then
      AC_MSG_RESULT("generating WebRTC/Signaling Makefiles...")
      $PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
        $GYP_WEBRTC_OPTIONS \
+       -D build_for_test=0 \
        --generator-output=${_objdir}/media/webrtc/signaling \
        ${srcdir}/media/webrtc/signaling/signaling.gyp
      if test "$?" != 0; then
         AC_MSG_ERROR([failed to generate WebRTC/Signaling Makefiles])
      fi
+
+     AC_MSG_RESULT("generating WebRTC/SignalingTest Makefiles...")
+     $PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium --format=mozmake \
+       $GYP_WEBRTC_OPTIONS \
+       -D build_for_test=1 \
+       --generator-output=${_objdir}/media/webrtc/signalingtest \
+       ${srcdir}/media/webrtc/signaling/signaling.gyp
+     if test "$?" != 0; then
+       AC_MSG_ERROR([failed to generate WebRTC/SignalingTest Makefiles])
+     fi
    fi
 
    AC_MSG_RESULT("generating gtest Makefiles...")
    # Ok to pass some extra -D's that are ignored here
    $PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
      $GYP_WEBRTC_OPTIONS \
      --generator-output=${_objdir}/media/webrtc/trunk/testing/ \
      ${srcdir}/media/webrtc/trunk/testing/gtest.gyp
--- a/content/media/webrtc/MediaEngine.h
+++ b/content/media/webrtc/MediaEngine.h
@@ -98,17 +98,17 @@ struct MediaEngineVideoOptions {
 
 class MediaEngineVideoSource : public MediaEngineSource
 {
 public:
   virtual ~MediaEngineVideoSource() {};
 
   /* Return a MediaEngineVideoOptions struct with appropriate values for all
    * fields. */
-  virtual MediaEngineVideoOptions GetOptions() = 0;
+  virtual const MediaEngineVideoOptions *GetOptions() = 0;
 };
 
 /**
  * Audio source and friends.
  */
 class MediaEngineAudioSource : public MediaEngineSource
 {
 public:
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -11,29 +11,34 @@
 #include "ImageContainer.h"
 #include "ImageTypes.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "nsISupportsUtils.h"
 #endif
 
-#define WIDTH 320
-#define HEIGHT 240
-#define FPS 10
 #define CHANNELS 1
 #define RATE USECS_PER_S
 
 namespace mozilla {
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback)
 /**
  * Default video source.
  */
 
+// Cannot be initialized in the class definition
+const MediaEngineVideoOptions MediaEngineDefaultVideoSource::mOpts = {
+  DEFAULT_WIDTH,
+  DEFAULT_HEIGHT,
+  DEFAULT_FPS,
+  kVideoCodecI420
+};
+
 MediaEngineDefaultVideoSource::MediaEngineDefaultVideoSource()
   : mTimer(nullptr), mState(kReleased)
 {}
 
 MediaEngineDefaultVideoSource::~MediaEngineDefaultVideoSource()
 {}
 
 void
@@ -66,25 +71,20 @@ MediaEngineDefaultVideoSource::Deallocat
 {
   if (mState != kStopped && mState != kAllocated) {
     return NS_ERROR_FAILURE;
   }
   mState = kReleased;
   return NS_OK;
 }
 
-MediaEngineVideoOptions
+const MediaEngineVideoOptions *
 MediaEngineDefaultVideoSource::GetOptions()
 {
-  MediaEngineVideoOptions aOpts;
-  aOpts.mWidth = WIDTH;
-  aOpts.mHeight = HEIGHT;
-  aOpts.mMaxFPS = FPS;
-  aOpts.codecType = kVideoCodecI420;
-  return aOpts;
+  return &mOpts;
 }
 
 nsresult
 MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
 {
   if (mState != kAllocated) {
     return NS_ERROR_FAILURE;
   }
@@ -97,54 +97,54 @@ MediaEngineDefaultVideoSource::Start(Sou
   mSource = aStream;
 
   // Allocate a single blank Image
   ImageFormat format = PLANAR_YCBCR;
   mImageContainer = layers::LayerManager::CreateImageContainer();
 
   nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1);
 
-  int len = ((WIDTH * HEIGHT) * 3 / 2);
+  int len = ((DEFAULT_WIDTH * DEFAULT_HEIGHT) * 3 / 2);
   mImage = static_cast<layers::PlanarYCbCrImage*>(image.get());
   uint8_t* frame = (uint8_t*) PR_Malloc(len);
   memset(frame, 0x80, len); // Gray
 
   const uint8_t lumaBpp = 8;
   const uint8_t chromaBpp = 4;
 
   layers::PlanarYCbCrImage::Data data;
   data.mYChannel = frame;
-  data.mYSize = gfxIntSize(WIDTH, HEIGHT);
-  data.mYStride = WIDTH * lumaBpp / 8.0;
-  data.mCbCrStride = WIDTH * chromaBpp / 8.0;
-  data.mCbChannel = frame + HEIGHT * data.mYStride;
-  data.mCrChannel = data.mCbChannel + HEIGHT * data.mCbCrStride / 2;
-  data.mCbCrSize = gfxIntSize(WIDTH / 2, HEIGHT / 2);
+  data.mYSize = gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+  data.mYStride = DEFAULT_WIDTH * lumaBpp / 8.0;
+  data.mCbCrStride = DEFAULT_WIDTH * chromaBpp / 8.0;
+  data.mCbChannel = frame + DEFAULT_HEIGHT * data.mYStride;
+  data.mCrChannel = data.mCbChannel + DEFAULT_HEIGHT * data.mCbCrStride / 2;
+  data.mCbCrSize = gfxIntSize(DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2);
   data.mPicX = 0;
   data.mPicY = 0;
-  data.mPicSize = gfxIntSize(WIDTH, HEIGHT);
+  data.mPicSize = gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
   data.mStereoMode = STEREO_MODE_MONO;
 
   // SetData copies data, so we can free the frame
   mImage->SetData(data);
   PR_Free(frame);
 
   // AddTrack takes ownership of segment
   VideoSegment *segment = new VideoSegment();
-  segment->AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT));
+  segment->AppendFrame(image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
   mSource->AddTrack(aID, RATE, 0, segment);
 
   // We aren't going to add any more tracks
   mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
   // Remember TrackID so we can end it later
   mTrackID = aID;
 
   // Start timer for subsequent frames
-  mTimer->InitWithCallback(this, 1000 / FPS, nsITimer::TYPE_REPEATING_SLACK);
+  mTimer->InitWithCallback(this, 1000 / DEFAULT_FPS, nsITimer::TYPE_REPEATING_SLACK);
   mState = kStarted;
 
   return NS_OK;
 }
 
 nsresult
 MediaEngineDefaultVideoSource::Stop()
 {
@@ -190,17 +190,17 @@ MediaEngineDefaultVideoSource::Snapshot(
 }
 
 NS_IMETHODIMP
 MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
 {
   VideoSegment segment;
 
   nsRefPtr<layers::PlanarYCbCrImage> image = mImage;
-  segment.AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT));
+  segment.AppendFrame(image.forget(), USECS_PER_S / DEFAULT_FPS, gfxIntSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
   mSource->AppendToTrack(mTrackID, &segment);
 
   return NS_OK;
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineDefaultAudioSource, nsITimerCallback)
 /**
  * Default audio source.
@@ -261,17 +261,17 @@ MediaEngineDefaultAudioSource::Start(Sou
 
   // We aren't going to add any more tracks
   mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
   // Remember TrackID so we can finish later
   mTrackID = aID;
 
   // 1 Audio frame per Video frame
-  mTimer->InitWithCallback(this, 1000 / FPS, nsITimer::TYPE_REPEATING_SLACK);
+  mTimer->InitWithCallback(this, 1000 / MediaEngineDefaultVideoSource::DEFAULT_FPS, nsITimer::TYPE_REPEATING_SLACK);
   mState = kStarted;
 
   return NS_OK;
 }
 
 nsresult
 MediaEngineDefaultAudioSource::Stop()
 {
--- a/content/media/webrtc/MediaEngineDefault.h
+++ b/content/media/webrtc/MediaEngineDefault.h
@@ -34,35 +34,41 @@ class MediaEngineDefaultVideoSource : pu
 {
 public:
   MediaEngineDefaultVideoSource();
   ~MediaEngineDefaultVideoSource();
 
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
 
-  virtual MediaEngineVideoOptions GetOptions();
+  virtual const MediaEngineVideoOptions *GetOptions();
   virtual nsresult Allocate();
 
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop();
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
+  // Need something better...
+  static const int DEFAULT_WIDTH=640;
+  static const int DEFAULT_HEIGHT=480;
+  static const int DEFAULT_FPS=30;
+
 protected:
   TrackID mTrackID;
   nsCOMPtr<nsITimer> mTimer;
   nsRefPtr<layers::ImageContainer> mImageContainer;
 
   MediaEngineState mState;
   SourceMediaStream* mSource;
   layers::PlanarYCbCrImage* mImage;
+  static const MediaEngineVideoOptions mOpts;
 };
 
 class MediaEngineDefaultAudioSource : public nsITimerCallback,
                                       public MediaEngineAudioSource
 {
 public:
   MediaEngineDefaultAudioSource() : mTimer(nullptr), mState(kReleased) {}
   ~MediaEngineDefaultAudioSource(){};
--- a/content/media/webrtc/MediaEngineWebRTC.cpp
+++ b/content/media/webrtc/MediaEngineWebRTC.cpp
@@ -1,38 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG
+#endif
+
+#if defined(PR_LOG)
+#error "This file must be #included before any IPDL-generated files or other files that #include prlog.h"
+#endif
+
+#include "prlog.h"
+
+#ifdef PR_LOGGING
+PRLogModuleInfo* GetUserMediaLog = PR_NewLogModule("GetUserMedia");
+#endif
+
+#undef LOG
+#define LOG(args) PR_LOG(GetUserMediaLog, PR_LOG_DEBUG, args)
+
 #include "MediaEngineWebRTC.h"
 #include "ImageContainer.h"
 
 namespace mozilla {
 
-MediaEngineWebRTCVideoSource::MediaEngineWebRTCVideoSource(webrtc::VideoEngine* videoEnginePtr,
-                                                           int index, int aFps)
-  : mVideoEngine(videoEnginePtr)
-  , mCapIndex(index)
-  , mWidth(640)
-  , mHeight(480)
-  , mState(kReleased)
-  , mMonitor("WebRTCCamera.Monitor")
-  , mFps(aFps)
-  , mInitDone(false)
-  , mInSnapshotMode(false)
-  , mSnapshotPath(NULL)
-{
-  Init();
-}
-
-MediaEngineWebRTCVideoSource::~MediaEngineWebRTCVideoSource()
-{
-  Shutdown();
-}
-
 void
 MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources)
 {
   webrtc::ViEBase* ptrViEBase;
   webrtc::ViECapture* ptrViECapture;
 
   if (!mVideoEngine) {
     if (!(mVideoEngine = webrtc::VideoEngine::Create())) {
@@ -58,16 +54,48 @@ MediaEngineWebRTC::EnumerateVideoDevices
   }
 
   int num = ptrViECapture->NumberOfCaptureDevices();
   if (num <= 0) {
     return;
   }
 
   for (int i = 0; i < num; i++) {
+#ifdef DEBUG
+    const unsigned int kMaxDeviceNameLength = 128; // XXX FIX!
+    const unsigned int kMaxUniqueIdLength = 256;
+    char deviceName[kMaxDeviceNameLength];
+    char uniqueId[kMaxUniqueIdLength];
+
+    // paranoia
+    deviceName[0] = '\0';
+    uniqueId[0] = '\0';
+    int error = ptrViECapture->GetCaptureDevice(i, deviceName,
+                                                sizeof(deviceName), uniqueId,
+                                                sizeof(uniqueId));
+    if (error) {
+      LOG((" VieCapture:GetCaptureDevice: Failed %d", 
+           ptrViEBase->LastError() ));
+      continue;
+    }
+    LOG(("  Capture Device Index %d, Name %s", i, deviceName));
+
+    webrtc::CaptureCapability cap;
+    int numCaps = ptrViECapture->NumberOfCapabilities(uniqueId, kMaxUniqueIdLength);
+    LOG(("Number of Capabilities %d", numCaps));
+    for (int j = 0; j < numCaps; j++) {
+      if (ptrViECapture->GetCaptureCapability(uniqueId, kMaxUniqueIdLength, 
+                                              j, cap ) != 0 ) {
+        break;
+      }
+      LOG(("type=%d width=%d height=%d maxFPS=%d",
+           cap.rawType, cap.width, cap.height, cap.maxFPS ));
+    }
+#endif
+
     nsRefPtr<MediaEngineVideoSource> vSource = new MediaEngineWebRTCVideoSource(mVideoEngine, i);
     aVSources->AppendElement(vSource.forget());
   }
 
   ptrViEBase->Release();
   ptrViECapture->Release();
 
   return;
@@ -103,20 +131,20 @@ MediaEngineWebRTC::EnumerateAudioDevices
     return;
   }
 
   int nDevices = 0;
   ptrVoEHw->GetNumOfRecordingDevices(nDevices);
   for (int i = 0; i < nDevices; i++) {
     // We use constants here because GetRecordingDeviceName takes char[128].
     char deviceName[128];
-    memset(deviceName, 0, sizeof(deviceName));
-
     char uniqueID[128];
-    memset(uniqueID, 0, sizeof(uniqueID));
+    // paranoia; jingle doesn't bother with this
+    deviceName[0] = '\0';
+    uniqueID[0] = '\0';
 
     ptrVoEHw->GetRecordingDeviceName(i, deviceName, uniqueID);
     nsRefPtr<MediaEngineAudioSource> aSource = new MediaEngineWebRTCAudioSource(
       mVoiceEngine, i, deviceName, uniqueID
     );
     aASources->AppendElement(aSource.forget());
   }
 
--- a/content/media/webrtc/MediaEngineWebRTC.h
+++ b/content/media/webrtc/MediaEngineWebRTC.h
@@ -23,22 +23,22 @@
 #include "VideoSegment.h"
 #include "AudioSegment.h"
 #include "StreamBuffer.h"
 #include "MediaStreamGraph.h"
 
 // WebRTC library includes follow
 
 // Audio Engine
-#include "voice_engine/main/interface/voe_base.h"
-#include "voice_engine/main/interface/voe_codec.h"
-#include "voice_engine/main/interface/voe_hardware.h"
-#include "voice_engine/main/interface/voe_audio_processing.h"
-#include "voice_engine/main/interface/voe_volume_control.h"
-#include "voice_engine/main/interface/voe_external_media.h"
+#include "voice_engine/include/voe_base.h"
+#include "voice_engine/include/voe_codec.h"
+#include "voice_engine/include/voe_hardware.h"
+#include "voice_engine/include/voe_audio_processing.h"
+#include "voice_engine/include/voe_volume_control.h"
+#include "voice_engine/include/voe_external_media.h"
 
 // Video Engine
 #include "video_engine/include/vie_base.h"
 #include "video_engine/include/vie_codec.h"
 #include "video_engine/include/vie_render.h"
 #include "video_engine/include/vie_capture.h"
 #include "video_engine/include/vie_file.h"
 
@@ -48,27 +48,30 @@ namespace mozilla {
 /**
  * The WebRTC implementation of the MediaEngine interface.
  */
 class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource,
                                      public webrtc::ExternalRenderer,
                                      public nsRunnable
 {
 public:
+  static const int DEFAULT_VIDEO_FPS = 30;
+  static const int DEFAULT_MIN_VIDEO_FPS = 10;
+
   // ViEExternalRenderer.
   virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
   virtual int DeliverFrame(unsigned char*, int, uint32_t, int64_t);
 
   MediaEngineWebRTCVideoSource(webrtc::VideoEngine* videoEnginePtr,
-    int index, int aFps = 30);
+    int index, int aMinFps = DEFAULT_MIN_VIDEO_FPS);
   ~MediaEngineWebRTCVideoSource();
 
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
-  virtual MediaEngineVideoOptions GetOptions();
+  virtual const MediaEngineVideoOptions *GetOptions();
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop();
   virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
 
   NS_DECL_ISUPPORTS
 
@@ -87,67 +90,75 @@ public:
     mSnapshotPath = new nsString();
     rv = tmp->GetPath(*mSnapshotPath);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
 private:
-  static const unsigned int KMaxDeviceNameLength;
-  static const unsigned int KMaxUniqueIdLength;
+  static const unsigned int KMaxDeviceNameLength = 128;
+  static const unsigned int KMaxUniqueIdLength = 256;
 
   // Initialize the needed Video engine interfaces.
   void Init();
   void Shutdown();
 
   // Engine variables.
 
   webrtc::VideoEngine* mVideoEngine; // Weak reference, don't free.
   webrtc::ViEBase* mViEBase;
   webrtc::ViECapture* mViECapture;
   webrtc::ViERender* mViERender;
-  webrtc::CaptureCapability mCaps; // Doesn't work on OS X.
+  webrtc::CaptureCapability mCapability; // Doesn't work on OS X.
 
-  int mCapIndex;
+  int mCaptureIndex;
+  bool mCapabilityChosen;
   int mWidth, mHeight;
   TrackID mTrackID;
 
   MediaEngineState mState;
   mozilla::ReentrantMonitor mMonitor; // Monitor for processing WebRTC frames.
   SourceMediaStream* mSource;
 
   int mFps; // Track rate (30 fps by default)
+  int mMinFps; // Min rate we want to accept
   bool mInitDone;
   bool mInSnapshotMode;
   nsString* mSnapshotPath;
 
   nsRefPtr<layers::ImageContainer> mImageContainer;
 
   PRLock* mSnapshotLock;
   PRCondVar* mSnapshotCondVar;
 
+  // These are in UTF-8 but webrtc api uses char arrays
+  char mDeviceName[KMaxDeviceNameLength];
+  char mUniqueId[KMaxUniqueIdLength];
+
+  void ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS);
+  MediaEngineVideoOptions mOpts;
 };
 
 class MediaEngineWebRTCAudioSource : public MediaEngineAudioSource,
                                      public webrtc::VoEMediaProcess
 {
 public:
   MediaEngineWebRTCAudioSource(webrtc::VoiceEngine* voiceEngine, int aIndex,
-    char* name, char* uuid)
+    const char* name, const char* uuid)
     : mVoiceEngine(voiceEngine)
     , mMonitor("WebRTCMic.Monitor")
     , mCapIndex(aIndex)
     , mChannel(-1)
     , mInitDone(false)
     , mState(kReleased) {
 
     mVoEBase = webrtc::VoEBase::GetInterface(mVoiceEngine);
-    mDeviceName.Assign(NS_ConvertASCIItoUTF16(name));
-    mDeviceUUID.Assign(NS_ConvertASCIItoUTF16(uuid));
+    mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
+    mDeviceUUID.Assign(NS_ConvertUTF8toUTF16(uuid));
     mInitDone = true;
   }
 
   ~MediaEngineWebRTCAudioSource() { Shutdown(); }
 
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
 
@@ -160,18 +171,18 @@ public:
   // VoEMediaProcess.
   void Process(const int channel, const webrtc::ProcessingTypes type,
                WebRtc_Word16 audio10ms[], const int length,
                const int samplingFreq, const bool isStereo);
 
   NS_DECL_ISUPPORTS
 
 private:
-  static const unsigned int KMaxDeviceNameLength;
-  static const unsigned int KMaxUniqueIdLength;
+  static const unsigned int KMaxDeviceNameLength = 128;
+  static const unsigned int KMaxUniqueIdLength = 256;
 
   void Init();
   void Shutdown();
 
   webrtc::VoiceEngine* mVoiceEngine;
   webrtc::VoEBase* mVoEBase;
   webrtc::VoEExternalMedia* mVoERender;
 
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -9,19 +9,38 @@
 
 namespace mozilla {
 
 /**
  * Webrtc video source.
  */
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
 
-// Static variables to hold device names and UUIDs.
-const unsigned int MediaEngineWebRTCVideoSource::KMaxDeviceNameLength = 128;
-const unsigned int MediaEngineWebRTCVideoSource::KMaxUniqueIdLength = 256;
+MediaEngineWebRTCVideoSource::MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr,
+                                                           int aIndex, int aMinFps)
+  : mVideoEngine(aVideoEnginePtr)
+  , mCaptureIndex(aIndex)
+  , mCapabilityChosen(false)
+  , mWidth(640)
+  , mHeight(480)
+  , mState(kReleased)
+  , mMonitor("WebRTCCamera.Monitor")
+  , mFps(DEFAULT_VIDEO_FPS)
+  , mMinFps(aMinFps)
+  , mInitDone(false)
+  , mInSnapshotMode(false)
+  , mSnapshotPath(NULL)
+{
+  Init();
+}
+
+MediaEngineWebRTCVideoSource::~MediaEngineWebRTCVideoSource()
+{
+  Shutdown();
+}
 
 // ViEExternalRenderer Callback.
 int
 MediaEngineWebRTCVideoSource::FrameSizeChange(
    unsigned int w, unsigned int h, unsigned int streams)
 {
   mWidth = w;
   mHeight = h;
@@ -76,100 +95,127 @@ MediaEngineWebRTCVideoSource::DeliverFra
 
   VideoSegment segment;
   segment.AppendFrame(image.forget(), 1, gfxIntSize(mWidth, mHeight));
   mSource->AppendToTrack(mTrackID, &(segment));
   return 0;
 }
 
 void
+MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS)
+{
+  int num = mViECapture->NumberOfCapabilities(mUniqueId, KMaxUniqueIdLength);
+
+  NS_WARN_IF_FALSE(!mCapabilityChosen,"Shouldn't select capability of a device twice");
+
+  if (num <= 0) {
+    // Set to default values
+    mCapability.width  = mOpts.mWidth  = aWidth;
+    mCapability.height = mOpts.mHeight = aHeight;
+    mCapability.maxFPS = mOpts.mMaxFPS = DEFAULT_VIDEO_FPS;
+    mOpts.codecType = kVideoCodecI420;
+
+    // Mac doesn't support capabilities.
+    mCapabilityChosen = true;
+    return;
+  }
+
+  // Default is closest to available capability but equal to or below;
+  // otherwise closest above.  Since we handle the num=0 case above and
+  // take the first entry always, we can never exit uninitialized.
+  webrtc::CaptureCapability cap;
+  bool higher = true;
+  for (int i = 0; i < num; i++) {
+    mViECapture->GetCaptureCapability(mUniqueId, KMaxUniqueIdLength, i, cap);
+    if (higher) {
+      if (i == 0 ||
+          (mOpts.mWidth > cap.width && mOpts.mHeight > cap.height)) {
+        mOpts.mWidth = cap.width;
+        mOpts.mHeight = cap.height;
+        mOpts.mMaxFPS = cap.maxFPS;
+        mCapability = cap;
+        // FIXME: expose expected capture delay?
+      }
+      if (cap.width <= aWidth && cap.height <= aHeight) {
+        higher = false;
+      }
+    } else {
+      if (cap.width > aWidth || cap.height > aHeight || cap.maxFPS < aMinFPS) {
+        continue;
+      }
+      if (mOpts.mWidth < cap.width && mOpts.mHeight < cap.height) {
+        mOpts.mWidth = cap.width;
+        mOpts.mHeight = cap.height;
+        mOpts.mMaxFPS = cap.maxFPS;
+        mCapability = cap;
+        // FIXME: expose expected capture delay?
+      }
+    }
+  }
+  mCapabilityChosen = true;
+}
+
+void
 MediaEngineWebRTCVideoSource::GetName(nsAString& aName)
 {
-  char deviceName[KMaxDeviceNameLength];
-  memset(deviceName, 0, KMaxDeviceNameLength);
-
-  char uniqueId[KMaxUniqueIdLength];
-  memset(uniqueId, 0, KMaxUniqueIdLength);
-
-  if (mInitDone) {
-    mViECapture->GetCaptureDevice(
-      mCapIndex, deviceName, KMaxDeviceNameLength, uniqueId, KMaxUniqueIdLength
-    );
-    aName.Assign(NS_ConvertASCIItoUTF16(deviceName));
-  }
+  // mDeviceName is UTF8
+  CopyUTF8toUTF16(mDeviceName, aName);
 }
 
 void
 MediaEngineWebRTCVideoSource::GetUUID(nsAString& aUUID)
 {
-  char deviceName[KMaxDeviceNameLength];
-  memset(deviceName, 0, KMaxDeviceNameLength);
-
-  char uniqueId[KMaxUniqueIdLength];
-  memset(uniqueId, 0, KMaxUniqueIdLength);
-
-  if (mInitDone) {
-    mViECapture->GetCaptureDevice(
-      mCapIndex, deviceName, KMaxDeviceNameLength, uniqueId, KMaxUniqueIdLength
-    );
-    aUUID.Assign(NS_ConvertASCIItoUTF16(uniqueId));
-  }
+  // mUniqueId is UTF8
+  CopyUTF8toUTF16(mUniqueId, aUUID);
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Allocate()
 {
   if (mState != kReleased) {
     return NS_ERROR_FAILURE;
   }
 
-  char deviceName[KMaxDeviceNameLength];
-  memset(deviceName, 0, KMaxDeviceNameLength);
-
-  char uniqueId[KMaxUniqueIdLength];
-  memset(uniqueId, 0, KMaxUniqueIdLength);
+  if (!mCapabilityChosen) {
+    // XXX these should come from constraints
+    ChooseCapability(mWidth, mHeight, mMinFps);
+  }
 
-  mViECapture->GetCaptureDevice(
-    mCapIndex, deviceName, KMaxDeviceNameLength, uniqueId, KMaxUniqueIdLength
-  );
-
-  if (mViECapture->AllocateCaptureDevice(uniqueId, KMaxUniqueIdLength, mCapIndex)) {
+  if (mViECapture->AllocateCaptureDevice(mUniqueId, KMaxUniqueIdLength, mCaptureIndex)) {
     return NS_ERROR_FAILURE;
   }
 
-  if (mViECapture->StartCapture(mCapIndex) < 0) {
+  if (mViECapture->StartCapture(mCaptureIndex, mCapability) < 0) {
     return NS_ERROR_FAILURE;
   }
 
   mState = kAllocated;
   return NS_OK;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Deallocate()
 {
   if (mState != kStopped && mState != kAllocated) {
     return NS_ERROR_FAILURE;
   }
 
-  mViECapture->StopCapture(mCapIndex);
-  mViECapture->ReleaseCaptureDevice(mCapIndex);
+  mViECapture->StopCapture(mCaptureIndex);
+  mViECapture->ReleaseCaptureDevice(mCaptureIndex);
   mState = kReleased;
   return NS_OK;
 }
 
-MediaEngineVideoOptions
+const MediaEngineVideoOptions*
 MediaEngineWebRTCVideoSource::GetOptions()
 {
-  MediaEngineVideoOptions aOpts;
-  aOpts.mWidth = mWidth;
-  aOpts.mHeight = mHeight;
-  aOpts.mMaxFPS = mFps;
-  aOpts.codecType = kVideoCodecI420;
-  return aOpts;
+  if (!mCapabilityChosen) {
+    ChooseCapability(mWidth, mHeight, mMinFps);
+  }
+  return &mOpts;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
 {
   int error = 0;
   if (!mInitDone || mState != kAllocated) {
     return NS_ERROR_FAILURE;
@@ -185,22 +231,22 @@ MediaEngineWebRTCVideoSource::Start(Sour
 
   mSource = aStream;
   mTrackID = aID;
 
   mImageContainer = layers::LayerManager::CreateImageContainer();
   mSource->AddTrack(aID, mFps, 0, new VideoSegment());
   mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
-  error = mViERender->AddRenderer(mCapIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
+  error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
   if (error == -1) {
     return NS_ERROR_FAILURE;
   }
 
-  error = mViERender->StartRender(mCapIndex);
+  error = mViERender->StartRender(mCaptureIndex);
   if (error == -1) {
     return NS_ERROR_FAILURE;
   }
 
   mState = kStarted;
   return NS_OK;
 }
 
@@ -209,18 +255,18 @@ MediaEngineWebRTCVideoSource::Stop()
 {
   if (mState != kStarted) {
     return NS_ERROR_FAILURE;
   }
 
   mSource->EndTrack(mTrackID);
   mSource->Finish();
 
-  mViERender->StopRender(mCapIndex);
-  mViERender->RemoveRenderer(mCapIndex);
+  mViERender->StopRender(mCaptureIndex);
+  mViERender->RemoveRenderer(mCaptureIndex);
 
   mState = kStopped;
   return NS_OK;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
 {
@@ -251,21 +297,21 @@ MediaEngineWebRTCVideoSource::Snapshot(u
   PR_Lock(mSnapshotLock);
   mInSnapshotMode = true;
 
   // Start the rendering (equivalent to calling Start(), but without a track).
   int error = 0;
   if (!mInitDone || mState != kAllocated) {
     return NS_ERROR_FAILURE;
   }
-  error = mViERender->AddRenderer(mCapIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
+  error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
   if (error == -1) {
     return NS_ERROR_FAILURE;
   }
-  error = mViERender->StartRender(mCapIndex);
+  error = mViERender->StartRender(mCaptureIndex);
   if (error == -1) {
     return NS_ERROR_FAILURE;
   }
 
   // Wait for the condition variable, will be set in DeliverFrame.
   // We use a while loop, because even if PR_WaitCondVar returns, it's not
   // guaranteed that the condition variable changed.
   while (mInSnapshotMode) {
@@ -286,25 +332,25 @@ MediaEngineWebRTCVideoSource::Snapshot(u
   // See Run() in MediaEngineWebRTCVideo.h (sets mSnapshotPath).
   NS_DispatchToMainThread(this, NS_DISPATCH_SYNC);
 
   if (!mSnapshotPath) {
     return NS_ERROR_FAILURE;
   }
 
   NS_ConvertUTF16toUTF8 path(*mSnapshotPath);
-  if (vieFile->GetCaptureDeviceSnapshot(mCapIndex, path.get()) < 0) {
+  if (vieFile->GetCaptureDeviceSnapshot(mCaptureIndex, path.get()) < 0) {
     delete mSnapshotPath;
     mSnapshotPath = NULL;
     return NS_ERROR_FAILURE;
   }
 
   // Stop the camera.
-  mViERender->StopRender(mCapIndex);
-  mViERender->RemoveRenderer(mCapIndex);
+  mViERender->StopRender(mCaptureIndex);
+  mViERender->RemoveRenderer(mCaptureIndex);
 
   nsCOMPtr<nsIFile> file;
   nsresult rv = NS_NewLocalFile(*mSnapshotPath, false, getter_AddRefs(file));
 
   delete mSnapshotPath;
   mSnapshotPath = NULL;
 
   NS_ENSURE_SUCCESS(rv, rv);
@@ -317,16 +363,19 @@ MediaEngineWebRTCVideoSource::Snapshot(u
 /**
  * Initialization and Shutdown functions for the video source, called by the
  * constructor and destructor respectively.
  */
 
 void
 MediaEngineWebRTCVideoSource::Init()
 {
+  mDeviceName[0] = '\0'; // paranoia
+  mUniqueId[0] = '\0';
+
   if (mVideoEngine == NULL) {
     return;
   }
 
   mViEBase = webrtc::ViEBase::GetInterface(mVideoEngine);
   if (mViEBase == NULL) {
     return;
   }
@@ -334,37 +383,43 @@ MediaEngineWebRTCVideoSource::Init()
   // Get interfaces for capture, render for now
   mViECapture = webrtc::ViECapture::GetInterface(mVideoEngine);
   mViERender = webrtc::ViERender::GetInterface(mVideoEngine);
 
   if (mViECapture == NULL || mViERender == NULL) {
     return;
   }
 
+  if (mViECapture->GetCaptureDevice(mCaptureIndex,
+                                    mDeviceName, sizeof(mDeviceName),
+                                    mUniqueId, sizeof(mUniqueId))) {
+    return;
+  }
+
   mInitDone = true;
 }
 
 void
 MediaEngineWebRTCVideoSource::Shutdown()
 {
   bool continueShutdown = false;
 
   if (!mInitDone) {
     return;
   }
 
   if (mState == kStarted) {
-    mViERender->StopRender(mCapIndex);
-    mViERender->RemoveRenderer(mCapIndex);
+    mViERender->StopRender(mCaptureIndex);
+    mViERender->RemoveRenderer(mCaptureIndex);
     continueShutdown = true;
   }
 
   if (mState == kAllocated || continueShutdown) {
-    mViECapture->StopCapture(mCapIndex);
-    mViECapture->ReleaseCaptureDevice(mCapIndex);
+    mViECapture->StopCapture(mCaptureIndex);
+    mViECapture->ReleaseCaptureDevice(mCaptureIndex);
     continueShutdown = false;
   }
 
   mViECapture->Release();
   mViERender->Release();
   mViEBase->Release();
   mState = kReleased;
   mInitDone = false;
--- a/layout/media/Makefile.in
+++ b/layout/media/Makefile.in
@@ -109,22 +109,26 @@ SHARED_LIBRARY_LIBS 	+= \
 	$(DEPTH)/gfx/angle/$(LIB_PREFIX)angle.$(LIB_SUFFIX) \
 	$(DEPTH)/parser/expat/lib/$(LIB_PREFIX)mozexpat_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 SHARED_LIBRARY_LIBS 	+= \
 	$(DEPTH)/gfx/2d/$(LIB_PREFIX)gfx2d.$(LIB_SUFFIX) \
 	$(NULL)
 
-ifdef MOZ_WEBRTC
-include $(topsrcdir)/media/webrtc/shared_libs.mk
+ifdef MOZ_ENABLE_SKIA
+SHARED_LIBRARY_LIBS += $(MOZ_SKIA_LIBS)
 endif
 
-ifdef MOZ_ENABLE_SKIA
-SHARED_LIBRARY_LIBS += $(MOZ_SKIA_LIBS)
+ifdef MOZ_WEBRTC
+ifndef MOZ_WEBRTC_IN_LIBXUL
+DEFINES += -DMOZ_WEBRTC_GKMEDIA=1
+include $(topsrcdir)/media/webrtc/shared_libs.mk
+SHARED_LIBRARY_LIBS += $(WEBRTC_LIBS)
+endif
 endif
 
 ifeq (WINNT,$(OS_TARGET))
 EXTRA_DSO_LDOPTS = $(MOZALLOC_LIB) $(NSPR_LIBS)
 OS_LIBS += $(call EXPAND_LIBNAME,usp10 ole32)
 
 ifdef MOZ_WEBRTC
 EXTRA_DSO_LDOPTS += \
@@ -134,16 +138,22 @@ OS_LIBS += $(call EXPAND_LIBNAME,secur32
 ifdef _MSC_VER
 OS_LIBS += $(call EXPAND_LIBNAME,delayimp)
 EXTRA_DSO_LDOPTS += \
   -DELAYLOAD:msdmo.dll \
   $(NULL)
 endif
 endif
 
+ifdef MOZ_WEBRTC
+EXTRA_DSO_LDOPTS += \
+  -LIBPATH:"$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)" \
+  $(NULL)
+OS_LIBS += $(call EXPAND_LIBNAME,secur32 crypt32 iphlpapi strmiids dmoguids wmcodecdspuuid amstrmid msdmo wininet)
+endif
 DEFFILE = symbols.def
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 ifeq (WINNT,$(OS_TARGET))
 symbols.def: symbols.def.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(ACDEFINES) $< > $@
--- a/layout/media/symbols.def.in
+++ b/layout/media/symbols.def.in
@@ -29,16 +29,25 @@ nestegg_tstamp_scale
 #ifndef MOZ_NATIVE_LIBVPX
 vpx_codec_control_
 vpx_codec_dec_init_ver
 vpx_codec_decode
 vpx_codec_destroy
 vpx_codec_get_frame
 vpx_codec_peek_stream_info
 vpx_codec_vp8_dx
+vpx_img_free
+vpx_codec_enc_config_set
+vpx_codec_enc_init_ver
+vpx_codec_vp8_cx
+vpx_img_set_rect
+vpx_codec_get_cx_data
+vpx_codec_enc_config_default
+vpx_img_alloc
+vpx_codec_encode
 #endif
 #endif
 #ifdef MOZ_VORBIS
 ogg_page_bos
 ogg_page_granulepos
 ogg_page_serialno
 ogg_stream_check
 ogg_stream_clear
@@ -137,26 +146,31 @@ opus_decode
 opus_decode_float
 opus_multistream_decoder_create
 opus_multistream_decoder_ctl
 opus_multistream_decoder_destroy
 opus_multistream_decode_float
 opus_multistream_decode
 opus_packet_get_nb_frames
 opus_packet_get_samples_per_frame
+opus_encoder_create
+opus_encoder_destroy
+opus_encoder_ctl
+opus_encode
+opus_encode_float
 #endif
 ShInitialize
 ShFinalize
 ShGetObjectCode
 ShDestruct
 ShGetInfoLog
 ShCompile
 ShGetInfo
 ShConstructCompiler
-#ifdef MOZ_WEBRTC
+#ifdef MOZ_WEBRTC_GKMEDIA
 #ifdef HAVE_64BIT_OS
 ?GetInterface@ViERender@webrtc@@SAPEAV12@PEAVVideoEngine@2@@Z
 ?GetInterface@ViECapture@webrtc@@SAPEAV12@PEAVVideoEngine@2@@Z
 ?GetInterface@ViEBase@webrtc@@SAPEAV12@PEAVVideoEngine@2@@Z
 ?Create@VideoEngine@webrtc@@SAPEAV12@XZ
 ?Delete@VideoEngine@webrtc@@SA_NAEAPEAV12@@Z
 #else
 ?GetInterface@ViERender@webrtc@@SAPAV12@PAVVideoEngine@2@@Z
@@ -238,16 +252,21 @@ jpeg_resync_to_restart
 jpeg_save_markers
 jpeg_set_defaults
 jpeg_set_quality
 jpeg_start_compress
 jpeg_start_decompress
 jpeg_start_output
 jpeg_std_error
 jpeg_write_scanlines
+jpeg_write_raw_data
+jpeg_stdio_dest
+jpeg_abort
+jpeg_abort_decompress
+jpeg_read_raw_data
 #endif
 qcms_enable_iccv4
 qcms_profile_create_rgb_with_gamma
 qcms_profile_from_memory
 qcms_profile_from_path
 qcms_profile_from_unicode_path
 qcms_profile_get_color_space
 qcms_profile_get_rendering_intent
--- a/media/webrtc/shared_libs.mk
+++ b/media/webrtc/shared_libs.mk
@@ -1,45 +1,57 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # shared libs for webrtc
-SHARED_LIBRARY_LIBS += \
+WEBRTC_LIBS = \
   $(call EXPAND_LIBNAME_PATH,video_capture_module,$(DEPTH)/media/webrtc/trunk/src/modules/modules_video_capture_module) \
   $(call EXPAND_LIBNAME_PATH,webrtc_utility,$(DEPTH)/media/webrtc/trunk/src/modules/modules_webrtc_utility) \
   $(call EXPAND_LIBNAME_PATH,audio_coding_module,$(DEPTH)/media/webrtc/trunk/src/modules/modules_audio_coding_module) \
   $(call EXPAND_LIBNAME_PATH,CNG,$(DEPTH)/media/webrtc/trunk/src/modules/modules_CNG) \
   $(call EXPAND_LIBNAME_PATH,signal_processing,$(DEPTH)/media/webrtc/trunk/src/common_audio/common_audio_signal_processing) \
   $(call EXPAND_LIBNAME_PATH,G711,$(DEPTH)/media/webrtc/trunk/src/modules/modules_G711) \
-  $(call EXPAND_LIBNAME_PATH,G722,$(DEPTH)/media/webrtc/trunk/src/modules/modules_G722) \
-  $(call EXPAND_LIBNAME_PATH,iLBC,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iLBC) \
-  $(call EXPAND_LIBNAME_PATH,iSAC,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iSAC) \
-  $(call EXPAND_LIBNAME_PATH,iSACFix,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iSACFix) \
+  $(call EXPAND_LIBNAME_PATH,opus,$(DEPTH)/media/webrtc/trunk/src/modules/modules_opus) \
   $(call EXPAND_LIBNAME_PATH,PCM16B,$(DEPTH)/media/webrtc/trunk/src/modules/modules_PCM16B) \
   $(call EXPAND_LIBNAME_PATH,NetEq,$(DEPTH)/media/webrtc/trunk/src/modules/modules_NetEq) \
   $(call EXPAND_LIBNAME_PATH,resampler,$(DEPTH)/media/webrtc/trunk/src/common_audio/common_audio_resampler) \
   $(call EXPAND_LIBNAME_PATH,vad,$(DEPTH)/media/webrtc/trunk/src/common_audio/common_audio_vad) \
   $(call EXPAND_LIBNAME_PATH,system_wrappers,$(DEPTH)/media/webrtc/trunk/src/system_wrappers/source/system_wrappers_system_wrappers) \
   $(call EXPAND_LIBNAME_PATH,webrtc_video_coding,$(DEPTH)/media/webrtc/trunk/src/modules/modules_webrtc_video_coding) \
   $(call EXPAND_LIBNAME_PATH,webrtc_i420,$(DEPTH)/media/webrtc/trunk/src/modules/modules_webrtc_i420) \
-  $(call EXPAND_LIBNAME_PATH,webrtc_vp8,$(DEPTH)/media/webrtc/trunk/src/modules/modules_webrtc_vp8) \
+  $(call EXPAND_LIBNAME_PATH,webrtc_vp8,$(DEPTH)/media/webrtc/trunk/src/modules/video_coding/codecs/vp8/vp8_webrtc_vp8) \
   $(call EXPAND_LIBNAME_PATH,webrtc_libyuv,$(DEPTH)/media/webrtc/trunk/src/common_video/common_video_webrtc_libyuv) \
   $(call EXPAND_LIBNAME_PATH,video_render_module,$(DEPTH)/media/webrtc/trunk/src/modules/modules_video_render_module) \
   $(call EXPAND_LIBNAME_PATH,video_engine_core,$(DEPTH)/media/webrtc/trunk/src/video_engine/video_engine_video_engine_core) \
   $(call EXPAND_LIBNAME_PATH,media_file,$(DEPTH)/media/webrtc/trunk/src/modules/modules_media_file) \
   $(call EXPAND_LIBNAME_PATH,rtp_rtcp,$(DEPTH)/media/webrtc/trunk/src/modules/modules_rtp_rtcp) \
   $(call EXPAND_LIBNAME_PATH,udp_transport,$(DEPTH)/media/webrtc/trunk/src/modules/modules_udp_transport) \
+  $(call EXPAND_LIBNAME_PATH,bitrate_controller,$(DEPTH)/media/webrtc/trunk/src/modules/modules_bitrate_controller) \
+  $(call EXPAND_LIBNAME_PATH,remote_bitrate_estimator,$(DEPTH)/media/webrtc/trunk/src/modules/modules_remote_bitrate_estimator) \
   $(call EXPAND_LIBNAME_PATH,video_processing,$(DEPTH)/media/webrtc/trunk/src/modules/modules_video_processing) \
   $(call EXPAND_LIBNAME_PATH,video_processing_sse2,$(DEPTH)/media/webrtc/trunk/src/modules/modules_video_processing_sse2) \
   $(call EXPAND_LIBNAME_PATH,voice_engine_core,$(DEPTH)/media/webrtc/trunk/src/voice_engine/voice_engine_voice_engine_core) \
   $(call EXPAND_LIBNAME_PATH,audio_conference_mixer,$(DEPTH)/media/webrtc/trunk/src/modules/modules_audio_conference_mixer) \
   $(call EXPAND_LIBNAME_PATH,audio_device,$(DEPTH)/media/webrtc/trunk/src/modules/modules_audio_device) \
   $(call EXPAND_LIBNAME_PATH,audio_processing,$(DEPTH)/media/webrtc/trunk/src/modules/modules_audio_processing) \
   $(call EXPAND_LIBNAME_PATH,aec,$(DEPTH)/media/webrtc/trunk/src/modules/modules_aec) \
   $(call EXPAND_LIBNAME_PATH,aec_sse2,$(DEPTH)/media/webrtc/trunk/src/modules/modules_aec_sse2) \
   $(call EXPAND_LIBNAME_PATH,apm_util,$(DEPTH)/media/webrtc/trunk/src/modules/modules_apm_util) \
   $(call EXPAND_LIBNAME_PATH,aecm,$(DEPTH)/media/webrtc/trunk/src/modules/modules_aecm) \
   $(call EXPAND_LIBNAME_PATH,agc,$(DEPTH)/media/webrtc/trunk/src/modules/modules_agc) \
   $(call EXPAND_LIBNAME_PATH,ns,$(DEPTH)/media/webrtc/trunk/src/modules/modules_ns) \
   $(call EXPAND_LIBNAME_PATH,yuv,$(DEPTH)/media/webrtc/trunk/third_party/libyuv/libyuv_libyuv) \
   $(call EXPAND_LIBNAME_PATH,webrtc_jpeg,$(DEPTH)/media/webrtc/trunk/src/common_video/common_video_webrtc_jpeg) \
   $(NULL)
+
+# If you enable one of these codecs in webrtc_config.gypi, you'll need to re-add the
+# relevant library from this list:
+#
+#  $(call EXPAND_LIBNAME_PATH,G722,$(DEPTH)/media/webrtc/trunk/src/modules/modules_G722) \
+#  $(call EXPAND_LIBNAME_PATH,iLBC,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iLBC) \
+#  $(call EXPAND_LIBNAME_PATH,iSAC,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iSAC) \
+#  $(call EXPAND_LIBNAME_PATH,iSACFix,$(DEPTH)/media/webrtc/trunk/src/modules/modules_iSACFix) \
+#
+
+#  $(call EXPAND_LIBNAME_PATH,nicer,$(DEPTH)/media/mtransport/third_party/nICEr/nicer_nicer) \
+#  $(call EXPAND_LIBNAME_PATH,nrappkit,$(DEPTH)/media/mtransport/third_party/nrappkit/nrappkit_nrappkit) \
+#
--- a/media/webrtc/trunk/src/modules/modules.gyp
+++ b/media/webrtc/trunk/src/modules/modules.gyp
@@ -46,34 +46,34 @@
     }],
     ['codec_ilbc_enable!=0', {
       'includes': [
         'audio_coding/codecs/ilbc/ilbc.gypi',
       ],
     }],
     ['codec_isac_enable!=0', {
       'includes': [
-        'audio_coding/codecs/isac/main/source/isac.gypi',
-        'audio_coding/codecs/isac/fix/source/isacfix.gypi',
+#        'audio_coding/codecs/isac/main/source/isac.gypi',
+#        'audio_coding/codecs/isac/fix/source/isacfix.gypi',
       ],
     }],
     ['codec_opus_enable!=0', {
       'includes': [
         'audio_coding/codecs/opus/opus.gypi',
       ],
     }],
     ['codec_pcm16b_enable!=0', {
       'includes': [
         'audio_coding/codecs/pcm16b/pcm16b.gypi',
       ],
     }],
     ['include_tests==1', {
       'includes': [
-        'audio_coding/codecs/isac/isac_test.gypi',
-        'audio_coding/codecs/isac/isacfix_test.gypi',
+#        'audio_coding/codecs/isac/isac_test.gypi',
+#        'audio_coding/codecs/isac/isacfix_test.gypi',
         'audio_processing/apm_tests.gypi',
         'rtp_rtcp/source/rtp_rtcp_tests.gypi',
         'rtp_rtcp/test/testFec/test_fec.gypi',
         'rtp_rtcp/test/testAPI/test_api.gypi',
         'video_coding/main/source/video_coding_test.gypi',
         'video_coding/codecs/test/video_codecs_test_framework.gypi',
         'video_coding/codecs/tools/video_codecs_tools.gypi',
         'video_processing/main/test/vpm_tests.gypi',
new file mode 100644
--- /dev/null
+++ b/media/webrtc/webrtc-config.mk
@@ -0,0 +1,51 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla platform.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+ifndef INCLUDED_CONFIG_MK
+$(error Must include config.mk before this file.)
+endif
+
+ifdef WEBRTC_CONFIG_INCLUDED
+$(error Must not include webrtc-config.mk twice.)
+endif
+
+WEBRTC_CONFIG_INCLUDED = 1
+
+EXTRA_DEPS += $(topsrcdir)/media/webrtc/webrtc-config.mk
+
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/media/webrtc/trunk/src \
+  $(NULL)
new file mode 100644
--- /dev/null
+++ b/media/webrtc/webrtc_config.gypi
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# definitions to control what gets built in webrtc
+{
+  'variables': {
+    # basic stuff for everything
+    'include_internal_video_render': 0,
+    'clang_use_chrome_plugins': 0,
+    'enable_protobuf': 0,
+    'include_pulse_audio': 0,
+    'include_tests': 0,
+    'use_system_libjpeg': 1,
+    'use_system_libvpx': 1,
+
+    # codec enable/disables:
+    # Note: if you change one here, you must modify shared_libs.mk!
+    'codec_g711_enable': 1,
+    'codec_opus_enable': 1,
+    'codec_g722_enable': 0,
+    'codec_ilbc_enable': 0,
+    'codec_isac_enable': 0,
+    'codec_pcm16b_enable': 1,
+  }
+}
new file mode 100644
--- /dev/null
+++ b/media/webrtc/webrtc_update.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# First, get a new copy of the tree to play with
+# They both want to be named 'trunk'...
+#cd media/webrtc
+mkdir webrtc_update
+cd webrtc_update
+
+# Note: must be in trunk; won't work with --name (error during sync)
+gclient config --name trunk http://webrtc.googlecode.com/svn/trunk/peerconnection
+gclient sync --force
+if [ $2 ] ; then
+    sed -i -e "s/\"webrtc_revision\":.*,/\"webrtc_revision\": \"$1\",/" -e "s/\"libjingle_revision\":.*,/\"libjingle_revision\": \"$2\",/" trunk/DEPS
+    gclient sync --force
+fi
+
+cd trunk
+
+export date=`date`
+export revision=`svnversion -n`
+if [ $1 ] ; then
+  echo "WebRTC revision overridden from $revision to $1" 
+  export revision=$1
+else
+  echo "WebRTC revision = $revision"
+fi
+
+cd ../../media/webrtc
+
+# safety - make it easy to find our way out of the forest
+hg tag -f -l old-tip
+
+# Ok, now we have a copy of the source.  See what changed
+# (webrtc-import-last is a bookmark)
+# FIX! verify no changes in webrtc!
+hg update --clean webrtc-import-last
+
+rm -rf trunk
+mv ../../webrtc_update/trunk trunk
+mv -f ../../webrtc_update/.g* .
+rmdir ../../webrtc_update
+(hg addremove --exclude "**webrtcsessionobserver.h" --exclude "**webrtcjson.h" --exclude "**.svn" --exclude "**.git" --exclude "**.pyc" --exclude "**.yuv" --similarity 70 --dry-run trunk; hg status -m; echo "************* Please look at the filenames found by rename and see if they match!!! ***********" ) | less
+
+# FIX! Query user about add-removes better!!
+echo "Waiting 30 seconds - Hit ^C now to stop addremove and commit!"
+sleep 30  # let them ^C
+
+# Add/remove files, detect renames
+hg addremove --exclude "**webrtcsessionobserver.h" --exclude "**webrtcjson.h" --exclude "**.svn" --exclude "**.git" --exclude "**.pyc" --exclude "**.yuv" --similarity 70 trunk
+hg status -a -r >/tmp/changed_webrtc_files
+
+# leave this for the user for now until we're comfortable it works safely
+
+# Commit the vendor branch
+echo "Commit, merge and push to server - cut and paste"
+echo "You probably want to do these from another shell so you can look at these"
+hg commit -m "Webrtc import $revision"
+# webrtc-import-last is auto-updated (bookmark)
+
+echo ""
+hg update --clean webrtc-pending
+hg merge -r webrtc-import-last
+hg commit -m 'merge latest import to pending, $revision'
+# webrtc-pending is auto-updated (bookmark)
+
+echo ""
+hg update --clean webrtc-trim
+hg merge -r webrtc-pending
+hg commit -m "merge latest import to trim, $revision"
+# webrtc-trim is auto-updated (bookmark)
+
+# commands to pull - never do more than echo them for the user
+echo ""
+echo "Here's how to pull this update into the mozilla repo:"
+echo "cd your_tree"
+echo "hg qpop -a"
+echo "hg pull --bookmark webrtc-trim path-to-webrtc-import-repo"
+echo "hg merge"
+echo "echo '#define WEBRTC_SVNVERSION $revision' >media/webrtc/webrtc_version.h"
+echo "echo '#define WEBRTC_PULL_DATE \"$date\"' >>media/webrtc/webrtc_version.h"
+echo "hg commit -m 'Webrtc updated to $revision; pull made on $date'"
+echo ""
+echo "Please check for added/removed/moved .gyp/.gypi files, and if so update EXTRA_CONFIG_DEPS in client.mk!"
+echo "possible gyp* file changes:"
+grep gyp /tmp/changed_webrtc_files
+echo ""
+echo "Once you feel safe:"
+echo "hg push"
--- a/media/webrtc/webrtc_version.h
+++ b/media/webrtc/webrtc_version.h
@@ -1,2 +1,3 @@
-#define WEBRTC_SVNVERSION 2047
-#define WEBRTC_PULL_DATE "Thu Apr 26 17:54:33 EDT 2012"
+#define WEBRTC_SVNVERSION 2820
+#define WEBRTC_PULL_DATE "Mon Sep 24 22:53:49 EDT 2012"
+
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -375,16 +375,40 @@ EXTRA_DSO_LDOPTS += $(MOZ_LIBVPX_LIBS)
 endif
 
 ifndef MOZ_TREE_PIXMAN
 EXTRA_DSO_LDOPTS += $(MOZ_PIXMAN_LIBS)
 endif
 
 EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib)
 
+ifdef MOZ_WEBRTC
+ifdef MOZ_PEERCONNECTION
+COMPONENT_LIBS += peerconnection
+endif
+ifdef MOZ_WEBRTC_SIGNALING
+EXTRA_DSO_LDOPTS += \
+  $(DEPTH)/media/mtransport/build/$(LIB_PREFIX)mtransport.$(LIB_SUFFIX) \
+  $(DEPTH)/media/webrtc/signaling/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \
+  $(DEPTH)/media/webrtc/signaling/signaling_sipcc/$(LIB_PREFIX)sipcc.$(LIB_SUFFIX) \
+  $(NULL)
+endif
+ifdef MOZ_WEBRTC_IN_LIBXUL
+include $(topsrcdir)/media/webrtc/shared_libs.mk
+EXTRA_DSO_LDOPTS += $(WEBRTC_LIBS)
+ifeq (WINNT,$(OS_TARGET))
+EXTRA_DSO_LDOPTS += \
+  -LIBPATH:"$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)" \
+  $(NULL)
+OS_LIBS += $(call EXPAND_LIBNAME,secur32 crypt32 iphlpapi strmiids dmoguids wmcodecdspuuid amstrmid msdmo wininet)
+endif
+endif
+endif
+
+
 ifdef MOZ_SYDNEYAUDIO
 ifeq ($(OS_ARCH),Linux)
 EXTRA_DSO_LDOPTS += $(MOZ_ALSA_LIBS)
 endif
 endif
 
 ifdef MOZ_PULSEAUDIO
 ifdef MOZ_CUBEB