Bug 1198588 - Remove unused MSG-specific code from AudioStream. r=padenot
authorMatthew Gregan <kinetik@flim.org>
Thu, 27 Aug 2015 14:49:17 +1200
changeset 292341 b12b9840d67b693c3227286ef34ff4eaa2e024c4
parent 292340 376965bcb1f7410398a187fcb9735e676bcb90d7
child 292342 e37f08a03a936f7c75341d3acc2357c5d8941553
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1198588
milestone43.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 1198588 - Remove unused MSG-specific code from AudioStream. r=padenot
dom/media/AudioStream.cpp
dom/media/AudioStream.h
dom/media/mediasink/DecodedAudioDataSink.cpp
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -10,22 +10,18 @@
 #include "prdtoa.h"
 #include "AudioStream.h"
 #include "VideoUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Snprintf.h"
 #include <algorithm>
 #include "mozilla/Telemetry.h"
-#include "Latency.h"
 #include "CubebUtils.h"
 #include "nsPrintfCString.h"
-#ifdef XP_MACOSX
-#include <sys/sysctl.h>
-#endif
 
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 PRLogModuleInfo* gAudioStreamLog = nullptr;
@@ -125,28 +121,21 @@ AudioStream::AudioStream()
   : mMonitor("AudioStream")
   , mInRate(0)
   , mOutRate(0)
   , mChannels(0)
   , mOutChannels(0)
   , mWritten(0)
   , mAudioClock(this)
   , mTimeStretcher(nullptr)
-  , mLatencyRequest(HighLatency)
-  , mReadPoint(0)
   , mDumpFile(nullptr)
   , mBytesPerFrame(0)
   , mState(INITIALIZED)
-  , mNeedsStart(false)
-  , mShouldDropFrames(false)
-  , mPendingAudioInitTask(false)
   , mLastGoodPosition(0)
 {
-  // keep a ref in case we shut down later than nsLayoutStatics
-  mLatencyLog = AsyncLatencyLogger::Get(true);
 }
 
 AudioStream::~AudioStream()
 {
   LOG(("AudioStream: delete %p, state %d", this, mState));
   MOZ_ASSERT(mState == SHUTDOWN && !mCubebStream,
              "Should've called Shutdown() before deleting an AudioStream");
   if (mDumpFile) {
@@ -159,20 +148,18 @@ AudioStream::~AudioStream()
 
 size_t
 AudioStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t amount = aMallocSizeOf(this);
 
   // Possibly add in the future:
   // - mTimeStretcher
-  // - mLatencyLog
   // - mCubebStream
 
-  amount += mInserts.ShallowSizeOfExcludingThis(aMallocSizeOf);
   amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf);
 
   return amount;
 }
 
 nsresult AudioStream::EnsureTimeStretcherInitializedUnlocked()
 {
   mMonitor.AssertCurrentThreadOwns();
@@ -314,36 +301,32 @@ WriteDumpFile(FILE* aDumpFile, AudioStre
   uint8_t* output = buf.Elements();
   for (uint32_t i = 0; i < samples; ++i) {
     SetUint16LE(output + i*2, int16_t(input[i]*32767.0f));
   }
   fwrite(output, 2, samples, aDumpFile);
   fflush(aDumpFile);
 }
 
-// NOTE: this must not block a LowLatency stream for any significant amount
-// of time, or it will block the entirety of MSG
 nsresult
 AudioStream::Init(int32_t aNumChannels, int32_t aRate,
-                  const dom::AudioChannel aAudioChannel,
-                  LatencyRequest aLatencyRequest)
+                  const dom::AudioChannel aAudioChannel)
 {
   mStartTime = TimeStamp::Now();
   mIsFirst = CubebUtils::GetFirstStream();
 
   if (!CubebUtils::GetCubebContext() || aNumChannels < 0 || aRate < 0) {
     return NS_ERROR_FAILURE;
   }
 
   MOZ_LOG(gAudioStreamLog, LogLevel::Debug,
     ("%s  channels: %d, rate: %d for %p", __FUNCTION__, aNumChannels, aRate, this));
   mInRate = mOutRate = aRate;
   mChannels = aNumChannels;
   mOutChannels = (aNumChannels > 2) ? 2 : aNumChannels;
-  mLatencyRequest = aLatencyRequest;
 
   mDumpFile = OpenDumpFile(this);
 
   cubeb_stream_params params;
   params.rate = aRate;
   params.channels = mOutChannels;
 #if defined(__ANDROID__)
 #if defined(MOZ_B2G)
@@ -369,239 +352,71 @@ AudioStream::Init(int32_t aNumChannels, 
 
   // Size mBuffer for one second of audio.  This value is arbitrary, and was
   // selected based on the observed behaviour of the existing AudioStream
   // implementations.
   uint32_t bufferLimit = FramesToBytes(aRate);
   MOZ_ASSERT(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
   mBuffer.SetCapacity(bufferLimit);
 
-  if (aLatencyRequest == LowLatency) {
-    // Don't block this thread to initialize a cubeb stream.
-    // When this is done, it will start callbacks from Cubeb.  Those will
-    // cause us to move from INITIALIZED to RUNNING.  Until then, we
-    // can't access any cubeb functions.
-    // Use a RefPtr to avoid leaks if Dispatch fails
-    mPendingAudioInitTask = true;
-    RefPtr<AudioInitTask> init = new AudioInitTask(this, aLatencyRequest, params);
-    nsresult rv = init->Dispatch();
-    if (NS_FAILED(rv)) {
-      mPendingAudioInitTask = false;
-    }
-    return rv;
-  }
-  // High latency - open synchronously
-  nsresult rv = OpenCubeb(params, aLatencyRequest);
-  NS_ENSURE_SUCCESS(rv, rv);
-  // See if we need to start() the stream, since we must do that from this
-  // thread for now (cubeb API issue)
-  {
-    MonitorAutoLock mon(mMonitor);
-    CheckForStart();
-  }
-  return NS_OK;
-}
-
-// On certain MacBookPro, the microphone is located near the left speaker.
-// We need to pan the sound output to the right speaker if we are using the mic
-// and the built-in speaker, or we will have terrible echo.
-void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive)
-{
-#ifdef XP_MACOSX
-  cubeb_device* device;
-  int rv;
-  char name[128];
-  size_t length = sizeof(name);
-  bool panCenter = false;
-
-  rv = sysctlbyname("hw.model", name, &length, NULL, 0);
-  if (rv) {
-    return;
-  }
-
-  if (!strncmp(name, "MacBookPro", 10)) {
-    if (cubeb_stream_get_current_device(mCubebStream.get(), &device) == CUBEB_OK) {
-      // Check if we are currently outputing sound on external speakers.
-      if (!strcmp(device->output_name, "ispk")) {
-        // Pan everything to the right speaker.
-        if (aMicrophoneActive) {
-          LOG(("%p Panning audio output to the right.", this));
-          if (cubeb_stream_set_panning(mCubebStream.get(), 1.0) != CUBEB_OK) {
-            NS_WARNING("Could not pan audio output to the right.");
-          }
-        } else {
-          panCenter = true;
-        }
-      } else {
-        panCenter = true;
-      }
-      if (panCenter) {
-        LOG(("%p Panning audio output to the center.", this));
-        if (cubeb_stream_set_panning(mCubebStream.get(), 0.0) != CUBEB_OK) {
-          NS_WARNING("Could not pan audio output to the center.");
-        }
-      }
-      cubeb_stream_device_destroy(mCubebStream.get(), device);
-    }
-  }
-#endif
-}
-
-void AudioStream::ResetStreamIfNeeded()
-{
-  cubeb_device * device;
-  // Only reset a device if a mic is active, and this is a low latency stream.
-  if (!mMicrophoneActive || mLatencyRequest != LowLatency) {
-    return;
-  }
-  if (cubeb_stream_get_current_device(mCubebStream.get(), &device) == CUBEB_OK) {
-    // This a microphone that goes through the headphone plug, reset the
-    // output to prevent echo building up.
-    if (strcmp(device->input_name, "emic") == 0) {
-      LOG(("Resetting audio output"));
-      Reset();
-    }
-    cubeb_stream_device_destroy(mCubebStream.get(), device);
-  }
-}
-
-void AudioStream::DeviceChangedCallback()
-{
-  MonitorAutoLock mon(mMonitor);
-  PanOutputIfNeeded(mMicrophoneActive);
-  mShouldDropFrames = true;
-  ResetStreamIfNeeded();
+  return OpenCubeb(params);
 }
 
 // This code used to live inside AudioStream::Init(), but on Mac (others?)
 // it has been known to take 300-800 (or even 8500) ms to execute(!)
 nsresult
-AudioStream::OpenCubeb(cubeb_stream_params &aParams,
-                       LatencyRequest aLatencyRequest)
+AudioStream::OpenCubeb(cubeb_stream_params &aParams)
 {
   cubeb* cubebContext = CubebUtils::GetCubebContext();
   if (!cubebContext) {
     NS_WARNING("Can't get cubeb context!");
     MonitorAutoLock mon(mMonitor);
     mState = AudioStream::ERRORED;
     return NS_ERROR_FAILURE;
   }
 
   // If the latency pref is set, use it. Otherwise, if this stream is intended
   // for low latency playback, try to get the lowest latency possible.
   // Otherwise, for normal streams, use 100ms.
-  uint32_t latency;
-  if (aLatencyRequest == LowLatency && !CubebUtils::CubebLatencyPrefSet()) {
-    if (cubeb_get_min_latency(cubebContext, aParams, &latency) != CUBEB_OK) {
-      latency = CubebUtils::GetCubebLatency();
-    }
-  } else {
-    latency = CubebUtils::GetCubebLatency();
-  }
+  uint32_t latency = CubebUtils::GetCubebLatency();
 
   {
     cubeb_stream* stream;
     if (cubeb_stream_init(cubebContext, &stream, "AudioStream", aParams,
                           latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
       MonitorAutoLock mon(mMonitor);
       MOZ_ASSERT(mState != SHUTDOWN);
       mCubebStream.reset(stream);
-      // We can't cubeb_stream_start() the thread from a transient thread due to
-      // cubeb API requirements (init can be called from another thread, but
-      // not start/stop/destroy/etc)
     } else {
       MonitorAutoLock mon(mMonitor);
       mState = ERRORED;
       NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
       return NS_ERROR_FAILURE;
     }
   }
 
-  cubeb_stream_register_device_changed_callback(mCubebStream.get(),
-                                                AudioStream::DeviceChangedCallback_s);
-
   mState = INITIALIZED;
 
   if (!mStartTime.IsNull()) {
     TimeDuration timeDelta = TimeStamp::Now() - mStartTime;
     LOG(("AudioStream creation time %sfirst: %u ms", mIsFirst ? "" : "not ",
           (uint32_t) timeDelta.ToMilliseconds()));
     Telemetry::Accumulate(mIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
         Telemetry::AUDIOSTREAM_LATER_OPEN_MS, timeDelta.ToMilliseconds());
   }
 
   return NS_OK;
 }
 
-void
-AudioStream::AudioInitTaskFinished()
-{
-  MonitorAutoLock mon(mMonitor);
-  mPendingAudioInitTask = false;
-  mon.NotifyAll();
-}
-
-void
-AudioStream::CheckForStart()
-{
-  mMonitor.AssertCurrentThreadOwns();
-  if (mState == INITIALIZED) {
-    // Start the stream right away when low latency has been requested. This means
-    // that the DataCallback will feed silence to cubeb, until the first frames
-    // are written to this AudioStream.  Also start if a start has been queued.
-    if (mLatencyRequest == LowLatency || mNeedsStart) {
-      StartUnlocked(); // mState = STARTED or ERRORED
-      mNeedsStart = false;
-      MOZ_LOG(gAudioStreamLog, LogLevel::Warning,
-             ("Started waiting %s-latency stream",
-              mLatencyRequest == LowLatency ? "low" : "high"));
-    } else {
-      // high latency, not full - OR Pause() was called before we got here
-      MOZ_LOG(gAudioStreamLog, LogLevel::Debug,
-             ("Not starting waiting %s-latency stream",
-              mLatencyRequest == LowLatency ? "low" : "high"));
-    }
-  }
-}
-
-NS_IMETHODIMP
-AudioInitTask::Run()
-{
-  MOZ_ASSERT(mThread);
-  if (NS_IsMainThread()) {
-    mThread->Shutdown(); // can't Shutdown from the thread itself, darn
-    // Don't null out mThread!
-    // See bug 999104.  We must hold a ref to the thread across Dispatch()
-    // since the internal mThread ref could be released while processing
-    // the Dispatch(), and Dispatch/PutEvent itself doesn't hold a ref; it
-    // assumes the caller does.
-    return NS_OK;
-  }
-
-  nsresult rv = mAudioStream->OpenCubeb(mParams, mLatencyRequest);
-  mAudioStream->AudioInitTaskFinished();
-
-  // and now kill this thread
-  NS_DispatchToMainThread(this);
-  return rv;
-}
-
 // aTime is the time in ms the samples were inserted into MediaStreamGraph
 nsresult
-AudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames, TimeStamp *aTime)
+AudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
 {
   MonitorAutoLock mon(mMonitor);
 
-  // See if we need to start() the stream, since we must do that from this thread
-  CheckForStart();
-
-  if (mShouldDropFrames) {
-    mBuffer.ContractTo(0);
-    return NS_OK;
-  }
   if (mState == ERRORED) {
     return NS_ERROR_FAILURE;
   }
   NS_ASSERTION(mState == INITIALIZED || mState == STARTED || mState == RUNNING,
     "Stream write in unexpected state.");
 
   // Downmix to Stereo.
   if (mChannels > 2 && mChannels <= 8) {
@@ -609,69 +424,39 @@ AudioStream::Write(const AudioDataValue*
   }
   else if (mChannels > 8) {
     return NS_ERROR_FAILURE;
   }
 
   const uint8_t* src = reinterpret_cast<const uint8_t*>(aBuf);
   uint32_t bytesToCopy = FramesToBytes(aFrames);
 
-  // XXX this will need to change if we want to enable this on-the-fly!
-  if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
-    // Record the position and time this data was inserted
-    int64_t timeMs;
-    if (aTime && !aTime->IsNull()) {
-      if (mStartTime.IsNull()) {
-        AsyncLatencyLogger::Get(true)->GetStartTime(mStartTime);
-      }
-      timeMs = (*aTime - mStartTime).ToMilliseconds();
-    } else {
-      timeMs = 0;
-    }
-    struct Inserts insert = { timeMs, aFrames};
-    mInserts.AppendElement(insert);
-  }
-
   while (bytesToCopy > 0) {
     uint32_t available = std::min(bytesToCopy, mBuffer.Available());
     MOZ_ASSERT(available % mBytesPerFrame == 0,
                "Must copy complete frames.");
 
     mBuffer.AppendElements(src, available);
     src += available;
     bytesToCopy -= available;
 
     if (bytesToCopy > 0) {
-      // Careful - the CubebInit thread may not have gotten to STARTED yet
-      if ((mState == INITIALIZED || mState == STARTED) && mLatencyRequest == LowLatency) {
-        // don't ever block MediaStreamGraph low-latency streams
-        uint32_t remains = 0; // we presume the buffer is full
-        if (mBuffer.Length() > bytesToCopy) {
-          remains = mBuffer.Length() - bytesToCopy; // Free up just enough space
-        }
-        // account for dropping samples
-        MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Stream %p dropping %u bytes (%u frames)in Write()",
-            this, mBuffer.Length() - remains, BytesToFrames(mBuffer.Length() - remains)));
-        mReadPoint += BytesToFrames(mBuffer.Length() - remains);
-        mBuffer.ContractTo(remains);
-      } else { // RUNNING or high latency
-        // If we are not playing, but our buffer is full, start playing to make
-        // room for soon-to-be-decoded data.
-        if (mState != STARTED && mState != RUNNING) {
-          MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Starting stream %p in Write (%u waiting)",
-                                                 this, bytesToCopy));
-          StartUnlocked();
-          if (mState == ERRORED) {
-            return NS_ERROR_FAILURE;
-          }
-        }
-        MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Stream %p waiting in Write() (%u waiting)",
-                                                 this, bytesToCopy));
-        mon.Wait();
-      }
+     // If we are not playing, but our buffer is full, start playing to make
+     // room for soon-to-be-decoded data.
+     if (mState != STARTED && mState != RUNNING) {
+       MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Starting stream %p in Write (%u waiting)",
+                                              this, bytesToCopy));
+       StartUnlocked();
+       if (mState == ERRORED) {
+         return NS_ERROR_FAILURE;
+       }
+     }
+     MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Stream %p waiting in Write() (%u waiting)",
+                                              this, bytesToCopy));
+     mon.Wait();
     }
   }
 
   mWritten += aFrames;
   return NS_OK;
 }
 
 uint32_t
@@ -688,26 +473,16 @@ AudioStream::SetVolume(double aVolume)
   MOZ_ASSERT(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume");
 
   if (cubeb_stream_set_volume(mCubebStream.get(), aVolume * CubebUtils::GetVolumeScale()) != CUBEB_OK) {
     NS_WARNING("Could not change volume on cubeb stream.");
   }
 }
 
 void
-AudioStream::SetMicrophoneActive(bool aActive)
-{
-  MonitorAutoLock mon(mMonitor);
-
-  mMicrophoneActive = aActive;
-
-  PanOutputIfNeeded(mMicrophoneActive);
-}
-
-void
 AudioStream::Cancel()
 {
   MonitorAutoLock mon(mMonitor);
   mState = ERRORED;
   mon.NotifyAll();
 }
 
 void
@@ -732,44 +507,40 @@ AudioStream::Start()
   StartUnlocked();
 }
 
 void
 AudioStream::StartUnlocked()
 {
   mMonitor.AssertCurrentThreadOwns();
   if (!mCubebStream) {
-    mNeedsStart = true;
     return;
   }
 
   if (mState == INITIALIZED) {
     int r;
     {
       MonitorAutoUnlock mon(mMonitor);
       r = cubeb_stream_start(mCubebStream.get());
-
-      PanOutputIfNeeded(mMicrophoneActive);
     }
     mState = r == CUBEB_OK ? STARTED : ERRORED;
     LOG(("AudioStream: started %p, state %s", this, mState == STARTED ? "STARTED" : "ERRORED"));
   }
 }
 
 void
 AudioStream::Pause()
 {
   MonitorAutoLock mon(mMonitor);
 
   if (mState == ERRORED) {
     return;
   }
 
   if (!mCubebStream || (mState != STARTED && mState != RUNNING)) {
-    mNeedsStart = false;
     mState = STOPPED; // which also tells async OpenCubeb not to start, just init
     return;
   }
 
   int r;
   {
     MonitorAutoUnlock mon(mMonitor);
     r = cubeb_stream_stop(mCubebStream.get());
@@ -798,20 +569,16 @@ AudioStream::Resume()
 }
 
 void
 AudioStream::Shutdown()
 {
   MonitorAutoLock mon(mMonitor);
   LOG(("AudioStream: Shutdown %p, state %d", this, mState));
 
-  while (mPendingAudioInitTask) {
-    mon.Wait();
-  }
-
   if (mCubebStream) {
     MonitorAutoUnlock mon(mMonitor);
     // Force stop to put the cubeb stream in a stable state before deletion.
     cubeb_stream_stop(mCubebStream.get());
     // Must not try to shut down cubeb from within the lock!  wasapi may still
     // call our callback after Pause()/stop()!?! Bug 996162
     mCubebStream.reset();
   }
@@ -860,54 +627,25 @@ AudioStream::GetPositionInFramesUnlocked
   MOZ_ASSERT(position >= mLastGoodPosition, "cubeb position shouldn't go backward");
   // This error handling/recovery keeps us in good shape in release build.
   if (position >= mLastGoodPosition) {
     mLastGoodPosition = position;
   }
   return std::min<uint64_t>(mLastGoodPosition, INT64_MAX);
 }
 
-int64_t
-AudioStream::GetLatencyInFrames()
-{
-  uint32_t latency;
-  if (cubeb_stream_get_latency(mCubebStream.get(), &latency)) {
-    NS_WARNING("Could not get cubeb latency.");
-    return 0;
-  }
-  return static_cast<int64_t>(latency);
-}
-
 bool
 AudioStream::IsPaused()
 {
   MonitorAutoLock mon(mMonitor);
   return mState == STOPPED;
 }
 
-void
-AudioStream::GetBufferInsertTime(int64_t &aTimeMs)
-{
-  mMonitor.AssertCurrentThreadOwns();
-  if (mInserts.Length() > 0) {
-    // Find the right block, but don't leave the array empty
-    while (mInserts.Length() > 1 && mReadPoint >= mInserts[0].mFrames) {
-      mReadPoint -= mInserts[0].mFrames;
-      mInserts.RemoveElementAt(0);
-    }
-    // offset for amount already read
-    // XXX Note: could misreport if we couldn't find a block in the right timeframe
-    aTimeMs = mInserts[0].mTimeMs + ((mReadPoint * 1000) / mOutRate);
-  } else {
-    aTimeMs = INT64_MAX;
-  }
-}
-
 long
-AudioStream::GetUnprocessed(void* aBuffer, long aFrames, int64_t &aTimeMs)
+AudioStream::GetUnprocessed(void* aBuffer, long aFrames)
 {
   mMonitor.AssertCurrentThreadOwns();
   uint8_t* wpos = reinterpret_cast<uint8_t*>(aBuffer);
 
   // Flush the timestretcher pipeline, if we were playing using a playback rate
   // other than 1.0.
   uint32_t flushedFrames = 0;
   if (mTimeStretcher && mTimeStretcher->numSamples()) {
@@ -919,52 +657,21 @@ AudioStream::GetUnprocessed(void* aBuffe
 
   void* input[2];
   uint32_t input_size[2];
   mBuffer.PopElements(available, &input[0], &input_size[0], &input[1], &input_size[1]);
   memcpy(wpos, input[0], input_size[0]);
   wpos += input_size[0];
   memcpy(wpos, input[1], input_size[1]);
 
-  // First time block now has our first returned sample
-  mReadPoint += BytesToFrames(available);
-  GetBufferInsertTime(aTimeMs);
-
   return BytesToFrames(available) + flushedFrames;
 }
 
-// Get unprocessed samples, and pad the beginning of the buffer with silence if
-// there is not enough data.
 long
-AudioStream::GetUnprocessedWithSilencePadding(void* aBuffer, long aFrames, int64_t& aTimeMs)
-{
-  mMonitor.AssertCurrentThreadOwns();
-  uint32_t toPopBytes = FramesToBytes(aFrames);
-  uint32_t available = std::min(toPopBytes, mBuffer.Length());
-  uint32_t silenceOffset = toPopBytes - available;
-
-  uint8_t* wpos = reinterpret_cast<uint8_t*>(aBuffer);
-
-  memset(wpos, 0, silenceOffset);
-  wpos += silenceOffset;
-
-  void* input[2];
-  uint32_t input_size[2];
-  mBuffer.PopElements(available, &input[0], &input_size[0], &input[1], &input_size[1]);
-  memcpy(wpos, input[0], input_size[0]);
-  wpos += input_size[0];
-  memcpy(wpos, input[1], input_size[1]);
-
-  GetBufferInsertTime(aTimeMs);
-
-  return aFrames;
-}
-
-long
-AudioStream::GetTimeStretched(void* aBuffer, long aFrames, int64_t &aTimeMs)
+AudioStream::GetTimeStretched(void* aBuffer, long aFrames)
 {
   mMonitor.AssertCurrentThreadOwns();
   long processedFrames = 0;
 
   // We need to call the non-locking version, because we already have the lock.
   if (EnsureTimeStretcherInitializedUnlocked() != NS_OK) {
     return 0;
   }
@@ -980,146 +687,58 @@ AudioStream::GetTimeStretched(void* aBuf
       void* input[2];
       uint32_t input_size[2];
       available = std::min(mBuffer.Length(), toPopBytes);
       if (available != toPopBytes) {
         lowOnBufferedData = true;
       }
       mBuffer.PopElements(available, &input[0], &input_size[0],
                                      &input[1], &input_size[1]);
-      mReadPoint += BytesToFrames(available);
       for(uint32_t i = 0; i < 2; i++) {
         mTimeStretcher->putSamples(reinterpret_cast<AudioDataValue*>(input[i]), BytesToFrames(input_size[i]));
       }
     }
     uint32_t receivedFrames = mTimeStretcher->receiveSamples(reinterpret_cast<AudioDataValue*>(wpos), aFrames - processedFrames);
     wpos += FramesToBytes(receivedFrames);
     processedFrames += receivedFrames;
   } while (processedFrames < aFrames && !lowOnBufferedData);
 
-  GetBufferInsertTime(aTimeMs);
-
   return processedFrames;
 }
 
-void
-AudioStream::Reset()
-{
-
-  MOZ_ASSERT(mLatencyRequest == LowLatency, "We should only be reseting low latency streams");
-
-  mShouldDropFrames = true;
-  mNeedsStart = true;
-
-  cubeb_stream_params params;
-  params.rate = mInRate;
-  params.channels = mOutChannels;
-#if defined(__ANDROID__)
-#if defined(MOZ_B2G)
-  params.stream_type = CubebUtils::ConvertChannelToCubebType(mAudioChannel);
-#else
-  params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
-#endif
-
-  if (params.stream_type == CUBEB_STREAM_TYPE_MAX) {
-    return;
-  }
-#endif
-
-  if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
-    params.format = CUBEB_SAMPLE_S16NE;
-  } else {
-    params.format = CUBEB_SAMPLE_FLOAT32NE;
-  }
-  mBytesPerFrame = sizeof(AudioDataValue) * mOutChannels;
-
-  // Size mBuffer for one second of audio.  This value is arbitrary, and was
-  // selected based on the observed behaviour of the existing AudioStream
-  // implementations.
-  uint32_t bufferLimit = FramesToBytes(mInRate);
-  MOZ_ASSERT(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
-  mBuffer.Reset();
-  mBuffer.SetCapacity(bufferLimit);
-
-  // Don't block this thread to initialize a cubeb stream.
-  // When this is done, it will start callbacks from Cubeb.  Those will
-  // cause us to move from INITIALIZED to RUNNING.  Until then, we
-  // can't access any cubeb functions.
-  // Use a RefPtr to avoid leaks if Dispatch fails
-  RefPtr<AudioInitTask> init = new AudioInitTask(this, mLatencyRequest, params);
-  init->Dispatch();
-}
-
 long
 AudioStream::DataCallback(void* aBuffer, long aFrames)
 {
   MonitorAutoLock mon(mMonitor);
   MOZ_ASSERT(mState != SHUTDOWN, "No data callback after shutdown");
   uint32_t available = std::min(static_cast<uint32_t>(FramesToBytes(aFrames)), mBuffer.Length());
   MOZ_ASSERT(available % mBytesPerFrame == 0, "Must copy complete frames");
   AudioDataValue* output = reinterpret_cast<AudioDataValue*>(aBuffer);
   uint32_t underrunFrames = 0;
   uint32_t servicedFrames = 0;
-  int64_t insertTime;
-
-  mShouldDropFrames = false;
 
   // NOTE: wasapi (others?) can call us back *after* stop()/Shutdown() (mState == SHUTDOWN)
   // Bug 996162
 
   // callback tells us cubeb succeeded initializing
   if (mState == STARTED) {
-    // For low-latency streams, we want to minimize any built-up data when
-    // we start getting callbacks.
-    // Simple version - contract on first callback only.
-    if (mLatencyRequest == LowLatency) {
-      uint32_t old_len = mBuffer.Length();
-      available = mBuffer.ContractTo(FramesToBytes(aFrames));
-      TimeStamp now = TimeStamp::Now();
-      if (!mStartTime.IsNull()) {
-        int64_t timeMs = (now - mStartTime).ToMilliseconds();
-        MOZ_LOG(gAudioStreamLog, LogLevel::Warning,
-               ("Stream took %lldms to start after first Write() @ %u", timeMs, mOutRate));
-      } else {
-        MOZ_LOG(gAudioStreamLog, LogLevel::Warning,
-          ("Stream started before Write() @ %u", mOutRate));
-      }
-
-      if (old_len != available) {
-        // Note that we may have dropped samples in Write() as well!
-        MOZ_LOG(gAudioStreamLog, LogLevel::Warning,
-               ("AudioStream %p dropped %u + %u initial frames @ %u", this,
-                 mReadPoint, BytesToFrames(old_len - available), mOutRate));
-        mReadPoint += BytesToFrames(old_len - available);
-      }
-    }
     mState = RUNNING;
   }
 
   if (available) {
-    // When we are playing a low latency stream, and it is the first time we are
-    // getting data from the buffer, we prefer to add the silence for an
-    // underrun at the beginning of the buffer, so the first buffer is not cut
-    // in half by the silence inserted to compensate for the underrun.
     if (mInRate == mOutRate) {
-      if (mLatencyRequest == LowLatency && !mWritten) {
-        servicedFrames = GetUnprocessedWithSilencePadding(output, aFrames, insertTime);
-      } else {
-        servicedFrames = GetUnprocessed(output, aFrames, insertTime);
-      }
+      servicedFrames = GetUnprocessed(output, aFrames);
     } else {
-      servicedFrames = GetTimeStretched(output, aFrames, insertTime);
+      servicedFrames = GetTimeStretched(output, aFrames);
     }
 
     MOZ_ASSERT(mBuffer.Length() % mBytesPerFrame == 0, "Must copy complete frames");
 
     // Notify any blocked Write() call that more space is available in mBuffer.
     mon.NotifyAll();
-  } else {
-    GetBufferInsertTime(insertTime);
   }
 
   underrunFrames = aFrames - servicedFrames;
 
   // Always send audible frames first, and silent frames later.
   // Otherwise it will break the assumption of FrameHistory.
   if (mState != DRAINING) {
     mAudioClock.UpdateFrameHistory(servicedFrames, underrunFrames);
@@ -1130,31 +749,16 @@ AudioStream::DataCallback(void* aBuffer,
              ("AudioStream %p lost %d frames", this, underrunFrames));
     }
     servicedFrames += underrunFrames;
   } else {
     mAudioClock.UpdateFrameHistory(servicedFrames, 0);
   }
 
   WriteDumpFile(mDumpFile, this, aFrames, aBuffer);
-  // Don't log if we're not interested or if the stream is inactive
-  if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug) &&
-      mState != SHUTDOWN &&
-      insertTime != INT64_MAX && servicedFrames > underrunFrames) {
-    uint32_t latency = UINT32_MAX;
-    if (cubeb_stream_get_latency(mCubebStream.get(), &latency)) {
-      NS_WARNING("Could not get latency from cubeb.");
-    }
-    TimeStamp now = TimeStamp::Now();
-
-    mLatencyLog->Log(AsyncLatencyLogger::AudioStream, reinterpret_cast<uint64_t>(this),
-                     insertTime, now);
-    mLatencyLog->Log(AsyncLatencyLogger::Cubeb, reinterpret_cast<uint64_t>(mCubebStream.get()),
-                     (latency * 1000) / mOutRate, now);
-  }
 
   return servicedFrames;
 }
 
 void
 AudioStream::StateCallback(cubeb_state aState)
 {
   MonitorAutoLock mon(mMonitor);
--- a/dom/media/AudioStream.h
+++ b/dom/media/AudioStream.h
@@ -5,19 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(AudioStream_h_)
 #define AudioStream_h_
 
 #include "AudioSampleFormat.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsThreadUtils.h"
-#include "Latency.h"
 #include "mozilla/dom/AudioChannelBinding.h"
+#include "mozilla/Monitor.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "CubebUtils.h"
 #include "soundtouch/SoundTouchFactory.h"
 
 namespace mozilla {
 
 struct CubebDestroyPolicy
 {
@@ -66,17 +67,17 @@ private:
   // pointer is garanteed to always be valid.
   AudioStream* const mAudioStream;
   // Output rate in Hz (characteristic of the playback rate)
   int mOutRate;
   // Input rate in Hz (characteristic of the media being played)
   int mInRate;
   // True if the we are timestretching, false if we are resampling.
   bool mPreservesPitch;
-  // The history of frames sent to the audio engine in each Datacallback.
+  // The history of frames sent to the audio engine in each DataCallback.
   const nsAutoPtr<FrameHistory> mFrameHistory;
 };
 
 class CircularByteBuffer
 {
 public:
   CircularByteBuffer()
     : mBuffer(nullptr), mCapacity(0), mStart(0), mCount(0)
@@ -128,102 +129,66 @@ public:
     *aSize1 = std::min(mCapacity - mStart, aSize);
     *aData2 = &mBuffer[0];
     *aSize2 = aSize - *aSize1;
     mCount -= *aSize1 + *aSize2;
     mStart += *aSize1 + *aSize2;
     mStart %= mCapacity;
   }
 
-  // Throw away all but aSize bytes from the buffer.  Returns new size, which
-  // may be less than aSize
-  uint32_t ContractTo(uint32_t aSize) {
-    MOZ_ASSERT(mBuffer && mCapacity, "Buffer not initialized.");
-    if (aSize >= mCount) {
-      return mCount;
-    }
-    mStart += (mCount - aSize);
-    mCount = aSize;
-    mStart %= mCapacity;
-    return mCount;
-  }
-
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
   {
     size_t amount = 0;
     amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf);
     return amount;
   }
 
-  void Reset()
-  {
-    mBuffer = nullptr;
-    mCapacity = 0;
-    mStart = 0;
-    mCount = 0;
-  }
-
 private:
   nsAutoArrayPtr<uint8_t> mBuffer;
   uint32_t mCapacity;
   uint32_t mStart;
   uint32_t mCount;
 };
 
-class AudioInitTask;
-
 // Access to a single instance of this class must be synchronized by
 // callers, or made from a single thread.  One exception is that access to
 // GetPosition, GetPositionInFrames, SetVolume, and Get{Rate,Channels},
 // SetMicrophoneActive is thread-safe without external synchronization.
 class AudioStream final
 {
   virtual ~AudioStream();
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioStream)
   AudioStream();
 
-  enum LatencyRequest {
-    HighLatency,
-    LowLatency
-  };
-
   // Initialize the audio stream. aNumChannels is the number of audio
   // channels (1 for mono, 2 for stereo, etc) and aRate is the sample rate
   // (22050Hz, 44100Hz, etc).
   nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const dom::AudioChannel aAudioStreamChannel,
-                LatencyRequest aLatencyRequest);
+                const dom::AudioChannel aAudioStreamChannel);
 
   // Closes the stream. All future use of the stream is an error.
   void Shutdown();
 
   void Reset();
 
   // Write audio data to the audio hardware.  aBuf is an array of AudioDataValues
   // AudioDataValue of length aFrames*mChannels.  If aFrames is larger
   // than the result of Available(), the write will block until sufficient
-  // buffer space is available.  aTime is the time in ms associated with the first sample
-  // for latency calculations
-  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames, TimeStamp* aTime = nullptr);
+  // buffer space is available.
+  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
 
   // Return the number of audio frames that can be written without blocking.
   uint32_t Available();
 
   // Set the current volume of the audio playback. This is a value from
   // 0 (meaning muted) to 1 (meaning full volume).  Thread-safe.
   void SetVolume(double aVolume);
 
-  // Informs the AudioStream that a microphone is being used by someone in the
-  // application.
-  void SetMicrophoneActive(bool aActive);
-  void PanOutputIfNeeded(bool aMicrophoneActive);
-  void ResetStreamIfNeeded();
-
   // Block until buffered audio data has been consumed.
   void Drain();
 
   // Break any blocking operation and set the stream to shutdown.
   void Cancel();
 
   // Start the stream.
   void Start();
@@ -266,53 +231,36 @@ protected:
 
   // Return the position, measured in audio frames played since the stream was
   // opened, of the audio hardware, not adjusted for the changes of playback
   // rate or underrun frames.
   // Caller must own the monitor.
   int64_t GetPositionInFramesUnlocked();
 
 private:
-  friend class AudioInitTask;
-
-  // So we can call it asynchronously from AudioInitTask
-  nsresult OpenCubeb(cubeb_stream_params &aParams,
-                     LatencyRequest aLatencyRequest);
-  void AudioInitTaskFinished();
-
-  void CheckForStart();
+  nsresult OpenCubeb(cubeb_stream_params &aParams);
 
   static long DataCallback_S(cubeb_stream*, void* aThis, void* aBuffer, long aFrames)
   {
     return static_cast<AudioStream*>(aThis)->DataCallback(aBuffer, aFrames);
   }
 
   static void StateCallback_S(cubeb_stream*, void* aThis, cubeb_state aState)
   {
     static_cast<AudioStream*>(aThis)->StateCallback(aState);
   }
 
 
-  static void DeviceChangedCallback_s(void * aThis) {
-    static_cast<AudioStream*>(aThis)->DeviceChangedCallback();
-  }
-
   long DataCallback(void* aBuffer, long aFrames);
   void StateCallback(cubeb_state aState);
-  void DeviceChangedCallback();
 
   nsresult EnsureTimeStretcherInitializedUnlocked();
 
-  // aTime is the time in ms the samples were inserted into MediaStreamGraph
-  long GetUnprocessed(void* aBuffer, long aFrames, int64_t &aTime);
-  long GetTimeStretched(void* aBuffer, long aFrames, int64_t &aTime);
-  long GetUnprocessedWithSilencePadding(void* aBuffer, long aFrames, int64_t &aTime);
-
-  int64_t GetLatencyInFrames();
-  void GetBufferInsertTime(int64_t &aTimeMs);
+  long GetUnprocessed(void* aBuffer, long aFrames);
+  long GetTimeStretched(void* aBuffer, long aFrames);
 
   void StartUnlocked();
 
   // The monitor is held to protect all access to member variables.  Write()
   // waits while mBuffer is full; DataCallback() notifies as it consumes
   // data from mBuffer.  Drain() waits while mState is DRAINING;
   // StateCallback() notifies when mState is DRAINED.
   Monitor mMonitor;
@@ -325,32 +273,19 @@ private:
   int mOutChannels;
 #if defined(__ANDROID__)
   dom::AudioChannel mAudioChannel;
 #endif
   // Number of frames written to the buffers.
   int64_t mWritten;
   AudioClock mAudioClock;
   soundtouch::SoundTouch* mTimeStretcher;
-  nsRefPtr<AsyncLatencyLogger> mLatencyLog;
 
-  // copy of Latency logger's starting time for offset calculations
+  // Stream start time for stream open delay telemetry.
   TimeStamp mStartTime;
-  // Whether we are playing a low latency stream, or a normal stream.
-  LatencyRequest mLatencyRequest;
-  // Where in the current mInserts[0] block cubeb has read to
-  int64_t mReadPoint;
-  // Keep track of each inserted block of samples and the time it was inserted
-  // so we can estimate the clock time for a specific sample's insertion (for when
-  // we send data to cubeb).  Blocks are aged out as needed.
-  struct Inserts {
-    int64_t mTimeMs;
-    int64_t mFrames;
-  };
-  nsAutoTArray<Inserts, 8> mInserts;
 
   // Output file for dumping audio
   FILE* mDumpFile;
 
   // Temporary audio buffer.  Filled by Write() and consumed by
   // DataCallback().  Once mBuffer is full, Write() blocks until sufficient
   // space becomes available in mBuffer.  mBuffer is sized in bytes, not
   // frames.
@@ -381,62 +316,17 @@ private:
                  // cubeb, after which StateCallback will indicate drain
                  // completion.
     DRAINED,     // StateCallback has indicated that the drain is complete.
     ERRORED,     // Stream disabled due to an internal error.
     SHUTDOWN     // Shutdown has been called
   };
 
   StreamState mState;
-  bool mNeedsStart; // needed in case Start() is called before cubeb is open
   bool mIsFirst;
-  // True if a microphone is active.
-  bool mMicrophoneActive;
-  // When we are in the process of changing the output device, and the callback
-  // is not going to be called for a little while, simply drop incoming frames.
-  // This is only on OSX for now, because other systems handle this gracefully.
-  bool mShouldDropFrames;
-  // True if there is a pending AudioInitTask. Shutdown() will wait until the
-  // pending AudioInitTask is finished.
-  bool mPendingAudioInitTask;
   // The last good position returned by cubeb_stream_get_position(). Used to
   // check if the cubeb position is going backward.
   uint64_t mLastGoodPosition;
 };
 
-class AudioInitTask : public nsRunnable
-{
-public:
-  AudioInitTask(AudioStream *aStream,
-                AudioStream::LatencyRequest aLatencyRequest,
-                const cubeb_stream_params &aParams)
-    : mAudioStream(aStream)
-    , mLatencyRequest(aLatencyRequest)
-    , mParams(aParams)
-  {}
-
-  nsresult Dispatch()
-  {
-    // Can't add 'this' as the event to run, since mThread may not be set yet
-    nsresult rv = NS_NewNamedThread("CubebInit", getter_AddRefs(mThread));
-    if (NS_SUCCEEDED(rv)) {
-      // Note: event must not null out mThread!
-      rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL);
-    }
-    return rv;
-  }
-
-protected:
-  virtual ~AudioInitTask() {};
-
-private:
-  NS_IMETHOD Run() override final;
-
-  RefPtr<AudioStream> mAudioStream;
-  AudioStream::LatencyRequest mLatencyRequest;
-  cubeb_stream_params mParams;
-
-  nsCOMPtr<nsIThread> mThread;
-};
-
 } // namespace mozilla
 
 #endif
--- a/dom/media/mediasink/DecodedAudioDataSink.cpp
+++ b/dom/media/mediasink/DecodedAudioDataSink.cpp
@@ -258,18 +258,17 @@ DecodedAudioDataSink::SetPlaying(bool aP
 
 nsresult
 DecodedAudioDataSink::InitializeAudioStream()
 {
   // AudioStream initialization can block for extended periods in unusual
   // circumstances, so we take care to drop the decoder monitor while
   // initializing.
   RefPtr<AudioStream> audioStream(new AudioStream());
-  nsresult rv = audioStream->Init(mInfo.mChannels, mInfo.mRate,
-                                  mChannel, AudioStream::HighLatency);
+  nsresult rv = audioStream->Init(mInfo.mChannels, mInfo.mRate, mChannel);
   if (NS_FAILED(rv)) {
     audioStream->Shutdown();
     return rv;
   }
 
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mAudioStream = audioStream;