Search in sources :

Example 1 with SeekMap

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

the class ExtractorMediaPeriod method maybeFinishPrepare.

// Internal methods.
private void maybeFinishPrepare() {
    if (released || prepared || seekMap == null || !tracksBuilt) {
        return;
    }
    int trackCount = sampleQueues.size();
    for (int i = 0; i < trackCount; i++) {
        if (sampleQueues.valueAt(i).getUpstreamFormat() == null) {
            return;
        }
    }
    loadCondition.close();
    TrackGroup[] trackArray = new TrackGroup[trackCount];
    trackIsAudioVideoFlags = new boolean[trackCount];
    trackEnabledStates = new boolean[trackCount];
    durationUs = seekMap.getDurationUs();
    for (int i = 0; i < trackCount; i++) {
        Format trackFormat = sampleQueues.valueAt(i).getUpstreamFormat();
        trackArray[i] = new TrackGroup(trackFormat);
        String mimeType = trackFormat.sampleMimeType;
        boolean isAudioVideo = MimeTypes.isVideo(mimeType) || MimeTypes.isAudio(mimeType);
        trackIsAudioVideoFlags[i] = isAudioVideo;
        haveAudioVideoTracks |= isAudioVideo;
    }
    tracks = new TrackGroupArray(trackArray);
    prepared = true;
    sourceListener.onSourceInfoRefreshed(new SinglePeriodTimeline(durationUs, seekMap.isSeekable()), null);
    callback.onPrepared(this);
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 2 with SeekMap

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

the class StreamReader method readPayload.

private int readPayload(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
    long position = oggSeeker.read(input);
    if (position >= 0) {
        seekPosition.position = position;
        return Extractor.RESULT_SEEK;
    } else if (position < -1) {
        onSeekEnd(-(position + 2));
    }
    if (!seekMapSet) {
        SeekMap seekMap = oggSeeker.createSeekMap();
        extractorOutput.seekMap(seekMap);
        seekMapSet = true;
    }
    if (lengthOfReadPacket > 0 || oggPacket.populate(input)) {
        lengthOfReadPacket = 0;
        ParsableByteArray payload = oggPacket.getPayload();
        long granulesInPacket = preparePayload(payload);
        if (granulesInPacket >= 0 && currentGranule + granulesInPacket >= targetGranule) {
            // calculate time and send payload data to codec
            long timeUs = convertGranuleToTime(currentGranule);
            trackOutput.sampleData(payload, payload.limit());
            trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, payload.limit(), 0, null);
            targetGranule = -1;
        }
        currentGranule += granulesInPacket;
    } else {
        state = STATE_END_OF_INPUT;
        return Extractor.RESULT_END_OF_INPUT;
    }
    return Extractor.RESULT_CONTINUE;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Example 3 with SeekMap

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

the class DefaultDashChunkSource method onChunkLoadCompleted.

@Override
public void onChunkLoadCompleted(Chunk chunk) {
    if (chunk instanceof InitializationChunk) {
        InitializationChunk initializationChunk = (InitializationChunk) chunk;
        RepresentationHolder representationHolder = representationHolders[trackSelection.indexOf(initializationChunk.trackFormat)];
        // where it does we should ignore it.
        if (representationHolder.segmentIndex == null) {
            SeekMap seekMap = representationHolder.extractorWrapper.getSeekMap();
            if (seekMap != null) {
                representationHolder.segmentIndex = new DashWrappingSegmentIndex((ChunkIndex) seekMap);
            }
        }
    }
}
Also used : InitializationChunk(com.google.android.exoplayer2.source.chunk.InitializationChunk) SeekMap(com.google.android.exoplayer2.extractor.SeekMap) ChunkIndex(com.google.android.exoplayer2.extractor.ChunkIndex)

Example 4 with SeekMap

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

the class FlacExtractor method read.

@Override
public int read(final ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
    decoderJni.setData(input);
    if (!metadataParsed) {
        final FlacStreamInfo streamInfo;
        try {
            streamInfo = decoderJni.decodeMetadata();
            if (streamInfo == null) {
                throw new IOException("Metadata decoding failed");
            }
        } catch (IOException e) {
            decoderJni.reset(0);
            input.setRetryPosition(0, e);
            // never executes
            throw e;
        }
        metadataParsed = true;
        extractorOutput.seekMap(new SeekMap() {

            final boolean isSeekable = decoderJni.getSeekPosition(0) != -1;

            final long durationUs = streamInfo.durationUs();

            @Override
            public boolean isSeekable() {
                return isSeekable;
            }

            @Override
            public long getPosition(long timeUs) {
                return isSeekable ? decoderJni.getSeekPosition(timeUs) : 0;
            }

            @Override
            public long getDurationUs() {
                return durationUs;
            }
        });
        Format mediaFormat = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_RAW, null, streamInfo.bitRate(), Format.NO_VALUE, streamInfo.channels, streamInfo.sampleRate, C.ENCODING_PCM_16BIT, null, null, 0, null);
        trackOutput.format(mediaFormat);
        outputBuffer = new ParsableByteArray(streamInfo.maxDecodedFrameSize());
        outputByteBuffer = ByteBuffer.wrap(outputBuffer.data);
    }
    outputBuffer.reset();
    long lastDecodePosition = decoderJni.getDecodePosition();
    int size;
    try {
        size = decoderJni.decodeSample(outputByteBuffer);
    } catch (IOException e) {
        if (lastDecodePosition >= 0) {
            decoderJni.reset(lastDecodePosition);
            input.setRetryPosition(lastDecodePosition, e);
        }
        throw e;
    }
    if (size <= 0) {
        return RESULT_END_OF_INPUT;
    }
    trackOutput.sampleData(outputBuffer, size);
    trackOutput.sampleMetadata(decoderJni.getLastSampleTimestamp(), C.BUFFER_FLAG_KEY_FRAME, size, 0, null);
    return decoderJni.isEndOfData() ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) Format(com.google.android.exoplayer2.Format) FlacStreamInfo(com.google.android.exoplayer2.util.FlacStreamInfo) IOException(java.io.IOException) SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Example 5 with SeekMap

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

the class TestUtil method assertOutput.

/**
   * Asserts that {@code extractor} consumes {@code sampleFile} successfully and its output equals
   * to a prerecorded output dump file with the name {@code sampleFile} + "{@value
   * #DUMP_EXTENSION}". If {@code simulateUnknownLength} is true and {@code sampleFile} + "{@value
   * #UNKNOWN_LENGTH_EXTENSION}" exists, it's preferred.
   *
   * @param extractor The {@link Extractor} to be tested.
   * @param sampleFile The path to the input sample.
   * @param fileData Content of the input file.
   * @param instrumentation To be used to load the sample file.
   * @param simulateIOErrors If true simulates IOErrors.
   * @param simulateUnknownLength If true simulates unknown input length.
   * @param simulatePartialReads If true simulates partial reads.
   * @return The {@link FakeExtractorOutput} used in the test.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from the input.
   */
public static FakeExtractorOutput assertOutput(Extractor extractor, String sampleFile, byte[] fileData, Instrumentation instrumentation, boolean simulateIOErrors, boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException, InterruptedException {
    FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData).setSimulateIOErrors(simulateIOErrors).setSimulateUnknownLength(simulateUnknownLength).setSimulatePartialReads(simulatePartialReads).build();
    Assert.assertTrue(sniffTestData(extractor, input));
    input.resetPeekPosition();
    FakeExtractorOutput extractorOutput = consumeTestData(extractor, input, 0, true);
    if (simulateUnknownLength && assetExists(instrumentation, sampleFile + UNKNOWN_LENGTH_EXTENSION)) {
        extractorOutput.assertOutput(instrumentation, sampleFile + UNKNOWN_LENGTH_EXTENSION);
    } else {
        extractorOutput.assertOutput(instrumentation, sampleFile + ".0" + DUMP_EXTENSION);
    }
    SeekMap seekMap = extractorOutput.seekMap;
    if (seekMap.isSeekable()) {
        long durationUs = seekMap.getDurationUs();
        for (int j = 0; j < 4; j++) {
            long timeUs = (durationUs * j) / 3;
            long position = seekMap.getPosition(timeUs);
            input.setPosition((int) position);
            for (int i = 0; i < extractorOutput.numberOfTracks; i++) {
                extractorOutput.trackOutputs.valueAt(i).clear();
            }
            consumeTestData(extractor, input, timeUs, extractorOutput, false);
            extractorOutput.assertOutput(instrumentation, sampleFile + '.' + j + DUMP_EXTENSION);
        }
    }
    return extractorOutput;
}
Also used : SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Aggregations

SeekMap (com.google.android.exoplayer2.extractor.SeekMap)4 Format (com.google.android.exoplayer2.Format)2 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)2 ChunkIndex (com.google.android.exoplayer2.extractor.ChunkIndex)1 InitializationChunk (com.google.android.exoplayer2.source.chunk.InitializationChunk)1 FlacStreamInfo (com.google.android.exoplayer2.util.FlacStreamInfo)1 IOException (java.io.IOException)1