Bug 1437366 - Add a way to force the sample-rate used for a MediaStreamGraph. r?pehrsons
MozReview-Commit-ID: 4ICQiNKbUpJ
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -28,16 +28,19 @@
#ifdef MOZ_WIDGET_ANDROID
#include "GeneratedJNIWrappers.h"
#endif
#define PREF_VOLUME_SCALE "media.volume_scale"
#define PREF_CUBEB_BACKEND "media.cubeb.backend"
#define PREF_CUBEB_LATENCY_PLAYBACK "media.cubeb_latency_playback_ms"
#define PREF_CUBEB_LATENCY_MSG "media.cubeb_latency_msg_frames"
+// Allows to get something non-default for the preferred sample-rate, to allow
+// troubleshooting in the field and testing.
+#define PREF_CUBEB_FORCE_SAMPLE_RATE "media.cubeb.force_sample_rate"
#define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level"
#define PREF_CUBEB_SANDBOX "media.cubeb.sandbox"
#define MASK_MONO (1 << AudioConfig::CHANNEL_MONO)
#define MASK_MONO_LFE (MASK_MONO | (1 << AudioConfig::CHANNEL_LFE))
#define MASK_STEREO ((1 << AudioConfig::CHANNEL_LEFT) | (1 << AudioConfig::CHANNEL_RIGHT))
#define MASK_STEREO_LFE (MASK_STEREO | (1 << AudioConfig::CHANNEL_LFE))
#define MASK_3F (MASK_STEREO | (1 << AudioConfig::CHANNEL_CENTER))
@@ -117,16 +120,20 @@ enum class CubebState {
Uninitialized = 0,
Initialized,
Shutdown
} sCubebState = CubebState::Uninitialized;
cubeb* sCubebContext;
double sVolumeScale = 1.0;
uint32_t sCubebPlaybackLatencyInMilliseconds = 100;
uint32_t sCubebMSGLatencyInFrames = 512;
+// If sCubebForcedSampleRate is zero, PreferredSampleRate will return the
+// preferred sample-rate for the audio backend in use. Otherwise, it will be
+// used as the preferred sample-rate.
+uint32_t sCubebForcedSampleRate = 0;
bool sCubebPlaybackLatencyPrefSet = false;
bool sCubebMSGLatencyPrefSet = false;
bool sAudioStreamInitEverSucceeded = false;
#ifdef MOZ_CUBEB_REMOTING
bool sCubebSandbox;
#endif
StaticAutoPtr<char> sBrandName;
StaticAutoPtr<char> sCubebBackendName;
@@ -232,16 +239,19 @@ void PrefChanged(const char* aPref, void
sCubebMSGLatencyPrefSet = Preferences::HasUserValue(aPref);
uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_FRAMES);
StaticMutexAutoLock lock(sMutex);
// 128 is the block size for the Web Audio API, which limits how low the
// latency can be here.
// We don't want to limit the upper limit too much, so that people can
// experiment.
sCubebMSGLatencyInFrames = std::min<uint32_t>(std::max<uint32_t>(value, 128), 1e6);
+ } else if (strcmp(aPref, PREF_CUBEB_FORCE_SAMPLE_RATE) == 0) {
+ StaticMutexAutoLock lock(sMutex);
+ sCubebForcedSampleRate = Preferences::GetUint(aPref);
} else if (strcmp(aPref, PREF_CUBEB_LOGGING_LEVEL) == 0) {
nsAutoCString value;
Preferences::GetCString(aPref, value);
LogModule* cubebLog = LogModule::Get("cubeb");
if (value.EqualsLiteral("verbose")) {
cubeb_set_log_callback(CUBEB_LOG_VERBOSE, CubebLogCallback);
cubebLog->SetLevel(LogLevel::Verbose);
} else if (value.EqualsLiteral("normal")) {
@@ -318,16 +328,19 @@ bool InitPreferredSampleRate()
}
#endif
MOZ_ASSERT(sPreferredSampleRate);
return true;
}
uint32_t PreferredSampleRate()
{
+ if (sCubebForcedSampleRate) {
+ return sCubebForcedSampleRate;
+ }
if (!InitPreferredSampleRate()) {
return 44100;
}
MOZ_ASSERT(sPreferredSampleRate);
return sPreferredSampleRate;
}
bool InitPreferredChannelLayout()
@@ -558,16 +571,17 @@ uint32_t GetCubebMSGLatencyInFrames(cube
#endif
}
void InitLibrary()
{
Preferences::RegisterCallbackAndCall(PrefChanged, PREF_VOLUME_SCALE);
Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_LATENCY_PLAYBACK);
Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_LATENCY_MSG);
+ Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_FORCE_SAMPLE_RATE);
Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_BACKEND);
Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_SANDBOX);
if (MOZ_LOG_TEST(gCubebLog, LogLevel::Verbose)) {
cubeb_set_log_callback(CUBEB_LOG_VERBOSE, CubebLogCallback);
} else if (MOZ_LOG_TEST(gCubebLog, LogLevel::Error)) {
cubeb_set_log_callback(CUBEB_LOG_NORMAL, CubebLogCallback);
}
// We don't want to call the callback on startup, because the pref is the
@@ -587,16 +601,17 @@ void InitLibrary()
}
void ShutdownLibrary()
{
Preferences::UnregisterCallback(PrefChanged, PREF_VOLUME_SCALE);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_SANDBOX);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_BACKEND);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY_PLAYBACK);
+ Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_FORCE_SAMPLE_RATE);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY_MSG);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LOGGING_LEVEL);
StaticMutexAutoLock lock(sMutex);
if (sCubebContext) {
cubeb_destroy(sCubebContext);
sCubebContext = nullptr;
}
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -324,8 +324,9 @@ skip-if = (android_version == '18') # an
[test_peerConnection_bug1227781.html]
[test_peerConnection_stats.html]
skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
[test_peerConnection_sender_and_receiver_stats.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_verifyDescriptions.html]
skip-if = (android_version == '18')
[test_fingerprinting_resistance.html]
+[test_forceSampleRate.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_forceSampleRate.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test the pref media.cubeb.force_sample_rate</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+const WEIRD_SAMPLE_RATE = 44101;
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [
+ ["media.cubeb.force_sample_rate", WEIRD_SAMPLE_RATE]
+]}).then(function() {
+ var ac = new AudioContext();
+ is(ac.sampleRate, WEIRD_SAMPLE_RATE, "Forced sample-rate set successfully.");
+ SimpleTest.finish();
+});
+</script>
+</pre>
+</body>