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§
- Audio
Track Config - The audio track’s
stsdsample entry. - Built
Sample - One converted access unit ready for the fragment writer.
- Fragment
Writer - Codec-agnostic fMP4 fragment writer:
ftyp+moovonce, then onemoof+mdatpair per video sample, each anchored at its wall-clock decode time viatfdt, and one per batch of audio samples. - H264
Sample Builder - 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
avc1sample entry. - Mp4Stats
- Aggregate counters reported when the writer finishes.
- Track
Config - A codec’s contribution to the init segment: its
stsdsample entry (with decoder configuration record) plus the display dimensions fortkhd.
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
Opussample entry with itsdOpsrecord, 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).