Fix handling of H.262 CSD

The start code for H.262 codec-specific data may be across a packet boundary.
Before this change the offset passed to CsdBuffer.onData may have been before
the start point of the data in the newData buffer.

After this change, start codes are added directly to the CSD buffer when it's
filling and any start code bytes added by onData (at the end of a packet) are
discarded.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=163943584
This commit is contained in:
andrewlewis 2017-08-02 01:25:41 -07:00 committed by Oliver Woodman
parent 0717782fdc
commit e604daaa09

View file

@ -103,9 +103,8 @@ public final class H262Reader implements ElementaryStreamReader {
totalBytesWritten += data.bytesLeft();
output.sampleData(data, data.bytesLeft());
int searchOffset = offset;
while (true) {
int startCodeOffset = NalUnitUtil.findNalUnit(dataArray, searchOffset, limit, prefixFlags);
int startCodeOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
if (startCodeOffset == limit) {
// We've scanned to the end of the data without finding another start code.
@ -126,7 +125,7 @@ public final class H262Reader implements ElementaryStreamReader {
csdBuffer.onData(dataArray, offset, startCodeOffset);
}
// This is the number of bytes belonging to the next start code that have already been
// passed to csdDataTargetBuffer.
// passed to csdBuffer.
int bytesAlreadyPassed = lengthToStartCode < 0 ? -lengthToStartCode : 0;
if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) {
// The csd data is complete, so we can decode and output the media format.
@ -160,8 +159,7 @@ public final class H262Reader implements ElementaryStreamReader {
isKeyframe = true;
}
offset = startCodeOffset;
searchOffset = offset + 3;
offset = startCodeOffset + 3;
}
}
@ -226,6 +224,8 @@ public final class H262Reader implements ElementaryStreamReader {
private static final class CsdBuffer {
private static final byte[] START_CODE = new byte[] {0, 0, 1};
private boolean isFilling;
public int length;
@ -249,24 +249,25 @@ public final class H262Reader implements ElementaryStreamReader {
* Called when a start code is encountered in the stream.
*
* @param startCodeValue The start code value.
* @param bytesAlreadyPassed The number of bytes of the start code that have already been
* passed to {@link #onData(byte[], int, int)}, or 0.
* @param bytesAlreadyPassed The number of bytes of the start code that have been passed to
* {@link #onData(byte[], int, int)}, or 0.
* @return Whether the csd data is now complete. If true is returned, neither
* this method or {@link #onData(byte[], int, int)} should be called again without an
* this method nor {@link #onData(byte[], int, int)} should be called again without an
* interleaving call to {@link #reset()}.
*/
public boolean onStartCode(int startCodeValue, int bytesAlreadyPassed) {
if (isFilling) {
length -= bytesAlreadyPassed;
if (sequenceExtensionPosition == 0 && startCodeValue == START_EXTENSION) {
sequenceExtensionPosition = length - bytesAlreadyPassed;
sequenceExtensionPosition = length;
} else {
length -= bytesAlreadyPassed;
isFilling = false;
return true;
}
} else if (startCodeValue == START_SEQUENCE_HEADER) {
isFilling = true;
}
onData(START_CODE, 0, START_CODE.length);
return false;
}