# VideoFrameReleaseControl

Artifact: [androidx.media3:media3-exoplayer](https://developer.android.com/jetpack/androidx/releases/media3) [View Source](https://cs.android.com/search?q=file:androidx/media3/exoplayer/video/VideoFrameReleaseControl.java+class:androidx.media3.exoplayer.video.VideoFrameReleaseControl)

*** ** * ** ***


```
@UnstableApi
public final class VideoFrameReleaseControl
```

<br />

*** ** * ** ***

Controls the releasing of video frames.

## Summary

| ### Nested types |
|---|
| `@https://developer.android.com/reference/java/lang/annotation/Documented.html @https://developer.android.com/reference/java/lang/annotation/Retention.html(value = https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html#SOURCE) @https://developer.android.com/reference/java/lang/annotation/Target.html(value = https://developer.android.com/reference/java/lang/annotation/ElementType.html#TYPE_USE) @https://developer.android.com/reference/androidx/media3/common/util/UnstableApi @https://developer.android.com/reference/androidx/annotation/IntDef(value = ) public annotation https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` The frame release action returned by `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#getFrameReleaseAction(long,long,long,long,boolean,boolean,long,long,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameReleaseInfo)` or `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#probeFrameReleaseAction(long,long,long,long,long,long,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameReleaseInfo)`. |
| `public class https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo` Per `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` metadata. |
| `public interface https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator` Decides whether a frame should be forced to be released, or dropped. |

| ### Constants |
|---|---|
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_DROP() = 2` Signals a frame should be dropped. |
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_IGNORE() = 4` Signals that a frame should be ignored. |
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_IMMEDIATELY() = 0` Signals a frame should be released immediately. |
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_SCHEDULED() = 1` Signals a frame should be scheduled for release. |
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_SKIP() = 3` Signals that a frame should be skipped. |
| `static final int` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_TRY_AGAIN_LATER() = 5` Signals that a frame should not be released and the caller should try again later. |

| ### Public constructors |
|---|
| `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#VideoFrameReleaseControl(android.content.Context,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameTimingEvaluator,long,boolean)( https://developer.android.com/reference/android/content/Context.html applicationContext, https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator frameTimingEvaluator, long allowedJoiningTimeMs, boolean skipBuffersWithIdenticalReleaseTime )` Creates an instance. |

| ### Public methods |
|---|---|
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#allowReleaseFirstFrameBeforeStarted()()` Allows the frame control to indicate the first frame can be released before this instance is started. |
| `int` | `@https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#getFrameReleaseAction(long,long,long,long,boolean,boolean,long,long,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameReleaseInfo)( long presentationTimeUs, long positionUs, long elapsedRealtimeUs, long outputStreamStartPositionUs, boolean isDecodeOnlyFrame, boolean isLastFrame, long frameDurationNs, long frameIndex, https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo )` Returns a `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` for a video frame which instructs the caller what to do with the frame. |
| `boolean` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#isJoining()()` Returns whether the release control is currently joining. |
| `boolean` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#isReady(boolean)(boolean otherwiseReady)` Whether the release control is ready to start playback. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#join(boolean)(boolean renderNextFrameImmediately)` Joins the release control to a new stream. |
| `boolean` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#onFrameReleasedIsFirstFrame()()` Called when a frame has been released. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#onStarted()()` Called when rendering starts. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#onStopped()()` Called when rendering stops. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#onStreamChanged(int)( @https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoSink.FirstFrameReleaseInstruction int firstFrameReleaseInstruction )` Called when the stream changes. |
| `int` | `@https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#probeFrameReleaseAction(long,long,long,long,long,long,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameReleaseInfo)( long presentationTimeUs, long positionUs, long elapsedRealtimeUs, long outputStreamStartPositionUs, long frameDurationNs, long frameIndex, https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo )` Probes the expected `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` and populates `frameReleaseInfo` for a pending video frame without mutating release state or invoking `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator#shouldIgnoreFrame(long,long,long,boolean,boolean)`. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#reset()()` Resets the release control. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setChangeFrameRateStrategy(int)( @https://developer.android.com/reference/androidx/media3/common/C.VideoChangeFrameRateStrategy int changeFrameRateStrategy )` Changes the `https://developer.android.com/reference/androidx/media3/common/C.VideoChangeFrameRateStrategy` used when calling `https://developer.android.com/reference/android/view/Surface.html#setFrameRate(float, int)`. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setClock(androidx.media3.common.util.Clock)(https://developer.android.com/reference/androidx/media3/common/util/Clock clock)` Sets the clock that will be used. |
| `void` | `@https://developer.android.com/reference/androidx/media3/common/util/ExperimentalApi https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setEarlySchedulingThresholdUs(long)(long earlySchedulingThresholdUs)` Sets the threshold for how early a frame may be scheduled for release on the surface. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setOutputSurface(android.view.Surface)(@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/Surface.html outputSurface)` Called when the display surface changed. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setPlaybackSpeed(float)(@https://developer.android.com/reference/androidx/annotation/FloatRange(from = 0, fromInclusive = false) float speed)` Sets the playback speed. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setRequiresOutputSurface(boolean)(boolean requiresOutputSurface)` Sets whether an output surface is required for the release control to release frames. |
| `void` | `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setSurfaceMediaFrameRate(float)(float surfaceMediaFrameRate)` Sets the surface media frame rate. |
| `void` | `@https://developer.android.com/reference/androidx/annotation/VisibleForTesting https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#setVsyncData(long,long)(long vsyncSampleTimeNs, long vsyncDurationNs)` Sets the vsync timing data. |

## Constants

### FRAME_RELEASE_DROP

```
public static final int FRAME_RELEASE_DROP = 2
```

Signals a frame should be dropped.

### FRAME_RELEASE_IGNORE

```
public static final int FRAME_RELEASE_IGNORE = 4
```

Signals that a frame should be ignored.

### FRAME_RELEASE_IMMEDIATELY

```
public static final int FRAME_RELEASE_IMMEDIATELY = 0
```

Signals a frame should be released immediately.

### FRAME_RELEASE_SCHEDULED

```
public static final int FRAME_RELEASE_SCHEDULED = 1
```

Signals a frame should be scheduled for release. The release timestamp will be returned by `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo#getReleaseTimeNs()`.

### FRAME_RELEASE_SKIP

```
public static final int FRAME_RELEASE_SKIP = 3
```

Signals that a frame should be skipped.

### FRAME_RELEASE_TRY_AGAIN_LATER

```
public static final int FRAME_RELEASE_TRY_AGAIN_LATER = 5
```

Signals that a frame should not be released and the caller should try again later.

## Public constructors

### VideoFrameReleaseControl

```
public VideoFrameReleaseControl(
    Context applicationContext,
    VideoFrameReleaseControl.FrameTimingEvaluator frameTimingEvaluator,
    long allowedJoiningTimeMs,
    boolean skipBuffersWithIdenticalReleaseTime
)
```

Creates an instance.

| Parameters |
|---|---|
| `https://developer.android.com/reference/android/content/Context.html applicationContext` | The application context. |
| `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator frameTimingEvaluator` | The `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator` that will assist in `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#getFrameReleaseAction(long,long,long,long,boolean,boolean,long,long,androidx.media3.exoplayer.video.VideoFrameReleaseControl.FrameReleaseInfo)`. |
| `long allowedJoiningTimeMs` | The maximum duration in milliseconds for which the caller can attempt to seamlessly join an ongoing playback. |
| `boolean skipBuffersWithIdenticalReleaseTime` | Whether to skip buffers that have an identical release time as the previous released buffer. |

## Public methods

### allowReleaseFirstFrameBeforeStarted

```
public void allowReleaseFirstFrameBeforeStarted()
```

Allows the frame control to indicate the first frame can be released before this instance is started.

### getFrameReleaseAction

```
@VideoFrameReleaseControl.FrameReleaseAction
public int getFrameReleaseAction(
    long presentationTimeUs,
    long positionUs,
    long elapsedRealtimeUs,
    long outputStreamStartPositionUs,
    boolean isDecodeOnlyFrame,
    boolean isLastFrame,
    long frameDurationNs,
    long frameIndex,
    VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo
)
```

Returns a `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` for a video frame which instructs the caller what to do with the frame.

| Parameters |
|---|---|
| `long presentationTimeUs` | The presentation time of the video frame, in microseconds. |
| `long positionUs` | The current playback position, in microseconds. |
| `long elapsedRealtimeUs` | `https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtime()` in microseconds, taken approximately at the time the playback position was `positionUs`. |
| `long outputStreamStartPositionUs` | The stream's start position, in microseconds. |
| `boolean isDecodeOnlyFrame` | Whether the frame is decode-only because its presentation time is before the intended start time. |
| `boolean isLastFrame` | Whether the frame is known to contain the last frame of the current stream. |
| `long frameDurationNs` | The estimated fixed frame duration in nanoseconds, or `https://developer.android.com/reference/androidx/media3/common/C#TIME_UNSET()` if unknown. |
| `long frameIndex` | A monotonically increasing index for the frame, or `https://developer.android.com/reference/androidx/media3/common/C#INDEX_UNSET()` if unknown. |
| `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo` | A `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo` that will be filled with detailed data only if the method returns `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_IMMEDIATELY()` or `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#FRAME_RELEASE_SCHEDULED()`. |

| Returns |
|---|---|
| `int` | A `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` that should instruct the caller whether to release the frame or not. |

| Throws |
|---|---|
| `https://developer.android.com/reference/androidx/media3/exoplayer/ExoPlaybackException` |   |

### isJoining

```
public boolean isJoining()
```

Returns whether the release control is currently joining.

### isReady

```
public boolean isReady(boolean otherwiseReady)
```

Whether the release control is ready to start playback.

| Parameters |
|---|---|
| `boolean otherwiseReady` | Whether the caller is ready except for the release control. |

| Returns |
|---|---|
| `boolean` | Whether the release control is ready. |

### join

```
public void join(boolean renderNextFrameImmediately)
```

Joins the release control to a new stream.

The release control will pretend to be `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl#isReady(boolean)` for a short time even if the first frame hasn't been rendered yet to avoid interrupting an ongoing playback.

| Parameters |
|---|---|
| `boolean renderNextFrameImmediately` | Whether the next frame should be released as soon as possible or only at its preferred scheduled release time. |

### onFrameReleasedIsFirstFrame

```
public boolean onFrameReleasedIsFirstFrame()
```

Called when a frame has been released.

| Returns |
|---|---|
| `boolean` | Whether this is the first released frame. |

### onStarted

```
public void onStarted()
```

Called when rendering starts.

### onStopped

```
public void onStopped()
```

Called when rendering stops.

### onStreamChanged

```
public void onStreamChanged(
    @VideoSink.FirstFrameReleaseInstruction int firstFrameReleaseInstruction
)
```

Called when the stream changes.

Must also be called for the first stream.

### probeFrameReleaseAction

```
@VideoFrameReleaseControl.FrameReleaseAction
public int probeFrameReleaseAction(
    long presentationTimeUs,
    long positionUs,
    long elapsedRealtimeUs,
    long outputStreamStartPositionUs,
    long frameDurationNs,
    long frameIndex,
    VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo
)
```

Probes the expected `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` and populates `frameReleaseInfo` for a pending video frame without mutating release state or invoking `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameTimingEvaluator#shouldIgnoreFrame(long,long,long,boolean,boolean)`.

| Parameters |
|---|---|
| `long presentationTimeUs` | The presentation time of the video frame, in microseconds. |
| `long positionUs` | The current playback position, in microseconds. |
| `long elapsedRealtimeUs` | `https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtime()` in microseconds, taken approximately at the time the playback position was `positionUs`. |
| `long outputStreamStartPositionUs` | The stream's start position, in microseconds. |
| `long frameDurationNs` | The estimated fixed frame duration in nanoseconds, or `https://developer.android.com/reference/androidx/media3/common/C#TIME_UNSET()` if unknown. |
| `long frameIndex` | A monotonically increasing index for the frame, or `https://developer.android.com/reference/androidx/media3/common/C#INDEX_UNSET()` if unknown. |
| `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo frameReleaseInfo` | A `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseInfo` that will be filled with timing details. |

| Returns |
|---|---|
| `int` | The expected `https://developer.android.com/reference/androidx/media3/exoplayer/video/VideoFrameReleaseControl.FrameReleaseAction` for the frame. |

### reset

```
public void reset()
```

Resets the release control.

### setChangeFrameRateStrategy

```
public void setChangeFrameRateStrategy(
    @C.VideoChangeFrameRateStrategy int changeFrameRateStrategy
)
```

Changes the `https://developer.android.com/reference/androidx/media3/common/C.VideoChangeFrameRateStrategy` used when calling `https://developer.android.com/reference/android/view/Surface.html#setFrameRate(float, int)`.

The default value is `https://developer.android.com/reference/androidx/media3/common/C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_ONLY_IF_SEAMLESS()`.

### setClock

```
public void setClock(Clock clock)
```

Sets the clock that will be used.

### setEarlySchedulingThresholdUs

```
@ExperimentalApi
public void setEarlySchedulingThresholdUs(long earlySchedulingThresholdUs)
```

Sets the threshold for how early a frame may be scheduled for release on the surface.

Frames that are earlier than this threshold will be held and 'release' will be tried again later.

This value is in microseconds. The default value is `https://developer.android.com/reference/androidx/media3/exoplayer/video/MediaCodecVideoRenderer#DEFAULT_EARLY_SCHEDULING_THRESHOLD_US()`.

This method is experimental and will be renamed or removed in a future release.

| Parameters |
|---|---|
| `long earlySchedulingThresholdUs` | The maximum early time threshold in microseconds. |

### setOutputSurface

```
public void setOutputSurface(@Nullable Surface outputSurface)
```

Called when the display surface changed.

### setPlaybackSpeed

```
public void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed)
```

Sets the playback speed.

### setRequiresOutputSurface

```
public void setRequiresOutputSurface(boolean requiresOutputSurface)
```

Sets whether an output surface is required for the release control to release frames.

The default value is `true`.

### setSurfaceMediaFrameRate

```
public void setSurfaceMediaFrameRate(float surfaceMediaFrameRate)
```

Sets the surface media frame rate.

### setVsyncData

```
@VisibleForTesting
public void setVsyncData(long vsyncSampleTimeNs, long vsyncDurationNs)
```

Sets the vsync timing data.

| Parameters |
|---|---|
| `long vsyncSampleTimeNs` | The vsync sample time in nanoseconds. |
| `long vsyncDurationNs` | The vsync duration in nanoseconds. |