Bug 1410456 - use jni methods in place of removed cubeb methods. r?padenot draft
authorAlex Chronopoulos <achronop@gmail.com>
Tue, 20 Feb 2018 15:37:07 +0200
changeset 758410 aaf3cb211aa32185f3aef6560a8f0e72abbed8fc
parent 758409 281a676acab8352376d16f7fcb4d44a765f81693
child 758411 406729fe337c0d4b11e2678a28d0124281e435ba
push id100043
push userachronop@gmail.com
push dateThu, 22 Feb 2018 11:35:08 +0000
reviewerspadenot
bugs1410456
milestone60.0a1
Bug 1410456 - use jni methods in place of removed cubeb methods. r?padenot MozReview-Commit-ID: 18fQVZeYAgk
dom/media/CubebUtils.cpp
dom/media/CubebUtils.h
dom/media/GraphDriver.cpp
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -20,16 +20,19 @@
 #include "nsAutoRef.h"
 #include "nsDebug.h"
 #include "nsIStringBundle.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prdtoa.h"
 #include <algorithm>
 #include <stdint.h>
+#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"
 #define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level"
 #define PREF_CUBEB_SANDBOX "media.cubeb.sandbox"
 
@@ -114,18 +117,18 @@ enum class CubebState {
   Uninitialized = 0,
   Initialized,
   Shutdown
 } sCubebState = CubebState::Uninitialized;
 cubeb* sCubebContext;
 double sVolumeScale = 1.0;
 uint32_t sCubebPlaybackLatencyInMilliseconds = 100;
 uint32_t sCubebMSGLatencyInFrames = 512;
-bool sCubebPlaybackLatencyPrefSet;
-bool sCubebMSGLatencyPrefSet;
+bool sCubebPlaybackLatencyPrefSet = false;
+bool sCubebMSGLatencyPrefSet = false;
 bool sAudioStreamInitEverSucceeded = false;
 #ifdef MOZ_CUBEB_REMOTING
 bool sCubebSandbox;
 #endif
 StaticAutoPtr<char> sBrandName;
 StaticAutoPtr<char> sCubebBackendName;
 
 const char kBrandBundleURL[]      = "chrome://branding/locale/brand.properties";
@@ -300,21 +303,25 @@ bool InitPreferredSampleRate()
   StaticMutexAutoLock lock(sMutex);
   if (sPreferredSampleRate != 0) {
     return true;
   }
   cubeb* context = GetCubebContextUnlocked();
   if (!context) {
     return false;
   }
+#ifdef MOZ_WIDGET_ANDROID
+  sPreferredSampleRate = AndroidGetAudioOutputSampleRate();
+#else
   if (cubeb_get_preferred_sample_rate(context,
                                       &sPreferredSampleRate) != CUBEB_OK) {
 
     return false;
   }
+#endif
   MOZ_ASSERT(sPreferredSampleRate);
   return true;
 }
 
 uint32_t PreferredSampleRate()
 {
   if (!InitPreferredSampleRate()) {
     return 44100;
@@ -522,24 +529,38 @@ bool CubebPlaybackLatencyPrefSet()
 }
 
 bool CubebMSGLatencyPrefSet()
 {
   StaticMutexAutoLock lock(sMutex);
   return sCubebMSGLatencyPrefSet;
 }
 
-Maybe<uint32_t> GetCubebMSGLatencyInFrames()
+uint32_t GetCubebMSGLatencyInFrames(cubeb_stream_params * params)
 {
   StaticMutexAutoLock lock(sMutex);
-  if (!sCubebMSGLatencyPrefSet) {
-    return Maybe<uint32_t>();
+  if (sCubebMSGLatencyPrefSet) {
+    MOZ_ASSERT(sCubebMSGLatencyInFrames > 0);
+    return sCubebMSGLatencyInFrames;
   }
-  MOZ_ASSERT(sCubebMSGLatencyInFrames > 0);
-  return Some(sCubebMSGLatencyInFrames);
+
+#ifdef MOZ_WIDGET_ANDROID
+  return AndroidGetAudioOutputFramesPerBuffer();
+#else
+  cubeb* context = GetCubebContextUnlocked();
+  if (!context) {
+    return sCubebMSGLatencyInFrames; // default 512
+  }
+  uint32_t latency_frames = 0;
+  if (cubeb_get_min_latency(context, params, &latency_frames) != CUBEB_OK) {
+    NS_WARNING("Could not get minimal latency from cubeb.");
+    return sCubebMSGLatencyInFrames; // default 512
+  }
+  return latency_frames;
+#endif
 }
 
 void InitLibrary()
 {
   Preferences::RegisterCallbackAndCall(PrefChanged, PREF_VOLUME_SCALE);
   Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_LATENCY_PLAYBACK);
   Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_LATENCY_MSG);
   Preferences::RegisterCallbackAndCall(PrefChanged, PREF_CUBEB_BACKEND);
@@ -736,10 +757,25 @@ void GetDeviceCollection(nsTArray<RefPtr
                               device.latency_lo);
         aDeviceInfos.AppendElement(info);
       }
     }
     cubeb_device_collection_destroy(context, &collection);
   }
 }
 
+#ifdef MOZ_WIDGET_ANDROID
+uint32_t AndroidGetAudioOutputSampleRate()
+{
+  int32_t sample_rate = java::GeckoAppShell::GetAudioOutputSampleRate();
+  MOZ_ASSERT(sample_rate > 0);
+  return sample_rate;
+}
+uint32_t AndroidGetAudioOutputFramesPerBuffer()
+{
+  int32_t frames = java::GeckoAppShell::GetAudioOutputFramesPerBuffer();
+  MOZ_ASSERT(frames > 0);
+  return frames;
+}
+#endif
+
 } // namespace CubebUtils
 } // namespace mozilla
--- a/dom/media/CubebUtils.h
+++ b/dom/media/CubebUtils.h
@@ -39,20 +39,25 @@ enum Side {
 };
 
 double GetVolumeScale();
 bool GetFirstStream();
 cubeb* GetCubebContext();
 void ReportCubebStreamInitFailure(bool aIsFirstStream);
 void ReportCubebBackendUsed();
 uint32_t GetCubebPlaybackLatencyInMilliseconds();
-Maybe<uint32_t> GetCubebMSGLatencyInFrames();
+uint32_t GetCubebMSGLatencyInFrames(cubeb_stream_params * params);
 bool CubebLatencyPrefSet();
 cubeb_channel_layout ConvertChannelMapToCubebLayout(uint32_t aChannelMap);
 void GetCurrentBackend(nsAString& aBackend);
 void GetPreferredChannelLayout(nsAString& aLayout);
 void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
                          Side aSide);
 cubeb_channel_layout GetPreferredChannelLayoutOrSMPTE(cubeb* context, uint32_t aChannels);
+
+#ifdef MOZ_WIDGET_ANDROID
+uint32_t AndroidGetAudioOutputSampleRate();
+uint32_t AndroidGetAudioOutputFramesPerBuffer();
+#endif
 } // namespace CubebUtils
 } // namespace mozilla
 
 #endif // CubebUtils_h_
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -594,17 +594,16 @@ AudioCallbackDriver::Init()
     if (!mFromFallback) {
       CubebUtils::ReportCubebStreamInitFailure(true);
     }
     return false;
   }
 
   cubeb_stream_params output;
   cubeb_stream_params input;
-  uint32_t latency_frames;
   bool firstStream = CubebUtils::GetFirstStream();
 
   MOZ_ASSERT(!NS_IsMainThread(),
       "This is blocking and should never run on the main thread.");
 
   mSampleRate = output.rate = CubebUtils::PreferredSampleRate();
 
   if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
@@ -624,24 +623,17 @@ AudioCallbackDriver::Init()
 
   mBuffer = AudioCallbackBufferWrapper<AudioDataValue>(mOutputChannels);
   mScratchBuffer = SpillBuffer<AudioDataValue, WEBAUDIO_BLOCK_SIZE * 2>(mOutputChannels);
 
   output.channels = mOutputChannels;
   output.layout = CubebUtils::GetPreferredChannelLayoutOrSMPTE(cubebContext, mOutputChannels);
   output.prefs = CUBEB_STREAM_PREF_NONE;
 
-  Maybe<uint32_t> latencyPref = CubebUtils::GetCubebMSGLatencyInFrames();
-  if (latencyPref) {
-    latency_frames = latencyPref.value();
-  } else {
-    if (cubeb_get_min_latency(cubebContext, &output, &latency_frames) != CUBEB_OK) {
-      NS_WARNING("Could not get minimal latency from cubeb.");
-    }
-  }
+  uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output);
 
   // 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;