From 7218ada4313ff41bb246a8608f471c1a137ba4cc Mon Sep 17 00:00:00 2001 From: Data Retriever <100052557+data-retriever@users.noreply.github.com> Date: Wed, 25 May 2022 00:32:31 +0000 Subject: [PATCH] Proper handle display matrix (#72) --- src/mp4box/mvhd.rs | 75 ++++++++++++++++++++++++++++++++++++++++++---- src/mp4box/tkhd.rs | 73 ++++++++++++++++++++++++++------------------ 2 files changed, 114 insertions(+), 34 deletions(-) diff --git a/src/mp4box/mvhd.rs b/src/mp4box/mvhd.rs index 5232019..41dcf03 100644 --- a/src/mp4box/mvhd.rs +++ b/src/mp4box/mvhd.rs @@ -1,6 +1,6 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use serde::Serialize; use std::io::{Read, Seek, Write}; -use serde::{Serialize}; use crate::mp4box::*; @@ -15,6 +15,12 @@ pub struct MvhdBox { #[serde(with = "value_u32")] pub rate: FixedPointU16, + #[serde(with = "value_u8")] + pub volume: FixedPointU8, + + pub matrix: tkhd::Matrix, + + pub next_track_id: u32, } impl MvhdBox { @@ -44,6 +50,9 @@ impl Default for MvhdBox { timescale: 1000, duration: 0, rate: FixedPointU16::new(1), + matrix: tkhd::Matrix::default(), + volume: FixedPointU8::new(1), + next_track_id: 1, } } } @@ -62,8 +71,16 @@ impl Mp4Box for MvhdBox { } fn summary(&self) -> Result { - let s = format!("creation_time={} timescale={} duration={} rate={}", - self.creation_time, self.timescale, self.duration, self.rate.value()); + let s = format!( + "creation_time={} timescale={} duration={} rate={} volume={}, matrix={}, next_track_id={}", + self.creation_time, + self.timescale, + self.duration, + self.rate.value(), + self.volume.value(), + self.matrix, + self.next_track_id + ); Ok(s) } } @@ -93,6 +110,28 @@ impl ReadBox<&mut R> for MvhdBox { }; let rate = FixedPointU16::new_raw(reader.read_u32::()?); + let volume = FixedPointU8::new_raw(reader.read_u16::()?); + + reader.read_u16::()?; // reserved = 0 + + reader.read_u64::()?; // reserved = 0 + + let matrix = tkhd::Matrix { + a: reader.read_i32::()?, + b: reader.read_i32::()?, + u: reader.read_i32::()?, + c: reader.read_i32::()?, + d: reader.read_i32::()?, + v: reader.read_i32::()?, + x: reader.read_i32::()?, + y: reader.read_i32::()?, + w: reader.read_i32::()?, + }; + + skip_bytes(reader, 24)?; // pre_defined = 0 + + let next_track_id = reader.read_u32::()?; + skip_bytes_to(reader, start + size)?; Ok(MvhdBox { @@ -103,6 +142,9 @@ impl ReadBox<&mut R> for MvhdBox { timescale, duration, rate, + volume, + matrix, + next_track_id, }) } } @@ -129,8 +171,25 @@ impl WriteBox<&mut W> for MvhdBox { } writer.write_u32::(self.rate.raw_value())?; - // XXX volume, ... - write_zeros(writer, 76)?; + writer.write_u16::(self.volume.raw_value())?; + + writer.write_u16::(0)?; // reserved = 0 + + writer.write_u64::(0)?; // reserved = 0 + + writer.write_i32::(self.matrix.a)?; + writer.write_i32::(self.matrix.b)?; + writer.write_i32::(self.matrix.u)?; + writer.write_i32::(self.matrix.c)?; + writer.write_i32::(self.matrix.d)?; + writer.write_i32::(self.matrix.v)?; + writer.write_i32::(self.matrix.x)?; + writer.write_i32::(self.matrix.y)?; + writer.write_i32::(self.matrix.w)?; + + write_zeros(writer, 24)?; // pre_defined = 0 + + writer.write_u32::(self.next_track_id)?; Ok(size) } @@ -152,6 +211,9 @@ mod tests { timescale: 1000, duration: 634634, rate: FixedPointU16::new(1), + volume: FixedPointU8::new(1), + matrix: tkhd::Matrix::default(), + next_track_id: 1, }; let mut buf = Vec::new(); src_box.write_box(&mut buf).unwrap(); @@ -176,6 +238,9 @@ mod tests { timescale: 1000, duration: 634634, rate: FixedPointU16::new(1), + volume: FixedPointU8::new(1), + matrix: tkhd::Matrix::default(), + next_track_id: 1, }; let mut buf = Vec::new(); src_box.write_box(&mut buf).unwrap(); diff --git a/src/mp4box/tkhd.rs b/src/mp4box/tkhd.rs index b222300..e57f44d 100644 --- a/src/mp4box/tkhd.rs +++ b/src/mp4box/tkhd.rs @@ -1,6 +1,6 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use serde::Serialize; use std::io::{Read, Seek, Write}; -use serde::{Serialize}; use crate::mp4box::*; @@ -51,7 +51,7 @@ impl Default for TkhdBox { } } -#[derive(Debug, Clone, PartialEq, Default, Serialize)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Matrix { pub a: i32, pub b: i32, @@ -64,6 +64,33 @@ pub struct Matrix { pub w: i32, } +impl std::fmt::Display for Matrix { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{:#x} {:#x} {:#x} {:#x} {:#x} {:#x} {:#x} {:#x} {:#x}", + self.a, self.b, self.u, self.c, self.d, self.v, self.x, self.y, self.w + ) + } +} + +impl Default for Matrix { + fn default() -> Self { + Self { + // unity matrix according to ISO/IEC 14496-12:2005(E) + a: 0x00010000, + b: 0, + u: 0, + c: 0, + d: 0x00010000, + v: 0, + x: 0, + y: 0, + w: 0x40000000, + } + } +} + impl TkhdBox { pub fn get_type(&self) -> BoxType { BoxType::TkhdBox @@ -103,9 +130,17 @@ impl Mp4Box for TkhdBox { } fn summary(&self) -> Result { - let s = format!("creation_time={} track_id={} duration={} layer={} volume={} width={} height={}", - self.creation_time, self.track_id, self.duration, self.layer, - self.volume.value(), self.width.value(), self.height.value()); + let s = format!( + "creation_time={} track_id={} duration={} layer={} volume={} matrix={} width={} height={}", + self.creation_time, + self.track_id, + self.duration, + self.layer, + self.volume.value(), + self.matrix, + self.width.value(), + self.height.value() + ); Ok(s) } } @@ -142,7 +177,7 @@ impl ReadBox<&mut R> for TkhdBox { reader.read_u16::()?; // reserved let matrix = Matrix { - a: reader.read_i32::()?, + a: reader.read_i32::()?, b: reader.read_i32::()?, u: reader.read_i32::()?, c: reader.read_i32::()?, @@ -205,7 +240,7 @@ impl WriteBox<&mut W> for TkhdBox { writer.write_u16::(0)?; // reserved - writer.write_i32::(self.matrix.a)?; + writer.write_i32::(self.matrix.a)?; writer.write_i32::(self.matrix.b)?; writer.write_i32::(self.matrix.u)?; writer.write_i32::(self.matrix.c)?; @@ -240,17 +275,7 @@ mod tests { layer: 0, alternate_group: 0, volume: FixedPointU8::new(1), - matrix: Matrix { - a: 0x00010000, - b: 0, - u: 0, - c: 0, - d: 0x00010000, - v: 0, - x: 0, - y: 0, - w: 0x40000000, - }, + matrix: Matrix::default(), width: FixedPointU16::new(512), height: FixedPointU16::new(288), }; @@ -279,17 +304,7 @@ mod tests { layer: 0, alternate_group: 0, volume: FixedPointU8::new(1), - matrix: Matrix { - a: 0x00010000, - b: 0, - u: 0, - c: 0, - d: 0x00010000, - v: 0, - x: 0, - y: 0, - w: 0x40000000, - }, + matrix: Matrix::default(), width: FixedPointU16::new(512), height: FixedPointU16::new(288), };