private void maybeStartLoading() { Chunk currentLoadable = currentLoadableHolder.chunk; if (currentLoadable == null) { // Nothing to load. return; } currentLoadStartTimeMs = SystemClock.elapsedRealtime(); if (isMediaChunk(currentLoadable)) { BaseMediaChunk mediaChunk = (BaseMediaChunk) currentLoadable; mediaChunk.init(sampleQueue); mediaChunks.add(mediaChunk); if (isPendingReset()) { pendingResetPositionUs = NO_RESET_PENDING; } notifyLoadStarted( mediaChunk.dataSpec.length, mediaChunk.type, mediaChunk.trigger, mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs); } else { notifyLoadStarted( currentLoadable.dataSpec.length, currentLoadable.type, currentLoadable.trigger, currentLoadable.format, -1, -1); } loader.startLoading(currentLoadable, this); }
/** * Resumes loading. * * <p>If the {@link ChunkSource} returns a chunk equivalent to the backed off chunk B, then the * loading of B will be resumed. In all other cases B will be discarded and the new chunk will be * loaded. */ private void resumeFromBackOff() { currentLoadableException = null; Chunk backedOffChunk = currentLoadableHolder.chunk; if (!isMediaChunk(backedOffChunk)) { doChunkOperation(); discardUpstreamMediaChunks(currentLoadableHolder.queueSize); if (currentLoadableHolder.chunk == backedOffChunk) { // Chunk was unchanged. Resume loading. loader.startLoading(backedOffChunk, this); } else { // Chunk was changed. Notify that the existing load was canceled. notifyLoadCanceled(backedOffChunk.bytesLoaded()); // Start loading the replacement. maybeStartLoading(); } return; } if (backedOffChunk == mediaChunks.getFirst()) { // We're not able to clear the first media chunk, so we have no choice but to continue // loading it. loader.startLoading(backedOffChunk, this); return; } // The current loadable is the last media chunk. Remove it before we invoke the chunk source, // and add it back again afterwards. BaseMediaChunk removedChunk = mediaChunks.removeLast(); Assertions.checkState(backedOffChunk == removedChunk); doChunkOperation(); mediaChunks.add(removedChunk); if (currentLoadableHolder.chunk == backedOffChunk) { // Chunk was unchanged. Resume loading. loader.startLoading(backedOffChunk, this); } else { // Chunk was changed. Notify that the existing load was canceled. notifyLoadCanceled(backedOffChunk.bytesLoaded()); // This call will remove and release at least one chunk from the end of mediaChunks. Since // the current loadable is the last media chunk, it is guaranteed to be removed. discardUpstreamMediaChunks(currentLoadableHolder.queueSize); clearCurrentLoadableException(); maybeStartLoading(); } }