Initial revision 6759
[qball-mpd.git] / src / mp4ff / mp4atom.c
blobb75a3da7f23dae132df7e96399c44f25b88d137e
1 /*
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
4 **
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.
9 **
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
20 ** forbidden.
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 $
26 **/
28 #include <stdlib.h>
29 #include "mp4ffint.h"
31 #include "drms.h"
33 /* parse atom header size */
34 static int32_t mp4ff_atom_get_size(const int8_t *data)
36 uint32_t result;
37 uint32_t a, b, c, d;
39 a = (uint8_t)data[0];
40 b = (uint8_t)data[1];
41 c = (uint8_t)data[2];
42 d = (uint8_t)data[3];
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)
55 return 1;
56 else
57 return 0;
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)
63 if (a == 'm')
65 if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v'))
66 return ATOM_MOOV;
67 else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f'))
68 return ATOM_MINF;
69 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a'))
70 return ATOM_MDIA;
71 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t'))
72 return ATOM_MDAT;
73 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d'))
74 return ATOM_MDHD;
75 else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d'))
76 return ATOM_MVHD;
77 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a'))
78 return ATOM_MP4A;
79 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v'))
80 return ATOM_MP4V;
81 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s'))
82 return ATOM_MP4S;
83 else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a'))
84 return ATOM_META;
85 } else if (a == 't') {
86 if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k'))
87 return ATOM_TRAK;
88 else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d'))
89 return ATOM_TKHD;
90 else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f'))
91 return ATOM_TREF;
92 else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n'))
93 return ATOM_TRACK;
94 else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
95 return ATOM_TEMPO;
96 } else if (a == 's') {
97 if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
98 return ATOM_STBL;
99 else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d'))
100 return ATOM_SMHD;
101 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d'))
102 return ATOM_STSD;
103 else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s'))
104 return ATOM_STTS;
105 else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o'))
106 return ATOM_STCO;
107 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c'))
108 return ATOM_STSC;
109 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z'))
110 return ATOM_STSZ;
111 else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2'))
112 return ATOM_STZ2;
113 else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p'))
114 return ATOM_SKIP;
115 else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f'))
116 return ATOM_SINF;
117 else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
118 return ATOM_SCHI;
119 } else if (a == '©') {
120 if (mp4ff_atom_compare(a,b,c,d, '©','n','a','m'))
121 return ATOM_TITLE;
122 else if (mp4ff_atom_compare(a,b,c,d, '©','A','R','T'))
123 return ATOM_ARTIST;
124 else if (mp4ff_atom_compare(a,b,c,d, '©','w','r','t'))
125 return ATOM_WRITER;
126 else if (mp4ff_atom_compare(a,b,c,d, '©','a','l','b'))
127 return ATOM_ALBUM;
128 else if (mp4ff_atom_compare(a,b,c,d, '©','d','a','y'))
129 return ATOM_DATE;
130 else if (mp4ff_atom_compare(a,b,c,d, '©','t','o','o'))
131 return ATOM_TOOL;
132 else if (mp4ff_atom_compare(a,b,c,d, '©','c','m','t'))
133 return ATOM_COMMENT;
134 else if (mp4ff_atom_compare(a,b,c,d, '©','g','e','n'))
135 return ATOM_GENRE1;
138 if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
139 return ATOM_EDTS;
140 else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s'))
141 return ATOM_ESDS;
142 else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p'))
143 return ATOM_FTYP;
144 else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e'))
145 return ATOM_FREE;
146 else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d'))
147 return ATOM_HMHD;
148 else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d'))
149 return ATOM_VMHD;
150 else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a'))
151 return ATOM_UDTA;
152 else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t'))
153 return ATOM_ILST;
154 else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e'))
155 return ATOM_NAME;
156 else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a'))
157 return ATOM_DATA;
158 else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k'))
159 return ATOM_DISC;
160 else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
161 return ATOM_GENRE2;
162 else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
163 return ATOM_COVER;
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'))
167 return ATOM_CTTS;
168 else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
169 return ATOM_DRMS;
170 else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
171 return ATOM_FRMA;
172 else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
173 return ATOM_PRIV;
174 else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
175 return ATOM_IVIV;
176 else
177 return ATOM_UNKNOWN;
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)
183 uint64_t size;
184 int32_t ret;
185 int8_t atom_header[8];
187 ret = mp4ff_read_data(f, atom_header, 8);
188 if (ret != 8)
189 return 0;
191 size = mp4ff_atom_get_size(atom_header);
192 *header_size = 8;
194 /* check for 64 bit atom size */
195 if (size == 1)
197 *header_size = 16;
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]);
205 return size;
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)
217 int32_t i;
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);
227 return 0;
230 static int32_t mp4ff_read_esds(mp4ff_t *f)
232 uint8_t tag;
233 uint32_t temp;
235 mp4ff_read_char(f); /* version */
236 mp4ff_read_int24(f); /* flags */
238 /* get and verify ES_DescrTag */
239 tag = mp4ff_read_char(f);
240 if (tag == 0x03)
242 /* read length */
243 if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
245 return 1;
247 /* skip 3 bytes */
248 mp4ff_read_int24(f);
249 } else {
250 /* skip 2 bytes */
251 mp4ff_read_int16(f);
254 /* get and verify DecoderConfigDescrTab */
255 if (mp4ff_read_char(f) != 0x04)
257 return 1;
260 /* read length */
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)
272 return 1;
275 /* read length */
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);
284 } else {
285 f->track[f->total_tracks - 1]->decoderConfigLen = 0;
288 /* will skip the remainder of the atom */
289 return 0;
292 static int32_t mp4ff_read_mp4a(mp4ff_t *f)
294 uint64_t size;
295 int32_t i;
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);
311 mp4ff_read_int16(f);
312 mp4ff_read_int16(f);
314 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
316 mp4ff_read_int16(f);
318 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
319 if (atom_type == ATOM_ESDS)
321 mp4ff_read_esds(f);
324 return 0;
327 #ifdef ITUNES_DRM
328 static int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
330 uint64_t size;
331 int32_t i;
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);
357 mp4ff_read_int16(f);
358 mp4ff_read_int16(f);
360 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
362 mp4ff_read_int16(f);
364 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
365 if (atom_type == ATOM_ESDS)
367 mp4ff_read_esds(f);
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);
377 return 0;
380 static int32_t mp4ff_read_frma(mp4ff_t *f)
382 uint8_t atom_type;
383 int8_t type[4];
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;
396 } else {
397 f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
400 return 0;
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) );
414 if (data)
415 free(data);
417 return 0;
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 );
431 if (data)
432 free(data);
434 return 0;
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 );
448 if (data)
449 free(data);
451 return 0;
453 #endif
455 static int32_t mp4ff_read_stsd(mp4ff_t *f)
457 int32_t i;
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);
468 uint64_t size;
469 uint8_t atom_type = 0;
470 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
471 skip += size;
473 if (atom_type == ATOM_MP4A)
475 f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
476 mp4ff_read_mp4a(f);
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;
481 #ifdef ITUNES_DRM
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);
486 #endif
487 } else {
488 f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
491 mp4ff_set_position(f, skip);
494 return 0;
497 static int32_t mp4ff_read_stsc(mp4ff_t *f)
499 int32_t i;
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);
519 return 0;
522 static int32_t mp4ff_read_stco(mp4ff_t *f)
524 int32_t i;
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);
538 return 0;
541 static int32_t mp4ff_read_ctts(mp4ff_t *f)
543 int32_t i;
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;
560 return 0;
562 else
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);
569 return 1;
573 static int32_t mp4ff_read_stts(mp4ff_t *f)
575 int32_t i;
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;
592 return 0;
594 else
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);
601 return 1;
605 static int32_t mp4ff_read_mvhd(mp4ff_t *f)
607 int32_t i;
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);
633 return 0;
636 #if 0
637 static int32_t mp4ff_read_tkhd(mp4ff_t *f)
639 uint8_t version;
640 uint32_t flags;
641 version = mp4ff_read_char(f); /* version */
642 flags = mp4ff_read_int24(f); /* flags */
643 if (version==1)
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
651 else //version == 0
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
669 //matrix
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
675 return 1;
677 #endif
679 static int32_t mp4ff_read_mdhd(mp4ff_t *f)
681 uint32_t version;
683 version = mp4ff_read_int32(f);
684 if (version==1)
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
691 else //version == 0
693 uint32_t temp;
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);
701 mp4ff_read_int16(f);
702 mp4ff_read_int16(f);
703 return 1;
705 #ifdef USE_TAGGING
706 static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
708 uint64_t subsize, sumsize = 0;
709 uint8_t atom_type;
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)));
721 } else {
722 mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
724 sumsize += subsize;
727 return 0;
729 #endif
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 */
737 mp4ff_read_stsz(f);
738 } else if (atom_type == ATOM_STTS) {
739 /* time to sample box */
740 mp4ff_read_stts(f);
741 } else if (atom_type == ATOM_CTTS) {
742 /* composition offset box */
743 mp4ff_read_ctts(f);
744 } else if (atom_type == ATOM_STSC) {
745 /* sample to chunk box */
746 mp4ff_read_stsc(f);
747 } else if (atom_type == ATOM_STCO) {
748 /* chunk offset box */
749 mp4ff_read_stco(f);
750 } else if (atom_type == ATOM_STSD) {
751 /* sample description box */
752 mp4ff_read_stsd(f);
753 } else if (atom_type == ATOM_MVHD) {
754 /* movie header box */
755 mp4ff_read_mvhd(f);
756 } else if (atom_type == ATOM_MDHD) {
757 /* track header */
758 mp4ff_read_mdhd(f);
759 #ifdef ITUNES_DRM
760 } else if (atom_type == ATOM_FRMA) {
761 /* DRM track format */
762 mp4ff_read_frma(f);
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);
769 #endif
770 #ifdef USE_TAGGING
771 } else if (atom_type == ATOM_META) {
772 /* iTunes Metadata box */
773 mp4ff_read_meta(f, size);
774 #endif
777 mp4ff_set_position(f, dest_position);
780 return 0;