AVI File Documentation


Summary

AVI (Audio Video Interleave) is a multimedia container Microsoft introduced in 1992 as part of Video for Windows. It is built on RIFF, so its bytes begin with RIFF and the form type AVI . Because it is a container, the video inside can use many codecs (DivX, Xvid, MJPEG), which is why an AVI sometimes plays with sound but no picture. Its MIME type is video/x-msvideo. The free VLC player opens virtually any .avi; convert to MP4 for smaller, more portable files.

Technical details

FeatureValue
Full nameAudio Video Interleave
File extension.avi
MIME typevideo/x-msvideo
Format typeRIFF-based multimedia container (binary)
DeveloperMicrosoft
Introduced1992 (Video for Windows)
Container / base formatRIFF (Resource Interchange File Format)
Byte orderLittle-endian
Magic number52 49 46 46 (“RIFF”) at offset 0; 41 56 49 20 (“AVI ”) at offset 8
Video codecsDivX/Xvid (MPEG-4 ASP), Motion JPEG, Cinepak, uncompressed, others
Audio codecsPCM, MP3, AC-3, others (via FourCC / format tag)
Key chunkshdrl (headers), movi (media), idx1/indx (index)
Original size limit2 GB; lifted by OpenDML / AVI 2.0 (indx)
Open standardNo — Microsoft format; RIFF/AVI reference published
SubtitlesNo native soft subtitles
Universal playerVLC media player (bundles the needed codecs)
Common conversionAVI to MP4 (HandBrake, FFmpeg)
Related extensions.wav, .mp4, .mkv, .mov, .wmv, .divx
Specificationlearn.microsoft.com/windows/win32/directshow/avi-riff-file-reference
File signature (magic bytes)
52 49 46 46 xx xx xx xx 41 56 49 20

Bytes 0–3 are the ASCII string RIFF. Bytes 4–7 are a 32-bit little-endian size (the length of everything after this field). Bytes 8–11 are the form type 41 56 49 20 = AVI with a trailing space, which is what marks the file as AVI rather than any other RIFF file. The same RIFF family is used by WAV (form type WAVE) and WebP (WEBP): the four bytes at offset 8 are what tell the formats apart. All integers in AVI are little-endian.

What is an AVI file?

AVI stands for Audio Video Interleave. It is a multimedia container format Microsoft introduced in 1992 as part of Video for Windows. As a container, AVI does not itself define how the picture is compressed; it defines a structure that stores one or more media streams, most commonly one video stream and one audio stream, interleaved so a player can read them together during playback. The actual compression is the job of a codec, and an AVI can hold DivX or Xvid (MPEG-4 ASP), Motion JPEG, Cinepak, or uncompressed video, among others.

That container-versus-codec split is the single most important thing to understand about AVI. A file that “won’t play” or that plays with sound but no video is almost always a missing-codec problem, not a corrupt file: the container parses fine, but the system lacks a decoder for the bitstream inside. The reliable fix is a player that carries its own decoders, which is why the free VLC media player opens AVIs that the built-in Windows player rejects. Everything below is about how AVI encodes that structure, chunk by chunk.

RIFF: the tagged-chunk container

AVI is built on RIFF (Resource Interchange File Format), Microsoft’s generic tagged-chunk container, the same base used by WAV audio and, much later, WebP. A RIFF file is a tree of chunks. Every chunk has the same simple header:

chunk:
  ckID    : FOURCC   // 4 ASCII bytes, e.g. 'strh'
  ckSize  : uint32   // little-endian size of ckData, in bytes
  ckData  : bytes    // ckSize bytes, padded to even length

A four-character code (FourCC) names the chunk, a 32-bit little-endian size gives its data length, and the data follows, padded to an even byte boundary. A special chunk type, LIST, holds other chunks: its data begins with a FourCC list type, then nested chunks. The whole file is itself one RIFF chunk whose form type is AVI (with a trailing space). Because every chunk carries its own size, a reader can skip any chunk it does not recognise by jumping ckSize bytes forward, which is what gives the format its forward compatibility.

The top-level layout: hdrl, movi, idx1

A well-formed AVI has three parts in order inside the top RIFF('AVI ') form: the header list hdrl, the media list movi, and an optional index idx1. The overall shape is:

RIFF ('AVI '
  LIST ('hdrl'
      'avih' (main AVI header)
      LIST ('strl'  'strh' 'strf' ['strd'] ['strn'])   // stream 1
      LIST ('strl'  'strh' 'strf' ...)                 // stream 2
      ...
  )
  LIST ('movi'
      { data chunks, or LIST('rec ' ...) groups }
  )
  ['idx1' (index of the movi chunks)]
)

hdrl declares the format of everything, movi holds the actual audio and video data, and idx1 lists where each data chunk lives so a player can seek. AVI requires these to appear in this sequence; a player reads hdrl first to learn what streams exist and how to decode them before it touches a byte of media.

The main AVI header: the avih chunk

The hdrl list opens with an avih chunk, the main AVI header, which describes the file as a whole. Its fields include dwMicroSecPerFrame (the frame period, from which frame rate is derived), dwMaxBytesPerSec (the data rate), dwTotalFrames (the number of frames in the file), dwStreams (how many streams follow), and the video frame dwWidth and dwHeight in pixels. A flags field records properties such as whether the file has an index (AVIF_HASINDEX) and whether the interleaving is such that the index must be used for correct playback. These header values let a player set up timing and allocate buffers before decoding starts.

Per-stream headers: strl, strh, strf and the codec FourCC

After avih, the hdrl list contains one strl (stream list) per stream, and each strl must contain a stream header strh and a stream format strf. The strh chunk identifies the stream type through a FourCC: vids for video, auds for audio, plus txts and others. Crucially, strh also carries the handler FourCC that names the codec, and it holds the dwScale and dwRate pair whose ratio gives the stream’s sample rate (for video, the frame rate; for audio, the sample rate).

The strf chunk gives the format details a decoder needs, and its content depends on the stream type. For a video stream it is a BITMAPINFOHEADER, whose biCompression field holds the codec FourCCXVID, DIVX, MJPG, DX50, or 00000000 for uncompressed RGB. For an audio stream it is a WAVEFORMATEX, whose wFormatTag identifies the audio codec (for example 0x0001 for PCM or 0x0055 for MP3). This is exactly where a player learns which decoder to load, and it is the value at the heart of the “plays sound but no video” problem: if the system has no decoder for the biCompression FourCC, the video stream cannot be shown even though the audio decodes fine. Optional strd (codec setup data) and strn (a human-readable stream name) chunks can follow.

ChunkHolds
avihMain header: frame period, total frames, dimensions, stream count
strhStream header: type (vids/auds), codec handler, rate/scale
strfStream format: BITMAPINFOHEADER (video FourCC) or WAVEFORMATEX (audio tag)
strdOptional codec-specific setup data
strnOptional stream name

The movi list and the idx1 index

The movi list holds the media itself as a run of data chunks. Each data chunk’s FourCC encodes which stream it belongs to and what kind of data it is: a two-digit stream number followed by a two-letter type, so 00dc is compressed video for stream 0 (“dc” = DIB compressed), 01wb is audio waveform bytes for stream 1, and 00db is an uncompressed video frame. The chunks are interleaved — a run of video, then the audio that plays alongside it, then more video — so a player reads roughly sequentially while feeding both decoders, which is where the format’s name comes from. Chunks may be grouped inside LIST('rec ') records to hint at how much should be read at once.

After movi comes the optional idx1 chunk, the classic AVI index. It is a flat table with one entry per data chunk, each entry giving the chunk’s FourCC, flags (for example whether the chunk is a keyframe), its offset, and its size. With idx1 a player can seek: to jump to a time it finds the nearest keyframe entry and reads from that offset instead of scanning the whole movi list. Because idx1 stores 32-bit offsets, the original design could not address data beyond 2 GB, which brings us to the format’s main limit.

The 2 GB limit and the OpenDML indx extension

The original AVI specification effectively caps a file near 2 GB, because sizes and the idx1 offsets are 32-bit and measured from the start of movi. The OpenDML extension (AVI 2.0) removes this by adding a hierarchical index identified by the FourCC indx, with per-stream ix## sub-indexes, and by splitting the media across multiple RIFF chunks: the first is RIFF('AVI ') and each continuation is RIFF('AVIX'). The indx super-index points at the sub-indexes, which point at the actual chunks, so files far larger than 2 GB can be indexed and seeked. OpenDML is widely produced but not universally supported by very old readers, which is one reason a large AVI occasionally misbehaves in dated software.

Container versus codec, and why AVIs are large

The reason AVI files tend to be big is the codecs that AVI grew up with, not the container itself. DivX and Xvid (MPEG-4 ASP) compress less efficiently than the H.264 and H.265 used in modern MP4, and some AVIs are Motion JPEG or fully uncompressed, which are larger still. AVI also lacks conveniences that newer containers added: no native soft subtitle track, awkward handling of variable frame rate, and limited support for modern multi-channel audio. This is why the common task with an AVI is to convert it to MP4, re-encoding the DivX/Xvid video to H.264, which shrinks the file substantially with little visible loss. A container swap to MKV is different: MKV can hold the same streams, so ffmpeg -i in.avi -c copy out.mkv remuxes without re-encoding and mainly serves to add subtitle tracks AVI cannot carry. A move to MOV for Apple workflows is a true re-encode to H.264 in a different container.

References