ExYUV (ExYUV v0.2.0)

View Source

ExYUV

Elixir binding for libyuv.

libyuv is an open source project that includes YUV scaling and conversion functionality.

  • Scale YUV to prepare content for compression, with point, bilinear or box filter.
  • Convert to YUV from webcam formats for compression.
  • Convert to RGB formats for rendering/effects.
  • Rotate by 90/180/270 degrees to adjust for mobile devices in portrait mode.
  • Optimized for SSSE3/AVX2 on x86/x64.
  • Optimized for Neon/SVE2/SME on Arm.
  • Optimized for MSA on Mips.
  • Optimized for RVV on RISC-V.

Formats

Formats (FOURCC) supported by libyuv are detailed here.

Core Formats

There are 2 core formats supported by libyuv - I420 and ARGB. All YUV formats can be converted to/from I420. All RGB formats can be converted to/from ARGB.

Filtering functions such as scaling and planar functions work on I420 and/or ARGB.

Planar Formats

FormatPlanesDescription
I4203Y full resolution. U half width, half height. V half width, half height

Packed Formats

FormatBits Per PixelPixel Memory Layout
RAW (RGB)24<<r::8, g::8, b::8>>
RGB2424<<b::8, g::8, r::8>>
ARGB32<<b::8, g::8, r::8, a::8>>
ABGR32<<r::8, g::8, b::8, a::8>>
BGRA32<<a::8, r::8, g::8, b::8>>
RGBA32<<a::8, b::8, g::8, r::8>>
RGB56516<<r::5, g::6, b::5>>
RGB155516<<a::1, r::5, g::6, b::5>>
RGB444416<<a::4, r::4, g::4, b::4>>
AR3032<<a::2, r::10, g::10, b::10>>
AB3032<<a::2, b::10, g::10, r::10>>

Installation

The package can be installed by adding ex_yuv to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_yuv, "~> 0.1.0"}
  ]
end

Summary

Types

argb_16()

@type argb_16() :: binary()

argb_32()

@type argb_32() :: binary()

filter_mode()

@type filter_mode() :: :none | :linear | :bilinear | :box

height()

@type height() :: pos_integer()

i420_data()

@type i420_data() :: binary() | {y_plane(), u_plane(), v_plane()} | [binary()]

rgb_16()

@type rgb_16() :: binary()

rgb_24()

@type rgb_24() :: binary()

u_plane()

@type u_plane() :: binary()

v_plane()

@type v_plane() :: binary()

width()

@type width() :: pos_integer()

y_plane()

@type y_plane() :: binary()

yuv_planes()

@type yuv_planes() :: {y_plane(), u_plane(), v_plane()}

Functions

i420_to_ab30!(data, width, height)

@spec i420_to_ab30!(i420_data(), width(), height()) :: argb_32()

Convert I420 to AB30.

The memory layout of the result is <<alpha::2, blue::10, green::10, red::10>>

i420_to_abgr!(data, width, height)

@spec i420_to_abgr!(i420_data(), width(), height()) :: argb_32()

Convert I420 to ABGR.

The memory layout of the result is <<red::8, green::8, blue::8, alpha::8>>

i420_to_ar30!(data, width, height)

@spec i420_to_ar30!(i420_data(), width(), height()) :: argb_32()

Convert I420 to AR30.

The memory layout of the result is <<alpha::2, red::10, green::10, blue::10>>

i420_to_argb1555!(data, width, height)

@spec i420_to_argb1555!(i420_data(), width(), height()) :: argb_16()

Convert I420 to ARGB1555.

The memory layout of the result is <<alpha::1, red::5, green::5, blue::5>>

i420_to_argb4444!(data, width, height)

@spec i420_to_argb4444!(i420_data(), width(), height()) :: argb_16()

Convert I420 to ARGB4444.

The memory layout of the result is <<alpha::4, red::4, green::4, blue::4>>

i420_to_argb!(data, width, height)

@spec i420_to_argb!(i420_data(), width(), height()) :: argb_32()

Convert I420 to ARGB.

The memory layout of the result is <<blue::8, green::8, red::8, alpha::8>>

i420_to_bgra!(data, width, height)

@spec i420_to_bgra!(i420_data(), width(), height()) :: argb_32()

Convert I420 to BGRA.

The memory layout of the result is <<alpha::8, red::8, green::8, blue::8>>

i420_to_raw!(data, width, height)

@spec i420_to_raw!(i420_data(), width(), height()) :: rgb_24()

Converts from I420 to RGB24 format.

The input should be the planes (Y, U and V), in case a binary is provided, it'll try to get the planes from it.

The memory layout of the result is <<red::8, green::8, blue::8>>

i420_to_rgb24!(data, width, height)

@spec i420_to_rgb24!(i420_data(), width(), height()) :: rgb_24()

Convert I420 to BGR24.

Note

Even when the function name hints that the output format is RGB24, it's actually BGR24. We kept the same naming convention used in libyuv.

i420_to_rgb565!(data, width, height)

@spec i420_to_rgb565!(i420_data(), width(), height()) :: rgb_16()

Convert I420 to RGB565.

The memory layout of the result is <<red::5, green::6, blue::5>>

i420_to_rgba!(data, width, height)

@spec i420_to_rgba!(i420_data(), width(), height()) :: argb_32()

Convert I420 to RGBA.

The memory layout of the result is <<alpha::8, blue::8, green::8, red::8>>

raw_to_i420!(data, width, height)

@spec raw_to_i420!(rgb_24(), width(), height()) :: yuv_planes()

Converts from RGB24 to I420 format.

scale_argb!(data, width, height, out_width, out_height, filter_mode \\ :none)

@spec scale_argb!(argb_32(), width(), height(), width(), height(), filter_mode()) ::
  argb_32()

Scale ARGB/ABGR/RGBA/BGRA image.

The following filters are supported: none, linear, bilinear, and box.

Check libyuv documentation for more details.

scale_i420!(data, width, height, out_width, out_height, filter_mode \\ :none)

@spec scale_i420!(i420_data(), width(), height(), width(), height(), filter_mode()) ::
  yuv_planes()

Scale I420 image.

The following filters are supported: none, linear, bilinear, and box.

Check libyuv documentation for more details.

scale_rgb!(data, width, height, out_width, out_height, filter_mode \\ :none)

@spec scale_rgb!(rgb_24(), width(), height(), width(), height(), filter_mode()) ::
  rgb_24()

Scale RAW/RGB24 image.

The following filters are supported: none, linear, bilinear, and box.

Check libyuv documentation for more details.