4:4:4 chroma sampling 2026-11-05
4:4:4 chroma sampling retains one sample of each colour-difference component for every luma sample position. In a YCbCr image, the Y, Cb and Cr sample grids therefore have equal counts. The notation describes sampling density, not the number of bits in a sample.[ref]
For an original eight-bit image, there are four Y samples, four Cb samples and four Cr samples: 12 active bytes. Declare the row-major component arrays to be
Every image location has its own colour-difference values. Averaging each pair of Cb values would discard the alternating pattern; 4:4:4 sampling itself has not performed that averaging.
A planar pixel format can store those three arrays separately. A packed pixel format can instead put each location's three samples together. Both can represent the same 4:4:4 data, while dimensions, framebuffer stride and component order determine how to address the stored bytes.
Full component sampling also does not promise a lossless pipeline. YCbCr conversion can include rounding, and an image compression method can discard information even when its input uses 4:4:4. Conversely, a decoder that expands 4:2:0 chroma subsampling to a full grid by chroma reconstruction has not necessarily restored the original missing colour detail. Equal output counts and preservation of the original samples are distinct properties.
Chroma sample location 2026-11-05
A chroma sample location specifies where a colour-difference sample is positioned relative to the luma sampling grid. The counts in 4:2:2 chroma subsampling or 4:2:0 chroma subsampling do not fully specify those positions. Co-sited chroma shares selected luma positions; centered chroma lies between them.[ref]
Use an original one-dimensional coordinate system with luma samples at integers. A colour-difference grid at is co-sited with every second luma sample. The equally dense grid at is centered between successive pairs. Both contain half as many horizontal samples, but they have different offsets.
Suppose the first two stored component codes are 20 and 100. At the luma position , linear interpolation on the first grid gives
On the second grid it gives
The same stored array and interpolation rule yield different reconstructed values because the sample coordinates differ. An incorrect location convention can therefore shift colour relative to luma without corrupting the byte buffer.
Horizontal and vertical choices also need not match. The Linux documentation illustrates 4:2:0 with horizontally centered and vertically co-sited colour-difference samples.[ref] By contrast, the original grid diagram in 4:2:0 chroma subsampling deliberately chooses centering in both directions. That is an illustration, not a claim that every format follows it.
A framebuffer stride locates rows in computer memory; it does not identify the physical sampling offset. A decoder performing chroma reconstruction therefore needs both the storage layout and the sample-location convention.
Component plane 2026-11-05
A component plane stores samples of one component of an image separately from its other components. A three-plane RGB color model layout can hold a red array, a green array and a blue array, each indexed by image location. Intel's planar-format table records this arrangement explicitly.[ref] A component plane stores component samples, which can occupy several bits; a bit plane stores only one bit position from each sample.
For an original image, take
At row one, column zero, using zero-based indices, the pixel is . If each component uses one byte and row-major order, the active red bytes are 10 40 70 100. A routine that changes the red component plane can leave the green and blue arrays untouched.
The three active arrays contain bytes. With a separately declared four-byte framebuffer stride for each plane's row, storage instead occupies bytes, including padding. The image values are unchanged. A plane's dimensions, base address and row stride are therefore distinct parts of its layout description.
Other colour representations need not have three equal-sized, separate component arrays. Intel's table includes formats with differently sized planes and formats that interleave two colour components in one plane.[ref] A semiplanar pixel format combines a separate plane with such an interleaved plane. Thus an API's memory-plane count alone need not equal the number of colour components. A component plane is a statement about data organization, separate from the color space that interprets its numerical samples.
Framebuffer 2026-11-05
A framebuffer is computer memory holding an image's pixel values in a representation usable by graphics hardware or software. A pixel format specifies how stored bits encode those values. The image's dimensions alone do not determine its complete memory layout: rows can include padding, and different layouts can organize components differently.[ref]
For a concrete packed-row model, let the image be three pixels wide and two rows high, using four bytes per pixel. A row's actual pixel data occupies bytes. If each row starts 16 bytes after the previous one, the framebuffer stride is 16 bytes and four padding bytes separate consecutive pixel rows. Reserving two complete row slots takes bytes, although the pixel values themselves occupy only 24 bytes.
With zero-based coordinates, base memory address , stride and bytes per pixel, the start of a pixel in this stipulated layout is
Thus starts at . Replacing by the packed width12 would instead address the wrong location. This formula assumes packed, byte-addressable rows; it is not a formula for every possible pixel format.
The Linux interface makes the distinction explicit: line_length reports row length in bytes, separately from resolution and bits_per_pixel. A program should use the layout supplied by the interface when interpreting a framebuffer, rather than infer it from the visible dimensions alone.[ref]
Image memory plane 2026-11-05
An image memory plane is a separately described region of stored image data within a video frame or pixel buffer. It is a memory-organization concept, distinct from a component plane or a bit plane. One memory plane can contain several interleaved components, while one image can use several memory planes.[ref]
For example, NV12M uses one memory plane for luma and another for alternating Cb/Cr samples. It therefore has two memory planes but three colour components. NV21M uses the same plane count with the colour-difference pair order reversed. Their 4:2:0 chroma subsampling specifies sample counts; it does not turn the two components in the second plane into separate allocations.
Allocation capacity and video buffer payload also differ. A V4L2 plane descriptor records length, bytesused and a V4L2 plane data offset. In that API, bytesused includes the offset before the actual image data, so the image-data extent is
The allocation size is a separate limit.[ref]
For an original example, stipulate length = 4096, bytesused = 3072 and data_offset = 128, all in bytes. The image data begin128 bytes after the plane base and span2944 bytes, ending at base offset3072. They occupy neither the full4096-byte allocation nor all3072 bytes preceding that endpoint. The necessary bounds are
A consumer must combine these extents with the actual pixel format and framebuffer stride. A plane's capacity alone does not identify where a particular component or row begins.
NV12 2026-11-05
NV12 is an eight-bit YCbCr semiplanar pixel format with 4:2:0 chroma subsampling. A full-resolution plane holds luma samples. The following plane stores alternating Cb and Cr samples, with half as many sample positions in each spatial direction. Linux specifies ordinary untiled NV12 with adjacent planes; the separately allocated variant is NV12M.[ref]
For even dimensions , active samples occupy luma bytes plus interleaved colour-difference bytes. This is bytes, or an average of 12 bits per original pixel. It does not give every pixel its own three-component triple: neighbouring pixels share the lower-resolution colour-difference samples.
For an original address calculation, choose width six, height four and an eight-byte framebuffer stride in both planes. Put the first luma row at address 1000. The luma allocation occupies bytes, so the colour-difference plane starts at 1032 and occupies another bytes. There are 36 active bytes in 48 allocated bytes, including row padding.
With zero-based indices, luma position is at . Its associated subsampled grid cell has indices in this declared layout. That cell's Cb and Cr bytes are at 1044 and 1045. Colour reconstruction additionally needs a sampling-location and filtering convention; these address calculations alone do not specify it.
The pixel format identifies storage. A decoder must also know the YCbCr matrix and code ranges to interpret the numbers as colour.
NV21 2026-11-05
NV21 is an eight-bit YCbCr semiplanar pixel format using 4:2:0 chroma subsampling. It has a full-resolution luma plane followed by interleaved colour-difference samples in Cr, Cb order. NV12 uses the reverse pair order, Cb, Cr. The separately allocated Linux variant is NV21M.[ref]
An original tightly stored image has eight luma bytes followed by four colour-difference bytes. Suppose the latter are 200 40 150 90. Under NV21, the two pairs are and . Reading the same bytes as NV12 instead assigns and . The buffer length remains correct while its colour-difference channels are exchanged.
Converting this declared NV21 buffer to NV12 requires swapping adjacent bytes in the interleaved plane, giving 40 200 90 150, while retaining the luma data. This is a layout conversion, not a conversion to the RGB color model. The numerical colour interpretation still depends on the declared YCbCr encoding.
The active footprint is bytes for even width and height under eight-bit 4:2:0 sampling. Framebuffer stride can add padding, so the next row need not start immediately after the last active sample. A converter must apply the actual row and plane boundaries: swapping pairs across padding or across the luma plane would corrupt the image rather than exchange the intended channels.
Packed pixel format 2026-11-05
A packed pixel format stores the component fields or index for each pixel together in a single image plane, with successive pixels following one another in that plane. A planar pixel format instead separates component or bit planes. Packed does not necessarily mean one byte per pixel or the absence of row padding: the Linux frame-buffer API explicitly permits end-of-row padding in its packed storage type.[ref]
Consider an original 16-bit encoding with 4-bit fields in the order red, green, blue, alpha from most significant to least significant:
The bit fields for give . Extracting components by integer arithmetic gives
The same extraction can be implemented with bitwise operations. Declaring endianness is a separate step: this word occupies successive bytes C5 A3 in little-endian storage, and A3 C5 in big-endian storage. A component order in a word does not by itself specify the byte sequence.
If a row contains 100 of these two-byte pixels, its active data occupy 200 bytes. With framebuffer stride 208 bytes, the next row begins 208 bytes later, leaving eight padding bytes. A pixel-buffer consumer therefore needs the exact pixel format, dimensions and framebuffer stride, as well as any alpha channel convention and color space.
Pixel format 2026-11-05
A pixel format specifies how stored bits represent a pixel value: its components or table index, the allocation of bits to those components, and the applicable representation conventions. A complete image layout also needs dimensions and row organization, including framebuffer stride. The Linux frame-buffer API separates storage type from color interpretation and describes component offsets and lengths explicitly.[ref]
For an original packed pixel format, place red, green and blue codes in a 16-bit unsigned word , with widths 5, 6 and 5 bits respectively. Declare the red component to occupy bits15–11, green10–5 and blue4–0:
These non-overlapping bit fields specify a particular encoding. Setting gives , or 0xF800 in hexadecimal. Knowing only “16 bits per pixel” would not identify those component positions.
Endianness then controls how the word occupies byte-addressed computer memory. Little-endian storage of 0xF800 gives successive bytes 00 F8; big-endian storage gives F8 00. Reading the little-endian bytes as a big-endian word instead produces 0x00F8. Under the same declared component fields, that decodes to rather than . Bit significance in the word and byte order in memory are separate specifications.
Bit allocation also limits representable component codes: the red and blue fields have 32 levels each, while green has 64. If normalized codes are defined as , and , their respective increments are , and . These are code increments, not a claim that emitted light varies linearly with the stored number. The RGB color model and an appropriate color space supply further interpretation.
Other formats can store an image lookup table index or include an alpha channel for transparency. The frame-buffer documentation likewise distinguishes pseudocolor indices from direct component fields.[ref] Report the actual format alongside dimensions and stride when exchanging pixel buffers.
Planar pixel format 2026-11-05
A planar pixel format distributes a pixel's information among separate planes of stored samples, instead of putting all its components together as in a packed pixel format. A component plane may contain all red samples, another all green samples and another all blue samples. Intel's image-format documentation distinguishes these arrangements explicitly.[ref]
For an original one-row, two-pixel RGB color model image, suppose the component triples are and , each component occupying one byte. A packed order can be 10 20 30 40 50 60. A declared planar layout can instead store red bytes 10 40, green bytes 20 50 and blue bytes 30 60. Reinterpreting one sequence as the other changes the reconstructed colours; it is not an image compression method.
For a chosen planar layout with one byte per sample, plane has base address and framebuffer stride bytes. The sample at row and column then has address
For example, with , , row and column , the red sample is at address . Width, height, plane order, sample size and each plane's stride belong in the layout specification. Separate planes need not be adjacent allocations.
A bit plane is another arrangement: one plane stores the same bit position from many pixels. The Linux frame-buffer API's FB_TYPE_PLANES uses this bit-plane meaning, rather than one entire colour component per plane.[ref] Thus the word planar alone is insufficient to decode a buffer. Processing one component across many pixels can use a contiguous component plane, while processing whole pixels must gather their components according to the declared pixel format.
Semiplanar pixel format 2026-11-05
A semiplanar pixel format combines a separate sample plane with another plane containing interleaved components. A common YCbCr arrangement stores luma samples in one plane and pairs of colour-difference samples in another. It therefore has two planes while representing three components. Linux's video API distinguishes this from the three separate planes of a fully planar pixel format.[ref]
In NV12, one byte represents each sample. Chroma subsampling halves the colour-difference sampling count in both directions, and the second plane stores Cb followed by Cr in each pair. NV21 reverses that pair order. For even width and height , tightly stored active samples occupy
Thus a stipulated image contains eight Y samples and two Cb/Cr pairs: 12 active bytes. The eight Y bytes can be followed by Cb00 Cr00 Cb01 Cr01. The component names identify stored codes; their colour interpretation also requires the declared YCbCr conventions.[ref]
Active sample count differs from allocated storage. With an eight-byte framebuffer stride for both planes in this example, two Y rows and one interleaved row occupy bytes including padding. A consumer needs dimensions, strides, component order and whether planes are adjacent or separately allocated. Reinterpreting NV21 as NV12 swaps the two colour-difference components; it does not recover the intended colours merely because the buffer size matches.
Stephen Estrop 2026-11-05
Stephen Estrop coauthored Microsoft's Recommended 8-Bit YUV Formats for Video Rendering by Gary Sullivan and Stephen Estrop with Gary Sullivan. The article is dated April2002, updated November2008, and specifies sample grids and memory layouts for eight-bit video rendering.[ref]
An original address calculation illustrates why a pixel format needs more than a sample count. Stipulate an NV12 image of width 10 and height 6, with framebuffer stride 16 bytes in both planes. Let the first luma byte have address 2000, and place the interleaved colour-difference plane immediately after the six stored luma rows. Its base is . The allocation holds bytes, although active samples require only bytes.
At zero-based row 5, column 9, the luma byte is at . Its associated subsampled grid cell is row 2, column 4, whose Cb and Cr bytes are at and 2137. Counting active samples as if they were the allocation size would give the wrong plane base. The shared technical article defines NV12's component order; the chosen dimensions, padding and addresses here are illustrative.[ref]
These calculations locate stored samples. Reconstructing colour additionally requires chroma sample location, chroma reconstruction and the specified YCbCr conversion. The article's joint byline does not identify which coauthor designed an individual format.
V4L2 multi-planar API 2026-11-05
The V4L2 multi-planar API is the Video4Linux interface for describing video buffers whose data may occupy several image memory planes. A buffer acts as a container, while per-plane descriptors identify the relevant storage. This supports formats such as NV12M and NV21M without assuming that one plane immediately follows another.[ref]
A multi-planar interface and a multi-planar format are different choices. The interface can also carry supported single-planar formats when described through its structures; the reverse interface cannot describe a multi-planar format. Buffer-type names ending in _MPLANE identify the multi-planar interface, rather than specifying a colour model or sampling ratio.[ref]
A practical interpretation depends on the structure being read. In v4l2_buffer, length means a number of plane-array elements under the multi-planar API. Inside a V4L2 plane descriptor, length instead means that plane's allocation size in bytes.[ref]
For an original descriptor example, a frame with two planes has a container plane count of two and stipulated plane capacities4096 and2048 bytes. Treating the outer count as a two-byte storage capacity, or treating4096 as the number of plane descriptors, confuses quantities with different meanings. The sum6144 describes those declared capacities, not the number of active image bytes.
The negotiated pixel format still determines the component arrangement. Descriptors for two planes could represent a luma plane plus interleaved colour differences; they do not automatically mean one red plane and one green plane. Framebuffer stride, sample encoding and chroma sample location remain part of interpreting the image.
V4L2 plane data offset 2026-11-05
The V4L2 plane data offset is the byte distance from the beginning of an image memory plane to its image data. It is the data_offset member of a V4L2 plane descriptor. In this interface, bytesused includes that prefix, so the image-data extent is bytesused - data_offset.[ref]
Write for data_offset, for bytesused and for the plane's length, all in bytes. A consistent nonnegative extent satisfies
If is the mapped plane-base address, the image begins at and ends immediately before . This is an offset within a plane, distinct from the descriptor's mem_offset used when arranging a memory mapping.
For an original bounds example, stipulate , and . The image occupies 5888 bytes beginning at byte offset 256. Its last byte is at offset 6143. Taking a length of 6144 from the shifted starting address would instead read through offset 6399, including 256 bytes beyond the declared extent. Conversely, discarding the prefix twice would lose 256 valid bytes.
The offset does not specify framebuffer stride or component order. Once the correct image start is found, the negotiated pixel format still determines how rows and color components are read. A correct extent prevents a boundary mistake; it does not by itself establish that the samples represent the intended image.
V4L2 plane descriptor 2026-11-05
A V4L2 plane descriptor is a v4l2_plane structure describing one image memory plane in the V4L2 multi-planar API. The containing v4l2_buffer refers to an array of these descriptors. Each descriptor records storage capacity, occupied extent and the V4L2 plane data offset; its storage reference depends on the selected input-output method.[ref]
The two structures use length for different quantities. The container's length counts descriptor-array elements; a plane descriptor's length counts bytes. Neither is automatically the active image extent. For a stipulated two-plane NV12M buffer, suppose the plane capacities are 8192 and 4096 bytes, with occupied extents 7000 and 3500 bytes and zero data offsets. Then the container describes two planes, storage capacity totals 12288 bytes, and occupied data total 10500 bytes. These are three different measurements of the same buffer.
For capture, the device driver supplies the occupied extent and data offset; for output, the application supplies them. A consumer combines those values with the negotiated pixel format and framebuffer stride. Describing two planes does not imply two colour components: NV12M has a luma plane and another containing both colour-difference components.
A descriptor describes access to image storage; it does not itself contain an image-sized copy. Two equal descriptor counts can therefore describe different allocations, different component arrangements or different amounts of valid data. The video buffer payload and its layout must be interpreted separately.
Video4Linux 2026-11-05
Video4Linux is the Linux kernel subsystem through which applications control supported video-related hardware and exchange data with it. Its version-two application programming interface is called V4L2. A device driver exposes the applicable device interfaces; applications use file descriptors and control operations rather than directly programming the hardware registers. The kernel specification describes video capture/output, radio and related device-node types.[ref]
A video device node such as /dev/video0 is an entry point to an interface, not a promise about a camera's identity or its supported formats. Device numbering can depend on discovery order. After opening a device, an application queries its capabilities with VIDIOC_QUERYCAP; the available operations depend on the device.[ref]
For an original frame-storage example, suppose a device supports NV12M at width 640 and height 480, with eight-bit samples, even dimensions and no padding. Full-resolution luma needs bytes. The two colour-difference components together need bytes, giving 460800 active bytes per frame. At a stipulated 30 frames per second, active sample data total . Allocation padding, other transport data and actual timing are separate quantities.
The V4L2 multi-planar API can describe those separately stored image memory planes; each V4L2 plane descriptor supplies that plane's extents. A negotiated pixel format and framebuffer stride tell an application how to interpret the received data. A successful device open alone establishes none of those layout choices.
Video buffer payload 2026-11-05
A video buffer payload is the occupied data extent carried by a video buffer, distinguished from its allocated capacity. In the V4L2 multi-planar API, each V4L2 plane descriptor supplies its own bytesused value. For a single-planar buffer the corresponding field is in v4l2_buffer. Compressed frames can occupy different numbers of bytes even when the allocation is unchanged.[ref]
The field name needs care: in a V4L2 plane descriptor, bytesused includes any prefix specified by the V4L2 plane data offset. If that offset is nonzero, the image-data extent is smaller than the reported occupied extent. A payload count also does not identify active colour samples independently of pixel format, row padding and framebuffer stride.
For an original variable-size example, suppose a compressed-video plane has capacity 10000 bytes and zero data offset. Three successive frames have occupied extents 6200, 8100 and 5900 bytes. Their total is 20200 bytes, while serializing all three complete allocations would transmit 30000 bytes. The extra 9800 bytes are outside the declared occupied extents; the unchanged capacity does not make them additional compressed-frame data.
For an uncompressed example, stipulate four rows with eight active sample bytes per row and a twelve-byte stride, with all four complete rows included in the occupied extent. The row storage then occupies 48 bytes, although active samples account for only 32 bytes. Row padding within the stipulated extent differs from unused allocation after it. The consumer needs both the extent and the layout to distinguish them.