Send empty pusi flagged data, on end of input, from TS extractor to readers; add end of input flag to readers to flush accumulated data from last PES

This commit is contained in:
Daniele Sparano 2023-05-22 18:53:56 +01:00 committed by Ian Baker
parent e0191ddded
commit c6c048f542
17 changed files with 45 additions and 20 deletions

View File

@ -157,7 +157,7 @@ public final class Ac3Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -159,7 +159,7 @@ public final class Ac4Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -192,7 +192,7 @@ public final class AdtsReader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -131,7 +131,7 @@ public final class DtsReader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -87,7 +87,7 @@ public final class DvbSubtitleReader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
if (writingSample) { if (writingSample) {
if (sampleTimeUs != C.TIME_UNSET) { if (sampleTimeUs != C.TIME_UNSET) {
for (TrackOutput output : outputs) { for (TrackOutput output : outputs) {

View File

@ -54,5 +54,5 @@ public interface ElementaryStreamReader {
void consume(ParsableByteArray data) throws ParserException; void consume(ParsableByteArray data) throws ParserException;
/** Called when a packet ends. */ /** Called when a packet ends. */
void packetFinished(); void packetFinished(boolean isEndOfInput);
} }

View File

@ -217,7 +217,7 @@ public final class H262Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -217,7 +217,7 @@ public final class H263Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -168,8 +168,10 @@ public final class H264Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. if (isEndOfInput) {
sampleReader.end(totalBytesWritten);
}
} }
@RequiresNonNull("sampleReader") @RequiresNonNull("sampleReader")
@ -500,6 +502,12 @@ public final class H264Reader implements ElementaryStreamReader {
output.sampleMetadata(sampleTimeUs, flags, size, offset, null); output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
} }
public void end(long position) {
// Output a final sample with the nal units currently held
nalUnitStartPosition = position;
outputSample(0);
}
private static final class SliceHeaderData { private static final class SliceHeaderData {
private static final int SLICE_TYPE_I = 2; private static final int SLICE_TYPE_I = 2;

View File

@ -173,8 +173,10 @@ public final class H265Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. if (isEndOfInput) {
sampleReader.end(totalBytesWritten);
}
} }
@RequiresNonNull("sampleReader") @RequiresNonNull("sampleReader")
@ -376,6 +378,12 @@ public final class H265Reader implements ElementaryStreamReader {
output.sampleMetadata(sampleTimeUs, flags, size, offset, null); output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
} }
public void end(long position) {
// Output a final sample with the nal units currently held
nalUnitPosition = position;
outputSample(0);
}
/** Returns whether a NAL unit type is one that occurs before any VCL NAL units in a sample. */ /** Returns whether a NAL unit type is one that occurs before any VCL NAL units in a sample. */
private static boolean isPrefixNalUnit(int nalUnitType) { private static boolean isPrefixNalUnit(int nalUnitType) {
return (VPS_NUT <= nalUnitType && nalUnitType <= AUD_NUT) || nalUnitType == PREFIX_SEI_NUT; return (VPS_NUT <= nalUnitType && nalUnitType <= AUD_NUT) || nalUnitType == PREFIX_SEI_NUT;

View File

@ -121,7 +121,7 @@ public final class Id3Reader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
Assertions.checkStateNotNull(output); // Asserts that createTracks has been called. Assertions.checkStateNotNull(output); // Asserts that createTracks has been called.
if (!writingSample || sampleSize == 0 || sampleBytesRead != sampleSize) { if (!writingSample || sampleSize == 0 || sampleBytesRead != sampleSize) {
return; return;

View File

@ -151,7 +151,7 @@ public final class LatmReader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -118,7 +118,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
} }
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
// Do nothing. // Do nothing.
} }

View File

@ -107,7 +107,8 @@ public final class PesReader implements TsPayloadReader {
Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes"); Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
} }
// Either way, notify the reader that it has now finished. // Either way, notify the reader that it has now finished.
reader.packetFinished(); boolean isEndOfInput = (data.limit() == 0);
reader.packetFinished(isEndOfInput);
break; break;
default: default:
throw new IllegalStateException(); throw new IllegalStateException();
@ -147,7 +148,8 @@ public final class PesReader implements TsPayloadReader {
if (payloadSize != C.LENGTH_UNSET) { if (payloadSize != C.LENGTH_UNSET) {
payloadSize -= readLength; payloadSize -= readLength;
if (payloadSize == 0) { if (payloadSize == 0) {
reader.packetFinished(); // There are bytes left in data, see above, so this is not the end of input
reader.packetFinished(false);
setState(STATE_READING_HEADER); setState(STATE_READING_HEADER);
} }
} }

View File

@ -357,7 +357,7 @@ public final class PsExtractor implements Extractor {
pesPayloadReader.packetStarted(timeUs, TsPayloadReader.FLAG_DATA_ALIGNMENT_INDICATOR); pesPayloadReader.packetStarted(timeUs, TsPayloadReader.FLAG_DATA_ALIGNMENT_INDICATOR);
pesPayloadReader.consume(data); pesPayloadReader.consume(data);
// We always have complete PES packets with program stream. // We always have complete PES packets with program stream.
pesPayloadReader.packetFinished(); pesPayloadReader.packetFinished(false);
} }
private void parseHeader() { private void parseHeader() {

View File

@ -323,7 +323,14 @@ public final class TsExtractor implements Extractor {
} }
if (!fillBufferWithAtLeastOnePacket(input)) { if (!fillBufferWithAtLeastOnePacket(input)) {
return RESULT_END_OF_INPUT; if (mode != MODE_HLS) {
// Send a dummy pusi to allow for packetFinished to be triggered on the last unit
for (int i = 0; i < tsPayloadReaders.size(); i++) {
TsPayloadReader payloadReader = tsPayloadReaders.valueAt(i);
int pid = tsPayloadReaders.keyAt(i);
payloadReader.consume(new ParsableByteArray(), FLAG_PAYLOAD_UNIT_START_INDICATOR);
}
} return RESULT_END_OF_INPUT;
} }
int endOfPacket = findEndOfFirstTsPacketInBuffer(); int endOfPacket = findEndOfFirstTsPacketInBuffer();

View File

@ -287,7 +287,7 @@ public final class TsExtractorTest {
public void consume(ParsableByteArray data) {} public void consume(ParsableByteArray data) {}
@Override @Override
public void packetFinished() { public void packetFinished(boolean isEndOfInput) {
packetsRead++; packetsRead++;
} }