1 /*
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2005 M. Bakker, Nero 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 **
19 ** Any non-GPL usage of this software or parts of this software is strictly
20 ** forbidden.
21 **
22 ** The "appropriate copyright message" mentioned in section 2c of the GPLv2
23 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
24 **
25 ** Commercial non-GPL licensing of this software is possible.
26 ** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
27 **
28 ** $Id: mp4ffint.h,v 1.26 2009/01/25 20:14:34 menno Exp $
29 **/
30 
31 #ifndef MP4FF_INTERNAL_H
32 #define MP4FF_INTERNAL_H
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif /* __cplusplus */
37 
38 #include "mp4ff_int_types.h"
39 #include <stdlib.h>
40 
41 #define MAX_TRACKS 1024
42 #define TRACK_UNKNOWN 0
43 #define TRACK_AUDIO   1
44 #define TRACK_VIDEO   2
45 #define TRACK_SYSTEM  3
46 #define TRACK_TEXT    4
47 
48 #define ATOM_TREF 100
49 
50 #define SUBATOMIC 128
51 
52 /* atoms without subatoms */
53 #define ATOM_FTYP 129
54 #define ATOM_MDAT 130
55 #define ATOM_MVHD 131
56 #define ATOM_TKHD 132
57 #define ATOM_MDHD 134
58 #define ATOM_VMHD 135
59 #define ATOM_SMHD 136
60 #define ATOM_HMHD 137
61 #define ATOM_STSD 138
62 #define ATOM_STTS 139
63 #define ATOM_STSZ 140
64 #define ATOM_STZ2 141
65 #define ATOM_STCO 142
66 #define ATOM_STSC 143
67 #define ATOM_MP4A 144
68 #define ATOM_MP4V 145
69 #define ATOM_MP4S 146
70 #define ATOM_ESDS 147
71 #define ATOM_META 148 /* iTunes Metadata box */
72 #define ATOM_NAME 149 /* iTunes Metadata name box */
73 #define ATOM_DATA 150 /* iTunes Metadata data box */
74 #define ATOM_CTTS 151
75 #define ATOM_FRMA 152
76 #define ATOM_IVIV 153
77 #define ATOM_PRIV 154
78 #define ATOM_USER 155
79 #define ATOM_KEY  156
80 
81 #define ATOM_ALBUM_ARTIST	157
82 #define ATOM_CONTENTGROUP   158
83 #define ATOM_LYRICS         159
84 #define ATOM_DESCRIPTION    160
85 #define ATOM_NETWORK        161
86 #define ATOM_SHOW           162
87 #define ATOM_EPISODENAME    163
88 #define ATOM_SORTTITLE      164
89 #define ATOM_SORTALBUM      165
90 #define ATOM_SORTARTIST     166
91 #define ATOM_SORTALBUMARTIST    167
92 #define ATOM_SORTWRITER     168
93 #define ATOM_SORTSHOW       169
94 #define ATOM_SEASON         170
95 #define ATOM_EPISODE        171
96 #define ATOM_PODCAST        172
97 #define ATOM_CUSTOM         173
98 #define ATOM_CHPL           174
99 #define ATOM_CHAP           175
100 #define ATOM_TEXT 176
101 #define ATOM_ELST 176
102 
103 #define ATOM_UNKNOWN 255
104 #define ATOM_FREE ATOM_UNKNOWN
105 #define ATOM_SKIP ATOM_UNKNOWN
106 
107 /* atoms with subatoms */
108 #define ATOM_MOOV 1
109 #define ATOM_TRAK 2
110 #define ATOM_EDTS 3
111 #define ATOM_MDIA 4
112 #define ATOM_MINF 5
113 #define ATOM_STBL 6
114 #define ATOM_UDTA 7
115 #define ATOM_ILST 8 /* iTunes Metadata list */
116 #define ATOM_TITLE 9
117 #define ATOM_ARTIST 10
118 #define ATOM_WRITER 11
119 #define ATOM_ALBUM 12
120 #define ATOM_DATE 13
121 #define ATOM_TOOL 14
122 #define ATOM_COMMENT 15
123 #define ATOM_GENRE1 16
124 #define ATOM_TRACK 17
125 #define ATOM_DISC 18
126 #define ATOM_COMPILATION 19
127 #define ATOM_GENRE2 20
128 #define ATOM_TEMPO 21
129 #define ATOM_COVER 22
130 #define ATOM_DRMS 23
131 #define ATOM_SINF 24
132 #define ATOM_SCHI 25
133 
134 #ifdef HAVE_CONFIG_H
135 #include "../../config.h"
136 #endif
137 
138 #if !(defined(_WIN32) || defined(_WIN32_WCE))
139 #define stricmp strcasecmp
140 #else
141 #define stricmp _stricmp
142 #define strdup _strdup
143 #endif
144 
145 /* file callback structure */
146 typedef struct
147 {
148     uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
149     uint32_t (*write)(void *udata, void *buffer, uint32_t length);
150     uint32_t (*seek)(void *user_data, uint64_t position);
151     uint32_t (*truncate)(void *user_data);
152     void *user_data;
153 } mp4ff_callback_t;
154 
155 
156 /* metadata tag structure */
157 typedef struct
158 {
159     char *item;
160     char *value;
161 } mp4ff_tag_t;
162 
163 /* metadata list structure */
164 typedef struct
165 {
166     mp4ff_tag_t *tags;
167     uint32_t count;
168 } mp4ff_metadata_t;
169 
170 
171 typedef struct
172 {
173     int32_t type;
174     int32_t id;
175     int32_t channelCount;
176     int32_t sampleSize;
177     uint16_t sampleRate;
178     int32_t audioType;
179 
180     /* stsd */
181     int32_t stsd_entry_count;
182 
183     /* stsz */
184     int32_t stsz_sample_size;
185     int32_t stsz_sample_count;
186     int32_t *stsz_table;
187 
188     /* stts */
189     int32_t stts_entry_count;
190     int32_t *stts_sample_count;
191     int32_t *stts_sample_delta;
192 
193 #if 0
194 // experimental support for indexing chunks samples based on VLC code
195     /* chunk index generated in mp4ff_create_chunks_index */
196     // chunk->i_sample_count = stsc_samples_per_chunk[i_chunk]
197     // chunk->i_sample_description_index = stsc_sample_desc_index[chunk]
198     // trk->p_sample_size[i_sample] = stsz_sample_size ? stsz_sample_size : stsz_table[i_sample]
199     int32_t i_chunk_count; // stco_entry_count
200     int32_t *chunk_sample_first;
201     int32_t *chunk_first_dts;
202     int32_t *chunk_last_dts;
203     int32_t **p_sample_count_dts;
204     int32_t **p_sample_delta_dts;
205     int32_t **p_sample_count_pts;
206     int32_t **p_sample_offset_pts;
207 #endif
208     /* stsc */
209     int32_t stsc_entry_count;
210     int32_t *stsc_first_chunk;
211     int32_t *stsc_samples_per_chunk;
212     int32_t *stsc_sample_desc_index;
213 
214     /* stsc */
215     int32_t stco_entry_count;
216     int32_t *stco_chunk_offset;
217 
218     /* ctts */
219     int32_t ctts_entry_count;
220     int32_t *ctts_sample_count;
221     int32_t *ctts_sample_offset;
222 
223 
224 #if 0
225     /* elst */
226     int      i_elst;         /* current elst */
227     int64_t  i_elst_time;    /* current elst start time (in movie time scale)*/
228     uint32_t elst_entry_count;
229     uint64_t *elst_segment_duration;
230     int64_t  *elst_media_time;
231     uint16_t *elst_media_rate_integer;
232     uint16_t *elst_media_rate_fraction;
233 #endif
234 
235     /* esde */
236     uint8_t *decoderConfig;
237     int32_t decoderConfigLen;
238 
239     uint32_t maxBitrate;
240     uint32_t avgBitrate;
241 
242     uint32_t timeScale; // FIXME: check calculation
243     uint64_t duration;
244 
245 } mp4ff_track_t;
246 
247 typedef struct
248 {
249     uint8_t i_chapter;
250     struct
251     {
252         char    *psz_name;
253         int64_t  i_start;
254     } chapter[256];
255 } mp4ff_chapterdata_t;
256 
257 typedef struct
258 {
259     uint32_t i_entry_count;
260     uint32_t *i_track_ID;
261 } mp4ff_trefdata_t;
262 
263 /* mp4 main file structure */
264 typedef struct
265 {
266     /* stream to read from */
267     mp4ff_callback_t *stream;
268     int64_t current_position;
269 
270     int32_t moov_read;
271     uint64_t moov_offset;
272     uint64_t moov_size;
273     uint8_t last_atom;
274     uint64_t file_size;
275 
276     /* mvhd */
277     int32_t time_scale;
278     int32_t duration;
279 
280     /* incremental track index while reading the file */
281     int32_t total_tracks;
282 
283     /* track data */
284     mp4ff_track_t *track[MAX_TRACKS];
285 
286     /* metadata */
287     mp4ff_metadata_t tags;
288 
289     /* chapters */
290     mp4ff_chapterdata_t chapters;
291     mp4ff_trefdata_t tref;
292 } mp4ff_t;
293 
294 
295 
296 
297 /* mp4util.c */
298 int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
299 int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size);
300 uint64_t mp4ff_read_int64(mp4ff_t *f);
301 uint32_t mp4ff_read_int32(mp4ff_t *f);
302 uint32_t mp4ff_read_int24(mp4ff_t *f);
303 uint16_t mp4ff_read_int16(mp4ff_t *f);
304 uint8_t mp4ff_read_char(mp4ff_t *f);
305 int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data);
306 uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f);
307 int64_t mp4ff_position(const mp4ff_t *f);
308 int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
309 int32_t mp4ff_truncate(mp4ff_t * f);
310 char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
311 
312 /* mp4atom.c */
313 static int32_t mp4ff_atom_get_size(const int8_t *data);
314 static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
315                                   const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2);
316 static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
317 uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
318 static int32_t mp4ff_read_stsz(mp4ff_t *f);
319 static int32_t mp4ff_read_esds(mp4ff_t *f);
320 static int32_t mp4ff_read_mp4a(mp4ff_t *f);
321 static int32_t mp4ff_read_stsd(mp4ff_t *f);
322 static int32_t mp4ff_read_stsc(mp4ff_t *f);
323 static int32_t mp4ff_read_stco(mp4ff_t *f);
324 static int32_t mp4ff_read_stts(mp4ff_t *f);
325 #ifdef USE_TAGGING
326 static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
327 #endif
328 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
329 
330 /* mp4sample.c */
331 static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
332                                      int32_t *chunk_sample, int32_t *chunk);
333 static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
334 static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
335                                        const int32_t chunk_sample, const int32_t sample);
336 static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
337 int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
338 int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
339 
340 #ifdef USE_TAGGING
341 /* mp4meta.c */
342 static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
343 static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
344 static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name);
345 static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
346 int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
347 int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
348 int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
349 int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
350 int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
351                             char **item, char **value);
352 int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value);
353 int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
354 int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
355 int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value);
356 int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value);
357 int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
358 int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
359 int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
360 int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value);
361 int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
362 int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
363 int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
364 int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
365 #endif
366 
367 /* mp4ff.c */
368 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
369 mp4ff_t *mp4ff_open_read_streaming(mp4ff_callback_t *f);
370 #ifdef USE_TAGGING
371 mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
372 #endif
373 void mp4ff_close(mp4ff_t *ff);
374 //void mp4ff_track_add(mp4ff_t *f);
375 #if 0
376 int mp4ff_track_create_chunks_index(mp4ff_t *f, mp4ff_track_t *trk);
377 int mp4ff_track_create_samples_index (mp4ff_t *f, mp4ff_track_t *trk);
378 #endif
379 int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only);
380 int32_t parse_atoms(mp4ff_t *f,int meta_only);
381 
382 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
383 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
384 int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
385 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
386 
387 int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
388                           uint8_t **audio_buffer,  uint32_t *bytes);
389 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
390                                  uint8_t** ppBuf, uint32_t* pBufSize);
391 int32_t mp4ff_total_tracks(const mp4ff_t *f);
392 int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track);
393 int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
394 
395 uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
396 const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
397 
398 void mp4ff_chapters_free (mp4ff_t *f);
399 void mp4ff_tref_free (mp4ff_t *f);
400 
401 #ifdef __cplusplus
402 }
403 #endif /* __cplusplus */
404 
405 #endif
406