H264 File Documentation


Summary

An .h264 (or .264) file is a raw H.264/AVC video elementary stream: the encoder’s compressed output with no container, no audio and no timing, the kind a CCTV camera or DVR exports. Its MIME type is video/h264. Because it has no container, generic players often show no duration or refuse it; the standard fix is a lossless remux into MP4 or MKV with ffmpeg (-c copy), which wraps the existing frames without re-encoding.

Technical details

FeatureValue
Full nameRaw H.264 / AVC video elementary stream
File extension.h264, .264
MIME typevideo/h264
Format typeRaw elementary stream (no container, no audio, no timing)
Byte formatAnnex-B: NAL units separated by start-code prefixes
StandardITU-T Rec. H.264 / ISO/IEC 14496-10 (MPEG-4 Part 10, AVC)
Finalised2003
DeveloperITU-T VCEG and ISO/IEC MPEG (Joint Video Team)
Open standardYes (published ITU-T / ISO-IEC specification)
Start-code prefix00 00 00 01 (4-byte) or 00 00 01 (3-byte)
Typical first NAL unitsSPS (0x67), then PPS (0x68), then IDR slice (0x65)
AudioNone; video only by definition
Timing / indexNone; frame rate supplied at remux time
Typical sourceCCTV/IP cameras, DVRs, NVRs, encoder dumps
Lossless container targets.mp4, .mkv, .mov, .ts
Related extensions.264, .mp4, .mkv, .ts
Specification URLitu.int/rec/T-REC-H.264
File signature (start code)
00 00 00 01 67

Offset 0. The bytes 00 00 00 01 are an Annex-B NAL unit start-code prefix (a 3-byte 00 00 01 is also valid), not a container magic number. The byte that follows is the first NAL unit header: 0x67 marks a Sequence Parameter Set (nal_unit_type 7), usually followed by 0x68 (PPS) and 0x65 (an IDR keyframe slice). There is no ftyp/RIFF header, no audio and no duration, which is why container-expecting players reject the file.

What is an .h264 file?

H.264, also called AVC and MPEG-4 Part 10, is a video compression standard finalised in 2003 by the Joint Video Team of ITU-T VCEG and ISO/IEC MPEG, published as ITU-T Rec. H.264 and ISO/IEC 14496-10. An .h264 or .264 file is a raw H.264 elementary stream: nothing but the encoder’s output, a sequence of coded units with no wrapper around them. That is the key distinction from a normal video file. There is no container (no MP4, MKV or MOV boxes), no audio track, and no frame-timing or seek index, so a player that expects a container often shows no duration or refuses to open the file at all.

These files come overwhelmingly from surveillance hardware. CCTV and IP cameras, DVRs and NVRs frequently export clips as raw .264/.h264, and encoding pipelines produce them when a tool dumps a codec’s output directly. The rest of this page describes what those bytes actually are: the NAL unit structure, the start-code framing, and the parameter sets that a decoder needs before it can render a single frame.

The NAL unit: the atom of an H.264 stream

H.264 organises its output into NAL units (Network Abstraction Layer units). Each NAL unit is a self-contained packet: a one-byte header followed by a payload called the RBSP (Raw Byte Sequence Payload). The whole file is just a run of these units back to back. The one-byte header packs three fields:

bit  7    forbidden_zero_bit   must be 0
bits 6-5  nal_ref_idc          0 = disposable, non-zero = reference
bits 4-0  nal_unit_type        1-31, what this NAL carries

So a header byte of 0x67 is 0 11 00111: forbidden bit 0, nal_ref_idc 3 (a high-priority reference), and nal_unit_type 7, which is a Sequence Parameter Set. A byte of 0x65 is nal_ref_idc 3 with type 5, an IDR (instantaneous decoder refresh) slice, the H.264 name for a clean keyframe. A byte of 0x41 is type 1, a non-IDR coded slice (a P or B frame). Reading just the low five bits of each post-start-code byte tells you the shape of the whole stream.

nal_unit_typeHeader byte (ref_idc 3 / 0)Meaning
10x41 / 0x01Coded slice of a non-IDR picture (P/B frame)
50x65 / —Coded slice of an IDR picture (keyframe)
60x06SEI, supplemental enhancement information
70x67Sequence Parameter Set (SPS)
80x68Picture Parameter Set (PPS)
90x09Access unit delimiter

Annex-B framing and start-code emulation prevention

A raw stream stored on disk uses the Annex-B byte-stream format, which is what makes an .h264 file parseable without any index. Each NAL unit is prefixed with a start code: the three bytes 00 00 01, usually preceded by one or more zero bytes so the common prefix is the four bytes 00 00 00 01. A decoder finds NAL boundaries simply by scanning for this pattern.

That scanning creates a problem: the payload could accidentally contain 00 00 01 and be mistaken for a boundary. H.264 solves it with emulation prevention. When encoding the RBSP, any sequence of 00 00 00, 00 00 01, 00 00 02 or 00 00 03 has an emulation-prevention byte 0x03 inserted, so 00 00 01 becomes 00 00 03 01 on the wire. The decoder strips every 0x03 that follows two zero bytes to recover the true payload. This is why you occasionally see stray 03 bytes in a hex dump of an H.264 stream that are not part of the actual coded data.

SPS and PPS: the parameters a decoder needs first

A decoder cannot render anything until it has read two parameter sets, which is why a well-formed raw stream begins with them. The Sequence Parameter Set (type 7, byte 0x67) describes the whole video sequence: profile and level (in the two bytes right after the header, e.g. profile_idc then constraint flags then level_idc), the frame width and height (coded as pic_width_in_mbs_minus1 and pic_height_in_map_units_minus1 in 16-pixel macroblock units, adjusted by cropping fields), the chroma format, and how frame numbering and reference pictures work. The Picture Parameter Set (type 8, byte 0x68) describes per-picture decoding choices: the entropy coder (CAVLC or CABAC), whether weighted prediction is used, the initial quantisation parameter, and which SPS it references.

Both parameter sets use Exp-Golomb coding for their fields, a variable-length bit encoding, so they are not byte-aligned after the header and must be parsed bit by bit. The practical consequence for these files: if a camera exports a stream that omits the SPS/PPS at the start (some emit them only once and a mid-stream capture misses them), the file will not decode until those parameter sets are supplied, which is a common reason a raw .264 fails where the same footage inside the camera plays fine.

Why there is no timing, audio or index

The elementary stream carries coded pictures and their decoding relationships, but it does not carry a clock. There are no presentation timestamps, no frame-rate field that a player must honour, and no table mapping frame number to file offset. In a normal video these live in the container: an MP4 keeps them in its sample tables, an MPEG-TS stream carries PCR and PTS in its packet headers. A bare .h264 has none of that, so when a player does open it, it must guess the frame rate, and seeking is approximate because it has to scan for the next start code. There is also no audio, by definition: H.264 codes video only, so a surveillance clip with sound stored this way either kept the audio in a separate file or used a real container.

Remuxing the stream into a container

The correct repair for a raw .h264 is not to re-encode it but to remux it: copy the existing NAL units, unchanged, into a container that adds the missing timing and index. Because the coded frames are untouched, this is lossless and near-instant. With ffmpeg, ffmpeg -i in.h264 -c copy out.mp4 wraps the stream into MP4; when muxing into MP4 the tool converts the Annex-B start codes into the length-prefixed AVCC format that MP4 sample tables use, and lifts the SPS/PPS into the avcC configuration box. If the stream carries no usable timing, supplying a frame rate fixes playback speed: ffmpeg -framerate 25 -i in.h264 -c copy out.mp4. MKV is the most forgiving target when MP4 muxing complains about an odd stream: ffmpeg -i in.h264 -c copy out.mkv. VLC can also play a raw stream directly, sometimes after selecting its H.264 demuxer, because it runs the same start-code scan internally.

FAQ

Why is there no sound in my .h264 file?

A raw H.264 stream codes video only; it has no audio track by design. If the recording had sound, it was stored separately or in a real container. Remuxing the .h264 alone will never add audio because the bytes simply do not contain any.

Why does my remuxed video play too fast or too slow?

The elementary stream carries no timing, so the muxer guessed a frame rate. Re-remux with the camera’s real rate, for example ffmpeg -framerate 25 -i in.h264 -c copy out.mp4, using whatever fps the DVR recorded at.

What is the difference between .h264 and .mp4?

.h264 is the bare compressed video: NAL units in Annex-B framing, nothing else. MP4 is a container that holds that same H.264 video plus audio, timestamps and a seek index. Putting the raw stream into an MP4 (remuxing) is exactly what turns it into a normal, portable video.

References