pub struct AudioInfo {
pub codec: String,
pub sample_rate: u32,
pub channels: u16,
pub timescale: u32,
pub asc_bytes: Vec<u8>,
pub codec_private: Vec<u8>,
}Expand description
Parameters required to bolt an audio track onto Av1Mp4Muxer.
Four codec families are supported:
- AAC-LC (Squad-18, task #63 v1): mono or stereo, sample_rate as the
mdhd timescale per ISO/IEC 14496-14 standard practice, and the
AudioSpecificConfig surfaced verbatim from the demuxer (see
demux::AudioTrack::asc) so HE-AAC / xHE-AAC signalling bits survive the passthrough intact. Sample entry:mp4a+esds. - Opus (Squad-23): mono or stereo, sample_rate is the source’s
InputSampleRate(typically 48000),mdhdtimescale is pinned at 48000 per RFC 7845 §3 (Opus internally always operates at 48 kHz). Sample entry:Opus(4cc per RFC 7845 §4.4 — capital O) +dOps(Opus-Specific Box per §4.5). TheOpusHeadbody bytes are carried incodec_privateand emitted verbatim insidedOps. - AC-3 / Dolby Digital (Squad-26): up to 5.1 channels, sample_rate
from the source’s syncframe (32 / 44.1 / 48 kHz). Sample entry:
ac-3+dac3(ETSI TS 102 366 §F.4 / Annex F). The 3-bytedac3body is carried incodec_privateand emitted verbatim. - E-AC-3 / Dolby Digital Plus (Squad-26): up to 5.1 channels in v1
scope (single independent substream). Sample entry:
ec-3+dec3(ETSI TS 102 366 §F.6). Thedec3body is carried incodec_privateand emitted verbatim.
Discriminator: codec field. "aac" → AAC path; "opus" → Opus path;
"ac3" → AC-3 path; "eac3" → E-AC-3 path. Anything else is rejected
at with_audio() time.
Fields§
§codec: StringHuman-readable codec tag. Muxer accepts "aac" (case-insensitive)
and "opus" (case-insensitive). Anything else is rejected with a
clear error — this is intentional (no stubs).
sample_rate: u32Audio sample rate in Hz. For AAC: typically 44100 / 48000; doubles as
the mdhd timescale. For Opus: the source’s InputSampleRate
(informational; the mdhd timescale is pinned to 48000 per RFC 7845
regardless of this value).
channels: u16Channel count. Both codecs support 1 (mono) and 2 (stereo) only; the muxer bails on other values.
timescale: u32Audio timescale in ticks per second. AAC: equals sample_rate.
Opus: caller should pass 48000 (RFC 7845); the muxer additionally
validates this for the Opus path.
asc_bytes: Vec<u8>AudioSpecificConfig bytes verbatim from the demuxer (AAC only).
Embedded into the esds box’s DecoderSpecificInfo (tag 0x05)
payload. Empty for non-AAC codecs.
codec_private: Vec<u8>Codec-private body bytes (Opus / AC-3 / E-AC-3). For Opus this MUST
be the RFC 7845 §5.1 OpusHead payload (the same bytes a WebM/MKV
CodecPrivate element would carry; see RFC 7845 §5.2 for the
MKV mapping). Emitted verbatim as the body of the dOps box
inside the Opus sample entry. For AC-3 this carries the 3-byte
dac3 body (ETSI TS 102 366 §F.4); for E-AC-3 the variable-size
dec3 body (§F.6). Empty for AAC.
Layout (RFC 7845 §5.1, 19 bytes minimum for ChannelMappingFamily=0
with the 8-byte ‘OpusHead’ magic prefix; the magic is NOT carried
in dOps — only the post-magic body, which is 11 bytes minimum):
Versionu8 = 1 (in OpusHead; mapped to 0 in dOps per §4.5)OutputChannelCountu8PreSkipu16 LE (in OpusHead; converted to BE for dOps per §4.5)InputSampleRateu32 LE (LE in OpusHead, BE in dOps)OutputGaini16 LE (LE in OpusHead, BE in dOps)ChannelMappingFamilyu8- (if family != 0: 1 + 1 + N additional bytes)
The byte-order conversion between OpusHead (Ogg LE convention) and
dOps (ISOBMFF BE convention) is handled by build_dops in mux.rs.
Callers should pass the OpusHead bytes (LE numeric fields) — that’s
the form the MKV / WebM demuxer surfaces directly out of CodecPrivate.
Implementations§
Source§impl AudioInfo
impl AudioInfo
Sourcepub fn aac_lc(sample_rate: u32, channels: u16, asc_bytes: Vec<u8>) -> Self
pub fn aac_lc(sample_rate: u32, channels: u16, asc_bytes: Vec<u8>) -> Self
Convenience constructor for the AAC-LC path. Mirrors Squad-18’s original API surface so existing AAC call sites stay terse.
Sourcepub fn opus(
input_sample_rate: u32,
channels: u16,
codec_private: Vec<u8>,
) -> Self
pub fn opus( input_sample_rate: u32, channels: u16, codec_private: Vec<u8>, ) -> Self
Convenience constructor for the Opus path. Pins timescale to 48000
per RFC 7845 §3 — Opus is internally always 48 kHz so the mdhd
timescale, not the source’s nominal InputSampleRate, is what
drives sample-duration math on every player.
Sourcepub fn ac3(sample_rate: u32, channels: u16, dac3_body: Vec<u8>) -> Self
pub fn ac3(sample_rate: u32, channels: u16, dac3_body: Vec<u8>) -> Self
Convenience constructor for the AC-3 (Dolby Digital) passthrough
path (Squad-26). codec_private carries the 3-byte dac3 body
payload (ETSI TS 102 366 §F.4) the muxer writes verbatim into the
dac3 box. mdhd timescale = sample_rate (48000 / 44100 / 32000) —
AC-3 doesn’t have Opus’s “internally fixed at 48 kHz” rule.
Sourcepub fn eac3(sample_rate: u32, channels: u16, dec3_body: Vec<u8>) -> Self
pub fn eac3(sample_rate: u32, channels: u16, dec3_body: Vec<u8>) -> Self
Convenience constructor for the E-AC-3 (Dolby Digital Plus) passthrough
path (Squad-26). codec_private carries the dec3 body payload
(ETSI TS 102 366 §F.6) — variable size based on substream count;
minimum ~5 bytes for the single-independent-substream case.