Reference · Worked examples
YUV and image-format examples
Concrete walkthroughs to accompany the YUVTools guide. Numbers are illustrative; substitute your own dimensions and formats as needed.
These examples are informational. Sunray Image does not provide software, downloads or support.
§ 01
How big is a raw frame?
A raw frame's size depends only on resolution, sampling and bit depth. For an 8-bit 1920×1080 frame:
frame_bytes = width × height × (bytes_per_pixel)
| Format | Sampling | Bytes / pixel | Frame size (bytes) |
|---|---|---|---|
| I420 / NV12 | 4:2:0 | 1.5 | 3,110,400 |
| I422 / YUY2 / UYVY | 4:2:2 | 2.0 | 4,147,200 |
| I444 | 4:4:4 | 3.0 | 6,220,800 |
| I420, 10-bit | 4:2:0 | 3.0 | 6,220,800 |
Notice that 10-bit 4:2:0 needs the same space as 8-bit 4:4:4: each sample now occupies two bytes, but there are still only 1.5 samples per pixel.
§ 02
Finding a pixel in YUY2
YUY2 stores two horizontally adjacent pixels in four bytes: Y0 U Y1 V. To read pixel (x, y) in a frame of width W:
stride = W × 2 row = stride × y pair = (x - (x mod 2)) / 2 base = row + pair × 4 Y = base + (x mod 2) × 2 U = base + 1 V = base + 3
Worked example — pixel (100, 50) in a 1920-wide YUY2 frame:
stride = 1920 × 2 = 3840 row = 3840 × 50 = 192000 pair = 100 / 2 = 50 base = 192000 + 50 × 4 = 192200 Y at 192200 · U at 192201 · V at 192203
Pixel 100 is even, so its Y sits at base + 0; pixel 101 would use base + 2 and share the same U and V.
§ 03
Chroma subsampling, one block at a time
Take a 4-pixel-wide, 2-row block. Each cell below is one sample. Y is always full resolution; the difference is how many U and V samples remain.
4:4:4 — 8 Y, 8 U, 8 V
4:2:2 — 8 Y, 4 U, 4 V
4:2:0 — 8 Y, 2 U, 2 V
The dots are samples that were never stored; the decoder fills them in by copying from a neighbour. That is why 4:2:0 saves half the bytes of 4:4:4.
§ 04
PSNR by hand
Given a tiny 2×2 reference and a distorted version, PSNR is computed in four steps.
reference = [100 110 | 120 130] distorted = [102 108 | 119 134] errors = [ +2 -2 | -1 +4] squared = [ 4 4 | 1 16] MSE = (4 + 4 + 1 + 16) / 4 = 6.25 PSNR = 10·log10(255² / MSE) = 10·log10(65025 / 6.25) = 10·log10(10404) ≈ 40.17 dB
A result around 40 dB for natural content usually means the difference is hard to see; below about 30 dB it is often visible. See PSNR, SSIM and your eyes for the caveats.
§ 05
Planar vs. packed, first bytes
For a 4×2 frame, here is the order in which the first samples are written to memory in two common layouts.
I420 (planar, 4:2:0): Y0 Y1 Y2 Y3 | Y4 Y5 Y6 Y7 U0 U1 | V0 V1 YUY2 (packed, 4:2:2): Y0 U0 Y1 V0 | Y2 U1 Y3 V1 Y4 U2 Y5 V2 | Y6 U3 Y7 V3
Same picture, different order. A decoder that expects one layout and receives the other produces colour-swapped or sheared output. More in Planar vs. packed YUV.