1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | #include <stdlib.h> |
32 | #ifdef HAVE_CONFIG_H |
33 | #include "config.h" |
34 | #elif _WIN32 |
35 | #include <tchar.h> |
36 | #include <windows.h> |
37 | #endif |
38 | #ifdef HAVE_GETPWUID |
39 | # include <pwd.h> |
40 | #endif |
41 | #ifdef HAVE_STRING_H |
42 | # include <string.h> |
43 | #endif |
44 | #include "mp4ffint.h" |
45 | |
46 | #define COPYRIGHT_SYMBOL((int8_t)0xA9) ((int8_t)0xA9) |
47 | |
48 | |
49 | int32_t mp4ff_atom_get_size(const uint8_t *data) |
50 | { |
51 | uint32_t result; |
52 | uint32_t a, b, c, d; |
53 | |
54 | a = (uint8_t)data[0]; |
55 | b = (uint8_t)data[1]; |
56 | c = (uint8_t)data[2]; |
57 | d = (uint8_t)data[3]; |
58 | |
59 | result = (a<<24) | (b<<16) | (c<<8) | d; |
60 | |
61 | |
62 | return (int32_t)result; |
63 | } |
64 | |
65 | |
66 | int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1, |
67 | const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2) |
68 | { |
69 | if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2) |
70 | return 1; |
71 | else |
72 | return 0; |
73 | } |
74 | |
75 | uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, |
76 | const int8_t c, const int8_t d) |
77 | { |
78 | if (a == 'm') |
79 | { |
80 | if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v')) |
81 | return ATOM_MOOV1; |
82 | else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f')) |
83 | return ATOM_MINF5; |
84 | else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a')) |
85 | return ATOM_MDIA4; |
86 | else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t')) |
87 | return ATOM_MDAT130; |
88 | else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d')) |
89 | return ATOM_MDHD134; |
90 | else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d')) |
91 | return ATOM_MVHD131; |
92 | else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a')) |
93 | return ATOM_MP4A144; |
94 | else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v')) |
95 | return ATOM_MP4V145; |
96 | else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s')) |
97 | return ATOM_MP4S146; |
98 | else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a')) |
99 | return ATOM_META148; |
100 | } else if (a == 't') { |
101 | if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k')) |
102 | return ATOM_TRAK2; |
103 | else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d')) |
104 | return ATOM_TKHD132; |
105 | else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f')) |
106 | return ATOM_TREF133; |
107 | else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n')) |
108 | return ATOM_TRACK17; |
109 | else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o')) |
110 | return ATOM_TEMPO21; |
111 | else if (mp4ff_atom_compare(a,b,c,d, 't','v','n','n')) |
112 | return ATOM_NETWORK161; |
113 | else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','h')) |
114 | return ATOM_SHOW162; |
115 | else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','n')) |
116 | return ATOM_EPISODENAME163; |
117 | else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','n')) |
118 | return ATOM_SEASON170; |
119 | else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','s')) |
120 | return ATOM_EPISODE171; |
121 | } else if (a == 's') { |
122 | if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l')) |
123 | return ATOM_STBL6; |
124 | else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d')) |
125 | return ATOM_SMHD136; |
126 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d')) |
127 | return ATOM_STSD138; |
128 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s')) |
129 | return ATOM_STTS139; |
130 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o')) |
131 | return ATOM_STCO142; |
132 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c')) |
133 | return ATOM_STSC143; |
134 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z')) |
135 | return ATOM_STSZ140; |
136 | else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2')) |
137 | return ATOM_STZ2141; |
138 | else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p')) |
139 | return ATOM_SKIP255; |
140 | else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f')) |
141 | return ATOM_SINF24; |
142 | else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i')) |
143 | return ATOM_SCHI25; |
144 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','n','m')) |
145 | return ATOM_SORTTITLE164; |
146 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','l')) |
147 | return ATOM_SORTALBUM165; |
148 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','r')) |
149 | return ATOM_SORTARTIST166; |
150 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','a')) |
151 | return ATOM_SORTALBUMARTIST167; |
152 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','c','o')) |
153 | return ATOM_SORTWRITER168; |
154 | else if (mp4ff_atom_compare(a,b,c,d, 's','o','s','n')) |
155 | return ATOM_SORTSHOW169; |
156 | } else if (a == COPYRIGHT_SYMBOL((int8_t)0xA9)) { |
157 | if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'n','a','m')) |
158 | return ATOM_TITLE9; |
159 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'A','R','T')) |
160 | return ATOM_ARTIST10; |
161 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'w','r','t')) |
162 | return ATOM_WRITER11; |
163 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'a','l','b')) |
164 | return ATOM_ALBUM12; |
165 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'d','a','y')) |
166 | return ATOM_DATE13; |
167 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'t','o','o')) |
168 | return ATOM_TOOL14; |
169 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'c','m','t')) |
170 | return ATOM_COMMENT15; |
171 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'g','e','n')) |
172 | return ATOM_GENRE116; |
173 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'g','r','p')) |
174 | return ATOM_CONTENTGROUP158; |
175 | else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL((int8_t)0xA9),'l','y','r')) |
176 | return ATOM_LYRICS159; |
177 | } |
178 | |
179 | if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s')) |
180 | return ATOM_EDTS3; |
181 | else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s')) |
182 | return ATOM_ESDS147; |
183 | else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p')) |
184 | return ATOM_FTYP129; |
185 | else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e')) |
186 | return ATOM_FREE255; |
187 | else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d')) |
188 | return ATOM_HMHD137; |
189 | else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d')) |
190 | return ATOM_VMHD135; |
191 | else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a')) |
192 | return ATOM_UDTA7; |
193 | else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t')) |
194 | return ATOM_ILST8; |
195 | else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e')) |
196 | return ATOM_NAME149; |
197 | else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a')) |
198 | return ATOM_DATA150; |
199 | else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k')) |
200 | return ATOM_DISC18; |
201 | else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e')) |
202 | return ATOM_GENRE220; |
203 | else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r')) |
204 | return ATOM_COVER22; |
205 | else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l')) |
206 | return ATOM_COMPILATION19; |
207 | else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s')) |
208 | return ATOM_CTTS151; |
209 | else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s')) |
210 | return ATOM_DRMS23; |
211 | else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a')) |
212 | return ATOM_FRMA152; |
213 | else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v')) |
214 | return ATOM_PRIV154; |
215 | else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v')) |
216 | return ATOM_IVIV153; |
217 | else if (mp4ff_atom_compare(a,b,c,d, 'u','s','e','r')) |
218 | return ATOM_USER155; |
219 | else if (mp4ff_atom_compare(a,b,c,d, 'k','e','y',' ')) |
220 | return ATOM_KEY156; |
221 | else if (mp4ff_atom_compare(a,b,c,d, 'a','l','a','c')) |
222 | return ATOM_ALAC192; |
223 | else if (mp4ff_atom_compare(a,b,c,d, 'a','A','R','T')) |
224 | return ATOM_ALBUM_ARTIST157; |
225 | else if (mp4ff_atom_compare(a,b,c,d, 'd','e','s','c')) |
226 | return ATOM_DESCRIPTION160; |
227 | else if (mp4ff_atom_compare(a,b,c,d, 'p','c','s','t')) |
228 | return ATOM_PODCAST172; |
229 | else |
230 | return ATOM_UNKNOWN255; |
231 | } |
232 | |
233 | |
234 | uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size) |
235 | { |
236 | uint64_t size; |
237 | int32_t ret; |
238 | uint8_t atom_header[8]; |
239 | |
240 | ret = mp4ff_read_data(f, atom_header, 8); |
241 | if (ret != 8) |
242 | return 0; |
243 | |
244 | size = mp4ff_atom_get_size(atom_header); |
245 | *header_size = 8; |
246 | |
247 | |
248 | if (size == 1) |
249 | { |
250 | *header_size = 16; |
251 | size = mp4ff_read_int64(f); |
252 | } |
253 | |
254 | |
255 | |
256 | *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]); |
257 | |
258 | return size; |
259 | } |
260 | |
261 | int32_t mp4ff_read_stsz(mp4ff_t *f) |
262 | { |
263 | mp4ff_read_char(f); |
264 | mp4ff_read_int24(f); |
265 | f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f); |
266 | f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f); |
267 | |
268 | if (f->track[f->total_tracks - 1]->stsz_sample_size == 0) |
269 | { |
270 | int32_t i; |
271 | f->track[f->total_tracks - 1]->stsz_table = |
272 | (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t)); |
273 | |
274 | for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++) |
275 | { |
276 | f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f); |
277 | } |
278 | } |
279 | |
280 | return 0; |
281 | } |
282 | |
283 | int32_t mp4ff_read_esds(mp4ff_t *f) |
284 | { |
285 | uint8_t tag; |
286 | uint32_t temp; |
287 | |
288 | mp4ff_read_char(f); |
289 | mp4ff_read_int24(f); |
290 | |
291 | |
292 | tag = mp4ff_read_char(f); |
293 | if (tag == 0x03) |
294 | { |
295 | |
296 | if (mp4ff_read_mp4_descr_length(f) < 5 + 15) |
297 | { |
298 | return 1; |
299 | } |
300 | |
301 | mp4ff_read_int24(f); |
302 | } else { |
303 | |
304 | mp4ff_read_int16(f); |
305 | } |
306 | |
307 | |
308 | if (mp4ff_read_char(f) != 0x04) |
309 | { |
310 | return 1; |
311 | } |
312 | |
313 | |
314 | temp = mp4ff_read_mp4_descr_length(f); |
315 | if (temp < 13) return 1; |
316 | |
317 | f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f); |
318 | mp4ff_read_int32(f); |
319 | f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f); |
320 | f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f); |
321 | |
322 | |
323 | if (mp4ff_read_char(f) != 0x05) |
324 | { |
325 | return 1; |
326 | } |
327 | |
328 | |
329 | f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f); |
330 | |
331 | if (f->track[f->total_tracks - 1]->decoderConfig) |
332 | free(f->track[f->total_tracks - 1]->decoderConfig); |
333 | f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen); |
334 | if (f->track[f->total_tracks - 1]->decoderConfig) |
335 | { |
336 | mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen); |
337 | } else { |
338 | f->track[f->total_tracks - 1]->decoderConfigLen = 0; |
339 | } |
340 | |
341 | |
342 | return 0; |
343 | } |
344 | |
345 | int32_t mp4ff_read_mp4a(mp4ff_t *f) |
346 | { |
347 | uint64_t size; |
348 | int32_t i; |
349 | uint8_t atom_type = 0; |
350 | uint8_t header_size = 0; |
351 | |
352 | for (i = 0; i < 6; i++) |
353 | { |
354 | mp4ff_read_char(f); |
355 | } |
356 | mp4ff_read_int16(f); |
357 | |
358 | mp4ff_read_int32(f); |
359 | mp4ff_read_int32(f); |
360 | |
361 | f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f); |
362 | f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f); |
363 | |
364 | mp4ff_read_int16(f); |
365 | mp4ff_read_int16(f); |
366 | |
367 | f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f); |
368 | |
369 | mp4ff_read_int16(f); |
370 | |
371 | size = mp4ff_atom_read_header(f, &atom_type, &header_size); |
372 | if (atom_type == ATOM_ESDS147) |
373 | { |
374 | mp4ff_read_esds(f); |
375 | } |
376 | |
377 | return 0; |
378 | } |
379 | |
380 | int32_t mp4ff_read_alac(mp4ff_t *f) |
381 | { |
382 | mp4ff_track_t *current_track = f->track[f->total_tracks - 1]; |
383 | |
384 | mp4ff_read_int32(f); |
385 | mp4ff_read_int32(f); |
386 | mp4ff_read_int32(f); |
387 | mp4ff_read_int32(f); |
388 | mp4ff_read_int32(f); |
389 | mp4ff_read_int32(f); |
390 | mp4ff_read_int32(f); |
391 | |
392 | current_track->decoderConfigLen = 36; |
393 | if (current_track->decoderConfig) |
| 20 | | Assuming the condition is false | |
|
| |
394 | free(current_track->decoderConfig); |
395 | current_track->decoderConfig = calloc(1, current_track->decoderConfigLen); |
| 22 | | Value assigned to field 'decoderConfig' | |
|
396 | |
397 | if (current_track->decoderConfig) |
| 23 | | Assuming pointer value is null | |
|
| |
398 | { |
399 | mp4ff_read_data(f, current_track->decoderConfig, |
400 | current_track->decoderConfigLen); |
401 | } else { |
402 | current_track->decoderConfigLen = 0; |
403 | } |
404 | |
405 | current_track->channelCount = current_track->decoderConfig[21]; |
| 25 | | Array access (via field 'decoderConfig') results in a null pointer dereference |
|
406 | current_track->avgBitrate = (current_track->decoderConfig[28] << 24) | |
407 | (current_track->decoderConfig[29] << 16) | |
408 | (current_track->decoderConfig[30] << 8) | |
409 | current_track->decoderConfig[31]; |
410 | current_track->sampleRate = (current_track->decoderConfig[32] << 24) | |
411 | (current_track->decoderConfig[33] << 16) | |
412 | (current_track->decoderConfig[34] << 8) | |
413 | current_track->decoderConfig[35]; |
414 | current_track->audioType = 0xff; |
415 | |
416 | |
417 | return 0; |
418 | } |
419 | |
420 | int32_t mp4ff_read_stsd(mp4ff_t *f) |
421 | { |
422 | int32_t i; |
423 | uint8_t header_size = 0; |
424 | |
425 | mp4ff_read_char(f); |
426 | mp4ff_read_int24(f); |
427 | |
428 | f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f); |
429 | |
430 | for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++) |
| 14 | | Loop condition is true. Entering loop body | |
|
431 | { |
432 | uint64_t skip = mp4ff_position(f); |
433 | uint64_t size; |
434 | uint8_t atom_type = 0; |
435 | size = mp4ff_atom_read_header(f, &atom_type, &header_size); |
436 | skip += size; |
437 | |
438 | if (atom_type == ATOM_MP4A144) |
| 15 | | Assuming 'atom_type' is not equal to ATOM_MP4A | |
|
| |
439 | { |
440 | f->track[f->total_tracks - 1]->type = TRACK_AUDIO1; |
441 | mp4ff_read_mp4a(f); |
442 | } else if (atom_type == ATOM_ALAC192) { |
| 17 | | Assuming 'atom_type' is equal to ATOM_ALAC | |
|
| |
443 | f->track[f->total_tracks - 1]->type = TRACK_AUDIO1; |
444 | mp4ff_read_alac(f); |
| 19 | | Calling 'mp4ff_read_alac' | |
|
445 | } else if (atom_type == ATOM_MP4V145) { |
446 | f->track[f->total_tracks - 1]->type = TRACK_VIDEO2; |
447 | } else if (atom_type == ATOM_MP4S146) { |
448 | f->track[f->total_tracks - 1]->type = TRACK_SYSTEM3; |
449 | } else { |
450 | f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN0; |
451 | } |
452 | |
453 | mp4ff_set_position(f, skip); |
454 | } |
455 | |
456 | return 0; |
457 | } |
458 | |
459 | int32_t mp4ff_read_stsc(mp4ff_t *f) |
460 | { |
461 | int32_t i; |
462 | |
463 | mp4ff_read_char(f); |
464 | mp4ff_read_int24(f); |
465 | f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f); |
466 | |
467 | f->track[f->total_tracks - 1]->stsc_first_chunk = |
468 | (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t)); |
469 | f->track[f->total_tracks - 1]->stsc_samples_per_chunk = |
470 | (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t)); |
471 | f->track[f->total_tracks - 1]->stsc_sample_desc_index = |
472 | (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t)); |
473 | |
474 | for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++) |
475 | { |
476 | f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f); |
477 | f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f); |
478 | f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f); |
479 | } |
480 | |
481 | return 0; |
482 | } |
483 | |
484 | int32_t mp4ff_read_stco(mp4ff_t *f) |
485 | { |
486 | int32_t i; |
487 | |
488 | mp4ff_read_char(f); |
489 | mp4ff_read_int24(f); |
490 | f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f); |
491 | |
492 | f->track[f->total_tracks - 1]->stco_chunk_offset = |
493 | (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t)); |
494 | |
495 | for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++) |
496 | { |
497 | f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f); |
498 | } |
499 | |
500 | return 0; |
501 | } |
502 | |
503 | static int32_t mp4ff_read_ctts(mp4ff_t *f) |
504 | { |
505 | int32_t i; |
506 | mp4ff_track_t * p_track = f->track[f->total_tracks - 1]; |
507 | |
508 | if (p_track->ctts_entry_count) return 0; |
509 | |
510 | mp4ff_read_char(f); |
511 | mp4ff_read_int24(f); |
512 | p_track->ctts_entry_count = mp4ff_read_int32(f); |
513 | |
514 | p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t)); |
515 | p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t)); |
516 | |
517 | if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0) |
518 | { |
519 | if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;} |
520 | if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;} |
521 | p_track->ctts_entry_count = 0; |
522 | return 0; |
523 | } |
524 | else |
525 | { |
526 | for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++) |
527 | { |
528 | p_track->ctts_sample_count[i] = mp4ff_read_int32(f); |
529 | p_track->ctts_sample_offset[i] = mp4ff_read_int32(f); |
530 | } |
531 | return 1; |
532 | } |
533 | } |
534 | |
535 | int32_t mp4ff_read_stts(mp4ff_t *f) |
536 | { |
537 | int32_t i; |
538 | mp4ff_track_t * p_track = f->track[f->total_tracks - 1]; |
539 | |
540 | if (p_track->stts_entry_count) return 0; |
541 | |
542 | mp4ff_read_char(f); |
543 | mp4ff_read_int24(f); |
544 | p_track->stts_entry_count = mp4ff_read_int32(f); |
545 | |
546 | p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t)); |
547 | p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t)); |
548 | |
549 | if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0) |
550 | { |
551 | if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;} |
552 | if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;} |
553 | p_track->stts_entry_count = 0; |
554 | return 0; |
555 | } |
556 | else |
557 | { |
558 | for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++) |
559 | { |
560 | p_track->stts_sample_count[i] = mp4ff_read_int32(f); |
561 | p_track->stts_sample_delta[i] = mp4ff_read_int32(f); |
562 | } |
563 | return 1; |
564 | } |
565 | } |
566 | |
567 | static int32_t mp4ff_read_mvhd(mp4ff_t *f) |
568 | { |
569 | int32_t i; |
570 | |
571 | mp4ff_read_char(f); |
572 | mp4ff_read_int24(f); |
573 | mp4ff_read_int32(f); |
574 | mp4ff_read_int32(f); |
575 | f->time_scale = mp4ff_read_int32(f); |
576 | f->duration = mp4ff_read_int32(f); |
577 | mp4ff_read_int32(f); |
578 | mp4ff_read_int16(f); |
579 | for (i = 0; i < 10; i++) |
580 | { |
581 | mp4ff_read_char(f); |
582 | } |
583 | for (i = 0; i < 9; i++) |
584 | { |
585 | mp4ff_read_int32(f); |
586 | } |
587 | mp4ff_read_int32(f); |
588 | mp4ff_read_int32(f); |
589 | mp4ff_read_int32(f); |
590 | mp4ff_read_int32(f); |
591 | mp4ff_read_int32(f); |
592 | mp4ff_read_int32(f); |
593 | mp4ff_read_int32(f); |
594 | |
595 | return 0; |
596 | } |
597 | |
598 | #if 0 |
599 | static int32_t mp4ff_read_tkhd(mp4ff_t *f) |
600 | { |
601 | uint8_t version; |
602 | uint32_t flags; |
603 | version = mp4ff_read_char(f); |
604 | flags = mp4ff_read_int24(f); |
605 | if (version==1) |
606 | { |
607 | mp4ff_read_int64(f); |
608 | mp4ff_read_int64(f); |
609 | mp4ff_read_int32(f); |
610 | mp4ff_read_int32(f); |
611 | f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f); |
612 | } |
613 | else |
614 | { |
615 | mp4ff_read_int32(f); |
616 | mp4ff_read_int32(f); |
617 | mp4ff_read_int32(f); |
618 | mp4ff_read_int32(f); |
619 | f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f); |
620 | if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF) |
621 | f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF; |
622 | |
623 | } |
624 | mp4ff_read_int32(f); |
625 | mp4ff_read_int32(f); |
626 | mp4ff_read_int16(f); |
627 | mp4ff_read_int16(f); |
628 | mp4ff_read_int16(f); |
629 | mp4ff_read_int16(f); |
630 | |
631 | |
632 | mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f); |
633 | mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f); |
634 | mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f); |
635 | mp4ff_read_int32(f); |
636 | mp4ff_read_int32(f); |
637 | return 1; |
638 | } |
639 | #endif |
640 | |
641 | static int32_t mp4ff_read_mdhd(mp4ff_t *f) |
642 | { |
643 | uint32_t version; |
644 | |
645 | version = mp4ff_read_int32(f); |
646 | if (version==1) |
647 | { |
648 | mp4ff_read_int64(f); |
649 | mp4ff_read_int64(f); |
650 | f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f); |
651 | f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f); |
652 | } |
653 | else |
654 | { |
655 | uint32_t temp; |
656 | |
657 | mp4ff_read_int32(f); |
658 | mp4ff_read_int32(f); |
659 | f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f); |
660 | temp = mp4ff_read_int32(f); |
661 | f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp); |
662 | } |
663 | mp4ff_read_int16(f); |
664 | mp4ff_read_int16(f); |
665 | return 1; |
666 | } |
667 | #ifdef USE_TAGGING1 |
668 | int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size) |
669 | { |
670 | uint64_t subsize, sumsize = 0; |
671 | uint8_t atom_type; |
672 | uint8_t header_size = 0; |
673 | |
674 | mp4ff_read_char(f); |
675 | mp4ff_read_int24(f); |
676 | |
677 | while (sumsize < (size-(header_size+4))) |
678 | { |
679 | subsize = mp4ff_atom_read_header(f, &atom_type, &header_size); |
680 | if (subsize <= header_size+4) |
681 | return 1; |
682 | if (atom_type == ATOM_ILST8) |
683 | { |
684 | mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4))); |
685 | } else { |
686 | mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size); |
687 | } |
688 | sumsize += subsize; |
689 | } |
690 | |
691 | return 0; |
692 | } |
693 | #endif |
694 | |
695 | int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type) |
696 | { |
697 | uint64_t dest_position = mp4ff_position(f)+size-8; |
698 | if (atom_type == ATOM_STSZ140) |
| 1 | Assuming 'atom_type' is not equal to ATOM_STSZ | |
|
| |
699 | { |
700 | |
701 | mp4ff_read_stsz(f); |
702 | } else if (atom_type == ATOM_STTS139) { |
| 3 | | Assuming 'atom_type' is not equal to ATOM_STTS | |
|
| |
703 | |
704 | mp4ff_read_stts(f); |
705 | } else if (atom_type == ATOM_CTTS151) { |
| 5 | | Assuming 'atom_type' is not equal to ATOM_CTTS | |
|
| |
706 | |
707 | mp4ff_read_ctts(f); |
708 | } else if (atom_type == ATOM_STSC143) { |
| 7 | | Assuming 'atom_type' is not equal to ATOM_STSC | |
|
| |
709 | |
710 | mp4ff_read_stsc(f); |
711 | } else if (atom_type == ATOM_STCO142) { |
| 9 | | Assuming 'atom_type' is not equal to ATOM_STCO | |
|
| |
712 | |
713 | mp4ff_read_stco(f); |
714 | } else if (atom_type == ATOM_STSD138) { |
| 11 | | Assuming 'atom_type' is equal to ATOM_STSD | |
|
| |
715 | |
716 | mp4ff_read_stsd(f); |
| 13 | | Calling 'mp4ff_read_stsd' | |
|
717 | } else if (atom_type == ATOM_MVHD131) { |
718 | |
719 | mp4ff_read_mvhd(f); |
720 | } else if (atom_type == ATOM_MDHD134) { |
721 | |
722 | mp4ff_read_mdhd(f); |
723 | #ifdef USE_TAGGING1 |
724 | } else if (atom_type == ATOM_META148) { |
725 | |
726 | mp4ff_read_meta(f, size); |
727 | #endif |
728 | } |
729 | |
730 | mp4ff_set_position(f, dest_position); |
731 | |
732 | |
733 | return 0; |
734 | } |