NV12M 2026-11-05
NV12M is the non-contiguous-memory variant of NV12 in the Linux video API. It stores eight-bit luma separately from an interleaved Cb, Cr plane, using 4:2:0 chroma subsampling. Its two image memory planes can occupy independent allocations; the second plane's address is not inferred by adding the first plane's size.[ref]
Planar YUV formats in the Linux Kernel documentation. Semi-Planar table and NV12/NV21/NV12M/NV21M subsection
For an original address example, stipulate an accepted width-six, height-four layout. Let the luma base be 1000 with framebuffer stride eight bytes, and the colour-difference base be 8000 with stride 12 bytes. The allocations occupy and bytes, respectively. Their 56 allocated bytes contain 36 active samples, with padding accounting for the difference.
At zero-based luma position , the address is . In the declared subsampling grid, its associated colour-difference cell is . The Cb address is , and Cr is at 8017. Substituting 1032 for the second base would access an unrelated region under these stipulated allocations.
The V4L2 multi-planar API describes each memory plane explicitly. It also supports single-planar formats, so using that API does not itself prove that a buffer is NV12M. The negotiated pixel format, plane addresses, sizes and strides must agree.[ref]
Single- and multi-planar APIs in the Linux Kernel documentation. §1.26, especially Multi-planar formats
This separation changes buffer organization, not the YCbCr matrix, code ranges or chroma sample location. Those remain additional information needed for colour interpretation and chroma reconstruction.
NV21M 2026-11-05
NV21M is a two-memory-plane semiplanar pixel format for eight-bit YCbCr with 4:2:0 chroma subsampling. Like NV21, its colour-difference plane stores Cr before Cb in each pair. Unlike ordinary contiguous NV21, the two image memory planes can have independent allocations.[ref]
Planar YUV formats in the Linux Kernel documentation. Semi-Planar table and NV12/NV21/NV12M/NV21M subsection
For an original example, stipulate an accepted width-four, height-four layout whose luma plane begins at 1000 with an eight-byte framebuffer stride, while its Cr/Cb plane begins at 5000 with a four-byte stride. Luma position is at . The corresponding subsampled cell has Cr at and Cb at 5007. This ordering is the reverse of NV12M.
The active sample count is bytes. The declared allocation sizes are bytes because luma rows have padding. Neither 40 nor 24 is an offset that can replace the explicitly supplied second-plane base.
A layout conversion to NV12M can exchange the two bytes in each active colour-difference pair while respecting each plane's stride. It does not require changing luma values or reducing the colour sample count. By contrast, choosing a different YCbCr matrix would be a colour conversion.
The distinction between a multi-planar format and the V4L2 multi-planar API matters here: the interface can carry formats with different memory organizations, while the format identifies which organization the supplied descriptors represent.[ref]
Single- and multi-planar APIs in the Linux Kernel documentation. §1.26.1, API versus format
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]Opening devices and querying capabilities in the Linux Kernel video API documentation. §1.1.2, device naming notes; Querying Capabilities, §1.2
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.
Video device node 2026-11-05
A video device node is a device node through which an application accesses a supported video or metadata interface in Video4Linux. A conventional path is
/dev/video0, but the name identifies a kernel interface rather than a persistent physical-camera identity. Device drivers register the interfaces, and applications open them to obtain file descriptors for the appropriate operations.[ref]A single hardware peripheral can expose several interfaces. Conversely, a path numbered zero can refer to different hardware after discovery order changes. The kernel documentation identifies
/dev/v4l/by-id/ and /dev/v4l/by-path/ links as alternatives for identifying devices independently of transient numbering.[ref]Opening devices and querying capabilities in the Linux Kernel video API documentation. §1.1.2, naming notes and example device links
For an original selection example, suppose cameras A and B are discovered in that order and receive paths
/dev/video0 and /dev/video1. On another boot B is discovered first, reversing those assignments. A configuration containing only /dev/video0 then selects a different camera while remaining a valid path. Identifying the intended hardware and querying the opened interface's capabilities addresses two separate questions.The returned file descriptor refers to an open instance; it is not the camera number. An application may receive descriptor 7 when opening
/dev/video0, and another application may also have a descriptor 7 referring to another object in its own descriptor table. File descriptors are local process handles, while the device path belongs to the file system namespace.Before interpreting data, query the interface with
VIDIOC_QUERYCAP and negotiate its supported pixel format. A video device node alone does not imply support for NV12M, a chosen image size or the V4L2 multi-planar API. The resulting image memory planes and video buffer payload must follow the actual negotiated interface.