After the stream header the file is a series of frames to the end of the file. Each is a one-line frame header followed by the image data.
Frame header
The line is the magic string FRAME, then any number of tagged fields, each
with one space before it, then one newline byte. Most files have a bare
FRAME line, 6 bytes long. A reader must still look for the newline, because
tags are allowed. FFmpeg’s reader accepts a frame header of at most 80 bytes.
Plane layout
Directly after the newline comes the image: the planes one after another, each stored row by row from the top, with no padding and no alignment. For an interlaced stream the two fields are interleaved line by line.
Plane order is Y′, then Cb, then Cr, then alpha for 444alpha. Each sample
of the standard formats is one byte. For 444alpha the alpha plane uses the
luma range, where 16 is fully transparent and 235 fully opaque.
| Colour space | Y′ size | Cb and Cr size, each | Bytes per frame (8-bit) |
|---|---|---|---|
420jpeg, 420mpeg2, 420paldv | W × H | W/2 × H/2 | W × H × 3/2 |
411 | W × H | W/4 × H | W × H × 3/2 |
422 | W × H | W/2 × H | W × H × 2 |
444 | W × H | W × H | W × H × 3 |
444alpha | W × H | W × H, plus an alpha plane of W × H | W × H × 4 |
mono | W × H | none | W × H |
When the width or height is odd, chroma planes round up: FFmpeg uses (W + 1) / 2 and (H + 1) / 2 for subsampled chroma. The manual page speaks only of half-size planes and does not address odd sizes.
Above 8 bits, the FFmpeg extensions store each sample in two bytes in the machine’s native order, which is little-endian on the usual platforms. The sample keeps its low bits at the bottom, so a 10-bit sample’s range is 0 to 1023.
Chroma siting of the 4:2:0 modes
| Colour space | Position of the chroma samples relative to luma |
|---|---|
420jpeg | centred between four luma samples, horizontally and vertically |
420mpeg2 | horizontally cosited with luma, half a sample down vertically |
420paldv | Cr cosited with luma, Cb one luma sample down |
MultimediaWiki describes these positions and notes that tools interpret plain
C420 differently. FFmpeg maps 420paldv to top-left siting and
420mpeg2 to left siting.
Worked example
With the header YUV4MPEG2 W640 H360 F30:1 Ip C420jpeg:
FRAME
(230,400 bytes of Y′, 640 × 360)
(57,600 bytes of Cb, 320 × 180)
(57,600 bytes of Cr, 320 × 180)
FRAME
…
Each frame is 6 + 345,600 bytes. The number of frames is the file size minus the header length, divided by 345,606, as long as no frame carries tags.