VideoFrameReleaseControl: merge onEnabled and onProcessedStreamChange

This is a step towards removing the assumption that there is only one
sequence and therefore one renderer feeding data to DefaultVideoSink and
VideoFrameReleaseControl.

This is a no-op refactoring.

PiperOrigin-RevId: 734044100
This commit is contained in:
kimvde 2025-03-06 01:46:38 -08:00 committed by Copybara-Service
parent f996a5e3e4
commit 7e6089d3aa
6 changed files with 89 additions and 45 deletions

View File

@ -17,6 +17,8 @@ package androidx.media3.exoplayer.video;
import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Assertions.checkStateNotNull;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_IMMEDIATELY;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_WHEN_STARTED;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.view.Surface; import android.view.Surface;
@ -83,7 +85,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public void onRendererEnabled(boolean mayRenderStartOfStream) { public void onRendererEnabled(boolean mayRenderStartOfStream) {
videoFrameReleaseControl.onEnabled(mayRenderStartOfStream); int firstFrameReleaseInstruction =
mayRenderStartOfStream ? RELEASE_FIRST_FRAME_IMMEDIATELY : RELEASE_FIRST_FRAME_WHEN_STARTED;
videoFrameReleaseControl.onStreamChanged(firstFrameReleaseInstruction);
} }
@Override @Override

View File

@ -22,6 +22,9 @@ import static androidx.media3.common.util.Assertions.checkStateNotNull;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED; import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED; import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO; import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_IMMEDIATELY;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_WHEN_STARTED;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
@ -911,7 +914,11 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
} }
} else { } else {
videoFrameReleaseControl.setClock(getClock()); videoFrameReleaseControl.setClock(getClock());
videoFrameReleaseControl.onEnabled(mayRenderStartOfStream); int firstFrameReleaseInstruction =
mayRenderStartOfStream
? RELEASE_FIRST_FRAME_IMMEDIATELY
: RELEASE_FIRST_FRAME_WHEN_STARTED;
videoFrameReleaseControl.onStreamChanged(firstFrameReleaseInstruction);
} }
} }
@ -1837,7 +1844,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
videoSink.setStreamTimestampInfo( videoSink.setStreamTimestampInfo(
getOutputStreamStartPositionUs(), getBufferTimestampAdjustmentUs()); getOutputStreamStartPositionUs(), getBufferTimestampAdjustmentUs());
} else { } else {
videoFrameReleaseControl.onProcessedStreamChange(); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED);
} }
pendingVideoSinkInputStreamChange = true; pendingVideoSinkInputStreamChange = true;
maybeSetupTunnelingForFirstFrame(); maybeSetupTunnelingForFirstFrame();

View File

@ -41,6 +41,35 @@ import java.lang.annotation.Target;
@UnstableApi @UnstableApi
public final class VideoFrameReleaseControl { public final class VideoFrameReleaseControl {
/**
* The instruction provided to {@link #onStreamChanged(int)} for releasing the first frame.
*
* <p>One of {@link #RELEASE_FIRST_FRAME_IMMEDIATELY}, {@link #RELEASE_FIRST_FRAME_WHEN_STARTED}
* or {@link #RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@UnstableApi
@IntDef({
RELEASE_FIRST_FRAME_IMMEDIATELY,
RELEASE_FIRST_FRAME_WHEN_STARTED,
RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED
})
public @interface FirstFrameReleaseInstruction {}
/** Instructs to release the first frame as soon as possible. */
public static final int RELEASE_FIRST_FRAME_IMMEDIATELY = 0;
/** Instructs to release the first frame when rendering starts. */
public static final int RELEASE_FIRST_FRAME_WHEN_STARTED = 1;
/**
* Instructs to release the first frame when the playback position reaches the stream start
* position.
*/
public static final int RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED = 2;
/** /**
* The frame release action returned by {@link #getFrameReleaseAction(long, long, long, long, * The frame release action returned by {@link #getFrameReleaseAction(long, long, long, long,
* boolean, FrameReleaseInfo)}. * boolean, FrameReleaseInfo)}.
@ -206,12 +235,25 @@ public final class VideoFrameReleaseControl {
clock = Clock.DEFAULT; clock = Clock.DEFAULT;
} }
/** Called when the renderer is enabled. */ /**
public void onEnabled(boolean releaseFirstFrameBeforeStarted) { * Called when the stream changes.
firstFrameState = *
releaseFirstFrameBeforeStarted * <p>Must also be called for the first stream.
? C.FIRST_FRAME_NOT_RENDERED */
: C.FIRST_FRAME_NOT_RENDERED_ONLY_ALLOWED_IF_STARTED; public void onStreamChanged(@FirstFrameReleaseInstruction int firstFrameReleaseInstruction) {
switch (firstFrameReleaseInstruction) {
case RELEASE_FIRST_FRAME_IMMEDIATELY:
firstFrameState = C.FIRST_FRAME_NOT_RENDERED;
break;
case RELEASE_FIRST_FRAME_WHEN_STARTED:
firstFrameState = C.FIRST_FRAME_NOT_RENDERED_ONLY_ALLOWED_IF_STARTED;
break;
case RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED:
lowerFirstFrameState(C.FIRST_FRAME_NOT_RENDERED_AFTER_STREAM_CHANGE);
break;
default:
throw new IllegalStateException();
}
} }
/** Called when the renderer is started. */ /** Called when the renderer is started. */
@ -228,11 +270,6 @@ public final class VideoFrameReleaseControl {
frameReleaseHelper.onStopped(); frameReleaseHelper.onStopped();
} }
/** Called when the renderer processed a stream change. */
public void onProcessedStreamChange() {
lowerFirstFrameState(C.FIRST_FRAME_NOT_RENDERED_AFTER_STREAM_CHANGE);
}
/** Called when the display surface changed. */ /** Called when the display surface changed. */
public void setOutputSurface(@Nullable Surface outputSurface) { public void setOutputSurface(@Nullable Surface outputSurface) {
frameReleaseHelper.onSurfaceChanged(outputSurface); frameReleaseHelper.onSurfaceChanged(outputSurface);

View File

@ -17,6 +17,7 @@ package androidx.media3.exoplayer.video;
import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.C; import androidx.media3.common.C;
@ -138,7 +139,8 @@ import androidx.media3.exoplayer.ExoPlaybackException;
long presentationTimeUs = presentationTimestampsUs.element(); long presentationTimeUs = presentationTimestampsUs.element();
// Check whether this buffer comes with a new stream start position. // Check whether this buffer comes with a new stream start position.
if (maybeUpdateOutputStreamStartPosition(presentationTimeUs)) { if (maybeUpdateOutputStreamStartPosition(presentationTimeUs)) {
videoFrameReleaseControl.onProcessedStreamChange(); videoFrameReleaseControl.onStreamChanged(
RELEASE_FIRST_FRAME_WHEN_PREVIOUS_STREAM_PROCESSED);
} }
@VideoFrameReleaseControl.FrameReleaseAction @VideoFrameReleaseControl.FrameReleaseAction
int frameReleaseAction = int frameReleaseAction =

View File

@ -15,6 +15,8 @@
*/ */
package androidx.media3.exoplayer.video; package androidx.media3.exoplayer.video;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_IMMEDIATELY;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_WHEN_STARTED;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import androidx.media3.exoplayer.ExoPlaybackException; import androidx.media3.exoplayer.ExoPlaybackException;
@ -98,21 +100,12 @@ public class VideoFrameReleaseControlTest {
} }
@Test @Test
public void onFrameReleasedIsFirstFrame_resetsAfterOnEnabled() { public void onFrameReleasedIsFirstFrame_resetsAfterOnStreamChanged() {
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isTrue(); videoFrameReleaseControl.onFrameReleasedIsFirstFrame();
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isFalse();
videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isTrue();
}
@Test
public void onFrameReleasedIsFirstFrame_resetsAfterOnProcessedStreamChange() {
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isTrue();
videoFrameReleaseControl.onProcessedStreamChange();
assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isTrue(); assertThat(videoFrameReleaseControl.onFrameReleasedIsFirstFrame()).isTrue();
} }
@ -144,7 +137,7 @@ public class VideoFrameReleaseControlTest {
VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo = VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo =
new VideoFrameReleaseControl.FrameReleaseInfo(); new VideoFrameReleaseControl.FrameReleaseInfo();
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
assertThat( assertThat(
videoFrameReleaseControl.getFrameReleaseAction( videoFrameReleaseControl.getFrameReleaseAction(
@ -163,7 +156,7 @@ public class VideoFrameReleaseControlTest {
VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo = VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo =
new VideoFrameReleaseControl.FrameReleaseInfo(); new VideoFrameReleaseControl.FrameReleaseInfo();
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ false); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_WHEN_STARTED);
assertThat( assertThat(
videoFrameReleaseControl.getFrameReleaseAction( videoFrameReleaseControl.getFrameReleaseAction(
@ -185,7 +178,7 @@ public class VideoFrameReleaseControlTest {
FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false); FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false);
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ false); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_WHEN_STARTED);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
@ -208,7 +201,7 @@ public class VideoFrameReleaseControlTest {
FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false); FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false);
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
// First frame released. // First frame released.
assertThat( assertThat(
@ -242,7 +235,7 @@ public class VideoFrameReleaseControlTest {
FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false); FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false);
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
// First frame released. // First frame released.
@ -277,7 +270,7 @@ public class VideoFrameReleaseControlTest {
FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false); FakeClock clock = new FakeClock(/* isAutoAdvancing= */ false);
VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl(); VideoFrameReleaseControl videoFrameReleaseControl = createVideoFrameReleaseControl();
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
@ -320,7 +313,7 @@ public class VideoFrameReleaseControlTest {
/* shouldIgnoreFrame= */ false), /* shouldIgnoreFrame= */ false),
/* allowedJoiningTimeMs= */ 0); /* allowedJoiningTimeMs= */ 0);
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
@ -365,7 +358,7 @@ public class VideoFrameReleaseControlTest {
/* shouldIgnoreFrame= */ false), /* shouldIgnoreFrame= */ false),
/* allowedJoiningTimeMs= */ 1234); /* allowedJoiningTimeMs= */ 1234);
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
// Start joining. // Start joining.
@ -409,7 +402,7 @@ public class VideoFrameReleaseControlTest {
/* shouldIgnoreFrame= */ false), /* shouldIgnoreFrame= */ false),
/* allowedJoiningTimeMs= */ 1234); /* allowedJoiningTimeMs= */ 1234);
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
// Start joining. // Start joining.
@ -452,7 +445,7 @@ public class VideoFrameReleaseControlTest {
/* shouldIgnoreFrame= */ true), /* shouldIgnoreFrame= */ true),
/* allowedJoiningTimeMs= */ 0); /* allowedJoiningTimeMs= */ 0);
videoFrameReleaseControl.setClock(clock); videoFrameReleaseControl.setClock(clock);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();

View File

@ -15,6 +15,7 @@
*/ */
package androidx.media3.exoplayer.video; package androidx.media3.exoplayer.video;
import static androidx.media3.exoplayer.video.VideoFrameReleaseControl.RELEASE_FIRST_FRAME_IMMEDIATELY;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@ -44,7 +45,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0); videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0);
@ -72,7 +73,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
@ -117,7 +118,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
@ -164,7 +165,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
@ -202,7 +203,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameReleaseControl.onStarted(); videoFrameReleaseControl.onStarted();
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
@ -247,7 +248,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0); videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0);
@ -265,7 +266,7 @@ public class VideoFrameRenderControlTest {
VideoFrameRenderControl videoFrameRenderControl = VideoFrameRenderControl videoFrameRenderControl =
new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl); new VideoFrameRenderControl(frameRenderer, videoFrameReleaseControl);
videoFrameReleaseControl.onEnabled(/* releaseFirstFrameBeforeStarted= */ true); videoFrameReleaseControl.onStreamChanged(RELEASE_FIRST_FRAME_IMMEDIATELY);
videoFrameRenderControl.onVideoSizeChanged( videoFrameRenderControl.onVideoSizeChanged(
/* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT); /* width= */ VIDEO_WIDTH, /* height= */ VIDEO_HEIGHT);
videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0); videoFrameRenderControl.onFrameAvailableForRendering(/* presentationTimeUs= */ 0);