1
0
Fork 0
mirror of https://github.com/alfg/mp4-rust.git synced 2024-05-08 03:22:59 +00:00

Proper handle display matrix (#72)

This commit is contained in:
Data Retriever 2022-05-25 00:32:31 +00:00 committed by GitHub
parent 084381bde5
commit 7218ada431
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 114 additions and 34 deletions

View file

@ -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<String> {
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<R: Read + Seek> ReadBox<&mut R> for MvhdBox {
};
let rate = FixedPointU16::new_raw(reader.read_u32::<BigEndian>()?);
let volume = FixedPointU8::new_raw(reader.read_u16::<BigEndian>()?);
reader.read_u16::<BigEndian>()?; // reserved = 0
reader.read_u64::<BigEndian>()?; // reserved = 0
let matrix = tkhd::Matrix {
a: reader.read_i32::<BigEndian>()?,
b: reader.read_i32::<BigEndian>()?,
u: reader.read_i32::<BigEndian>()?,
c: reader.read_i32::<BigEndian>()?,
d: reader.read_i32::<BigEndian>()?,
v: reader.read_i32::<BigEndian>()?,
x: reader.read_i32::<BigEndian>()?,
y: reader.read_i32::<BigEndian>()?,
w: reader.read_i32::<BigEndian>()?,
};
skip_bytes(reader, 24)?; // pre_defined = 0
let next_track_id = reader.read_u32::<BigEndian>()?;
skip_bytes_to(reader, start + size)?;
Ok(MvhdBox {
@ -103,6 +142,9 @@ impl<R: Read + Seek> ReadBox<&mut R> for MvhdBox {
timescale,
duration,
rate,
volume,
matrix,
next_track_id,
})
}
}
@ -129,8 +171,25 @@ impl<W: Write> WriteBox<&mut W> for MvhdBox {
}
writer.write_u32::<BigEndian>(self.rate.raw_value())?;
// XXX volume, ...
write_zeros(writer, 76)?;
writer.write_u16::<BigEndian>(self.volume.raw_value())?;
writer.write_u16::<BigEndian>(0)?; // reserved = 0
writer.write_u64::<BigEndian>(0)?; // reserved = 0
writer.write_i32::<BigEndian>(self.matrix.a)?;
writer.write_i32::<BigEndian>(self.matrix.b)?;
writer.write_i32::<BigEndian>(self.matrix.u)?;
writer.write_i32::<BigEndian>(self.matrix.c)?;
writer.write_i32::<BigEndian>(self.matrix.d)?;
writer.write_i32::<BigEndian>(self.matrix.v)?;
writer.write_i32::<BigEndian>(self.matrix.x)?;
writer.write_i32::<BigEndian>(self.matrix.y)?;
writer.write_i32::<BigEndian>(self.matrix.w)?;
write_zeros(writer, 24)?; // pre_defined = 0
writer.write_u32::<BigEndian>(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();

View file

@ -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<String> {
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<R: Read + Seek> ReadBox<&mut R> for TkhdBox {
reader.read_u16::<BigEndian>()?; // reserved
let matrix = Matrix {
a: reader.read_i32::<byteorder::LittleEndian>()?,
a: reader.read_i32::<BigEndian>()?,
b: reader.read_i32::<BigEndian>()?,
u: reader.read_i32::<BigEndian>()?,
c: reader.read_i32::<BigEndian>()?,
@ -205,7 +240,7 @@ impl<W: Write> WriteBox<&mut W> for TkhdBox {
writer.write_u16::<BigEndian>(0)?; // reserved
writer.write_i32::<byteorder::LittleEndian>(self.matrix.a)?;
writer.write_i32::<BigEndian>(self.matrix.a)?;
writer.write_i32::<BigEndian>(self.matrix.b)?;
writer.write_i32::<BigEndian>(self.matrix.u)?;
writer.write_i32::<BigEndian>(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),
};