diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java index 42c5908619..d13194793e 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java @@ -67,7 +67,7 @@ public final class FlacExtractor implements Extractor { @Override public void init(ExtractorOutput output) { extractorOutput = output; - trackOutput = extractorOutput.track(0); + trackOutput = extractorOutput.track(0, C.TRACK_TYPE_AUDIO); extractorOutput.endTracks(); try { decoderJni = new FlacDecoderJni(); diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java index ebb547810b..bcfa90a565 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/AdtsReaderTest.java @@ -69,8 +69,8 @@ public class AdtsReaderTest extends TestCase { @Override protected void setUp() throws Exception { FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput(); - adtsOutput = fakeExtractorOutput.track(0); - id3Output = fakeExtractorOutput.track(1); + adtsOutput = fakeExtractorOutput.track(0, C.TRACK_TYPE_AUDIO); + id3Output = fakeExtractorOutput.track(1, C.TRACK_TYPE_METADATA); adtsReader = new AdtsReader(true); TrackIdGenerator idGenerator = new TrackIdGenerator(0, 1); adtsReader.createTracks(fakeExtractorOutput, idGenerator); diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/TsExtractorTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/TsExtractorTest.java index 74e0748119..9bcb1c2377 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/TsExtractorTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/ts/TsExtractorTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.extractor.ts; import android.test.InstrumentationTestCase; import android.util.SparseArray; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.ExtractorOutput; @@ -179,7 +180,7 @@ public final class TsExtractorTest extends InstrumentationTestCase { @Override public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_UNKNOWN); output.format(Format.createTextSampleFormat(idGenerator.getFormatId(), "mime", null, 0, 0, language, null, 0)); } diff --git a/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java b/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java index 0f979d6a4f..8d057230ca 100644 --- a/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java +++ b/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java @@ -210,7 +210,8 @@ public final class OfflineLicenseHelper { Representation representation = adaptationSet.representations.get(0); DrmInitData drmInitData = representation.format.drmInitData; if (drmInitData == null) { - ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(representation.format); + ChunkExtractorWrapper extractorWrapper = newWrappedExtractor(representation.format, + adaptationSet.type); InitializationChunk initializationChunk = loadInitializationChunk(dataSource, representation, extractorWrapper); if (initializationChunk == null) { @@ -306,12 +307,13 @@ public final class OfflineLicenseHelper { return initializationChunk; } - private static ChunkExtractorWrapper newWrappedExtractor(final Format format) { + private static ChunkExtractorWrapper newWrappedExtractor(Format format, int trackType) { final String mimeType = format.containerMimeType; final boolean isWebm = mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM); final Extractor extractor = isWebm ? new MatroskaExtractor() : new FragmentedMp4Extractor(); - return new ChunkExtractorWrapper(extractor, format, false /* preferManifestDrmInitData */); + return new ChunkExtractorWrapper(extractor, format, trackType, + false /* preferManifestDrmInitData */); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ExtractorOutput.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ExtractorOutput.java index a547f745ca..a59cb1d1f2 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ExtractorOutput.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ExtractorOutput.java @@ -23,17 +23,18 @@ public interface ExtractorOutput { /** * Called by the {@link Extractor} to get the {@link TrackOutput} for a specific track. *

- * The same {@link TrackOutput} is returned if multiple calls are made with the same - * {@code trackId}. + * The same {@link TrackOutput} is returned if multiple calls are made with the same {@code id}. * - * @param trackId A track identifier. + * @param id A track identifier. + * @param type The type of the track. Typically one of the {@link com.google.android.exoplayer2.C} + * {@code TRACK_TYPE_*} constants. * @return The {@link TrackOutput} for the given track identifier. */ - TrackOutput track(int trackId); + TrackOutput track(int id, int type); /** * Called when all tracks have been identified, meaning no new {@code trackId} values will be - * passed to {@link #track(int)}. + * passed to {@link #track(int, int)}. */ void endTracks(); diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/flv/FlvExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/flv/FlvExtractor.java index 5b396749ac..218e6ffd82 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/flv/FlvExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/flv/FlvExtractor.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor.flv; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorOutput; @@ -183,10 +184,12 @@ public final class FlvExtractor implements Extractor, SeekMap { boolean hasAudio = (flags & 0x04) != 0; boolean hasVideo = (flags & 0x01) != 0; if (hasAudio && audioReader == null) { - audioReader = new AudioTagPayloadReader(extractorOutput.track(TAG_TYPE_AUDIO)); + audioReader = new AudioTagPayloadReader( + extractorOutput.track(TAG_TYPE_AUDIO, C.TRACK_TYPE_AUDIO)); } if (hasVideo && videoReader == null) { - videoReader = new VideoTagPayloadReader(extractorOutput.track(TAG_TYPE_VIDEO)); + videoReader = new VideoTagPayloadReader( + extractorOutput.track(TAG_TYPE_VIDEO, C.TRACK_TYPE_VIDEO)); } if (metadataReader == null) { metadataReader = new ScriptTagPayloadReader(null); diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java index 970335e9d2..ed1a86e651 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java @@ -1462,6 +1462,7 @@ public final class MatroskaExtractor implements Extractor { throw new ParserException("Unrecognized codec identifier."); } + int type; Format format; @C.SelectionFlags int selectionFlags = 0; selectionFlags |= flagDefault ? C.SELECTION_FLAG_DEFAULT : 0; @@ -1469,10 +1470,12 @@ public final class MatroskaExtractor implements Extractor { // TODO: Consider reading the name elements of the tracks and, if present, incorporating them // into the trackId passed when creating the formats. if (MimeTypes.isAudio(mimeType)) { + type = C.TRACK_TYPE_AUDIO; format = Format.createAudioSampleFormat(Integer.toString(trackId), mimeType, null, Format.NO_VALUE, maxInputSize, channelCount, sampleRate, pcmEncoding, initializationData, drmInitData, selectionFlags, language); } else if (MimeTypes.isVideo(mimeType)) { + type = C.TRACK_TYPE_VIDEO; if (displayUnit == Track.DISPLAY_UNIT_PIXELS) { displayWidth = displayWidth == Format.NO_VALUE ? width : displayWidth; displayHeight = displayHeight == Format.NO_VALUE ? height : displayHeight; @@ -1485,17 +1488,19 @@ public final class MatroskaExtractor implements Extractor { Format.NO_VALUE, maxInputSize, width, height, Format.NO_VALUE, initializationData, Format.NO_VALUE, pixelWidthHeightRatio, projectionData, stereoMode, drmInitData); } else if (MimeTypes.APPLICATION_SUBRIP.equals(mimeType)) { + type = C.TRACK_TYPE_TEXT; format = Format.createTextSampleFormat(Integer.toString(trackId), mimeType, null, Format.NO_VALUE, selectionFlags, language, drmInitData); } else if (MimeTypes.APPLICATION_VOBSUB.equals(mimeType) || MimeTypes.APPLICATION_PGS.equals(mimeType)) { + type = C.TRACK_TYPE_TEXT; format = Format.createImageSampleFormat(Integer.toString(trackId), mimeType, null, Format.NO_VALUE, initializationData, language, drmInitData); } else { throw new ParserException("Unexpected MIME type."); } - this.output = output.track(number); + this.output = output.track(number, type); this.output.format(format); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java index 9bdefeceaf..ff84c7da25 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java @@ -118,7 +118,7 @@ public final class Mp3Extractor implements Extractor { @Override public void init(ExtractorOutput output) { extractorOutput = output; - trackOutput = extractorOutput.track(0); + trackOutput = extractorOutput.track(0, C.TRACK_TYPE_AUDIO); extractorOutput.endTracks(); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index f7cc42c48f..d72eb62509 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -164,7 +164,14 @@ public final class FragmentedMp4Extractor implements Extractor { private boolean haveOutputSeekMap; public FragmentedMp4Extractor() { - this(0, null); + this(0); + } + + /** + * @param flags Flags that control the extractor's behavior. + */ + public FragmentedMp4Extractor(@Flags int flags) { + this(flags, null); } /** @@ -172,20 +179,20 @@ public final class FragmentedMp4Extractor implements Extractor { * @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed. */ public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster) { - this(flags, null, timestampAdjuster); + this(flags, timestampAdjuster, null); } /** * @param flags Flags that control the extractor's behavior. + * @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed. * @param sideloadedTrack Sideloaded track information, in the case that the extractor * will not receive a moov box in the input data. - * @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed. */ - public FragmentedMp4Extractor(@Flags int flags, Track sideloadedTrack, - TimestampAdjuster timestampAdjuster) { - this.sideloadedTrack = sideloadedTrack; + public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster, + Track sideloadedTrack) { this.flags = flags | (sideloadedTrack != null ? FLAG_SIDELOADED : 0); this.timestampAdjuster = timestampAdjuster; + this.sideloadedTrack = sideloadedTrack; atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE); nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE); nalLength = new ParsableByteArray(4); @@ -209,7 +216,7 @@ public final class FragmentedMp4Extractor implements Extractor { public void init(ExtractorOutput output) { extractorOutput = output; if (sideloadedTrack != null) { - TrackBundle bundle = new TrackBundle(output.track(0)); + TrackBundle bundle = new TrackBundle(output.track(0, sideloadedTrack.type)); bundle.init(sideloadedTrack, new DefaultSampleValues(0, 0, 0, 0)); trackBundles.put(0, bundle); maybeInitExtraTracks(); @@ -420,7 +427,7 @@ public final class FragmentedMp4Extractor implements Extractor { // We need to create the track bundles. for (int i = 0; i < trackCount; i++) { Track track = tracks.valueAt(i); - TrackBundle trackBundle = new TrackBundle(extractorOutput.track(i)); + TrackBundle trackBundle = new TrackBundle(extractorOutput.track(i, track.type)); trackBundle.init(track, defaultSampleValuesArray.get(track.id)); trackBundles.put(track.id, trackBundle); durationUs = Math.max(durationUs, track.durationUs); @@ -449,12 +456,12 @@ public final class FragmentedMp4Extractor implements Extractor { private void maybeInitExtraTracks() { if ((flags & FLAG_ENABLE_EMSG_TRACK) != 0 && eventMessageTrackOutput == null) { - eventMessageTrackOutput = extractorOutput.track(trackBundles.size()); + eventMessageTrackOutput = extractorOutput.track(trackBundles.size(), C.TRACK_TYPE_METADATA); eventMessageTrackOutput.format(Format.createSampleFormat(null, MimeTypes.APPLICATION_EMSG, Format.OFFSET_SAMPLE_RELATIVE)); } if ((flags & FLAG_ENABLE_CEA608_TRACK) != 0 && cea608TrackOutput == null) { - cea608TrackOutput = extractorOutput.track(trackBundles.size() + 1); + cea608TrackOutput = extractorOutput.track(trackBundles.size() + 1, C.TRACK_TYPE_TEXT); cea608TrackOutput.format(Format.createTextSampleFormat(null, MimeTypes.APPLICATION_CEA608, null, Format.NO_VALUE, 0, null, null)); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java index 3759a80fd4..0c990f5747 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java @@ -344,7 +344,8 @@ public final class Mp4Extractor implements Extractor, SeekMap { continue; } - Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i)); + Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, + extractorOutput.track(i, track.type)); // Each sample has up to three bytes of overhead for the start code that replaces its length. // Allow ten source samples per output sample, like the platform extractor. int maxInputSize = trackSampleTable.maximumSize + 3 * 10; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggExtractor.java index 5f41126737..cc3c5de311 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ogg/OggExtractor.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor.ogg; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.ExtractorInput; @@ -75,7 +76,7 @@ public class OggExtractor implements Extractor { @Override public void init(ExtractorOutput output) { - TrackOutput trackOutput = output.track(0); + TrackOutput trackOutput = output.track(0, C.TRACK_TYPE_AUDIO); output.endTracks(); // TODO: fix the case if sniff() isn't called streamReader.init(output, trackOutput); diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/rawcc/RawCcExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/rawcc/RawCcExtractor.java index f9957aebe5..7840eafce6 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/rawcc/RawCcExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/rawcc/RawCcExtractor.java @@ -65,7 +65,7 @@ public final class RawCcExtractor implements Extractor { @Override public void init(ExtractorOutput output) { output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET)); - trackOutput = output.track(0); + trackOutput = output.track(0, C.TRACK_TYPE_TEXT); output.endTracks(); trackOutput.format(format); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java index afef154ed4..790c036f1d 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java @@ -87,7 +87,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator generator) { generator.generateNewId(); trackFormatId = generator.getFormatId(); - output = extractorOutput.track(generator.getTrackId()); + output = extractorOutput.track(generator.getTrackId(), C.TRACK_TYPE_AUDIO); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java index 56793119e4..58318ea78d 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/AdtsReader.java @@ -111,10 +111,10 @@ import java.util.Collections; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_AUDIO); if (exposeId3) { idGenerator.generateNewId(); - id3Output = extractorOutput.track(idGenerator.getTrackId()); + id3Output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_METADATA); id3Output.format(Format.createSampleFormat(idGenerator.getFormatId(), MimeTypes.APPLICATION_ID3, null, Format.NO_VALUE, null)); } else { diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java index 50be258ae5..874de83b68 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java @@ -82,7 +82,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_AUDIO); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java index df6ba208c3..ba515d31ed 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java @@ -81,7 +81,7 @@ import java.util.Collections; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_VIDEO); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java index 5b9c2cdcea..c1d24b7a33 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java @@ -93,7 +93,7 @@ import java.util.List; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_VIDEO); sampleReader = new SampleReader(output, allowNonIdrKeyframes, detectAccessUnits); seiReader.createTracks(extractorOutput, idGenerator); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H265Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H265Reader.java index 93cfe9f5cb..30a5bdc1fd 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H265Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H265Reader.java @@ -98,7 +98,7 @@ import java.util.Collections; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_VIDEO); sampleReader = new SampleReader(output); seiReader.createTracks(extractorOutput, idGenerator); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Id3Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Id3Reader.java index 27eb2a1bb4..7d2ecc4e74 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Id3Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Id3Reader.java @@ -57,7 +57,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; @Override public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_METADATA); output.format(Format.createSampleFormat(idGenerator.getFormatId(), MimeTypes.APPLICATION_ID3, null, Format.NO_VALUE, null)); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java index ae7edc51e4..6301716286 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java @@ -79,7 +79,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); formatId = idGenerator.getFormatId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_AUDIO); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java index ced28c3b93..a3f4deffcb 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor.ts; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.TrackOutput; @@ -32,7 +33,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { idGenerator.generateNewId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT); output.format(Format.createTextSampleFormat(idGenerator.getFormatId(), MimeTypes.APPLICATION_CEA608, null, Format.NO_VALUE, 0, null, null)); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SpliceInfoSectionReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SpliceInfoSectionReader.java index 625bb70560..27838d4c25 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SpliceInfoSectionReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SpliceInfoSectionReader.java @@ -37,7 +37,7 @@ public final class SpliceInfoSectionReader implements SectionPayloadReader { TsPayloadReader.TrackIdGenerator idGenerator) { this.timestampAdjuster = timestampAdjuster; idGenerator.generateNewId(); - output = extractorOutput.track(idGenerator.getTrackId()); + output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_METADATA); output.format(Format.createSampleFormat(idGenerator.getFormatId(), MimeTypes.APPLICATION_SCTE35, null, Format.NO_VALUE, null)); } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java index 3d9f8166ab..cb46aa5519 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java @@ -60,7 +60,7 @@ public final class WavExtractor implements Extractor, SeekMap { @Override public void init(ExtractorOutput output) { extractorOutput = output; - trackOutput = output.track(0); + trackOutput = output.track(0, C.TRACK_TYPE_AUDIO); wavHeader = null; output.endTracks(); } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java index 5226043593..dc189058a6 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java @@ -381,7 +381,7 @@ import java.io.IOException; // ExtractorOutput implementation. Called by the loading thread. @Override - public TrackOutput track(int id) { + public TrackOutput track(int id, int type) { DefaultTrackOutput trackOutput = sampleQueues.get(id); if (trackOutput == null) { trackOutput = new DefaultTrackOutput(allocator); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java index 51db1e2a17..4984ed0ff0 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.chunk; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmInitData; +import com.google.android.exoplayer2.extractor.DummyTrackOutput; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorOutput; @@ -37,6 +38,7 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput public final Extractor extractor; private final Format manifestFormat; + private final int primaryTrackType; private final boolean preferManifestDrmInitData; private boolean extractorInitialized; @@ -52,13 +54,16 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput * @param extractor The extractor to wrap. * @param manifestFormat A manifest defined {@link Format} whose data should be merged into any * sample {@link Format} output from the {@link Extractor}. + * @param primaryTrackType The type of the primary track. Typically one of the {@link C} + * {@code TRACK_TYPE_*} constants. * @param preferManifestDrmInitData Whether {@link DrmInitData} defined in {@code manifestFormat} * should be preferred when the sample and manifest {@link Format}s are merged. */ - public ChunkExtractorWrapper(Extractor extractor, Format manifestFormat, + public ChunkExtractorWrapper(Extractor extractor, Format manifestFormat, int primaryTrackType, boolean preferManifestDrmInitData) { this.extractor = extractor; this.manifestFormat = manifestFormat; + this.primaryTrackType = primaryTrackType; this.preferManifestDrmInitData = preferManifestDrmInitData; } @@ -98,7 +103,10 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput // ExtractorOutput implementation. @Override - public TrackOutput track(int id) { + public TrackOutput track(int id, int type) { + if (primaryTrackType != C.TRACK_TYPE_UNKNOWN && primaryTrackType != type) { + return new DummyTrackOutput(); + } Assertions.checkState(!seenTrack || seenTrackId == id); seenTrack = true; seenTrackId = id; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java b/library/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java index d264283b68..88dcdd50be 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java @@ -34,6 +34,7 @@ import com.google.android.exoplayer2.source.chunk.ContainerMediaChunk; import com.google.android.exoplayer2.source.chunk.InitializationChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk; +import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet; import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.Representation; @@ -119,11 +120,13 @@ public class DefaultDashChunkSource implements DashChunkSource { this.maxSegmentsPerLoad = maxSegmentsPerLoad; long periodDurationUs = manifest.getPeriodDurationUs(periodIndex); - List representations = getRepresentations(); + AdaptationSet adaptationSet = getAdaptationSet(); + List representations = adaptationSet.representations; representationHolders = new RepresentationHolder[trackSelection.length()]; for (int i = 0; i < representationHolders.length; i++) { Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i)); - representationHolders[i] = new RepresentationHolder(periodDurationUs, representation); + representationHolders[i] = new RepresentationHolder(periodDurationUs, representation, + adaptationSet.type); } } @@ -133,7 +136,7 @@ public class DefaultDashChunkSource implements DashChunkSource { manifest = newManifest; periodIndex = newPeriodIndex; long periodDurationUs = manifest.getPeriodDurationUs(periodIndex); - List representations = getRepresentations(); + List representations = getAdaptationSet().representations; for (int i = 0; i < representationHolders.length; i++) { Representation representation = representations.get(trackSelection.getIndexInTrackGroup(i)); representationHolders[i].updateRepresentation(periodDurationUs, representation); @@ -278,8 +281,8 @@ public class DefaultDashChunkSource implements DashChunkSource { // Private methods. - private List getRepresentations() { - return manifest.getPeriod(periodIndex).adaptationSets.get(adaptationSetIndex).representations; + private AdaptationSet getAdaptationSet() { + return manifest.getPeriod(periodIndex).adaptationSets.get(adaptationSetIndex); } private long getNowUnixTimeUs() { @@ -350,6 +353,7 @@ public class DefaultDashChunkSource implements DashChunkSource { protected static final class RepresentationHolder { + public final int trackType; public final ChunkExtractorWrapper extractorWrapper; public Representation representation; @@ -358,9 +362,11 @@ public class DefaultDashChunkSource implements DashChunkSource { private long periodDurationUs; private int segmentNumShift; - public RepresentationHolder(long periodDurationUs, Representation representation) { + public RepresentationHolder(long periodDurationUs, Representation representation, + int trackType) { this.periodDurationUs = periodDurationUs; this.representation = representation; + this.trackType = trackType; String containerMimeType = representation.format.containerMimeType; if (mimeTypeIsRawText(containerMimeType)) { extractorWrapper = null; @@ -371,12 +377,13 @@ public class DefaultDashChunkSource implements DashChunkSource { } else if (mimeTypeIsWebm(containerMimeType)) { extractor = new MatroskaExtractor(); } else { - extractor = new FragmentedMp4Extractor(); + extractor = new FragmentedMp4Extractor(FragmentedMp4Extractor.FLAG_ENABLE_CEA608_TRACK + | FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK); } // Prefer drmInitData obtained from the manifest over drmInitData obtained from the stream, // as per DASH IF Interoperability Recommendations V3.0, 7.5.3. extractorWrapper = new ChunkExtractorWrapper(extractor, representation.format, - true /* preferManifestDrmInitData */); + trackType, true /* preferManifestDrmInitData */); } segmentIndex = representation.getIndex(); } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index bee38c59b5..538acbeabf 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -156,7 +156,7 @@ import java.util.LinkedList; * prepare. */ public void prepareSingleTrack(Format format) { - track(0).format(format); + track(0, C.TRACK_TYPE_UNKNOWN).format(format); sampleQueuesBuilt = true; maybeFinishPrepare(); } @@ -456,7 +456,7 @@ import java.util.LinkedList; // ExtractorOutput implementation. Called by the loading thread. @Override - public DefaultTrackOutput track(int id) { + public DefaultTrackOutput track(int id, int type) { if (sampleQueues.indexOfKey(id) >= 0) { return sampleQueues.get(id); } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java index c8928ce65d..12ea2c16c7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java @@ -167,7 +167,7 @@ import java.util.regex.Pattern; } private TrackOutput buildTrackOutput(long subsampleOffsetUs) { - TrackOutput trackOutput = output.track(0); + TrackOutput trackOutput = output.track(0, C.TRACK_TYPE_TEXT); trackOutput.format(Format.createTextSampleFormat(null, MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, language, null, subsampleOffsetUs)); output.endTracks(); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java index 2116d852ec..b0a583e8e5 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java @@ -101,8 +101,9 @@ public class DefaultSsChunkSource implements SsChunkSource { trackEncryptionBoxes, nalUnitLengthFieldLength, null, null); FragmentedMp4Extractor extractor = new FragmentedMp4Extractor( FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME - | FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX, track, null); - extractorWrappers[i] = new ChunkExtractorWrapper(extractor, format, false); + | FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX, null, track); + extractorWrappers[i] = new ChunkExtractorWrapper(extractor, format, streamElement.type, + false); } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorOutput.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorOutput.java index 3716c6d37f..ee8927ea21 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorOutput.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorOutput.java @@ -47,13 +47,13 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab } @Override - public FakeTrackOutput track(int trackId) { - FakeTrackOutput output = trackOutputs.get(trackId); + public FakeTrackOutput track(int id, int type) { + FakeTrackOutput output = trackOutputs.get(id); if (output == null) { Assert.assertFalse(tracksEnded); numberOfTracks++; output = new FakeTrackOutput(); - trackOutputs.put(trackId, output); + trackOutputs.put(id, output); } return output; }