Commit c9e644b4 by claincly Committed by Ian Baker

Allow changing output surface in previewing

It covers the following cases:

| From/To     | `null` | `surface 0` | `surface 1` |
|-------------|--------|-------------|-------------|
| `null`      | 🆖      | 📺           | 📺           |
| `surface 0` |       | 🔁           | 📺           |
| `surface 1` |       | 📺           | 🔁           |

Where
- 🆖 means NOP
-  means
  - Set `null` on FrameProcessor, effectively dropping all frames
- 📺 means
  - Notify the listener of video size
  - Set FrameProcessor output surface and size when MSG_SET_VIDEO_OUTPUT_SIZE is received
- 🔁 means
  - Notify the listener of video size

PiperOrigin-RevId: 495477620
parent d5ae7687
...@@ -2588,6 +2588,8 @@ import java.util.concurrent.TimeoutException; ...@@ -2588,6 +2588,8 @@ import java.util.concurrent.TimeoutException;
surfaceSize = new Size(width, height); surfaceSize = new Size(width, height);
listeners.sendEvent( listeners.sendEvent(
EVENT_SURFACE_SIZE_CHANGED, listener -> listener.onSurfaceSizeChanged(width, height)); 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; ...@@ -2945,8 +2947,6 @@ import java.util.concurrent.TimeoutException;
@Override @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
maybeNotifySurfaceSizeChanged(width, height); maybeNotifySurfaceSizeChanged(width, height);
sendRendererMessage(
TRACK_TYPE_VIDEO, MSG_SET_VIDEO_OUTPUT_RESOLUTION, new Size(width, height));
} }
@Override @Override
......
...@@ -695,7 +695,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -695,7 +695,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
private void setOutput(@Nullable Object output) throws ExoPlaybackException { 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. // Handle unsupported (i.e., non-Surface) outputs by clearing the display surface.
@Nullable Surface displaySurface = output instanceof Surface ? (Surface) output : null; @Nullable Surface displaySurface = output instanceof Surface ? (Surface) output : null;
...@@ -720,7 +719,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -720,7 +719,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@State int state = getState(); @State int state = getState();
@Nullable MediaCodecAdapter codec = getCodec(); @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) { if (Util.SDK_INT >= 23 && displaySurface != null && !codecNeedsSetOutputSurfaceWorkaround) {
setOutputSurfaceV23(codec, displaySurface); setOutputSurfaceV23(codec, displaySurface);
} else { } else {
...@@ -734,12 +735,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -734,12 +735,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// We haven't rendered to the new display surface yet. // We haven't rendered to the new display surface yet.
clearRenderedFirstFrame(); clearRenderedFirstFrame();
if (state == STATE_STARTED) { if (state == STATE_STARTED) {
// Set joining deadline to report MediaCodecVideoRenderer is ready.
setJoiningDeadlineMs(); setJoiningDeadlineMs();
} }
} else { } else {
// The display surface has been removed. // The display surface has been removed.
clearReportedVideoSize(); clearReportedVideoSize();
clearRenderedFirstFrame(); clearRenderedFirstFrame();
if (frameProcessorManager.isEnabled()) {
frameProcessorManager.clearOutputSurfaceInfo();
}
} }
} else if (displaySurface != null && displaySurface != placeholderSurface) { } else if (displaySurface != null && displaySurface != placeholderSurface) {
// The display surface is set and unchanged. If we know the video size and/or have already // 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 { ...@@ -1807,6 +1812,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
*/ */
private @MonotonicNonNull Pair<Long, Format> currentFrameFormat; private @MonotonicNonNull Pair<Long, Format> currentFrameFormat;
@Nullable private Pair<Surface, Size> currentSurfaceAndSize;
private int frameProcessorMaxPendingFrameCount; private int frameProcessorMaxPendingFrameCount;
private boolean canEnableFrameProcessing; private boolean canEnableFrameProcessing;
...@@ -1957,13 +1964,29 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1957,13 +1964,29 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @param outputResolution The {@link Size} of the output resolution. * @param outputResolution The {@link Size} of the output resolution.
*/ */
public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) { public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) {
if (currentSurfaceAndSize != null
&& currentSurfaceAndSize.first.equals(outputSurface)
&& currentSurfaceAndSize.second.equals(outputResolution)) {
return;
}
checkNotNull(frameProcessor) checkNotNull(frameProcessor)
.setOutputSurfaceInfo( .setOutputSurfaceInfo(
new SurfaceInfo( new SurfaceInfo(
outputSurface, outputResolution.getWidth(), outputResolution.getHeight())); outputSurface, outputResolution.getWidth(), outputResolution.getHeight()));
currentSurfaceAndSize = Pair.create(outputSurface, outputResolution);
} }
/** /**
* Clears the set output surface info.
*
* <p>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. * Sets the input surface info.
* *
* <p>Caller must ensure the {@code FrameProcessorManager} {@link #isEnabled()} before calling * <p>Caller must ensure the {@code FrameProcessorManager} {@link #isEnabled()} before calling
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment