Search in sources :

Example 11 with ChunkIndex

use of com.google.android.exoplayer2.extractor.ChunkIndex in project ExoPlayer by google.

the class FakeChunkSource method getNextChunk.

@Override
public void getNextChunk(long playbackPositionUs, long loadPositionUs, List<? extends MediaChunk> queue, ChunkHolder out) {
    long bufferedDurationUs = loadPositionUs - playbackPositionUs;
    int chunkIndex = queue.isEmpty() ? dataSet.getChunkIndexByPosition(playbackPositionUs) : (int) queue.get(queue.size() - 1).getNextChunkIndex();
    MediaChunkIterator[] chunkIterators = new MediaChunkIterator[trackSelection.length()];
    for (int i = 0; i < chunkIterators.length; i++) {
        int trackGroupIndex = trackSelection.getIndexInTrackGroup(i);
        chunkIterators[i] = new FakeAdaptiveDataSet.Iterator(dataSet, trackGroupIndex, chunkIndex);
    }
    trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, C.TIME_UNSET, queue, chunkIterators);
    if (chunkIndex >= dataSet.getChunkCount()) {
        out.endOfStream = true;
    } else {
        Format selectedFormat = trackSelection.getSelectedFormat();
        long startTimeUs = dataSet.getStartTime(chunkIndex);
        long endTimeUs = startTimeUs + dataSet.getChunkDuration(chunkIndex);
        int trackGroupIndex = trackSelection.getIndexInTrackGroup(trackSelection.getSelectedIndex());
        String uri = dataSet.getUri(trackGroupIndex);
        Segment fakeDataChunk = Assertions.checkStateNotNull(dataSet.getData(uri)).getSegments().get(chunkIndex);
        DataSpec dataSpec = new DataSpec(Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length);
        int trackType = MimeTypes.getTrackType(selectedFormat.sampleMimeType);
        out.chunk = new SingleSampleMediaChunk(dataSource, dataSpec, selectedFormat, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), startTimeUs, endTimeUs, chunkIndex, trackType, selectedFormat);
    }
}
Also used : Format(com.google.android.exoplayer2.Format) MediaChunkIterator(com.google.android.exoplayer2.source.chunk.MediaChunkIterator) SingleSampleMediaChunk(com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) Segment(com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment)

Example 12 with ChunkIndex

use of com.google.android.exoplayer2.extractor.ChunkIndex in project ExoPlayer by google.

the class FragmentedMp4Extractor method parseSidx.

/**
 * Parses a sidx atom (defined in 14496-12).
 *
 * @param atom The atom data.
 * @param inputPosition The input position of the first byte after the atom.
 * @return A pair consisting of the earliest presentation time in microseconds, and the parsed
 *     {@link ChunkIndex}.
 */
private static Pair<Long, ChunkIndex> parseSidx(ParsableByteArray atom, long inputPosition) throws ParserException {
    atom.setPosition(Atom.HEADER_SIZE);
    int fullAtom = atom.readInt();
    int version = Atom.parseFullAtomVersion(fullAtom);
    atom.skipBytes(4);
    long timescale = atom.readUnsignedInt();
    long earliestPresentationTime;
    long offset = inputPosition;
    if (version == 0) {
        earliestPresentationTime = atom.readUnsignedInt();
        offset += atom.readUnsignedInt();
    } else {
        earliestPresentationTime = atom.readUnsignedLongToLong();
        offset += atom.readUnsignedLongToLong();
    }
    long earliestPresentationTimeUs = Util.scaleLargeTimestamp(earliestPresentationTime, C.MICROS_PER_SECOND, timescale);
    atom.skipBytes(2);
    int referenceCount = atom.readUnsignedShort();
    int[] sizes = new int[referenceCount];
    long[] offsets = new long[referenceCount];
    long[] durationsUs = new long[referenceCount];
    long[] timesUs = new long[referenceCount];
    long time = earliestPresentationTime;
    long timeUs = earliestPresentationTimeUs;
    for (int i = 0; i < referenceCount; i++) {
        int firstInt = atom.readInt();
        int type = 0x80000000 & firstInt;
        if (type != 0) {
            throw ParserException.createForMalformedContainer("Unhandled indirect reference", /* cause= */
            null);
        }
        long referenceDuration = atom.readUnsignedInt();
        sizes[i] = 0x7FFFFFFF & firstInt;
        offsets[i] = offset;
        // Calculate time and duration values such that any rounding errors are consistent. i.e. That
        // timesUs[i] + durationsUs[i] == timesUs[i + 1].
        timesUs[i] = timeUs;
        time += referenceDuration;
        timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
        durationsUs[i] = timeUs - timesUs[i];
        atom.skipBytes(4);
        offset += sizes[i];
    }
    return Pair.create(earliestPresentationTimeUs, new ChunkIndex(sizes, offsets, durationsUs, timesUs));
}
Also used : ChunkIndex(com.google.android.exoplayer2.extractor.ChunkIndex)

Example 13 with ChunkIndex

use of com.google.android.exoplayer2.extractor.ChunkIndex in project ExoPlayer by google.

the class DefaultSsChunkSource method getNextChunk.

@Override
public final void getNextChunk(long playbackPositionUs, long loadPositionUs, List<? extends MediaChunk> queue, ChunkHolder out) {
    if (fatalError != null) {
        return;
    }
    StreamElement streamElement = manifest.streamElements[streamElementIndex];
    if (streamElement.chunkCount == 0) {
        // There aren't any chunks for us to load.
        out.endOfStream = !manifest.isLive;
        return;
    }
    int chunkIndex;
    if (queue.isEmpty()) {
        chunkIndex = streamElement.getChunkIndex(loadPositionUs);
    } else {
        chunkIndex = (int) (queue.get(queue.size() - 1).getNextChunkIndex() - currentManifestChunkOffset);
        if (chunkIndex < 0) {
            // This is before the first chunk in the current manifest.
            fatalError = new BehindLiveWindowException();
            return;
        }
    }
    if (chunkIndex >= streamElement.chunkCount) {
        // This is beyond the last chunk in the current manifest.
        out.endOfStream = !manifest.isLive;
        return;
    }
    long bufferedDurationUs = loadPositionUs - playbackPositionUs;
    long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
    MediaChunkIterator[] chunkIterators = new MediaChunkIterator[trackSelection.length()];
    for (int i = 0; i < chunkIterators.length; i++) {
        int trackIndex = trackSelection.getIndexInTrackGroup(i);
        chunkIterators[i] = new StreamElementIterator(streamElement, trackIndex, chunkIndex);
    }
    trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, timeToLiveEdgeUs, queue, chunkIterators);
    long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
    long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(chunkIndex);
    long chunkSeekTimeUs = queue.isEmpty() ? loadPositionUs : C.TIME_UNSET;
    int currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
    int trackSelectionIndex = trackSelection.getSelectedIndex();
    ChunkExtractor chunkExtractor = chunkExtractors[trackSelectionIndex];
    int manifestTrackIndex = trackSelection.getIndexInTrackGroup(trackSelectionIndex);
    Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex);
    out.chunk = newMediaChunk(trackSelection.getSelectedFormat(), dataSource, uri, currentAbsoluteChunkIndex, chunkStartTimeUs, chunkEndTimeUs, chunkSeekTimeUs, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), chunkExtractor);
}
Also used : BaseMediaChunkIterator(com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator) MediaChunkIterator(com.google.android.exoplayer2.source.chunk.MediaChunkIterator) BehindLiveWindowException(com.google.android.exoplayer2.source.BehindLiveWindowException) StreamElement(com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement) ChunkExtractor(com.google.android.exoplayer2.source.chunk.ChunkExtractor) BundledChunkExtractor(com.google.android.exoplayer2.source.chunk.BundledChunkExtractor) Uri(android.net.Uri)

Example 14 with ChunkIndex

use of com.google.android.exoplayer2.extractor.ChunkIndex in project ExoPlayer by google.

the class OutputConsumerAdapterV30 method maybeObtainChunkIndex.

// Private methods.
private boolean maybeObtainChunkIndex(MediaFormat mediaFormat) {
    @Nullable ByteBuffer chunkIndexSizesByteBuffer = mediaFormat.getByteBuffer(MEDIA_FORMAT_KEY_CHUNK_INDEX_SIZES);
    if (chunkIndexSizesByteBuffer == null) {
        return false;
    }
    IntBuffer chunkIndexSizes = chunkIndexSizesByteBuffer.asIntBuffer();
    LongBuffer chunkIndexOffsets = Assertions.checkNotNull(mediaFormat.getByteBuffer(MEDIA_FORMAT_KEY_CHUNK_INDEX_OFFSETS)).asLongBuffer();
    LongBuffer chunkIndexDurationsUs = Assertions.checkNotNull(mediaFormat.getByteBuffer(MEDIA_FORMAT_KEY_CHUNK_INDEX_DURATIONS)).asLongBuffer();
    LongBuffer chunkIndexTimesUs = Assertions.checkNotNull(mediaFormat.getByteBuffer(MEDIA_FORMAT_KEY_CHUNK_INDEX_TIMES)).asLongBuffer();
    int[] sizes = new int[chunkIndexSizes.remaining()];
    long[] offsets = new long[chunkIndexOffsets.remaining()];
    long[] durationsUs = new long[chunkIndexDurationsUs.remaining()];
    long[] timesUs = new long[chunkIndexTimesUs.remaining()];
    chunkIndexSizes.get(sizes);
    chunkIndexOffsets.get(offsets);
    chunkIndexDurationsUs.get(durationsUs);
    chunkIndexTimesUs.get(timesUs);
    lastChunkIndex = new ChunkIndex(sizes, offsets, durationsUs, timesUs);
    extractorOutput.seekMap(lastChunkIndex);
    return true;
}
Also used : LongBuffer(java.nio.LongBuffer) IntBuffer(java.nio.IntBuffer) ByteBuffer(java.nio.ByteBuffer) Nullable(androidx.annotation.Nullable) ChunkIndex(com.google.android.exoplayer2.extractor.ChunkIndex)

Aggregations

ChunkIndex (com.google.android.exoplayer2.extractor.ChunkIndex)4 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)4 Uri (android.net.Uri)3 Nullable (androidx.annotation.Nullable)3 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)3 MediaChunkIterator (com.google.android.exoplayer2.source.chunk.MediaChunkIterator)3 StreamElement (com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)3 Format (com.google.android.exoplayer2.Format)2 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)2 SampleQueue (com.google.android.exoplayer2.source.SampleQueue)1 BaseMediaChunkIterator (com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator)1 BundledChunkExtractor (com.google.android.exoplayer2.source.chunk.BundledChunkExtractor)1 ChunkExtractor (com.google.android.exoplayer2.source.chunk.ChunkExtractor)1 ChunkExtractorWrapper (com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper)1 InitializationChunk (com.google.android.exoplayer2.source.chunk.InitializationChunk)1 SingleSampleMediaChunk (com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk)1 DashSegmentIndex (com.google.android.exoplayer2.source.dash.DashSegmentIndex)1 DashWrappingSegmentIndex (com.google.android.exoplayer2.source.dash.DashWrappingSegmentIndex)1 HlsUrl (com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl)1 HlsMediaPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist)1