Merge "Add API for querying direct playback support."
This commit is contained in:
@@ -20940,11 +20940,12 @@ package android.media {
|
||||
method @NonNull public java.util.List<android.media.AudioDeviceInfo> getAvailableCommunicationDevices();
|
||||
method @Nullable public android.media.AudioDeviceInfo getCommunicationDevice();
|
||||
method public android.media.AudioDeviceInfo[] getDevices(int);
|
||||
method public static int getDirectPlaybackSupport(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method public int getEncodedSurroundMode();
|
||||
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
|
||||
method public int getMode();
|
||||
method public String getParameters(String);
|
||||
method public static int getPlaybackOffloadSupport(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method @Deprecated public static int getPlaybackOffloadSupport(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method public String getProperty(String);
|
||||
method public int getRingerMode();
|
||||
method @Deprecated public int getRouting(int);
|
||||
@@ -21035,6 +21036,10 @@ package android.media {
|
||||
field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
|
||||
field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
|
||||
field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
|
||||
field public static final int DIRECT_PLAYBACK_BITSTREAM_SUPPORTED = 4; // 0x4
|
||||
field public static final int DIRECT_PLAYBACK_NOT_SUPPORTED = 0; // 0x0
|
||||
field public static final int DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED = 3; // 0x3
|
||||
field public static final int DIRECT_PLAYBACK_OFFLOAD_SUPPORTED = 1; // 0x1
|
||||
field public static final int ENCODED_SURROUND_OUTPUT_ALWAYS = 2; // 0x2
|
||||
field public static final int ENCODED_SURROUND_OUTPUT_AUTO = 0; // 0x0
|
||||
field public static final int ENCODED_SURROUND_OUTPUT_MANUAL = 3; // 0x3
|
||||
@@ -21425,7 +21430,7 @@ package android.media {
|
||||
method public int getStreamType();
|
||||
method public boolean getTimestamp(android.media.AudioTimestamp);
|
||||
method public int getUnderrunCount();
|
||||
method public static boolean isDirectPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method @Deprecated public static boolean isDirectPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method public boolean isOffloadedPlayback();
|
||||
method public void pause() throws java.lang.IllegalStateException;
|
||||
method public void play() throws java.lang.IllegalStateException;
|
||||
|
||||
@@ -1429,6 +1429,9 @@ package android.media {
|
||||
field public static final int DEVICE_ROLE_DISABLED = 2; // 0x2
|
||||
field public static final int DEVICE_ROLE_NONE = 0; // 0x0
|
||||
field public static final int DEVICE_ROLE_PREFERRED = 1; // 0x1
|
||||
field public static final int DIRECT_BITSTREAM_SUPPORTED = 4; // 0x4
|
||||
field public static final int DIRECT_OFFLOAD_GAPLESS_SUPPORTED = 3; // 0x3
|
||||
field public static final int DIRECT_OFFLOAD_SUPPORTED = 1; // 0x1
|
||||
field public static final int OFFLOAD_GAPLESS_SUPPORTED = 2; // 0x2
|
||||
field public static final int OFFLOAD_SUPPORTED = 1; // 0x1
|
||||
field public static final int STREAM_DEFAULT = -1; // 0xffffffff
|
||||
|
||||
@@ -2774,6 +2774,46 @@ static jboolean android_media_AudioSystem_canBeSpatialized(JNIEnv *env, jobject
|
||||
return canBeSpatialized;
|
||||
}
|
||||
|
||||
// keep these values in sync with AudioSystem.java
|
||||
#define DIRECT_NOT_SUPPORTED 0
|
||||
#define DIRECT_OFFLOAD_SUPPORTED 1
|
||||
#define DIRECT_OFFLOAD_GAPLESS_SUPPORTED 3
|
||||
#define DIRECT_BITSTREAM_SUPPORTED 4
|
||||
|
||||
static jint convertAudioDirectModeFromNative(audio_direct_mode_t directMode) {
|
||||
jint result = DIRECT_NOT_SUPPORTED;
|
||||
if ((directMode | AUDIO_DIRECT_OFFLOAD_SUPPORTED) != AUDIO_DIRECT_NOT_SUPPORTED) {
|
||||
result |= DIRECT_OFFLOAD_SUPPORTED;
|
||||
}
|
||||
if ((directMode | AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED) != AUDIO_DIRECT_NOT_SUPPORTED) {
|
||||
result |= DIRECT_OFFLOAD_GAPLESS_SUPPORTED;
|
||||
}
|
||||
if ((directMode | AUDIO_DIRECT_BITSTREAM_SUPPORTED) != AUDIO_DIRECT_NOT_SUPPORTED) {
|
||||
result |= DIRECT_BITSTREAM_SUPPORTED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static jint android_media_AudioSystem_getDirectPlaybackSupport(JNIEnv *env, jobject thiz,
|
||||
jobject jFormat, jobject jaa) {
|
||||
JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
|
||||
jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
|
||||
if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
|
||||
return AUDIO_DIRECT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
audio_config_t nConfig;
|
||||
javaAudioFormatToNativeAudioConfig(env, &nConfig, jFormat, false /*isInput*/);
|
||||
|
||||
audio_direct_mode_t directMode;
|
||||
status_t status = AudioSystem::getDirectPlaybackSupport(paa.get(), &nConfig, &directMode);
|
||||
if (status != NO_ERROR) {
|
||||
ALOGW("%s native returned error %d", __func__, status);
|
||||
return AUDIO_DIRECT_NOT_SUPPORTED;
|
||||
}
|
||||
return convertAudioDirectModeFromNative(directMode);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const JNINativeMethod gMethods[] =
|
||||
@@ -2917,7 +2957,10 @@ static const JNINativeMethod gMethods[] =
|
||||
{"canBeSpatialized",
|
||||
"(Landroid/media/AudioAttributes;Landroid/media/AudioFormat;"
|
||||
"[Landroid/media/AudioDeviceAttributes;)Z",
|
||||
(void *)android_media_AudioSystem_canBeSpatialized}};
|
||||
(void *)android_media_AudioSystem_canBeSpatialized},
|
||||
{"getDirectPlaybackSupport",
|
||||
"(Landroid/media/AudioFormat;Landroid/media/AudioAttributes;)I",
|
||||
(void *)android_media_AudioSystem_getDirectPlaybackSupport}};
|
||||
|
||||
static const JNINativeMethod gEventHandlerMethods[] = {
|
||||
{"native_setup",
|
||||
|
||||
@@ -2398,6 +2398,77 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// Direct playback query
|
||||
|
||||
/** Return value for {@link #getDirectPlaybackSupport(AudioFormat, AudioAttributes)}:
|
||||
direct playback not supported. */
|
||||
public static final int DIRECT_PLAYBACK_NOT_SUPPORTED = AudioSystem.DIRECT_NOT_SUPPORTED;
|
||||
/** Return value for {@link #getDirectPlaybackSupport(AudioFormat, AudioAttributes)}:
|
||||
direct offload playback supported. Compressed offload is a variant of direct playback.
|
||||
It is the feature that allows audio processing tasks to be done on the Android device but
|
||||
not on the application processor, instead, it is handled by dedicated hardware such as audio
|
||||
DSPs. That will allow the application processor to be idle as much as possible, which is
|
||||
good for power saving. Compressed offload playback supports
|
||||
{@link AudioTrack.StreamEventCallback} for event notifications. */
|
||||
public static final int DIRECT_PLAYBACK_OFFLOAD_SUPPORTED =
|
||||
AudioSystem.DIRECT_OFFLOAD_SUPPORTED;
|
||||
/** Return value for {@link #getDirectPlaybackSupport(AudioFormat, AudioAttributes)}:
|
||||
direct offload playback supported with gapless transitions. Compressed offload is a variant
|
||||
of direct playback. It is the feature that allows audio processing tasks to be done on the
|
||||
Android device but not on the application processor, instead, it is handled by dedicated
|
||||
hardware such as audio DSPs. That will allow the application processor to be idle as much as
|
||||
possible, which is good for power saving. Compressed offload playback supports
|
||||
{@link AudioTrack.StreamEventCallback} for event notifications. Gapless transitions
|
||||
indicates the ability to play consecutive audio tracks without an audio silence in
|
||||
between. */
|
||||
public static final int DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED =
|
||||
AudioSystem.DIRECT_OFFLOAD_GAPLESS_SUPPORTED;
|
||||
/** Return value for {@link #getDirectPlaybackSupport(AudioFormat, AudioAttributes)}:
|
||||
direct playback supported. This value covers direct playback that is bitstream pass-through
|
||||
such as compressed pass-through. */
|
||||
public static final int DIRECT_PLAYBACK_BITSTREAM_SUPPORTED =
|
||||
AudioSystem.DIRECT_BITSTREAM_SUPPORTED;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(flag = true, prefix = "DIRECT_PLAYBACK_", value = {
|
||||
DIRECT_PLAYBACK_NOT_SUPPORTED,
|
||||
DIRECT_PLAYBACK_OFFLOAD_SUPPORTED,
|
||||
DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED,
|
||||
DIRECT_PLAYBACK_BITSTREAM_SUPPORTED}
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AudioDirectPlaybackMode {}
|
||||
|
||||
/**
|
||||
* Returns a bitfield representing the different forms of direct playback currently available
|
||||
* for a given audio format.
|
||||
* <p>Direct playback means that the audio stream is not altered by the framework. The audio
|
||||
* stream will not be resampled, volume scaled, downmixed or mixed with other content by
|
||||
* the framework. But it may be wrapped in a higher level protocol such as IEC61937 for
|
||||
* passthrough.
|
||||
* <p>Checking for direct support can help the app select the representation of audio content
|
||||
* that most closely matches the capabilities of the device and peripherals (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.
|
||||
* @param format the audio format (codec, sample rate, channels) being checked.
|
||||
* @param attributes the {@link AudioAttributes} to be used for playback
|
||||
* @return the direct playback mode available with given format and attributes. The returned
|
||||
* value will be {@link #DIRECT_PLAYBACK_NOT_SUPPORTED} or a combination of
|
||||
* {@link #DIRECT_PLAYBACK_OFFLOAD_SUPPORTED},
|
||||
* {@link #DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED} and
|
||||
* {@link #DIRECT_PLAYBACK_BITSTREAM_SUPPORTED}. Note that if
|
||||
* {@link #DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED} is present in the returned value,
|
||||
* then {@link #DIRECT_PLAYBACK_OFFLOAD_SUPPORTED} will be too.
|
||||
*/
|
||||
@AudioDirectPlaybackMode
|
||||
public static int getDirectPlaybackSupport(@NonNull AudioFormat format,
|
||||
@NonNull AudioAttributes attributes) {
|
||||
Objects.requireNonNull(format);
|
||||
Objects.requireNonNull(attributes);
|
||||
return AudioSystem.getDirectPlaybackSupport(format, attributes);
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// Offload query
|
||||
/**
|
||||
@@ -2458,7 +2529,9 @@ public class AudioManager {
|
||||
* {@link #PLAYBACK_OFFLOAD_SUPPORTED} if offload playback is supported or
|
||||
* {@link #PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED} if gapless transitions are
|
||||
* also supported.
|
||||
* @deprecated Use {@link #getDirectPlaybackSupport(AudioFormat, AudioAttributes)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@AudioOffloadMode
|
||||
public static int getPlaybackOffloadSupport(@NonNull AudioFormat format,
|
||||
@NonNull AudioAttributes attributes) {
|
||||
|
||||
@@ -1766,15 +1766,36 @@ public class AudioSystem
|
||||
*/
|
||||
public static native int setAllowedCapturePolicy(int uid, int flags);
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Direct playback modes supported by audio HAL implementation.
|
||||
*/
|
||||
public static final int DIRECT_NOT_SUPPORTED = 0;
|
||||
public static final int DIRECT_OFFLOAD_SUPPORTED = 1;
|
||||
public static final int DIRECT_OFFLOAD_GAPLESS_SUPPORTED = 3;
|
||||
public static final int DIRECT_BITSTREAM_SUPPORTED = 4;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Compressed audio offload decoding modes supported by audio HAL implementation.
|
||||
* Keep in sync with system/media/include/media/audio.h.
|
||||
*/
|
||||
public static final int OFFLOAD_NOT_SUPPORTED = 0;
|
||||
public static final int OFFLOAD_SUPPORTED = 1;
|
||||
public static final int OFFLOAD_NOT_SUPPORTED = DIRECT_NOT_SUPPORTED;
|
||||
public static final int OFFLOAD_SUPPORTED = DIRECT_OFFLOAD_SUPPORTED;
|
||||
public static final int OFFLOAD_GAPLESS_SUPPORTED = 2;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns how direct playback of an audio format is currently available on the device.
|
||||
* @param format the audio format (codec, sample rate, channels) being checked.
|
||||
* @param attributes the {@link AudioAttributes} to be used for playback
|
||||
* @return the direct playback mode available with given format and attributes. Any combination
|
||||
* of {@link #DIRECT_NOT_SUPPORTED}, {@link #DIRECT_OFFLOAD_SUPPORTED},
|
||||
* {@link #DIRECT_OFFLOAD_GAPLESS_SUPPORTED} and {@link #DIRECT_BITSTREAM_SUPPORTED}.
|
||||
*/
|
||||
public static native int getDirectPlaybackSupport(
|
||||
@NonNull AudioFormat format, @NonNull AudioAttributes attributes);
|
||||
|
||||
static int getOffloadSupport(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
|
||||
return native_get_offload_support(format.getEncoding(), format.getSampleRate(),
|
||||
format.getChannelMask(), format.getChannelIndexMask(),
|
||||
|
||||
@@ -1357,8 +1357,8 @@ public class AudioTrack extends PlayerBase
|
||||
throw new UnsupportedOperationException(
|
||||
"Offload and low latency modes are incompatible");
|
||||
}
|
||||
if (AudioSystem.getOffloadSupport(mFormat, mAttributes)
|
||||
== AudioSystem.OFFLOAD_NOT_SUPPORTED) {
|
||||
if (AudioSystem.getDirectPlaybackSupport(mFormat, mAttributes)
|
||||
== AudioSystem.DIRECT_NOT_SUPPORTED) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot create AudioTrack, offload format / attributes not supported");
|
||||
}
|
||||
@@ -1530,7 +1530,10 @@ public class AudioTrack extends PlayerBase
|
||||
* the audio data.
|
||||
* @param attributes a non-null {@link AudioAttributes} instance.
|
||||
* @return true if the given audio format can be played directly.
|
||||
* @deprecated Use {@link AudioManager#getDirectPlaybackSupport(AudioFormat, AudioAttributes)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isDirectPlaybackSupported(@NonNull AudioFormat format,
|
||||
@NonNull AudioAttributes attributes) {
|
||||
if (format == null) {
|
||||
|
||||
Reference in New Issue
Block a user