Remove 1 track per type limitation in TsExtractor

Mainly, this allows the extractor to expose multiple audio tracks.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130928152
This commit is contained in:
aquilescanta 2016-08-22 05:07:42 -07:00 committed by Oliver Woodman
parent d5607cfc47
commit abdb8ddb6e
3 changed files with 31 additions and 46 deletions

View File

@ -2,8 +2,8 @@ seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = 0
numberOfTracks = 3
track 2:
numberOfTracks = 2
track 256:
format:
bitrate = -1
id = null
@ -35,7 +35,7 @@ track 2:
time = 66733
flags = 0
data = length 18112, hash EC44B35B
track 3:
track 257:
format:
bitrate = -1
id = null
@ -74,27 +74,4 @@ track 3:
time = 100822
flags = 1
data = length 1254, hash 73FB07B8
track 21:
format:
bitrate = -1
id = null
containerMimeType = null
sampleMimeType = application/id3
maxInputSize = -1
width = -1
height = -1
frameRate = -1.0
rotationDegrees = -1
pixelWidthHeightRatio = -1.0
channelCount = -1
sampleRate = -1
pcmEncoding = -1
encoderDelay = -1
encoderPadding = -1
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
initializationData:
sample count = 0
tracksEnded = true

View File

@ -53,6 +53,7 @@ public final class TsExtractor implements Extractor {
public static final int WORKAROUND_IGNORE_AAC_STREAM = 2;
public static final int WORKAROUND_IGNORE_H264_STREAM = 4;
public static final int WORKAROUND_DETECT_ACCESS_UNITS = 8;
public static final int WORKAROUND_MAP_BY_TYPE = 16;
private static final String TAG = "TsExtractor";
@ -71,7 +72,7 @@ public final class TsExtractor implements Extractor {
private static final int TS_STREAM_TYPE_H264 = 0x1B;
private static final int TS_STREAM_TYPE_H265 = 0x24;
private static final int TS_STREAM_TYPE_ID3 = 0x15;
private static final int TS_STREAM_TYPE_EIA608 = 0x100; // 0xFF + 1
private static final int BASE_EMBEDDED_TRACK_ID = 0x2000; // 0xFF + 1
private static final long AC3_FORMAT_IDENTIFIER = Util.getIntegerCodeForString("AC-3");
private static final long E_AC3_FORMAT_IDENTIFIER = Util.getIntegerCodeForString("EAC3");
@ -85,10 +86,11 @@ public final class TsExtractor implements Extractor {
private final ParsableByteArray tsPacketBuffer;
private final ParsableBitArray tsScratch;
/* package */ final SparseArray<TsPayloadReader> tsPayloadReaders; // Indexed by pid
/* package */ final SparseBooleanArray streamTypes;
/* package */ final SparseBooleanArray trackIds;
// Accessed only by the loading thread.
private ExtractorOutput output;
private int nextEmbeddedTrackId;
/* package */ Id3Reader id3Reader;
public TsExtractor() {
@ -106,7 +108,8 @@ public final class TsExtractor implements Extractor {
tsScratch = new ParsableBitArray(new byte[3]);
tsPayloadReaders = new SparseArray<>();
tsPayloadReaders.put(TS_PAT_PID, new PatReader());
streamTypes = new SparseBooleanArray();
trackIds = new SparseBooleanArray();
nextEmbeddedTrackId = BASE_EMBEDDED_TRACK_ID;
}
// Extractor implementation.
@ -359,7 +362,7 @@ public final class TsExtractor implements Extractor {
// Skip the descriptors.
sectionData.skipBytes(programInfoLength);
if (id3Reader == null) {
if ((workaroundFlags & WORKAROUND_MAP_BY_TYPE) != 0 && id3Reader == null) {
// Setup an ID3 track regardless of whether there's a corresponding entry, in case one
// appears intermittently during playback. See b/20261500.
id3Reader = new Id3Reader(output.track(TS_STREAM_TYPE_ID3));
@ -381,48 +384,52 @@ public final class TsExtractor implements Extractor {
sectionData.skipBytes(esInfoLength);
}
remainingEntriesLength -= esInfoLength + 5;
if (streamTypes.get(streamType)) {
int trackId = (workaroundFlags & WORKAROUND_MAP_BY_TYPE) != 0 ? streamType : elementaryPid;
if (trackIds.get(trackId)) {
continue;
}
ElementaryStreamReader pesPayloadReader;
switch (streamType) {
case TS_STREAM_TYPE_MPA:
pesPayloadReader = new MpegAudioReader(output.track(TS_STREAM_TYPE_MPA));
pesPayloadReader = new MpegAudioReader(output.track(trackId));
break;
case TS_STREAM_TYPE_MPA_LSF:
pesPayloadReader = new MpegAudioReader(output.track(TS_STREAM_TYPE_MPA_LSF));
pesPayloadReader = new MpegAudioReader(output.track(trackId));
break;
case TS_STREAM_TYPE_AAC:
pesPayloadReader = (workaroundFlags & WORKAROUND_IGNORE_AAC_STREAM) != 0 ? null
: new AdtsReader(output.track(TS_STREAM_TYPE_AAC), new DummyTrackOutput());
: new AdtsReader(output.track(trackId), new DummyTrackOutput());
break;
case TS_STREAM_TYPE_AC3:
pesPayloadReader = new Ac3Reader(output.track(TS_STREAM_TYPE_AC3), false);
pesPayloadReader = new Ac3Reader(output.track(trackId), false);
break;
case TS_STREAM_TYPE_E_AC3:
pesPayloadReader = new Ac3Reader(output.track(TS_STREAM_TYPE_E_AC3), true);
pesPayloadReader = new Ac3Reader(output.track(trackId), true);
break;
case TS_STREAM_TYPE_DTS:
case TS_STREAM_TYPE_HDMV_DTS:
pesPayloadReader = new DtsReader(output.track(TS_STREAM_TYPE_DTS));
pesPayloadReader = new DtsReader(output.track(trackId));
break;
case TS_STREAM_TYPE_H262:
pesPayloadReader = new H262Reader(output.track(TS_STREAM_TYPE_H262));
pesPayloadReader = new H262Reader(output.track(trackId));
break;
case TS_STREAM_TYPE_H264:
pesPayloadReader = (workaroundFlags & WORKAROUND_IGNORE_H264_STREAM) != 0 ? null
: new H264Reader(output.track(TS_STREAM_TYPE_H264),
new SeiReader(output.track(TS_STREAM_TYPE_EIA608)),
: new H264Reader(output.track(trackId),
new SeiReader(output.track(nextEmbeddedTrackId++)),
(workaroundFlags & WORKAROUND_ALLOW_NON_IDR_KEYFRAMES) != 0,
(workaroundFlags & WORKAROUND_DETECT_ACCESS_UNITS) != 0);
break;
case TS_STREAM_TYPE_H265:
pesPayloadReader = new H265Reader(output.track(TS_STREAM_TYPE_H265),
new SeiReader(output.track(TS_STREAM_TYPE_EIA608)));
pesPayloadReader = new H265Reader(output.track(trackId),
new SeiReader(output.track(nextEmbeddedTrackId++)));
break;
case TS_STREAM_TYPE_ID3:
pesPayloadReader = id3Reader;
if ((workaroundFlags & WORKAROUND_MAP_BY_TYPE) != 0) {
pesPayloadReader = id3Reader;
} else {
pesPayloadReader = new Id3Reader(output.track(nextEmbeddedTrackId++));
}
break;
default:
pesPayloadReader = null;
@ -430,7 +437,7 @@ public final class TsExtractor implements Extractor {
}
if (pesPayloadReader != null) {
streamTypes.put(streamType, true);
trackIds.put(trackId, true);
tsPayloadReaders.put(elementaryPid,
new PesReader(pesPayloadReader, ptsTimestampAdjuster));
}

View File

@ -309,7 +309,8 @@ public class HlsChunkSource {
// The master source has yet to instantiate an adjuster for the discontinuity sequence.
return;
}
int workaroundFlags = 0;
// This flag ensures the change of pid between streams does not affect the sample queues.
int workaroundFlags = TsExtractor.WORKAROUND_MAP_BY_TYPE;
String codecs = variants[newVariantIndex].codecs;
if (!TextUtils.isEmpty(codecs)) {
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really