mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
0717782fdc
commit
e604daaa09
1 changed files with 11 additions and 10 deletions
|
|
@ -103,9 +103,8 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
totalBytesWritten += data.bytesLeft();
|
totalBytesWritten += data.bytesLeft();
|
||||||
output.sampleData(data, data.bytesLeft());
|
output.sampleData(data, data.bytesLeft());
|
||||||
|
|
||||||
int searchOffset = offset;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int startCodeOffset = NalUnitUtil.findNalUnit(dataArray, searchOffset, limit, prefixFlags);
|
int startCodeOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
|
||||||
|
|
||||||
if (startCodeOffset == limit) {
|
if (startCodeOffset == limit) {
|
||||||
// We've scanned to the end of the data without finding another start code.
|
// 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);
|
csdBuffer.onData(dataArray, offset, startCodeOffset);
|
||||||
}
|
}
|
||||||
// This is the number of bytes belonging to the next start code that have already been
|
// 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;
|
int bytesAlreadyPassed = lengthToStartCode < 0 ? -lengthToStartCode : 0;
|
||||||
if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) {
|
if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) {
|
||||||
// The csd data is complete, so we can decode and output the media format.
|
// 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;
|
isKeyframe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = startCodeOffset;
|
offset = startCodeOffset + 3;
|
||||||
searchOffset = offset + 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,6 +224,8 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
|
|
||||||
private static final class CsdBuffer {
|
private static final class CsdBuffer {
|
||||||
|
|
||||||
|
private static final byte[] START_CODE = new byte[] {0, 0, 1};
|
||||||
|
|
||||||
private boolean isFilling;
|
private boolean isFilling;
|
||||||
|
|
||||||
public int length;
|
public int length;
|
||||||
|
|
@ -249,24 +249,25 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
* Called when a start code is encountered in the stream.
|
* Called when a start code is encountered in the stream.
|
||||||
*
|
*
|
||||||
* @param startCodeValue The start code value.
|
* @param startCodeValue The start code value.
|
||||||
* @param bytesAlreadyPassed The number of bytes of the start code that have already been
|
* @param bytesAlreadyPassed The number of bytes of the start code that have been passed to
|
||||||
* passed to {@link #onData(byte[], int, int)}, or 0.
|
* {@link #onData(byte[], int, int)}, or 0.
|
||||||
* @return Whether the csd data is now complete. If true is returned, neither
|
* @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()}.
|
* interleaving call to {@link #reset()}.
|
||||||
*/
|
*/
|
||||||
public boolean onStartCode(int startCodeValue, int bytesAlreadyPassed) {
|
public boolean onStartCode(int startCodeValue, int bytesAlreadyPassed) {
|
||||||
if (isFilling) {
|
if (isFilling) {
|
||||||
|
length -= bytesAlreadyPassed;
|
||||||
if (sequenceExtensionPosition == 0 && startCodeValue == START_EXTENSION) {
|
if (sequenceExtensionPosition == 0 && startCodeValue == START_EXTENSION) {
|
||||||
sequenceExtensionPosition = length - bytesAlreadyPassed;
|
sequenceExtensionPosition = length;
|
||||||
} else {
|
} else {
|
||||||
length -= bytesAlreadyPassed;
|
|
||||||
isFilling = false;
|
isFilling = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (startCodeValue == START_SEQUENCE_HEADER) {
|
} else if (startCodeValue == START_SEQUENCE_HEADER) {
|
||||||
isFilling = true;
|
isFilling = true;
|
||||||
}
|
}
|
||||||
|
onData(START_CODE, 0, START_CODE.length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue