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); }
@Override public int readData( int track, long positionUs, MediaFormatHolder formatHolder, SampleHolder sampleHolder) { Assertions.checkState(state == STATE_ENABLED); downstreamPositionUs = positionUs; if (pendingDiscontinuity || isPendingReset()) { return NOTHING_READ; } boolean haveSamples = !sampleQueue.isEmpty(); BaseMediaChunk currentChunk = mediaChunks.getFirst(); while (haveSamples && mediaChunks.size() > 1 && mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) { mediaChunks.removeFirst(); currentChunk = mediaChunks.getFirst(); } Format format = currentChunk.format; if (!format.equals(downstreamFormat)) { notifyDownstreamFormatChanged(format, currentChunk.trigger, currentChunk.startTimeUs); } downstreamFormat = format; if (haveSamples || currentChunk.isMediaFormatFinal) { MediaFormat mediaFormat = currentChunk.getMediaFormat(); if (!mediaFormat.equals(downstreamMediaFormat)) { formatHolder.format = mediaFormat; formatHolder.drmInitData = currentChunk.getDrmInitData(); downstreamMediaFormat = mediaFormat; return FORMAT_READ; } // If mediaFormat and downstreamMediaFormat are equal but different objects then the equality // check above will have been expensive, comparing the fields in each format. We update // downstreamMediaFormat here so that referential equality can be cheaply established during // subsequent calls. downstreamMediaFormat = mediaFormat; } if (!haveSamples) { if (loadingFinished) { return END_OF_STREAM; } return NOTHING_READ; } if (sampleQueue.getSample(sampleHolder)) { boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs; sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; onSampleRead(currentChunk, sampleHolder); return SAMPLE_READ; } return NOTHING_READ; }
/** * Discard upstream media chunks until the queue length is equal to the length specified. * * @param queueLength The desired length of the queue. * @return True if chunks were discarded. False otherwise. */ private boolean discardUpstreamMediaChunks(int queueLength) { if (mediaChunks.size() <= queueLength) { return false; } long startTimeUs = 0; long endTimeUs = mediaChunks.getLast().endTimeUs; BaseMediaChunk removed = null; while (mediaChunks.size() > queueLength) { removed = mediaChunks.removeLast(); startTimeUs = removed.startTimeUs; loadingFinished = false; } sampleQueue.discardUpstreamSamples(removed.getFirstSampleIndex()); notifyUpstreamDiscarded(startTimeUs, endTimeUs); return true; }