AudioManager: add reporting of gapless playback support
Add reporting of gapless transitions in offload playback via a new method AudioManager.getPlaybackOffloadSupport() which replaces AudioManager.isOffloadPlaybackSupported(). Bug: 158191844 Test: make Change-Id: I68c0e4865828d336ad8e1d18c5d2a550e2fedd1b
This commit is contained in:
@@ -24453,6 +24453,7 @@ package android.media {
|
||||
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 public String getProperty(String);
|
||||
method public int getRingerMode();
|
||||
method @Deprecated public int getRouting(int);
|
||||
@@ -24571,6 +24572,9 @@ package android.media {
|
||||
field public static final int MODE_NORMAL = 0; // 0x0
|
||||
field public static final int MODE_RINGTONE = 1; // 0x1
|
||||
field @Deprecated public static final int NUM_STREAMS = 5; // 0x5
|
||||
field public static final int PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED = 2; // 0x2
|
||||
field public static final int PLAYBACK_OFFLOAD_NOT_SUPPORTED = 0; // 0x0
|
||||
field public static final int PLAYBACK_OFFLOAD_SUPPORTED = 1; // 0x1
|
||||
field public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
|
||||
field public static final String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
|
||||
field public static final String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
|
||||
|
||||
@@ -986,6 +986,8 @@ 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 OFFLOAD_GAPLESS_SUPPORTED = 2; // 0x2
|
||||
field public static final int OFFLOAD_SUPPORTED = 1; // 0x1
|
||||
field public static final int STREAM_DEFAULT = -1; // 0xffffffff
|
||||
}
|
||||
|
||||
|
||||
@@ -2113,10 +2113,9 @@ android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
|
||||
(audio_devices_t)device);
|
||||
}
|
||||
|
||||
static jboolean
|
||||
android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
|
||||
jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask, jint streamType)
|
||||
{
|
||||
static jint android_media_AudioSystem_getOffloadSupport(JNIEnv *env, jobject thiz, jint encoding,
|
||||
jint sampleRate, jint channelMask,
|
||||
jint channelIndexMask, jint streamType) {
|
||||
audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
|
||||
format.format = (audio_format_t) audioFormatToNative(encoding);
|
||||
format.sample_rate = (uint32_t) sampleRate;
|
||||
@@ -2128,7 +2127,7 @@ android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
|
||||
// client side code cannot access "audio.offload.min.duration.secs" property to make a query
|
||||
// agnostic of duration, so using acceptable estimate of 2mn
|
||||
format.duration_us = 120 * 1000000;
|
||||
return AudioSystem::isOffloadSupported(format);
|
||||
return AudioSystem::getOffloadSupport(format);
|
||||
}
|
||||
|
||||
static jint
|
||||
@@ -2604,8 +2603,8 @@ static const JNINativeMethod gMethods[] =
|
||||
(void *)android_media_AudioSystem_registerRecordingCallback},
|
||||
{"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
|
||||
{"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
|
||||
{"native_is_offload_supported", "(IIIII)Z",
|
||||
(void *)android_media_AudioSystem_isOffloadSupported},
|
||||
{"native_get_offload_support", "(IIIII)I",
|
||||
(void *)android_media_AudioSystem_getOffloadSupport},
|
||||
{"getMicrophones", "(Ljava/util/ArrayList;)I",
|
||||
(void *)android_media_AudioSystem_getMicrophones},
|
||||
{"getSurroundFormats", "(Ljava/util/Map;Z)I",
|
||||
|
||||
@@ -2319,7 +2319,55 @@ public class AudioManager {
|
||||
if (attributes == null) {
|
||||
throw new NullPointerException("Illegal null AudioAttributes");
|
||||
}
|
||||
return AudioSystem.isOffloadSupported(format, attributes);
|
||||
return AudioSystem.getOffloadSupport(format, attributes) != PLAYBACK_OFFLOAD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
|
||||
offload playback not supported */
|
||||
public static final int PLAYBACK_OFFLOAD_NOT_SUPPORTED = AudioSystem.OFFLOAD_NOT_SUPPORTED;
|
||||
/** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
|
||||
offload playback supported */
|
||||
public static final int PLAYBACK_OFFLOAD_SUPPORTED = AudioSystem.OFFLOAD_SUPPORTED;
|
||||
/** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
|
||||
offload playback supported with gapless transitions */
|
||||
public static final int PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED =
|
||||
AudioSystem.OFFLOAD_GAPLESS_SUPPORTED;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(flag = false, prefix = "PLAYBACK_OFFLOAD_", value = {
|
||||
PLAYBACK_OFFLOAD_NOT_SUPPORTED,
|
||||
PLAYBACK_OFFLOAD_SUPPORTED,
|
||||
PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED }
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AudioOffloadMode {}
|
||||
|
||||
/**
|
||||
* Returns whether offloaded playback of an audio format is supported on the device or not and
|
||||
* when supported whether gapless transitions are possible or not.
|
||||
* <p>Offloaded playback is the feature where the decoding and playback of an audio stream
|
||||
* is not competing with other software resources. In general, it is supported by dedicated
|
||||
* hardware, such as audio DSPs.
|
||||
* <p>Note that this query only provides information about the support of an audio format,
|
||||
* it does not indicate whether the resources necessary for the offloaded playback are
|
||||
* available at that instant.
|
||||
* @param format the audio format (codec, sample rate, channels) being checked.
|
||||
* @param attributes the {@link AudioAttributes} to be used for playback
|
||||
* @return {@link #PLAYBACK_OFFLOAD_NOT_SUPPORTED} if offload playback if not supported,
|
||||
* {@link #PLAYBACK_OFFLOAD_SUPPORTED} if offload playback is supported or
|
||||
* {@link #PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED} if gapless transitions are
|
||||
* also supported.
|
||||
*/
|
||||
@AudioOffloadMode
|
||||
public static int getPlaybackOffloadSupport(@NonNull AudioFormat format,
|
||||
@NonNull AudioAttributes attributes) {
|
||||
if (format == null) {
|
||||
throw new NullPointerException("Illegal null AudioFormat");
|
||||
}
|
||||
if (attributes == null) {
|
||||
throw new NullPointerException("Illegal null AudioAttributes");
|
||||
}
|
||||
return AudioSystem.getOffloadSupport(format, attributes);
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
|
||||
@@ -1636,13 +1636,22 @@ public class AudioSystem
|
||||
*/
|
||||
public static native int setAllowedCapturePolicy(int uid, int flags);
|
||||
|
||||
static boolean isOffloadSupported(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
|
||||
return native_is_offload_supported(format.getEncoding(), format.getSampleRate(),
|
||||
/**
|
||||
* @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_GAPLESS_SUPPORTED = 2;
|
||||
|
||||
static int getOffloadSupport(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
|
||||
return native_get_offload_support(format.getEncoding(), format.getSampleRate(),
|
||||
format.getChannelMask(), format.getChannelIndexMask(),
|
||||
attr.getVolumeControlStream());
|
||||
}
|
||||
|
||||
private static native boolean native_is_offload_supported(int encoding, int sampleRate,
|
||||
private static native int native_get_offload_support(int encoding, int sampleRate,
|
||||
int channelMask, int channelIndexMask, int streamType);
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -1256,7 +1256,8 @@ public class AudioTrack extends PlayerBase
|
||||
throw new UnsupportedOperationException(
|
||||
"Offload and low latency modes are incompatible");
|
||||
}
|
||||
if (!AudioSystem.isOffloadSupported(mFormat, mAttributes)) {
|
||||
if (AudioSystem.getOffloadSupport(mFormat, mAttributes)
|
||||
== AudioSystem.OFFLOAD_NOT_SUPPORTED) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot create AudioTrack, offload format / attributes not supported");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user