2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 ** Any non-GPL usage of this software or parts of this software is strictly
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25 ** $Id: mp4atom.c,v 1.17 2004/01/11 15:52:18 menno Exp $
33 /* parse atom header size */
34 static int32_t mp4ff_atom_get_size(const int8_t *data
)
44 result
= (a
<<24) | (b
<<16) | (c
<<8) | d
;
45 //if (result > 0 && result < 8) result = 8;
47 return (int32_t)result
;
50 /* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
51 static int32_t mp4ff_atom_compare(const int8_t a1
, const int8_t b1
, const int8_t c1
, const int8_t d1
,
52 const int8_t a2
, const int8_t b2
, const int8_t c2
, const int8_t d2
)
54 if (a1
== a2
&& b1
== b2
&& c1
== c2
&& d1
== d2
)
60 static uint8_t mp4ff_atom_name_to_type(const int8_t a
, const int8_t b
,
61 const int8_t c
, const int8_t d
)
65 if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','o','o','v'))
67 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','i','n','f'))
69 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','d','i','a'))
71 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','d','a','t'))
73 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','d','h','d'))
75 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','v','h','d'))
77 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','p','4','a'))
79 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','p','4','v'))
81 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','p','4','s'))
83 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'm','e','t','a'))
85 } else if (a
== 't') {
86 if (mp4ff_atom_compare(a
,b
,c
,d
, 't','r','a','k'))
88 else if (mp4ff_atom_compare(a
,b
,c
,d
, 't','k','h','d'))
90 else if (mp4ff_atom_compare(a
,b
,c
,d
, 't','r','e','f'))
92 else if (mp4ff_atom_compare(a
,b
,c
,d
, 't','r','k','n'))
94 else if (mp4ff_atom_compare(a
,b
,c
,d
, 't','m','p','o'))
96 } else if (a
== 's') {
97 if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','b','l'))
99 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','m','h','d'))
101 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','s','d'))
103 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','t','s'))
105 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','c','o'))
107 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','s','c'))
109 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','s','z'))
111 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','t','z','2'))
113 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','k','i','p'))
115 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','i','n','f'))
117 else if (mp4ff_atom_compare(a
,b
,c
,d
, 's','c','h','i'))
119 } else if (a
== '©') {
120 if (mp4ff_atom_compare(a
,b
,c
,d
, '©','n','a','m'))
122 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','A','R','T'))
124 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','w','r','t'))
126 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','a','l','b'))
128 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','d','a','y'))
130 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','t','o','o'))
132 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','c','m','t'))
134 else if (mp4ff_atom_compare(a
,b
,c
,d
, '©','g','e','n'))
138 if (mp4ff_atom_compare(a
,b
,c
,d
, 'e','d','t','s'))
140 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'e','s','d','s'))
142 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'f','t','y','p'))
144 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'f','r','e','e'))
146 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'h','m','h','d'))
148 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'v','m','h','d'))
150 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'u','d','t','a'))
152 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'i','l','s','t'))
154 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'n','a','m','e'))
156 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'd','a','t','a'))
158 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'd','i','s','k'))
160 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'g','n','r','e'))
162 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'c','o','v','r'))
164 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'c','p','i','l'))
165 return ATOM_COMPILATION
;
166 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'c','t','t','s'))
168 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'd','r','m','s'))
170 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'f','r','m','a'))
172 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'p','r','i','v'))
174 else if (mp4ff_atom_compare(a
,b
,c
,d
, 'i','v','i','v'))
180 /* read atom header, return atom size, atom size is with header included */
181 uint64_t mp4ff_atom_read_header(mp4ff_t
*f
, uint8_t *atom_type
, uint8_t *header_size
)
185 int8_t atom_header
[8];
187 ret
= mp4ff_read_data(f
, atom_header
, 8);
191 size
= mp4ff_atom_get_size(atom_header
);
194 /* check for 64 bit atom size */
198 size
= mp4ff_read_int64(f
);
201 //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
203 *atom_type
= mp4ff_atom_name_to_type(atom_header
[4], atom_header
[5], atom_header
[6], atom_header
[7]);
208 static int32_t mp4ff_read_stsz(mp4ff_t
*f
)
210 mp4ff_read_char(f
); /* version */
211 mp4ff_read_int24(f
); /* flags */
212 f
->track
[f
->total_tracks
- 1]->stsz_sample_size
= mp4ff_read_int32(f
);
213 f
->track
[f
->total_tracks
- 1]->stsz_sample_count
= mp4ff_read_int32(f
);
215 if (f
->track
[f
->total_tracks
- 1]->stsz_sample_size
== 0)
218 f
->track
[f
->total_tracks
- 1]->stsz_table
=
219 (int32_t*)malloc(f
->track
[f
->total_tracks
- 1]->stsz_sample_count
*sizeof(int32_t));
221 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->stsz_sample_count
; i
++)
223 f
->track
[f
->total_tracks
- 1]->stsz_table
[i
] = mp4ff_read_int32(f
);
230 static int32_t mp4ff_read_esds(mp4ff_t
*f
)
235 mp4ff_read_char(f
); /* version */
236 mp4ff_read_int24(f
); /* flags */
238 /* get and verify ES_DescrTag */
239 tag
= mp4ff_read_char(f
);
243 if (mp4ff_read_mp4_descr_length(f
) < 5 + 15)
254 /* get and verify DecoderConfigDescrTab */
255 if (mp4ff_read_char(f
) != 0x04)
261 temp
= mp4ff_read_mp4_descr_length(f
);
262 if (temp
< 13) return 1;
264 f
->track
[f
->total_tracks
- 1]->audioType
= mp4ff_read_char(f
);
265 mp4ff_read_int32(f
);//0x15000414 ????
266 f
->track
[f
->total_tracks
- 1]->maxBitrate
= mp4ff_read_int32(f
);
267 f
->track
[f
->total_tracks
- 1]->avgBitrate
= mp4ff_read_int32(f
);
269 /* get and verify DecSpecificInfoTag */
270 if (mp4ff_read_char(f
) != 0x05)
276 f
->track
[f
->total_tracks
- 1]->decoderConfigLen
= mp4ff_read_mp4_descr_length(f
);
278 if (f
->track
[f
->total_tracks
- 1]->decoderConfig
)
279 free(f
->track
[f
->total_tracks
- 1]->decoderConfig
);
280 f
->track
[f
->total_tracks
- 1]->decoderConfig
= malloc(f
->track
[f
->total_tracks
- 1]->decoderConfigLen
);
281 if (f
->track
[f
->total_tracks
- 1]->decoderConfig
)
283 mp4ff_read_data(f
, f
->track
[f
->total_tracks
- 1]->decoderConfig
, f
->track
[f
->total_tracks
- 1]->decoderConfigLen
);
285 f
->track
[f
->total_tracks
- 1]->decoderConfigLen
= 0;
288 /* will skip the remainder of the atom */
292 static int32_t mp4ff_read_mp4a(mp4ff_t
*f
)
296 uint8_t atom_type
= 0;
297 uint8_t header_size
= 0;
299 for (i
= 0; i
< 6; i
++)
301 mp4ff_read_char(f
); /* reserved */
303 /* data_reference_index */ mp4ff_read_int16(f
);
305 mp4ff_read_int32(f
); /* reserved */
306 mp4ff_read_int32(f
); /* reserved */
308 f
->track
[f
->total_tracks
- 1]->channelCount
= mp4ff_read_int16(f
);
309 f
->track
[f
->total_tracks
- 1]->sampleSize
= mp4ff_read_int16(f
);
314 f
->track
[f
->total_tracks
- 1]->sampleRate
= mp4ff_read_int16(f
);
318 size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
319 if (atom_type
== ATOM_ESDS
)
328 static int32_t mp4ff_read_drms(mp4ff_t
*f
, uint64_t skip
)
332 uint8_t atom_type
= 0;
333 uint8_t header_size
= 0;
334 uint32_t drms_user_key
[4];
336 if (drms_get_user_key(NULL
, drms_user_key
) == 0)
338 f
->track
[f
->total_tracks
- 1]->p_drms
= drms_alloc();
340 drms_init( f
->track
[f
->total_tracks
- 1]->p_drms
,
341 DRMS_INIT_UKEY
, (uint8_t *)drms_user_key
,
342 sizeof(drms_user_key
) );
345 for (i
= 0; i
< 6; i
++)
347 mp4ff_read_char(f
); /* reserved */
349 /* data_reference_index */ mp4ff_read_int16(f
);
351 mp4ff_read_int32(f
); /* reserved */
352 mp4ff_read_int32(f
); /* reserved */
354 f
->track
[f
->total_tracks
- 1]->channelCount
= mp4ff_read_int16(f
);
355 f
->track
[f
->total_tracks
- 1]->sampleSize
= mp4ff_read_int16(f
);
360 f
->track
[f
->total_tracks
- 1]->sampleRate
= mp4ff_read_int16(f
);
364 size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
365 if (atom_type
== ATOM_ESDS
)
369 mp4ff_set_position(f
, skip
+size
+28);
371 size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
372 if (atom_type
== ATOM_SINF
)
374 parse_sub_atoms(f
, size
-header_size
);
380 static int32_t mp4ff_read_frma(mp4ff_t
*f
)
385 mp4ff_read_data(f
, type
, 4);
387 atom_type
= mp4ff_atom_name_to_type(type
[0], type
[1], type
[2], type
[3]);
389 if (atom_type
== ATOM_MP4A
)
391 f
->track
[f
->total_tracks
- 1]->type
= TRACK_AUDIO
;
392 } else if (atom_type
== ATOM_MP4V
) {
393 f
->track
[f
->total_tracks
- 1]->type
= TRACK_VIDEO
;
394 } else if (atom_type
== ATOM_MP4S
) {
395 f
->track
[f
->total_tracks
- 1]->type
= TRACK_SYSTEM
;
397 f
->track
[f
->total_tracks
- 1]->type
= TRACK_UNKNOWN
;
403 static int32_t mp4ff_read_name(mp4ff_t
*f
, uint64_t size
)
405 uint8_t *data
= malloc(size
);
406 mp4ff_read_data(f
, data
, size
);
408 if (f
->track
[f
->total_tracks
- 1]->p_drms
!= NULL
)
410 drms_init(f
->track
[f
->total_tracks
- 1]->p_drms
,
411 DRMS_INIT_NAME
, data
, strlen(data
) );
420 static int32_t mp4ff_read_priv(mp4ff_t
*f
, uint64_t size
)
422 uint8_t *data
= malloc(size
);
423 mp4ff_read_data(f
, data
, size
);
425 if (f
->track
[f
->total_tracks
- 1]->p_drms
!= 0)
427 drms_init(f
->track
[f
->total_tracks
- 1]->p_drms
,
428 DRMS_INIT_PRIV
, data
, size
);
437 static int32_t mp4ff_read_iviv(mp4ff_t
*f
, uint64_t size
)
439 uint8_t *data
= malloc(size
);
440 mp4ff_read_data(f
, data
, size
);
442 if (f
->track
[f
->total_tracks
- 1]->p_drms
!= 0)
444 drms_init(f
->track
[f
->total_tracks
- 1]->p_drms
,
445 DRMS_INIT_IVIV
, data
, sizeof(uint32_t) * 4 );
455 static int32_t mp4ff_read_stsd(mp4ff_t
*f
)
458 uint8_t header_size
= 0;
460 mp4ff_read_char(f
); /* version */
461 mp4ff_read_int24(f
); /* flags */
463 f
->track
[f
->total_tracks
- 1]->stsd_entry_count
= mp4ff_read_int32(f
);
465 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->stsd_entry_count
; i
++)
467 uint64_t skip
= mp4ff_position(f
);
469 uint8_t atom_type
= 0;
470 size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
473 if (atom_type
== ATOM_MP4A
)
475 f
->track
[f
->total_tracks
- 1]->type
= TRACK_AUDIO
;
477 } else if (atom_type
== ATOM_MP4V
) {
478 f
->track
[f
->total_tracks
- 1]->type
= TRACK_VIDEO
;
479 } else if (atom_type
== ATOM_MP4S
) {
480 f
->track
[f
->total_tracks
- 1]->type
= TRACK_SYSTEM
;
482 } else if (atom_type
== ATOM_DRMS
) {
483 // track type is read from the "frma" atom
484 f
->track
[f
->total_tracks
- 1]->type
= TRACK_UNKNOWN
;
485 mp4ff_read_drms(f
, skip
-size
+header_size
);
488 f
->track
[f
->total_tracks
- 1]->type
= TRACK_UNKNOWN
;
491 mp4ff_set_position(f
, skip
);
497 static int32_t mp4ff_read_stsc(mp4ff_t
*f
)
501 mp4ff_read_char(f
); /* version */
502 mp4ff_read_int24(f
); /* flags */
503 f
->track
[f
->total_tracks
- 1]->stsc_entry_count
= mp4ff_read_int32(f
);
505 f
->track
[f
->total_tracks
- 1]->stsc_first_chunk
=
506 (int32_t*)malloc(f
->track
[f
->total_tracks
- 1]->stsc_entry_count
*sizeof(int32_t));
507 f
->track
[f
->total_tracks
- 1]->stsc_samples_per_chunk
=
508 (int32_t*)malloc(f
->track
[f
->total_tracks
- 1]->stsc_entry_count
*sizeof(int32_t));
509 f
->track
[f
->total_tracks
- 1]->stsc_sample_desc_index
=
510 (int32_t*)malloc(f
->track
[f
->total_tracks
- 1]->stsc_entry_count
*sizeof(int32_t));
512 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->stsc_entry_count
; i
++)
514 f
->track
[f
->total_tracks
- 1]->stsc_first_chunk
[i
] = mp4ff_read_int32(f
);
515 f
->track
[f
->total_tracks
- 1]->stsc_samples_per_chunk
[i
] = mp4ff_read_int32(f
);
516 f
->track
[f
->total_tracks
- 1]->stsc_sample_desc_index
[i
] = mp4ff_read_int32(f
);
522 static int32_t mp4ff_read_stco(mp4ff_t
*f
)
526 mp4ff_read_char(f
); /* version */
527 mp4ff_read_int24(f
); /* flags */
528 f
->track
[f
->total_tracks
- 1]->stco_entry_count
= mp4ff_read_int32(f
);
530 f
->track
[f
->total_tracks
- 1]->stco_chunk_offset
=
531 (int32_t*)malloc(f
->track
[f
->total_tracks
- 1]->stco_entry_count
*sizeof(int32_t));
533 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->stco_entry_count
; i
++)
535 f
->track
[f
->total_tracks
- 1]->stco_chunk_offset
[i
] = mp4ff_read_int32(f
);
541 static int32_t mp4ff_read_ctts(mp4ff_t
*f
)
544 mp4ff_track_t
* p_track
= f
->track
[f
->total_tracks
- 1];
546 if (p_track
->ctts_entry_count
) return 0;
548 mp4ff_read_char(f
); /* version */
549 mp4ff_read_int24(f
); /* flags */
550 p_track
->ctts_entry_count
= mp4ff_read_int32(f
);
552 p_track
->ctts_sample_count
= (int32_t*)malloc(p_track
->ctts_entry_count
* sizeof(int32_t));
553 p_track
->ctts_sample_offset
= (int32_t*)malloc(p_track
->ctts_entry_count
* sizeof(int32_t));
555 if (p_track
->ctts_sample_count
== 0 || p_track
->ctts_sample_offset
== 0)
557 if (p_track
->ctts_sample_count
) {free(p_track
->ctts_sample_count
);p_track
->ctts_sample_count
=0;}
558 if (p_track
->ctts_sample_offset
) {free(p_track
->ctts_sample_offset
);p_track
->ctts_sample_offset
=0;}
559 p_track
->ctts_entry_count
= 0;
564 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->ctts_entry_count
; i
++)
566 p_track
->ctts_sample_count
[i
] = mp4ff_read_int32(f
);
567 p_track
->ctts_sample_offset
[i
] = mp4ff_read_int32(f
);
573 static int32_t mp4ff_read_stts(mp4ff_t
*f
)
576 mp4ff_track_t
* p_track
= f
->track
[f
->total_tracks
- 1];
578 if (p_track
->stts_entry_count
) return 0;
580 mp4ff_read_char(f
); /* version */
581 mp4ff_read_int24(f
); /* flags */
582 p_track
->stts_entry_count
= mp4ff_read_int32(f
);
584 p_track
->stts_sample_count
= (int32_t*)malloc(p_track
->stts_entry_count
* sizeof(int32_t));
585 p_track
->stts_sample_delta
= (int32_t*)malloc(p_track
->stts_entry_count
* sizeof(int32_t));
587 if (p_track
->stts_sample_count
== 0 || p_track
->stts_sample_delta
== 0)
589 if (p_track
->stts_sample_count
) {free(p_track
->stts_sample_count
);p_track
->stts_sample_count
=0;}
590 if (p_track
->stts_sample_delta
) {free(p_track
->stts_sample_delta
);p_track
->stts_sample_delta
=0;}
591 p_track
->stts_entry_count
= 0;
596 for (i
= 0; i
< f
->track
[f
->total_tracks
- 1]->stts_entry_count
; i
++)
598 p_track
->stts_sample_count
[i
] = mp4ff_read_int32(f
);
599 p_track
->stts_sample_delta
[i
] = mp4ff_read_int32(f
);
605 static int32_t mp4ff_read_mvhd(mp4ff_t
*f
)
609 mp4ff_read_char(f
); /* version */
610 mp4ff_read_int24(f
); /* flags */
611 /* creation_time */ mp4ff_read_int32(f
);
612 /* modification_time */ mp4ff_read_int32(f
);
613 f
->time_scale
= mp4ff_read_int32(f
);
614 f
->duration
= mp4ff_read_int32(f
);
615 /* preferred_rate */ mp4ff_read_int32(f
); /*mp4ff_read_fixed32(f);*/
616 /* preferred_volume */ mp4ff_read_int16(f
); /*mp4ff_read_fixed16(f);*/
617 for (i
= 0; i
< 10; i
++)
619 /* reserved */ mp4ff_read_char(f
);
621 for (i
= 0; i
< 9; i
++)
623 mp4ff_read_int32(f
); /* matrix */
625 /* preview_time */ mp4ff_read_int32(f
);
626 /* preview_duration */ mp4ff_read_int32(f
);
627 /* poster_time */ mp4ff_read_int32(f
);
628 /* selection_time */ mp4ff_read_int32(f
);
629 /* selection_duration */ mp4ff_read_int32(f
);
630 /* current_time */ mp4ff_read_int32(f
);
631 /* next_track_id */ mp4ff_read_int32(f
);
637 static int32_t mp4ff_read_tkhd(mp4ff_t
*f
)
641 version
= mp4ff_read_char(f
); /* version */
642 flags
= mp4ff_read_int24(f
); /* flags */
645 mp4ff_read_int64(f
);//creation-time
646 mp4ff_read_int64(f
);//modification-time
647 mp4ff_read_int32(f
);//track-id
648 mp4ff_read_int32(f
);//reserved
649 f
->track
[f
->total_tracks
- 1]->duration
= mp4ff_read_int64(f
);//duration
653 mp4ff_read_int32(f
);//creation-time
654 mp4ff_read_int32(f
);//modification-time
655 mp4ff_read_int32(f
);//track-id
656 mp4ff_read_int32(f
);//reserved
657 f
->track
[f
->total_tracks
- 1]->duration
= mp4ff_read_int32(f
);//duration
658 if (f
->track
[f
->total_tracks
- 1]->duration
== 0xFFFFFFFF)
659 f
->track
[f
->total_tracks
- 1]->duration
= 0xFFFFFFFFFFFFFFFF;
662 mp4ff_read_int32(f
);//reserved
663 mp4ff_read_int32(f
);//reserved
664 mp4ff_read_int16(f
);//layer
665 mp4ff_read_int16(f
);//pre-defined
666 mp4ff_read_int16(f
);//volume
667 mp4ff_read_int16(f
);//reserved
670 mp4ff_read_int32(f
); mp4ff_read_int32(f
); mp4ff_read_int32(f
);
671 mp4ff_read_int32(f
); mp4ff_read_int32(f
); mp4ff_read_int32(f
);
672 mp4ff_read_int32(f
); mp4ff_read_int32(f
); mp4ff_read_int32(f
);
673 mp4ff_read_int32(f
);//width
674 mp4ff_read_int32(f
);//height
679 static int32_t mp4ff_read_mdhd(mp4ff_t
*f
)
683 version
= mp4ff_read_int32(f
);
686 mp4ff_read_int64(f
);//creation-time
687 mp4ff_read_int64(f
);//modification-time
688 f
->track
[f
->total_tracks
- 1]->timeScale
= mp4ff_read_int32(f
);//timescale
689 f
->track
[f
->total_tracks
- 1]->duration
= mp4ff_read_int64(f
);//duration
695 mp4ff_read_int32(f
);//creation-time
696 mp4ff_read_int32(f
);//modification-time
697 f
->track
[f
->total_tracks
- 1]->timeScale
= mp4ff_read_int32(f
);//timescale
698 temp
= mp4ff_read_int32(f
);
699 f
->track
[f
->total_tracks
- 1]->duration
= (temp
== (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp
);
706 static int32_t mp4ff_read_meta(mp4ff_t
*f
, const uint64_t size
)
708 uint64_t subsize
, sumsize
= 0;
710 uint8_t header_size
= 0;
712 mp4ff_read_char(f
); /* version */
713 mp4ff_read_int24(f
); /* flags */
715 while (sumsize
< (size
-12))
717 subsize
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
718 if (atom_type
== ATOM_ILST
)
720 mp4ff_parse_metadata(f
, (uint32_t)(subsize
-(header_size
+4)));
722 mp4ff_set_position(f
, mp4ff_position(f
)+subsize
-header_size
);
731 int32_t mp4ff_atom_read(mp4ff_t
*f
, const int32_t size
, const uint8_t atom_type
)
733 uint64_t dest_position
= mp4ff_position(f
)+size
-8;
734 if (atom_type
== ATOM_STSZ
)
736 /* sample size box */
738 } else if (atom_type
== ATOM_STTS
) {
739 /* time to sample box */
741 } else if (atom_type
== ATOM_CTTS
) {
742 /* composition offset box */
744 } else if (atom_type
== ATOM_STSC
) {
745 /* sample to chunk box */
747 } else if (atom_type
== ATOM_STCO
) {
748 /* chunk offset box */
750 } else if (atom_type
== ATOM_STSD
) {
751 /* sample description box */
753 } else if (atom_type
== ATOM_MVHD
) {
754 /* movie header box */
756 } else if (atom_type
== ATOM_MDHD
) {
760 } else if (atom_type
== ATOM_FRMA
) {
761 /* DRM track format */
763 } else if (atom_type
== ATOM_IVIV
) {
764 mp4ff_read_iviv(f
, size
-8);
765 } else if (atom_type
== ATOM_NAME
) {
766 mp4ff_read_name(f
, size
-8);
767 } else if (atom_type
== ATOM_PRIV
) {
768 mp4ff_read_priv(f
, size
-8);
771 } else if (atom_type
== ATOM_META
) {
772 /* iTunes Metadata box */
773 mp4ff_read_meta(f
, size
);
777 mp4ff_set_position(f
, dest_position
);