Bug 1376873 - Updates to dom/media/, dom/media/systemservices and dom/media/webrtc; r=pehrsons
☠☠ backed out by 63f135d2db22 ☠ ☠
authorDan Minor <dminor@mozilla.com>
Tue, 20 Feb 2018 15:23:09 -0500
changeset 444241 19d9a30b300c4653088bffa1598c26f6f16c427d
parent 444240 6a52b92ff03731a1e2ef13aa7f7349a1e7e48bee
child 444242 909f472c2e402f81a8326e93e839666d2aba1fc5
push id34986
push usershindli@mozilla.com
push dateSat, 03 Nov 2018 09:44:53 +0000
treeherdermozilla-central@ef27c14b46bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1376873
milestone65.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 1376873 - Updates to dom/media/, dom/media/systemservices and dom/media/webrtc; r=pehrsons Differential Revision: https://phabricator.services.mozilla.com/D7438
dom/media/MediaManager.cpp
dom/media/moz.build
dom/media/systemservices/CamerasChild.cpp
dom/media/systemservices/CamerasParent.cpp
dom/media/systemservices/PCameras.ipdl
dom/media/systemservices/VideoEngine.cpp
dom/media/systemservices/VideoFrameUtils.cpp
dom/media/webrtc/MediaEnginePrefs.h
dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
dom/media/webrtc/MediaEngineWebRTC.cpp
dom/media/webrtc/MediaEngineWebRTCAudio.cpp
dom/media/webrtc/MediaEngineWebRTCAudio.h
dom/media/webrtc/moz.build
modules/libpref/init/all.js
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -72,16 +72,17 @@
 #include "nss.h"
 #include "pk11pub.h"
 
 /* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
 #include "MediaEngineDefault.h"
 #if defined(MOZ_WEBRTC)
 #include "MediaEngineWebRTC.h"
 #include "browser_logging/WebRtcLog.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
 #endif
 
 #if defined (XP_WIN)
 #include "mozilla/WindowsVersion.h"
 #include <objbase.h>
 #include <winsock2.h>
 #include <iphlpapi.h>
 #include <tchar.h>
@@ -2145,25 +2146,26 @@ MediaManager::EnumerateRawDevices(uint64
 MediaManager::MediaManager()
   : mMediaThread(nullptr)
   , mBackend(nullptr) {
   mPrefs.mFreq         = 1000; // 1KHz test tone
   mPrefs.mWidth        = 0; // adaptive default
   mPrefs.mHeight       = 0; // adaptive default
   mPrefs.mFPS          = MediaEnginePrefs::DEFAULT_VIDEO_FPS;
   mPrefs.mAecOn        = false;
+  mPrefs.mUseAecMobile = false;
   mPrefs.mAgcOn        = false;
   mPrefs.mNoiseOn      = false;
   mPrefs.mExtendedFilter = true;
   mPrefs.mDelayAgnostic = true;
   mPrefs.mFakeDeviceChangeEventOn = false;
 #ifdef MOZ_WEBRTC
-  mPrefs.mAec          = webrtc::kEcUnchanged;
-  mPrefs.mAgc          = webrtc::kAgcUnchanged;
-  mPrefs.mNoise        = webrtc::kNsUnchanged;
+  mPrefs.mAec          = webrtc::EchoCancellation::SuppressionLevel::kModerateSuppression;
+  mPrefs.mAgc          = webrtc::GainControl::Mode::kAdaptiveDigital;
+  mPrefs.mNoise        = webrtc::NoiseSuppression::Level::kModerate;
 #else
   mPrefs.mAec          = 0;
   mPrefs.mAgc          = 0;
   mPrefs.mNoise        = 0;
 #endif
   mPrefs.mFullDuplex = false;
   mPrefs.mChannels     = 0; // max channels default
   nsresult rv;
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -327,16 +327,17 @@ LOCAL_INCLUDES += [
     '/media/libyuv/libyuv/include',
     '/netwerk/base',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
     LOCAL_INCLUDES += [
         '/media/webrtc/signaling/src/common',
         '/media/webrtc/trunk',
+        '/media/webrtc/trunk/webrtc',
     ]
 
 DEFINES['MOZILLA_INTERNAL_API'] = True
 DEFINES['TRACING'] = True
 
 if CONFIG['MOZ_ANDROID_HLS_SUPPORT']:
     DEFINES['MOZ_ANDROID_HLS_SUPPORT'] = True
 
--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -374,19 +374,17 @@ CamerasChild::RecvReplyGetCaptureCapabil
 {
   LOG((__PRETTY_FUNCTION__));
   MonitorAutoLock monitor(mReplyMonitor);
   mReceivedReply = true;
   mReplySuccess = true;
   mReplyCapability.width = ipcCapability.width();
   mReplyCapability.height = ipcCapability.height();
   mReplyCapability.maxFPS = ipcCapability.maxFPS();
-  mReplyCapability.expectedCaptureDelay = ipcCapability.expectedCaptureDelay();
-  mReplyCapability.rawType = static_cast<webrtc::RawVideoType>(ipcCapability.rawType());
-  mReplyCapability.codecType = static_cast<webrtc::VideoCodecType>(ipcCapability.codecType());
+  mReplyCapability.videoType = static_cast<webrtc::VideoType>(ipcCapability.videoType());
   mReplyCapability.interlaced = ipcCapability.interlaced();
   monitor.Notify();
   return IPC_OK();
 }
 
 int
 CamerasChild::GetCaptureDevice(CaptureEngine aCapEngine,
                                unsigned int list_number, char* device_nameUTF8,
@@ -516,22 +514,20 @@ int
 CamerasChild::StartCapture(CaptureEngine aCapEngine,
                            const int capture_id,
                            webrtc::VideoCaptureCapability& webrtcCaps,
                            FrameRelay* cb)
 {
   LOG((__PRETTY_FUNCTION__));
   AddCallback(aCapEngine, capture_id, cb);
   VideoCaptureCapability capCap(webrtcCaps.width,
-                           webrtcCaps.height,
-                           webrtcCaps.maxFPS,
-                           webrtcCaps.expectedCaptureDelay,
-                           webrtcCaps.rawType,
-                           webrtcCaps.codecType,
-                           webrtcCaps.interlaced);
+                                webrtcCaps.height,
+                                webrtcCaps.maxFPS,
+                                static_cast<int>(webrtcCaps.videoType),
+                                webrtcCaps.interlaced);
   nsCOMPtr<nsIRunnable> runnable = mozilla::
     NewRunnableMethod<CaptureEngine, int, VideoCaptureCapability>(
       "camera::PCamerasChild::SendStartCapture",
       this,
       &CamerasChild::SendStartCapture,
       aCapEngine,
       capture_id,
       capCap);
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -620,27 +620,24 @@ CamerasParent::RecvGetCaptureCapability(
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
           if (!self->mChildIsAlive) {
             return NS_ERROR_FAILURE;
           }
           VideoCaptureCapability capCap(webrtcCaps.width,
                                    webrtcCaps.height,
                                    webrtcCaps.maxFPS,
-                                   webrtcCaps.expectedCaptureDelay,
-                                   webrtcCaps.rawType,
-                                   webrtcCaps.codecType,
+                                   static_cast<int>(webrtcCaps.videoType),
                                    webrtcCaps.interlaced);
-          LOG(("Capability: %u %u %u %u %d %d",
+          LOG(("Capability: %u %u %u %d %d",
                webrtcCaps.width,
                webrtcCaps.height,
                webrtcCaps.maxFPS,
-               webrtcCaps.expectedCaptureDelay,
-               webrtcCaps.rawType,
-               webrtcCaps.codecType));
+               static_cast<int>(webrtcCaps.videoType),
+               webrtcCaps.interlaced));
           if (error) {
             Unused << self->SendReplyFailure();
             return NS_ERROR_FAILURE;
           }
           Unused << self->SendReplyGetCaptureCapability(capCap);
           return NS_OK;
         });
       self->mPBackgroundEventTarget->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
@@ -877,19 +874,17 @@ CamerasParent::RecvStartCapture(const Ca
 
         self->sEngines[aCapEngine]->WithEntry(capnum,
           [&capnum, &aCapEngine, &error, &ipcCaps, &cbh, self]
           (VideoEngine::CaptureEntry& cap) {
           webrtc::VideoCaptureCapability capability;
           capability.width = ipcCaps.width();
           capability.height = ipcCaps.height();
           capability.maxFPS = ipcCaps.maxFPS();
-          capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
-          capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
-          capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
+          capability.videoType = static_cast<webrtc::VideoType>(ipcCaps.videoType());
           capability.interlaced = ipcCaps.interlaced();
 
           MOZ_DIAGNOSTIC_ASSERT(sDeviceUniqueIDs.find(capnum) ==
                                 sDeviceUniqueIDs.end());
           sDeviceUniqueIDs.emplace(capnum, cap.VideoCapture()->CurrentDeviceName());
 
           MOZ_DIAGNOSTIC_ASSERT(sAllRequestedCapabilities.find(capnum) ==
                                 sAllRequestedCapabilities.end());
@@ -910,17 +905,17 @@ CamerasParent::RecvStartCapture(const Ca
             auto candidateCapabilities = self->mAllCandidateCapabilities.find(
               nsCString(cap.VideoCapture()->CurrentDeviceName()));
             if ((candidateCapabilities != self->mAllCandidateCapabilities.end()) &&
                 (!candidateCapabilities->second.empty())) {
               int32_t minIdx = -1;
               uint64_t minDistance = UINT64_MAX;
 
               for (auto & candidateCapability : candidateCapabilities->second) {
-                if (candidateCapability.second.rawType != capability.rawType) {
+                if (candidateCapability.second.videoType != capability.videoType) {
                   continue;
                 }
                 // The first priority is finding a suitable resolution.
                 // So here we raise the weight of width and height
                 uint64_t distance =
                   uint64_t(ResolutionFeasibilityDistance(
                     candidateCapability.second.width, capability.width)) +
                   uint64_t(ResolutionFeasibilityDistance(
--- a/dom/media/systemservices/PCameras.ipdl
+++ b/dom/media/systemservices/PCameras.ipdl
@@ -13,19 +13,17 @@ namespace mozilla {
 namespace camera {
 
 // IPC analog for webrtc::VideoCaptureCapability
 struct VideoCaptureCapability
 {
   int width;
   int height;
   int maxFPS;
-  int expectedCaptureDelay;
-  int rawType;
-  int codecType;
+  int videoType;
   bool interlaced;
 };
 
 
 // IPC analog for webrtc::VideoFrame
 // the described buffer is transported seperately in a Shmem
 // See VideoFrameUtils.h
 struct VideoFrameProperties
--- a/dom/media/systemservices/VideoEngine.cpp
+++ b/dom/media/systemservices/VideoEngine.cpp
@@ -61,16 +61,17 @@ VideoEngine::CreateVideoCapture(int32_t&
     }
   }
 
   CaptureEntry entry = {-1, nullptr};
 
   if (mCaptureDevInfo.type == webrtc::CaptureDeviceType::Camera) {
     entry = CaptureEntry(id,
 		         webrtc::VideoCaptureFactory::Create(deviceUniqueIdUTF8));
+    entry.VideoCapture()->SetApplyRotation(true);
   } else {
 #ifndef WEBRTC_ANDROID
 #ifdef MOZ_X11
     webrtc::VideoCaptureModule* captureModule;
     auto type = mCaptureDevInfo.type;
     nsresult result = NS_DispatchToMainThread(media::NewRunnableFrom(
       [&captureModule, id, deviceUniqueIdUTF8, type]() -> nsresult {
         captureModule = webrtc::DesktopCaptureImpl::Create(id, deviceUniqueIdUTF8, type);
--- a/dom/media/systemservices/VideoFrameUtils.cpp
+++ b/dom/media/systemservices/VideoFrameUtils.cpp
@@ -1,93 +1,91 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et ft=cpp : */
 /* 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/. */
 
 #include "VideoFrameUtils.h"
-#include "webrtc/video_frame.h"
+#include "webrtc/api/video/video_frame.h"
 #include "mozilla/ShmemPool.h"
 
 namespace mozilla {
 
 size_t
 VideoFrameUtils::TotalRequiredBufferSize(
                   const webrtc::VideoFrame& aVideoFrame)
 {
-  auto height = aVideoFrame.video_frame_buffer()->height();
-  return height * aVideoFrame.video_frame_buffer()->StrideY() +
-    ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideU() +
-    ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideV();
+  auto i420 = aVideoFrame.video_frame_buffer()->ToI420();
+  auto height = i420->height();
+  return height * i420->StrideY() + ((height+1)/2) * i420->StrideU() +
+         ((height+1)/2) * i420->StrideV();
 }
 
 void VideoFrameUtils::InitFrameBufferProperties(
                   const webrtc::VideoFrame& aVideoFrame,
                   camera::VideoFrameProperties& aDestProps)
 {
   // The VideoFrameBuffer image data stored in the accompanying buffer
   // the buffer is at least this size of larger.
   aDestProps.bufferSize() = TotalRequiredBufferSize(aVideoFrame);
 
   aDestProps.timeStamp() = aVideoFrame.timestamp();
   aDestProps.ntpTimeMs() = aVideoFrame.ntp_time_ms();
   aDestProps.renderTimeMs() = aVideoFrame.render_time_ms();
 
   aDestProps.rotation() = aVideoFrame.rotation();
 
-  auto height = aVideoFrame.video_frame_buffer()->height();
-  aDestProps.yAllocatedSize() = height * aVideoFrame.video_frame_buffer()->StrideY();
-  aDestProps.uAllocatedSize() = ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideU();
-  aDestProps.vAllocatedSize() = ((height+1)/2) * aVideoFrame.video_frame_buffer()->StrideV();
+  auto i420 = aVideoFrame.video_frame_buffer()->ToI420();
+  auto height = i420->height();
+  aDestProps.yAllocatedSize() = height * i420->StrideY();
+  aDestProps.uAllocatedSize() = ((height+1)/2) * i420->StrideU();
+  aDestProps.vAllocatedSize() = ((height+1)/2) * i420->StrideV();
 
-  aDestProps.width() = aVideoFrame.video_frame_buffer()->width();
+  aDestProps.width() = i420->width();
   aDestProps.height() = height;
 
-  aDestProps.yStride() = aVideoFrame.video_frame_buffer()->StrideY();
-  aDestProps.uStride() = aVideoFrame.video_frame_buffer()->StrideU();
-  aDestProps.vStride() = aVideoFrame.video_frame_buffer()->StrideV();
+  aDestProps.yStride() = i420->StrideY();
+  aDestProps.uStride() = i420->StrideU();
+  aDestProps.vStride() = i420->StrideV();
 }
 
 void VideoFrameUtils::CopyVideoFrameBuffers(uint8_t* aDestBuffer,
                        const size_t aDestBufferSize,
                        const webrtc::VideoFrame& aFrame)
 {
   size_t aggregateSize = TotalRequiredBufferSize(aFrame);
 
   MOZ_ASSERT(aDestBufferSize >= aggregateSize);
+  auto i420 = aFrame.video_frame_buffer()->ToI420();
 
   // If planes are ordered YUV and contiguous then do a single copy
-  if ((aFrame.video_frame_buffer()->DataY() != nullptr) &&
+  if ((i420->DataY() != nullptr) &&
       // Check that the three planes are ordered
-      (aFrame.video_frame_buffer()->DataY()
-       < aFrame.video_frame_buffer()->DataU()) &&
-      (aFrame.video_frame_buffer()->DataU()
-       < aFrame.video_frame_buffer()->DataV()) &&
+      (i420->DataY() < i420->DataU()) &&
+      (i420->DataU() < i420->DataV()) &&
       //  Check that the last plane ends at firstPlane[totalsize]
-      (&aFrame.video_frame_buffer()->DataY()[aggregateSize] ==
-       &aFrame.video_frame_buffer()
-          ->DataV()[((aFrame.video_frame_buffer()->height() + 1) / 2)
-                    * aFrame.video_frame_buffer()->StrideV()])) {
-    memcpy(aDestBuffer, aFrame.video_frame_buffer()->DataY(), aggregateSize);
+      (&i420->DataY()[aggregateSize] ==
+       &i420->DataV()[((i420->height() + 1) / 2) * i420->StrideV()])) {
+    memcpy(aDestBuffer, i420->DataY(), aggregateSize);
     return;
   }
 
   // Copy each plane
   size_t offset = 0;
   size_t size;
-  auto height = aFrame.video_frame_buffer()->height();
-  size = height * aFrame.video_frame_buffer()->StrideY();
-  memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataY(), size);
+  auto height = i420->height();
+  size = height * i420->StrideY();
+  memcpy(&aDestBuffer[offset], i420->DataY(), size);
   offset += size;
-  size = ((height+1)/2) * aFrame.video_frame_buffer()->StrideU();
-  memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataU(), size);
+  size = ((height+1)/2) * i420->StrideU();
+  memcpy(&aDestBuffer[offset], i420->DataU(), size);
   offset += size;
-  size = ((height+1)/2) * aFrame.video_frame_buffer()->StrideV();
-  memcpy(&aDestBuffer[offset], aFrame.video_frame_buffer()->DataV(), size);
+  size = ((height+1)/2) * i420->StrideV();
+  memcpy(&aDestBuffer[offset], i420->DataV(), size);
 }
 
 void VideoFrameUtils::CopyVideoFrameBuffers(ShmemBuffer& aDestShmem,
                         const webrtc::VideoFrame& aVideoFrame)
 {
   CopyVideoFrameBuffers(aDestShmem.Get().get<uint8_t>(), aDestShmem.Get().Size<uint8_t>(), aVideoFrame);
 }
 
--- a/dom/media/webrtc/MediaEnginePrefs.h
+++ b/dom/media/webrtc/MediaEnginePrefs.h
@@ -21,16 +21,17 @@ public:
   static const int DEFAULT_169_VIDEO_HEIGHT = 720;
 
   MediaEnginePrefs()
     : mWidth(0)
     , mHeight(0)
     , mFPS(0)
     , mFreq(0)
     , mAecOn(false)
+    , mUseAecMobile(false)
     , mAgcOn(false)
     , mNoiseOn(false)
     , mAec(0)
     , mAgc(0)
     , mNoise(0)
     , mFullDuplex(false)
     , mExtendedFilter(false)
     , mDelayAgnostic(false)
@@ -38,16 +39,17 @@ public:
     , mChannels(0)
   {}
 
   int32_t mWidth;
   int32_t mHeight;
   int32_t mFPS;
   int32_t mFreq; // for test tones (fake:true)
   bool mAecOn;
+  bool mUseAecMobile;
   bool mAgcOn;
   bool mNoiseOn;
   int32_t mAec;
   int32_t mAgc;
   int32_t mNoise;
   bool mFullDuplex;
   bool mExtendedFilter;
   bool mDelayAgnostic;
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -796,35 +796,16 @@ MediaEngineRemoteVideoSource::GetBestFit
   return candidateSet[0].mDistance;
 }
 
 static void
 LogCapability(const char* aHeader,
               const webrtc::CaptureCapability &aCapability,
               uint32_t aDistance)
 {
-  // RawVideoType and VideoCodecType media/webrtc/trunk/webrtc/common_types.h
-  static const char* const types[] = {
-    "I420",
-    "YV12",
-    "YUY2",
-    "UYVY",
-    "IYUV",
-    "ARGB",
-    "RGB24",
-    "RGB565",
-    "ARGB4444",
-    "ARGB1555",
-    "MJPEG",
-    "NV12",
-    "NV21",
-    "BGRA",
-    "Unknown type"
-  };
-
   static const char* const codec[] = {
     "VP8",
     "VP9",
     "H264",
     "I420",
     "RED",
     "ULPFEC",
     "Generic codec",
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -134,17 +134,18 @@ MediaEngineWebRTC::EnumerateVideoDevices
       if (mozilla::camera::GetChildAndCall(
             &mozilla::camera::CamerasChild::GetCaptureCapability,
             capEngine,
             uniqueId,
             j, cap) != 0) {
        break;
       }
       LOG(("type=%d width=%d height=%d maxFPS=%d",
-           cap.rawType, cap.width, cap.height, cap.maxFPS ));
+           static_cast<int>(cap.videoType), cap.width, cap.height,
+           cap.maxFPS ));
     }
 #endif
 
     if (uniqueId[0] == '\0') {
       // In case a device doesn't set uniqueId!
       strncpy(uniqueId, deviceName, sizeof(uniqueId));
       uniqueId[sizeof(uniqueId)-1] = '\0'; // strncpy isn't safe
     }
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -216,141 +216,149 @@ MediaEngineWebRTCMicrophoneSource::Pull(
 {
   // If pull is enabled, it means that the audio input is not open, and we
   // should fill it out with silence. This is the only method called on the
   // MSG thread.
   mInputProcessing->Pull(aStream, aTrackID, aDesiredTime, aPrincipalHandle);
 }
 
 void
-MediaEngineWebRTCMicrophoneSource::UpdateAECSettingsIfNeeded(
+MediaEngineWebRTCMicrophoneSource::UpdateAECSettings(
   bool aEnable,
-  webrtc::EcModes aMode)
+  bool aUseAecMobile,
+  EchoCancellation::SuppressionLevel aLevel)
 {
   AssertIsOnOwningThread();
 
   RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
   RefPtr<MediaStreamGraphImpl> gripGraph = mStream->GraphImpl();
   NS_DispatchToMainThread(media::NewRunnableFrom(
-    [that, graph = std::move(gripGraph), aEnable, aMode]() mutable {
+    [ that, graph = std::move(gripGraph), aEnable, aUseAecMobile,
+      aLevel ]() mutable {
       class Message : public ControlMessage
       {
       public:
         Message(AudioInputProcessing* aInputProcessing,
                 bool aEnable,
-                webrtc::EcModes aMode)
+                bool aUseAecMobile,
+                EchoCancellation::SuppressionLevel aLevel)
+          : ControlMessage(nullptr)
+          , mInputProcessing(aInputProcessing)
+          , mEnable(aEnable)
+          , mUseAecMobile(aUseAecMobile)
+          , mLevel(aLevel)
+        {
+        }
+
+        void Run() override
+        {
+          mInputProcessing->UpdateAECSettings(mEnable,
+                                              mUseAecMobile,
+                                              mLevel);
+        }
+
+      protected:
+        RefPtr<AudioInputProcessing> mInputProcessing;
+        bool mEnable;
+        bool mUseAecMobile;
+        EchoCancellation::SuppressionLevel mLevel;
+      };
+
+      if (graph) {
+        graph->AppendMessage(
+          MakeUnique<Message>(that->mInputProcessing, aEnable,
+                              aUseAecMobile, aLevel));
+      }
+
+      return NS_OK;
+    }));
+}
+
+void
+MediaEngineWebRTCMicrophoneSource::UpdateAGCSettings(
+  bool aEnable,
+  GainControl::Mode aMode)
+{
+  AssertIsOnOwningThread();
+
+  RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
+  RefPtr<MediaStreamGraphImpl> gripGraph = mStream->GraphImpl();
+  NS_DispatchToMainThread(media::NewRunnableFrom(
+    [ that, graph = std::move(gripGraph), aEnable, aMode ]() mutable {
+      class Message : public ControlMessage
+      {
+      public:
+        Message(AudioInputProcessing* aInputProcessing,
+                bool aEnable,
+                GainControl::Mode aMode)
           : ControlMessage(nullptr)
           , mInputProcessing(aInputProcessing)
           , mEnable(aEnable)
           , mMode(aMode)
         {
         }
 
         void Run() override
         {
-          mInputProcessing->UpdateAECSettingsIfNeeded(mEnable, mMode);
+          mInputProcessing->UpdateAGCSettings(mEnable, mMode);
         }
 
       protected:
         RefPtr<AudioInputProcessing> mInputProcessing;
         bool mEnable;
-        webrtc::EcModes mMode;
+        GainControl::Mode mMode;
       };
 
       if (graph) {
         graph->AppendMessage(
           MakeUnique<Message>(that->mInputProcessing, aEnable, aMode));
       }
 
       return NS_OK;
     }));
 }
 
 void
-MediaEngineWebRTCMicrophoneSource::UpdateAGCSettingsIfNeeded(
+MediaEngineWebRTCMicrophoneSource::UpdateNSSettings(
   bool aEnable,
-  webrtc::AgcModes aMode)
+  webrtc::NoiseSuppression::Level aLevel)
 {
   AssertIsOnOwningThread();
 
   RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
   RefPtr<MediaStreamGraphImpl> gripGraph = mStream->GraphImpl();
   NS_DispatchToMainThread(media::NewRunnableFrom(
-    [that, graph = std::move(gripGraph), aEnable, aMode]() mutable {
+    [ that, graph = std::move(gripGraph), aEnable, aLevel ]() mutable {
       class Message : public ControlMessage
       {
       public:
         Message(AudioInputProcessing* aInputProcessing,
                 bool aEnable,
-                webrtc::AgcModes aMode)
+                webrtc::NoiseSuppression::Level aLevel)
           : ControlMessage(nullptr)
           , mInputProcessing(aInputProcessing)
           , mEnable(aEnable)
-          , mMode(aMode)
+          , mLevel(aLevel)
         {
         }
 
         void Run() override
         {
-          mInputProcessing->UpdateAGCSettingsIfNeeded(mEnable, mMode);
+          mInputProcessing->UpdateNSSettings(mEnable, mLevel);
         }
 
       protected:
         RefPtr<AudioInputProcessing> mInputProcessing;
         bool mEnable;
-        webrtc::AgcModes mMode;
+        webrtc::NoiseSuppression::Level mLevel;
       };
 
       if (graph) {
         graph->AppendMessage(
-          MakeUnique<Message>(that->mInputProcessing, aEnable, aMode));
-      }
-
-      return NS_OK;
-    }));
-}
-
-void
-MediaEngineWebRTCMicrophoneSource::UpdateNSSettingsIfNeeded(
-  bool aEnable,
-  webrtc::NsModes aMode)
-{
-  AssertIsOnOwningThread();
-
-  RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
-  RefPtr<MediaStreamGraphImpl> gripGraph = mStream->GraphImpl();
-  NS_DispatchToMainThread(media::NewRunnableFrom(
-    [that, graph = std::move(gripGraph), aEnable, aMode]() mutable {
-      class Message : public ControlMessage
-      {
-      public:
-        Message(AudioInputProcessing* aInputProcessing,
-                bool aEnable,
-                webrtc::NsModes aMode)
-          : ControlMessage(nullptr)
-          , mInputProcessing(aInputProcessing)
-          , mEnable(aEnable)
-          , mMode(aMode)
-        {
-        }
-
-        void Run() override
-        {
-          mInputProcessing->UpdateNSSettingsIfNeeded(mEnable, mMode);
-        }
-
-      protected:
-        RefPtr<AudioInputProcessing> mInputProcessing;
-        bool mEnable;
-        webrtc::NsModes mMode;
-      };
-
-      if (graph) {
-        graph->AppendMessage(
-          MakeUnique<Message>(that->mInputProcessing, aEnable, aMode));
+          MakeUnique<Message>(that->mInputProcessing, aEnable, aLevel));
       }
 
       return NS_OK;
     }));
 }
 
 void
 MediaEngineWebRTCMicrophoneSource::UpdateAPMExtraOptions(bool aExtendedFilter,
@@ -403,21 +411,22 @@ MediaEngineWebRTCMicrophoneSource::Apply
 {
   AssertIsOnOwningThread();
 
   MOZ_ASSERT(
     mStream,
     "ApplySetting is to be called only after SetTrack has been called");
 
   if (mStream) {
-    UpdateAGCSettingsIfNeeded(aPrefs.mAgcOn,
-                              static_cast<AgcModes>(aPrefs.mAgc));
-    UpdateNSSettingsIfNeeded(aPrefs.mNoiseOn,
-                             static_cast<NsModes>(aPrefs.mNoise));
-    UpdateAECSettingsIfNeeded(aPrefs.mAecOn, static_cast<EcModes>(aPrefs.mAec));
+    UpdateAGCSettings(aPrefs.mAgcOn,
+                      static_cast<webrtc::GainControl::Mode>(aPrefs.mAgc));
+    UpdateNSSettings(aPrefs.mNoiseOn,
+                     static_cast<webrtc::NoiseSuppression::Level>(aPrefs.mNoise));
+    UpdateAECSettings(aPrefs.mAecOn, aPrefs.mUseAecMobile,
+                      static_cast<webrtc::EchoCancellation::SuppressionLevel>(aPrefs.mAec));
 
     UpdateAPMExtraOptions(mExtendedFilter, mDelayAgnostic);
   }
 
   RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
   RefPtr<MediaStreamGraphImpl> graphImpl = mStream->GraphImpl();
   NS_DispatchToMainThread(media::NewRunnableFrom(
     [that, graph = std::move(graphImpl), prefs = aPrefs]() mutable {
@@ -801,136 +810,89 @@ AudioInputProcessing::SetRequestedInputC
     int rv = fn;                                                               \
     if (rv != AudioProcessing::kNoError) {                                     \
       MOZ_ASSERT_UNREACHABLE("APM error in " #fn);                             \
       return;                                                                  \
     }                                                                          \
   } while (0);
 
 void
-AudioInputProcessing::UpdateAECSettingsIfNeeded(bool aEnable, EcModes aMode)
+AudioInputProcessing::UpdateAECSettings(bool aEnable,
+                                        bool aUseAecMobile,
+                                        EchoCancellation::SuppressionLevel aLevel)
 {
-  using webrtc::EcModes;
-
-  EchoCancellation::SuppressionLevel level;
+  if (aUseAecMobile) {
+    HANDLE_APM_ERROR(mAudioProcessing->echo_control_mobile()->Enable(aEnable));
+    HANDLE_APM_ERROR(mAudioProcessing->echo_cancellation()->Enable(false));
+  } else {
+    if (aLevel != EchoCancellation::SuppressionLevel::kLowSuppression &&
+        aLevel != EchoCancellation::SuppressionLevel::kModerateSuppression &&
+        aLevel != EchoCancellation::SuppressionLevel::kHighSuppression) {
 
-  switch (aMode) {
-    case EcModes::kEcUnchanged:
-      level = mAudioProcessing->echo_cancellation()->suppression_level();
-      break;
-    case EcModes::kEcConference:
-      level = EchoCancellation::kHighSuppression;
-      break;
-    case EcModes::kEcDefault:
-      level = EchoCancellation::kModerateSuppression;
-      break;
-    case EcModes::kEcAec:
-      level = EchoCancellation::kModerateSuppression;
-      break;
-    case EcModes::kEcAecm:
-      // No suppression level to set for the mobile echo canceller
-      break;
-    default:
-      MOZ_LOG(GetMediaManagerLog(), LogLevel::Error, ("Bad EcMode value"));
-      MOZ_ASSERT_UNREACHABLE("Bad pref set in all.js or in about:config"
-                             " for the echo cancelation mode.");
-      // fall back to something sensible in release
-      level = EchoCancellation::kModerateSuppression;
-      break;
-  }
+      MOZ_LOG(GetMediaManagerLog(),
+              LogLevel::Error,
+              ("Attempt to set invalid AEC suppression level %d",
+               static_cast<int>(aLevel)));
 
-  // AECm and AEC are mutually exclusive.
-  if (aMode == EcModes::kEcAecm) {
-    HANDLE_APM_ERROR(mAudioProcessing->echo_cancellation()->Enable(false));
-    HANDLE_APM_ERROR(mAudioProcessing->echo_control_mobile()->Enable(aEnable));
-  } else {
+      aLevel = EchoCancellation::SuppressionLevel::kModerateSuppression;
+    }
+
     HANDLE_APM_ERROR(mAudioProcessing->echo_control_mobile()->Enable(false));
     HANDLE_APM_ERROR(mAudioProcessing->echo_cancellation()->Enable(aEnable));
-    HANDLE_APM_ERROR(
-      mAudioProcessing->echo_cancellation()->set_suppression_level(level));
+    HANDLE_APM_ERROR(mAudioProcessing->echo_cancellation()->set_suppression_level(aLevel));
   }
 }
 
 void
-AudioInputProcessing::UpdateAGCSettingsIfNeeded(bool aEnable, AgcModes aMode)
+AudioInputProcessing::UpdateAGCSettings(bool aEnable,
+                                        GainControl::Mode aMode)
 {
+  if (aMode != GainControl::Mode::kAdaptiveAnalog &&
+      aMode != GainControl::Mode::kAdaptiveDigital &&
+      aMode != GainControl::Mode::kFixedDigital) {
+
+    MOZ_LOG(GetMediaManagerLog(),
+            LogLevel::Error,
+            ("Attempt to set invalid AGC mode %d", static_cast<int>(aMode)));
+
+    aMode = GainControl::Mode::kAdaptiveDigital;
+  }
+
 #if defined(WEBRTC_IOS) || defined(ATA) || defined(WEBRTC_ANDROID)
-  if (aMode == kAgcAdaptiveAnalog) {
+  if (aMode == GainControl::Mode::kAdaptiveAnalog) {
     MOZ_LOG(GetMediaManagerLog(),
             LogLevel::Error,
             ("Invalid AGC mode kAgcAdaptiveAnalog on mobile"));
     MOZ_ASSERT_UNREACHABLE("Bad pref set in all.js or in about:config"
                            " for the auto gain, on mobile.");
-    aMode = kAgcDefault;
+    aMode = GainControl::Mode::kDefaultAgcMode;
   }
 #endif
-  GainControl::Mode mode = kDefaultAgcMode;
-
-  switch (aMode) {
-    case AgcModes::kAgcDefault:
-      mode = kDefaultAgcMode;
-      break;
-    case AgcModes::kAgcUnchanged:
-      mode = mAudioProcessing->gain_control()->mode();
-      break;
-    case AgcModes::kAgcFixedDigital:
-      mode = GainControl::Mode::kFixedDigital;
-      break;
-    case AgcModes::kAgcAdaptiveAnalog:
-      mode = GainControl::Mode::kAdaptiveAnalog;
-      break;
-    case AgcModes::kAgcAdaptiveDigital:
-      mode = GainControl::Mode::kAdaptiveDigital;
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Bad pref set in all.js or in about:config"
-                             " for the auto gain.");
-      // This is a good fallback, it works regardless of the platform.
-      mode = GainControl::Mode::kAdaptiveDigital;
-      break;
-  }
-
-  HANDLE_APM_ERROR(mAudioProcessing->gain_control()->set_mode(mode));
+  HANDLE_APM_ERROR(mAudioProcessing->gain_control()->set_mode(aMode));
   HANDLE_APM_ERROR(mAudioProcessing->gain_control()->Enable(aEnable));
 }
 
 void
-AudioInputProcessing::UpdateNSSettingsIfNeeded(bool aEnable, NsModes aMode)
+AudioInputProcessing::UpdateNSSettings(bool aEnable,
+                                       webrtc::NoiseSuppression::Level aLevel)
 {
-  NoiseSuppression::Level nsLevel;
+  if (aLevel != NoiseSuppression::Level::kLow &&
+      aLevel != NoiseSuppression::Level::kModerate &&
+      aLevel != NoiseSuppression::Level::kHigh &&
+      aLevel != NoiseSuppression::Level::kVeryHigh) {
 
-  switch (aMode) {
-    case NsModes::kNsDefault:
-      nsLevel = kDefaultNsMode;
-      break;
-    case NsModes::kNsUnchanged:
-      nsLevel = mAudioProcessing->noise_suppression()->level();
-      break;
-    case NsModes::kNsConference:
-      nsLevel = NoiseSuppression::kHigh;
-      break;
-    case NsModes::kNsLowSuppression:
-      nsLevel = NoiseSuppression::kLow;
-      break;
-    case NsModes::kNsModerateSuppression:
-      nsLevel = NoiseSuppression::kModerate;
-      break;
-    case NsModes::kNsHighSuppression:
-      nsLevel = NoiseSuppression::kHigh;
-      break;
-    case NsModes::kNsVeryHighSuppression:
-      nsLevel = NoiseSuppression::kVeryHigh;
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Bad pref set in all.js or in about:config"
-                             " for the noise suppression.");
-      // Pick something sensible as a faillback in release.
-      nsLevel = NoiseSuppression::kModerate;
+    MOZ_LOG(GetMediaManagerLog(),
+            LogLevel::Error,
+            ("Attempt to set invalid noise suppression level %d",
+             static_cast<int>(aLevel)));
+
+      aLevel = NoiseSuppression::Level::kModerate;
   }
-  HANDLE_APM_ERROR(mAudioProcessing->noise_suppression()->set_level(nsLevel));
+
+  HANDLE_APM_ERROR(mAudioProcessing->noise_suppression()->set_level(aLevel));
   HANDLE_APM_ERROR(mAudioProcessing->noise_suppression()->Enable(aEnable));
 }
 
 #undef HANDLE_APM_ERROR
 
 void
 AudioInputProcessing::UpdateAPMExtraOptions(bool aExtendedFilter,
                                             bool aDelayAgnostic)
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.h
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.h
@@ -106,19 +106,20 @@ private:
    * From settings output by EvaluateSettings, send those settings to the
    * AudioInputProcessing instance and the main thread (for use in GetSettings).
    */
   void ApplySettings(const MediaEnginePrefs& aPrefs);
 
   /**
    * Sent the AudioProcessingModule parameter for a given processing algorithm.
    */
-  void UpdateAECSettingsIfNeeded(bool aEnable, webrtc::EcModes aMode);
-  void UpdateAGCSettingsIfNeeded(bool aEnable, webrtc::AgcModes aMode);
-  void UpdateNSSettingsIfNeeded(bool aEnable, webrtc::NsModes aMode);
+  void UpdateAECSettings(bool aEnable, bool aUseAecMobile,
+                         webrtc::EchoCancellation::SuppressionLevel aLevel);
+  void UpdateAGCSettings(bool aEnable, webrtc::GainControl::Mode aMode);
+  void UpdateNSSettings(bool aEnable, webrtc::NoiseSuppression::Level aLevel);
   void UpdateAPMExtraOptions(bool aExtendedFilter, bool aDelayAgnostic);
 
   TrackID mTrackID = TRACK_NONE;
   PrincipalHandle mPrincipal = PRINCIPAL_HANDLE_NONE;
 
   const RefPtr<AudioDeviceInfo> mDeviceInfo;
   const bool mDelayAgnostic;
   const bool mExtendedFilter;
@@ -196,19 +197,20 @@ public:
   uint32_t GetRequestedInputChannelCount(MediaStreamGraphImpl* aGraphImpl);
   void SetRequestedInputChannelCount(uint32_t aRequestedInputChannelCount);
   // This is true when all processing is disabled, we can skip
   // packetization, resampling and other processing passes.
   bool PassThrough(MediaStreamGraphImpl* aGraphImpl) const;
 
   // This allow changing the APM options, enabling or disabling processing
   // steps.
-  void UpdateAECSettingsIfNeeded(bool aEnable, webrtc::EcModes aMode);
-  void UpdateAGCSettingsIfNeeded(bool aEnable, webrtc::AgcModes aMode);
-  void UpdateNSSettingsIfNeeded(bool aEnable, webrtc::NsModes aMode);
+  void UpdateAECSettings(bool aEnable, bool aUseAecMobile,
+                         webrtc::EchoCancellation::SuppressionLevel aLevel);
+  void UpdateAGCSettings(bool aEnable, webrtc::GainControl::Mode aMode);
+  void UpdateNSSettings(bool aEnable, webrtc::NoiseSuppression::Level aLevel);
   void UpdateAPMExtraOptions(bool aExtendedFilter, bool aDelayAgnostic);
 
   void End();
 
 private:
   ~AudioInputProcessing() = default;
   RefPtr<SourceMediaStream> mStream;
   // This implements the processing algoritm to apply to the input (e.g. a
--- a/dom/media/webrtc/moz.build
+++ b/dom/media/webrtc/moz.build
@@ -40,17 +40,18 @@ if CONFIG['MOZ_WEBRTC']:
     ]
     LOCAL_INCLUDES += [
         '..',
         '/dom/base',
         '/dom/media',
         '/media/libyuv/libyuv/include',
         '/media/webrtc/signaling/src/common',
         '/media/webrtc/signaling/src/common/browser_logging',
-        '/media/webrtc/trunk'
+        '/media/webrtc/trunk',
+        '/media/webrtc/trunk/webrtc'
     ]
 
 XPIDL_SOURCES += [
     'nsITabSource.idl'
 ]
 
 UNIFIED_SOURCES += [
     'MediaEngineDefault.cpp',
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -446,21 +446,18 @@ pref("media.navigator.video.default_widt
 pref("media.navigator.video.default_height",0); // adaptive default
 pref("media.peerconnection.enabled", true);
 pref("media.peerconnection.video.enabled", true);
 pref("media.navigator.video.max_fs", 12288); // Enough for 2048x1536
 pref("media.navigator.video.max_fr", 60);
 pref("media.navigator.video.h264.level", 31); // 0x42E01f - level 3.1
 pref("media.navigator.video.h264.max_br", 0);
 pref("media.navigator.video.h264.max_mbps", 0);
-pref("media.navigator.mediadatadecoder_enabled", false);
-pref("media.navigator.mediadatadecoder_h264_enabled", false);
 pref("media.peerconnection.video.vp9_enabled", true);
 pref("media.peerconnection.video.vp9_preferred", false);
-pref("media.getusermedia.aec", 1);
 pref("media.getusermedia.browser.enabled", false);
 pref("media.getusermedia.channels", 0);
 #if defined(ANDROID)
 pref("media.getusermedia.camera.off_while_disabled.enabled", false);
 pref("media.getusermedia.microphone.off_while_disabled.enabled", false);
 #else
 pref("media.getusermedia.camera.off_while_disabled.enabled", true);
 pref("media.getusermedia.microphone.off_while_disabled.enabled", true);
@@ -489,32 +486,33 @@ pref("media.peerconnection.use_document_
 pref("media.peerconnection.identity.enabled", true);
 pref("media.peerconnection.identity.timeout", 10000);
 pref("media.peerconnection.ice.stun_client_maximum_transmits", 7);
 pref("media.peerconnection.ice.trickle_grace_period", 5000);
 pref("media.peerconnection.ice.no_host", false);
 pref("media.peerconnection.ice.default_address_only", false);
 pref("media.peerconnection.ice.proxy_only", false);
 pref("media.peerconnection.rtpsourcesapi.enabled", true);
-
-// These values (aec, agc, and noise) are from media/webrtc/trunk/webrtc/common_types.h
-// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
-// setting (for Xxx = Ec, Agc, or Ns).  Defaults are all set to kXxxDefault here.
 pref("media.peerconnection.turn.disable", false);
+
+// These values (aec, agc, and noise) are from:
+// media/webrtc/trunk/webrtc/modules/audio_processing/include/audio_processing.h
 #if defined(MOZ_WEBRTC_HARDWARE_AEC_NS)
 pref("media.getusermedia.aec_enabled", false);
 pref("media.getusermedia.noise_enabled", false);
 #else
 pref("media.getusermedia.aec_enabled", true);
 pref("media.getusermedia.noise_enabled", true);
 #endif
+pref("media.getusermedia.use_aec_mobile", false);
+pref("media.getusermedia.aec", 1); // kModerateSuppression
 pref("media.getusermedia.aec_extended_filter", true);
-pref("media.getusermedia.noise", 1);
-pref("media.getusermedia.agc_enabled", true);
-pref("media.getusermedia.agc", 3); // kAgcAdaptiveDigital
+pref("media.getusermedia.noise", 1); // kModerate
+pref("media.getusermedia.agc_enabled", false);
+pref("media.getusermedia.agc", 1); // kAdaptiveDigital
 // capture_delay: Adjustments for OS-specific input delay (lower bound)
 // playout_delay: Adjustments for OS-specific AudioStream+cubeb+output delay (lower bound)
 // full_duplex: enable cubeb full-duplex capture/playback
 pref("media.navigator.audio.full_duplex", true);
 #if defined(XP_MACOSX)
 pref("media.peerconnection.capture_delay", 50);
 #elif defined(XP_WIN)
 pref("media.peerconnection.capture_delay", 50);