Fix blank video when switching on/off screen
This happens when using `ExoPlayer.setVideoEffects()`. This CL also fixes the first frame not rendered problem, originally solved in7e65cce967
, but rolled back in5056dfaa2b
because the solution introduces the flash that is observed in b/292111083. Before media3 1.1 release, the output size of `VideoFrameProcessor` is not reported to the app. This was changed later after introducing `CompositingVideoSinkProvider`, where the video size after processing **is** reported to the app. After this CL, the size is again, not reported. PiperOrigin-RevId: 602345087
This commit is contained in:
parent
bb533332f4
commit
dcae49a561
@ -55,7 +55,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
@ -103,7 +102,6 @@ public class EffectPlaybackTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("b/292111083")
|
|
||||||
public void exoplayerEffectsPreviewTest_ensuresFirstFrameRendered() throws Exception {
|
public void exoplayerEffectsPreviewTest_ensuresFirstFrameRendered() throws Exception {
|
||||||
assumeTrue(Util.SDK_INT >= 18);
|
assumeTrue(Util.SDK_INT >= 18);
|
||||||
|
|
||||||
|
@ -154,6 +154,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
|||||||
private boolean codecNeedsSetOutputSurfaceWorkaround;
|
private boolean codecNeedsSetOutputSurfaceWorkaround;
|
||||||
private boolean codecHandlesHdr10PlusOutOfBandMetadata;
|
private boolean codecHandlesHdr10PlusOutOfBandMetadata;
|
||||||
@Nullable private Surface displaySurface;
|
@Nullable private Surface displaySurface;
|
||||||
|
@Nullable private Size outputResolution;
|
||||||
@Nullable private PlaceholderSurface placeholderSurface;
|
@Nullable private PlaceholderSurface placeholderSurface;
|
||||||
private boolean haveReportedFirstFrameRenderedForCurrentSurface;
|
private boolean haveReportedFirstFrameRenderedForCurrentSurface;
|
||||||
private @C.VideoScalingMode int scalingMode;
|
private @C.VideoScalingMode int scalingMode;
|
||||||
@ -771,14 +772,14 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
|||||||
setVideoEffects(videoEffects);
|
setVideoEffects(videoEffects);
|
||||||
break;
|
break;
|
||||||
case MSG_SET_VIDEO_OUTPUT_RESOLUTION:
|
case MSG_SET_VIDEO_OUTPUT_RESOLUTION:
|
||||||
Size outputResolution = (Size) checkNotNull(message);
|
outputResolution = (Size) checkNotNull(message);
|
||||||
// TODO: b/292111083 Set the surface on the videoSinkProvider before it's initialized
|
// TODO: b/292111083 Set the surface on the videoSinkProvider before it's initialized
|
||||||
// otherwise the first frames are missed until a new video output resolution arrives.
|
// otherwise the first frames are missed until a new video output resolution arrives.
|
||||||
if (videoSinkProvider.isInitialized()
|
if (videoSinkProvider.isInitialized()
|
||||||
&& outputResolution.getWidth() != 0
|
&& checkNotNull(outputResolution).getWidth() != 0
|
||||||
&& outputResolution.getHeight() != 0
|
&& checkNotNull(outputResolution).getHeight() != 0
|
||||||
&& displaySurface != null) {
|
&& displaySurface != null) {
|
||||||
videoSinkProvider.setOutputSurfaceInfo(displaySurface, outputResolution);
|
videoSinkProvider.setOutputSurfaceInfo(displaySurface, checkNotNull(outputResolution));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_SET_AUDIO_ATTRIBUTES:
|
case MSG_SET_AUDIO_ATTRIBUTES:
|
||||||
@ -1063,6 +1064,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
|||||||
if (frameMetadataListener != null) {
|
if (frameMetadataListener != null) {
|
||||||
videoSinkProvider.setVideoFrameMetadataListener(frameMetadataListener);
|
videoSinkProvider.setVideoFrameMetadataListener(frameMetadataListener);
|
||||||
}
|
}
|
||||||
|
if (displaySurface != null && outputResolution != null) {
|
||||||
|
videoSinkProvider.setOutputSurfaceInfo(displaySurface, outputResolution);
|
||||||
|
}
|
||||||
} catch (VideoSink.VideoSinkException e) {
|
} catch (VideoSink.VideoSinkException e) {
|
||||||
throw createRendererException(
|
throw createRendererException(
|
||||||
e, format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSOR_INIT_FAILED);
|
e, format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSOR_INIT_FAILED);
|
||||||
@ -1087,7 +1091,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoSizeChanged(VideoSink videoSink, VideoSize videoSize) {
|
public void onVideoSizeChanged(VideoSink videoSink, VideoSize videoSize) {
|
||||||
maybeNotifyVideoSizeChanged(videoSize);
|
// TODO: b/292111083 - Report video size change to app. Video size reporting is
|
||||||
|
// removed at the moment to ensure the first frame is rendered, and the video is
|
||||||
|
// rendered after switching on/off the screen.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,8 +81,6 @@ import androidx.media3.exoplayer.ExoPlaybackException;
|
|||||||
|
|
||||||
private VideoSize reportedVideoSize;
|
private VideoSize reportedVideoSize;
|
||||||
private long outputStreamOffsetUs;
|
private long outputStreamOffsetUs;
|
||||||
// TODO b/292111083 - Remove the field and trigger the callback on every video size change.
|
|
||||||
private boolean reportedVideoSizeChange;
|
|
||||||
private long lastPresentationTimeUs;
|
private long lastPresentationTimeUs;
|
||||||
|
|
||||||
/** Creates an instance. */
|
/** Creates an instance. */
|
||||||
@ -122,8 +120,6 @@ import androidx.media3.exoplayer.ExoPlaybackException;
|
|||||||
// we keep the latest value of pendingOutputVideoSize
|
// we keep the latest value of pendingOutputVideoSize
|
||||||
videoSizeChanges.clear();
|
videoSizeChanges.clear();
|
||||||
}
|
}
|
||||||
// Do not clear reportedVideoSizeChange because we report a video size change at most once
|
|
||||||
// (b/292111083).
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the renderer is ready. */
|
/** Returns whether the renderer is ready. */
|
||||||
@ -230,9 +226,8 @@ import androidx.media3.exoplayer.ExoPlaybackException;
|
|||||||
long presentationTimeUs = checkStateNotNull(presentationTimestampsUs.remove());
|
long presentationTimeUs = checkStateNotNull(presentationTimestampsUs.remove());
|
||||||
|
|
||||||
boolean videoSizeUpdated = maybeUpdateVideoSize(presentationTimeUs);
|
boolean videoSizeUpdated = maybeUpdateVideoSize(presentationTimeUs);
|
||||||
if (videoSizeUpdated && !reportedVideoSizeChange) {
|
if (videoSizeUpdated) {
|
||||||
frameRenderer.onVideoSizeChanged(reportedVideoSize);
|
frameRenderer.onVideoSizeChanged(reportedVideoSize);
|
||||||
reportedVideoSizeChange = true;
|
|
||||||
}
|
}
|
||||||
long renderTimeNs =
|
long renderTimeNs =
|
||||||
shouldRenderImmediately
|
shouldRenderImmediately
|
||||||
|
Loading…
x
Reference in New Issue
Block a user