Update to 6762
[qball-mpd.git] / src / mp4ff / mp4ff.c
blobe0bb781e858c6d3bd842549bb0ac4d4fd2441674
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: mp4ff.c,v 1.15 2004/01/11 15:52:18 menno Exp $
26 **/
28 #include <stdlib.h>
29 #include <string.h>
30 #include "mp4ffint.h"
32 #include "drms.h"
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));
42 ff->stream = f;
44 parse_atoms(ff);
46 return ff;
49 void mp4ff_close(mp4ff_t *ff)
51 int32_t i;
53 for (i = 0; i < ff->total_tracks; i++)
55 if (ff->track[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);
77 #ifdef ITUNES_DRM
78 if (ff->track[i]->p_drms)
79 drms_free(ff->track[i]->p_drms);
80 #endif
81 free(ff->track[i]);
85 #ifdef USE_TAGGING
86 mp4ff_tag_delete(&(ff->tags));
87 #endif
89 if (ff) free(ff);
92 static void mp4ff_track_add(mp4ff_t *f)
94 f->total_tracks++;
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)
104 uint64_t 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 */
115 if (size == 0)
116 break;
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)
123 mp4ff_track_add(f);
126 /* parse subatoms */
127 if (atom_type < SUBATOMIC)
129 parse_sub_atoms(f, size-header_size);
130 } else {
131 mp4ff_atom_read(f, (uint32_t)size, atom_type);
135 return 0;
138 /* parse root atoms */
139 int32_t parse_atoms(mp4ff_t *f)
141 uint64_t size;
142 uint8_t atom_type = 0;
143 uint8_t header_size = 0;
145 f->file_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 */
156 // break;
159 if (atom_type == ATOM_MOOV && size > header_size)
161 f->moov_read = 1;
162 f->moov_offset = mp4ff_position(f)-header_size;
163 f->moov_size = size;
166 /* parse subatoms */
167 if (atom_type < SUBATOMIC)
169 parse_sub_atoms(f, size-header_size);
170 } else {
171 /* skip this atom */
172 mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
176 return 0;
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)
184 *ppBuf = NULL;
185 *pBufSize = 0;
186 return 1;
189 if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
191 *ppBuf = NULL;
192 *pBufSize = 0;
193 } else {
194 *ppBuf = malloc(f->track[track]->decoderConfigLen);
195 if (*ppBuf == NULL)
197 *pBufSize = 0;
198 return 1;
200 memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
201 *pBufSize = f->track[track]->decoderConfigLen;
204 return 0;
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);
240 if (duration!=-1)
242 int64_t offset = mp4ff_get_sample_offset(f,track,0);
243 if (offset > duration) duration = 0;
244 else duration -= offset;
246 return duration;
250 int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
252 int32_t i;
253 int32_t total = 0;
255 for (i = 0; i < f->track[track]->stts_entry_count; i++)
257 total += f->track[track]->stts_sample_count[i];
259 return total;
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)
282 int32_t d,o;
283 d = mp4ff_get_sample_duration(f,track,sample);
284 if (d!=-1)
286 o = mp4ff_get_sample_offset(f,track,sample);
287 if (o>d) d = 0;
288 else d -= o;
290 return d;
293 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
295 int32_t i, co = 0;
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];
302 co += delta;
304 return (int32_t)(-1);
307 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
309 int32_t i, co = 0;
310 int64_t acc = 0;
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);
318 return acc;
320 else
322 acc += f->track[track]->stts_sample_delta[i] * delta;
324 co += 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)
331 int32_t i, co = 0;
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];
338 co += delta;
340 return 0;
343 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
345 int32_t i, co = 0;
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);
360 else
362 offset_total += offset_delta;
364 co += sample_count;
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)
377 int32_t result = 0;
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);
389 if (!result)
391 free(*audio_buffer);
392 *audio_buffer = 0;
393 return 0;
396 #ifdef ITUNES_DRM
397 if (f->track[track]->p_drms != NULL)
399 drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
401 #endif
403 return *bytes;
407 static int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
409 int32_t result = 0;
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);
415 #ifdef ITUNES_DRM
416 if (f->track[track]->p_drms != NULL)
418 drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
420 #endif
422 return result;
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;
429 return temp;