Pro-actively parse the final PES packet.
This commit is contained in:
parent
71f918c01b
commit
55b4272a46
@ -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.
|
||||||
pesBuffer.append(tsBuffer, tsBuffer.bytesLeft());
|
Assertions.checkState(packetLength == 0);
|
||||||
|
readPacketBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
pesBuffer.append(tsBuffer, tsBuffer.bytesLeft());
|
||||||
* Parses completed PES data.
|
|
||||||
*/
|
if (packetLength == -1 && pesBuffer.bytesLeft() >= 6) {
|
||||||
private void readPES() {
|
// We haven't read the start of the packet, but have enough data to do so.
|
||||||
int packetStartCodePrefix = pesBuffer.readBits(24);
|
readPacketStart();
|
||||||
if (packetStartCodePrefix != 0x000001) {
|
}
|
||||||
|
if (packetLength > 0 && pesBuffer.bytesLeft() >= packetLength) {
|
||||||
|
// The packet length was specified and we now have the whole packet. Read it.
|
||||||
|
readPacketBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readPacketStart() {
|
||||||
|
int startCodePrefix = pesBuffer.readBits(24);
|
||||||
|
if (startCodePrefix != 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user