Convert raw H.264 (.h264 / .264) to MP4
Raw H.264 files are the compressed video bitstream with no container around them - no timing, no audio, no index. Wave wraps them in MP4 with a proper timebase so every player understands what to do with the file.
What actually changes
A raw H.264 file (.h264, .264, or .avc depending on the tool that produced it) is a sequence of NAL (Network Abstraction Layer) units in Annex B format - start codes (00 00 00 01) delimiting each SPS / PPS / IDR / P / B frame. There is no container, no per-frame timestamp, and no audio track. Files like these come out of the reference H.264 encoder, ffmpeg's `-f h264` output, some hardware capture cards, and any tool that dumps the video bitstream without wrapping it.
Because the payload is exactly what MP4 stores internally (the sample table just points at these NAL units), the conversion is a re-mux with no re-encoding. Wave sniffs the leading bytes to confirm a genuine Annex B stream, forces ffmpeg's `-f h264` demuxer, and copies every NAL bit-for-bit into an MP4 container. A synthetic timebase is added (25 fps by default; adjustable via ffmpeg CLI if you need something else) because raw H.264 carries no timing of its own. Nothing about the picture changes.
The Annex B format was defined in the H.264 spec (ITU-T H.264 Annex B) precisely because streaming and broadcast workflows needed a way to send H.264 video over paths that lacked their own framing - satellite feeds, MPEG-2 Transport Stream payloads, or raw pipes between processes. The start-code prefix lets a demuxer find NAL boundaries by scanning bytes; MP4's in-container form (called length-prefixed AVC1 sample format) is a different byte layout of the same NAL contents, which is why the conversion between them is a pure repack rather than a decode-encode.
The trade-off of raw Annex B is that it carries no timing information whatsoever. Real timing (frame duration, presentation timestamps) has to come from an external source - either a wrapper container like MP4, or a companion timing file (rare in practice), or an educated assumption based on the encoding tool that produced the bitstream. Wave's 25 fps default matches broadcast PAL and the most common encoder default; sources at 30, 50, 60, or fractional rates need an explicit '-r' override in a command-line ffmpeg step.
Three steps.
-
01
Step 1
Drop your .h264 or .264 file onto the card.
-
02
Step 2
Wave inspects and shows Fast copy - the NAL units go straight into MP4.
-
03
Step 3
Convert and save. The output plays in any H.264-capable player.
Answers, specifically.
Why does raw H.264 even exist as a file format?
Because sometimes you want the codec output without container overhead. Encoder pipelines, streaming servers, and low-level analysis tools all produce raw bitstreams as an intermediate. The trade-off is that no consumer player wants to open one - all of them expect a container. Wrapping in MP4 is the standard fix.
The playback speed looks wrong. Why?
Because raw H.264 has no timebase, Wave assumes 25 fps. If the source was captured at 30, 60, or 120 fps, the MP4 will play at the wrong speed. In that case, re-mux from the command line with `ffmpeg -r 60 -i input.h264 -c copy output.mp4` to force the correct rate.
Can I combine an H.264 file with a separate audio track?
Not in the current Wave build. On the command line, `ffmpeg -i video.h264 -i audio.aac -c copy output.mp4` does it in one pass.
What is the difference between .h264, .264, and .avc?
None. They are three names for the same file. Different tools use different conventions - x264 writes .264 by default, ffmpeg writes .h264 with `-f h264`. Wave treats them identically.
What if my file is actually renamed MKV or MP4?
Wave sniffs the first four bytes for the Annex B start code before applying the `-f h264` hint. If the bytes do not match, Wave falls back to ffmpeg's auto-detection, so a renamed container still converts through its correct path.
What is the difference between Annex B and AVCC / length-prefixed?
Same NAL contents, different framing bytes. Annex B uses start codes (00 00 00 01) to delimit NALs; AVCC uses a 4-byte length prefix before each NAL, and the parameter sets (SPS / PPS) live in the container's codec configuration record. Converting between them is a byte-level repack, no re-encoding.
The MP4 plays but only my computer opens it. Why?
Some MP4 players are strict about H.264 profile constraints (level, entropy encoding, chroma format). Broadcast-flavoured raw H.264 sometimes uses High 4:2:2 or High 10 profile that iOS refuses. Check the source profile with Wave's inspect step; if it is anything above High 4:2:0, expect narrower playback.
Does the MP4 output play in the browser?
Yes for H.264 Baseline, Main, and High 4:2:0 profiles (which is 99% of raw H.264 files in the wild). More exotic profiles (High 10, High 4:2:2, High 4:4:4) render fine in some browsers but not others.