@@ -956,6 +956,8 @@ impl FileTypeBox {
956956/// Movie header box 'mvhd'.
957957#[ derive( Debug ) ]
958958struct MovieHeaderBox {
959+ creation : u64 ,
960+ modification : u64 ,
959961 pub timescale : u32 ,
960962 #[ allow( dead_code) ] // See https://github.com/mozilla/mp4parse-rust/issues/340
961963 duration : u64 ,
@@ -1503,9 +1505,14 @@ pub enum XmlBox {
15031505 BinaryXmlBox ( TryVec < u8 > ) ,
15041506}
15051507
1508+ #[ derive( Debug ) ]
1509+ pub struct UtcSecondsSince1904 ( pub u64 ) ;
1510+
15061511/// Internal data structures.
15071512#[ derive( Debug , Default ) ]
15081513pub struct MediaContext {
1514+ pub creation : Option < UtcSecondsSince1904 > ,
1515+ pub modification : Option < UtcSecondsSince1904 > ,
15091516 pub timescale : Option < MediaTimeScale > ,
15101517 /// Tracks found in the file.
15111518 pub tracks : TryVec < Track > ,
@@ -4123,8 +4130,14 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
41234130 if mvhd. timescale == 0 {
41244131 return Status :: MvhdBadTimescale . into ( ) ;
41254132 }
4126- let timescale = Some ( MediaTimeScale ( u64:: from ( mvhd. timescale ) ) ) ;
4127- Ok ( timescale)
4133+ }
4134+
4135+ fn validate_timescale ( mvhd : & MovieHeaderBox ) -> Result < Option < MediaTimeScale > > {
4136+ if mvhd. timescale == 0 {
4137+ Err ( Error :: InvalidData ( "zero timescale in mdhd" ) )
4138+ } else {
4139+ Ok ( Some ( MediaTimeScale ( u64:: from ( mvhd. timescale ) ) ) )
4140+ }
41284141}
41294142
41304143/// Parse a Movie Box
@@ -4134,6 +4147,8 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
41344147/// such as with tests/test_case_1185230.mp4.
41354148fn read_moov < T : Read > ( f : & mut BMFFBox < T > , context : Option < MediaContext > ) -> Result < MediaContext > {
41364149 let MediaContext {
4150+ mut creation,
4151+ mut modification,
41374152 mut timescale,
41384153 mut tracks,
41394154 mut mvex,
@@ -4147,7 +4162,11 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
41474162 while let Some ( mut b) = iter. next_box ( ) ? {
41484163 match b. head . name {
41494164 BoxType :: MovieHeaderBox => {
4150- timescale = parse_mvhd ( & mut b) ?;
4165+ let mvhd = read_mvhd ( & mut b) ?;
4166+ debug ! ( "{:?}" , mvhd) ;
4167+ creation = Some ( UtcSecondsSince1904 ( mvhd. creation ) ) ;
4168+ modification = Some ( UtcSecondsSince1904 ( mvhd. modification ) ) ;
4169+ timescale = validate_timescale ( & mvhd) ?;
41514170 }
41524171 BoxType :: TrackBox => {
41534172 let mut track = Track :: new ( tracks. len ( ) ) ;
@@ -4178,6 +4197,8 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
41784197 }
41794198
41804199 Ok ( MediaContext {
4200+ creation,
4201+ modification,
41814202 timescale,
41824203 tracks,
41834204 mvex,
@@ -4490,28 +4511,32 @@ fn read_ftyp<T: Read>(src: &mut BMFFBox<T>) -> Result<FileTypeBox> {
44904511/// Parse an mvhd box.
44914512fn read_mvhd < T : Read > ( src : & mut BMFFBox < T > ) -> Result < MovieHeaderBox > {
44924513 let ( version, _) = read_fullbox_extra ( src) ?;
4514+ let to_u64 = |n| {
4515+ if n == std:: u32:: MAX {
4516+ std:: u64:: MAX
4517+ } else {
4518+ u64:: from ( n)
4519+ }
4520+ } ;
4521+ let creation;
4522+ let modification;
44934523 match version {
44944524 // 64 bit creation and modification times.
44954525 1 => {
4496- skip ( src, 16 ) ?;
4526+ creation = be_u64 ( src) ?;
4527+ modification = be_u64 ( src) ?;
44974528 }
44984529 // 32 bit creation and modification times.
44994530 0 => {
4500- skip ( src, 8 ) ?;
4531+ creation = to_u64 ( be_u32 ( src) ?) ;
4532+ modification = to_u64 ( be_u32 ( src) ?) ;
45014533 }
45024534 _ => return Status :: MvhdBadVersion . into ( ) ,
45034535 }
45044536 let timescale = be_u32 ( src) ?;
45054537 let duration = match version {
45064538 1 => be_u64 ( src) ?,
4507- 0 => {
4508- let d = be_u32 ( src) ?;
4509- if d == u32:: MAX {
4510- u64:: MAX
4511- } else {
4512- u64:: from ( d)
4513- }
4514- }
4539+ 0 => to_u64 ( be_u32 ( src) ?) ,
45154540 _ => unreachable ! ( "Should have returned Status::MvhdBadVersion" ) ,
45164541 } ;
45174542 // Skip remaining valid fields.
@@ -4520,6 +4545,8 @@ fn read_mvhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieHeaderBox> {
45204545 // Padding could be added in some contents.
45214546 skip_box_remain ( src) ?;
45224547 Ok ( MovieHeaderBox {
4548+ creation,
4549+ modification,
45234550 timescale,
45244551 duration,
45254552 } )
0 commit comments