summaryrefslogtreecommitdiff
path: root/apps/metadata/mp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/metadata/mp4.c')
-rw-r--r--apps/metadata/mp4.c669
1 files changed, 669 insertions, 0 deletions
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
new file mode 100644
index 0000000000..6523bb6551
--- /dev/null
+++ b/apps/metadata/mp4.c
@@ -0,0 +1,669 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "errno.h"
27#include "id3.h"
28#include "metadata_common.h"
29#include "logf.h"
30#include "debug.h"
31#include "replaygain.h"
32
33#define MP4_ID(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
34
35#define MP4_3gp6 MP4_ID('3', 'g', 'p', '6')
36#define MP4_alac MP4_ID('a', 'l', 'a', 'c')
37#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
38#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
39#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
40#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
41#define MP4_esds MP4_ID('e', 's', 'd', 's')
42#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
43#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
44#define MP4_hdlr MP4_ID('h', 'd', 'l', 'r')
45#define MP4_ilst MP4_ID('i', 'l', 's', 't')
46#define MP4_M4A MP4_ID('M', '4', 'A', ' ')
47#define MP4_M4B MP4_ID('M', '4', 'B', ' ')
48#define MP4_mdat MP4_ID('m', 'd', 'a', 't')
49#define MP4_mdia MP4_ID('m', 'd', 'i', 'a')
50#define MP4_mdir MP4_ID('m', 'd', 'i', 'r')
51#define MP4_meta MP4_ID('m', 'e', 't', 'a')
52#define MP4_minf MP4_ID('m', 'i', 'n', 'f')
53#define MP4_moov MP4_ID('m', 'o', 'o', 'v')
54#define MP4_mp4a MP4_ID('m', 'p', '4', 'a')
55#define MP4_mp42 MP4_ID('m', 'p', '4', '2')
56#define MP4_qt MP4_ID('q', 't', ' ', ' ')
57#define MP4_soun MP4_ID('s', 'o', 'u', 'n')
58#define MP4_stbl MP4_ID('s', 't', 'b', 'l')
59#define MP4_stsd MP4_ID('s', 't', 's', 'd')
60#define MP4_stts MP4_ID('s', 't', 't', 's')
61#define MP4_trak MP4_ID('t', 'r', 'a', 'k')
62#define MP4_trkn MP4_ID('t', 'r', 'k', 'n')
63#define MP4_udta MP4_ID('u', 'd', 't', 'a')
64#define MP4_extra MP4_ID('-', '-', '-', '-')
65
66/* Read the tag data from an MP4 file, storing up to buffer_size bytes in
67 * buffer.
68 */
69static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer,
70 unsigned int buffer_left)
71{
72 unsigned int bytes_read = 0;
73
74 if (buffer_left == 0)
75 {
76 lseek(fd, size_left, SEEK_CUR); /* Skip everything */
77 }
78 else
79 {
80 /* Skip the data tag header - maybe we should parse it properly? */
81 lseek(fd, 16, SEEK_CUR);
82 size_left -= 16;
83
84 if (size_left > buffer_left)
85 {
86 read(fd, buffer, buffer_left);
87 lseek(fd, size_left - buffer_left, SEEK_CUR);
88 bytes_read = buffer_left;
89 }
90 else
91 {
92 read(fd, buffer, size_left);
93 bytes_read = size_left;
94 }
95 }
96
97 return bytes_read;
98}
99
100/* Read a string tag from an MP4 file */
101static unsigned int read_mp4_tag_string(int fd, int size_left, char** buffer,
102 unsigned int* buffer_left, char** dest)
103{
104 unsigned int bytes_read = read_mp4_tag(fd, size_left, *buffer,
105 *buffer_left - 1);
106 unsigned int length = 0;
107
108 if (bytes_read)
109 {
110 (*buffer)[bytes_read] = 0;
111 *dest = *buffer;
112 length = strlen(*buffer) + 1;
113 *buffer_left -= length;
114 *buffer += length;
115 }
116 else
117 {
118 *dest = NULL;
119 }
120
121 return length;
122}
123
124static unsigned int read_mp4_atom(int fd, unsigned int* size,
125 unsigned int* type, unsigned int size_left)
126{
127 read_uint32be(fd, size);
128 read_uint32be(fd, type);
129
130 if (*size == 1)
131 {
132 /* FAT32 doesn't support files this big, so something seems to
133 * be wrong. (64-bit sizes should only be used when required.)
134 */
135 errno = EFBIG;
136 *type = 0;
137 return 0;
138 }
139
140 if (*size > 0)
141 {
142 if (*size > size_left)
143 {
144 size_left = 0;
145 }
146 else
147 {
148 size_left -= *size;
149 }
150
151 *size -= 8;
152 }
153 else
154 {
155 *size = size_left;
156 size_left = 0;
157 }
158
159 return size_left;
160}
161
162static unsigned int read_mp4_length(int fd, unsigned int* size)
163{
164 unsigned int length = 0;
165 int bytes = 0;
166 unsigned char c;
167
168 do
169 {
170 read(fd, &c, 1);
171 bytes++;
172 (*size)--;
173 length = (length << 7) | (c & 0x7F);
174 }
175 while ((c & 0x80) && (bytes < 4) && (*size > 0));
176
177 return length;
178}
179
180static bool read_mp4_esds(int fd, struct mp3entry* id3,
181 unsigned int* size)
182{
183 unsigned char buf[8];
184 bool sbr = false;
185
186 lseek(fd, 4, SEEK_CUR); /* Version and flags. */
187 read(fd, buf, 1); /* Verify ES_DescrTag. */
188 *size -= 5;
189
190 if (*buf == 3)
191 {
192 /* read length */
193 if (read_mp4_length(fd, size) < 20)
194 {
195 return sbr;
196 }
197
198 lseek(fd, 3, SEEK_CUR);
199 *size -= 3;
200 }
201 else
202 {
203 lseek(fd, 2, SEEK_CUR);
204 *size -= 2;
205 }
206
207 read(fd, buf, 1); /* Verify DecoderConfigDescrTab. */
208 *size -= 1;
209
210 if (*buf != 4)
211 {
212 return sbr;
213 }
214
215 if (read_mp4_length(fd, size) < 13)
216 {
217 return sbr;
218 }
219
220 lseek(fd, 13, SEEK_CUR); /* Skip audio type, bit rates, etc. */
221 read(fd, buf, 1);
222 *size -= 14;
223
224 if (*buf != 5) /* Verify DecSpecificInfoTag. */
225 {
226 return sbr;
227 }
228
229 {
230 static const int sample_rates[] =
231 {
232 96000, 88200, 64000, 48000, 44100, 32000,
233 24000, 22050, 16000, 12000, 11025, 8000
234 };
235 unsigned long bits;
236 unsigned int length;
237 unsigned int index;
238 unsigned int type;
239
240 /* Read the (leading part of the) decoder config. */
241 length = read_mp4_length(fd, size);
242 length = MIN(length, *size);
243 length = MIN(length, sizeof(buf));
244 memset(buf, 0, sizeof(buf));
245 read(fd, buf, length);
246 *size -= length;
247
248 /* Maybe time to write a simple read_bits function... */
249
250 /* Decoder config format:
251 * Object type - 5 bits
252 * Frequency index - 4 bits
253 * Channel configuration - 4 bits
254 */
255 bits = get_long_be(buf);
256 type = bits >> 27; /* Object type - 5 bits */
257 index = (bits >> 23) & 0xf; /* Frequency index - 4 bits */
258
259 if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
260 {
261 id3->frequency = sample_rates[index];
262 }
263
264 if (type == 5)
265 {
266 DEBUGF("MP4: SBR\n");
267 unsigned int old_index = index;
268
269 sbr = true;
270 index = (bits >> 15) & 0xf; /* Frequency index - 4 bits */
271
272 if (index == 15)
273 {
274 /* 17 bits read so far... */
275 bits = get_long_be(&buf[2]);
276 id3->frequency = (bits >> 7) & 0x00ffffff;
277 }
278 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
279 {
280 id3->frequency = sample_rates[index];
281 }
282
283 if (old_index == index)
284 {
285 /* Downsampled SBR */
286 id3->frequency *= 2;
287 }
288 }
289 /* Skip 13 bits from above, plus 3 bits, then read 11 bits */
290 else if ((length >= 4) && (((bits >> 5) & 0x7ff) == 0x2b7))
291 {
292 /* extensionAudioObjectType */
293 DEBUGF("MP4: extensionAudioType\n");
294 type = bits & 0x1f; /* Object type - 5 bits*/
295 bits = get_long_be(&buf[4]);
296
297 if (type == 5)
298 {
299 sbr = bits >> 31;
300
301 if (sbr)
302 {
303 unsigned int old_index = index;
304
305 /* 1 bit read so far */
306 index = (bits >> 27) & 0xf; /* Frequency index - 4 bits */
307
308 if (index == 15)
309 {
310 /* 5 bits read so far */
311 id3->frequency = (bits >> 3) & 0x00ffffff;
312 }
313 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
314 {
315 id3->frequency = sample_rates[index];
316 }
317
318 if (old_index == index)
319 {
320 /* Downsampled SBR */
321 id3->frequency *= 2;
322 }
323 }
324 }
325 }
326
327 if (!sbr && (id3->frequency <= 24000) && (length <= 2))
328 {
329 /* Double the frequency for low-frequency files without a "long"
330 * DecSpecificConfig header. The file may or may not contain SBR,
331 * but here we guess it does if the header is short. This can
332 * fail on some files, but it's the best we can do, short of
333 * decoding (parts of) the file.
334 */
335 id3->frequency *= 2;
336 }
337 }
338
339 return sbr;
340}
341
342static bool read_mp4_tags(int fd, struct mp3entry* id3,
343 unsigned int size_left)
344{
345 unsigned int size;
346 unsigned int type;
347 unsigned int buffer_left = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
348 char* buffer = id3->id3v2buf;
349 bool cwrt = false;
350
351 do
352 {
353 size_left = read_mp4_atom(fd, &size, &type, size_left);
354
355 /* DEBUGF("Tag atom: '%c%c%c%c' (%d bytes left)\n", type >> 24 & 0xff,
356 type >> 16 & 0xff, type >> 8 & 0xff, type & 0xff, size); */
357
358 switch (type)
359 {
360 case MP4_cnam:
361 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
362 &id3->title);
363 break;
364
365 case MP4_cART:
366 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
367 &id3->artist);
368 break;
369
370 case MP4_calb:
371 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
372 &id3->album);
373 break;
374
375 case MP4_cwrt:
376 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
377 &id3->composer);
378 cwrt = false;
379 break;
380
381 case MP4_gnre:
382 {
383 unsigned short genre;
384
385 read_mp4_tag(fd, size, (char*) &genre, sizeof(genre));
386 id3->genre_string = id3_get_num_genre(betoh16(genre) - 1);
387 }
388 break;
389
390 case MP4_trkn:
391 {
392 unsigned short n[2];
393
394 read_mp4_tag(fd, size, (char*) &n, sizeof(n));
395 id3->tracknum = betoh16(n[1]);
396 }
397 break;
398
399 case MP4_extra:
400 {
401 char tag_name[TAG_NAME_LENGTH];
402 unsigned int sub_size;
403
404 /* "mean" atom */
405 read_uint32be(fd, &sub_size);
406 size -= sub_size;
407 lseek(fd, sub_size - 4, SEEK_CUR);
408 /* "name" atom */
409 read_uint32be(fd, &sub_size);
410 size -= sub_size;
411 lseek(fd, 8, SEEK_CUR);
412 sub_size -= 12;
413
414 if (sub_size > sizeof(tag_name) - 1)
415 {
416 read(fd, tag_name, sizeof(tag_name) - 1);
417 lseek(fd, sub_size - sizeof(tag_name) - 1, SEEK_CUR);
418 tag_name[sizeof(tag_name) - 1] = 0;
419 }
420 else
421 {
422 read(fd, tag_name, sub_size);
423 tag_name[sub_size] = 0;
424 }
425
426 if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
427 {
428 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
429 &id3->composer);
430 }
431 else if (strcasecmp(tag_name, "iTunSMPB") == 0)
432 {
433 char value[TAG_VALUE_LENGTH];
434 char* value_p = value;
435 char* any;
436 unsigned int length = sizeof(value);
437
438 read_mp4_tag_string(fd, size, &value_p, &length, &any);
439 id3->lead_trim = get_itunes_int32(value, 1);
440 id3->tail_trim = get_itunes_int32(value, 2);
441 DEBUGF("AAC: lead_trim %d, tail_trim %d\n",
442 id3->lead_trim, id3->tail_trim);
443 }
444 else
445 {
446 char* any;
447 unsigned int length = read_mp4_tag_string(fd, size,
448 &buffer, &buffer_left, &any);
449
450 if (length > 0)
451 {
452 /* Re-use the read buffer as the dest buffer... */
453 buffer -= length;
454 buffer_left += length;
455
456 if (parse_replaygain(tag_name, buffer, id3,
457 buffer, buffer_left) > 0)
458 {
459 /* Data used, keep it. */
460 buffer += length;
461 buffer_left -= length;
462 }
463 }
464 }
465 }
466 break;
467
468 default:
469 lseek(fd, size, SEEK_CUR);
470 break;
471 }
472 }
473 while ((size_left > 0) && (errno == 0));
474
475 return true;
476}
477
478static bool read_mp4_container(int fd, struct mp3entry* id3,
479 unsigned int size_left)
480{
481 unsigned int size;
482 unsigned int type;
483 unsigned int handler = 0;
484 bool rc = true;
485
486 do
487 {
488 size_left = read_mp4_atom(fd, &size, &type, size_left);
489
490 /* DEBUGF("Atom: '%c%c%c%c' (0x%08x, %d bytes left)\n",
491 (type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff,
492 type & 0xff, type, size); */
493
494 switch (type)
495 {
496 case MP4_ftyp:
497 {
498 unsigned int id;
499
500 read_uint32be(fd, &id);
501 size -= 4;
502
503 if ((id != MP4_M4A) && (id != MP4_M4B) && (id != MP4_mp42)
504 && (id != MP4_qt) && (id != MP4_3gp6))
505 {
506 DEBUGF("Unknown MP4 file type: '%c%c%c%c'\n",
507 id >> 24 & 0xff, id >> 16 & 0xff, id >> 8 & 0xff,
508 id & 0xff);
509 return false;
510 }
511 }
512 break;
513
514 case MP4_meta:
515 lseek(fd, 4, SEEK_CUR); /* Skip version */
516 size -= 4;
517 /* Fall through */
518
519 case MP4_moov:
520 case MP4_udta:
521 case MP4_mdia:
522 case MP4_stbl:
523 case MP4_trak:
524 rc = read_mp4_container(fd, id3, size);
525 size = 0;
526 break;
527
528 case MP4_ilst:
529 if (handler == MP4_mdir)
530 {
531 rc = read_mp4_tags(fd, id3, size);
532 size = 0;
533 }
534 break;
535
536 case MP4_minf:
537 if (handler == MP4_soun)
538 {
539 rc = read_mp4_container(fd, id3, size);
540 size = 0;
541 }
542 break;
543
544 case MP4_stsd:
545 lseek(fd, 8, SEEK_CUR);
546 size -= 8;
547 rc = read_mp4_container(fd, id3, size);
548 size = 0;
549 break;
550
551 case MP4_hdlr:
552 lseek(fd, 8, SEEK_CUR);
553 read_uint32be(fd, &handler);
554 size -= 12;
555 /* DEBUGF(" Handler '%c%c%c%c'\n", handler >> 24 & 0xff,
556 handler >> 16 & 0xff, handler >> 8 & 0xff,handler & 0xff); */
557 break;
558
559 case MP4_stts:
560 {
561 unsigned int entries;
562 unsigned int i;
563
564 lseek(fd, 4, SEEK_CUR);
565 read_uint32be(fd, &entries);
566 id3->samples = 0;
567
568 for (i = 0; i < entries; i++)
569 {
570 unsigned int n;
571 unsigned int l;
572
573 read_uint32be(fd, &n);
574 read_uint32be(fd, &l);
575 id3->samples += n * l;
576 }
577
578 size = 0;
579 }
580 break;
581
582 case MP4_mp4a:
583 case MP4_alac:
584 {
585 unsigned int frequency;
586
587 id3->codectype = (type == MP4_mp4a) ? AFMT_AAC : AFMT_ALAC;
588 lseek(fd, 22, SEEK_CUR);
589 read_uint32be(fd, &frequency);
590 size -= 26;
591 id3->frequency = frequency;
592
593 if (type == MP4_mp4a)
594 {
595 unsigned int subsize;
596 unsigned int subtype;
597
598 /* Get frequency from the decoder info tag, if possible. */
599 lseek(fd, 2, SEEK_CUR);
600 /* The esds atom is a part of the mp4a atom, so ignore
601 * the returned size (it's already accounted for).
602 */
603 read_mp4_atom(fd, &subsize, &subtype, size);
604 size -= 10;
605
606 if (subtype == MP4_esds)
607 {
608 read_mp4_esds(fd, id3, &size);
609 }
610 }
611 }
612 break;
613
614 case MP4_mdat:
615 id3->filesize = size;
616 break;
617
618 default:
619 break;
620 }
621
622 lseek(fd, size, SEEK_CUR);
623 }
624 while (rc && (size_left > 0) && (errno == 0) && (id3->filesize == 0));
625 /* Break on non-zero filesize, since Rockbox currently doesn't support
626 * metadata after the mdat atom (which sets the filesize field).
627 */
628
629 return rc;
630}
631
632bool get_mp4_metadata(int fd, struct mp3entry* id3)
633{
634 id3->codectype = AFMT_UNKNOWN;
635 id3->filesize = 0;
636 errno = 0;
637
638 if (read_mp4_container(fd, id3, filesize(fd)) && (errno == 0)
639 && (id3->samples > 0) && (id3->frequency > 0)
640 && (id3->filesize > 0))
641 {
642 if (id3->codectype == AFMT_UNKNOWN)
643 {
644 logf("Not an ALAC or AAC file");
645 return false;
646 }
647
648 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
649
650 if (id3->length <= 0)
651 {
652 logf("mp4 length invalid!");
653 return false;
654 }
655
656 id3->bitrate = ((int64_t) id3->filesize * 8) / id3->length;
657 DEBUGF("MP4 bitrate %d, frequency %ld Hz, length %ld ms\n",
658 id3->bitrate, id3->frequency, id3->length);
659 }
660 else
661 {
662 logf("MP4 metadata error");
663 DEBUGF("MP4 metadata error. errno %d, length %ld, frequency %ld, filesize %ld\n",
664 errno, id3->length, id3->frequency, id3->filesize);
665 return false;
666 }
667
668 return true;
669}