After the 32-byte file header the file is nothing but frames, one after another, to the end of the file. There is no index and no end marker.
Frame header
Each frame starts with a 12-byte header. All numbers are little-endian.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | u32 | frame size | the number of bytes of frame data, not counting this header |
| 4 | 8 | u64 | timestamp | the presentation time of the frame, in the units of the time base |
| 12 | frame size | bytes | frame data | one compressed frame, see below |
The next frame header follows at offset 12 + frame size. The timestamp is often simply the frame number, when the time base is one over the frame rate. IVF stores no duration for a frame: FFmpeg keeps one while writing but never puts it in the file.
What a frame holds
| Codec | Frame data |
|---|---|
| VP8 | one VP8 frame |
| VP9 | one VP9 frame or superframe. FFmpeg packs hidden frames into superframes when writing, with its vp9_superframe bitstream filter |
| AV1 | one temporal unit of OBUs in the low-overhead format. FFmpeg makes sure each one starts with a temporal delimiter OBU, with its av1_metadata filter set to td=insert |
Reading a file
- Check the signature
DKIFand read the codec, size and time base. - Skip to the offset given by the header length, normally 32.
- Read 12 bytes. If fewer than 12 remain, stop.
- Read frame size bytes as one frame. If fewer remain, the file is truncated.
- Repeat from step 3.
Worked example
The header of a frame of 4,660 bytes at timestamp 3:
00000020 34 12 00 00 03 00 00 00 00 00 00 00
| Offset | Bytes | Value |
|---|---|---|
| 32 | 34 12 00 00 | frame size 0x1234, 4,660 bytes |
| 36 | 03 00 00 00 00 00 00 00 | timestamp 3 |
| 44 | 4,660 bytes | the frame data; the next frame header is at offset 4,704 |