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.
BitReader 🔒
MSB-first bit reader over an unescaped RBSP, with Exp-Golomb decode for SPS parsing.
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.
PendingSample 🔒
One buffered access unit awaiting its duration (known when the next one arrives).
TrackConfig
A codec’s contribution to the init segment: its stsd sample entry (with decoder configuration record) plus the display dimensions for tkhd.

Enums§

TrakMedia 🔒
The tkhd fields that differ by media: a video track states its display size, an audio track its volume.

Constants§

AUDIO_FLUSH_SAMPLES 🔒
Audio packets buffered before they go out as a fragment of their own: half a second of 20 ms packets.
DEFAULT_LAST_DURATION 🔒
Fallback duration for the final buffered sample when only one frame was ever written (no observed inter-frame delta to take a median of): 1/30 s.
MATRIX_IDENTITY 🔒
The unity transformation matrix mvhd and tkhd carry: 0x00010000, 0x00010000, and 0x40000000 on the diagonal (16.16 fixed point for the first two, 2.30 for the last).
OPUS_TIMESCALE
Opus in ISOBMFF runs its track at Opus’s own 48 kHz whatever the input rate.
TIMESCALE 🔒
90 kHz: the conventional H.264 track timescale, exactly representing common frame intervals.

Functions§

dinf 🔒
The data reference every track shares: an empty url entry flagged self-contained.
mk_box 🔒
mk_full_box 🔒
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).
stbl 🔒
A sample table holding only the sample entry: every sample lives in a fragment.
trak 🔒
One trak: tkhd (enabled, in_movie) with the display size or, for audio, the volume; mdhd at timescale; the handler; then the media header given and the sample table.
trex 🔒
A trex whose fragments state their own durations, sizes, and flags unless default_duration is set, which the audio track’s fixed packet length is.
unescape_rbsp 🔒
Unescape an H.264 RBSP: drop the emulation-prevention byte from every 00 00 03 run.