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.