Bug 1264199: P3. Attempt to minimize audio quality loss and unnecessary processing. r=kinetik draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 13 Apr 2016 17:55:48 +1000
changeset 356282 89565a98b33c81c3a268524075c289dfe388eea2
parent 356281 c1b416e1c4f22a71c5a8fb00e9146ee7c1d5b5ed
child 356283 33e4f515f3888f221848da0eb2db213789e86a09
push id16486
push userbmo:jyavenard@mozilla.com
push dateTue, 26 Apr 2016 02:36:37 +0000
reviewerskinetik
bugs1264199
milestone49.0a1
Bug 1264199: P3. Attempt to minimize audio quality loss and unnecessary processing. r=kinetik We attempt to avoid unnecessary resampling of 44.1kHz and 48kHz content, for all others we use cubeb's preferred sampling rate as final sampling rate. MozReview-Commit-ID: 413qnsDFHzY
dom/media/AudioStream.h
dom/media/mediasink/DecodedAudioDataSink.cpp
--- a/dom/media/AudioStream.h
+++ b/dom/media/AudioStream.h
@@ -281,16 +281,21 @@ public:
 
   // Return the position, measured in audio frames played since the stream
   // was opened, of the audio hardware.  Thread-safe.
   int64_t GetPositionInFrames();
 
   // Returns true when the audio stream is paused.
   bool IsPaused();
 
+  static uint32_t GetPreferredRate()
+  {
+    CubebUtils::InitPreferredSampleRate();
+    return CubebUtils::PreferredSampleRate();
+  }
   uint32_t GetRate() { return mOutRate; }
   uint32_t GetChannels() { return mChannels; }
   uint32_t GetOutChannels() { return mOutChannels; }
 
   // Set playback rate as a multiple of the intrinsic playback rate. This is to
   // be called only with aPlaybackRate > 0.0.
   nsresult SetPlaybackRate(double aPlaybackRate);
   // Switch between resampling (if false) and time stretching (if true, default).
--- a/dom/media/mediasink/DecodedAudioDataSink.cpp
+++ b/dom/media/mediasink/DecodedAudioDataSink.cpp
@@ -47,18 +47,31 @@ DecodedAudioDataSink::DecodedAudioDataSi
   , mErrored(false)
   , mPlaybackComplete(false)
   , mOwnerThread(aThread)
   , mProcessedQueueLength(0)
   , mFramesParsed(0)
   , mLastEndTime(0)
 {
   bool resampling = gfxPrefs::AudioSinkResampling();
-  uint32_t resamplingRate = gfxPrefs::AudioSinkResampleRate();
-  mOutputRate = resampling ? resamplingRate : mInfo.mRate;
+
+  if (resampling) {
+    mOutputRate = gfxPrefs::AudioSinkResampleRate();
+  } else if (mInfo.mRate == 44100 || mInfo.mRate == 48000) {
+    // The original rate is of good quality and we want to minimize unecessary
+    // resampling. The common scenario being that the sampling rate is one or
+    // the other, this allows to minimize audio quality regression and hoping
+    // content provider want change from those rates mid-stream.
+    mOutputRate = mInfo.mRate;
+  } else {
+    // We will resample all data to match cubeb's preferred sampling rate.
+    mOutputRate = AudioStream::GetPreferredRate();
+  }
+  MOZ_DIAGNOSTIC_ASSERT(mOutputRate, "output rate can't be 0.");
+
   mOutputChannels = mInfo.mChannels > 2 && gfxPrefs::AudioSinkForceStereo()
                       ? 2 : mInfo.mChannels;
 }
 
 DecodedAudioDataSink::~DecodedAudioDataSink()
 {
 }