aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-03-06 17:08:26 +0100
committermetamuffin <metamuffin@disroot.org>2026-03-06 17:08:26 +0100
commitd6287e2f54bd3ad22f970c0a3fe5230be00a592e (patch)
treeb4363deda59a1434f9126f8f56ae29cc46973f58
parent711f56963c114565a2be8848a6070b28a168c5ff (diff)
downloadjellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar
jellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar.bz2
jellything-d6287e2f54bd3ad22f970c0a3fe5230be00a592e.tar.zst
pasp and colr boxes for sample entry
-rw-r--r--remuxer/mp4/src/boxes.rs60
-rw-r--r--remuxer/src/muxers/mp4.rs15
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(