Fix offload buffer full detection after setEndOfStream
This issue has been observed on a test app stress testing setEndOfStream. The issue has not been observed on ExoPlayer, probably due to timing differences, but it is fixed preventively. #exo-offload PiperOrigin-RevId: 333472136
This commit is contained in:
parent
c76bc43de6
commit
3be2463a94
@ -336,6 +336,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
private boolean tunneling;
|
private boolean tunneling;
|
||||||
private long lastFeedElapsedRealtimeMs;
|
private long lastFeedElapsedRealtimeMs;
|
||||||
private boolean offloadDisabledUntilNextConfiguration;
|
private boolean offloadDisabledUntilNextConfiguration;
|
||||||
|
private boolean isWaitingForOffloadEndOfStreamHandled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new default audio sink.
|
* Creates a new default audio sink.
|
||||||
@ -712,6 +713,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
audioTrack.setOffloadEndOfStream();
|
audioTrack.setOffloadEndOfStream();
|
||||||
audioTrack.setOffloadDelayPadding(
|
audioTrack.setOffloadDelayPadding(
|
||||||
configuration.inputFormat.encoderDelay, configuration.inputFormat.encoderPadding);
|
configuration.inputFormat.encoderDelay, configuration.inputFormat.encoderPadding);
|
||||||
|
isWaitingForOffloadEndOfStreamHandled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Re-apply playback parameters.
|
// Re-apply playback parameters.
|
||||||
@ -932,13 +934,26 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
throw new WriteException(bytesWritten);
|
throw new WriteException(bytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playing
|
if (isOffloadedPlayback(audioTrack)) {
|
||||||
&& listener != null
|
// After calling AudioTrack.setOffloadEndOfStream, the AudioTrack internally stops and
|
||||||
&& bytesWritten < bytesRemaining
|
// restarts during which AudioTrack.write will return 0. This situation must be detected to
|
||||||
&& isOffloadedPlayback(audioTrack)) {
|
// prevent reporting the buffer as full even though it is not which could lead ExoPlayer to
|
||||||
long pendingDurationMs =
|
// sleep forever waiting for a onDataRequest that will never come.
|
||||||
audioTrackPositionTracker.getPendingBufferDurationMs(writtenEncodedFrames);
|
if (writtenEncodedFrames > 0) {
|
||||||
listener.onOffloadBufferFull(pendingDurationMs);
|
isWaitingForOffloadEndOfStreamHandled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider the offload buffer as full if the AudioTrack is playing and AudioTrack.write could
|
||||||
|
// not write all the data provided to it. This relies on the assumption that AudioTrack.write
|
||||||
|
// always writes as much as possible.
|
||||||
|
if (playing
|
||||||
|
&& listener != null
|
||||||
|
&& bytesWritten < bytesRemaining
|
||||||
|
&& !isWaitingForOffloadEndOfStreamHandled) {
|
||||||
|
long pendingDurationMs =
|
||||||
|
audioTrackPositionTracker.getPendingBufferDurationMs(writtenEncodedFrames);
|
||||||
|
listener.onOffloadBufferFull(pendingDurationMs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.outputMode == OUTPUT_MODE_PCM) {
|
if (configuration.outputMode == OUTPUT_MODE_PCM) {
|
||||||
@ -1221,6 +1236,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
submittedEncodedFrames = 0;
|
submittedEncodedFrames = 0;
|
||||||
writtenPcmBytes = 0;
|
writtenPcmBytes = 0;
|
||||||
writtenEncodedFrames = 0;
|
writtenEncodedFrames = 0;
|
||||||
|
isWaitingForOffloadEndOfStreamHandled = false;
|
||||||
framesPerEncodedSample = 0;
|
framesPerEncodedSample = 0;
|
||||||
mediaPositionParameters =
|
mediaPositionParameters =
|
||||||
new MediaPositionParameters(
|
new MediaPositionParameters(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user