@Override public void onLoadCompleted(Loadable loadable) { long now = SystemClock.elapsedRealtime(); long loadDurationMs = now - currentLoadStartTimeMs; Chunk currentLoadable = currentLoadableHolder.chunk; chunkSource.onChunkLoadCompleted(currentLoadable); if (isMediaChunk(currentLoadable)) { BaseMediaChunk mediaChunk = (BaseMediaChunk) currentLoadable; notifyLoadCompleted( currentLoadable.bytesLoaded(), mediaChunk.type, mediaChunk.trigger, mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs, now, loadDurationMs); } else { notifyLoadCompleted( currentLoadable.bytesLoaded(), currentLoadable.type, currentLoadable.trigger, currentLoadable.format, -1, -1, now, loadDurationMs); } clearCurrentLoadable(); updateLoadControl(); }
/** * 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(); } }
@Override public void onLoadCanceled(Loadable loadable) { Chunk currentLoadable = currentLoadableHolder.chunk; notifyLoadCanceled(currentLoadable.bytesLoaded()); clearCurrentLoadable(); if (state == STATE_ENABLED) { restartFrom(pendingResetPositionUs); } else { sampleQueue.clear(); mediaChunks.clear(); clearCurrentLoadable(); loadControl.trimAllocator(); } }