# `Membrane.RawVideo`
[🔗](https://github.com/membraneframework/membrane_raw_video_format/blob/v0.4.5/lib/membrane_raw_video.ex#L1)

This module provides a struct (`t:Membrane.RawVideo.t/0`) describing raw video frames.

# `aligned`

```elixir
@type aligned() :: boolean()
```

Determines, whether buffers are aligned i.e. each buffer contains one frame.

# `framerate`

```elixir
@type framerate() :: {frames :: non_neg_integer(), seconds :: pos_integer()} | nil
```

Number of frames per second. To avoid using floating point numbers,
it is described by 2 integers number of frames per timeframe in seconds.

For example, NTSC's framerate of ~29.97 fps is represented by `{30_000, 1001}`.
If the information about the framerate is not present in the stream, `nil` value
should be used and the buffers described by this stream format must have non-nil timestamps.

# `height`

```elixir
@type height() :: pos_integer()
```

Height of single frame in pixels.

# `pixel_format`

```elixir
@type pixel_format() ::
  :I420
  | :I422
  | :I444
  | :RGB
  | :BGR
  | :BGRA
  | :RGBA
  | :NV12
  | :NV21
  | :YV12
  | :AYUV
  | :YUY2
  | :I420_10LE
  | :I420_10BE
  | :I422_10LE
  | :I422_10BE
  | :I444_10LE
  | :I444_10BE
```

Format used to encode the color of every pixel in each video frame.

# `t`

```elixir
@type t() :: %Membrane.RawVideo{
  aligned: aligned(),
  framerate: framerate(),
  height: height(),
  pixel_format: pixel_format(),
  width: width()
}
```

# `width`

```elixir
@type width() :: pos_integer()
```

Width of single frame in pixels.

# `frame_size`

```elixir
@spec frame_size(t()) :: {:ok, pos_integer()} | {:error, reason}
when reason: :invalid_dimensions | :invalid_pixel_format
```

Simple wrapper over `frame_size/3`. Returns the size of raw video frame
in bytes for the given raw video stream format.

# `frame_size`

```elixir
@spec frame_size(pixel_format(), width(), height()) ::
  {:ok, pos_integer()} | {:error, reason}
when reason: :invalid_dimensions | :invalid_pixel_format
```

Returns the size of raw video frame in bytes (without padding).

It may result in error when dimensions don't fulfill requirements for the given format
(e.g. I420 requires both dimensions to be divisible by 2).

# `image_to_payload`

```elixir
@spec image_to_payload(Vix.Vips.Image.t()) :: {:ok, binary(), t()} | {:error, term()}
```

Converts `t:Vix.Vips.Image.t/0` struct to raw video frame payload.

Returns a tuple `{:ok, payload, format}` where `payload` is a binary representing
the raw video frame and `format` is a `t:Membrane.RawVideo.t/0` struct describing
the format of the frame. Note, that `framerate` field in the returned format struct is
always `nil`, however the stream may have a framerate associated with it.

Calls `Vix.Vips.Image.write_to_binary/1` internally.

This function is available only if `:image` dependency is present.

# `payload_to_image`

```elixir
@spec payload_to_image(binary(), t()) ::
  {:ok, Vix.Vips.Image.t()} | {:error, :invalid_pixel_format | term()}
```

Converts raw video frame to `t:Vix.Vips.Image.t/0` struct.

It requires the pixel format to be `:RGB`.

Calls `Vix.Vips.Image.new_from_binary/5` internally.

This function is available only if `:image` dependency is present.

---

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