Bug 1451781 - Check if output device is mono and remove stereo check in order to disable opus channel inversion. r?jya draft
authorAlex Chronopoulos <achronop@gmail.com>
Mon, 09 Apr 2018 13:07:58 +0300
changeset 779150 2e406779faa61078951a2beadcda357451a7533b
parent 778006 b4527f3bc75f3d04c4366d0685a311c7bcc95a19
push id105670
push userachronop@gmail.com
push dateMon, 09 Apr 2018 10:08:50 +0000
reviewersjya
bugs1451781
milestone61.0a1
Bug 1451781 - Check if output device is mono and remove stereo check in order to disable opus channel inversion. r?jya MozReview-Commit-ID: 3x27rBs5Ika
dom/media/VideoUtils.cpp
dom/media/VideoUtils.h
dom/media/platforms/agnostic/OpusDecoder.cpp
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -2,16 +2,17 @@
  * 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 "VideoUtils.h"
 
 #include <functional>
 #include <stdint.h>
 
+#include "CubebUtils.h"
 #include "ImageContainer.h"
 #include "MediaContainerType.h"
 #include "MediaPrefs.h"
 #include "MediaResource.h"
 #include "TimeUnits.h"
 #include "VorbisUtils.h"
 #include "mozilla/Base64.h"
 #include "mozilla/SharedThreadPool.h"
@@ -162,30 +163,37 @@ void DownmixStereoToMono(mozilla::AudioD
     int sample = 0;
 #endif
     // The sample of the buffer would be interleaved.
     sample = (aBuffer[fIdx*channels] + aBuffer[fIdx*channels + 1]) * 0.5;
     aBuffer[fIdx*channels] = aBuffer[fIdx*channels + 1] = sample;
   }
 }
 
-uint32_t DecideAudioPlaybackChannels(const AudioInfo& info)
+uint32_t
+DecideAudioPlaybackChannels(const AudioInfo& info)
 {
   if (MediaPrefs::MonoAudio()) {
     return 1;
   }
 
   if (MediaPrefs::AudioSinkForceStereo()) {
     return 2;
   }
 
   return info.mChannels;
 }
 
 bool
+IsDefaultPlaybackDeviceMono()
+{
+  return CubebUtils::MaxNumberOfChannels() == 1;
+}
+
+bool
 IsVideoContentType(const nsCString& aContentType)
 {
   NS_NAMED_LITERAL_CSTRING(video, "video");
   if (FindInReadable(video, aContentType)) {
     return true;
   }
   return false;
 }
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -157,16 +157,18 @@ ScaleDisplayByAspectRatio(gfx::IntSize& 
 // Input are the buffer contains stereo data and the number of frames.
 void DownmixStereoToMono(mozilla::AudioDataValue* aBuffer,
                          uint32_t aFrames);
 
 // Decide the number of playback channels according to the
 // given AudioInfo and the prefs that are being set.
 uint32_t DecideAudioPlaybackChannels(const AudioInfo& info);
 
+bool IsDefaultPlaybackDeviceMono();
+
 bool IsVideoContentType(const nsCString& aContentType);
 
 // Returns true if it's safe to use aPicture as the picture to be
 // extracted inside a frame of size aFrame, and scaled up to and displayed
 // at a size of aDisplay. You should validate the frame, picture, and
 // display regions before using them to display video frames.
 bool
 IsValidVideoRegion(const gfx::IntSize& aFrame,
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -96,17 +96,17 @@ OpusDataDecoder::Init()
                                                  mMappingTable.Elements(),
                                                  &r);
 
   // Opus has a special feature for stereo coding where it represent wide
   // stereo channels by 180-degree out of phase. This improves quality, but
   // needs to be disabled when the output is downmixed to mono. Playback number
   // of channels are set in AudioSink, using the same method
   // `DecideAudioPlaybackChannels()`, and triggers downmix if needed.
-  if (mOpusDecoder && mOpusParser->mChannels == 2 &&
+  if (IsDefaultPlaybackDeviceMono() ||
       DecideAudioPlaybackChannels(mInfo) == 1) {
     opus_multistream_decoder_ctl(mOpusDecoder, OPUS_SET_PHASE_INVERSION_DISABLED(1));
   }
 
   mSkip = mOpusParser->mPreSkip;
   mPaddingDiscarded = false;
 
   if (codecDelay != FramesToUsecs(mOpusParser->mPreSkip,