Skip to main content

Module mp4

Module mp4 

Source
Expand description

Pure-Rust fragmented-MP4 (fMP4) muxer for the built-in recorder.

Hand-rolled rather than pulled in as a dependency for two reasons: libavformat would be a hard runtime dependency of every build, and the pure-Rust mp4 crates only write moov-trailing progressive files, which lose everything on a crash. Fragmented MP4 needs no trailer and no seeking — each moof+mdat pair is self-contained — so a file truncated by a crash or SIGKILL stays playable up to the last fragment, and the writer works on any Write sink.

Timestamps are caller-supplied wall-clock microseconds (damage-driven capture emits sparse, irregular frames), carried at a 90 kHz track timescale with one sample per fragment: tfdt anchors every sample at its true capture time, so variable framerate needs no constant-rate lie. The sample duration is only known once the NEXT frame arrives, so one sample is always buffered and flushed a frame behind (a clean stop closes it with the median observed duration); on SIGKILL at most that one buffered frame is lost — every fragment already written remains playable.

Codec support is deliberately split: [annexb_to_sample] and the H.264-specific parameter-set capture live in H264SampleBuilder, while the fragment/box writer below is codec-agnostic (bytes + sync flag + timestamps + a ready-made stsd sample entry). HEVC or AV1 recording later means a new sample builder emitting an hvc1/av01 entry, not a new muxer.

An optional Opus audio track (track 2) takes packets with their decode time on the 48 kHz clock and each one’s duration from its own TOC byte; they go out in fragments of their own, so a still desktop that yields no video fragment still keeps the file growing.

Structs§

AudioTrackConfig
The audio track’s stsd sample entry.
BuiltSample
One converted access unit ready for the fragment writer.
FragmentWriter
Codec-agnostic fMP4 fragment writer: ftyp+moov once, then one moof+mdat pair per video sample, each anchored at its wall-clock decode time via tfdt, and one per batch of audio samples.
H264SampleBuilder
H.264-specific front end: captures SPS/PPS from the stream, gates output on the first IDR, converts Annex-B access units to AVCC samples, and builds the avc1 sample entry.
Mp4Stats
Aggregate counters reported when the writer finishes.
TrackConfig
A codec’s contribution to the init segment: its stsd sample entry (with decoder configuration record) plus the display dimensions for tkhd.

Constants§

OPUS_TIMESCALE
Opus in ISOBMFF runs its track at Opus’s own 48 kHz whatever the input rate.

Functions§

opus_packet_samples
The 48 kHz samples an Opus packet decodes to, from its TOC byte: the configuration’s frame duration times the frame count its code carries.
opus_sample_entry
The Opus sample entry with its dOps record, the head’s own fields.
parse_sps_dimensions
Coded frame dimensions parsed out of an H.264 SPS NAL (with its NAL header byte).
split_annexb
Split an Annex-B elementary stream into NAL payloads (start codes removed, emulation prevention bytes kept — the RBSP layer is only unescaped where a parser needs it).