Fix misreporting cached bytes when caching is paused

When caching is resumed, it starts from the initial position. This makes
more data to be reported as cached.

Issue:#5573
PiperOrigin-RevId: 250678841
This commit is contained in:
eguven 2019-05-30 14:41:03 +01:00 committed by Toni
parent 126aad5882
commit f9d6f314e2
2 changed files with 28 additions and 18 deletions

View File

@ -37,6 +37,8 @@
([#5915](https://github.com/google/ExoPlayer/issues/5915)).
* Fix CacheUtil.cache() use too much data
([#5927](https://github.com/google/ExoPlayer/issues/5927)).
* Fix misreporting cached bytes when caching is paused
([#5573](https://github.com/google/ExoPlayer/issues/5573)).
* Add a playWhenReady flag to MediaSessionConnector.PlaybackPreparer methods
to indicate whether a controller sent a play or only a prepare command. This
allows to take advantage of decoder reuse with the MediaSessionConnector

View File

@ -268,6 +268,8 @@ public final class CacheUtil {
AtomicBoolean isCanceled)
throws IOException, InterruptedException {
long positionOffset = absoluteStreamPosition - dataSpec.absoluteStreamPosition;
long initialPositionOffset = positionOffset;
long endOffset = length != C.LENGTH_UNSET ? positionOffset + length : C.POSITION_UNSET;
while (true) {
if (priorityTaskManager != null) {
// Wait for any other thread with higher priority to finish its job.
@ -275,45 +277,51 @@ public final class CacheUtil {
}
throwExceptionIfInterruptedOrCancelled(isCanceled);
try {
long resolvedLength;
try {
resolvedLength = dataSource.open(dataSpec.subrange(positionOffset, length));
} catch (IOException exception) {
if (length == C.LENGTH_UNSET
|| !isLastBlock
|| !isCausedByPositionOutOfRange(exception)) {
throw exception;
long resolvedLength = C.LENGTH_UNSET;
boolean isDataSourceOpen = false;
if (endOffset != C.POSITION_UNSET) {
// If a specific length is given, first try to open the data source for that length to
// avoid more data then required to be requested. If the given length exceeds the end of
// input we will get a "position out of range" error. In that case try to open the source
// again with unset length.
try {
resolvedLength =
dataSource.open(dataSpec.subrange(positionOffset, endOffset - positionOffset));
isDataSourceOpen = true;
} catch (IOException exception) {
if (!isLastBlock || !isCausedByPositionOutOfRange(exception)) {
throw exception;
}
Util.closeQuietly(dataSource);
}
Util.closeQuietly(dataSource);
// Retry to open the data source again, setting length to C.LENGTH_UNSET to prevent
// getting an error in case the given length exceeds the end of input.
}
if (!isDataSourceOpen) {
resolvedLength = dataSource.open(dataSpec.subrange(positionOffset, C.LENGTH_UNSET));
}
if (isLastBlock && progressNotifier != null && resolvedLength != C.LENGTH_UNSET) {
progressNotifier.onRequestLengthResolved(positionOffset + resolvedLength);
}
long totalBytesRead = 0;
while (totalBytesRead != length) {
while (positionOffset != endOffset) {
throwExceptionIfInterruptedOrCancelled(isCanceled);
int bytesRead =
dataSource.read(
buffer,
0,
length != C.LENGTH_UNSET
? (int) Math.min(buffer.length, length - totalBytesRead)
endOffset != C.POSITION_UNSET
? (int) Math.min(buffer.length, endOffset - positionOffset)
: buffer.length);
if (bytesRead == C.RESULT_END_OF_INPUT) {
if (progressNotifier != null) {
progressNotifier.onRequestLengthResolved(positionOffset + totalBytesRead);
progressNotifier.onRequestLengthResolved(positionOffset);
}
break;
}
totalBytesRead += bytesRead;
positionOffset += bytesRead;
if (progressNotifier != null) {
progressNotifier.onBytesCached(bytesRead);
}
}
return totalBytesRead;
return positionOffset - initialPositionOffset;
} catch (PriorityTaskManager.PriorityTooLowException exception) {
// catch and try again
} finally {