summaryrefslogtreecommitdiff
path: root/dom/media/GraphDriver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/GraphDriver.cpp')
-rw-r--r--dom/media/GraphDriver.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp
index daf1ccc989..c4ee2ee2b1 100644
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -14,6 +14,10 @@
#include "webrtc/MediaEngineWebRTC.h"
#endif
+#ifdef XP_MACOSX
+#include <sys/sysctl.h>
+#endif
+
extern mozilla::LazyLogModule gMediaStreamGraphLog;
#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
@@ -577,6 +581,32 @@ AudioCallbackDriver::~AudioCallbackDriver()
MOZ_ASSERT(mPromisesForOperation.IsEmpty());
}
+bool IsMacbookOrMacbookAir()
+{
+#ifdef XP_MACOSX
+ size_t len = 0;
+ sysctlbyname("hw.model", NULL, &len, NULL, 0);
+ if (len) {
+ UniquePtr<char[]> model(new char[len]);
+ // This string can be
+ // MacBook%d,%d for a normal MacBook
+ // MacBookPro%d,%d for a MacBook Pro
+ // MacBookAir%d,%d for a Macbook Air
+ sysctlbyname("hw.model", model.get(), &len, NULL, 0);
+ char* substring = strstr(model.get(), "MacBook");
+ if (substring) {
+ const size_t offset = strlen("MacBook");
+ if (strncmp(model.get() + offset, "Air", len - offset) ||
+ isdigit(model[offset + 1])) {
+ return true;
+ }
+ }
+ return false;
+ }
+#endif
+ return false;
+}
+
void
AudioCallbackDriver::Init()
{
@@ -613,6 +643,13 @@ AudioCallbackDriver::Init()
}
}
+ // Macbook and MacBook air don't have enough CPU to run very low latency
+ // MediaStreamGraphs, cap the minimal latency to 512 frames int this case.
+ if (IsMacbookOrMacbookAir()) {
+ latency_frames = std::max((uint32_t) 512, latency_frames);
+ }
+
+
input = output;
input.channels = mInputChannels; // change to support optional stereo capture
@@ -1026,6 +1063,44 @@ AudioCallbackDriver::MixerCallback(AudioDataValue* aMixedBuffer,
NS_WARNING_ASSERTION(written == aFrames - toWrite, "Dropping frames.");
};
+void AudioCallbackDriver::PanOutputIfNeeded(bool aMicrophoneActive)
+{
+#ifdef XP_MACOSX
+ cubeb_device* out;
+ int rv;
+ char name[128];
+ size_t length = sizeof(name);
+
+ rv = sysctlbyname("hw.model", name, &length, NULL, 0);
+ if (rv) {
+ return;
+ }
+
+ if (!strncmp(name, "MacBookPro", 10)) {
+ if (cubeb_stream_get_current_device(mAudioStream, &out) == CUBEB_OK) {
+ // Check if we are currently outputing sound on external speakers.
+ if (!strcmp(out->output_name, "ispk")) {
+ // Pan everything to the right speaker.
+ if (aMicrophoneActive) {
+ if (cubeb_stream_set_panning(mAudioStream, 1.0) != CUBEB_OK) {
+ NS_WARNING("Could not pan audio output to the right.");
+ }
+ } else {
+ if (cubeb_stream_set_panning(mAudioStream, 0.0) != CUBEB_OK) {
+ NS_WARNING("Could not pan audio output to the center.");
+ }
+ }
+ } else {
+ if (cubeb_stream_set_panning(mAudioStream, 0.0) != CUBEB_OK) {
+ NS_WARNING("Could not pan audio output to the center.");
+ }
+ }
+ cubeb_stream_device_destroy(mAudioStream, out);
+ }
+ }
+#endif
+}
+
void
AudioCallbackDriver::DeviceChangedCallback() {
// Tell the audio engine the device has changed, it might want to reset some
@@ -1034,6 +1109,9 @@ AudioCallbackDriver::DeviceChangedCallback() {
if (mAudioInput) {
mAudioInput->DeviceChanged();
}
+#ifdef XP_MACOSX
+ PanOutputIfNeeded(mMicrophoneActive);
+#endif
}
void
@@ -1042,6 +1120,10 @@ AudioCallbackDriver::SetMicrophoneActive(bool aActive)
MonitorAutoLock mon(mGraphImpl->GetMonitor());
mMicrophoneActive = aActive;
+
+#ifdef XP_MACOSX
+ PanOutputIfNeeded(mMicrophoneActive);
+#endif
}
uint32_t