V4L2 pixel formats

V4L2 (Video For Linux 2) supports a large variety of pixel formats expressed with fourcc codes. In this guide we will focus on what V4L2 calls “packed RGBA” formats. These are formats that store all of the RGBA pixel data next to each other in memory.

As in many other pixel format families, the RGBA formats come in two flavors: packed and array. Note that, in this context, “packed” is distinct from the V4L2 term “packed RGBA” which is described above.

Packed pixel formats

Packed formats follow the scheme:

V4L2_PIX_FMT_{components}{rgb-component-bits}(X)

These formats specify a pixel represented by a native type of the least size (8, 16, 24 or 32 bits) that can fit the sum of rgb-component-bits. The leftmost component occupies the most significant bits of the type and the rightmost component the least significant bits.

The leftmost value in rgb-component-bits specifies the size of the leftmost RGB component in components, and the rightmost value in rgb-component-bits the size of the rightmost RGB component in components. Note that the size of the A or X component is never explicitly specified, but can be inferred from the difference between the sum of the rgb-component-bits and the size of the native type used for this format.

The memory layout of formats without the X suffix is that of the native type when stored on a little-endian system. The memory layout of formats with the X suffix is that of the native type when stored on a big-endian system.

Although the formats are expressed in terms of a native type, the addition of the little- or big-endianness specification in the formats themselves makes the formats independent of system endianness.

Examples: V4L2_PIX_FMT_RGB332

This is a 8-bit pixel format, since 3 + 3 + 2 = 8 bits, which fits in a single byte. Its memory layout is:

M              L
R₂R₁R₀G₂G₁G₀B₁B₀

Examples: V4L2_PIX_FMT_ARGB555

This is a 16-bit pixel format, since 5 + 5 + 5 = 15 bits, which fits in a two byte type. The A component occupies 1 bit (16-bit type - 15-bit RGB size specification). This format corresponds to the native type:

M                              L
A₀R₄R₃R₂R₁R₀G₄G₃G₂G₁G₀B₄B₃B₂B₁B₀

The memory layout of this format is always that of the native type when stored on a little-endian system:

0                1
M              L M              L
G₂G₁G₀B₄B₃B₂B₁B₀ A₀R₄R₃R₂R₁R₀G₄G₃

Examples: V4L2_PIX_FMT_ARGB555X

This format represents the same 16-bit native type as its little-endian counterpart ( V4L2_PIX_FMT_ARGB555) described in the previous example. However, its memory layout is always that of the native type when stored on a big-endian system:

0                1
M              L M              L
A₀R₄R₃R₂R₁R₀G₄G₃ G₂G₁G₀B₄B₃B₂B₁B₀

Array pixel formats

Array formats follow the scheme:

V4L2_PIX_FMT_{components}{24,32}

They specify a pixel stored in memory as an array of either 3 (suffix 24) or 4 (suffix 32) consecutive bytes with each component occupying a single byte. The leftmost component is stored at the lowest memory address, and the rightmost component is stored at the highest memory address.

Example: V4L2_PIX_FMT_RGB24

Stored in memory as the bytes R, G, B (R at the lowest address, B at the highest address).

Example: V4L2_PIX_FMT_ARGB32

Stored in memory as the bytes A, R, G, B (A at the lowest address, B at the highest address).

Exceptions

There are a few unfortunate exceptions in the V4L2 format schemes mentioned above.

Exception: V4L2_PIX_FMT_BGR666

This looks like a packed little-endian format, but it’s actually a strange beast. Its memory layout is:

0                1                2
M              L M              L M              L
B₅B₄B₃B₂B₁B₀G₅G₄ G₃G₂G₁G₀R₅R₄R₃R₂ R₁R₀X₅X₄X₃X₂X₁X₀

Note the unconventional placement of the low bits of the R component in the most significant bits of the third byte.

Exception: V4L2_PIX_FMT_ABGR32 and V4L2_PIX_FMT_XBGR32

Again, these look like typical array formats, but it turns out that the A/X component is misplaced (with regard to the normal array pixel format scheme). The memory layout of these formats is really: B, G, R, A/X.

For consistency, these formats should have been named V4L2_PIX_FMT_BGRA32 and V4L2_PIX_FMT_BGRX32, respectively.