You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mp4Sink records an Opus track of any channel count OpusEncoder can mint — one to eight — so a surround or ambisonic rig can be recorded, not just a mono or stereo microphone.
What we do today
Mp4Sink records one- and two-channel Opus tracks and refuses three to eight by name, naming the container rather than the codec:
the opus track on <link> carries N channels, which this writer cannot describe: an Opus sample entry with more than 2 channels needs channel mapping family 1, and mp4-atom writes family 0 only. The encoder mints such a stream; recording it does not yet follow
OpusEncoder is unaffected — it mints and encodes 1–8 channels today (opus_stream_layout.rs carries libopus's vorbis_mappings table for family 1), and OpusDecoder decodes them. Only the container write is missing.
Why we're moving away from it
mp4-atom 0.15 — 0.15.0 is the latest published release as of 2026-09-03 — cannot express mapping family 1:
Dops::encode_body writes ChannelMappingFamily as a hardcoded 0u8 and carries no stream count, coupled count or channel mapping table.
Dops::decode_body returns Error::Unsupported("OPUS channel mapping") for any non-zero family, so even a correctly hand-written family-1 track would not re-parse through the same crate the container-bytes tests use.
Codec::Unknown(FourCC) carries only the four-character code, not a payload, so a hand-built Opus sample entry cannot be placed into a typed Stsd.
Opus-in-ISOBMFF §4.3.2 requires dOps.OutputChannelCount to match the identification header and permits exactly one Opus Specific Box per sample entry, so there is no second entry to fall back to.
Options
Contribute family-1 dOps upstream to mp4-atom and take the released version — cleanest, and the crate is MIT/Apache-2.0.
Fork and pin by rev — engine doctrine allows a rev-pinned git dep, but it adds a second vendored fork to carry beside tatolab-vulkanalia.
Hand-write the dOps bytes and patch the ancestor box sizes — rejected on 2026-09-03 as the "hand-written box writer" the recording rung already rejected as a maintenance burden and no capability.
Option 1 is the recommendation.
Not blocking
examples/camera-audio-recorder (the rung's showcase) is mono or stereo, so nothing in the current milestone waits on this. Owner ruling 2026-09-03 during #2127: refuse by name now, track the gap.
Where it is written down
runtime/streamlib-media-builtins/src/mp4_track_sample_entry.rs — HIGHEST_CHANNEL_COUNT_THIS_CONTAINER_WRITER_PLACES and the refusal, with the reason in its doc comment.
docs/plan/ARCHITECTURE.md §Media I/O — the DECIDED entry "Three to eight channels record no Opus track yet", which is where the gap now lives.
Original body, before the 2026-09-07 tracker reconcile
The two citations of docs/plan/changes/opus-mp4-recording-rung.md were repointed: that file
was folded into the plan and archived on 2026-09-03, so the path no longer resolves. Nothing
else changed — the ask, the refusal text, the options and the recommendation are untouched.
What we want
Mp4Sink records an Opus track of any channel count OpusEncoder can mint — one to eight — so a surround or ambisonic rig can be recorded, not just a mono or stereo microphone.
What we do today
Mp4Sink records one- and two-channel Opus tracks and refuses three to eight by name, naming the container rather than the codec:
the opus track on <link> carries N channels, which this writer cannot describe: an Opus sample entry with more than 2 channels needs channel mapping family 1, and mp4-atom writes family 0 only. The encoder mints such a stream; recording it does not yet follow
OpusEncoder is unaffected — it mints and encodes 1–8 channels today (opus_stream_layout.rs carries libopus's vorbis_mappings table for family 1), and OpusDecoder decodes them. Only the container write is missing.
Why we're moving away from it
mp4-atom 0.15 — 0.15.0 is the latest published release as of 2026-09-03 — cannot express mapping family 1:
Dops::encode_body writes ChannelMappingFamily as a hardcoded 0u8 and carries no stream count, coupled count or channel mapping table.
Dops::decode_body returns Error::Unsupported("OPUS channel mapping") for any non-zero family, so even a correctly hand-written family-1 track would not re-parse through the same crate the container-bytes tests use.
Codec::Unknown(FourCC) carries only the four-character code, not a payload, so a hand-built Opus sample entry cannot be placed into a typed Stsd.
Opus-in-ISOBMFF §4.3.2 requires dOps.OutputChannelCount to match the identification header and permits exactly one Opus Specific Box per sample entry, so there is no second entry to fall back to.
Options
Contribute family-1 dOps upstream to mp4-atom and take the released version — cleanest, and the crate is MIT/Apache-2.0.
Fork and pin by rev — engine doctrine allows a rev-pinned git dep, but it adds a second vendored fork to carry beside tatolab-vulkanalia.
Hand-write the dOps bytes and patch the ancestor box sizes — rejected on 2026-09-03 as the "hand-written box writer" docs/plan/changes/opus-mp4-recording-rung.md already rejected as a maintenance burden and no capability.
Option 1 is the recommendation.
Not blocking
examples/camera-audio-recorder (the rung's showcase) is mono or stereo, so nothing in the current milestone waits on this. Owner ruling 2026-09-03 during #2127: refuse by name now, track the gap.
Where it is written down
runtime/streamlib-media-builtins/src/mp4_track_sample_entry.rs — HIGHEST_CHANNEL_COUNT_THIS_CONTAINER_WRITER_PLACES and the refusal, with the reason in its doc comment.
docs/plan/changes/opus-mp4-recording-rung.md — the DECIDED bullet recording the gap.
What we want
Mp4Sinkrecords an Opus track of any channel countOpusEncodercan mint — one to eight — so a surround or ambisonic rig can be recorded, not just a mono or stereo microphone.What we do today
Mp4Sinkrecords one- and two-channel Opus tracks and refuses three to eight by name, naming the container rather than the codec:OpusEncoderis unaffected — it mints and encodes 1–8 channels today (opus_stream_layout.rscarries libopus'svorbis_mappingstable for family 1), andOpusDecoderdecodes them. Only the container write is missing.Why we're moving away from it
mp4-atom0.15 — 0.15.0 is the latest published release as of 2026-09-03 — cannot express mapping family 1:Dops::encode_bodywritesChannelMappingFamilyas a hardcoded0u8and carries no stream count, coupled count or channel mapping table.Dops::decode_bodyreturnsError::Unsupported("OPUS channel mapping")for any non-zero family, so even a correctly hand-written family-1 track would not re-parse through the same crate the container-bytes tests use.Codec::Unknown(FourCC)carries only the four-character code, not a payload, so a hand-builtOpussample entry cannot be placed into a typedStsd.Opus-in-ISOBMFF §4.3.2 requires
dOps.OutputChannelCountto match the identification header and permits exactly one Opus Specific Box per sample entry, so there is no second entry to fall back to.Options
dOpsupstream tomp4-atomand take the released version — cleanest, and the crate is MIT/Apache-2.0.rev-pinned git dep, but it adds a second vendored fork to carry besidetatolab-vulkanalia.dOpsbytes and patch the ancestor box sizes — rejected on 2026-09-03 as the "hand-written box writer" the recording rung already rejected as a maintenance burden and no capability.Option 1 is the recommendation.
Not blocking
examples/camera-audio-recorder(the rung's showcase) is mono or stereo, so nothing in the current milestone waits on this. Owner ruling 2026-09-03 during #2127: refuse by name now, track the gap.Where it is written down
runtime/streamlib-media-builtins/src/mp4_track_sample_entry.rs—HIGHEST_CHANNEL_COUNT_THIS_CONTAINER_WRITER_PLACESand the refusal, with the reason in its doc comment.docs/plan/ARCHITECTURE.md§Media I/O — the DECIDED entry "Three to eight channels record no Opus track yet", which is where the gap now lives.docs/plan/changes/archive/2026-09-03-opus-mp4-recording-rung.md— the change that recorded it, folded and archived 2026-09-03 (ship PR docs(plan): ship opus-mp4-recording-rung — §Media I/O gains the Opus pair and Mp4Sink #2146).a_channel_count_needing_mapping_family_one_is_refused_naming_the_container.Original body, before the 2026-09-07 tracker reconcile
The two citations of
docs/plan/changes/opus-mp4-recording-rung.mdwere repointed: that filewas folded into the plan and archived on 2026-09-03, so the path no longer resolves. Nothing
else changed — the ask, the refusal text, the options and the recommendation are untouched.
What we want
Mp4Sinkrecords an Opus track of any channel countOpusEncodercan mint — one to eight — so a surround or ambisonic rig can be recorded, not just a mono or stereo microphone.What we do today
Mp4Sinkrecords one- and two-channel Opus tracks and refuses three to eight by name, naming the container rather than the codec:OpusEncoderis unaffected — it mints and encodes 1–8 channels today (opus_stream_layout.rscarries libopus'svorbis_mappingstable for family 1), andOpusDecoderdecodes them. Only the container write is missing.Why we're moving away from it
mp4-atom0.15 — 0.15.0 is the latest published release as of 2026-09-03 — cannot express mapping family 1:Dops::encode_bodywritesChannelMappingFamilyas a hardcoded0u8and carries no stream count, coupled count or channel mapping table.Dops::decode_bodyreturnsError::Unsupported("OPUS channel mapping")for any non-zero family, so even a correctly hand-written family-1 track would not re-parse through the same crate the container-bytes tests use.Codec::Unknown(FourCC)carries only the four-character code, not a payload, so a hand-builtOpussample entry cannot be placed into a typedStsd.Opus-in-ISOBMFF §4.3.2 requires
dOps.OutputChannelCountto match the identification header and permits exactly one Opus Specific Box per sample entry, so there is no second entry to fall back to.Options
dOpsupstream tomp4-atomand take the released version — cleanest, and the crate is MIT/Apache-2.0.rev-pinned git dep, but it adds a second vendored fork to carry besidetatolab-vulkanalia.dOpsbytes and patch the ancestor box sizes — rejected on 2026-09-03 as the "hand-written box writer"docs/plan/changes/opus-mp4-recording-rung.mdalready rejected as a maintenance burden and no capability.Option 1 is the recommendation.
Not blocking
examples/camera-audio-recorder(the rung's showcase) is mono or stereo, so nothing in the current milestone waits on this. Owner ruling 2026-09-03 during #2127: refuse by name now, track the gap.Where it is written down
runtime/streamlib-media-builtins/src/mp4_track_sample_entry.rs—HIGHEST_CHANNEL_COUNT_THIS_CONTAINER_WRITER_PLACESand the refusal, with the reason in its doc comment.docs/plan/changes/opus-mp4-recording-rung.md— the DECIDED bullet recording the gap.a_channel_count_needing_mapping_family_one_is_refused_naming_the_container.