diff options
| author | 2018-04-24 14:33:57 +1000 | |
|---|---|---|
| committer | 2018-12-06 14:41:03 -0800 | |
| commit | 2de156d15fceed4c834cb0e1dfdd1bcd0f94f4cf (patch) | |
| tree | 23a7b9a20c4cab709948c31ca9bbb84c7cf2dce7 | |
| parent | efd355c1c355ba237204c0a8bce10355382a64cd (diff) | |
Add AudioTrack.isDirectPlaybackSupported method
The method checks whether the provided AudioFormat can be played
via currently connected output devices w/o SRC or downmixing
by the framework.
Bug: 120044865
Test: atest CtsMediaTestCases:AudioTrackTest#testIsDirectPlaybackSupported
Change-Id: I63e8334a60d48c17999f500d87360f9c71185dfb
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | core/jni/android_media_AudioTrack.cpp | 21 | ||||
| -rw-r--r-- | media/java/android/media/AudioTrack.java | 32 |
3 files changed, 54 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 2eb90d50c1c8..42bb89b278f3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23349,6 +23349,7 @@ package android.media { method public int getStreamType(); method public boolean getTimestamp(android.media.AudioTimestamp); method public int getUnderrunCount(); + method public static boolean isDirectPlaybackSupported(android.media.AudioFormat, android.media.AudioAttributes); method public void pause() throws java.lang.IllegalStateException; method public void play() throws java.lang.IllegalStateException; method public void registerStreamEventCallback(java.util.concurrent.Executor, android.media.AudioTrack.StreamEventCallback); diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index d927972cf8d3..dcd7c88cda96 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -481,6 +481,24 @@ native_init_failure: } // ---------------------------------------------------------------------------- +static jboolean +android_media_AudioTrack_is_direct_output_supported(JNIEnv *env, jobject thiz, + jint encoding, jint sampleRate, + jint channelMask, jint channelIndexMask, + jint contentType, jint usage, jint flags) { + audio_config_base_t config = {}; + audio_attributes_t attributes = {}; + config.format = static_cast<audio_format_t>(audioFormatToNative(encoding)); + config.sample_rate = static_cast<uint32_t>(sampleRate); + config.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask); + attributes.content_type = static_cast<audio_content_type_t>(contentType); + attributes.usage = static_cast<audio_usage_t>(usage); + attributes.flags = static_cast<audio_flags_mask_t>(flags); + // ignore source and tags attributes as they don't affect querying whether output is supported + return AudioTrack::isDirectOutputSupported(config, attributes); +} + +// ---------------------------------------------------------------------------- static void android_media_AudioTrack_start(JNIEnv *env, jobject thiz) { @@ -1298,6 +1316,9 @@ static jint android_media_AudioTrack_get_port_id(JNIEnv *env, jobject thiz) { // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { // name, signature, funcPtr + {"native_is_direct_output_supported", + "(IIIIIII)Z", + (void *)android_media_AudioTrack_is_direct_output_supported}, {"native_start", "()V", (void *)android_media_AudioTrack_start}, {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 2c4ec3a1a0a6..7d5f4377293f 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -995,6 +995,35 @@ public class AudioTrack extends PlayerBase } } + /** + * Returns whether direct playback of an audio format with the provided attributes is + * currently supported on the system. + * <p>Direct playback means that the audio stream is not resampled or downmixed + * by the framework. Checking for direct support can help the app select the representation + * of audio content that most closely matches the capabilities of the device and peripherials + * (e.g. A/V receiver) connected to it. Note that the provided stream can still be re-encoded + * or mixed with other streams, if needed. + * <p>Also note that this query only provides information about the support of an audio format. + * It does not indicate whether the resources necessary for the playback are available + * at that instant. + * @param format a non-null {@link AudioFormat} instance describing the format of + * the audio data. + * @param attributes a non-null {@link AudioAttributes} instance. + * @return true if the given audio format can be played directly. + */ + public static boolean isDirectPlaybackSupported(@NonNull AudioFormat format, + @NonNull AudioAttributes attributes) { + if (format == null) { + throw new IllegalArgumentException("Illegal null AudioFormat argument"); + } + if (attributes == null) { + throw new IllegalArgumentException("Illegal null AudioAttributes argument"); + } + return native_is_direct_output_supported(format.getEncoding(), format.getSampleRate(), + format.getChannelMask(), format.getChannelIndexMask(), + attributes.getContentType(), attributes.getUsage(), attributes.getFlags()); + } + // mask of all the positional channels supported, however the allowed combinations // are further restricted by the matching left/right rule and // AudioSystem.OUT_CHANNEL_COUNT_MAX @@ -3328,6 +3357,9 @@ public class AudioTrack extends PlayerBase // Native methods called from the Java side //-------------------- + private static native boolean native_is_direct_output_supported(int encoding, int sampleRate, + int channelMask, int channelIndexMask, int contentType, int usage, int flags); + // post-condition: mStreamType is overwritten with a value // that reflects the audio attributes (e.g. an AudioAttributes object with a usage of // AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC |