Fix H264 reader key frame detection

This commit is contained in:
Daniele Sparano 2023-11-29 13:09:27 +00:00 committed by tonihei
parent 379cb3ba54
commit d4af13803a

View file

@ -183,7 +183,7 @@ public final class H264Reader implements ElementaryStreamReader {
pps.startNalUnit(nalUnitType); pps.startNalUnit(nalUnitType);
} }
sei.startNalUnit(nalUnitType); sei.startNalUnit(nalUnitType);
sampleReader.startNalUnit(position, nalUnitType, pesTimeUs); sampleReader.startNalUnit(position, nalUnitType, pesTimeUs, randomAccessIndicator);
} }
@RequiresNonNull("sampleReader") @RequiresNonNull("sampleReader")
@ -254,7 +254,7 @@ public final class H264Reader implements ElementaryStreamReader {
seiReader.consume(pesTimeUs, seiWrapper); seiReader.consume(pesTimeUs, seiWrapper);
} }
boolean sampleIsKeyFrame = boolean sampleIsKeyFrame =
sampleReader.endNalUnit(position, offset, hasOutputFormat, randomAccessIndicator); sampleReader.endNalUnit(position, offset, hasOutputFormat);
if (sampleIsKeyFrame) { if (sampleIsKeyFrame) {
// This is either an IDR frame or the first I-frame since the random access indicator, so mark // This is either an IDR frame or the first I-frame since the random access indicator, so mark
// it as a keyframe. Clear the flag so that subsequent non-IDR I-frames are not marked as // it as a keyframe. Clear the flag so that subsequent non-IDR I-frames are not marked as
@ -297,6 +297,7 @@ public final class H264Reader implements ElementaryStreamReader {
private long samplePosition; private long samplePosition;
private long sampleTimeUs; private long sampleTimeUs;
private boolean sampleIsKeyframe; private boolean sampleIsKeyframe;
private boolean randomAccessIndicator;
public SampleReader( public SampleReader(
TrackOutput output, boolean allowNonIdrKeyframes, boolean detectAccessUnits) { TrackOutput output, boolean allowNonIdrKeyframes, boolean detectAccessUnits) {
@ -330,10 +331,11 @@ public final class H264Reader implements ElementaryStreamReader {
sliceHeader.clear(); sliceHeader.clear();
} }
public void startNalUnit(long position, int type, long pesTimeUs) { public void startNalUnit(long position, int type, long pesTimeUs, boolean rai) {
nalUnitType = type; nalUnitType = type;
nalUnitTimeUs = pesTimeUs; nalUnitTimeUs = pesTimeUs;
nalUnitStartPosition = position; nalUnitStartPosition = position;
randomAccessIndicator = rai;
if ((allowNonIdrKeyframes && nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_NON_IDR) if ((allowNonIdrKeyframes && nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_NON_IDR)
|| (detectAccessUnits || (detectAccessUnits
&& (nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_IDR && (nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_IDR
@ -482,7 +484,7 @@ public final class H264Reader implements ElementaryStreamReader {
} }
public boolean endNalUnit( public boolean endNalUnit(
long position, int offset, boolean hasOutputFormat, boolean randomAccessIndicator) { long position, int offset, boolean hasOutputFormat) {
if (nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_AUD if (nalUnitType == NalUnitUtil.NAL_UNIT_TYPE_AUD
|| (detectAccessUnits && sliceHeader.isFirstVclNalUnitOfPicture(previousSliceHeader))) { || (detectAccessUnits && sliceHeader.isFirstVclNalUnitOfPicture(previousSliceHeader))) {
// If the NAL unit ending is the start of a new sample, output the previous one. // If the NAL unit ending is the start of a new sample, output the previous one.