Merge "Don't wait indefinitely for audio tracks to finish playing."
This commit is contained in:
committed by
Android (Google) Code Review
commit
8dd41fb992
@@ -450,6 +450,19 @@ class AudioPlaybackHandler {
|
|||||||
*/
|
*/
|
||||||
private static final long MIN_SLEEP_TIME_MS = 20;
|
private static final long MIN_SLEEP_TIME_MS = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum increment of time to sleep while waiting for an audiotrack
|
||||||
|
* to finish playing.
|
||||||
|
*/
|
||||||
|
private static final long MAX_SLEEP_TIME_MS = 2500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum amount of time to wait for an audio track to make progress while
|
||||||
|
* it remains in PLAYSTATE_PLAYING. This should never happen in normal usage, but
|
||||||
|
* could happen in exceptional circumstances like a media_server crash.
|
||||||
|
*/
|
||||||
|
private static final long MAX_PROGRESS_WAIT_MS = MAX_SLEEP_TIME_MS;
|
||||||
|
|
||||||
private static void blockUntilDone(SynthesisMessageParams params) {
|
private static void blockUntilDone(SynthesisMessageParams params) {
|
||||||
if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
|
if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -490,16 +503,34 @@ class AudioPlaybackHandler {
|
|||||||
final AudioTrack audioTrack = params.mAudioTrack;
|
final AudioTrack audioTrack = params.mAudioTrack;
|
||||||
final int lengthInFrames = params.mBytesWritten / params.mBytesPerFrame;
|
final int lengthInFrames = params.mBytesWritten / params.mBytesPerFrame;
|
||||||
|
|
||||||
|
int previousPosition = -1;
|
||||||
int currentPosition = 0;
|
int currentPosition = 0;
|
||||||
while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames) {
|
long blockedTimeMs = 0;
|
||||||
if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
|
|
||||||
break;
|
while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames &&
|
||||||
}
|
audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
|
||||||
|
|
||||||
final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
|
final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
|
||||||
audioTrack.getSampleRate();
|
audioTrack.getSampleRate();
|
||||||
|
final long sleepTimeMs = clip(estimatedTimeMs, MIN_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS);
|
||||||
|
|
||||||
final long sleepTimeMs = Math.max(estimatedTimeMs, MIN_SLEEP_TIME_MS);
|
// Check if the audio track has made progress since the last loop
|
||||||
|
// iteration. We should then add in the amount of time that was
|
||||||
|
// spent sleeping in the last iteration.
|
||||||
|
if (currentPosition == previousPosition) {
|
||||||
|
// This works only because the sleep time that would have been calculated
|
||||||
|
// would be the same in the previous iteration too.
|
||||||
|
blockedTimeMs += sleepTimeMs;
|
||||||
|
// If we've taken too long to make progress, bail.
|
||||||
|
if (blockedTimeMs > MAX_PROGRESS_WAIT_MS) {
|
||||||
|
Log.w(TAG, "Waited unsuccessfully for " + MAX_PROGRESS_WAIT_MS + "ms " +
|
||||||
|
"for AudioTrack to make progress, Aborting");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blockedTimeMs = 0;
|
||||||
|
}
|
||||||
|
previousPosition = currentPosition;
|
||||||
|
|
||||||
if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
|
if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
|
||||||
" Playback position : " + currentPosition + ", Length in frames : "
|
" Playback position : " + currentPosition + ", Length in frames : "
|
||||||
@@ -512,6 +543,18 @@ class AudioPlaybackHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final long clip(long value, long min, long max) {
|
||||||
|
if (value < min) {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > max) {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) {
|
private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) {
|
||||||
final int channelConfig = getChannelConfig(params.mChannelCount);
|
final int channelConfig = getChannelConfig(params.mChannelCount);
|
||||||
final int sampleRateInHz = params.mSampleRateInHz;
|
final int sampleRateInHz = params.mSampleRateInHz;
|
||||||
|
|||||||
Reference in New Issue
Block a user