Backed out changeset 4e02fc1cbd35 (bug 1264199)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 18 Apr 2016 14:22:00 +0200
changeset 331459 f9390125f8425c6a72502f58a0a173c2965086ac
parent 331458 64a0ad4f6ac04a4951c815a948395374700ae2ad
child 331460 2ab22d41a4507326f3433667764b848b143f9558
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1264199
milestone48.0a1
backs out4e02fc1cbd35109ca54522fc9465893954063083
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
Backed out changeset 4e02fc1cbd35 (bug 1264199)
dom/media/AudioConverter.cpp
dom/media/AudioConverter.h
dom/media/mediasink/DecodedAudioDataSink.cpp
dom/media/mediasink/DecodedAudioDataSink.h
--- a/dom/media/AudioConverter.cpp
+++ b/dom/media/AudioConverter.cpp
@@ -28,17 +28,29 @@ AudioConverter::AudioConverter(const Aud
                         aIn.Interleaved() == aOut.Interleaved(),
                         "No format or rate conversion is supported at this stage");
   MOZ_DIAGNOSTIC_ASSERT(aOut.Channels() <= 2 ||
                         aIn.Channels() == aOut.Channels(),
                         "Only down/upmixing to mono or stereo is supported at this stage");
   MOZ_DIAGNOSTIC_ASSERT(aOut.Interleaved(), "planar audio format not supported");
   mIn.Layout().MappingTable(mOut.Layout(), mChannelOrderMap);
   if (aIn.Rate() != aOut.Rate()) {
-    RecreateResampler();
+    int error;
+    mResampler = speex_resampler_init(aOut.Channels(),
+                                      aIn.Rate(),
+                                      aOut.Rate(),
+                                      SPEEX_RESAMPLER_QUALITY_DEFAULT,
+                                      &error);
+
+    if (error == RESAMPLER_ERR_SUCCESS) {
+      speex_resampler_skip_zeros(mResampler);
+    } else {
+      NS_WARNING("Failed to initialize resampler.");
+      mResampler = nullptr;
+    }
   }
 }
 
 AudioConverter::~AudioConverter()
 {
   if (mResampler) {
     speex_resampler_destroy(mResampler);
     mResampler = nullptr;
@@ -265,56 +277,16 @@ AudioConverter::ResampleAudio(void* aOut
                                             out, &outframes);
   } else {
     MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
   }
   MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped");
   return outframes;
 }
 
-void
-AudioConverter::RecreateResampler()
-{
-  if (mResampler) {
-    speex_resampler_destroy(mResampler);
-  }
-  int error;
-  mResampler = speex_resampler_init(mOut.Channels(),
-                                    mIn.Rate(),
-                                    mOut.Rate(),
-                                    SPEEX_RESAMPLER_QUALITY_DEFAULT,
-                                    &error);
-
-  if (error == RESAMPLER_ERR_SUCCESS) {
-    speex_resampler_skip_zeros(mResampler);
-  } else {
-    NS_WARNING("Failed to initialize resampler.");
-    mResampler = nullptr;
-  }
-}
-
-size_t
-AudioConverter::DrainResampler(void* aOut)
-{
-  if (!mResampler) {
-    return 0;
-  }
-  int frames = speex_resampler_get_input_latency(mResampler);
-  AlignedByteBuffer buffer(FramesOutToSamples(frames) *
-                           AudioConfig::SampleSize(mOut.Format()));
-  if (!buffer) {
-    // OOM
-    return 0;
-  }
-  frames = ResampleAudio(aOut, buffer.Data(), frames);
-  // Tore down the resampler as it's easier than handling follow-up.
-  RecreateResampler();
-  return frames;
-}
-
 size_t
 AudioConverter::UpmixAudio(void* aOut, const void* aIn, size_t aFrames) const
 {
   MOZ_ASSERT(mIn.Format() == AudioConfig::FORMAT_S16 ||
              mIn.Format() == AudioConfig::FORMAT_FLT);
   MOZ_ASSERT(mIn.Channels() < mOut.Channels());
   MOZ_ASSERT(mIn.Channels() == 1, "Can only upmix mono for now");
   MOZ_ASSERT(mOut.Channels() == 2, "Can only upmix to stereo for now");
@@ -350,23 +322,17 @@ AudioConverter::UpmixAudio(void* aOut, c
   }
 
   return aFrames;
 }
 
 size_t
 AudioConverter::ResampleRecipientFrames(size_t aFrames) const
 {
-  if (!aFrames && mIn.Rate() != mOut.Rate()) {
-    // The resampler will be drained, account for frames currently buffered
-    // in the resampler.
-    return speex_resampler_get_output_latency(mResampler);
-  } else {
-    return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
-  }
+  return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
 }
 
 size_t
 AudioConverter::FramesOutToSamples(size_t aFrames) const
 {
   return aFrames * mOut.Channels();
 }
 
--- a/dom/media/AudioConverter.h
+++ b/dom/media/AudioConverter.h
@@ -118,18 +118,16 @@ typedef AudioDataBuffer<AudioConfig::FOR
 class AudioConverter {
 public:
   AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut);
   ~AudioConverter();
 
   // Convert the AudioDataBuffer.
   // Conversion will be done in place if possible. Otherwise a new buffer will
   // be returned.
-  // Providing an empty buffer and resampling is expected, the resampler
-  // will be drained.
   template <AudioConfig::SampleFormat Format, typename Value>
   AudioDataBuffer<Format, Value> Process(AudioDataBuffer<Format, Value>&& aBuffer)
   {
     MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
     AudioDataBuffer<Format, Value> buffer = Move(aBuffer);
     if (CanWorkInPlace()) {
       size_t frames = SamplesInToFrames(buffer.Length());
       frames = ProcessInternal(buffer.Data(), buffer.Data(), frames);
@@ -149,36 +147,32 @@ public:
     MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
     // Perform the downmixing / reordering in temporary buffer.
     size_t frames = SamplesInToFrames(aBuffer.Length());
     AlignedBuffer<Value> temp1;
     if (!temp1.SetLength(FramesOutToSamples(frames))) {
       return AudioDataBuffer<Format, Value>(Move(temp1));
     }
     frames = ProcessInternal(temp1.Data(), aBuffer.Data(), frames);
-    if (mIn.Rate() == mOut.Rate()) {
+    if (!frames || mIn.Rate() == mOut.Rate()) {
       temp1.SetLength(FramesOutToSamples(frames));
       return AudioDataBuffer<Format, Value>(Move(temp1));
     }
 
     // At this point, temp1 contains the buffer reordered and downmixed.
     // If we are downsampling we can re-use it.
     AlignedBuffer<Value>* outputBuffer = &temp1;
     AlignedBuffer<Value> temp2;
-    if (!frames || mOut.Rate() > mIn.Rate()) {
-      // We are upsampling or about to drain, we can't work in place.
-      // Allocate another temporary buffer where the upsampling will occur.
+    if (mOut.Rate() > mIn.Rate()) {
+      // We are upsampling, we can't work in place. Allocate another temporary
+      // buffer where the upsampling will occur.
       temp2.SetLength(FramesOutToSamples(ResampleRecipientFrames(frames)));
       outputBuffer = &temp2;
     }
-    if (!frames) {
-      frames = DrainResampler(outputBuffer->Data());
-    } else {
-      frames = ResampleAudio(outputBuffer->Data(), temp1.Data(), frames);
-    }
+    frames = ResampleAudio(outputBuffer->Data(), temp1.Data(), frames);
     outputBuffer->SetLength(FramesOutToSamples(frames));
     return AudioDataBuffer<Format, Value>(Move(*outputBuffer));
   }
 
   // Attempt to convert the AudioDataBuffer in place.
   // Will return 0 if the conversion wasn't possible.
   template <typename Value>
   size_t Process(Value* aBuffer, size_t aFrames)
@@ -224,15 +218,13 @@ private:
   size_t FramesOutToSamples(size_t aFrames) const;
   size_t SamplesInToFrames(size_t aSamples) const;
   size_t FramesOutToBytes(size_t aFrames) const;
 
   // Resampler context.
   SpeexResamplerState* mResampler;
   size_t ResampleAudio(void* aOut, const void* aIn, size_t aFrames);
   size_t ResampleRecipientFrames(size_t aFrames) const;
-  void RecreateResampler();
-  size_t DrainResampler(void* aOut);
 };
 
 } // namespace mozilla
 
 #endif /* AudioConverter_h */
--- a/dom/media/mediasink/DecodedAudioDataSink.cpp
+++ b/dom/media/mediasink/DecodedAudioDataSink.cpp
@@ -316,22 +316,16 @@ DecodedAudioDataSink::NotifyAudioNeeded(
   }
   if (!mProcessingThread->IsCurrentThreadIn()) {
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
       this, &DecodedAudioDataSink::NotifyAudioNeeded);
     mProcessingThread->Dispatch(r.forget());
     return;
   }
 
-  if (AudioQueue().IsFinished() && !AudioQueue().GetSize()) {
-    // We have reached the end of the data, drain the resampler.
-    DrainConverter();
-    return;
-  }
-
   // Always ensure we have two processed frames pending to allow for processing
   // latency.
   while (AudioQueue().GetSize() && mProcessedQueue.GetSize() < 2) {
     RefPtr<AudioData> data =
       dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>());
     // Ignore the element with 0 frames and try next.
     if (!data->mFrames) {
       continue;
@@ -340,18 +334,16 @@ DecodedAudioDataSink::NotifyAudioNeeded(
     if (!mConverter ||
         (data->mRate != mConverter->InputConfig().Rate() ||
          data->mChannels != mConverter->InputConfig().Channels())) {
       SINK_LOG_V("Audio format changed from %u@%uHz to %u@%uHz",
                  mConverter? mConverter->InputConfig().Channels() : 0,
                  mConverter ? mConverter->InputConfig().Rate() : 0,
                  data->mChannels, data->mRate);
 
-      DrainConverter();
-
       // mFramesParsed indicates the current playtime in frames at the current
       // input sampling rate. Recalculate it per the new sampling rate.
       if (mFramesParsed) {
         // We minimize overflow.
         uint32_t oldRate = mConverter->InputConfig().Rate();
         uint32_t newRate = data->mRate;
         int64_t major = mFramesParsed / oldRate;
         int64_t remainder = mFramesParsed % oldRate;
@@ -388,41 +380,35 @@ DecodedAudioDataSink::NotifyAudioNeeded(
 
     if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
       // The next audio packet begins some time after the end of the last packet
       // we pushed to the audio hardware. We must push silence into the audio
       // hardware so that the next audio packet begins playback at the correct
       // time.
       missingFrames = std::min<int64_t>(INT32_MAX, missingFrames.value());
       mFramesParsed += missingFrames.value();
-      // We need to insert silence, first use drained frames if any.
-      missingFrames -= DrainConverter(missingFrames.value());
-      // Insert silence is still needed.
-      if (missingFrames.value()) {
-        AlignedAudioBuffer silenceData(missingFrames.value() * mOutputChannels);
-        RefPtr<AudioData> silence = CreateAudioFromBuffer(Move(silenceData), data);
-        if (silence) {
-          mProcessedQueue.Push(silence);
-        }
+      AlignedAudioBuffer silenceData(missingFrames.value() * mOutputChannels);
+      RefPtr<AudioData> silence = CreateAudioFromBuffer(Move(silenceData), data);
+      if (silence) {
+        mProcessedQueue.Push(silence);
       }
     }
 
     mLastEndTime = data->GetEndTime();
     mFramesParsed += data->mFrames;
 
     if (mConverter->InputConfig() != mConverter->OutputConfig()) {
       AlignedAudioBuffer convertedData =
         mConverter->Process(AudioSampleBuffer(Move(data->mAudioData))).Forget();
       data = CreateAudioFromBuffer(Move(convertedData), data);
       if (!data) {
         continue;
       }
     }
     mProcessedQueue.Push(data);
-    mLastProcessedPacket = Some(data);
   }
 }
 
 already_AddRefed<AudioData>
 DecodedAudioDataSink::CreateAudioFromBuffer(AlignedAudioBuffer&& aBuffer,
                                             AudioData* aReference)
 {
   uint32_t frames = aBuffer.Length() / mOutputChannels;
@@ -441,41 +427,10 @@ DecodedAudioDataSink::CreateAudioFromBuf
                   duration.value(),
                   frames,
                   Move(aBuffer),
                   mOutputChannels,
                   mOutputRate);
   return data.forget();
 }
 
-uint32_t
-DecodedAudioDataSink::DrainConverter(uint32_t aMaxFrames)
-{
-  MOZ_ASSERT(mProcessingThread->IsCurrentThreadIn());
-
-  if (!mConverter || !mLastProcessedPacket) {
-    // nothing to drain.
-    return 0;
-  }
-
-  // To drain we simply provide an empty packet to the audio converter.
-  AlignedAudioBuffer convertedData =
-    mConverter->Process(AudioSampleBuffer(AlignedAudioBuffer())).Forget();
-
-  uint32_t frames = convertedData.Length() / mOutputChannels;
-  convertedData.SetLength(std::min(frames, aMaxFrames) * mOutputChannels);
-
-  // We assume the start time of the drained data is just before the end of the
-  // previous packet. Ultimately, the start time doesn't really matter, however
-  // we do not want to trigger the gap detection in PopFrames.
-  RefPtr<AudioData> data = CreateAudioFromBuffer(Move(convertedData),
-                                                 mLastProcessedPacket.ref());
-  mLastProcessedPacket.reset();
-
-  if (!data) {
-    return 0;
-  }
-  mProcessedQueue.Push(data);
-  return data->mFrames;
-}
-
 } // namespace media
 } // namespace mozilla
--- a/dom/media/mediasink/DecodedAudioDataSink.h
+++ b/dom/media/mediasink/DecodedAudioDataSink.h
@@ -110,30 +110,26 @@ private:
 
   const RefPtr<AbstractThread> mProcessingThread;
   Atomic<bool> mShutdown;
 
   // Audio Processing objects and methods
   void OnAudioPopped(const RefPtr<MediaData>& aSample);
   void OnAudioPushed(const RefPtr<MediaData>& aSample);
   void NotifyAudioNeeded();
-  // Drain the converter and add the output to the processed audio queue.
-  // A maximum of aMaxFrames will be added.
-  uint32_t DrainConverter(uint32_t aMaxFrames = UINT32_MAX);
   already_AddRefed<AudioData> CreateAudioFromBuffer(AlignedAudioBuffer&& aBuffer,
                                                     AudioData* aReference);
   UniquePtr<AudioConverter> mConverter;
   MediaQueue<AudioData> mProcessedQueue;
   MediaEventListener mAudioQueueListener;
   MediaEventListener mProcessedQueueListener;
   // Number of frames processed from AudioQueue(). Used to determine gaps in
   // the input stream. It indicates the time in frames since playback started
   // at the current input framerate.
   int64_t mFramesParsed;
-  Maybe<RefPtr<AudioData>> mLastProcessedPacket;
   int64_t mLastEndTime;
   // Never modifed after construction.
   uint32_t mOutputRate;
   uint32_t mOutputChannels;
 };
 
 } // namespace media
 } // namespace mozilla