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)). ([#5915](https://github.com/google/ExoPlayer/issues/5915)).
* Fix CacheUtil.cache() use too much data * Fix CacheUtil.cache() use too much data
([#5927](https://github.com/google/ExoPlayer/issues/5927)). ([#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 * Add a playWhenReady flag to MediaSessionConnector.PlaybackPreparer methods
to indicate whether a controller sent a play or only a prepare command. This to indicate whether a controller sent a play or only a prepare command. This
allows to take advantage of decoder reuse with the MediaSessionConnector allows to take advantage of decoder reuse with the MediaSessionConnector

View File

@ -268,6 +268,8 @@ public final class CacheUtil {
AtomicBoolean isCanceled) AtomicBoolean isCanceled)
throws IOException, InterruptedException { throws IOException, InterruptedException {
long positionOffset = absoluteStreamPosition - dataSpec.absoluteStreamPosition; long positionOffset = absoluteStreamPosition - dataSpec.absoluteStreamPosition;
long initialPositionOffset = positionOffset;
long endOffset = length != C.LENGTH_UNSET ? positionOffset + length : C.POSITION_UNSET;
while (true) { while (true) {
if (priorityTaskManager != null) { if (priorityTaskManager != null) {
// Wait for any other thread with higher priority to finish its job. // Wait for any other thread with higher priority to finish its job.
@ -275,45 +277,51 @@ public final class CacheUtil {
} }
throwExceptionIfInterruptedOrCancelled(isCanceled); throwExceptionIfInterruptedOrCancelled(isCanceled);
try { try {
long resolvedLength; 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 { try {
resolvedLength = dataSource.open(dataSpec.subrange(positionOffset, length)); resolvedLength =
dataSource.open(dataSpec.subrange(positionOffset, endOffset - positionOffset));
isDataSourceOpen = true;
} catch (IOException exception) { } catch (IOException exception) {
if (length == C.LENGTH_UNSET if (!isLastBlock || !isCausedByPositionOutOfRange(exception)) {
|| !isLastBlock
|| !isCausedByPositionOutOfRange(exception)) {
throw 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)); resolvedLength = dataSource.open(dataSpec.subrange(positionOffset, C.LENGTH_UNSET));
} }
if (isLastBlock && progressNotifier != null && resolvedLength != C.LENGTH_UNSET) { if (isLastBlock && progressNotifier != null && resolvedLength != C.LENGTH_UNSET) {
progressNotifier.onRequestLengthResolved(positionOffset + resolvedLength); progressNotifier.onRequestLengthResolved(positionOffset + resolvedLength);
} }
long totalBytesRead = 0; while (positionOffset != endOffset) {
while (totalBytesRead != length) {
throwExceptionIfInterruptedOrCancelled(isCanceled); throwExceptionIfInterruptedOrCancelled(isCanceled);
int bytesRead = int bytesRead =
dataSource.read( dataSource.read(
buffer, buffer,
0, 0,
length != C.LENGTH_UNSET endOffset != C.POSITION_UNSET
? (int) Math.min(buffer.length, length - totalBytesRead) ? (int) Math.min(buffer.length, endOffset - positionOffset)
: buffer.length); : buffer.length);
if (bytesRead == C.RESULT_END_OF_INPUT) { if (bytesRead == C.RESULT_END_OF_INPUT) {
if (progressNotifier != null) { if (progressNotifier != null) {
progressNotifier.onRequestLengthResolved(positionOffset + totalBytesRead); progressNotifier.onRequestLengthResolved(positionOffset);
} }
break; break;
} }
totalBytesRead += bytesRead; positionOffset += bytesRead;
if (progressNotifier != null) { if (progressNotifier != null) {
progressNotifier.onBytesCached(bytesRead); progressNotifier.onBytesCached(bytesRead);
} }
} }
return totalBytesRead; return positionOffset - initialPositionOffset;
} catch (PriorityTaskManager.PriorityTooLowException exception) { } catch (PriorityTaskManager.PriorityTooLowException exception) {
// catch and try again // catch and try again
} finally { } finally {