Bug 1428392 - Remove AudioOutputObserver, and feed the reverse-stream directly to the AEC. r=pehrsons draft
authorPaul Adenot <paul@paul.cx>
Fri, 05 Jan 2018 18:10:23 +0100
changeset 717317 1dc9c3c3102fa83f30dcdc0b6434b97dd5b7298f
parent 716397 b9cb2d32cf2a5fdca584044202c1598b3abbe0a0
child 745210 14235312c73b25254f248e65c3eb9a33239d95b7
push id94626
push userpaul@paul.cx
push dateMon, 08 Jan 2018 16:33:59 +0000
reviewerspehrsons
bugs1428392
milestone59.0a1
Bug 1428392 - Remove AudioOutputObserver, and feed the reverse-stream directly to the AEC. r=pehrsons MozReview-Commit-ID: EVpH5LUOZ6g
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamGraphImpl.h
dom/media/TrackUnionStream.cpp
dom/media/webrtc/AudioOutputObserver.h
dom/media/webrtc/MediaEngineWebRTC.h
dom/media/webrtc/MediaEngineWebRTCAudio.cpp
dom/media/webrtc/moz.build
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -25,19 +25,16 @@
 #include "MediaStreamVideoSink.h"
 #include "mozilla/dom/BaseAudioContextBinding.h"
 #include "mozilla/media/MediaUtils.h"
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "VideoFrameContainer.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/Unused.h"
-#ifdef MOZ_WEBRTC
-#include "AudioOutputObserver.h"
-#endif
 #include "mtransport/runnable_utils.h"
 #include "VideoUtils.h"
 
 #include "webaudio/blink/DenormalDisabler.h"
 #include "webaudio/blink/HRTFDatabaseLoader.h"
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
@@ -3564,19 +3561,16 @@ MediaStreamGraphImpl::MediaStreamGraphIm
   , mDetectedNotRunning(false)
   , mPostedRunInStableState(false)
   , mRealtime(aDriverRequested != OFFLINE_THREAD_DRIVER)
   , mNonRealtimeProcessing(false)
   , mStreamOrderDirty(false)
   , mLatencyLog(AsyncLatencyLogger::Get())
   , mAbstractMainThread(aMainThread)
   , mThreadPool(GetMediaThreadPool(MediaThreadType::MSG_CONTROL))
-#ifdef MOZ_WEBRTC
-  , mFarendObserverRef(nullptr)
-#endif
   , mSelfRef(this)
   , mOutputChannels(std::min<uint32_t>(8, CubebUtils::MaxNumberOfChannels()))
 #ifdef DEBUG
   , mCanRunMessagesSynchronously(false)
 #endif
 {
   if (mRealtime) {
     if (aDriverRequested == AUDIO_THREAD_DRIVER) {
--- a/dom/media/MediaStreamGraphImpl.h
+++ b/dom/media/MediaStreamGraphImpl.h
@@ -27,19 +27,16 @@
 namespace mozilla {
 
 namespace media {
 class ShutdownTicket;
 }
 
 template <typename T>
 class LinkedList;
-#ifdef MOZ_WEBRTC
-class AudioOutputObserver;
-#endif
 
 /**
  * A per-stream update message passed from the media graph thread to the
  * main thread.
  */
 struct StreamUpdate
 {
   RefPtr<MediaStream> mStream;
@@ -813,19 +810,16 @@ public:
   bool mStreamOrderDirty;
   /**
    * Hold a ref to the Latency logger
    */
   RefPtr<AsyncLatencyLogger> mLatencyLog;
   AudioMixer mMixer;
   const RefPtr<AbstractThread> mAbstractMainThread;
   RefPtr<SharedThreadPool> mThreadPool;
-#ifdef MOZ_WEBRTC
-  RefPtr<AudioOutputObserver> mFarendObserverRef;
-#endif
 
   // used to limit graph shutdown time
   // Only accessed on the main thread.
   nsCOMPtr<nsITimer> mShutdownTimer;
 
 private:
   virtual ~MediaStreamGraphImpl();
 
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -1,9 +1,8 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* 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 "MediaStreamGraphImpl.h"
 #include "MediaStreamListener.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Unused.h"
@@ -24,19 +23,16 @@
 #include "AudioChannelService.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include "webaudio/MediaStreamAudioDestinationNode.h"
 #include <algorithm>
 #include "DOMMediaStream.h"
 #include "GeckoProfiler.h"
-#ifdef MOZ_WEBRTC
-#include "AudioOutputObserver.h"
-#endif
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 #ifdef STREAM_LOG
deleted file mode 100644
--- a/dom/media/webrtc/AudioOutputObserver.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* 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/. */
-
-#ifndef AUDIOOUTPUTOBSERVER_H_
-#define AUDIOOUTPUTOBSERVER_H_
-
-#include "mozilla/StaticPtr.h"
-#include "nsAutoPtr.h"
-#include "AudioMixer.h"
-#include "MediaData.h"
-
-namespace webrtc {
-class SingleRwFifo;
-}
-
-namespace mozilla {
-
-typedef struct FarEndAudioChunk_ {
-  size_t mSamples;
-  bool mOverrun;
-  AudioDataValue mData[1]; // variable-length
-} FarEndAudioChunk;
-
-// This class is used to packetize and send the mixed audio from an MSG, in
-// float, to the AEC module of WebRTC.org.
-class AudioOutputObserver
-{
-public:
-  AudioOutputObserver();
-
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioOutputObserver);
-
-  void Clear();
-  void InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aFrames, bool aOverran,
-                    int aFreq, int aChannels);
-  uint32_t PlayoutFrequency() { return mPlayoutFreq; }
-  uint32_t PlayoutChannels() { return mPlayoutChannels; }
-
-  FarEndAudioChunk *Pop();
-  uint32_t Size();
-
-private:
-  virtual ~AudioOutputObserver();
-  uint32_t mPlayoutFreq;
-  uint32_t mPlayoutChannels;
-
-  nsAutoPtr<webrtc::SingleRwFifo> mPlayoutFifo;
-  uint32_t mChunkSize;
-
-  // chunking to 10ms support
-  FarEndAudioChunk *mSaved; // can't be nsAutoPtr since we need to use free(), not delete
-  uint32_t mSamplesSaved;
-  AlignedAudioBuffer mDownmixBuffer;
-};
-
-extern StaticRefPtr<AudioOutputObserver> gFarendObserver;
-
-}
-
-#endif
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -54,17 +54,16 @@
 // Video Engine
 // conflicts with #include of scoped_ptr.h
 #undef FF
 
 // WebRTC imports
 #include "webrtc/modules/video_capture/video_capture_defines.h"
 
 #include "NullTransport.h"
-#include "AudioOutputObserver.h"
 
 namespace mozilla {
 
 class MediaEngineWebRTCAudioCaptureSource : public MediaEngineAudioSource
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
@@ -517,20 +516,20 @@ private:
 
   RefPtr<mozilla::AudioInput> mAudioInput;
   RefPtr<WebRTCAudioDataListener> mListener;
 
   // Note: shared across all microphone sources
   static int sChannelsOpen;
 
   const UniquePtr<webrtc::AudioProcessing> mAudioProcessing;
-  const RefPtr<AudioOutputObserver> mAudioOutputObserver;
 
-  // accessed from the GraphDriver thread except for deletion
+  // accessed from the GraphDriver thread except for deletion.
   nsAutoPtr<AudioPacketizer<AudioDataValue, float>> mPacketizerInput;
+  nsAutoPtr<AudioPacketizer<AudioDataValue, float>> mPacketizerOutput;
 
   // mMonitor protects mSources[] and mPrinicpalIds[] access/changes, and
   // transitions of mState from kStarted to kStopped (which are combined with
   // EndTrack()). mSources[] and mPrincipalHandles[] are accessed from webrtc
   // threads.
   Monitor mMonitor;
   nsTArray<RefPtr<SourceMediaStream>> mSources;
   nsTArray<PrincipalHandle> mPrincipalHandles; // Maps to mSources.
@@ -552,19 +551,22 @@ private:
   // because of prefs or constraints. This allows simply copying the audio into
   // the MSG, skipping resampling and the whole webrtc.org code.
   // This is read and written to only on the MSG thread.
   bool mSkipProcessing;
 
   // To only update microphone when needed, we keep track of previous settings.
   MediaEnginePrefs mLastPrefs;
 
+  // Stores the mixed audio output for the reverse-stream of the AEC.
+  AlignedFloatBuffer mOutputBuffer;
+
   AlignedFloatBuffer mInputBuffer;
   AlignedFloatBuffer mDeinterleavedBuffer;
-  AlignedAudioBuffer mInputDownmixBuffer;
+  AlignedFloatBuffer mInputDownmixBuffer;
 };
 
 class MediaEngineWebRTC : public MediaEngine
 {
   typedef MediaEngine Super;
 public:
   explicit MediaEngineWebRTC(MediaEnginePrefs& aPrefs);
 
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -1,8 +1,9 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* 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 "MediaEngineWebRTC.h"
 #include <stdio.h>
 #include <algorithm>
 #include "mozilla/Assertions.h"
@@ -48,155 +49,26 @@ LogModule* AudioLogModule() {
 /**
  * Webrtc microphone source source.
  */
 NS_IMPL_ISUPPORTS0(MediaEngineWebRTCMicrophoneSource)
 NS_IMPL_ISUPPORTS0(MediaEngineWebRTCAudioCaptureSource)
 
 int MediaEngineWebRTCMicrophoneSource::sChannelsOpen = 0;
 
-AudioOutputObserver::AudioOutputObserver()
-  : mPlayoutFreq(0)
-  , mPlayoutChannels(0)
-  , mChunkSize(0)
-  , mSaved(nullptr)
-  , mSamplesSaved(0)
-  , mDownmixBuffer(MAX_SAMPLING_FREQ * MAX_CHANNELS / 100)
-{
-  // Buffers of 10ms chunks
-  mPlayoutFifo = new SingleRwFifo(MAX_AEC_FIFO_DEPTH/10);
-}
-
-AudioOutputObserver::~AudioOutputObserver()
-{
-  Clear();
-  free(mSaved);
-  mSaved = nullptr;
-}
-
-void
-AudioOutputObserver::Clear()
-{
-  while (mPlayoutFifo->size() > 0) {
-    free(mPlayoutFifo->Pop());
-  }
-  // we'd like to touch mSaved here, but we can't if we might still be getting callbacks
-}
-
-FarEndAudioChunk *
-AudioOutputObserver::Pop()
-{
-  return (FarEndAudioChunk *) mPlayoutFifo->Pop();
-}
-
-uint32_t
-AudioOutputObserver::Size()
-{
-  return mPlayoutFifo->size();
-}
-
-// static
-void
-AudioOutputObserver::InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aFrames, bool aOverran,
-                                  int aFreq, int aChannels)
-{
-  // Prepare for downmix if needed
-  int channels = aChannels;
-  if (aChannels > MAX_CHANNELS) {
-    channels = MAX_CHANNELS;
-  }
-
-  if (mPlayoutChannels != 0) {
-    if (mPlayoutChannels != static_cast<uint32_t>(channels)) {
-      MOZ_CRASH();
-    }
-  } else {
-    MOZ_ASSERT(channels <= MAX_CHANNELS);
-    mPlayoutChannels = static_cast<uint32_t>(channels);
-  }
-  if (mPlayoutFreq != 0) {
-    if (mPlayoutFreq != static_cast<uint32_t>(aFreq)) {
-      MOZ_CRASH();
-    }
-  } else {
-    MOZ_ASSERT(aFreq <= MAX_SAMPLING_FREQ);
-    MOZ_ASSERT(!(aFreq % 100), "Sampling rate for far end data should be multiple of 100.");
-    mPlayoutFreq = aFreq;
-    mChunkSize = aFreq/100; // 10ms
-  }
-
-#ifdef LOG_FAREND_INSERTION
-  static FILE *fp = fopen("insertfarend.pcm","wb");
-#endif
-
-  if (mSaved) {
-    // flag overrun as soon as possible, and only once
-    mSaved->mOverrun = aOverran;
-    aOverran = false;
-  }
-  // Rechunk to 10ms.
-  // The AnalyzeReverseStream() and WebRtcAec_BufferFarend() functions insist on 10ms
-  // samples per call.  Annoying...
-  while (aFrames) {
-    if (!mSaved) {
-      mSaved = (FarEndAudioChunk *) moz_xmalloc(sizeof(FarEndAudioChunk) +
-                                                (mChunkSize * channels - 1)*sizeof(AudioDataValue));
-      mSaved->mSamples = mChunkSize;
-      mSaved->mOverrun = aOverran;
-      aOverran = false;
-    }
-    uint32_t to_copy = mChunkSize - mSamplesSaved;
-    if (to_copy > aFrames) {
-      to_copy = aFrames;
-    }
-
-    AudioDataValue* dest = &(mSaved->mData[mSamplesSaved * channels]);
-    if (aChannels > MAX_CHANNELS) {
-      AudioConverter converter(AudioConfig(aChannels, 0), AudioConfig(channels, 0));
-      converter.Process(mDownmixBuffer, aBuffer, to_copy);
-      ConvertAudioSamples(mDownmixBuffer.Data(), dest, to_copy * channels);
-    } else {
-      ConvertAudioSamples(aBuffer, dest, to_copy * channels);
-    }
-
-#ifdef LOG_FAREND_INSERTION
-    if (fp) {
-      fwrite(&(mSaved->mData[mSamplesSaved * aChannels]), to_copy * aChannels, sizeof(AudioDataValue), fp);
-    }
-#endif
-    aFrames -= to_copy;
-    mSamplesSaved += to_copy;
-    aBuffer += to_copy * aChannels;
-
-    if (mSamplesSaved >= mChunkSize) {
-      int free_slots = mPlayoutFifo->capacity() - mPlayoutFifo->size();
-      if (free_slots <= 0) {
-        // XXX We should flag an overrun for the reader.  We can't drop data from it due to
-        // thread safety issues.
-        break;
-      } else {
-        mPlayoutFifo->Push((int8_t *) mSaved); // takes ownership
-        mSaved = nullptr;
-        mSamplesSaved = 0;
-      }
-    }
-  }
-}
-
 MediaEngineWebRTCMicrophoneSource::MediaEngineWebRTCMicrophoneSource(
     mozilla::AudioInput* aAudioInput,
     int aIndex,
     const char* name,
     const char* uuid,
     bool aDelayAgnostic,
     bool aExtendedFilter)
   : MediaEngineAudioSource(kReleased)
   , mAudioInput(aAudioInput)
   , mAudioProcessing(AudioProcessing::Create())
-  , mAudioOutputObserver(new AudioOutputObserver())
   , mMonitor("WebRTCMic.Monitor")
   , mCapIndex(aIndex)
   , mDelayAgnostic(aDelayAgnostic)
   , mExtendedFilter(aExtendedFilter)
   , mTrackID(TRACK_NONE)
   , mStarted(false)
   , mSampleFrequency(MediaEngine::USE_GRAPH_RATE)
   , mTotalFrames(0)
@@ -628,18 +500,16 @@ MediaEngineWebRTCMicrophoneSource::Start
     return NS_OK;
   }
   mState = kStarted;
   mTrackID = aID;
 
   // Make sure logger starts before capture
   AsyncLatencyLogger::Get(true);
 
-  mAudioOutputObserver->Clear();
-
   mAudioInput->StartRecording(aStream, mListener);
 
   return NS_OK;
 }
 
 nsresult
 MediaEngineWebRTCMicrophoneSource::Stop(SourceMediaStream *aSource, TrackID aID)
 {
@@ -692,19 +562,98 @@ MediaEngineWebRTCMicrophoneSource::Notif
 
 void
 MediaEngineWebRTCMicrophoneSource::NotifyOutputData(MediaStreamGraph* aGraph,
                                                     AudioDataValue* aBuffer,
                                                     size_t aFrames,
                                                     TrackRate aRate,
                                                     uint32_t aChannels)
 {
-  if (!PassThrough()) {
-    mAudioOutputObserver->InsertFarEnd(aBuffer, aFrames, false,
-                                       aRate, aChannels);
+  if (!mPacketizerOutput ||
+      mPacketizerOutput->PacketSize() != aRate/100u ||
+      mPacketizerOutput->Channels() != aChannels) {
+    // It's ok to drop the audio still in the packetizer here: if this changes,
+    // we changed devices or something.
+    mPacketizerOutput =
+      new AudioPacketizer<AudioDataValue, float>(aRate/100, aChannels);
+  }
+
+  mPacketizerOutput->Input(aBuffer, aFrames);
+
+  while (mPacketizerOutput->PacketsAvailable()) {
+    uint32_t samplesPerPacket = mPacketizerOutput->PacketSize() *
+                                mPacketizerOutput->Channels();
+    if (mOutputBuffer.Length() < samplesPerPacket) {
+      mOutputBuffer.SetLength(samplesPerPacket);
+    }
+    if (mDeinterleavedBuffer.Length() < samplesPerPacket) {
+      mDeinterleavedBuffer.SetLength(samplesPerPacket);
+    }
+    float* packet = mOutputBuffer.Data();
+    mPacketizerOutput->Output(packet);
+
+    AutoTArray<float*, MAX_CHANNELS> deinterleavedPacketDataChannelPointers;
+    float* interleavedFarend = nullptr;
+    uint32_t channelCountFarend = 0;
+    uint32_t framesPerPacketFarend = 0;
+
+    // Downmix from aChannels to MAX_CHANNELS if needed. We always have floats
+    // here, the packetized performed the conversion.
+    if (aChannels > MAX_CHANNELS) {
+      AudioConverter converter(AudioConfig(aChannels, 0, AudioConfig::FORMAT_FLT),
+                               AudioConfig(MAX_CHANNELS, 0, AudioConfig::FORMAT_FLT));
+      framesPerPacketFarend = mPacketizerOutput->PacketSize();
+      framesPerPacketFarend =
+        converter.Process(mInputDownmixBuffer,
+                          packet,
+                          framesPerPacketFarend);
+      interleavedFarend = mInputDownmixBuffer.Data();
+      channelCountFarend = MAX_CHANNELS;
+      deinterleavedPacketDataChannelPointers.SetLength(MAX_CHANNELS);
+    } else {
+      interleavedFarend = packet;
+      channelCountFarend = aChannels;
+      framesPerPacketFarend = mPacketizerOutput->PacketSize();
+      deinterleavedPacketDataChannelPointers.SetLength(aChannels);
+    }
+
+    MOZ_ASSERT(interleavedFarend &&
+               (channelCountFarend == 1 || channelCountFarend == 2) &&
+               framesPerPacketFarend);
+
+    if (mInputBuffer.Length() < framesPerPacketFarend * channelCountFarend) {
+      mInputBuffer.SetLength(framesPerPacketFarend * channelCountFarend);
+    }
+
+    size_t offset = 0;
+    for (size_t i = 0; i < deinterleavedPacketDataChannelPointers.Length(); ++i) {
+      deinterleavedPacketDataChannelPointers[i] = mInputBuffer.Data() + offset;
+      offset += framesPerPacketFarend;
+    }
+
+    // Deinterleave, prepare a channel pointers array, with enough storage for
+    // the frames.
+    DeinterleaveAndConvertBuffer(interleavedFarend,
+                                 framesPerPacketFarend,
+                                 channelCountFarend,
+                                 deinterleavedPacketDataChannelPointers.Elements());
+
+    // Having the same config for input and output means we potentially save
+    // some CPU.
+    StreamConfig inputConfig(aRate, channelCountFarend, false);
+    StreamConfig outputConfig = inputConfig;
+
+    // Passing the same pointers here saves a copy inside this function.
+    DebugOnly<int> err =
+      mAudioProcessing->ProcessReverseStream(deinterleavedPacketDataChannelPointers.Elements(),
+                                             inputConfig,
+                                             outputConfig,
+                                             deinterleavedPacketDataChannelPointers.Elements());
+
+    MOZ_ASSERT(!err, "Could not process the reverse stream.");
   }
 }
 
 // Only called if we're not in passthrough mode
 void
 MediaEngineWebRTCMicrophoneSource::PacketizeAndProcess(MediaStreamGraph* aGraph,
                                                        const AudioDataValue* aBuffer,
                                                        size_t aFrames,
@@ -717,104 +666,21 @@ MediaEngineWebRTCMicrophoneSource::Packe
   if (!mPacketizerInput ||
       mPacketizerInput->PacketSize() != aRate/100u ||
       mPacketizerInput->Channels() != aChannels) {
     // It's ok to drop the audio still in the packetizer here.
     mPacketizerInput =
       new AudioPacketizer<AudioDataValue, float>(aRate/100, aChannels);
   }
 
-  // On initial capture, throw away all far-end data except the most recent sample
-  // since it's already irrelevant and we want to keep avoid confusing the AEC far-end
-  // input code with "old" audio.
+  // On initial capture, throw away all far-end data except the most recent
+  // sample since it's already irrelevant and we want to avoid confusing the AEC
+  // far-end input code with "old" audio.
   if (!mStarted) {
     mStarted  = true;
-    while (mAudioOutputObserver->Size() > 1) {
-      free(mAudioOutputObserver->Pop()); // only call if size() > 0
-    }
-  }
-
-  // Feed the far-end audio data (speakers) to the feedback input of the AEC.
-  while (mAudioOutputObserver->Size() > 0) {
-    // Bug 1414837: This will call `free()`, and we should remove it.
-    // Pop gives ownership.
-    nsAutoPtr<FarEndAudioChunk> buffer(mAudioOutputObserver->Pop()); // only call if size() > 0
-    if (!buffer) {
-      continue;
-    }
-    AudioDataValue* packetDataPointer = buffer->mData;
-    AutoTArray<float*, MAX_CHANNELS> deinterleavedPacketDataChannelPointers;
-    AudioDataValue* interleavedFarend = nullptr;
-    uint32_t channelCountFarend = 0;
-    uint32_t framesPerPacketFarend = 0;
-
-    // Downmix from aChannels to MAX_CHANNELS if needed
-    if (mAudioOutputObserver->PlayoutChannels() > MAX_CHANNELS) {
-      AudioConverter converter(AudioConfig(aChannels, 0, AudioConfig::FORMAT_DEFAULT),
-                               AudioConfig(MAX_CHANNELS, 0, AudioConfig::FORMAT_DEFAULT));
-      framesPerPacketFarend =
-        buffer->mSamples;
-      framesPerPacketFarend =
-        converter.Process(mInputDownmixBuffer,
-                          packetDataPointer,
-                          framesPerPacketFarend);
-      interleavedFarend = mInputDownmixBuffer.Data();
-      channelCountFarend = MAX_CHANNELS;
-      deinterleavedPacketDataChannelPointers.SetLength(MAX_CHANNELS);
-    } else {
-      uint32_t outputChannels = mAudioOutputObserver->PlayoutChannels();
-      interleavedFarend = packetDataPointer;
-      channelCountFarend = outputChannels;
-      framesPerPacketFarend = buffer->mSamples;
-      deinterleavedPacketDataChannelPointers.SetLength(outputChannels);
-    }
-
-    MOZ_ASSERT(interleavedFarend &&
-               (channelCountFarend == 1 || channelCountFarend == 2) &&
-               framesPerPacketFarend);
-
-    if (mInputBuffer.Length() < framesPerPacketFarend * channelCountFarend) {
-      mInputBuffer.SetLength(framesPerPacketFarend * channelCountFarend);
-    }
-
-    offset = 0;
-    for (size_t i = 0; i < deinterleavedPacketDataChannelPointers.Length(); ++i) {
-      deinterleavedPacketDataChannelPointers[i] = mInputBuffer.Data() + offset;
-      offset += framesPerPacketFarend;
-    }
-
-    // Deinterleave, prepare a channel pointers array, with enough storage for
-    // the frames.
-    //
-    // If this is a platform that uses s16 for audio input and output,
-    // convert to floats, the APM API we use only accepts floats.
-    DeinterleaveAndConvertBuffer(interleavedFarend,
-                                 framesPerPacketFarend,
-                                 channelCountFarend,
-                                 deinterleavedPacketDataChannelPointers.Elements());
-
-    // Having the same config for input and output means we potentially save
-    // some CPU.
-    StreamConfig inputConfig(mAudioOutputObserver->PlayoutFrequency(),
-                             channelCountFarend,
-                             false /* we don't use typing detection*/);
-    StreamConfig outputConfig = inputConfig;
-
-    // Passing the same pointers here saves a copy inside this function.
-    int err =
-      mAudioProcessing->ProcessReverseStream(deinterleavedPacketDataChannelPointers.Elements(),
-                                             inputConfig,
-                                             outputConfig,
-                                             deinterleavedPacketDataChannelPointers.Elements());
-
-    if (err) {
-      MOZ_LOG(GetMediaManagerLog(), LogLevel::Error,
-          ("error in audio ProcessReverseStream(): %d", err));
-      return;
-    }
   }
 
   // Packetize our input data into 10ms chunks, deinterleave into planar channel
   // buffers, process, and append to the right MediaStreamTrack.
   mPacketizerInput->Input(aBuffer, static_cast<uint32_t>(aFrames));
 
   while (mPacketizerInput->PacketsAvailable()) {
     uint32_t samplesPerPacket = mPacketizerInput->PacketSize() *
--- a/dom/media/webrtc/moz.build
+++ b/dom/media/webrtc/moz.build
@@ -17,18 +17,17 @@ EXPORTS += [
     'MediaEngine.h',
     'MediaEngineCameraVideoSource.h',
     'MediaEngineDefault.h',
     'MediaTrackConstraints.h',
     'SineWaveGenerator.h',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
-    EXPORTS += ['AudioOutputObserver.h',
-                'MediaEngineRemoteVideoSource.h',
+    EXPORTS += ['MediaEngineRemoteVideoSource.h',
                 'MediaEngineWebRTC.h']
     EXPORTS.mozilla.dom += [ 'RTCIdentityProviderRegistrar.h' ]
     UNIFIED_SOURCES += [
         'MediaEngineCameraVideoSource.cpp',
         'MediaEngineRemoteVideoSource.cpp',
         'MediaEngineTabVideoSource.cpp',
         'MediaEngineWebRTCAudio.cpp',
         'RTCCertificate.cpp',