Commit 03a1a3ee by krocard Committed by kim-vde

Temporary disable offload after failure

PiperOrigin-RevId: 325429029
parent 805cfb02
...@@ -336,6 +336,15 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -336,6 +336,15 @@ public final class DefaultAudioSink implements AudioSink {
private AuxEffectInfo auxEffectInfo; private AuxEffectInfo auxEffectInfo;
private boolean tunneling; private boolean tunneling;
private long lastFeedElapsedRealtimeMs; private long lastFeedElapsedRealtimeMs;
/**
* Do not retrying offload if it just failed.
*
* <p>{@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,
* android.media.AudioAttributes)} does not guaranty that offload is available (eg: using {@link
* android.media.AudioPlaybackCaptureConfiguration}) will disable offload. As a result only try
* once per track/seek to play in offload mode.
*/
private boolean disableOffloadAfterFailureUntilNextConfiguration;
/** /**
* Creates a new default audio sink. * Creates a new default audio sink.
...@@ -459,7 +468,9 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -459,7 +468,9 @@ public final class DefaultAudioSink implements AudioSink {
// guaranteed to support. // guaranteed to support.
return SINK_FORMAT_SUPPORTED_WITH_TRANSCODING; return SINK_FORMAT_SUPPORTED_WITH_TRANSCODING;
} }
if (enableOffload && isOffloadedPlaybackSupported(format, audioAttributes)) { if (enableOffload
&& !disableOffloadAfterFailureUntilNextConfiguration
&& isOffloadedPlaybackSupported(format, audioAttributes)) {
return SINK_FORMAT_SUPPORTED_DIRECTLY; return SINK_FORMAT_SUPPORTED_DIRECTLY;
} }
if (isPassthroughPlaybackSupported(format, audioCapabilities)) { if (isPassthroughPlaybackSupported(format, audioCapabilities)) {
...@@ -566,6 +577,9 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -566,6 +577,9 @@ public final class DefaultAudioSink implements AudioSink {
throw new ConfigurationException( throw new ConfigurationException(
"Invalid output channel config (mode=" + outputMode + ") for: " + inputFormat); "Invalid output channel config (mode=" + outputMode + ") for: " + inputFormat);
} }
disableOffloadAfterFailureUntilNextConfiguration = false;
Configuration pendingConfiguration = Configuration pendingConfiguration =
new Configuration( new Configuration(
inputPcmFrameSize, inputPcmFrameSize,
...@@ -619,9 +633,7 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -619,9 +633,7 @@ public final class DefaultAudioSink implements AudioSink {
// initialization of the audio track to fail. // initialization of the audio track to fail.
releasingConditionVariable.block(); releasingConditionVariable.block();
audioTrack = audioTrack = buildAudioTrack();
Assertions.checkNotNull(configuration)
.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
if (isOffloadedPlayback(audioTrack)) { if (isOffloadedPlayback(audioTrack)) {
registerStreamEventCallbackV29(audioTrack); registerStreamEventCallbackV29(audioTrack);
audioTrack.setOffloadDelayPadding(configuration.trimStartFrames, configuration.trimEndFrames); audioTrack.setOffloadDelayPadding(configuration.trimStartFrames, configuration.trimEndFrames);
...@@ -813,6 +825,18 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -813,6 +825,18 @@ public final class DefaultAudioSink implements AudioSink {
return false; return false;
} }
private AudioTrack buildAudioTrack() throws InitializationException {
try {
return Assertions.checkNotNull(configuration)
.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
} catch (InitializationException e) {
if (configuration.outputModeIsOffload()) {
disableOffloadAfterFailureUntilNextConfiguration = true;
}
throw e;
}
}
@RequiresApi(29) @RequiresApi(29)
private void registerStreamEventCallbackV29(AudioTrack audioTrack) { private void registerStreamEventCallbackV29(AudioTrack audioTrack) {
if (offloadStreamEventCallbackV29 == null) { if (offloadStreamEventCallbackV29 == null) {
...@@ -898,6 +922,10 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -898,6 +922,10 @@ public final class DefaultAudioSink implements AudioSink {
lastFeedElapsedRealtimeMs = SystemClock.elapsedRealtime(); lastFeedElapsedRealtimeMs = SystemClock.elapsedRealtime();
if (bytesWritten < 0) { if (bytesWritten < 0) {
boolean isRecoverable = isAudioTrackDeadObject(bytesWritten);
if (isRecoverable && configuration.outputModeIsOffload()) {
disableOffloadAfterFailureUntilNextConfiguration = true;
}
throw new WriteException(bytesWritten); throw new WriteException(bytesWritten);
} }
...@@ -932,6 +960,10 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -932,6 +960,10 @@ public final class DefaultAudioSink implements AudioSink {
} }
} }
private static boolean isAudioTrackDeadObject(int status) {
return Util.SDK_INT >= 24 && status == AudioTrack.ERROR_DEAD_OBJECT;
}
private boolean drainToEndOfStream() throws WriteException { private boolean drainToEndOfStream() throws WriteException {
boolean audioProcessorNeedsEndOfStream = false; boolean audioProcessorNeedsEndOfStream = false;
if (drainingAudioProcessorIndex == C.INDEX_UNSET) { if (drainingAudioProcessorIndex == C.INDEX_UNSET) {
...@@ -1143,6 +1175,7 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1143,6 +1175,7 @@ public final class DefaultAudioSink implements AudioSink {
} }
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = C.AUDIO_SESSION_ID_UNSET;
playing = false; playing = false;
disableOffloadAfterFailureUntilNextConfiguration = false;
} }
// Internal methods. // Internal methods.
...@@ -1771,12 +1804,11 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1771,12 +1804,11 @@ public final class DefaultAudioSink implements AudioSink {
boolean tunneling, AudioAttributes audioAttributes, int audioSessionId) boolean tunneling, AudioAttributes audioAttributes, int audioSessionId)
throws InitializationException { throws InitializationException {
AudioTrack audioTrack; AudioTrack audioTrack;
if (Util.SDK_INT >= 29) { try {
audioTrack = createAudioTrackV29(tunneling, audioAttributes, audioSessionId); audioTrack = createAudioTrack(tunneling, audioAttributes, audioSessionId);
} else if (Util.SDK_INT >= 21) { } catch (UnsupportedOperationException e) {
audioTrack = createAudioTrackV21(tunneling, audioAttributes, audioSessionId); throw new InitializationException(
} else { AudioTrack.STATE_UNINITIALIZED, outputSampleRate, outputChannelConfig, bufferSize);
audioTrack = createAudioTrack(audioAttributes, audioSessionId);
} }
int state = audioTrack.getState(); int state = audioTrack.getState();
...@@ -1792,6 +1824,17 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1792,6 +1824,17 @@ public final class DefaultAudioSink implements AudioSink {
return audioTrack; return audioTrack;
} }
private AudioTrack createAudioTrack(
boolean tunneling, AudioAttributes audioAttributes, int audioSessionId) {
if (Util.SDK_INT >= 29) {
return createAudioTrackV29(tunneling, audioAttributes, audioSessionId);
} else if (Util.SDK_INT >= 21) {
return createAudioTrackV21(tunneling, audioAttributes, audioSessionId);
} else {
return createAudioTrackV9(audioAttributes, audioSessionId);
}
}
@RequiresApi(29) @RequiresApi(29)
private AudioTrack createAudioTrackV29( private AudioTrack createAudioTrackV29(
boolean tunneling, AudioAttributes audioAttributes, int audioSessionId) { boolean tunneling, AudioAttributes audioAttributes, int audioSessionId) {
...@@ -1820,7 +1863,7 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1820,7 +1863,7 @@ public final class DefaultAudioSink implements AudioSink {
audioSessionId); audioSessionId);
} }
private AudioTrack createAudioTrack(AudioAttributes audioAttributes, int audioSessionId) { private AudioTrack createAudioTrackV9(AudioAttributes audioAttributes, int audioSessionId) {
int streamType = Util.getStreamTypeForAudioUsage(audioAttributes.usage); int streamType = Util.getStreamTypeForAudioUsage(audioAttributes.usage);
if (audioSessionId == C.AUDIO_SESSION_ID_UNSET) { if (audioSessionId == C.AUDIO_SESSION_ID_UNSET) {
return new AudioTrack( return new AudioTrack(
...@@ -1896,5 +1939,9 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1896,5 +1939,9 @@ public final class DefaultAudioSink implements AudioSink {
.setUsage(android.media.AudioAttributes.USAGE_MEDIA) .setUsage(android.media.AudioAttributes.USAGE_MEDIA)
.build(); .build();
} }
public boolean outputModeIsOffload() {
return outputMode == OUTPUT_MODE_OFFLOAD;
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment