Fix end of stream handling for previewing.

Before this CL, the `renderedLastFrame` flag is not set if the last frame is released immediately (force render), or when it's dropped.

PiperOrigin-RevId: 506358626
This commit is contained in:
claincly 2023-02-01 18:37:44 +00:00 committed by christosts
parent 0f4fcc1110
commit a817bd42e2

View file

@ -2195,9 +2195,11 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
bufferPresentationTimeUs, bufferPresentationTimeUs,
isStarted); isStarted);
boolean isLastFrame = processedLastFrame && processedFramesTimestampsUs.size() == 1;
boolean shouldReleaseFrameImmediately = renderer.shouldForceRender(positionUs, earlyUs); boolean shouldReleaseFrameImmediately = renderer.shouldForceRender(positionUs, earlyUs);
if (shouldReleaseFrameImmediately) { if (shouldReleaseFrameImmediately) {
releaseProcessedFrameInternal(FrameProcessor.RELEASE_OUTPUT_FRAME_IMMEDIATELY); releaseProcessedFrameInternal(
FrameProcessor.RELEASE_OUTPUT_FRAME_IMMEDIATELY, isLastFrame);
break; break;
} else if (!isStarted || positionUs == renderer.initialPositionUs) { } else if (!isStarted || positionUs == renderer.initialPositionUs) {
return; return;
@ -2217,9 +2219,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// TODO(b/238302341) Handle very late buffers and drop to key frame. Need to flush // TODO(b/238302341) Handle very late buffers and drop to key frame. Need to flush
// FrameProcessor input frames in this case. // FrameProcessor input frames in this case.
boolean isLastFrame = processedLastFrame && processedFramesTimestampsUs.size() == 1;
if (renderer.shouldDropOutputBuffer(earlyUs, elapsedRealtimeUs, isLastFrame)) { if (renderer.shouldDropOutputBuffer(earlyUs, elapsedRealtimeUs, isLastFrame)) {
releaseProcessedFrameInternal(FrameProcessor.DROP_OUTPUT_FRAME); releaseProcessedFrameInternal(FrameProcessor.DROP_OUTPUT_FRAME, isLastFrame);
continue; continue;
} }
@ -2235,10 +2236,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
pendingOutputSizeChangeNotificationTimeUs = C.TIME_UNSET; pendingOutputSizeChangeNotificationTimeUs = C.TIME_UNSET;
renderer.maybeNotifyVideoSizeChanged(processedFrameSize); renderer.maybeNotifyVideoSizeChanged(processedFrameSize);
} }
releaseProcessedFrameInternal(adjustedFrameReleaseTimeNs); releaseProcessedFrameInternal(adjustedFrameReleaseTimeNs, isLastFrame);
if (isLastFrame) {
releasedLastFrame = true;
}
} }
} }
@ -2261,7 +2259,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
canEnableFrameProcessing = true; canEnableFrameProcessing = true;
} }
private void releaseProcessedFrameInternal(long releaseTimeNs) { private void releaseProcessedFrameInternal(long releaseTimeNs, boolean isLastFrame) {
checkStateNotNull(frameProcessor); checkStateNotNull(frameProcessor);
frameProcessor.releaseOutputFrame(releaseTimeNs); frameProcessor.releaseOutputFrame(releaseTimeNs);
processedFramesTimestampsUs.remove(); processedFramesTimestampsUs.remove();
@ -2269,6 +2267,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (releaseTimeNs != FrameProcessor.DROP_OUTPUT_FRAME) { if (releaseTimeNs != FrameProcessor.DROP_OUTPUT_FRAME) {
renderer.maybeNotifyRenderedFirstFrame(); renderer.maybeNotifyRenderedFirstFrame();
} }
if (isLastFrame) {
releasedLastFrame = true;
}
} }
private static final class FrameProcessorAccessor { private static final class FrameProcessorAccessor {