mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Do not discard TS PES payload readers on Seek for TSExtractor in non-HLS mode.
Currently, we are discarding all TS PES payload readers on seek. This is to fix a bug that makes PES stream readers read packets inconsistently after seeking (first time, the readers ignore all packets before PMT, second seek time after PMT is read, the readers will read all packets before PMT). This works fine if we don't support seeking to arbitrary position within the TS stream. However, this may lead to a problem if we want to support seeking, because some TS streams only have track format at the begining of the stream, and reseting the payload readers after seeking can lead to track format not available anymore. This change reverts the original fix (do not discard TS PES payload readers on seek anymore). Instead, in non-HLS mode, after we have processed all PMTs packets in the strea, we will re-seek to the beginning and perform readin again to make sure the result will be consistent across multiple seeks. This is a prepare step to support seeking in TS streams. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=202466233
This commit is contained in:
parent
dd14500eba
commit
4f57c46560
@ -117,6 +117,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
private final TsPayloadReader.Factory payloadReaderFactory;
|
private final TsPayloadReader.Factory payloadReaderFactory;
|
||||||
private final SparseArray<TsPayloadReader> tsPayloadReaders; // Indexed by pid
|
private final SparseArray<TsPayloadReader> tsPayloadReaders; // Indexed by pid
|
||||||
private final SparseBooleanArray trackIds;
|
private final SparseBooleanArray trackIds;
|
||||||
|
private final SparseBooleanArray trackPids;
|
||||||
|
|
||||||
// Accessed only by the loading thread.
|
// Accessed only by the loading thread.
|
||||||
private ExtractorOutput output;
|
private ExtractorOutput output;
|
||||||
@ -167,6 +168,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
tsPacketBuffer = new ParsableByteArray(new byte[BUFFER_SIZE], 0);
|
tsPacketBuffer = new ParsableByteArray(new byte[BUFFER_SIZE], 0);
|
||||||
trackIds = new SparseBooleanArray();
|
trackIds = new SparseBooleanArray();
|
||||||
|
trackPids = new SparseBooleanArray();
|
||||||
tsPayloadReaders = new SparseArray<>();
|
tsPayloadReaders = new SparseArray<>();
|
||||||
continuityCounters = new SparseIntArray();
|
continuityCounters = new SparseIntArray();
|
||||||
resetPayloadReaders();
|
resetPayloadReaders();
|
||||||
@ -203,14 +205,16 @@ public final class TsExtractor implements Extractor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seek(long position, long timeUs) {
|
public void seek(long position, long timeUs) {
|
||||||
|
Assertions.checkState(mode != MODE_HLS);
|
||||||
int timestampAdjustersCount = timestampAdjusters.size();
|
int timestampAdjustersCount = timestampAdjusters.size();
|
||||||
for (int i = 0; i < timestampAdjustersCount; i++) {
|
for (int i = 0; i < timestampAdjustersCount; i++) {
|
||||||
timestampAdjusters.get(i).reset();
|
timestampAdjusters.get(i).reset();
|
||||||
}
|
}
|
||||||
tsPacketBuffer.reset();
|
tsPacketBuffer.reset();
|
||||||
continuityCounters.clear();
|
continuityCounters.clear();
|
||||||
// Elementary stream readers' state should be cleared to get consistent behaviours when seeking.
|
for (int i = 0; i < tsPayloadReaders.size(); i++) {
|
||||||
resetPayloadReaders();
|
tsPayloadReaders.valueAt(i).seek();
|
||||||
|
}
|
||||||
bytesSinceLastSync = 0;
|
bytesSinceLastSync = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,10 +278,21 @@ public final class TsExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the payload.
|
// Read the payload.
|
||||||
tsPacketBuffer.setLimit(endOfPacket);
|
boolean wereTracksEnded = tracksEnded;
|
||||||
payloadReader.consume(tsPacketBuffer, payloadUnitStartIndicator);
|
if (shouldConsumePacketPayload(pid)) {
|
||||||
tsPacketBuffer.setLimit(limit);
|
tsPacketBuffer.setLimit(endOfPacket);
|
||||||
|
payloadReader.consume(tsPacketBuffer, payloadUnitStartIndicator);
|
||||||
|
tsPacketBuffer.setLimit(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != MODE_HLS && !wereTracksEnded && tracksEnded) {
|
||||||
|
// We have read all tracks from all PMTs in this stream. Now seek to the beginning and read
|
||||||
|
// again to make sure we output all media, including any contained in packets prior to those
|
||||||
|
// containing the track information.
|
||||||
|
seek(/* position= */ 0, /* timeUs= */ 0);
|
||||||
|
seekPosition.position = 0;
|
||||||
|
return RESULT_SEEK;
|
||||||
|
}
|
||||||
tsPacketBuffer.setPosition(endOfPacket);
|
tsPacketBuffer.setPosition(endOfPacket);
|
||||||
return RESULT_CONTINUE;
|
return RESULT_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -345,6 +360,12 @@ public final class TsExtractor implements Extractor {
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldConsumePacketPayload(int packetPid) {
|
||||||
|
return mode == MODE_HLS
|
||||||
|
|| tracksEnded
|
||||||
|
|| !trackPids.get(packetPid, /* valueIfKeyNotFound= */ false); // It's a PSI packet
|
||||||
|
}
|
||||||
|
|
||||||
private void resetPayloadReaders() {
|
private void resetPayloadReaders() {
|
||||||
trackIds.clear();
|
trackIds.clear();
|
||||||
tsPayloadReaders.clear();
|
tsPayloadReaders.clear();
|
||||||
@ -511,14 +532,16 @@ public final class TsExtractor implements Extractor {
|
|||||||
int trackIdCount = trackIdToPidScratch.size();
|
int trackIdCount = trackIdToPidScratch.size();
|
||||||
for (int i = 0; i < trackIdCount; i++) {
|
for (int i = 0; i < trackIdCount; i++) {
|
||||||
int trackId = trackIdToPidScratch.keyAt(i);
|
int trackId = trackIdToPidScratch.keyAt(i);
|
||||||
|
int trackPid = trackIdToPidScratch.valueAt(i);
|
||||||
trackIds.put(trackId, true);
|
trackIds.put(trackId, true);
|
||||||
|
trackPids.put(trackPid, true);
|
||||||
TsPayloadReader reader = trackIdToReaderScratch.valueAt(i);
|
TsPayloadReader reader = trackIdToReaderScratch.valueAt(i);
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
if (reader != id3Reader) {
|
if (reader != id3Reader) {
|
||||||
reader.init(timestampAdjuster, output,
|
reader.init(timestampAdjuster, output,
|
||||||
new TrackIdGenerator(programNumber, trackId, MAX_PID_PLUS_ONE));
|
new TrackIdGenerator(programNumber, trackId, MAX_PID_PLUS_ONE));
|
||||||
}
|
}
|
||||||
tsPayloadReaders.put(trackIdToPidScratch.valueAt(i), reader);
|
tsPayloadReaders.put(trackPid, reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user