Propagate track type through ExtractorOutput.track

This allows binding by track type in ChunkExtractorWrapper, which
allows the EMSG and 608 tracks to be enabled on FragmentedMp4Extractor
in DefaultDashChunkSource. ChunkExtractorWrapper currently binds these
to DummyTrackOutputs.

Note: I wanted to pass the mimeType instead, since it's a more specific,
but unfortunately there's at least one place where it's not known at the
point of invoking track() (FlvExtractor).

Issue #2176

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146471082
This commit is contained in:
olly 2017-02-03 07:06:58 -08:00 committed by Oliver Woodman
parent ebc5e327e6
commit d3f4da749c
30 changed files with 98 additions and 60 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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));
}

View File

@ -210,7 +210,8 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
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<T extends ExoMediaCrypto> {
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 */);
}
}

View File

@ -23,17 +23,18 @@ public interface ExtractorOutput {
/**
* Called by the {@link Extractor} to get the {@link TrackOutput} for a specific track.
* <p>
* 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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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<Representation> representations = getRepresentations();
AdaptationSet adaptationSet = getAdaptationSet();
List<Representation> 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<Representation> representations = getRepresentations();
List<Representation> 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<Representation> 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();
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;
}