pub struct CmafVideoMuxer { /* private fields */ }Expand description
Stateful CMAF video segmenter for one AV1 rendition.
Driven by the pipeline:
- Construct with rendition dimensions + output dir + timescale.
- Call
add_packetfor each encoded packet from the encoder. The first packet’s OBU stream MUST contain a sequence header; the muxer extracts it and uses it forav1Cin the init.mp4 (written lazily on the firstflush_segmentcall). - Call
flush_segmentwhenever a CMAF fragment boundary is reached (the orchestrator decides when based on accumulated duration + the segment_duration knob). - After the last packet is added and flushed, call
finalizeto consume the muxer and get theCmafTrackManifest.
Segment files are named seg-00001.m4s, seg-00002.m4s, …
in the output dir.
Implementations§
Source§impl CmafVideoMuxer
impl CmafVideoMuxer
Sourcepub fn new(
output_dir: impl AsRef<Path>,
width: u32,
height: u32,
timescale: u32,
color_metadata: ColorMetadata,
) -> Result<Self>
pub fn new( output_dir: impl AsRef<Path>, width: u32, height: u32, timescale: u32, color_metadata: ColorMetadata, ) -> Result<Self>
Construct a new video muxer that writes init.mp4 + segments to
output_dir. Creates the directory if it doesn’t exist.
Equivalent to new_with_options(..., CmafVideoMuxerOptions::default()).
Sourcepub fn new_with_options(
output_dir: impl AsRef<Path>,
width: u32,
height: u32,
timescale: u32,
color_metadata: ColorMetadata,
options: CmafVideoMuxerOptions,
) -> Result<Self>
pub fn new_with_options( output_dir: impl AsRef<Path>, width: u32, height: u32, timescale: u32, color_metadata: ColorMetadata, options: CmafVideoMuxerOptions, ) -> Result<Self>
Construct a muxer with non-default options. See
CmafVideoMuxerOptions.
The helper-task path uses this to attach to an in-progress rung:
the helper’s muxer starts numbering segments at the helper’s
claim range start, advances tfdt to the corresponding decode
time, and skips the init segment write that the primary owns.
Sourcepub fn add_packet(
&mut self,
payload: Vec<u8>,
duration: u32,
is_keyframe: bool,
) -> Result<()>
pub fn add_packet( &mut self, payload: Vec<u8>, duration: u32, is_keyframe: bool, ) -> Result<()>
Add one encoded video packet to the current pending segment.
duration is in track-timescale ticks. is_keyframe must be
true for IDR / sync-sample packets — the muxer doesn’t peek
into the OBU stream to figure that out, and a wrong value
will produce a CMAF segment that doesn’t decode (the spec
requires every segment to start with a sync sample).
Sourcepub fn first_pending_is_keyframe(&self) -> bool
pub fn first_pending_is_keyframe(&self) -> bool
Whether the muxer is ready to flush a segment that starts on a
sync sample. The first sample in pending must be a keyframe.
CMAF requires every segment to begin with a sync sample
(§7.3.2.1), so the orchestrator should ensure this invariant
before calling flush_segment.
Sourcepub fn pending_duration_ticks(&self) -> u64
pub fn pending_duration_ticks(&self) -> u64
Total duration of pending samples in track-timescale ticks. The orchestrator uses this to decide when a segment has reached its target duration.
Sourcepub fn segments(&self) -> &[SegmentInfo]
pub fn segments(&self) -> &[SegmentInfo]
View of segments already flushed to disk. Each entry’s
sequence_number is the segment’s 1-based index; path is
the on-disk location. The helper-task path
(pipeline::cmaf::cmaf_transcode_rung_slice) reads this
between add_packet calls to detect “did the last add
trigger an auto-flush?” — when segments().len() grows, the
last entry is the newly-flushed segment.
Sourcepub fn clear_pending(&mut self)
pub fn clear_pending(&mut self)
Drop every sample currently in the pending buffer without
writing them to disk. Used by the helper-task path when its
claim has been shrunk by an attach_helper and the encoder’s
lookahead would otherwise produce a segment that conflicts
with whichever helper now owns that range.
Specifically: when a primary’s claim is shrunk from [0..N)
to [0..K), the primary’s encoder has already received
frames K*KI..K*KI+lookahead by the time the claim-shrink
is observed at the segment boundary. Those frames belong to
the helper that took [K..N). Discarding the muxer pending
- dropping the encoder is the cleanest way to ensure no stale segment file is written for the helper’s territory.
Sourcepub fn flush_segment(&mut self) -> Result<Option<SegmentInfo>>
pub fn flush_segment(&mut self) -> Result<Option<SegmentInfo>>
Flush pending samples to a new media segment file. Writes
init.mp4 first if it hasn’t been written yet (the av1C config
record needs the first packet’s sequence header). Returns the
segment’s metadata and clears the pending buffer.
No-op if pending is empty.
Sourcepub fn finalize(self) -> Result<CmafTrackManifest>
pub fn finalize(self) -> Result<CmafTrackManifest>
Finalize the muxer: ensures the init segment is on disk (covers the edge case where add_packet was called but flush_segment never was — e.g. an empty source), drops any non-flushed pending samples (caller should have flushed them), and returns the manifest.