diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index bfb557d4c8..999692917b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -2588,6 +2588,8 @@ import java.util.concurrent.TimeoutException; surfaceSize = new Size(width, height); listeners.sendEvent( EVENT_SURFACE_SIZE_CHANGED, listener -> listener.onSurfaceSizeChanged(width, height)); + sendRendererMessage( + TRACK_TYPE_VIDEO, MSG_SET_VIDEO_OUTPUT_RESOLUTION, new Size(width, height)); } } @@ -2945,8 +2947,6 @@ import java.util.concurrent.TimeoutException; @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { maybeNotifySurfaceSizeChanged(width, height); - sendRendererMessage( - TRACK_TYPE_VIDEO, MSG_SET_VIDEO_OUTPUT_RESOLUTION, new Size(width, height)); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java index 6f5867ed83..94966f1f65 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java @@ -695,7 +695,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { } private void setOutput(@Nullable Object output) throws ExoPlaybackException { - // TODO(b/238302341) Handle output surface change in previewing. // Handle unsupported (i.e., non-Surface) outputs by clearing the display surface. @Nullable Surface displaySurface = output instanceof Surface ? (Surface) output : null; @@ -720,7 +719,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { @State int state = getState(); @Nullable MediaCodecAdapter codec = getCodec(); - if (codec != null) { + // When FrameProcessorManager is enabled, set FrameProcessorManager's display surface when + // surface's resolution is set on receiving MSG_SET_VIDEO_OUTPUT_RESOLUTION. + if (codec != null && !frameProcessorManager.isEnabled()) { if (Util.SDK_INT >= 23 && displaySurface != null && !codecNeedsSetOutputSurfaceWorkaround) { setOutputSurfaceV23(codec, displaySurface); } else { @@ -734,12 +735,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { // We haven't rendered to the new display surface yet. clearRenderedFirstFrame(); if (state == STATE_STARTED) { + // Set joining deadline to report MediaCodecVideoRenderer is ready. setJoiningDeadlineMs(); } } else { // The display surface has been removed. clearReportedVideoSize(); clearRenderedFirstFrame(); + if (frameProcessorManager.isEnabled()) { + frameProcessorManager.clearOutputSurfaceInfo(); + } } } else if (displaySurface != null && displaySurface != placeholderSurface) { // The display surface is set and unchanged. If we know the video size and/or have already @@ -1807,6 +1812,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { */ private @MonotonicNonNull Pair currentFrameFormat; + @Nullable private Pair currentSurfaceAndSize; + private int frameProcessorMaxPendingFrameCount; private boolean canEnableFrameProcessing; @@ -1957,12 +1964,28 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { * @param outputResolution The {@link Size} of the output resolution. */ public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) { + if (currentSurfaceAndSize != null + && currentSurfaceAndSize.first.equals(outputSurface) + && currentSurfaceAndSize.second.equals(outputResolution)) { + return; + } checkNotNull(frameProcessor) .setOutputSurfaceInfo( new SurfaceInfo( outputSurface, outputResolution.getWidth(), outputResolution.getHeight())); + currentSurfaceAndSize = Pair.create(outputSurface, outputResolution); } + /** + * Clears the set output surface info. + * + *

Caller must ensure the {@code FrameProcessorManager} {@link #isEnabled()} before calling + * this method. + */ + public void clearOutputSurfaceInfo() { + checkNotNull(frameProcessor).setOutputSurfaceInfo(null); + currentSurfaceAndSize = null; + } /** * Sets the input surface info. *