summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michael Chan <mzchan@dolby.com> 2018-04-24 14:33:57 +1000
committer Mikhail Naganov <mnaganov@google.com> 2018-12-06 14:41:03 -0800
commit2de156d15fceed4c834cb0e1dfdd1bcd0f94f4cf (patch)
tree23a7b9a20c4cab709948c31ca9bbb84c7cf2dce7
parentefd355c1c355ba237204c0a8bce10355382a64cd (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.txt1
-rw-r--r--core/jni/android_media_AudioTrack.cpp21
-rw-r--r--media/java/android/media/AudioTrack.java32
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