Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(562)

Unified Diff: webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java

Issue 2051323002: Optimize the repeated calls to AudioEffect.queryEffects() on Android (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Code review feedback Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java
diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java
index e5408fd81b5bc36459f3f9a24eb1365b16970819..255e92d9ec98389a6bef34ee677d818f3020b5d9 100644
--- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java
+++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioEffects.java
@@ -42,6 +42,11 @@ class WebRtcAudioEffects {
private static final UUID AOSP_NOISE_SUPPRESSOR =
UUID.fromString("c06c8400-8e06-11e0-9cb6-0002a5d5c51b");
+ // Contains the available effect descriptors returned from the
+ // AudioEffect.getEffects() call. This result is cached to avoid doing the
+ // slow OS call multiple times.
+ private static Descriptor[] cachedEffects = null;
+
// Contains the audio effect objects. Created in enable() and destroyed
// in release().
private AcousticEchoCanceler aec = null;
@@ -60,22 +65,31 @@ class WebRtcAudioEffects {
// Checks if the device implements Acoustic Echo Cancellation (AEC).
// Returns true if the device implements AEC, false otherwise.
public static boolean isAcousticEchoCancelerSupported() {
+ // Note: we're using isAcousticEchoCancelerEffectAvailable() instead of
+ // AcousticEchoCanceler.isAvailable() to avoid the expensive getEffects()
+ // OS API call.
return WebRtcAudioUtils.runningOnJellyBeanOrHigher()
- && AcousticEchoCanceler.isAvailable();
+ && isAcousticEchoCancelerEffectAvailable();
}
// Checks if the device implements Automatic Gain Control (AGC).
// Returns true if the device implements AGC, false otherwise.
public static boolean isAutomaticGainControlSupported() {
+ // Note: we're using isAutomaticGainControlEffectAvailable() instead of
+ // AutomaticGainControl.isAvailable() to avoid the expensive getEffects()
+ // OS API call.
return WebRtcAudioUtils.runningOnJellyBeanOrHigher()
- && AutomaticGainControl.isAvailable();
+ && isAutomaticGainControlEffectAvailable();
}
// Checks if the device implements Noise Suppression (NS).
// Returns true if the device implements NS, false otherwise.
public static boolean isNoiseSuppressorSupported() {
+ // Note: we're using isNoiseSuppressorEffectAvailable() instead of
+ // NoiseSuppressor.isAvailable() to avoid the expensive getEffects()
+ // OS API call.
return WebRtcAudioUtils.runningOnJellyBeanOrHigher()
- && NoiseSuppressor.isAvailable();
+ && isNoiseSuppressorEffectAvailable();
}
// Returns true if the device is blacklisted for HW AEC usage.
@@ -115,7 +129,7 @@ class WebRtcAudioEffects {
// AudioEffect.queryEffects() can throw IllegalStateException.
@TargetApi(18)
private static boolean isAcousticEchoCancelerExcludedByUUID() {
- for (Descriptor d : AudioEffect.queryEffects()) {
+ for (Descriptor d : getAvailableEffects()) {
if (d.type.equals(AudioEffect.EFFECT_TYPE_AEC) &&
d.uuid.equals(AOSP_ACOUSTIC_ECHO_CANCELER)) {
return true;
@@ -128,7 +142,7 @@ class WebRtcAudioEffects {
// AudioEffect.queryEffects() can throw IllegalStateException.
@TargetApi(18)
private static boolean isAutomaticGainControlExcludedByUUID() {
- for (Descriptor d : AudioEffect.queryEffects()) {
+ for (Descriptor d : getAvailableEffects()) {
if (d.type.equals(AudioEffect.EFFECT_TYPE_AGC) &&
d.uuid.equals(AOSP_AUTOMATIC_GAIN_CONTROL)) {
return true;
@@ -141,7 +155,7 @@ class WebRtcAudioEffects {
// AudioEffect.queryEffects() can throw IllegalStateException.
@TargetApi(18)
private static boolean isNoiseSuppressorExcludedByUUID() {
- for (Descriptor d : AudioEffect.queryEffects()) {
+ for (Descriptor d : getAvailableEffects()) {
if (d.type.equals(AudioEffect.EFFECT_TYPE_NS) &&
d.uuid.equals(AOSP_NOISE_SUPPRESSOR)) {
return true;
@@ -150,6 +164,24 @@ class WebRtcAudioEffects {
return false;
}
+ // Returns true if the device supports Acoustic Echo Cancellation (AEC).
+ @TargetApi(18)
+ private static boolean isAcousticEchoCancelerEffectAvailable() {
+ return isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AEC);
+ }
+
+ // Returns true if the device supports Automatic Gain Control (AGC).
+ @TargetApi(18)
+ private static boolean isAutomaticGainControlEffectAvailable() {
+ return isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AGC);
+ }
+
+ // Returns true if the device supports Noise Suppression (NS).
+ @TargetApi(18)
+ private static boolean isNoiseSuppressorEffectAvailable() {
+ return isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_NS);
+ }
+
// Returns true if all conditions for supporting the HW AEC are fulfilled.
// It will not be possible to enable the HW AEC if this method returns false.
public static boolean canUseAcousticEchoCanceler() {
@@ -378,4 +410,34 @@ class WebRtcAudioEffects {
throw new AssertionError("Expected condition to be true");
}
}
+
+ // Returns the cached copy of the audio effects array, if available, or
+ // queries the operating system for the list of effects.
+ private static Descriptor[] getAvailableEffects() {
+ if (cachedEffects != null) {
+ return cachedEffects;
+ }
+ // The caching is best effort only - if this method is called from several
+ // threads in parallel, they may end up doing the underlying OS call
+ // multiple times. It's normally only called on one thread so there's no
+ // real need to optimize for the multiple threads case.
+ cachedEffects = AudioEffect.queryEffects();
+ return cachedEffects;
+ }
+
+ // Returns true if an effect of the specified type is available. Functionally
+ // equivalent to (NoiseSuppressor|AutomaticGainControl|...).isAvailable(), but
+ // faster as it avoids the expensive OS call to enumerate effects.
+ private static boolean isEffectTypeAvailable(UUID effectType) {
+ Descriptor[] effects = getAvailableEffects();
+ if (effects == null) {
+ return false;
+ }
+ for (Descriptor d : effects) {
+ if (d.type.equals(effectType)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698