Pro-actively parse the final PES packet.

This commit is contained in:
Oliver Woodman 2014-11-05 17:25:02 +00:00
parent 71f918c01b
commit 55b4272a46

View File

@ -267,7 +267,9 @@ public final class TsExtractor {
* Parses payload data. * Parses payload data.
*/ */
private abstract static class TsPayloadReader { private abstract static class TsPayloadReader {
public abstract void read(BitsArray tsBuffer, boolean payloadUnitStartIndicator); public abstract void read(BitsArray tsBuffer, boolean payloadUnitStartIndicator);
} }
/** /**
@ -389,33 +391,47 @@ public final class TsExtractor {
// Parses PES payload and extracts individual samples. // Parses PES payload and extracts individual samples.
private final PesPayloadReader pesPayloadReader; private final PesPayloadReader pesPayloadReader;
private int packetLength;
public PesReader(PesPayloadReader pesPayloadReader) { public PesReader(PesPayloadReader pesPayloadReader) {
this.pesPayloadReader = pesPayloadReader; this.pesPayloadReader = pesPayloadReader;
this.packetLength = -1;
pesBuffer = new BitsArray(); pesBuffer = new BitsArray();
} }
@Override @Override
public void read(BitsArray tsBuffer, boolean payloadUnitStartIndicator) { public void read(BitsArray tsBuffer, boolean payloadUnitStartIndicator) {
if (payloadUnitStartIndicator && !pesBuffer.isEmpty()) { if (payloadUnitStartIndicator && !pesBuffer.isEmpty()) {
readPES(); // We've encountered the start of the next packet, but haven't yet read the body. Read it.
// Note that this should only happen if the packet length was unspecified.
Assertions.checkState(packetLength == 0);
readPacketBody();
} }
pesBuffer.append(tsBuffer, tsBuffer.bytesLeft()); pesBuffer.append(tsBuffer, tsBuffer.bytesLeft());
if (packetLength == -1 && pesBuffer.bytesLeft() >= 6) {
// We haven't read the start of the packet, but have enough data to do so.
readPacketStart();
}
if (packetLength > 0 && pesBuffer.bytesLeft() >= packetLength) {
// The packet length was specified and we now have the whole packet. Read it.
readPacketBody();
}
} }
/** private void readPacketStart() {
* Parses completed PES data. int startCodePrefix = pesBuffer.readBits(24);
*/ if (startCodePrefix != 0x000001) {
private void readPES() {
int packetStartCodePrefix = pesBuffer.readBits(24);
if (packetStartCodePrefix != 0x000001) {
// Error. // Error.
} }
// TODO: Read and use stream_id. // TODO: Read and use stream_id.
// Skip stream_id. // Skip stream_id.
pesBuffer.skipBits(8); pesBuffer.skipBits(8);
int pesPacketLength = pesBuffer.readBits(16); packetLength = pesBuffer.readBits(16);
}
private void readPacketBody() {
// Skip some fields/flags. // Skip some fields/flags.
// TODO: might need to use data_alignment_indicator. // TODO: might need to use data_alignment_indicator.
pesBuffer.skipBits(8); // 2+2+1+1+1+1 pesBuffer.skipBits(8); // 2+2+1+1+1+1
@ -425,9 +441,9 @@ public final class TsExtractor {
// Skip some fields/flags. // Skip some fields/flags.
pesBuffer.skipBits(6); // 1+1+1+1+1+1 pesBuffer.skipBits(6); // 1+1+1+1+1+1
int pesHeaderDataLength = pesBuffer.readBits(8); int headerDataLength = pesBuffer.readBits(8);
if (pesHeaderDataLength == 0) { if (headerDataLength == 0) {
pesHeaderDataLength = pesBuffer.bytesLeft(); headerDataLength = pesBuffer.bytesLeft();
} }
long timeUs = 0; long timeUs = 0;
@ -442,22 +458,23 @@ public final class TsExtractor {
pesBuffer.skipBits(1); pesBuffer.skipBits(1);
timeUs = pts * 1000000 / 90000; timeUs = pts * 1000000 / 90000;
// Skip the rest of the header. // Skip the rest of the header.
pesBuffer.skipBytes(pesHeaderDataLength - 5); pesBuffer.skipBytes(headerDataLength - 5);
} else { } else {
// Skip the rest of the header. // Skip the rest of the header.
pesBuffer.skipBytes(pesHeaderDataLength); pesBuffer.skipBytes(headerDataLength);
} }
int payloadSize; int payloadSize;
if (pesPacketLength == 0) { if (packetLength == 0) {
// If pesPacketLength is not specified read all available data. // If pesPacketLength is not specified read all available data.
payloadSize = pesBuffer.bytesLeft(); payloadSize = pesBuffer.bytesLeft();
} else { } else {
payloadSize = pesPacketLength - pesHeaderDataLength - 3; payloadSize = packetLength - headerDataLength - 3;
} }
pesPayloadReader.read(pesBuffer, payloadSize, timeUs); pesPayloadReader.read(pesBuffer, payloadSize, timeUs);
pesBuffer.reset(); pesBuffer.reset();
packetLength = -1;
} }
} }