private void updateLoadControl() { long now = SystemClock.elapsedRealtime(); long nextLoadPositionUs = getNextLoadPositionUs(); boolean isBackedOff = currentLoadableException != null; boolean loadingOrBackedOff = loader.isLoading() || isBackedOff; // If we're not loading or backed off, evaluate the operation if (a) we don't have the next // chunk yet and we're not finished, or (b) if the last evaluation was over 2000ms ago. if (!loadingOrBackedOff && ((currentLoadableHolder.chunk == null && nextLoadPositionUs != -1) || (now - lastPerformedBufferOperation > 2000))) { // Perform the evaluation. lastPerformedBufferOperation = now; doChunkOperation(); boolean chunksDiscarded = discardUpstreamMediaChunks(currentLoadableHolder.queueSize); // Update the next load position as appropriate. if (currentLoadableHolder.chunk == null) { // Set loadPosition to -1 to indicate that we don't have anything to load. nextLoadPositionUs = -1; } else if (chunksDiscarded) { // Chunks were discarded, so we need to re-evaluate the load position. nextLoadPositionUs = getNextLoadPositionUs(); } } // Update the control with our current state, and determine whether we're the next loader. boolean nextLoader = loadControl.update(this, downstreamPositionUs, nextLoadPositionUs, loadingOrBackedOff); if (isBackedOff) { long elapsedMillis = now - currentLoadableExceptionTimestamp; if (elapsedMillis >= getRetryDelayMillis(currentLoadableExceptionCount)) { resumeFromBackOff(); } return; } if (!loader.isLoading() && nextLoader) { maybeStartLoading(); } }
private void restartFrom(long positionUs) { pendingResetPositionUs = positionUs; loadingFinished = false; if (loader.isLoading()) { loader.cancelLoading(); } else { sampleQueue.clear(); mediaChunks.clear(); clearCurrentLoadable(); updateLoadControl(); } }
@Override public void disable(int track) { Assertions.checkState(state == STATE_ENABLED); Assertions.checkState(--enabledTrackCount == 0); state = STATE_PREPARED; try { chunkSource.disable(mediaChunks); } finally { loadControl.unregister(this); if (loader.isLoading()) { loader.cancelLoading(); } else { sampleQueue.clear(); mediaChunks.clear(); clearCurrentLoadable(); loadControl.trimAllocator(); } } }