Accurately determine hasPendingData after handling the end of stream

In `AudioTrackPositionTracker.hasPendingData()` method, `sourceEnded=false` is always passed. Thus, if the `AudioTimestampPoller` hasn't entered the `STATE_TIMESTAMP_ADVANCING` before the stream ends, then the current position can be inaccurately calculated in the absence of a correct `sourceEnded` value, and `AudioTrackPositionTracker.hasPendingData` will return a wrong result.

We used to avoid calling `getPlayheadPosition()` too often, which involves expensive binder request. However, here we need to adjust a bit back to compare the `writtenFrames` directly with `getPlayheadPosition()` after handling the end of stream, when not being able to declare `sourceEnded=true` can have significant difference.

PiperOrigin-RevId: 715358137
This commit is contained in:
tianyifeng 2025-01-14 06:33:48 -08:00 committed by Copybara-Service
parent adb9306e2d
commit f05e6a7d6e

View File

@ -450,9 +450,13 @@ import java.lang.reflect.Method;
* @return Whether the audio track has any pending data to play out.
*/
public boolean hasPendingData(long writtenFrames) {
long currentPositionUs = getCurrentPositionUs(/* sourceEnded= */ false);
return writtenFrames > durationUsToSampleCount(currentPositionUs, outputSampleRate)
|| forceHasPendingData();
if (stopTimestampUs != C.TIME_UNSET) {
return writtenFrames > getPlaybackHeadPosition() || forceHasPendingData();
} else {
long currentPositionUs = getCurrentPositionUs(/* sourceEnded= */ false);
return writtenFrames > durationUsToSampleCount(currentPositionUs, outputSampleRate)
|| forceHasPendingData();
}
}
/**