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
--- 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,