Use Android 12's AudioManager.getPlaybackOffloadSupport
Previously gapless offload support was hardcoded to Pixel only. PiperOrigin-RevId: 397070378
This commit is contained in:
parent
f8dde8ed5f
commit
4455554e9e
@ -459,6 +459,26 @@ public final class C {
|
|||||||
public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE =
|
public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE =
|
||||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
|
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Playback offload mode. One of {@link #PLAYBACK_OFFLOAD_NOT_SUPPORTED},{@link
|
||||||
|
* PLAYBACK_OFFLOAD_SUPPORTED} or {@link PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED}.
|
||||||
|
*/
|
||||||
|
@IntDef({
|
||||||
|
PLAYBACK_OFFLOAD_NOT_SUPPORTED,
|
||||||
|
PLAYBACK_OFFLOAD_SUPPORTED,
|
||||||
|
PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED
|
||||||
|
})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface AudioManagerOffloadMode {}
|
||||||
|
/** See AudioManager#PLAYBACK_OFFLOAD_NOT_SUPPORTED */
|
||||||
|
public static final int PLAYBACK_OFFLOAD_NOT_SUPPORTED =
|
||||||
|
AudioManager.PLAYBACK_OFFLOAD_NOT_SUPPORTED;
|
||||||
|
/** See AudioManager#PLAYBACK_OFFLOAD_SUPPORTED */
|
||||||
|
public static final int PLAYBACK_OFFLOAD_SUPPORTED = AudioManager.PLAYBACK_OFFLOAD_SUPPORTED;
|
||||||
|
/** See AudioManager#PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED */
|
||||||
|
public static final int PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED =
|
||||||
|
AudioManager.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags which can apply to a buffer containing a media sample. Possible flag values are {@link
|
* Flags which can apply to a buffer containing a media sample. Possible flag values are {@link
|
||||||
* #BUFFER_FLAG_KEY_FRAME}, {@link #BUFFER_FLAG_END_OF_STREAM}, {@link #BUFFER_FLAG_LAST_SAMPLE},
|
* #BUFFER_FLAG_KEY_FRAME}, {@link #BUFFER_FLAG_END_OF_STREAM}, {@link #BUFFER_FLAG_LAST_SAMPLE},
|
||||||
|
@ -1619,33 +1619,41 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AudioFormat audioFormat = getAudioFormat(format.sampleRate, channelConfig, encoding);
|
AudioFormat audioFormat = getAudioFormat(format.sampleRate, channelConfig, encoding);
|
||||||
if (!AudioManager.isOffloadedPlaybackSupported(
|
|
||||||
audioFormat, audioAttributes.getAudioAttributesV21())) {
|
switch (getOffloadedPlaybackSupport(audioFormat, audioAttributes.getAudioAttributesV21())) {
|
||||||
|
case C.PLAYBACK_OFFLOAD_NOT_SUPPORTED:
|
||||||
return false;
|
return false;
|
||||||
}
|
case C.PLAYBACK_OFFLOAD_SUPPORTED:
|
||||||
boolean isGapless = format.encoderDelay != 0 || format.encoderPadding != 0;
|
boolean isGapless = format.encoderDelay != 0 || format.encoderPadding != 0;
|
||||||
boolean offloadRequiresGaplessSupport = offloadMode == OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED;
|
boolean gaplessSupportRequired = offloadMode == OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED;
|
||||||
if (isGapless && offloadRequiresGaplessSupport && !isOffloadedGaplessPlaybackSupported()) {
|
return !isGapless || !gaplessSupportRequired;
|
||||||
return false;
|
case C.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED:
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@C.AudioManagerOffloadMode
|
||||||
|
private int getOffloadedPlaybackSupport(
|
||||||
|
AudioFormat audioFormat, android.media.AudioAttributes audioAttributes) {
|
||||||
|
if (Util.SDK_INT >= 31) {
|
||||||
|
return AudioManager.getPlaybackOffloadSupport(audioFormat, audioAttributes);
|
||||||
|
}
|
||||||
|
if (!AudioManager.isOffloadedPlaybackSupported(audioFormat, audioAttributes)) {
|
||||||
|
return C.PLAYBACK_OFFLOAD_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
// Manual testing has shown that Pixels on Android 11 support gapless offload.
|
||||||
|
if (Util.SDK_INT == 30 && Util.MODEL.startsWith("Pixel")) {
|
||||||
|
return C.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED;
|
||||||
|
}
|
||||||
|
return C.PLAYBACK_OFFLOAD_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isOffloadedPlayback(AudioTrack audioTrack) {
|
private static boolean isOffloadedPlayback(AudioTrack audioTrack) {
|
||||||
return Util.SDK_INT >= 29 && audioTrack.isOffloadedPlayback();
|
return Util.SDK_INT >= 29 && audioTrack.isOffloadedPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the device supports gapless in offload playback.
|
|
||||||
*
|
|
||||||
* <p>Gapless offload is not supported by all devices and there is no API to query its support. As
|
|
||||||
* a result this detection is currently based on manual testing.
|
|
||||||
*/
|
|
||||||
// TODO(internal b/158191844): Add an SDK API to query offload gapless support.
|
|
||||||
private static boolean isOffloadedGaplessPlaybackSupported() {
|
|
||||||
return Util.SDK_INT >= 30 && Util.MODEL.startsWith("Pixel");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) {
|
private static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) {
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case C.ENCODING_MP3:
|
case C.ENCODING_MP3:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user