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:
parent
d5607cfc47
commit
abdb8ddb6e
@ -2,8 +2,8 @@ seekMap:
|
|||||||
isSeekable = false
|
isSeekable = false
|
||||||
duration = UNSET TIME
|
duration = UNSET TIME
|
||||||
getPosition(0) = 0
|
getPosition(0) = 0
|
||||||
numberOfTracks = 3
|
numberOfTracks = 2
|
||||||
track 2:
|
track 256:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = -1
|
||||||
id = null
|
id = null
|
||||||
@ -35,7 +35,7 @@ track 2:
|
|||||||
time = 66733
|
time = 66733
|
||||||
flags = 0
|
flags = 0
|
||||||
data = length 18112, hash EC44B35B
|
data = length 18112, hash EC44B35B
|
||||||
track 3:
|
track 257:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = -1
|
||||||
id = null
|
id = null
|
||||||
@ -74,27 +74,4 @@ track 3:
|
|||||||
time = 100822
|
time = 100822
|
||||||
flags = 1
|
flags = 1
|
||||||
data = length 1254, hash 73FB07B8
|
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
|
tracksEnded = true
|
||||||
|
@ -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_AAC_STREAM = 2;
|
||||||
public static final int WORKAROUND_IGNORE_H264_STREAM = 4;
|
public static final int WORKAROUND_IGNORE_H264_STREAM = 4;
|
||||||
public static final int WORKAROUND_DETECT_ACCESS_UNITS = 8;
|
public static final int WORKAROUND_DETECT_ACCESS_UNITS = 8;
|
||||||
|
public static final int WORKAROUND_MAP_BY_TYPE = 16;
|
||||||
|
|
||||||
private static final String TAG = "TsExtractor";
|
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_H264 = 0x1B;
|
||||||
private static final int TS_STREAM_TYPE_H265 = 0x24;
|
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_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 AC3_FORMAT_IDENTIFIER = Util.getIntegerCodeForString("AC-3");
|
||||||
private static final long E_AC3_FORMAT_IDENTIFIER = Util.getIntegerCodeForString("EAC3");
|
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 ParsableByteArray tsPacketBuffer;
|
||||||
private final ParsableBitArray tsScratch;
|
private final ParsableBitArray tsScratch;
|
||||||
/* package */ final SparseArray<TsPayloadReader> tsPayloadReaders; // Indexed by pid
|
/* package */ final SparseArray<TsPayloadReader> tsPayloadReaders; // Indexed by pid
|
||||||
/* package */ final SparseBooleanArray streamTypes;
|
/* package */ final SparseBooleanArray trackIds;
|
||||||
|
|
||||||
// Accessed only by the loading thread.
|
// Accessed only by the loading thread.
|
||||||
private ExtractorOutput output;
|
private ExtractorOutput output;
|
||||||
|
private int nextEmbeddedTrackId;
|
||||||
/* package */ Id3Reader id3Reader;
|
/* package */ Id3Reader id3Reader;
|
||||||
|
|
||||||
public TsExtractor() {
|
public TsExtractor() {
|
||||||
@ -106,7 +108,8 @@ public final class TsExtractor implements Extractor {
|
|||||||
tsScratch = new ParsableBitArray(new byte[3]);
|
tsScratch = new ParsableBitArray(new byte[3]);
|
||||||
tsPayloadReaders = new SparseArray<>();
|
tsPayloadReaders = new SparseArray<>();
|
||||||
tsPayloadReaders.put(TS_PAT_PID, new PatReader());
|
tsPayloadReaders.put(TS_PAT_PID, new PatReader());
|
||||||
streamTypes = new SparseBooleanArray();
|
trackIds = new SparseBooleanArray();
|
||||||
|
nextEmbeddedTrackId = BASE_EMBEDDED_TRACK_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extractor implementation.
|
// Extractor implementation.
|
||||||
@ -359,7 +362,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
// Skip the descriptors.
|
// Skip the descriptors.
|
||||||
sectionData.skipBytes(programInfoLength);
|
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
|
// Setup an ID3 track regardless of whether there's a corresponding entry, in case one
|
||||||
// appears intermittently during playback. See b/20261500.
|
// appears intermittently during playback. See b/20261500.
|
||||||
id3Reader = new Id3Reader(output.track(TS_STREAM_TYPE_ID3));
|
id3Reader = new Id3Reader(output.track(TS_STREAM_TYPE_ID3));
|
||||||
@ -381,48 +384,52 @@ public final class TsExtractor implements Extractor {
|
|||||||
sectionData.skipBytes(esInfoLength);
|
sectionData.skipBytes(esInfoLength);
|
||||||
}
|
}
|
||||||
remainingEntriesLength -= esInfoLength + 5;
|
remainingEntriesLength -= esInfoLength + 5;
|
||||||
if (streamTypes.get(streamType)) {
|
int trackId = (workaroundFlags & WORKAROUND_MAP_BY_TYPE) != 0 ? streamType : elementaryPid;
|
||||||
|
if (trackIds.get(trackId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementaryStreamReader pesPayloadReader;
|
ElementaryStreamReader pesPayloadReader;
|
||||||
switch (streamType) {
|
switch (streamType) {
|
||||||
case TS_STREAM_TYPE_MPA:
|
case TS_STREAM_TYPE_MPA:
|
||||||
pesPayloadReader = new MpegAudioReader(output.track(TS_STREAM_TYPE_MPA));
|
pesPayloadReader = new MpegAudioReader(output.track(trackId));
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_MPA_LSF:
|
case TS_STREAM_TYPE_MPA_LSF:
|
||||||
pesPayloadReader = new MpegAudioReader(output.track(TS_STREAM_TYPE_MPA_LSF));
|
pesPayloadReader = new MpegAudioReader(output.track(trackId));
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_AAC:
|
case TS_STREAM_TYPE_AAC:
|
||||||
pesPayloadReader = (workaroundFlags & WORKAROUND_IGNORE_AAC_STREAM) != 0 ? null
|
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;
|
break;
|
||||||
case TS_STREAM_TYPE_AC3:
|
case TS_STREAM_TYPE_AC3:
|
||||||
pesPayloadReader = new Ac3Reader(output.track(TS_STREAM_TYPE_AC3), false);
|
pesPayloadReader = new Ac3Reader(output.track(trackId), false);
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_E_AC3:
|
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;
|
break;
|
||||||
case TS_STREAM_TYPE_DTS:
|
case TS_STREAM_TYPE_DTS:
|
||||||
case TS_STREAM_TYPE_HDMV_DTS:
|
case TS_STREAM_TYPE_HDMV_DTS:
|
||||||
pesPayloadReader = new DtsReader(output.track(TS_STREAM_TYPE_DTS));
|
pesPayloadReader = new DtsReader(output.track(trackId));
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_H262:
|
case TS_STREAM_TYPE_H262:
|
||||||
pesPayloadReader = new H262Reader(output.track(TS_STREAM_TYPE_H262));
|
pesPayloadReader = new H262Reader(output.track(trackId));
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_H264:
|
case TS_STREAM_TYPE_H264:
|
||||||
pesPayloadReader = (workaroundFlags & WORKAROUND_IGNORE_H264_STREAM) != 0 ? null
|
pesPayloadReader = (workaroundFlags & WORKAROUND_IGNORE_H264_STREAM) != 0 ? null
|
||||||
: new H264Reader(output.track(TS_STREAM_TYPE_H264),
|
: new H264Reader(output.track(trackId),
|
||||||
new SeiReader(output.track(TS_STREAM_TYPE_EIA608)),
|
new SeiReader(output.track(nextEmbeddedTrackId++)),
|
||||||
(workaroundFlags & WORKAROUND_ALLOW_NON_IDR_KEYFRAMES) != 0,
|
(workaroundFlags & WORKAROUND_ALLOW_NON_IDR_KEYFRAMES) != 0,
|
||||||
(workaroundFlags & WORKAROUND_DETECT_ACCESS_UNITS) != 0);
|
(workaroundFlags & WORKAROUND_DETECT_ACCESS_UNITS) != 0);
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_H265:
|
case TS_STREAM_TYPE_H265:
|
||||||
pesPayloadReader = new H265Reader(output.track(TS_STREAM_TYPE_H265),
|
pesPayloadReader = new H265Reader(output.track(trackId),
|
||||||
new SeiReader(output.track(TS_STREAM_TYPE_EIA608)));
|
new SeiReader(output.track(nextEmbeddedTrackId++)));
|
||||||
break;
|
break;
|
||||||
case TS_STREAM_TYPE_ID3:
|
case TS_STREAM_TYPE_ID3:
|
||||||
pesPayloadReader = id3Reader;
|
if ((workaroundFlags & WORKAROUND_MAP_BY_TYPE) != 0) {
|
||||||
|
pesPayloadReader = id3Reader;
|
||||||
|
} else {
|
||||||
|
pesPayloadReader = new Id3Reader(output.track(nextEmbeddedTrackId++));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pesPayloadReader = null;
|
pesPayloadReader = null;
|
||||||
@ -430,7 +437,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pesPayloadReader != null) {
|
if (pesPayloadReader != null) {
|
||||||
streamTypes.put(streamType, true);
|
trackIds.put(trackId, true);
|
||||||
tsPayloadReaders.put(elementaryPid,
|
tsPayloadReaders.put(elementaryPid,
|
||||||
new PesReader(pesPayloadReader, ptsTimestampAdjuster));
|
new PesReader(pesPayloadReader, ptsTimestampAdjuster));
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,8 @@ public class HlsChunkSource {
|
|||||||
// The master source has yet to instantiate an adjuster for the discontinuity sequence.
|
// The master source has yet to instantiate an adjuster for the discontinuity sequence.
|
||||||
return;
|
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;
|
String codecs = variants[newVariantIndex].codecs;
|
||||||
if (!TextUtils.isEmpty(codecs)) {
|
if (!TextUtils.isEmpty(codecs)) {
|
||||||
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really
|
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really
|
||||||
|
Loading…
x
Reference in New Issue
Block a user