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: mp4ff.c,v 1.15 2004/01/11 15:52:18 menno Exp $
34 int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t
*f
, const int32_t track
);
36 mp4ff_t
*mp4ff_open_read(mp4ff_callback_t
*f
)
38 mp4ff_t
*ff
= malloc(sizeof(mp4ff_t
));
40 memset(ff
, 0, sizeof(mp4ff_t
));
49 void mp4ff_close(mp4ff_t
*ff
)
53 for (i
= 0; i
< ff
->total_tracks
; i
++)
57 if (ff
->track
[i
]->stsz_table
)
58 free(ff
->track
[i
]->stsz_table
);
59 if (ff
->track
[i
]->stts_sample_count
)
60 free(ff
->track
[i
]->stts_sample_count
);
61 if (ff
->track
[i
]->stts_sample_delta
)
62 free(ff
->track
[i
]->stts_sample_delta
);
63 if (ff
->track
[i
]->stsc_first_chunk
)
64 free(ff
->track
[i
]->stsc_first_chunk
);
65 if (ff
->track
[i
]->stsc_samples_per_chunk
)
66 free(ff
->track
[i
]->stsc_samples_per_chunk
);
67 if (ff
->track
[i
]->stsc_sample_desc_index
)
68 free(ff
->track
[i
]->stsc_sample_desc_index
);
69 if (ff
->track
[i
]->stco_chunk_offset
)
70 free(ff
->track
[i
]->stco_chunk_offset
);
71 if (ff
->track
[i
]->decoderConfig
)
72 free(ff
->track
[i
]->decoderConfig
);
73 if (ff
->track
[i
]->ctts_sample_count
)
74 free(ff
->track
[i
]->ctts_sample_count
);
75 if (ff
->track
[i
]->ctts_sample_offset
)
76 free(ff
->track
[i
]->ctts_sample_offset
);
78 if (ff
->track
[i
]->p_drms
)
79 drms_free(ff
->track
[i
]->p_drms
);
86 mp4ff_tag_delete(&(ff
->tags
));
92 static void mp4ff_track_add(mp4ff_t
*f
)
96 f
->track
[f
->total_tracks
- 1] = malloc(sizeof(mp4ff_track_t
));
98 memset(f
->track
[f
->total_tracks
- 1], 0, sizeof(mp4ff_track_t
));
101 /* parse atoms that are sub atoms of other atoms */
102 int32_t parse_sub_atoms(mp4ff_t
*f
, const uint64_t total_size
)
105 uint8_t atom_type
= 0;
106 uint64_t counted_size
= 0;
107 uint8_t header_size
= 0;
109 while (counted_size
< total_size
)
111 size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
);
112 counted_size
+= size
;
114 /* check for end of file */
118 /* we're starting to read a new track, update index,
119 * so that all data and tables get written in the right place
121 if (atom_type
== ATOM_TRAK
)
127 if (atom_type
< SUBATOMIC
)
129 parse_sub_atoms(f
, size
-header_size
);
131 mp4ff_atom_read(f
, (uint32_t)size
, atom_type
);
138 /* parse root atoms */
139 int32_t parse_atoms(mp4ff_t
*f
)
142 uint8_t atom_type
= 0;
143 uint8_t header_size
= 0;
147 while ((size
= mp4ff_atom_read_header(f
, &atom_type
, &header_size
)) != 0)
149 f
->file_size
+= size
;
150 f
->last_atom
= atom_type
;
152 if (atom_type
== ATOM_MDAT
&& f
->moov_read
)
154 /* moov atom is before mdat, we can stop reading when mdat is encountered */
155 /* file position will stay at beginning of mdat data */
159 if (atom_type
== ATOM_MOOV
&& size
> header_size
)
162 f
->moov_offset
= mp4ff_position(f
)-header_size
;
167 if (atom_type
< SUBATOMIC
)
169 parse_sub_atoms(f
, size
-header_size
);
172 mp4ff_set_position(f
, mp4ff_position(f
)+size
-header_size
);
179 int32_t mp4ff_get_decoder_config(const mp4ff_t
*f
, const int32_t track
,
180 uint8_t** ppBuf
, uint32_t* pBufSize
)
182 if (track
>= f
->total_tracks
)
189 if (f
->track
[track
]->decoderConfig
== NULL
|| f
->track
[track
]->decoderConfigLen
== 0)
194 *ppBuf
= malloc(f
->track
[track
]->decoderConfigLen
);
200 memcpy(*ppBuf
, f
->track
[track
]->decoderConfig
, f
->track
[track
]->decoderConfigLen
);
201 *pBufSize
= f
->track
[track
]->decoderConfigLen
;
207 static int32_t mp4ff_get_track_type(const mp4ff_t
*f
, const int track
)
209 return f
->track
[track
]->type
;
212 int32_t mp4ff_total_tracks(const mp4ff_t
*f
)
214 return f
->total_tracks
;
217 int32_t mp4ff_time_scale(const mp4ff_t
*f
, const int32_t track
)
219 return f
->track
[track
]->timeScale
;
222 static uint32_t mp4ff_get_avg_bitrate(const mp4ff_t
*f
, const int32_t track
)
224 return f
->track
[track
]->avgBitrate
;
227 static uint32_t mp4ff_get_max_bitrate(const mp4ff_t
*f
, const int32_t track
)
229 return f
->track
[track
]->maxBitrate
;
232 static int64_t mp4ff_get_track_duration(const mp4ff_t
*f
, const int32_t track
)
234 return f
->track
[track
]->duration
;
237 int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t
*f
, const int32_t track
)
239 int64_t duration
= mp4ff_get_track_duration(f
,track
);
242 int64_t offset
= mp4ff_get_sample_offset(f
,track
,0);
243 if (offset
> duration
) duration
= 0;
244 else duration
-= offset
;
250 int32_t mp4ff_num_samples(const mp4ff_t
*f
, const int32_t track
)
255 for (i
= 0; i
< f
->track
[track
]->stts_entry_count
; i
++)
257 total
+= f
->track
[track
]->stts_sample_count
[i
];
265 static uint32_t mp4ff_get_sample_rate(const mp4ff_t
*f
, const int32_t track
)
267 return f
->track
[track
]->sampleRate
;
270 static uint32_t mp4ff_get_channel_count(const mp4ff_t
* f
,const int32_t track
)
272 return f
->track
[track
]->channelCount
;
275 static uint32_t mp4ff_get_audio_type(const mp4ff_t
* f
,const int32_t track
)
277 return f
->track
[track
]->audioType
;
280 static int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t
*f
, const int32_t track
, const int32_t sample
)
283 d
= mp4ff_get_sample_duration(f
,track
,sample
);
286 o
= mp4ff_get_sample_offset(f
,track
,sample
);
293 int32_t mp4ff_get_sample_duration(const mp4ff_t
*f
, const int32_t track
, const int32_t sample
)
297 for (i
= 0; i
< f
->track
[track
]->stts_entry_count
; i
++)
299 int32_t delta
= f
->track
[track
]->stts_sample_count
[i
];
300 if (sample
< co
+ delta
)
301 return f
->track
[track
]->stts_sample_delta
[i
];
304 return (int32_t)(-1);
307 int64_t mp4ff_get_sample_position(const mp4ff_t
*f
, const int32_t track
, const int32_t sample
)
312 for (i
= 0; i
< f
->track
[track
]->stts_entry_count
; i
++)
314 int32_t delta
= f
->track
[track
]->stts_sample_count
[i
];
315 if (sample
< co
+ delta
)
317 acc
+= f
->track
[track
]->stts_sample_delta
[i
] * (sample
- co
);
322 acc
+= f
->track
[track
]->stts_sample_delta
[i
] * delta
;
326 return (int64_t)(-1);
329 int32_t mp4ff_get_sample_offset(const mp4ff_t
*f
, const int32_t track
, const int32_t sample
)
333 for (i
= 0; i
< f
->track
[track
]->ctts_entry_count
; i
++)
335 int32_t delta
= f
->track
[track
]->ctts_sample_count
[i
];
336 if (sample
< co
+ delta
)
337 return f
->track
[track
]->ctts_sample_offset
[i
];
343 int32_t mp4ff_find_sample(const mp4ff_t
*f
, const int32_t track
, const int64_t offset
,int32_t * toskip
)
346 int64_t offset_total
= 0;
347 mp4ff_track_t
* p_track
= f
->track
[track
];
349 for (i
= 0; i
< p_track
->stts_entry_count
; i
++)
351 int32_t sample_count
= p_track
->stts_sample_count
[i
];
352 int32_t sample_delta
= p_track
->stts_sample_delta
[i
];
353 int64_t offset_delta
= (int64_t)sample_delta
* (int64_t)sample_count
;
354 if (offset
< offset_total
+ offset_delta
)
356 int64_t offset_fromstts
= offset
- offset_total
;
357 if (toskip
) *toskip
= (int32_t)(offset_fromstts
% sample_delta
);
358 return co
+ (int32_t)(offset_fromstts
/ sample_delta
);
362 offset_total
+= offset_delta
;
366 return (int32_t)(-1);
369 static int32_t mp4ff_find_sample_use_offsets(const mp4ff_t
*f
, const int32_t track
, const int64_t offset
,int32_t * toskip
)
371 return mp4ff_find_sample(f
,track
,offset
+ mp4ff_get_sample_offset(f
,track
,0),toskip
);
374 int32_t mp4ff_read_sample(mp4ff_t
*f
, const int32_t track
, const int32_t sample
,
375 uint8_t **audio_buffer
, uint32_t *bytes
)
379 *bytes
= mp4ff_audio_frame_size(f
, track
, sample
);
381 if (*bytes
==0) return 0;
383 *audio_buffer
= (uint8_t*)malloc(*bytes
);
385 mp4ff_set_sample_position(f
, track
, sample
);
387 result
= mp4ff_read_data(f
, *audio_buffer
, *bytes
);
397 if (f
->track
[track
]->p_drms
!= NULL
)
399 drms_decrypt(f
->track
[track
]->p_drms
, (uint32_t*)*audio_buffer
, *bytes
);
407 static int32_t mp4ff_read_sample_v2(mp4ff_t
*f
, const int track
, const int sample
,unsigned char *buffer
)
410 int32_t size
= mp4ff_audio_frame_size(f
,track
,sample
);
411 if (size
<=0) return 0;
412 mp4ff_set_sample_position(f
, track
, sample
);
413 result
= mp4ff_read_data(f
,buffer
,size
);
416 if (f
->track
[track
]->p_drms
!= NULL
)
418 drms_decrypt(f
->track
[track
]->p_drms
, (uint32_t*)buffer
, size
);
425 static int32_t mp4ff_read_sample_getsize(mp4ff_t
*f
, const int track
, const int sample
)
427 int32_t temp
= mp4ff_audio_frame_size(f
, track
, sample
);
428 if (temp
<0) temp
= 0;