Search in sources :

Example 6 with Extractor

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

the class HlsSampleStreamWrapper method buildTracks.

/**
   * Builds tracks that are exposed by this {@link HlsSampleStreamWrapper} instance, as well as
   * internal data-structures required for operation.
   * <p>
   * Tracks in HLS are complicated. A HLS master playlist contains a number of "variants". Each
   * variant stream typically contains muxed video, audio and (possibly) additional audio, metadata
   * and caption tracks. We wish to allow the user to select between an adaptive track that spans
   * all variants, as well as each individual variant. If multiple audio tracks are present within
   * each variant then we wish to allow the user to select between those also.
   * <p>
   * To do this, tracks are constructed as follows. The {@link HlsChunkSource} exposes (N+1) tracks,
   * where N is the number of variants defined in the HLS master playlist. These consist of one
   * adaptive track defined to span all variants and a track for each individual variant. The
   * adaptive track is initially selected. The extractor is then prepared to discover the tracks
   * inside of each variant stream. The two sets of tracks are then combined by this method to
   * create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
   * <ul>
   * <li>The extractor tracks are inspected to infer a "primary" track type. If a video track is
   * present then it is always the primary type. If not, audio is the primary type if present.
   * Else text is the primary type if present. Else there is no primary type.</li>
   * <li>If there is exactly one extractor track of the primary type, it's expanded into (N+1)
   * exposed tracks, all of which correspond to the primary extractor track and each of which
   * corresponds to a different chunk source track. Selecting one of these tracks has the effect
   * of switching the selected track on the chunk source.</li>
   * <li>All other extractor tracks are exposed directly. Selecting one of these tracks has the
   * effect of selecting an extractor track, leaving the selected track on the chunk source
   * unchanged.</li>
   * </ul>
   */
private void buildTracks() {
    // Iterate through the extractor tracks to discover the "primary" track type, and the index
    // of the single track of this type.
    int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
    int primaryExtractorTrackIndex = C.INDEX_UNSET;
    int extractorTrackCount = sampleQueues.size();
    for (int i = 0; i < extractorTrackCount; i++) {
        String sampleMimeType = sampleQueues.valueAt(i).getUpstreamFormat().sampleMimeType;
        int trackType;
        if (MimeTypes.isVideo(sampleMimeType)) {
            trackType = PRIMARY_TYPE_VIDEO;
        } else if (MimeTypes.isAudio(sampleMimeType)) {
            trackType = PRIMARY_TYPE_AUDIO;
        } else if (MimeTypes.isText(sampleMimeType)) {
            trackType = PRIMARY_TYPE_TEXT;
        } else {
            trackType = PRIMARY_TYPE_NONE;
        }
        if (trackType > primaryExtractorTrackType) {
            primaryExtractorTrackType = trackType;
            primaryExtractorTrackIndex = i;
        } else if (trackType == primaryExtractorTrackType && primaryExtractorTrackIndex != C.INDEX_UNSET) {
            // We have multiple tracks of the primary type. We only want an index if there only exists a
            // single track of the primary type, so unset the index again.
            primaryExtractorTrackIndex = C.INDEX_UNSET;
        }
    }
    TrackGroup chunkSourceTrackGroup = chunkSource.getTrackGroup();
    int chunkSourceTrackCount = chunkSourceTrackGroup.length;
    // Instantiate the necessary internal data-structures.
    primaryTrackGroupIndex = C.INDEX_UNSET;
    groupEnabledStates = new boolean[extractorTrackCount];
    // Construct the set of exposed track groups.
    TrackGroup[] trackGroups = new TrackGroup[extractorTrackCount];
    for (int i = 0; i < extractorTrackCount; i++) {
        Format sampleFormat = sampleQueues.valueAt(i).getUpstreamFormat();
        if (i == primaryExtractorTrackIndex) {
            Format[] formats = new Format[chunkSourceTrackCount];
            for (int j = 0; j < chunkSourceTrackCount; j++) {
                formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat);
            }
            trackGroups[i] = new TrackGroup(formats);
            primaryTrackGroupIndex = i;
        } else {
            Format trackFormat = primaryExtractorTrackType == PRIMARY_TYPE_VIDEO && MimeTypes.isAudio(sampleFormat.sampleMimeType) ? muxedAudioFormat : null;
            trackGroups[i] = new TrackGroup(deriveFormat(trackFormat, sampleFormat));
        }
    }
    this.trackGroups = new TrackGroupArray(trackGroups);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray)

Example 7 with Extractor

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

the class DashUtil method newWrappedExtractor.

private static ChunkExtractorWrapper newWrappedExtractor(Format format) {
    String mimeType = format.containerMimeType;
    boolean isWebm = mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM);
    Extractor extractor = isWebm ? new MatroskaExtractor() : new FragmentedMp4Extractor();
    return new ChunkExtractorWrapper(extractor, format);
}
Also used : FragmentedMp4Extractor(com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor) ChunkExtractorWrapper(com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper) FragmentedMp4Extractor(com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor) Extractor(com.google.android.exoplayer2.extractor.Extractor) MatroskaExtractor(com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor) MatroskaExtractor(com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor)

Example 8 with Extractor

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

the class TsExtractorTest method testIncompleteSample.

public void testIncompleteSample() throws Exception {
    Random random = new Random(0);
    byte[] fileData = TestUtil.getByteArray(getInstrumentation(), "ts/sample.ts");
    ByteArrayOutputStream out = new ByteArrayOutputStream(fileData.length * 2);
    writeJunkData(out, random.nextInt(TS_PACKET_SIZE - 1) + 1);
    out.write(fileData, 0, TS_PACKET_SIZE * 5);
    for (int i = TS_PACKET_SIZE * 5; i < fileData.length; i += TS_PACKET_SIZE) {
        writeJunkData(out, random.nextInt(TS_PACKET_SIZE));
        out.write(fileData, i, TS_PACKET_SIZE);
    }
    out.write(TS_SYNC_BYTE);
    writeJunkData(out, random.nextInt(TS_PACKET_SIZE - 1) + 1);
    fileData = out.toByteArray();
    TestUtil.assertOutput(new TestUtil.ExtractorFactory() {

        @Override
        public Extractor create() {
            return new TsExtractor();
        }
    }, "ts/sample.ts", fileData, getInstrumentation());
}
Also used : Random(java.util.Random) TestUtil(com.google.android.exoplayer2.testutil.TestUtil) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Extractor(com.google.android.exoplayer2.extractor.Extractor)

Example 9 with Extractor

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

the class ContainerMediaChunk method load.

@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public final void load() throws IOException, InterruptedException {
    DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded);
    try {
        // Create and open the input.
        ExtractorInput input = new DefaultExtractorInput(dataSource, loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
        if (bytesLoaded == 0) {
            // Configure the output and set it as the target for the extractor wrapper.
            BaseMediaChunkOutput output = getOutput();
            output.setSampleOffsetUs(sampleOffsetUs);
            extractorWrapper.init(output);
        }
        // Load and decode the sample data.
        try {
            Extractor extractor = extractorWrapper.extractor;
            int result = Extractor.RESULT_CONTINUE;
            while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
                result = extractor.read(input, null);
            }
            Assertions.checkState(result != Extractor.RESULT_SEEK);
        } finally {
            bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
        }
    } finally {
        Util.closeQuietly(dataSource);
    }
    loadCompleted = true;
}
Also used : ExtractorInput(com.google.android.exoplayer2.extractor.ExtractorInput) DefaultExtractorInput(com.google.android.exoplayer2.extractor.DefaultExtractorInput) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) DefaultExtractorInput(com.google.android.exoplayer2.extractor.DefaultExtractorInput) Extractor(com.google.android.exoplayer2.extractor.Extractor)

Example 10 with Extractor

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

the class InitializationChunk method load.

@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public void load() throws IOException, InterruptedException {
    DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded);
    try {
        // Create and open the input.
        ExtractorInput input = new DefaultExtractorInput(dataSource, loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
        if (bytesLoaded == 0) {
            extractorWrapper.init(null);
        }
        // Load and decode the initialization data.
        try {
            Extractor extractor = extractorWrapper.extractor;
            int result = Extractor.RESULT_CONTINUE;
            while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
                result = extractor.read(input, null);
            }
            Assertions.checkState(result != Extractor.RESULT_SEEK);
        } finally {
            bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
        }
    } finally {
        Util.closeQuietly(dataSource);
    }
}
Also used : ExtractorInput(com.google.android.exoplayer2.extractor.ExtractorInput) DefaultExtractorInput(com.google.android.exoplayer2.extractor.DefaultExtractorInput) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) DefaultExtractorInput(com.google.android.exoplayer2.extractor.DefaultExtractorInput) Extractor(com.google.android.exoplayer2.extractor.Extractor)

Aggregations

Extractor (com.google.android.exoplayer2.extractor.Extractor)6 DefaultExtractorInput (com.google.android.exoplayer2.extractor.DefaultExtractorInput)4 ExtractorInput (com.google.android.exoplayer2.extractor.ExtractorInput)4 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)4 FragmentedMp4Extractor (com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor)3 Format (com.google.android.exoplayer2.Format)2 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)2 Mp3Extractor (com.google.android.exoplayer2.extractor.mp3.Mp3Extractor)2 Ac3Extractor (com.google.android.exoplayer2.extractor.ts.Ac3Extractor)2 AdtsExtractor (com.google.android.exoplayer2.extractor.ts.AdtsExtractor)2 TsExtractor (com.google.android.exoplayer2.extractor.ts.TsExtractor)2 ParserException (com.google.android.exoplayer2.ParserException)1 GaplessInfoHolder (com.google.android.exoplayer2.extractor.GaplessInfoHolder)1 PositionHolder (com.google.android.exoplayer2.extractor.PositionHolder)1 SeekMap (com.google.android.exoplayer2.extractor.SeekMap)1 MatroskaExtractor (com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor)1 ContainerAtom (com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom)1 DefaultTsPayloadReaderFactory (com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory)1 Metadata (com.google.android.exoplayer2.metadata.Metadata)1 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)1