From 1b74ecfa0b678f91362b80677004990ac2bae417 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Mon, 14 Sep 2026 09:29:41 +0200 Subject: [PATCH] stsd: add roundtrip support for unknown codec Co-authored-by: Claude Sonnet 5 --- src/error.rs | 3 --- src/moov/trak/mdia/minf/stbl/stsd/mod.rs | 32 +++++++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/error.rs b/src/error.rs index 6b17107..6bcbe81 100644 --- a/src/error.rs +++ b/src/error.rs @@ -68,9 +68,6 @@ pub enum Error { #[error("invalid parameter combination: {0}")] InvalidCombination(&'static str), - - #[error("unknown codec in sample description box")] - UnknownCodec, } pub type Result = std::result::Result; diff --git a/src/moov/trak/mdia/minf/stbl/stsd/mod.rs b/src/moov/trak/mdia/minf/stbl/stsd/mod.rs index 8c637ff..ab9a8bf 100644 --- a/src/moov/trak/mdia/minf/stbl/stsd/mod.rs +++ b/src/moov/trak/mdia/minf/stbl/stsd/mod.rs @@ -207,7 +207,18 @@ impl Decode for Codec { impl Encode for Codec { fn encode(&self, buf: &mut B) -> Result<()> { match self { - Self::Unknown(..) => Err(Error::UnknownCodec), + Self::Unknown(kind, body) => { + let start = buf.len(); + 0u32.encode(buf)?; // size placeholder + kind.encode(buf)?; + buf.append_slice(body); + + let size: u32 = (buf.len() - start) + .try_into() + .map_err(|_| Error::TooLarge(*kind))?; + buf.set_slice(start, &size.to_be_bytes()); + Ok(()) + } Self::Avc1(atom) => atom.encode(buf), Self::Hev1(atom) => atom.encode(buf), Self::Hvc1(atom) => atom.encode(buf), @@ -287,21 +298,18 @@ mod tests { } #[test] - - fn unknown_codec_not_emitted() { - use crate::{Codec, Encode, FourCC, Stsd}; + fn unknown_codec_roundtrip() { + use crate::{Codec, Decode, Encode, FourCC, Stsd}; let stsd = Stsd { codecs: vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])], }; - assert_eq!( - stsd.codecs, - vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])] - ); + let mut output = Vec::new(); - assert!(matches!( - stsd.encode(&mut output), - Err(crate::Error::UnknownCodec) - )); + stsd.encode(&mut output) + .expect("failed to encode unknown codec"); + + let decoded = Stsd::decode(&mut output.as_slice()).expect("failed to decode stsd"); + assert_eq!(decoded, stsd); } }