Regression fix of ExoPlayer.setVideoEffects()

7e65cce967 introduced a regression on ExoPlayer.setVideoEffects()
where there is flash on the screen after the first few frames are shown.

Before 7e65cce967, the first frames of the content are missed, until
MediaCodecVideoRenderer sends the onVideoSizeChanged() callback. The
first frame is processed but not shown, the onVideoSizeChanged() is
triggered and the renderer receives a video output resolution message as
a response from the UI.

7e65cce967 fixed the missed first frames by setting a surface on the
CompositingVideoSinkProvider before the provider is initialized, and as
as result:
- the first frames are rendered
- the MediaCodecVideoRenderer sends the the onVideoSizeChanged() after
  frames are shown
- the UI sends a video output resolution change
- the MediaCodecVideoRenderer updates the CompositingVideoSinkProvider
  which causes the flash.

The underlying problem is with onVideoSizeChanged() not being
triggered early enough, before the first frame is shown.

Because the flashing is a regression, this commit is reverting
7e65cce967 but keeps the test that was added as ignored, so that the
test is re-enabled as soon as we address the underlying issue.

PiperOrigin-RevId: 597814013
This commit is contained in:
christosts 2024-01-12 05:18:18 -08:00 committed by Copybara-Service
parent 78c419e566
commit 5056dfaa2b
3 changed files with 6 additions and 8 deletions

View File

@ -55,6 +55,7 @@ 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;
@ -102,6 +103,7 @@ 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);

View File

@ -286,13 +286,6 @@ public final class CompositingVideoSinkProvider
} }
videoSinkImpl = videoSinkImpl =
new VideoSinkImpl(context, /* compositingVideoSinkProvider= */ this, videoGraph); new VideoSinkImpl(context, /* compositingVideoSinkProvider= */ this, videoGraph);
if (currentSurfaceAndSize != null) {
Surface outputSurface = currentSurfaceAndSize.first;
Size outputSize = currentSurfaceAndSize.second;
checkStateNotNull(videoGraph)
.setOutputSurfaceInfo(
new SurfaceInfo(outputSurface, outputSize.getWidth(), outputSize.getHeight()));
}
} catch (VideoFrameProcessingException e) { } catch (VideoFrameProcessingException e) {
throw new VideoSink.VideoSinkException(e, sourceFormat); throw new VideoSink.VideoSinkException(e, sourceFormat);
} }

View File

@ -771,7 +771,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
break; break;
case MSG_SET_VIDEO_OUTPUT_RESOLUTION: case MSG_SET_VIDEO_OUTPUT_RESOLUTION:
Size outputResolution = (Size) checkNotNull(message); Size outputResolution = (Size) checkNotNull(message);
if (outputResolution.getWidth() != 0 // 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.
if (videoSinkProvider.isInitialized()
&& outputResolution.getWidth() != 0
&& outputResolution.getHeight() != 0 && outputResolution.getHeight() != 0
&& displaySurface != null) { && displaySurface != null) {
videoSinkProvider.setOutputSurfaceInfo(displaySurface, outputResolution); videoSinkProvider.setOutputSurfaceInfo(displaySurface, outputResolution);