# SurfaceHolderFrameWriter

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

*** ** * ** ***


```
@ExperimentalApi
public final class SurfaceHolderFrameWriter implements FrameWriter, SurfaceHolder.Callback
```

<br />

*** ** * ** ***

A `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter` that outputs frames to a `https://developer.android.com/reference/android/view/SurfaceHolder.html`.

## Summary

| ### Nested types |
|---|
| `public interface https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener` A listener for `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter` events. |

| ### Public methods |
|---|---|
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#close()()` Blocks until all resources are released. |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#configure(androidx.media3.common.Format,long)(https://developer.android.com/reference/androidx/media3/common/Format format, @https://developer.android.com/reference/androidx/media3/common/video/Frame.Usage long usage)` Format and usage support can be Info#isSupported(Format, long) checked on the before configuring. |
| `static https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter` | `@https://developer.android.com/reference/androidx/annotation/RequiresApi(value = 33) https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#create(android.view.SurfaceHolder,java.util.concurrent.Executor,androidx.media3.common.video.SurfaceHolderFrameWriter.Listener,java.util.concurrent.Executor)( @https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder, https://developer.android.com/reference/java/util/concurrent/Executor.html surfaceHolderExecutor, https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener listener, https://developer.android.com/reference/java/util/concurrent/Executor.html listenerExecutor )` Creates a new instance that returns `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferFrame`s that are directly dequeued from an `https://developer.android.com/reference/android/media/ImageWriter.html` linked to the output `https://developer.android.com/reference/android/view/SurfaceHolder.html#getSurface()`. |
| `static https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#create(android.view.SurfaceHolder,java.util.concurrent.Executor,androidx.media3.common.video.SurfaceHolderFrameWriter.Listener,java.util.concurrent.Executor,androidx.media3.common.video.HardwareBufferNativeHelpers)( @https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder, https://developer.android.com/reference/java/util/concurrent/Executor.html surfaceHolderExecutor, https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener listener, https://developer.android.com/reference/java/util/concurrent/Executor.html listenerExecutor, https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferNativeHelpers hardwareBufferNativeHelpers )` Creates a new instance that returns video frames that will be written to the output `https://developer.android.com/reference/android/view/SurfaceHolder.html#getSurface()`. |
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/androidx/media3/common/video/AsyncFrame` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#dequeueInputFrame(java.util.concurrent.Executor,java.lang.Runnable)(https://developer.android.com/reference/java/util/concurrent/Executor.html wakeupExecutor, https://developer.android.com/reference/java/lang/Runnable.html wakeupListener)` Dequeues an `https://developer.android.com/reference/androidx/media3/common/video/AsyncFrame` storing a `https://developer.android.com/reference/androidx/media3/common/video/Frame` of the `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter#configure(androidx.media3.common.Format,long)` format and usage, and a `https://developer.android.com/reference/androidx/media3/common/video/SyncFenceWrapper` that must be waited on before filling the frame. |
| `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter.Info` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#getInfo()()` Returns the `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter.Info` for this FrameWriter. |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#queueInputFrame(androidx.media3.common.video.Frame,androidx.media3.common.video.SyncFenceWrapper)( https://developer.android.com/reference/androidx/media3/common/video/Frame frame, @https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/androidx/media3/common/video/SyncFenceWrapper writeCompleteFence )` Queues a filled frame for further processing. |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#setSurfaceHolder(android.view.SurfaceHolder)(@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder)` Sets the `https://developer.android.com/reference/android/view/SurfaceHolder.html` to which frames will be written. |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#signalEndOfStream()()` Notifies this `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter` that the current stream has ended. |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#surfaceChanged(android.view.SurfaceHolder,int,int,int)(https://developer.android.com/reference/android/view/SurfaceHolder.html holder, int format, int width, int height)` |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#surfaceCreated(android.view.SurfaceHolder)(https://developer.android.com/reference/android/view/SurfaceHolder.html holder)` |
| `void` | `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#surfaceDestroyed(android.view.SurfaceHolder)(https://developer.android.com/reference/android/view/SurfaceHolder.html holder)` |

### Inherited methods

From [java.lang.AutoCloseable](https://developer.android.com/reference/java/lang/AutoCloseable.html) `abstract void` `https://developer.android.com/reference/java/lang/AutoCloseable.html#close()()`

## Public methods

### close

```
public void close()
```

Blocks until all resources are released.

### configure

```
public void configure(Format format, @Frame.Usage long usage)
```

Format and usage support can be Info#isSupported(Format, long) checked on the before configuring.

Must be called before #dequeueInputFrame.

If `https://developer.android.com/reference/androidx/media3/common/Format#pixelFormat()` is unset (i.e. `https://developer.android.com/reference/androidx/media3/common/Format#NO_VALUE()`), it defaults to `https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12` below API 28, `https://developer.android.com/reference/android/hardware/HardwareBuffer.html#RGBA_1010102` for HDR on API 28+, or `https://developer.android.com/reference/android/hardware/HardwareBuffer.html#RGBA_8888` for SDR on API 28+.

### create

```
@RequiresApi(value = 33)
public static SurfaceHolderFrameWriter create(
    @Nullable SurfaceHolder surfaceHolder,
    Executor surfaceHolderExecutor,
    SurfaceHolderFrameWriter.Listener listener,
    Executor listenerExecutor
)
```

Creates a new instance that returns `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferFrame`s that are directly dequeued from an `https://developer.android.com/reference/android/media/ImageWriter.html` linked to the output `https://developer.android.com/reference/android/view/SurfaceHolder.html#getSurface()`.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder` | The `https://developer.android.com/reference/android/view/SurfaceHolder.html` to which frames will be written, or `null` if not yet available. |
| `https://developer.android.com/reference/java/util/concurrent/Executor.html surfaceHolderExecutor` | The `https://developer.android.com/reference/java/util/concurrent/Executor.html` on which the surface holder methods will be called. |
| `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener listener` | The `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener`. |
| `https://developer.android.com/reference/java/util/concurrent/Executor.html listenerExecutor` | The `https://developer.android.com/reference/java/util/concurrent/Executor.html` on which the listener methods will be called. |

### create

```
public static SurfaceHolderFrameWriter create(
    @Nullable SurfaceHolder surfaceHolder,
    Executor surfaceHolderExecutor,
    SurfaceHolderFrameWriter.Listener listener,
    Executor listenerExecutor,
    HardwareBufferNativeHelpers hardwareBufferNativeHelpers
)
```

Creates a new instance that returns video frames that will be written to the output `https://developer.android.com/reference/android/view/SurfaceHolder.html#getSurface()`.

Below API 28, `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#dequeueInputFrame(java.util.concurrent.Executor,java.lang.Runnable)` returns an `https://developer.android.com/reference/androidx/media3/common/video/ImagePlanesFrame` wrapping an `https://developer.android.com/reference/android/media/ImageWriter.html` buffer without intermediate copying, and `
hardwareBufferNativeHelpers` is ignored.

On API 28 to 32 (inclusive), `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#dequeueInputFrame(java.util.concurrent.Executor,java.lang.Runnable)` returns a pre-allocated `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferFrame`. It is copied to the `https://developer.android.com/reference/android/media/ImageWriter.html` (via `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferNativeHelpers`) after the caller fills and `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#queueInputFrame(androidx.media3.common.video.Frame,androidx.media3.common.video.SyncFenceWrapper)` it.

On API 33 and above, `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter#dequeueInputFrame(java.util.concurrent.Executor,java.lang.Runnable)` returns a `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferFrame` directly dequeued from the `https://developer.android.com/reference/android/media/ImageWriter.html` without intermediate copying, and `
hardwareBufferNativeHelpers` is ignored.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder` | The `https://developer.android.com/reference/android/view/SurfaceHolder.html` to which frames will be written, or `null` if not yet available. |
| `https://developer.android.com/reference/java/util/concurrent/Executor.html surfaceHolderExecutor` | The `https://developer.android.com/reference/java/util/concurrent/Executor.html` on which the surface holder methods will be called. |
| `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener listener` | The `https://developer.android.com/reference/androidx/media3/common/video/SurfaceHolderFrameWriter.Listener`. |
| `https://developer.android.com/reference/java/util/concurrent/Executor.html listenerExecutor` | The `https://developer.android.com/reference/java/util/concurrent/Executor.html` on which the listener methods will be called. |
| `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferNativeHelpers hardwareBufferNativeHelpers` | The `https://developer.android.com/reference/androidx/media3/common/video/HardwareBufferNativeHelpers` used to copy intermediate `https://developer.android.com/reference/android/hardware/HardwareBuffer.html`s to `https://developer.android.com/reference/android/hardware/HardwareBuffer.html`s dequeued from `https://developer.android.com/reference/android/media/ImageWriter.html` on API 28 to 32; ignored on other API levels. |

### dequeueInputFrame

```
public @Nullable AsyncFrame dequeueInputFrame(Executor wakeupExecutor, Runnable wakeupListener)
```

Dequeues an `https://developer.android.com/reference/androidx/media3/common/video/AsyncFrame` storing a `https://developer.android.com/reference/androidx/media3/common/video/Frame` of the `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter#configure(androidx.media3.common.Format,long)` format and usage, and a `https://developer.android.com/reference/androidx/media3/common/video/SyncFenceWrapper` that must be waited on before filling the frame.

The returned frame must be filled and `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter#queueInputFrame(androidx.media3.common.video.Frame,androidx.media3.common.video.SyncFenceWrapper)` back for processing.

If the `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter` is at capacity, this method returns null and will notify the listener when capacity is available, and it can be called again.

Only the most recent `wakeupListener` will be notified when capacity is available.

| Parameters |
|---|---|
| `https://developer.android.com/reference/java/util/concurrent/Executor.html wakeupExecutor` | The `https://developer.android.com/reference/java/util/concurrent/Executor.html` on which the `wakeupListener` is invoked. |
| `https://developer.android.com/reference/java/lang/Runnable.html wakeupListener` | A `https://developer.android.com/reference/java/lang/Runnable.html` to be invoked when capacity becomes available. |

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/androidx/media3/common/video/AsyncFrame` | The dequeued frame, or null if the writer is at capacity. |

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalStateException.html` | if `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter#configure(androidx.media3.common.Format,long)` has not been called. |

### getInfo

```
public FrameWriter.Info getInfo()
```

Returns the `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter.Info` for this FrameWriter.

### queueInputFrame

```
public void queueInputFrame(
    Frame frame,
    @Nullable SyncFenceWrapper writeCompleteFence
)
```

Queues a filled frame for further processing.

The queued frame must have been previously `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter#dequeueInputFrame(java.util.concurrent.Executor,java.lang.Runnable)` from this writer.

| Parameters |
|---|---|
| `https://developer.android.com/reference/androidx/media3/common/video/Frame frame` | The filled frame to queue. |
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/androidx/media3/common/video/SyncFenceWrapper writeCompleteFence` | A `https://developer.android.com/reference/androidx/media3/common/video/SyncFenceWrapper` that will signal when the caller has finished writing to the frame, or `null` if the write was synchronous. |

### setSurfaceHolder

```
public void setSurfaceHolder(@Nullable SurfaceHolder surfaceHolder)
```

Sets the `https://developer.android.com/reference/android/view/SurfaceHolder.html` to which frames will be written.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/android/view/SurfaceHolder.html surfaceHolder` | The `https://developer.android.com/reference/android/view/SurfaceHolder.html`, or `null` to clear the output. |

### signalEndOfStream

```
public void signalEndOfStream()
```

Notifies this `https://developer.android.com/reference/androidx/media3/common/video/FrameWriter` that the current stream has ended.

More frames may be queued after calling this method, if the current stream changes.

### surfaceChanged

```
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
```

### surfaceCreated

```
public void surfaceCreated(SurfaceHolder holder)
```

### surfaceDestroyed

```
public void surfaceDestroyed(SurfaceHolder holder)
```