Merge pull request #3115 from goffioul/h262-segmentation

Fix H262 segmentation.
This commit is contained in:
ojw28 2017-08-01 11:09:30 +01:00 committed by GitHub
commit 08faafb4c1

View File

@ -51,7 +51,7 @@ public final class H262Reader implements ElementaryStreamReader {
// State that should be reset on seek. // State that should be reset on seek.
private final boolean[] prefixFlags; private final boolean[] prefixFlags;
private final CsdBuffer csdBuffer; private final CsdBuffer csdBuffer;
private boolean foundFirstFrameInGroup; private boolean foundPicture;
private long totalBytesWritten; private long totalBytesWritten;
// Per packet state that gets reset at the start of each packet. // Per packet state that gets reset at the start of each packet.
@ -60,8 +60,8 @@ public final class H262Reader implements ElementaryStreamReader {
// Per sample state that gets reset at the start of each frame. // Per sample state that gets reset at the start of each frame.
private boolean isKeyframe; private boolean isKeyframe;
private long framePosition; private long samplePosition;
private long frameTimeUs; private long sampleTimeUs;
public H262Reader() { public H262Reader() {
prefixFlags = new boolean[4]; prefixFlags = new boolean[4];
@ -73,7 +73,8 @@ public final class H262Reader implements ElementaryStreamReader {
NalUnitUtil.clearPrefixFlags(prefixFlags); NalUnitUtil.clearPrefixFlags(prefixFlags);
csdBuffer.reset(); csdBuffer.reset();
pesPtsUsAvailable = false; pesPtsUsAvailable = false;
foundFirstFrameInGroup = false; foundPicture = false;
samplePosition = C.POSITION_UNSET;
totalBytesWritten = 0; totalBytesWritten = 0;
} }
@ -136,25 +137,28 @@ public final class H262Reader implements ElementaryStreamReader {
} }
} }
if (hasOutputFormat && (startCodeValue == START_GROUP || startCodeValue == START_PICTURE)) { if (hasOutputFormat && (startCodeValue == START_PICTURE || startCodeValue == START_SEQUENCE_HEADER)) {
int bytesWrittenPastStartCode = limit - startCodeOffset; int bytesWrittenPastStartCode = limit - startCodeOffset;
if (foundFirstFrameInGroup) { boolean resetSample = (samplePosition == C.POSITION_UNSET);
if (foundPicture) {
@C.BufferFlags int flags = isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0; @C.BufferFlags int flags = isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
int size = (int) (totalBytesWritten - framePosition) - bytesWrittenPastStartCode; int size = (int) (totalBytesWritten - samplePosition) - bytesWrittenPastStartCode;
output.sampleMetadata(frameTimeUs, flags, size, bytesWrittenPastStartCode, null); output.sampleMetadata(sampleTimeUs, flags, size, bytesWrittenPastStartCode, null);
isKeyframe = false; isKeyframe = false;
resetSample = true;
} }
if (startCodeValue == START_GROUP) { foundPicture = (startCodeValue == START_PICTURE);
foundFirstFrameInGroup = false; if (resetSample) {
isKeyframe = true; samplePosition = totalBytesWritten - bytesWrittenPastStartCode;
} else /* startCodeValue == START_PICTURE */ { sampleTimeUs = (pesPtsUsAvailable ? pesTimeUs : sampleTimeUs + frameDurationUs);
frameTimeUs = pesPtsUsAvailable ? pesTimeUs : (frameTimeUs + frameDurationUs);
framePosition = totalBytesWritten - bytesWrittenPastStartCode;
pesPtsUsAvailable = false; pesPtsUsAvailable = false;
foundFirstFrameInGroup = true;
} }
} }
if (hasOutputFormat && startCodeValue == START_GROUP) {
isKeyframe = true;
}
offset = startCodeOffset; offset = startCodeOffset;
searchOffset = offset + 3; searchOffset = offset + 3;
} }