@@ -266,6 +266,8 @@ struct FileTypeBox {
266266/// Movie header box 'mvhd'.
267267#[ derive( Debug ) ]
268268struct MovieHeaderBox {
269+ creation : u64 ,
270+ modification : u64 ,
269271 pub timescale : u32 ,
270272 duration : u64 ,
271273}
@@ -777,9 +779,14 @@ pub enum XmlBox {
777779 BinaryXmlBox ( TryVec < u8 > ) ,
778780}
779781
782+ #[ derive( Debug ) ]
783+ pub struct UtcSecondsSince1904 ( pub u64 ) ;
784+
780785/// Internal data structures.
781786#[ derive( Debug , Default ) ]
782787pub struct MediaContext {
788+ pub creation : Option < UtcSecondsSince1904 > ,
789+ pub modification : Option < UtcSecondsSince1904 > ,
783790 pub timescale : Option < MediaTimeScale > ,
784791 /// Tracks found in the file.
785792 pub tracks : TryVec < Track > ,
@@ -2866,16 +2873,12 @@ pub fn read_mp4<T: Read>(f: &mut T) -> Result<MediaContext> {
28662873 context. ok_or ( Error :: NoMoov )
28672874}
28682875
2869- /// Parse a Movie Header Box
2870- /// See ISOBMFF (ISO 14496-12:2015) § 8.2.2
2871- fn parse_mvhd < T : Read > ( f : & mut BMFFBox < T > ) -> Result < Option < MediaTimeScale > > {
2872- let mvhd = read_mvhd ( f) ?;
2873- debug ! ( "{:?}" , mvhd) ;
2876+ fn validate_timescale ( mvhd : & MovieHeaderBox ) -> Result < Option < MediaTimeScale > > {
28742877 if mvhd. timescale == 0 {
28752878 return Err ( Error :: InvalidData ( "zero timescale in mdhd" ) ) ;
2879+ } else {
2880+ Ok ( Some ( MediaTimeScale ( u64:: from ( mvhd. timescale ) ) ) )
28762881 }
2877- let timescale = Some ( MediaTimeScale ( u64:: from ( mvhd. timescale ) ) ) ;
2878- Ok ( timescale)
28792882}
28802883
28812884/// Parse a Movie Box
@@ -2885,6 +2888,8 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
28852888/// such as with tests/test_case_1185230.mp4.
28862889fn read_moov < T : Read > ( f : & mut BMFFBox < T > , context : Option < MediaContext > ) -> Result < MediaContext > {
28872890 let MediaContext {
2891+ mut creation,
2892+ mut modification,
28882893 mut timescale,
28892894 mut tracks,
28902895 mut mvex,
@@ -2898,7 +2903,11 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
28982903 while let Some ( mut b) = iter. next_box ( ) ? {
28992904 match b. head . name {
29002905 BoxType :: MovieHeaderBox => {
2901- timescale = parse_mvhd ( & mut b) ?;
2906+ let mvhd = read_mvhd ( & mut b) ?;
2907+ debug ! ( "{:?}" , mvhd) ;
2908+ creation = Some ( UtcSecondsSince1904 ( mvhd. creation ) ) ;
2909+ modification = Some ( UtcSecondsSince1904 ( mvhd. modification ) ) ;
2910+ timescale = validate_timescale ( & mvhd) ?;
29022911 }
29032912 BoxType :: TrackBox => {
29042913 let mut track = Track :: new ( tracks. len ( ) ) ;
@@ -2929,6 +2938,8 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
29292938 }
29302939
29312940 Ok ( MediaContext {
2941+ creation,
2942+ modification,
29322943 timescale,
29332944 tracks,
29342945 mvex,
@@ -3204,33 +3215,39 @@ fn read_ftyp<T: Read>(src: &mut BMFFBox<T>) -> Result<FileTypeBox> {
32043215/// Parse an mvhd box.
32053216fn read_mvhd < T : Read > ( src : & mut BMFFBox < T > ) -> Result < MovieHeaderBox > {
32063217 let ( version, _) = read_fullbox_extra ( src) ?;
3218+ let to_u64 = |n| {
3219+ if n == std:: u32:: MAX {
3220+ std:: u64:: MAX
3221+ } else {
3222+ u64:: from ( n)
3223+ }
3224+ } ;
3225+ let creation;
3226+ let modification;
32073227 match version {
32083228 // 64 bit creation and modification times.
32093229 1 => {
3210- skip ( src, 16 ) ?;
3230+ creation = be_u64 ( src) ?;
3231+ modification = be_u64 ( src) ?;
32113232 }
32123233 // 32 bit creation and modification times.
32133234 0 => {
3214- skip ( src, 8 ) ?;
3235+ creation = to_u64 ( be_u32 ( src) ?) ;
3236+ modification = to_u64 ( be_u32 ( src) ?) ;
32153237 }
32163238 _ => return Err ( Error :: InvalidData ( "unhandled mvhd version" ) ) ,
32173239 }
32183240 let timescale = be_u32 ( src) ?;
32193241 let duration = match version {
32203242 1 => be_u64 ( src) ?,
3221- 0 => {
3222- let d = be_u32 ( src) ?;
3223- if d == std:: u32:: MAX {
3224- std:: u64:: MAX
3225- } else {
3226- u64:: from ( d)
3227- }
3228- }
3243+ 0 => to_u64 ( be_u32 ( src) ?) ,
32293244 _ => return Err ( Error :: InvalidData ( "unhandled mvhd version" ) ) ,
32303245 } ;
32313246 // Skip remaining fields.
32323247 skip ( src, 80 ) ?;
32333248 Ok ( MovieHeaderBox {
3249+ creation,
3250+ modification,
32343251 timescale,
32353252 duration,
32363253 } )
0 commit comments