# `ExCubecl.Video`
[🔗](https://github.com/ohhi-vn/ex_cubecl/blob/v0.4.0/lib/ex_cubecl/video.ex#L1)

Video-specific GPU operations: overlay, mix, scale, crop, convert.

All operations run on GPU-resident frame buffers and return new frame buffers.

## Examples

    result = ExCubecl.Video.overlay(base_frame, overlay_frame, x: 100, y: 50, alpha: 0.8)
    result = ExCubecl.Video.mix(frame_a, frame_b, mode: :dissolve, ratio: 0.5)
    result = ExCubecl.Video.scale(frame, width: 1280, height: 720)
    rgb = ExCubecl.Video.convert(frame, :yuv420p, :rgb24)
    cropped = ExCubecl.Video.crop(frame, x: 0, y: 0, width: 640, height: 360)

# `blend_mode`

```elixir
@type blend_mode() :: :dissolve | :add | :multiply
```

# `frame`

```elixir
@type frame() :: ExCubecl.VideoFrame.t()
```

# `pixel_format`

```elixir
@type pixel_format() :: :yuv420p | :rgb24 | :rgba | :nv12
```

# `convert`

```elixir
@spec convert(frame(), pixel_format(), pixel_format()) ::
  {:ok, frame()} | {:error, term()}
```

Converts a video frame between pixel formats on the GPU.

## Examples

    rgb = ExCubecl.Video.convert(frame, :yuv420p, :rgb24)

# `crop`

```elixir
@spec crop(
  frame(),
  keyword()
) :: {:ok, frame()} | {:error, term()}
```

Crops a video frame to the specified rectangle.

## Options

  * `:x` — left edge (default 0)
  * `:y` — top edge (default 0)
  * `:width` — crop width
  * `:height` — crop height

# `mix`

```elixir
@spec mix(frame(), frame(), keyword()) :: {:ok, frame()} | {:error, term()}
```

Blends two video frames using the specified blend mode.

## Options

  * `:mode` — blend mode: `:dissolve` (default), `:add`, or `:multiply`
  * `:ratio` — blend ratio 0.0 (all A) to 1.0 (all B), default 0.5

# `overlay`

```elixir
@spec overlay(frame(), frame(), keyword()) :: {:ok, frame()} | {:error, term()}
```

Alpha-composites `overlay` onto `base` at position (`x`, `y`) with opacity `alpha`.

Uses Porter-Duff Over compositing on the GPU.

## Options

  * `:x` — horizontal offset (default 0)
  * `:y` — vertical offset (default 0)
  * `:alpha` — opacity 0.0–1.0 (default 1.0)

# `scale`

```elixir
@spec scale(
  frame(),
  keyword()
) :: {:ok, frame()} | {:error, term()}
```

Scales a video frame to the specified dimensions using GPU-accelerated resampling.

## Options

  * `:width` — target width in pixels
  * `:height` — target height in pixels

# `snapshot`

```elixir
@spec snapshot(frame(), String.t()) :: :ok | {:error, term()}
```

Saves a snapshot of the frame to a PNG file.

Note: This triggers a GPU→CPU readback, so it should be used sparingly.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
