The guide
A video file is a box of boxes: reading codecs, frame timing and bitrate from the container
Every MP4, MOV, MKV and WebM file carries an index of its own frames, and that index answers most questions about the video without decoding a single picture.
- 0.058% of the example file read to report every field below
- 5.42 Mbit/s average video bitrate of the worked example, from 288 sizes
- 16 and 18 transfer code points that mark PQ and HLG HDR video
- 21.3 ms AAC priming that the example's edit list trims away
Read the full guide Fold the guide
A video file is two things packed together. One is the compressed pictures and sound, the codec’s work. The other is the container, a filing system that says where every picture sits, when it should be shown and how it should be read. People mix the two up all the time, and the mix-up hides a useful fact: the container answers most practical questions about a video by itself.
H.264, HEVC, VP9 and AV1 are codecs. MP4, MOV, Matroska and WebM are containers. A codec decides how a frame is squeezed into bytes; a container decides how those bytes are labelled, timed and found again. The same H.264 stream can live in an MP4 file or a Matroska file, and the frames do not change when it moves. What changes is the index around them. That index is small, it sits at a known place in the file, and it is written in a documented layout that anyone may read.
Boxes and elements
The MP4 family grew out of the QuickTime movie format. Its formal base is the ISO base media file format, MPEG-4 Part 12, and the Library of Congress describes how everything in such a file lives inside boxes, with no data outside a box. Each box opens with its size and a four-letter type. A reader that meets a type it does not know can simply jump over it, which is how the format, first released in 2004, has grown without breaking older players.
Some boxes hold other boxes. The movie box, moov, holds one track box per stream, and inside each track sit the media header with its timescale and language, the handler that says whether the track is video or sound, and the sample table. The pictures themselves usually sit in a separate media data box, mdat, as an unstructured run of bytes. Nothing in mdat says where one frame ends and the next begins. Only the sample table knows.
Matroska takes a different route to the same goal. It is built on EBML, a binary cousin of XML defined in RFC 8794, where every element starts with a variable-length ID and a variable-length size. The first bits of each number say how many bytes it takes, so a reader never needs a fixed table of widths. RFC 9559, published in October 2024, turned the Matroska layout into an IETF standard. WebM is a deliberately narrow subset of it, limited to VP8, VP9 or AV1 video and Vorbis or Opus audio.
The Matroska names are friendlier than the four-letter codes. A Segment holds Info, with the TimestampScale and the duration, and Tracks, with one TrackEntry per stream, its CodecID and its CodecPrivate bytes. Clusters hold the frames as SimpleBlocks or BlockGroups. Cues, when present, are the seek index. A recorder that streams before it knows how long the recording will be may write a cluster with the size marked unknown; the reader then has to find the end by meeting the next cluster.
How a player finds a frame
To show the frame at 7.3 seconds, an MP4 player does arithmetic on the sample table. The decode-time table lists runs of samples and how many timescale ticks each lasts. The size table gives the byte count of every sample. The chunk tables say where groups of samples start in the file, with 32-bit offsets in one box and 64-bit offsets in another for files past 4 GB. Put together, they turn a time into a byte position without touching a single frame.
Those same tables measure the video more honestly than any label. Frame rate is not a field you trust; it is the spacing of the decode times. If every sample lasts the same number of ticks, the rate is constant and exact. If the spacing varies, as it does in many phone recordings and screen captures, the file has a variable frame rate, and the minimum, maximum and mean tell you how much it wanders.
Bitrate works the same way. The average is eight times the sum of the sample sizes, divided by the track’s duration. The peak is the most data that falls inside any one-second stretch of decode time. A streaming service cares about that peak far more than the average, because a buffer has to survive the busiest second, not the typical one.
Here is a worked example you can reproduce, because it is the file the viewer opens first. Its video track holds 288 samples, each lasting 512 ticks of a 12,288 tick per second clock. That is 24 frames per second, constant, for exactly 12 seconds. The 288 sizes add up to 8,130,973 bytes, so the average is 8,130,973 times 8, divided by 12, or 5.42 Mbit/s. The busiest one-second window starts at 6.0 seconds and holds 10.31 Mbit/s, almost twice the average, because the example has a stretch of fast motion there.
Nothing in that sum is estimated. Each size comes straight from the table, so two careful readers of the same file must reach the same answer, down to the last byte.
To report all of that, the reader took 4,801 bytes from an 8,341,187 byte file: about 0.058% of it. It read box headers, the movie box and the tables, and skipped the media data entirely. A file of many gigabytes costs barely more, because the index grows with the number of frames, not with their size. Matroska is a little more expensive, since its sizes live in the block headers spread through the clusters, so the viewer reads those headers one after another and jumps over each frame’s payload.
Keyframes, colour and rotation
Most frames in compressed video are described as changes to other frames. Only some can be decoded on their own, and those are the places a player can jump to. MP4 lists them in the sync sample box; a missing list means every sample stands alone, as audio usually does. Matroska marks a SimpleBlock with a key bit, and RFC 9559 says a frame that depends on others must carry a ReferenceBlock or lack that bit. In the example, keyframes sit at frames 1, 49, 97, 121, 145, 193 and 241, so the gaps are two seconds apart except around a cut at frame 121, where they shrink to one. Seeking can only land on those seven points.
Colour is described by three small numbers taken from a shared table of code points: the primaries, the transfer characteristics and the matrix. MP4 stores them in a colour box, Matroska in a Colour element, and RFC 9559 lists the values. Transfer 1 is the ordinary BT.709 curve. Transfer 16 is PQ and 18 is HLG, the two curves of high dynamic range video, so a reader can tell an HDR file from its flags alone. HDR files often add static light levels as well, MaxCLL and MaxFALL.
Rotation is the odd one out. A phone held upright usually records its pictures sideways and stores a flag that tells the player to turn them, a matrix in the MP4 track header or a roll angle in Matroska’s Projection element. Nothing in the pixels changes. That is why a clip can look correct in one player and lie on its side in another: the second player ignored the flag. A tool that copies the pixels but drops the flag does the same damage. Edit lists are a similar quiet instruction. The example’s audio track has one that skips its first 1,024 samples, 21.3 ms of encoder priming at 48 kHz, so sound and picture start together.
Codec strings pull these facts into one line a browser can test, such as avc1.640028 for High profile H.264 at level 4.0. RFC 6381 defines the form for H.264 and AAC, and the VP9 and AV1 bindings define theirs. A browser’s MediaCapabilities interface answers whether it can decode such a stream and whether that would be smooth and power efficient. MDN notes that a browser may report smooth and efficient playback before it has any statistics from the device, so that answer is a promise, not a measurement.
Even so, the codec string is the bridge between what a file is and what a particular device says it can do with it.
Fast start, and what the index cannot tell you
Where the index sits matters on the web. A movie box written after the media data forces a player to fetch the end of the file before it can show anything, and an incomplete download will not play at all. Moving the movie box to the front, often called fast start, lets playback begin while the rest arrives. The WebM guidelines make the same point for Matroska: put the Cues before the clusters so a browser can seek into data it has not yet downloaded.
Fragmented MP4 takes another path. It keeps a small movie box at the front and writes the sample tables in pieces, each movie fragment followed by its own media data. A reader must then walk every fragment to count the samples, which is why the viewer states a fragment limit whenever it stops early.
None of this is the same as judging quality. The container does not know whether a frame is blurred, blocky or badly exposed; only decoding can show that, and this approach decodes nothing. Some facts also live only inside the compressed stream. A WebM file without codec private data does not state its VP9 profile, and an encoder may write HDR flags into the bitstream but leave the container silent. When the index says nothing, the honest answer is not stated.
Within those limits the index is remarkably candid. It tells you the codec and its profile, the true frame timing, the exact bytes behind every second, where a player can seek, how the colour should be read and whether the file is ready for the web. All of it comes from a few kilobytes that sit in plain sight, written in layouts that open standards describe.
Sources
Every source consulted for this guide. Links checked October 25, 2026.
- RFC 9559: Matroska Media Container Format Specification RFC Editor (IETF)
- RFC 8794: Extensible Binary Meta Language RFC Editor (IETF)
- RFC 6381: The 'Codecs' and 'Profiles' Parameters for "Bucket" Media Types RFC Editor (IETF)
- Matroska Media Container Codec Specifications (draft-ietf-cellar-codec-21) IETF Datatracker
- WebM Container Guidelines The WebM Project
- VP Codec ISO Media File Format Binding The WebM Project
- AV1 Codec ISO Media File Format Binding Alliance for Open Media
- Encapsulation of Opus in ISO Base Media File Format Opus Codec project
- ISO Base Media File Format Library of Congress, Sustainability of Digital Formats
- MPEG-4 File Format, Version 2 Library of Congress, Sustainability of Digital Formats
- Codecs in common media types MDN Web Docs
- MediaCapabilities: decodingInfo() method MDN Web Docs
- ISO base media file format - Wikipedia Wikipedia
- MP4 file format - Wikipedia Wikipedia
- Matroska - Wikipedia Wikipedia
- WebM - Wikipedia Wikipedia
- Advanced Video Coding - Wikipedia Wikipedia
- High Efficiency Video Coding - Wikipedia Wikipedia
- High-dynamic-range television - Wikipedia Wikipedia
- Coding-independent code points - Wikipedia Wikipedia