diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-03-06 17:08:26 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-03-06 17:08:26 +0100 |
| commit | d6287e2f54bd3ad22f970c0a3fe5230be00a592e (patch) | |
| tree | b4363deda59a1434f9126f8f56ae29cc46973f58 | |
| parent | 711f56963c114565a2be8848a6070b28a168c5ff (diff) | |
| download | jellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar jellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar.bz2 jellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar.zst | |
pasp and colr boxes for sample entry
| -rw-r--r-- | remuxer/mp4/src/boxes.rs | 60 | ||||
| -rw-r--r-- | remuxer/src/muxers/mp4.rs | 15 |
2 files changed, 75 insertions, 0 deletions
diff --git a/remuxer/mp4/src/boxes.rs b/remuxer/mp4/src/boxes.rs index f695d98..5a4e108 100644 --- a/remuxer/mp4/src/boxes.rs +++ b/remuxer/mp4/src/boxes.rs @@ -414,6 +414,12 @@ impl WriteBox for AVCSampleEntry<'_> { fn write(&self, buf: &mut Vec<u8>) { self.visual.write(buf); BoxW(buf).write(&self.config); + if let Some(colr) = &self.visual.colr { + BoxW(buf).write(colr); + } + if let Some(pasp) = &self.visual.pasp { + BoxW(buf).write(pasp); + } } } @@ -446,6 +452,8 @@ pub struct VisualSampleEntry { pub frame_count: u16, pub compressorname: [u8; 32], pub depth: u16, + pub pasp: Option<PixelAspectRatio>, + pub colr: Option<ColourInformation>, } impl WriteBox for VisualSampleEntry { const BOXTYPE: [u8; 4] = [0; 4]; @@ -476,6 +484,58 @@ impl Default for VisualSampleEntry { frame_count: 1, compressorname: [0; 32], depth: 0x0018, + pasp: None, + colr: None, + } + } +} + +pub struct PixelAspectRatio { + pub h_spacing: u32, + pub v_spacing: u32, +} +impl WriteBox for PixelAspectRatio { + const BOXTYPE: [u8; 4] = *b"pasp"; + fn write(&self, buf: &mut Vec<u8>) { + buf.extend(self.h_spacing.to_be_bytes()); + buf.extend(self.v_spacing.to_be_bytes()); + } +} + +pub enum ColourInformation { + OnScreenColours { + colour_primaries: u16, + transfer_charateristics: u16, + matrix_coefficients: u16, + full_range: bool, + }, + RestrictedICC, + UnrestrictedICC, +} +impl WriteBox for ColourInformation { + const BOXTYPE: [u8; 4] = *b"colr"; + fn write(&self, buf: &mut Vec<u8>) { + match self { + ColourInformation::OnScreenColours { + colour_primaries, + transfer_charateristics, + matrix_coefficients, + full_range, + } => { + buf.extend(b"nclx"); + buf.extend(colour_primaries.to_be_bytes()); + buf.extend(transfer_charateristics.to_be_bytes()); + buf.extend(matrix_coefficients.to_be_bytes()); + buf.push((*full_range as u8) << 7); + } + ColourInformation::RestrictedICC => { + buf.extend(b"rICC"); + todo!() + } + ColourInformation::UnrestrictedICC => { + buf.extend(b"prof"); + todo!() + } } } } diff --git a/remuxer/src/muxers/mp4.rs b/remuxer/src/muxers/mp4.rs index bd36789..bb89563 100644 --- a/remuxer/src/muxers/mp4.rs +++ b/remuxer/src/muxers/mp4.rs @@ -37,6 +37,11 @@ impl FragmentMuxer for MP4FragmentMuxer { // edts.write(EditList(&[])); // })); trak.write(Media(|mdia| { + mdia.write(MediaHeader { + duration: 0, + timescale: 1_000_000_000, + ..Default::default() + }); mdia.write(Handler { handler_type: match track.track_type { TrackType::Video => *b"vide", @@ -68,6 +73,16 @@ impl FragmentMuxer for MP4FragmentMuxer { }, width: video.pixel_width as u16, height: video.pixel_height as u16, + pasp: Some(PixelAspectRatio { + h_spacing: 1, + v_spacing: 1, + }), + colr: Some(ColourInformation::OnScreenColours { + colour_primaries: 1, + transfer_charateristics: 1, + matrix_coefficients: 1, + full_range: false, + }), ..Default::default() }, config: AVCConfiguration( |