comparison src/aac/mp4ff/mp4atom.c @ 12:3da1b8942b8b trunk

[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author nenolod
date Mon, 18 Sep 2006 03:14:20 -0700
parents src/Input/aac/mp4ff/mp4atom.c@13389e613d67
children 357de698dab2
comparison
equal deleted inserted replaced
11:cff1d04026ae 12:3da1b8942b8b
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.
14 **
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **
19 ** Any non-GPL usage of this software or parts of this software is strictly
20 ** forbidden.
21 **
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
24 **
25 ** $Id: mp4atom.c,v 1.17 2004/01/11 15:52:18 menno Exp $
26 **/
27
28 #include <stdlib.h>
29 #include "mp4ffint.h"
30
31 #include "drms.h"
32
33 /* parse atom header size */
34 int32_t mp4ff_atom_get_size(const uint8_t *data)
35 {
36 uint32_t result;
37 uint32_t a, b, c, d;
38
39 a = data[0];
40 b = data[1];
41 c = data[2];
42 d = data[3];
43
44 result = (a<<24) | (b<<16) | (c<<8) | d;
45 //if (result > 0 && result < 8) result = 8;
46
47 return (int32_t)result;
48 }
49
50 /* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
51 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)
53 {
54 if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
55 return 1;
56 else
57 return 0;
58 }
59
60 uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
61 const int8_t c, const int8_t d)
62 {
63 if (a == 'm')
64 {
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;
136 }
137
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;
178 }
179
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)
182 {
183 uint64_t size;
184 int32_t ret;
185 uint8_t atom_header[8];
186
187 ret = mp4ff_read_data(f, atom_header, 8);
188 if (ret != 8)
189 return 0;
190
191 size = mp4ff_atom_get_size(atom_header);
192 *header_size = 8;
193
194 /* check for 64 bit atom size */
195 if (size == 1)
196 {
197 *header_size = 16;
198 size = mp4ff_read_int64(f);
199 }
200
201 //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
202
203 *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
204
205 return size;
206 }
207
208 int32_t mp4ff_read_stsz(mp4ff_t *f)
209 {
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);
214
215 if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
216 {
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));
220
221 for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
222 {
223 f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
224 }
225 }
226
227 return 0;
228 }
229
230 int32_t mp4ff_read_esds(mp4ff_t *f)
231 {
232 uint8_t tag;
233 uint32_t temp;
234
235 mp4ff_read_char(f); /* version */
236 mp4ff_read_int24(f); /* flags */
237
238 /* get and verify ES_DescrTag */
239 tag = mp4ff_read_char(f);
240 if (tag == 0x03)
241 {
242 /* read length */
243 if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
244 {
245 return 1;
246 }
247 /* skip 3 bytes */
248 mp4ff_read_int24(f);
249 } else {
250 /* skip 2 bytes */
251 mp4ff_read_int16(f);
252 }
253
254 /* get and verify DecoderConfigDescrTab */
255 if (mp4ff_read_char(f) != 0x04)
256 {
257 return 1;
258 }
259
260 /* read length */
261 temp = mp4ff_read_mp4_descr_length(f);
262 if (temp < 13) return 1;
263
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);
268
269 /* get and verify DecSpecificInfoTag */
270 if (mp4ff_read_char(f) != 0x05)
271 {
272 return 1;
273 }
274
275 /* read length */
276 f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
277
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)
282 {
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;
286 }
287
288 /* will skip the remainder of the atom */
289 return 0;
290 }
291
292 int32_t mp4ff_read_mp4a(mp4ff_t *f)
293 {
294 uint64_t size;
295 int32_t i;
296 uint8_t atom_type = 0;
297 uint8_t header_size = 0;
298
299 for (i = 0; i < 6; i++)
300 {
301 mp4ff_read_char(f); /* reserved */
302 }
303 /* data_reference_index */ mp4ff_read_int16(f);
304
305 mp4ff_read_int32(f); /* reserved */
306 mp4ff_read_int32(f); /* reserved */
307
308 f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
309 f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
310
311 mp4ff_read_int16(f);
312 mp4ff_read_int16(f);
313
314 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
315
316 mp4ff_read_int16(f);
317
318 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
319 if (atom_type == ATOM_ESDS)
320 {
321 mp4ff_read_esds(f);
322 }
323
324 return 0;
325 }
326
327 #ifdef ITUNES_DRM
328 int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
329 {
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];
335
336 if (drms_get_user_key(NULL, drms_user_key) == 0)
337 {
338 f->track[f->total_tracks - 1]->p_drms = drms_alloc();
339
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) );
343 }
344
345 for (i = 0; i < 6; i++)
346 {
347 mp4ff_read_char(f); /* reserved */
348 }
349 /* data_reference_index */ mp4ff_read_int16(f);
350
351 mp4ff_read_int32(f); /* reserved */
352 mp4ff_read_int32(f); /* reserved */
353
354 f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
355 f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
356
357 mp4ff_read_int16(f);
358 mp4ff_read_int16(f);
359
360 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
361
362 mp4ff_read_int16(f);
363
364 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
365 if (atom_type == ATOM_ESDS)
366 {
367 mp4ff_read_esds(f);
368 }
369 mp4ff_set_position(f, skip+size+28);
370
371 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
372 if (atom_type == ATOM_SINF)
373 {
374 parse_sub_atoms(f, size-header_size);
375 }
376
377 return 0;
378 }
379
380 int32_t mp4ff_read_frma(mp4ff_t *f)
381 {
382 uint8_t atom_type;
383 int8_t type[4];
384
385 mp4ff_read_data(f, type, 4);
386
387 atom_type = mp4ff_atom_name_to_type(type[0], type[1], type[2], type[3]);
388
389 if (atom_type == ATOM_MP4A)
390 {
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;
398 }
399
400 return 0;
401 }
402
403 int32_t mp4ff_read_name(mp4ff_t *f, uint64_t size)
404 {
405 uint8_t *data = malloc(size);
406 mp4ff_read_data(f, data, size);
407
408 if (f->track[f->total_tracks - 1]->p_drms != NULL)
409 {
410 drms_init(f->track[f->total_tracks - 1]->p_drms,
411 DRMS_INIT_NAME, data, strlen(data) );
412 }
413
414 if (data)
415 free(data);
416
417 return 0;
418 }
419
420 int32_t mp4ff_read_priv(mp4ff_t *f, uint64_t size)
421 {
422 uint8_t *data = malloc(size);
423 mp4ff_read_data(f, data, size);
424
425 if (f->track[f->total_tracks - 1]->p_drms != 0)
426 {
427 drms_init(f->track[f->total_tracks - 1]->p_drms,
428 DRMS_INIT_PRIV, data, size );
429 }
430
431 if (data)
432 free(data);
433
434 return 0;
435 }
436
437 int32_t mp4ff_read_iviv(mp4ff_t *f, uint64_t size)
438 {
439 uint8_t *data = malloc(size);
440 mp4ff_read_data(f, data, size);
441
442 if (f->track[f->total_tracks - 1]->p_drms != 0)
443 {
444 drms_init(f->track[f->total_tracks - 1]->p_drms,
445 DRMS_INIT_IVIV, data, sizeof(uint32_t) * 4 );
446 }
447
448 if (data)
449 free(data);
450
451 return 0;
452 }
453 #endif
454
455 int32_t mp4ff_read_stsd(mp4ff_t *f)
456 {
457 int32_t i;
458 uint8_t header_size = 0;
459
460 mp4ff_read_char(f); /* version */
461 mp4ff_read_int24(f); /* flags */
462
463 f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
464
465 for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
466 {
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;
472
473 if (atom_type == ATOM_MP4A)
474 {
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;
489 }
490
491 mp4ff_set_position(f, skip);
492 }
493
494 return 0;
495 }
496
497 int32_t mp4ff_read_stsc(mp4ff_t *f)
498 {
499 int32_t i;
500
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);
504
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));
511
512 for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
513 {
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);
517 }
518
519 return 0;
520 }
521
522 int32_t mp4ff_read_stco(mp4ff_t *f)
523 {
524 int32_t i;
525
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);
529
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));
532
533 for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
534 {
535 f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
536 }
537
538 return 0;
539 }
540
541 int32_t mp4ff_read_ctts(mp4ff_t *f)
542 {
543 int32_t i;
544 mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
545
546 if (p_track->ctts_entry_count) return 0;
547
548 mp4ff_read_char(f); /* version */
549 mp4ff_read_int24(f); /* flags */
550 p_track->ctts_entry_count = mp4ff_read_int32(f);
551
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));
554
555 if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
556 {
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;
561 }
562 else
563 {
564 for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
565 {
566 p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
567 p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
568 }
569 return 1;
570 }
571 }
572
573 int32_t mp4ff_read_stts(mp4ff_t *f)
574 {
575 int32_t i;
576 mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
577
578 if (p_track->stts_entry_count) return 0;
579
580 mp4ff_read_char(f); /* version */
581 mp4ff_read_int24(f); /* flags */
582 p_track->stts_entry_count = mp4ff_read_int32(f);
583
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));
586
587 if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
588 {
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;
593 }
594 else
595 {
596 for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
597 {
598 p_track->stts_sample_count[i] = mp4ff_read_int32(f);
599 p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
600 }
601 return 1;
602 }
603 }
604
605 int32_t mp4ff_read_mvhd(mp4ff_t *f)
606 {
607 int32_t i;
608
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++)
618 {
619 /* reserved */ mp4ff_read_char(f);
620 }
621 for (i = 0; i < 9; i++)
622 {
623 mp4ff_read_int32(f); /* matrix */
624 }
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);
632
633 return 0;
634 }
635
636 #if 0
637 int32_t mp4ff_read_tkhd(mp4ff_t *f)
638 {
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)
644 {
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
650 }
651 else //version == 0
652 {
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;
660
661 }
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
668
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;
676 }
677 #endif
678
679 int32_t mp4ff_read_mdhd(mp4ff_t *f)
680 {
681 uint32_t version;
682
683 version = mp4ff_read_int32(f);
684 if (version==1)
685 {
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
690 }
691 else //version == 0
692 {
693 uint32_t temp;
694
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);
700 }
701 mp4ff_read_int16(f);
702 mp4ff_read_int16(f);
703 return 1;
704 }
705 #ifdef USE_TAGGING
706 int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
707 {
708 uint64_t subsize, sumsize = 0;
709 uint8_t atom_type;
710 uint8_t header_size = 0;
711
712 mp4ff_read_char(f); /* version */
713 mp4ff_read_int24(f); /* flags */
714
715 while (sumsize < (size-12))
716 {
717 subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
718 if (atom_type == ATOM_ILST)
719 {
720 mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
721 } else {
722 mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
723 }
724 sumsize += subsize;
725 }
726
727 return 0;
728 }
729 #endif
730
731 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
732 {
733 uint64_t dest_position = mp4ff_position(f)+size-8;
734 if (atom_type == ATOM_STSZ)
735 {
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
775 }
776
777 mp4ff_set_position(f, dest_position);
778
779
780 return 0;
781 }