Add Offload gapless support

This it is enabled only on a list of
manually tested devices.
The list is empty in this CL.

*** Reason for rollforward ***

Fixed dependent cl was rolled forward.

*** Original change description ***

Rollback of 962e08d3be

*** Original commit ***

Add Offload gapless support

Confirmed to work on a Pixel 4 after enabling the feature:
 `setprop vendor.audio.offload.gapless.enabled true`

***

***

PiperOrigin-RevId: 318433123
This commit is contained in:
krocard 2020-06-26 09:55:54 +01:00 committed by Christos Tsilopoulos
parent 1c018e71d4
commit a971d09a46

View File

@ -432,7 +432,12 @@ public final class DefaultAudioSink implements AudioSink {
} }
if (enableOffload if (enableOffload
&& isOffloadedPlaybackSupported( && isOffloadedPlaybackSupported(
format.channelCount, format.sampleRate, encoding, audioAttributes)) { format.channelCount,
format.sampleRate,
encoding,
audioAttributes,
format.encoderDelay,
format.encoderPadding)) {
return true; return true;
} }
return isPassthroughPlaybackSupported(encoding, format.channelCount); return isPassthroughPlaybackSupported(encoding, format.channelCount);
@ -516,7 +521,13 @@ public final class DefaultAudioSink implements AudioSink {
boolean useOffload = boolean useOffload =
enableOffload enableOffload
&& !isInputPcm && !isInputPcm
&& isOffloadedPlaybackSupported(channelCount, sampleRate, encoding, audioAttributes); && isOffloadedPlaybackSupported(
channelCount,
sampleRate,
encoding,
audioAttributes,
trimStartFrames,
trimEndFrames);
Configuration pendingConfiguration = Configuration pendingConfiguration =
new Configuration( new Configuration(
@ -531,6 +542,8 @@ public final class DefaultAudioSink implements AudioSink {
processingEnabled, processingEnabled,
canApplyPlaybackParameters, canApplyPlaybackParameters,
availableAudioProcessors, availableAudioProcessors,
trimStartFrames,
trimEndFrames,
useOffload); useOffload);
if (isInitialized()) { if (isInitialized()) {
this.pendingConfiguration = pendingConfiguration; this.pendingConfiguration = pendingConfiguration;
@ -576,6 +589,7 @@ public final class DefaultAudioSink implements AudioSink {
.buildAudioTrack(tunneling, audioAttributes, audioSessionId); .buildAudioTrack(tunneling, audioAttributes, audioSessionId);
if (isOffloadedPlayback(audioTrack)) { if (isOffloadedPlayback(audioTrack)) {
registerStreamEventCallbackV29(audioTrack); registerStreamEventCallbackV29(audioTrack);
audioTrack.setOffloadDelayPadding(configuration.trimStartFrames, configuration.trimEndFrames);
} }
int audioSessionId = audioTrack.getAudioSessionId(); int audioSessionId = audioTrack.getAudioSessionId();
if (enablePreV21AudioSessionWorkaround) { if (enablePreV21AudioSessionWorkaround) {
@ -653,6 +667,11 @@ public final class DefaultAudioSink implements AudioSink {
// The current audio track can be reused for the new configuration. // The current audio track can be reused for the new configuration.
configuration = pendingConfiguration; configuration = pendingConfiguration;
pendingConfiguration = null; pendingConfiguration = null;
if (isOffloadedPlayback(audioTrack)) {
audioTrack.setOffloadEndOfStream();
audioTrack.setOffloadDelayPadding(
configuration.trimStartFrames, configuration.trimEndFrames);
}
} }
// Re-apply playback parameters. // Re-apply playback parameters.
applyPlaybackSpeedAndSkipSilence(presentationTimeUs); applyPlaybackSpeedAndSkipSilence(presentationTimeUs);
@ -1255,14 +1274,24 @@ public final class DefaultAudioSink implements AudioSink {
int channelCount, int channelCount,
int sampleRateHz, int sampleRateHz,
@C.Encoding int encoding, @C.Encoding int encoding,
AudioAttributes audioAttributes) { AudioAttributes audioAttributes,
int trimStartFrames,
int trimEndFrames) {
if (Util.SDK_INT < 29) { if (Util.SDK_INT < 29) {
return false; return false;
} }
int channelMask = getChannelConfig(channelCount, /* isInputPcm= */ false); int channelMask = getChannelConfig(channelCount, /* isInputPcm= */ false);
AudioFormat audioFormat = getAudioFormat(sampleRateHz, channelMask, encoding); AudioFormat audioFormat = getAudioFormat(sampleRateHz, channelMask, encoding);
return AudioManager.isOffloadedPlaybackSupported( if (!AudioManager.isOffloadedPlaybackSupported(
audioFormat, audioAttributes.getAudioAttributesV21()); audioFormat, audioAttributes.getAudioAttributesV21())) {
return false;
}
if (trimStartFrames > 0 || trimEndFrames > 0) {
// TODO(internal b/158191844): Gapless offload is not supported by all devices and there is no
// API to query its support.
return false;
}
return true;
} }
private static boolean isOffloadedPlayback(AudioTrack audioTrack) { private static boolean isOffloadedPlayback(AudioTrack audioTrack) {
@ -1579,6 +1608,8 @@ public final class DefaultAudioSink implements AudioSink {
public final boolean processingEnabled; public final boolean processingEnabled;
public final boolean canApplyPlaybackParameters; public final boolean canApplyPlaybackParameters;
public final AudioProcessor[] availableAudioProcessors; public final AudioProcessor[] availableAudioProcessors;
public int trimStartFrames;
public int trimEndFrames;
public final boolean useOffload; public final boolean useOffload;
public Configuration( public Configuration(
@ -1593,6 +1624,8 @@ public final class DefaultAudioSink implements AudioSink {
boolean processingEnabled, boolean processingEnabled,
boolean canApplyPlaybackParameters, boolean canApplyPlaybackParameters,
AudioProcessor[] availableAudioProcessors, AudioProcessor[] availableAudioProcessors,
int trimStartFrames,
int trimEndFrames,
boolean useOffload) { boolean useOffload) {
this.isInputPcm = isInputPcm; this.isInputPcm = isInputPcm;
this.inputPcmFrameSize = inputPcmFrameSize; this.inputPcmFrameSize = inputPcmFrameSize;
@ -1604,6 +1637,8 @@ public final class DefaultAudioSink implements AudioSink {
this.processingEnabled = processingEnabled; this.processingEnabled = processingEnabled;
this.canApplyPlaybackParameters = canApplyPlaybackParameters; this.canApplyPlaybackParameters = canApplyPlaybackParameters;
this.availableAudioProcessors = availableAudioProcessors; this.availableAudioProcessors = availableAudioProcessors;
this.trimStartFrames = trimStartFrames;
this.trimEndFrames = trimEndFrames;
this.useOffload = useOffload; this.useOffload = useOffload;
// Call computeBufferSize() last as it depends on the other configuration values. // Call computeBufferSize() last as it depends on the other configuration values.