2 * Copyright (C) 2008-2011 by ProFUSION embedded systems
3 * Copyright (C) 2008 by INdT
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * @author Andre Moreira Magalhaes <andre.magalhaes@openbossa.org>
21 * @author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
30 * http://www.mp3-tech.org/programmer/frame_header.html
31 * http://www.mpgedit.org/mpgedit/mpeg_format/MP3Format.html
32 * http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
33 * http://id3.org/id3v2.3.0
36 #include <lightmediascanner_plugin.h>
37 #include <lightmediascanner_db.h>
38 #include <lightmediascanner_charset_conv.h>
39 #include <shared/util.h>
41 #include <sys/types.h>
51 #define DECL_STR(cname, str) \
52 static const struct lms_string_size cname = LMS_STATIC_STRING_SIZE(str)
54 DECL_STR(_codec_mpeg1layer1, "mpeg1layer1");
55 DECL_STR(_codec_mpeg1layer2, "mpeg1layer2");
56 DECL_STR(_codec_mpeg1layer3, "mpeg1layer3");
57 DECL_STR(_codec_mpeg2layer1, "mpeg2layer1");
58 DECL_STR(_codec_mpeg2layer2, "mpeg2layer2");
59 DECL_STR(_codec_mpeg2layer3, "mpeg2layer3");
60 DECL_STR(_codec_mpeg2_5layer1, "mpeg2.5layer1");
61 DECL_STR(_codec_mpeg2_5layer2, "mpeg2.5layer2");
62 DECL_STR(_codec_mpeg2_5layer3, "mpeg2.5layer3");
63 DECL_STR(_codec_mpeg2aac_main, "mpeg2aac-main");
64 DECL_STR(_codec_mpeg2aac_lc, "mpeg2aac-lc");
65 DECL_STR(_codec_mpeg2aac_ssr, "mpeg2aac-ssr");
66 DECL_STR(_codec_mpeg2aac_ltp, "mpeg2aac-ltp");
67 DECL_STR(_codec_mpeg4aac_main, "mpeg4aac-main");
68 DECL_STR(_codec_mpeg4aac_lc, "mpeg4aac-lc");
69 DECL_STR(_codec_mpeg4aac_ssr, "mpeg4aac-ssr");
70 DECL_STR(_codec_mpeg4aac_ltp, "mpeg4aac-ltp");
72 DECL_STR(_dlna_mp3, "MP3");
73 DECL_STR(_dlna_mp3x, "MP3X");
75 DECL_STR(_dlna_aac_adts_320, "AAC_ADTS_320");
76 DECL_STR(_dlna_aac_adts, "AAC_ADTS");
77 DECL_STR(_dlna_aac_adts_mult5, "AAC_MULT5_ADTS");
79 DECL_STR(_dlna_mime_mpeg, "audio/mpeg");
80 DECL_STR(_dlna_mime_adts, "audio/vnd.dlna.adts");
85 _fill_dlna_profile(struct lms_audio_info *info)
87 if ((info->channels == 1 || info->channels == 2) &&
88 (info->sampling_rate == 32000 ||
89 info->sampling_rate == 44100 ||
90 info->sampling_rate == 48000) &&
91 (info->bitrate >= 32000 && info->bitrate <= 320000) &&
92 info->codec.str == _codec_mpeg1layer3.str) {
93 info->dlna_profile = _dlna_mp3;
94 info->dlna_mime = _dlna_mime_mpeg;
96 (info->channels == 1 || info->channels == 2) &&
97 (info->sampling_rate == 16000 ||
98 info->sampling_rate == 22050 ||
99 info->sampling_rate == 24000 ||
100 info->sampling_rate == 32000 ||
101 info->sampling_rate == 44100 ||
102 info->sampling_rate == 48000) &&
103 (info->bitrate >= 8000 && info->bitrate <= 320000) &&
104 (info->codec.str == _codec_mpeg1layer1.str ||
105 info->codec.str == _codec_mpeg1layer2.str ||
106 info->codec.str == _codec_mpeg1layer3.str ||
107 info->codec.str == _codec_mpeg2layer1.str ||
108 info->codec.str == _codec_mpeg2layer2.str ||
109 info->codec.str == _codec_mpeg2layer3.str)) {
110 info->dlna_profile = _dlna_mp3x;
111 info->dlna_mime = _dlna_mime_mpeg;
113 (info->sampling_rate == 8000 ||
114 info->sampling_rate == 11025 ||
115 info->sampling_rate == 12000 ||
116 info->sampling_rate == 16000 ||
117 info->sampling_rate == 22050 ||
118 info->sampling_rate == 24000 ||
119 info->sampling_rate == 32000 ||
120 info->sampling_rate == 44100 ||
121 info->sampling_rate == 48000) &&
122 (info->codec.str == _codec_mpeg2aac_lc.str ||
123 info->codec.str == _codec_mpeg4aac_lc.str)) {
125 if (info->channels == 1 || info->channels == 2) {
126 if (info->bitrate <= 320000) {
127 info->dlna_profile = _dlna_aac_adts_320;
128 info->dlna_mime = _dlna_mime_adts;
129 } else if (info->bitrate <= 576000) {
130 info->dlna_profile = _dlna_aac_adts;
131 info->dlna_mime = _dlna_mime_adts;
133 } else if ((info->channels >= 1 && info->channels <= 6) &&
134 (info->bitrate <= 1440000)) {
135 info->dlna_profile = _dlna_aac_adts_mult5;
136 info->dlna_mime = _dlna_mime_adts;
141 #define ID3V2_HEADER_SIZE 10
142 #define ID3V2_FOOTER_SIZE 10
144 #define MPEG_HEADER_SIZE 4
146 /* TODO: The higher these numbers are, the more performance impact you get
147 * when parsing mp3. However the lower they are, the more imprecise bitrate
148 * _and_ length estimate will be. Investigate which would be the best numbers
150 #define N_FRAMES_BITRATE_ESTIMATE 512
151 #define N_FRAMES_CBR_ESTIMATE 128
153 enum mpeg_audio_version {
154 MPEG_AUDIO_VERSION_1,
155 MPEG_AUDIO_VERSION_2,
156 MPEG_AUDIO_VERSION_2_5,
157 MPEG_AUDIO_VERSION_4,
158 _MPEG_AUDIO_VERSION_COUNT
161 enum mpeg_audio_layer {
165 MPEG_AUDIO_LAYER_AAC,
166 _MPEG_AUDIO_LAYER_COUNT
170 enum mpeg_audio_version version;
171 enum mpeg_audio_layer layer;
176 uint8_t sampling_rate_idx;
178 unsigned int bitrate_idx;
180 unsigned int bitrate;
185 static const struct lms_string_size *_codecs[] = {
187 [0] = &_codec_mpeg1layer1,
188 [1] = &_codec_mpeg1layer2,
189 [2] = &_codec_mpeg1layer3,
190 [3] = &_codec_mpeg2layer1,
191 [4] = &_codec_mpeg2layer2,
192 [5] = &_codec_mpeg2layer3,
193 [6] = &_codec_mpeg2_5layer1,
194 [7] = &_codec_mpeg2_5layer2,
195 [8] = &_codec_mpeg2_5layer3,
198 #define MPEG_CODEC_AAC_START 9
199 [9] = &_codec_mpeg2aac_main,
200 [10] = &_codec_mpeg2aac_lc,
201 [11] = &_codec_mpeg2aac_ssr,
202 [12] = &_codec_mpeg2aac_ltp,
204 [13] = &_codec_mpeg4aac_main,
205 [14] = &_codec_mpeg4aac_lc,
206 [15] = &_codec_mpeg4aac_ssr,
207 [16] = &_codec_mpeg4aac_ltp,
211 /* Ordered according to AAC index, take care with mp3 */
212 static int _sample_rates[16] = {
215 /* Frequencies available on mp3, */
220 7350, /* reserved, zeroed */
224 _bitrate_table[_MPEG_AUDIO_VERSION_COUNT][_MPEG_AUDIO_LAYER_COUNT][16] = {
225 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_1] = {
226 0,32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
227 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_2] = {
228 0,32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
229 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_3] = {
230 0,32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
231 [MPEG_AUDIO_VERSION_2][MPEG_AUDIO_LAYER_2] = {
232 0,32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
233 [MPEG_AUDIO_VERSION_2][MPEG_AUDIO_LAYER_3] = {
234 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
235 [MPEG_AUDIO_VERSION_2_5][MPEG_AUDIO_LAYER_2] = {
236 0,32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
237 [MPEG_AUDIO_VERSION_2_5][MPEG_AUDIO_LAYER_3] = {
238 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
242 _samples_per_frame_table[_MPEG_AUDIO_VERSION_COUNT][_MPEG_AUDIO_LAYER_COUNT] = {
243 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_1] = 384,
244 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_2] = 1152,
245 [MPEG_AUDIO_VERSION_1][MPEG_AUDIO_LAYER_3] = 1152,
246 [MPEG_AUDIO_VERSION_2][MPEG_AUDIO_LAYER_1] = 384,
247 [MPEG_AUDIO_VERSION_2][MPEG_AUDIO_LAYER_2] = 1152,
248 [MPEG_AUDIO_VERSION_2][MPEG_AUDIO_LAYER_3] = 576,
249 [MPEG_AUDIO_VERSION_2_5][MPEG_AUDIO_LAYER_1] = 384,
250 [MPEG_AUDIO_VERSION_2_5][MPEG_AUDIO_LAYER_2] = 1152,
251 [MPEG_AUDIO_VERSION_2_5][MPEG_AUDIO_LAYER_3] = 576,
255 ID3_ENCODING_LATIN1 = 0,
257 ID3_ENCODING_UTF16BE,
259 ID3_ENCODING_UTF16LE,
262 #define ID3_NUM_ENCODINGS ID3_ENCODING_LAST
265 #include "id3v1_genres.c"
268 struct lms_string_size title;
269 struct lms_string_size artist;
270 struct lms_string_size album;
271 struct lms_string_size genre;
273 int cur_artist_priority;
276 struct id3v2_frame_header {
278 unsigned int frame_size;
280 int data_length_indicator;
290 } __attribute__((packed));
293 struct lms_plugin plugin;
294 lms_db_audio_t *audio_db;
295 lms_charset_conv_t *cs_convs[ID3_NUM_ENCODINGS];
298 static const char _name[] = "id3";
299 static const struct lms_string_size _exts[] = {
300 LMS_STATIC_STRING_SIZE(".mp3"),
301 LMS_STATIC_STRING_SIZE(".aac"),
302 LMS_STATIC_STRING_SIZE(".adts"),
304 static const char *_cats[] = {
309 static const char *_authors[] = {
310 "Andre Moreira Magalhaes",
311 "Gustavo Sverzut Barbieri",
316 _to_uint(const char *data, int data_size)
318 unsigned int sum = 0;
319 unsigned int last, i;
321 last = data_size > 4 ? 3 : data_size - 1;
323 for (i = 0; i <= last; i++)
324 sum |= ((unsigned char) data[i]) << ((last - i) * 8);
330 _to_uint_max7b(const char *data, int data_size)
332 unsigned int sum = 0;
333 unsigned int last, i;
335 last = data_size > 4 ? 3 : data_size - 1;
337 for (i = 0; i <= last; i++)
338 sum |= ((unsigned char) data[i]) << ((last - i) * 7);
344 _is_id3v2_second_synch_byte(unsigned char byte)
348 if ((byte & 0xE0) == 0xE0)
354 _fill_mp3_header(struct mpeg_header *hdr, const uint8_t b[4])
356 unsigned int bitrate_idx = (b[2] & 0xF0) >> 4;
358 hdr->sampling_rate_idx = (b[2] & 0x0C) >> 2;
360 if (hdr->sampling_rate_idx == 0x3)
363 * Sampling rate frequency index
364 * bits MPEG1 MPEG2 MPEG2.5
365 * 00 44100 Hz 22050 Hz 11025 Hz
366 * 01 48000 Hz 24000 Hz 12000 Hz
367 * 10 32000 Hz 16000 Hz 8000 Hz
368 * 11 reserv. reserv. reserv.
371 /* swap 0x1 and 0x0 */
372 if (hdr->sampling_rate_idx < 0x2)
373 hdr->sampling_rate_idx = !hdr->sampling_rate_idx;
374 hdr->sampling_rate_idx += 3 * hdr->version + 3;
376 hdr->codec_idx = hdr->version * 3 + hdr->layer;
378 hdr->channels = (b[3] & 0xC0) >> 6;
379 hdr->channels = hdr->channels == 0x3 ? 1 : 2;
381 hdr->bitrate_idx = bitrate_idx;
387 _fill_aac_header(struct mpeg_header *hdr, const uint8_t b[4])
389 unsigned int profile;
391 hdr->sampling_rate_idx = (b[2] & 0x3C) >> 2;
393 profile = (b[2] & 0xC0) >> 6;
394 hdr->codec_idx = MPEG_CODEC_AAC_START + profile;
395 if (hdr->version == MPEG_AUDIO_VERSION_4)
398 hdr->channels = ((b[2] & 0x1) << 2) | ((b[3] & 0xC0) >> 6);
403 _fill_mpeg_header(struct mpeg_header *hdr, const uint8_t b[4])
405 unsigned int version = (b[1] & 0x18) >> 3;
406 unsigned int layer = (b[1] & 0x06) >> 1;
410 if (version == 0x2 || version == 0x3)
411 hdr->layer = MPEG_AUDIO_LAYER_AAC;
416 hdr->layer = MPEG_AUDIO_LAYER_3;
419 hdr->layer = MPEG_AUDIO_LAYER_2;
422 hdr->layer = MPEG_AUDIO_LAYER_1;
428 hdr->version = MPEG_AUDIO_VERSION_2_5;
434 hdr->version = MPEG_AUDIO_VERSION_4;
436 hdr->version = MPEG_AUDIO_VERSION_2;
440 hdr->version = MPEG_AUDIO_VERSION_2;
442 hdr->version = MPEG_AUDIO_VERSION_1;
445 hdr->crc = !(b[1] & 0x1);
446 hdr->padding = b[2] & 0x2;
452 _estimate_mp3_bitrate_from_frames(int fd, off_t mpeg_offset,
453 struct mpeg_header *orig_hdr)
455 struct mpeg_header hdr = *orig_hdr;
456 off_t offset = mpeg_offset;
457 unsigned int sum = 0, i;
460 /* For Layer I slot is 32 bits long, for Layer II and Layer III slot is 8
463 unsigned int padding_size_table[2] = { 1, 4 };
464 unsigned int samples_per_frame, sampling_rate;
466 samples_per_frame = _samples_per_frame_table[hdr.version][hdr.layer];
467 sampling_rate = _sample_rates[hdr.sampling_rate_idx];
468 assert(sampling_rate != 0);
470 for (i = 0; i < N_FRAMES_BITRATE_ESTIMATE;) {
471 unsigned int bitrate, padding_size;
472 unsigned int framesize;
475 bitrate = _bitrate_table[hdr.version][hdr.layer][hdr.bitrate_idx];
476 if (cbr && bitrate == hdr.bitrate && i > N_FRAMES_CBR_ESTIMATE) {
485 padding_size = hdr.padding ? padding_size_table[hdr.layer == 1] : 0;
487 framesize = 4; /* mpeg header */
488 framesize += (samples_per_frame / 8) * bitrate * 1000;
489 framesize /= sampling_rate;
490 framesize += (padding_size * samples_per_frame);
494 lseek(fd, offset, SEEK_SET);
495 r = read(fd, buf, sizeof(buf));
498 fprintf(stderr, "ERROR reading frame header at %#x\n",
499 (unsigned int) offset);
505 if (buf[0] != 0xff || !_is_id3v2_second_synch_byte(buf[1]) ||
506 _fill_mpeg_header(&hdr, buf) < 0 ||
507 _fill_mp3_header(&hdr, buf) < 0) {
508 fprintf(stderr, "ERROR interpreting frame header at 0x%x:"
509 "%#02x %#02x %#02x %#02x\n", (unsigned int) offset,
510 buf[0], buf[1], buf[2], buf[3]);
515 orig_hdr->bitrate = sum / i * 1000;
521 _parse_vbr_headers(int fd, off_t mpeg_offset, struct mpeg_header *hdr)
523 unsigned int sampling_rate, samples_per_frame, flags, nframes = 0, size = 0;
524 int xing_offset_table[2][2] = { /* [(version == 1)][channels == 1)] */
531 /* Try Xing first since it's the most likely to be there */
532 xing_offset = mpeg_offset + 4 + 2 * hdr->crc
533 + xing_offset_table[(hdr->version == 1)][(hdr->channels == 1)];
535 lseek(fd, xing_offset, SEEK_SET);
536 if (read(fd, buf, sizeof(buf)) != sizeof(buf))
539 hdr->cbr = (memcmp(buf, "Info", 4) == 0);
540 if (hdr->cbr || memcmp(buf, "Xing", 4) == 0) {
544 nframes = get_be32(&buf[8]);
546 size = get_be32(&buf[8 + !!(flags & 1) * 4]);
551 /* VBRI is found in files encoded by Fraunhofer Encoder. Fixed location: 32
552 * bytes after the mpeg header */
553 lseek(fd, mpeg_offset + 36, SEEK_SET);
554 if (read(fd, buf, sizeof(buf)) != sizeof(buf))
557 if (memcmp(buf, "VBRI", 4) == 0 && get_be16(buf) == 1) {
558 size = get_be32(&buf[10]);
559 nframes = get_be32(&buf[14]);
567 samples_per_frame = _samples_per_frame_table[hdr->version][hdr->layer];
568 sampling_rate = _sample_rates[hdr->sampling_rate_idx];
569 assert(sampling_rate != 0);
571 hdr->length = (nframes * samples_per_frame) / sampling_rate;
574 hdr->bitrate = (8 * size) / (1000 * hdr->length);
580 _parse_mpeg_header(int fd, off_t off, struct lms_audio_info *audio_info,
584 const uint8_t *p, *p_end;
585 unsigned int prev_read;
586 struct mpeg_header hdr = { };
589 lseek(fd, off, SEEK_SET);
594 int nread = read(fd, buffer + prev_read, sizeof(buffer) - prev_read);
595 if (nread < MPEG_HEADER_SIZE)
599 p_end = buffer + nread;
600 off += nread - prev_read;
601 while (p < p_end && (p = memchr(p, 0xFF, p_end - p))) {
602 /* poor man's ring buffer since the needle is small (4 bytes) */
603 if (p > p_end - MPEG_HEADER_SIZE) {
604 memcpy(buffer, p, p_end - p);
608 if (_is_id3v2_second_synch_byte(*(p + 1))) {
615 prev_read = p ? p_end - p : 0;
619 if (_fill_mpeg_header(&hdr, p) < 0) {
620 fprintf(stderr, "Invalid field in file, ignoring.\n");
624 if (hdr.layer == MPEG_AUDIO_LAYER_AAC)
625 r = _fill_aac_header(&hdr, p);
627 if ((r = _fill_mp3_header(&hdr, p) < 0) ||
628 (r = _parse_vbr_headers(fd, off, &hdr) < 0))
633 _bitrate_table[hdr.version][hdr.layer][hdr.bitrate_idx] * 1000;
634 else if (!hdr.bitrate) {
635 r = _estimate_mp3_bitrate_from_frames(fd, off, &hdr);
641 hdr.length = (8 * (size - off)) / (1000 * hdr.bitrate);
647 audio_info->codec = *_codecs[hdr.codec_idx];
648 audio_info->sampling_rate = _sample_rates[hdr.sampling_rate_idx];
649 audio_info->channels = hdr.channels;
650 audio_info->bitrate = hdr.bitrate;
651 audio_info->length = hdr.length;
656 /* Returns the offset in fd to the position after the ID3 tag, iff it occurs
657 * *before* a sync word. Otherwise < 0 is returned and if we gave up looking
658 * after ID3 because of a sync value, @syncframe_offset is set to its
659 * correspondent offset */
661 _find_id3v2(int fd, off_t *sync_offset)
663 static const char pattern[3] = "ID3";
665 unsigned int prev_part_match, prev_part_match_sync = 0;
668 if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer))
671 if (memcmp(buffer, pattern, sizeof(pattern)) == 0)
674 /* This loop is the crux of the find method. There are three cases that we
675 * want to account for:
676 * (1) The previously searched buffer contained a partial match of the
677 * search pattern and we want to see if the next one starts with the
678 * remainder of that pattern.
680 * (2) The search pattern is wholly contained within the current buffer.
682 * (3) The current buffer ends with a partial match of the pattern. We will
683 * note this for use in the next iteration, where we will check for the rest
687 prev_part_match_sync = 0;
690 const char *p, *p_end;
692 /* (1) previous partial match */
693 if (prev_part_match_sync) {
694 if (_is_id3v2_second_synch_byte(buffer[0])) {
695 *sync_offset = buffer_offset - 1;
698 prev_part_match_sync = 0;
701 if (prev_part_match) {
702 const int size = sizeof(buffer) - prev_part_match;
703 const char *part_pattern = pattern + prev_part_match;
705 if (memcmp(buffer, part_pattern, size) == 0)
706 return buffer_offset - prev_part_match;
711 p_end = buffer + sizeof(buffer);
712 for (p = buffer; p < p_end; p++) {
713 if (*p == pattern[0]) {
714 /* Try to match pattern, possible partial contents */
720 if (todo == 0 || memcmp(q, pattern + 1, todo) == 0) {
722 if (todo == sizeof(buffer))
723 /* (2) pattern contained in current buffer */
724 return buffer_offset;
726 /* (3) partial match */
727 prev_part_match = todo;
730 } else if ((unsigned char)*p == 0xff) {
731 /* Try to match synch pattern, possible partial contents */
736 if (_is_id3v2_second_synch_byte(*q)) {
737 /* (2) synch pattern contained in current buffer */
738 *sync_offset = buffer_offset + (p - buffer);
742 /* (3) partial match */
743 prev_part_match_sync = 1;
747 if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer))
749 buffer_offset += sizeof(buffer);
756 _get_id3v2_frame_header_size(unsigned int version)
771 _parse_id3v2_frame_header(char *data, unsigned int version, struct id3v2_frame_header *fh)
777 memcpy(fh->frame_id, data, 3);
779 fh->frame_size = _to_uint(data + 3, 3);
781 fh->data_length_indicator = 0;
784 memcpy(fh->frame_id, data, 4);
785 fh->frame_size = _to_uint(data + 4, 4);
786 fh->compression = data[9] & 0x40;
787 fh->data_length_indicator = 0;
791 memcpy(fh->frame_id, data, 4);
792 fh->frame_size = _to_uint(data + 4, 4);
793 fh->compression = data[9] & 0x4;
794 fh->data_length_indicator = data[9] & 0x1;
800 _get_id3v2_frame_info(const char *frame_data, unsigned int frame_size, struct lms_string_size *s, lms_charset_conv_t *cs_conv, int strip)
804 if (frame_size > s->len) {
807 tmp = realloc(s->str, sizeof(char) * (frame_size + 1));
812 memcpy(s->str, frame_data, frame_size);
813 s->str[frame_size] = '\0';
816 lms_charset_conv(cs_conv, &s->str, &s->len);
818 lms_string_size_strip_and_free(s);
822 _get_id3v2_artist(unsigned int index, const char *frame_data, unsigned int frame_size, struct id3_info *info, lms_charset_conv_t *cs_conv)
824 static const unsigned char artist_priorities[] = {3, 4, 2, 1};
825 const unsigned int index_max = sizeof(artist_priorities) / sizeof(*artist_priorities);
827 if (index >= index_max)
830 if (artist_priorities[index] > info->cur_artist_priority) {
831 struct lms_string_size artist = { };
833 _get_id3v2_frame_info(frame_data, frame_size, &artist, cs_conv, 1);
835 free(info->artist.str);
836 info->artist = artist;
837 info->cur_artist_priority = artist_priorities[index];
844 _get_id3v1_genre(unsigned int genre, struct lms_string_size *out)
846 if (genre < ID3V1_NUM_GENRES) {
847 unsigned int size, base, len;
849 base = id3v1_genres_offsets[genre];
850 size = id3v1_genres_offsets[genre + 1] - base;
853 if (len > out->len) {
854 char *p = realloc(out->str, size);
861 memcpy(out->str, id3v1_genres_mem + base, size);
869 _parse_id3v1_genre(const char *str_genre, struct lms_string_size *out)
871 return _get_id3v1_genre(atoi(str_genre), out);
875 _get_id3v2_genre(const char *frame_data, unsigned int frame_size, struct lms_string_size *out, lms_charset_conv_t *cs_conv)
877 unsigned int i, is_number;
878 struct lms_string_size genre = { };
880 _get_id3v2_frame_info(frame_data, frame_size, &genre, cs_conv, 1);
884 is_number = (genre.len != 0 && genre.str[0] != '(');
886 for (i = 0; i < genre.len; ++i) {
887 if (!isdigit(genre.str[i])) {
894 if (is_number && _parse_id3v1_genre(genre.str, out) == 0) {
895 /* id3v1 genre found */
900 /* ID3v2.3 "content type" can contain a ID3v1 genre number in parenthesis at
901 * the beginning of the field. If this is all that the field contains, do a
902 * translation from that number to the name and return that. If there is a
903 * string folloing the ID3v1 genre number, that is considered to be
904 * authoritative and we return that instead. Or finally, the field may
905 * simply be free text, in which case we just return the value. */
907 if (genre.len > 1 && genre.str[0] == '(') {
908 char *closing = NULL;
910 if (genre.str[genre.len - 1] == ')') {
911 closing = strchr(genre.str, ')');
912 if (closing == genre.str + genre.len - 1) {
913 /* ) is the last character and only appears once in the
914 * string get the id3v1 genre enclosed by parentheses
916 if (_parse_id3v1_genre(genre.str + 1, out) == 0) {
923 /* get the string followed by the id3v1 genre */
925 closing = strchr(genre.str, ')');
929 out->len = genre.len - (closing - genre.str);
930 out->str = genre.str;
931 memmove(out->str, closing, out->len + 1); /* includes '\0' */
932 lms_string_size_strip_and_free(out);
942 _get_id3v2_trackno(const char *frame_data, unsigned int frame_size, struct id3_info *info, lms_charset_conv_t *cs_conv)
944 struct lms_string_size trackno = { };
946 _get_id3v2_frame_info(frame_data, frame_size, &trackno, cs_conv, 0);
949 info->trackno = atoi(trackno.str);
954 _parse_id3v2_frame(struct id3v2_frame_header *fh, const char *frame_data, struct id3_info *info, lms_charset_conv_t **cs_convs)
956 lms_charset_conv_t *cs_conv;
957 unsigned int text_encoding, frame_size;
960 /* ignore frames which contains just the encoding */
961 if (fh->frame_size <= 1)
965 fprintf(stderr, "frame id = %.4s frame size = %d text encoding = %d\n",
966 fh->frame_id, fh->frame_size, frame_data[0]);
969 /* All used frames start with 'T' */
980 text_encoding = frame_data[0];
982 /* skip first byte - text encoding */
984 frame_size = fh->frame_size - 1;
986 if (text_encoding < ID3_NUM_ENCODINGS) {
987 if (text_encoding == ID3_ENCODING_UTF16) {
988 /* ignore frames which contains just the encoding */
992 if (memcmp(frame_data, "\xfe\xff", 2) == 0)
993 text_encoding = ID3_ENCODING_UTF16BE;
995 text_encoding = ID3_ENCODING_UTF16LE;
999 cs_conv = cs_convs[text_encoding];
1003 /* ID3v2.2 used 3 bytes for the frame id, so let's check it */
1004 if ((fid[1] == 'T' && fid[2] == '2') ||
1005 (fid[1] == 'I' && fid[2] == 'T' && fid[3] == '2'))
1006 _get_id3v2_frame_info(frame_data, frame_size, &info->title, cs_conv, 1);
1007 else if (fid[1] == 'P') {
1009 _get_id3v2_artist(fid[3] - '1', frame_data, frame_size,
1011 else if (fid[2] >= '1' && fid[2] <= '4')
1012 _get_id3v2_artist(fid[2] - '1', frame_data, frame_size,
1016 else if (fid[1] == 'A' && fid[2] == 'L')
1017 _get_id3v2_frame_info(frame_data, frame_size, &info->album, cs_conv, 1);
1018 /* TCON (Content/Genre) */
1019 else if (fid[1] == 'C' && fid[2] == 'O' && fid[3] == 'N')
1020 _get_id3v2_genre(frame_data, frame_size, &info->genre, cs_conv);
1021 else if (fid[1] == 'R' && (fid[2] == 'K' ||
1022 (fid[2] == 'C' && fid[3] == 'K')))
1023 _get_id3v2_trackno(frame_data, frame_size, info, cs_conv);
1027 _parse_id3v2(int fd, long id3v2_offset, struct id3_info *info,
1028 lms_charset_conv_t **cs_convs, off_t *ptag_size)
1030 char header_data[10], frame_header_data[10];
1031 unsigned int tag_size, major_version, frame_data_pos, frame_data_length, frame_header_size;
1032 int extended_header, footer_present;
1033 struct id3v2_frame_header fh;
1036 lseek(fd, id3v2_offset, SEEK_SET);
1039 if (read(fd, header_data, ID3V2_HEADER_SIZE) != ID3V2_HEADER_SIZE)
1042 tag_size = _to_uint_max7b(header_data + 6, 4);
1046 *ptag_size = tag_size + ID3V2_HEADER_SIZE;
1049 major_version = header_data[3];
1052 frame_data_length = tag_size;
1054 /* check for extended header */
1055 extended_header = header_data[5] & 0x20; /* bit 6 */
1056 if (extended_header) {
1057 /* skip extended header */
1058 unsigned int extended_header_size;
1059 char extended_header_data[6];
1062 if (read(fd, extended_header_data, 4) != 4)
1065 extended_header_size = _to_uint(extended_header_data, 4);
1066 crc = extended_header_data[5] & 0x8000;
1068 *ptag_size += extended_header_size + (crc * 4);
1070 lseek(fd, extended_header_size - 6, SEEK_CUR);
1071 frame_data_pos += extended_header_size;
1072 frame_data_length -= extended_header_size;
1075 footer_present = header_data[5] & 0x8; /* bit 4 */
1076 if (footer_present && frame_data_length > ID3V2_FOOTER_SIZE)
1077 frame_data_length -= ID3V2_FOOTER_SIZE;
1079 frame_header_size = _get_id3v2_frame_header_size(major_version);
1080 while (frame_data_pos < frame_data_length - frame_header_size) {
1081 nread = read(fd, frame_header_data, frame_header_size);
1085 if (nread != frame_header_size)
1088 if (frame_header_data[0] == 0)
1091 _parse_id3v2_frame_header(frame_header_data, major_version, &fh);
1093 if (fh.frame_size > 0 &&
1095 fh.frame_id[0] == 'T' &&
1096 memcmp(fh.frame_id, "TXXX", 4) != 0) {
1099 if (fh.data_length_indicator)
1100 lseek(fd, 4, SEEK_CUR);
1102 frame_data = malloc(sizeof(char) * fh.frame_size);
1103 if (read(fd, frame_data, fh.frame_size) != fh.frame_size) {
1108 _parse_id3v2_frame(&fh, frame_data, info, cs_convs);
1112 if (fh.data_length_indicator)
1113 lseek(fd, fh.frame_size + 4, SEEK_CUR);
1115 lseek(fd, fh.frame_size, SEEK_CUR);
1118 frame_data_pos += fh.frame_size + frame_header_size;
1125 _id3v1_str_get(struct lms_string_size *s, const char *buf, int maxlen, lms_charset_conv_t *cs_conv)
1128 const char *p, *p_end, *p_last;
1132 p_end = buf + maxlen;
1133 for (p = buf; *p != '\0' && p < p_end; p++) {
1143 len = (p_last - buf) - start;
1147 len++; /* p_last is not included yet */
1148 if ((unsigned)len > s->len) {
1151 tmp = realloc(s->str, sizeof(char) * (len + 1));
1158 memcpy(s->str, buf + start, len);
1162 lms_charset_conv(cs_conv, &s->str, &s->len);
1166 _parse_id3v1(int fd, struct id3_info *info, lms_charset_conv_t *cs_conv)
1168 struct id3v1_tag tag;
1169 if (read(fd, &tag, sizeof(struct id3v1_tag)) == -1)
1172 if (!info->title.str)
1173 _id3v1_str_get(&info->title, tag.title, sizeof(tag.title), cs_conv);
1174 if (!info->artist.str)
1175 _id3v1_str_get(&info->artist, tag.artist, sizeof(tag.artist), cs_conv);
1176 if (!info->album.str)
1177 _id3v1_str_get(&info->album, tag.album, sizeof(tag.album), cs_conv);
1178 if (!info->genre.str)
1179 _get_id3v1_genre(tag.genre, &info->genre);
1180 if (info->trackno == -1 &&
1181 tag.comments[28] == 0 && tag.comments[29] != 0)
1182 info->trackno = (unsigned char) tag.comments[29];
1188 _match(struct plugin *p, const char *path, int len, int base)
1192 i = lms_which_extension(path, len, _exts, LMS_ARRAY_SIZE(_exts));
1196 return (void*)(i + 1);
1200 _parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_info *finfo, void *match)
1202 struct id3_info info = {
1204 .cur_artist_priority = -1,
1206 struct lms_audio_info audio_info = { };
1209 off_t sync_offset = 0;
1211 fd = open(finfo->path, O_RDONLY);
1217 id3v2_offset = _find_id3v2(fd, &sync_offset);
1218 if (id3v2_offset >= 0) {
1219 off_t id3v2_size = 3;
1221 sync_offset = id3v2_offset;
1224 fprintf(stderr, "id3v2 tag found in file %s with offset %ld\n",
1225 finfo->path, id3v2_offset);
1227 if (_parse_id3v2(fd, id3v2_offset, &info, plugin->cs_convs,
1228 &id3v2_size) != 0 ||
1229 !info.title.str || !info.artist.str ||
1230 !info.album.str || !info.genre.str ||
1231 info.trackno == -1) {
1233 fprintf(stderr, "id3v2 invalid in file %s\n", finfo->path);
1238 /* Even if we later failed to parse the ID3, we want to look for sync
1239 * frame only after the tag */
1240 sync_offset += id3v2_size;
1243 if (id3v2_offset < 0) {
1246 fprintf(stderr, "id3v2 tag not found in file %s. trying id3v1\n",
1249 /* check for id3v1 tag */
1250 if (lseek(fd, -128, SEEK_END) == -1) {
1255 if (read(fd, &tag, 3) == -1) {
1260 if (memcmp(tag, "TAG", 3) == 0) {
1262 fprintf(stderr, "id3v1 tag found in file %s\n", finfo->path);
1264 if (_parse_id3v1(fd, &info, ctxt->cs_conv) != 0) {
1271 if (!info.title.str)
1272 lms_name_from_path(&info.title, finfo->path, finfo->path_len,
1273 finfo->base, _exts[((long) match) - 1].len,
1276 if (info.trackno == -1)
1280 fprintf(stderr, "file %s info\n", finfo->path);
1281 fprintf(stderr, "\ttitle='%s'\n", info.title.str);
1282 fprintf(stderr, "\tartist='%s'\n", info.artist.str);
1283 fprintf(stderr, "\talbum='%s'\n", info.album.str);
1284 fprintf(stderr, "\tgenre='%s'\n", info.genre.str);
1285 fprintf(stderr, "\ttrack number='%d'\n", info.trackno);
1288 audio_info.id = finfo->id;
1289 audio_info.title = info.title;
1290 audio_info.artist = info.artist;
1291 audio_info.album = info.album;
1292 audio_info.genre = info.genre;
1293 audio_info.trackno = info.trackno;
1295 _parse_mpeg_header(fd, sync_offset, &audio_info, finfo->size);
1297 _fill_dlna_profile(&audio_info);
1299 r = lms_db_audio_add(plugin->audio_db, &audio_info);
1302 posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
1305 free(info.title.str);
1306 free(info.artist.str);
1307 free(info.album.str);
1308 free(info.genre.str);
1314 _setup(struct plugin *plugin, struct lms_context *ctxt)
1317 const char *id3_encodings[ID3_NUM_ENCODINGS] = {
1325 plugin->audio_db = lms_db_audio_new(ctxt->db);
1326 if (!plugin->audio_db)
1329 for (i = 0; i < ID3_NUM_ENCODINGS; ++i) {
1330 /* do not create charset conv for UTF-8 encoding */
1331 if (!id3_encodings[i]) {
1332 plugin->cs_convs[i] = NULL;
1335 plugin->cs_convs[i] = lms_charset_conv_new_full(0, 0);
1336 if (!plugin->cs_convs[i])
1338 lms_charset_conv_add(plugin->cs_convs[i], id3_encodings[i]);
1345 _start(struct plugin *plugin, struct lms_context *ctxt)
1347 return lms_db_audio_start(plugin->audio_db);
1351 _finish(struct plugin *plugin, struct lms_context *ctxt)
1355 if (plugin->audio_db)
1356 lms_db_audio_free(plugin->audio_db);
1358 for (i = 0; i < ID3_NUM_ENCODINGS; ++i) {
1359 if (plugin->cs_convs[i])
1360 lms_charset_conv_free(plugin->cs_convs[i]);
1367 _close(struct plugin *plugin)
1373 API struct lms_plugin *
1374 lms_plugin_open(void)
1376 struct plugin *plugin;
1378 plugin = (struct plugin *)malloc(sizeof(*plugin));
1379 plugin->plugin.name = _name;
1380 plugin->plugin.match = (lms_plugin_match_fn_t)_match;
1381 plugin->plugin.parse = (lms_plugin_parse_fn_t)_parse;
1382 plugin->plugin.close = (lms_plugin_close_fn_t)_close;
1383 plugin->plugin.setup = (lms_plugin_setup_fn_t)_setup;
1384 plugin->plugin.start = (lms_plugin_start_fn_t)_start;
1385 plugin->plugin.finish = (lms_plugin_finish_fn_t)_finish;
1387 return (struct lms_plugin *)plugin;
1390 API const struct lms_plugin_info *
1391 lms_plugin_info(void)
1393 static struct lms_plugin_info info = {
1396 "ID3 v1 and v2 for mp3 files",
1399 "http://lms.garage.maemo.org"