@@ -6,8 +6,7 @@ use crate::meta::MetaBox;
6
6
use crate :: * ;
7
7
8
8
#[ derive( Debug ) ]
9
- pub struct Mp4Reader < R > {
10
- reader : R ,
9
+ pub struct Mp4Header {
11
10
pub ftyp : FtypBox ,
12
11
pub moov : MoovBox ,
13
12
pub moofs : Vec < MoofBox > ,
@@ -17,8 +16,8 @@ pub struct Mp4Reader<R> {
17
16
size : u64 ,
18
17
}
19
18
20
- impl < R : Read + Seek > Mp4Reader < R > {
21
- pub fn read_header ( mut reader : R , size : u64 ) -> Result < Self > {
19
+ impl Mp4Header {
20
+ pub fn read < R : Read + Seek > ( reader : & mut R , size : u64 ) -> Result < Self > {
22
21
let start = reader. stream_position ( ) ?;
23
22
24
23
let mut ftyp = None ;
@@ -30,7 +29,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
30
29
let mut current = start;
31
30
while current < size {
32
31
// Get box header.
33
- let header = BoxHeader :: read ( & mut reader) ?;
32
+ let header = BoxHeader :: read ( reader) ?;
34
33
let BoxHeader { name, size : s } = header;
35
34
if s > size {
36
35
return Err ( Error :: InvalidData (
@@ -46,30 +45,30 @@ impl<R: Read + Seek> Mp4Reader<R> {
46
45
// Match and parse the atom boxes.
47
46
match name {
48
47
BoxType :: FtypBox => {
49
- ftyp = Some ( FtypBox :: read_box ( & mut reader, s) ?) ;
48
+ ftyp = Some ( FtypBox :: read_box ( reader, s) ?) ;
50
49
}
51
50
BoxType :: FreeBox => {
52
- skip_box ( & mut reader, s) ?;
51
+ skip_box ( reader, s) ?;
53
52
}
54
53
BoxType :: MdatBox => {
55
- skip_box ( & mut reader, s) ?;
54
+ skip_box ( reader, s) ?;
56
55
}
57
56
BoxType :: MoovBox => {
58
- moov = Some ( MoovBox :: read_box ( & mut reader, s) ?) ;
57
+ moov = Some ( MoovBox :: read_box ( reader, s) ?) ;
59
58
}
60
59
BoxType :: MoofBox => {
61
60
let moof_offset = reader. stream_position ( ) ? - 8 ;
62
- let moof = MoofBox :: read_box ( & mut reader, s) ?;
61
+ let moof = MoofBox :: read_box ( reader, s) ?;
63
62
moofs. push ( moof) ;
64
63
moof_offsets. push ( moof_offset) ;
65
64
}
66
65
BoxType :: EmsgBox => {
67
- let emsg = EmsgBox :: read_box ( & mut reader, s) ?;
66
+ let emsg = EmsgBox :: read_box ( reader, s) ?;
68
67
emsgs. push ( emsg) ;
69
68
}
70
69
_ => {
71
70
// XXX warn!()
72
- skip_box ( & mut reader, s) ?;
71
+ skip_box ( reader, s) ?;
73
72
}
74
73
}
75
74
current = reader. stream_position ( ) ?;
@@ -118,8 +117,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
118
117
}
119
118
}
120
119
121
- Ok ( Mp4Reader {
122
- reader,
120
+ Ok ( Mp4Header {
123
121
ftyp : ftyp. unwrap ( ) ,
124
122
moov : moov. unwrap ( ) ,
125
123
moofs,
@@ -129,11 +127,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
129
127
} )
130
128
}
131
129
132
- pub fn read_fragment_header < FR : Read + Seek > (
133
- & self ,
134
- mut reader : FR ,
135
- size : u64 ,
136
- ) -> Result < Mp4Reader < FR > > {
130
+ pub fn read_fragment < R : Read + Seek > ( & self , reader : & mut R , size : u64 ) -> Result < Self > {
137
131
let start = reader. stream_position ( ) ?;
138
132
139
133
let mut moofs = Vec :: new ( ) ;
@@ -142,7 +136,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
142
136
let mut current = start;
143
137
while current < size {
144
138
// Get box header.
145
- let header = BoxHeader :: read ( & mut reader) ?;
139
+ let header = BoxHeader :: read ( reader) ?;
146
140
let BoxHeader { name, size : s } = header;
147
141
if s > size {
148
142
return Err ( Error :: InvalidData (
@@ -158,17 +152,17 @@ impl<R: Read + Seek> Mp4Reader<R> {
158
152
// Match and parse the atom boxes.
159
153
match name {
160
154
BoxType :: MdatBox => {
161
- skip_box ( & mut reader, s) ?;
155
+ skip_box ( reader, s) ?;
162
156
}
163
157
BoxType :: MoofBox => {
164
158
let moof_offset = reader. stream_position ( ) ? - 8 ;
165
- let moof = MoofBox :: read_box ( & mut reader, s) ?;
159
+ let moof = MoofBox :: read_box ( reader, s) ?;
166
160
moofs. push ( moof) ;
167
161
moof_offsets. push ( moof_offset) ;
168
162
}
169
163
_ => {
170
164
// XXX warn!()
171
- skip_box ( & mut reader, s) ?;
165
+ skip_box ( reader, s) ?;
172
166
}
173
167
}
174
168
current = reader. stream_position ( ) ?;
@@ -204,8 +198,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
204
198
}
205
199
}
206
200
207
- Ok ( Mp4Reader {
208
- reader,
201
+ Ok ( Mp4Header {
209
202
ftyp : self . ftyp . clone ( ) ,
210
203
moov : self . moov . clone ( ) ,
211
204
moofs,
@@ -215,10 +208,12 @@ impl<R: Read + Seek> Mp4Reader<R> {
215
208
} )
216
209
}
217
210
211
+ #[ inline]
218
212
pub fn size ( & self ) -> u64 {
219
213
self . size
220
214
}
221
215
216
+ #[ inline]
222
217
pub fn major_brand ( & self ) -> & FourCC {
223
218
& self . ftyp . major_brand
224
219
}
@@ -255,9 +250,14 @@ impl<R: Read + Seek> Mp4Reader<R> {
255
250
}
256
251
}
257
252
258
- pub fn read_sample ( & mut self , track_id : u32 , sample_id : u32 ) -> Result < Option < Mp4Sample > > {
253
+ pub fn read_sample < R : Read + Seek > (
254
+ & mut self ,
255
+ reader : & mut R ,
256
+ track_id : u32 ,
257
+ sample_id : u32 ,
258
+ ) -> Result < Option < Mp4Sample > > {
259
259
if let Some ( track) = self . tracks . get ( & track_id) {
260
- track. read_sample ( & mut self . reader , sample_id)
260
+ track. read_sample ( reader, sample_id)
261
261
} else {
262
262
Err ( Error :: TrakNotFound ( track_id) )
263
263
}
@@ -270,9 +270,7 @@ impl<R: Read + Seek> Mp4Reader<R> {
270
270
Err ( Error :: TrakNotFound ( track_id) )
271
271
}
272
272
}
273
- }
274
273
275
- impl < R > Mp4Reader < R > {
276
274
pub fn metadata ( & self ) -> impl Metadata < ' _ > {
277
275
self . moov . udta . as_ref ( ) . and_then ( |udta| {
278
276
udta. meta . as_ref ( ) . and_then ( |meta| match meta {
@@ -282,3 +280,80 @@ impl<R> Mp4Reader<R> {
282
280
} )
283
281
}
284
282
}
283
+
284
+ #[ derive( Debug ) ]
285
+ pub struct Mp4Reader < R > {
286
+ reader : R ,
287
+ pub header : Mp4Header ,
288
+ }
289
+
290
+ impl < R : Read + Seek > Mp4Reader < R > {
291
+ pub fn read_header ( mut reader : R , size : u64 ) -> Result < Self > {
292
+ Ok ( Mp4Reader {
293
+ header : Mp4Header :: read ( & mut reader, size) ?,
294
+ reader,
295
+ } )
296
+ }
297
+
298
+ pub fn read_fragment_header < FR : Read + Seek > (
299
+ & self ,
300
+ mut reader : FR ,
301
+ size : u64 ,
302
+ ) -> Result < Mp4Reader < FR > > {
303
+ Ok ( Mp4Reader {
304
+ header : self . header . read_fragment ( & mut reader, size) ?,
305
+ reader,
306
+ } )
307
+ }
308
+
309
+ pub fn size ( & self ) -> u64 {
310
+ self . header . size ( )
311
+ }
312
+
313
+ pub fn major_brand ( & self ) -> & FourCC {
314
+ self . header . major_brand ( )
315
+ }
316
+
317
+ pub fn minor_version ( & self ) -> u32 {
318
+ self . header . minor_version ( )
319
+ }
320
+
321
+ pub fn compatible_brands ( & self ) -> & [ FourCC ] {
322
+ self . header . compatible_brands ( )
323
+ }
324
+
325
+ pub fn duration ( & self ) -> Duration {
326
+ self . header . duration ( )
327
+ }
328
+
329
+ pub fn timescale ( & self ) -> u32 {
330
+ self . header . timescale ( )
331
+ }
332
+
333
+ pub fn is_fragmented ( & self ) -> bool {
334
+ self . header . is_fragmented ( )
335
+ }
336
+
337
+ pub fn tracks ( & self ) -> & HashMap < u32 , Mp4Track > {
338
+ self . header . tracks ( )
339
+ }
340
+
341
+ pub fn sample_count ( & self , track_id : u32 ) -> Result < u32 > {
342
+ self . header . sample_count ( track_id)
343
+ }
344
+
345
+ pub fn read_sample ( & mut self , track_id : u32 , sample_id : u32 ) -> Result < Option < Mp4Sample > > {
346
+ self . header
347
+ . read_sample ( & mut self . reader , track_id, sample_id)
348
+ }
349
+
350
+ pub fn sample_offset ( & mut self , track_id : u32 , sample_id : u32 ) -> Result < u64 > {
351
+ self . header . sample_offset ( track_id, sample_id)
352
+ }
353
+ }
354
+
355
+ impl < R > Mp4Reader < R > {
356
+ pub fn metadata ( & self ) -> impl Metadata < ' _ > {
357
+ self . header . metadata ( )
358
+ }
359
+ }
0 commit comments