diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 49fa49ba771..80aa49f3f43 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -10,20 +10,16 @@ `PlayerControlView`. * Change playback controls toggle from touch down to touch up events ([#5784](https://github.com/google/ExoPlayer/issues/5784)). -<<<<<<< HEAD * Fix issue where playback controls were not kept visible on key presses ([#5963](https://github.com/google/ExoPlayer/issues/5963)). -======= -* Add a workaround for broken raw audio decoding on Oppo R9 - ([#5782](https://github.com/google/ExoPlayer/issues/5782)). * Offline: - * Add Scheduler implementation which uses WorkManager. * Prevent unexpected `DownloadHelper.Callback.onPrepared` callbacks after the preparation of the `DownloadHelper` failed ([#5915](https://github.com/google/ExoPlayer/issues/5915)). * Fix CacheUtil.cache() use too much data ([#5927](https://github.com/google/ExoPlayer/issues/5927)). ->>>>>>> 42ba6abf5... Fix CacheUtil.cache() use too much data + * 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 diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java index 5b066b79301..47470c5de75 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java @@ -268,6 +268,8 @@ private static long readAndDiscard( 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 @@ private static long readAndDiscard( } 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 {