@@ -956,6 +956,8 @@ impl FileTypeBox {
956
956
/// Movie header box 'mvhd'.
957
957
#[ derive( Debug ) ]
958
958
struct MovieHeaderBox {
959
+ creation : u64 ,
960
+ modification : u64 ,
959
961
pub timescale : u32 ,
960
962
#[ allow( dead_code) ] // See https://github.com/mozilla/mp4parse-rust/issues/340
961
963
duration : u64 ,
@@ -1503,9 +1505,14 @@ pub enum XmlBox {
1503
1505
BinaryXmlBox ( TryVec < u8 > ) ,
1504
1506
}
1505
1507
1508
+ #[ derive( Debug ) ]
1509
+ pub struct UtcSecondsSince1904 ( pub u64 ) ;
1510
+
1506
1511
/// Internal data structures.
1507
1512
#[ derive( Debug , Default ) ]
1508
1513
pub struct MediaContext {
1514
+ pub creation : Option < UtcSecondsSince1904 > ,
1515
+ pub modification : Option < UtcSecondsSince1904 > ,
1509
1516
pub timescale : Option < MediaTimeScale > ,
1510
1517
/// Tracks found in the file.
1511
1518
pub tracks : TryVec < Track > ,
@@ -4123,8 +4130,14 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
4123
4130
if mvhd. timescale == 0 {
4124
4131
return Status :: MvhdBadTimescale . into ( ) ;
4125
4132
}
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
+ }
4128
4141
}
4129
4142
4130
4143
/// Parse a Movie Box
@@ -4134,6 +4147,8 @@ fn parse_mvhd<T: Read>(f: &mut BMFFBox<T>) -> Result<Option<MediaTimeScale>> {
4134
4147
/// such as with tests/test_case_1185230.mp4.
4135
4148
fn read_moov < T : Read > ( f : & mut BMFFBox < T > , context : Option < MediaContext > ) -> Result < MediaContext > {
4136
4149
let MediaContext {
4150
+ mut creation,
4151
+ mut modification,
4137
4152
mut timescale,
4138
4153
mut tracks,
4139
4154
mut mvex,
@@ -4147,7 +4162,11 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
4147
4162
while let Some ( mut b) = iter. next_box ( ) ? {
4148
4163
match b. head . name {
4149
4164
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) ?;
4151
4170
}
4152
4171
BoxType :: TrackBox => {
4153
4172
let mut track = Track :: new ( tracks. len ( ) ) ;
@@ -4178,6 +4197,8 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
4178
4197
}
4179
4198
4180
4199
Ok ( MediaContext {
4200
+ creation,
4201
+ modification,
4181
4202
timescale,
4182
4203
tracks,
4183
4204
mvex,
@@ -4490,28 +4511,32 @@ fn read_ftyp<T: Read>(src: &mut BMFFBox<T>) -> Result<FileTypeBox> {
4490
4511
/// Parse an mvhd box.
4491
4512
fn read_mvhd < T : Read > ( src : & mut BMFFBox < T > ) -> Result < MovieHeaderBox > {
4492
4513
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;
4493
4523
match version {
4494
4524
// 64 bit creation and modification times.
4495
4525
1 => {
4496
- skip ( src, 16 ) ?;
4526
+ creation = be_u64 ( src) ?;
4527
+ modification = be_u64 ( src) ?;
4497
4528
}
4498
4529
// 32 bit creation and modification times.
4499
4530
0 => {
4500
- skip ( src, 8 ) ?;
4531
+ creation = to_u64 ( be_u32 ( src) ?) ;
4532
+ modification = to_u64 ( be_u32 ( src) ?) ;
4501
4533
}
4502
4534
_ => return Status :: MvhdBadVersion . into ( ) ,
4503
4535
}
4504
4536
let timescale = be_u32 ( src) ?;
4505
4537
let duration = match version {
4506
4538
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) ?) ,
4515
4540
_ => unreachable ! ( "Should have returned Status::MvhdBadVersion" ) ,
4516
4541
} ;
4517
4542
// Skip remaining valid fields.
@@ -4520,6 +4545,8 @@ fn read_mvhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieHeaderBox> {
4520
4545
// Padding could be added in some contents.
4521
4546
skip_box_remain ( src) ?;
4522
4547
Ok ( MovieHeaderBox {
4548
+ creation,
4549
+ modification,
4523
4550
timescale,
4524
4551
duration,
4525
4552
} )
0 commit comments