utils refactor.
[platform/upstream/lightmediascanner.git] / src / plugins / id3 / id3.c
1 /**
2  * Copyright (C) 2008-2011 by ProFUSION embedded systems
3  * Copyright (C) 2008 by INdT
4  *
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.
9  *
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.
14  *
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
18  * 02110-1301 USA
19  *
20  * @author Andre Moreira Magalhaes <andre.magalhaes@openbossa.org>
21  * @author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
22  */
23
24 /**
25  * @brief
26  *
27  * id3 file parser.
28  *
29  * Reference:
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
34  */
35
36 #include <lightmediascanner_plugin.h>
37 #include <lightmediascanner_db.h>
38 #include <lightmediascanner_charset_conv.h>
39 #include <shared/util.h>
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <assert.h>
44 #include <fcntl.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 #include <ctype.h>
50
51 #define DECL_STR(cname, str)                                            \
52     static const struct lms_string_size cname = LMS_STATIC_STRING_SIZE(str)
53
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");
71
72 DECL_STR(_dlna_mp3, "MP3");
73 DECL_STR(_dlna_mp3x, "MP3X");
74
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");
78
79 DECL_STR(_dlna_mime_mpeg, "audio/mpeg");
80 DECL_STR(_dlna_mime_adts, "audio/vnd.dlna.adts");
81 #undef DECL_STR
82
83
84 static void
85 _fill_dlna_profile(struct lms_audio_info *info)
86 {
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;
95    } else if (
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;
112     } else if (
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)) {
124
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;
132             }
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;
137         }
138     }
139 }
140
141 #define ID3V2_HEADER_SIZE       10
142 #define ID3V2_FOOTER_SIZE       10
143
144 #define MPEG_HEADER_SIZE 4
145
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
149  * here. */
150 #define N_FRAMES_BITRATE_ESTIMATE 512
151 #define N_FRAMES_CBR_ESTIMATE 128
152
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
159 };
160
161 enum mpeg_audio_layer {
162     MPEG_AUDIO_LAYER_1,
163     MPEG_AUDIO_LAYER_2,
164     MPEG_AUDIO_LAYER_3,
165     MPEG_AUDIO_LAYER_AAC,
166     _MPEG_AUDIO_LAYER_COUNT
167 };
168
169 struct mpeg_header {
170     enum mpeg_audio_version version;
171     enum mpeg_audio_layer layer;
172
173     bool crc;
174     bool padding;
175     uint8_t channels;
176     uint8_t sampling_rate_idx;
177     uint8_t codec_idx;
178     unsigned int bitrate_idx;
179
180     unsigned int bitrate;
181     unsigned int length;
182     bool cbr;
183 };
184
185 static const struct lms_string_size *_codecs[] = {
186     /* mp3 */
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,
196
197     /* aac */
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,
203
204     [13] = &_codec_mpeg4aac_main,
205     [14] = &_codec_mpeg4aac_lc,
206     [15] = &_codec_mpeg4aac_ssr,
207     [16] = &_codec_mpeg4aac_ltp,
208     [17] = NULL
209 };
210
211 /* Ordered according to AAC index, take care with mp3 */
212 static int _sample_rates[16] = {
213     96000, 88200, 64000,
214
215     /* Frequencies available on mp3, */
216     48000, 44100, 32000,
217     24000, 22050, 16000,
218     12000, 11025, 8000,
219
220     7350, /* reserved, zeroed */
221 };
222
223 static unsigned int
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},
239 };
240
241 static unsigned int
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,
252 };
253
254 enum ID3Encodings {
255     ID3_ENCODING_LATIN1 = 0,
256     ID3_ENCODING_UTF16,
257     ID3_ENCODING_UTF16BE,
258     ID3_ENCODING_UTF8,
259     ID3_ENCODING_UTF16LE,
260     ID3_ENCODING_LAST
261 };
262 #define ID3_NUM_ENCODINGS ID3_ENCODING_LAST
263
264
265 #include "id3v1_genres.c"
266
267 struct id3_info {
268     struct lms_string_size title;
269     struct lms_string_size artist;
270     struct lms_string_size album;
271     struct lms_string_size genre;
272     int trackno;
273     int cur_artist_priority;
274 };
275
276 struct id3v2_frame_header {
277     char frame_id[4];
278     unsigned int frame_size;
279     int compression;
280     int data_length_indicator;
281 };
282
283 struct id3v1_tag {
284     char title[30];
285     char artist[30];
286     char album[30];
287     char year[4];
288     char comments[30];
289     char genre;
290 } __attribute__((packed));
291
292 struct plugin {
293     struct lms_plugin plugin;
294     lms_db_audio_t *audio_db;
295     lms_charset_conv_t *cs_convs[ID3_NUM_ENCODINGS];
296 };
297
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"),
303 };
304 static const char *_cats[] = {
305     "multimedia",
306     "audio",
307     NULL
308 };
309 static const char *_authors[] = {
310     "Andre Moreira Magalhaes",
311     "Gustavo Sverzut Barbieri",
312     NULL
313 };
314
315 static unsigned int
316 _to_uint(const char *data, int data_size)
317 {
318     unsigned int sum = 0;
319     unsigned int last, i;
320
321     last = data_size > 4 ? 3 : data_size - 1;
322
323     for (i = 0; i <= last; i++)
324         sum |= ((unsigned char) data[i]) << ((last - i) * 8);
325
326     return sum;
327 }
328
329 static unsigned int
330 _to_uint_max7b(const char *data, int data_size)
331 {
332     unsigned int sum = 0;
333     unsigned int last, i;
334
335     last = data_size > 4 ? 3 : data_size - 1;
336
337     for (i = 0; i <= last; i++)
338         sum |= ((unsigned char) data[i]) << ((last - i) * 7);
339
340     return sum;
341 }
342
343 static inline int
344 _is_id3v2_second_synch_byte(unsigned char byte)
345 {
346     if (byte == 0xff)
347         return 0;
348     if ((byte & 0xE0) == 0xE0)
349         return 1;
350     return 0;
351 }
352
353 static inline int
354 _fill_mp3_header(struct mpeg_header *hdr, const uint8_t b[4])
355 {
356     unsigned int bitrate_idx = (b[2] & 0xF0) >> 4;
357
358     hdr->sampling_rate_idx = (b[2] & 0x0C) >> 2;
359
360     if (hdr->sampling_rate_idx == 0x3)
361         return -1;
362     /*
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.
369      */
370
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;
375
376     hdr->codec_idx = hdr->version * 3 + hdr->layer;
377
378     hdr->channels = (b[3] & 0xC0) >> 6;
379     hdr->channels = hdr->channels == 0x3 ? 1 : 2;
380
381     hdr->bitrate_idx = bitrate_idx;
382
383     return 0;
384 }
385
386 static inline int
387 _fill_aac_header(struct mpeg_header *hdr, const uint8_t b[4])
388 {
389     unsigned int profile;
390
391     hdr->sampling_rate_idx = (b[2] & 0x3C) >> 2;
392
393     profile = (b[2] & 0xC0) >> 6;
394     hdr->codec_idx = MPEG_CODEC_AAC_START + profile;
395     if (hdr->version == MPEG_AUDIO_VERSION_4)
396         hdr->codec_idx += 4;
397
398     hdr->channels = ((b[2] & 0x1) << 2) | ((b[3] & 0xC0) >> 6);
399     return 0;
400 }
401
402 static inline int
403 _fill_mpeg_header(struct mpeg_header *hdr, const uint8_t b[4])
404 {
405     unsigned int version = (b[1] & 0x18) >>  3;
406     unsigned int layer = (b[1] & 0x06) >> 1;
407
408     switch (layer) {
409     case 0x0:
410         if (version == 0x2 || version == 0x3)
411             hdr->layer = MPEG_AUDIO_LAYER_AAC;
412         else
413             return -1;
414         break;
415     case 0x1:
416         hdr->layer = MPEG_AUDIO_LAYER_3;
417         break;
418     case 0x2:
419         hdr->layer = MPEG_AUDIO_LAYER_2;
420         break;
421     case 0x3:
422         hdr->layer = MPEG_AUDIO_LAYER_1;
423         break;
424     }
425
426     switch (version) {
427     case 0x0:
428         hdr->version = MPEG_AUDIO_VERSION_2_5;
429         break;
430     case 0x1:
431         return -1;
432     case 0x2:
433         if (layer == 0x0)
434             hdr->version = MPEG_AUDIO_VERSION_4;
435         else
436             hdr->version = MPEG_AUDIO_VERSION_2;
437         break;
438     case 0x3:
439         if (layer == 0x0)
440             hdr->version = MPEG_AUDIO_VERSION_2;
441         else
442             hdr->version = MPEG_AUDIO_VERSION_1;
443     }
444
445     hdr->crc = !(b[1] & 0x1);
446     hdr->padding = b[2] & 0x2;
447
448     return 0;
449 }
450
451 static int
452 _estimate_mp3_bitrate_from_frames(int fd, off_t mpeg_offset,
453                                   struct mpeg_header *orig_hdr)
454 {
455     struct mpeg_header hdr = *orig_hdr;
456     off_t offset = mpeg_offset;
457     unsigned int sum = 0, i;
458     int r;
459     bool cbr = true;
460     /* For Layer I slot is 32 bits long, for Layer II and Layer III slot is 8
461      * bits long.
462      * [layer == 1] */
463     unsigned int padding_size_table[2] = { 1, 4 };
464     unsigned int samples_per_frame, sampling_rate;
465
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);
469
470     for (i = 0; i < N_FRAMES_BITRATE_ESTIMATE;) {
471         unsigned int bitrate, padding_size;
472         unsigned int framesize;
473         uint8_t buf[4];
474
475         bitrate = _bitrate_table[hdr.version][hdr.layer][hdr.bitrate_idx];
476         if (cbr && bitrate == hdr.bitrate && i > N_FRAMES_CBR_ESTIMATE) {
477             i = 1;
478             sum = bitrate;
479             break;
480         }
481
482         sum += bitrate;
483         i++;
484
485         padding_size = hdr.padding ? padding_size_table[hdr.layer == 1] : 0;
486
487         framesize = 4;          /* mpeg header */
488         framesize += (samples_per_frame / 8) * bitrate * 1000;
489         framesize /= sampling_rate;
490         framesize += (padding_size * samples_per_frame);
491
492         offset += framesize;
493
494         lseek(fd, offset, SEEK_SET);
495         r = read(fd, buf, sizeof(buf));
496
497         if (r < 0) {
498             fprintf(stderr, "ERROR reading frame header at %#x\n",
499                     (unsigned int) offset);
500             break;
501         }
502         if (!r)
503             break;
504
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]);
511             break;
512         }
513     }
514
515     orig_hdr->bitrate = sum / i * 1000;
516
517     return 0;
518 }
519
520 static int
521 _parse_vbr_headers(int fd, off_t mpeg_offset, struct mpeg_header *hdr)
522 {
523     unsigned int sampling_rate, samples_per_frame, flags, nframes = 0, size = 0;
524     int xing_offset_table[2][2] = { /* [(version == 1)][channels == 1)] */
525         { 17,  9 },
526         { 32, 17 }
527     };
528     uint8_t buf[18];
529     off_t xing_offset;
530
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)];
534
535     lseek(fd, xing_offset, SEEK_SET);
536     if (read(fd, buf, sizeof(buf)) != sizeof(buf))
537         return -1;
538
539     hdr->cbr = (memcmp(buf, "Info", 4) == 0);
540     if (hdr->cbr || memcmp(buf, "Xing", 4) == 0) {
541         flags = buf[7];
542
543         if (flags & 1)
544             nframes = get_be32(&buf[8]);
545         if (flags & 2)
546             size = get_be32(&buf[8 + !!(flags & 1) * 4]);
547
548         goto proceed;
549     }
550
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))
555         return -1;
556
557     if (memcmp(buf, "VBRI", 4) == 0 && get_be16(buf) == 1) {
558         size = get_be32(&buf[10]);
559         nframes = get_be32(&buf[14]);
560
561         goto proceed;
562     }
563
564     return 0;
565
566 proceed:
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);
570
571     hdr->length = (nframes * samples_per_frame) / sampling_rate;
572
573     if (hdr->length)
574         hdr->bitrate = (8 * size) / (1000 * hdr->length);
575
576     return 0;
577 }
578
579 static int
580 _parse_mpeg_header(int fd, off_t off, struct lms_audio_info *audio_info,
581                    size_t size)
582 {
583     uint8_t buffer[32];
584     const uint8_t *p, *p_end;
585     unsigned int prev_read;
586     struct mpeg_header hdr = { };
587     int r;
588
589     lseek(fd, off, SEEK_SET);
590
591     /* Find sync word */
592     prev_read = 0;
593     do {
594         int nread = read(fd, buffer + prev_read, sizeof(buffer) - prev_read);
595         if (nread < MPEG_HEADER_SIZE)
596             return -1;
597
598         p = buffer;
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);
605                 break;
606             }
607
608             if (_is_id3v2_second_synch_byte(*(p + 1))) {
609                 off -= (p_end - p);
610                 goto found;
611             }
612
613             p++;
614         }
615         prev_read = p ? p_end - p : 0;
616     } while(1);
617
618 found:
619     if (_fill_mpeg_header(&hdr, p) < 0) {
620         fprintf(stderr, "Invalid field in file, ignoring.\n");
621         return 0;
622     }
623
624     if (hdr.layer == MPEG_AUDIO_LAYER_AAC)
625         r = _fill_aac_header(&hdr, p);
626     else {
627         if ((r = _fill_mp3_header(&hdr, p) < 0) ||
628             (r = _parse_vbr_headers(fd, off, &hdr) < 0))
629             return r;
630
631         if (hdr.cbr)
632             hdr.bitrate =
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);
636             if (r < 0)
637                 return r;
638         }
639
640         if (!hdr.length)
641             hdr.length =  (8 * (size - off)) / (1000 * hdr.bitrate);
642     }
643
644     if (r < 0)
645         return r;
646
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;
652
653     return 0;
654 }
655
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 */
660 static long
661 _find_id3v2(int fd, off_t *sync_offset)
662 {
663     static const char pattern[3] = "ID3";
664     char buffer[3];
665     unsigned int prev_part_match, prev_part_match_sync = 0;
666     long buffer_offset;
667
668     if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer))
669         return -1;
670
671     if (memcmp(buffer, pattern, sizeof(pattern)) == 0)
672         return 0;
673
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.
679      *
680      * (2) The search pattern is wholly contained within the current buffer.
681      *
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
684      * of the pattern.
685      */
686     buffer_offset = 0;
687     prev_part_match_sync = 0;
688     prev_part_match = 0;
689     while (1) {
690         const char *p, *p_end;
691
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;
696                 return -1;
697             }
698             prev_part_match_sync = 0;
699         }
700
701         if (prev_part_match) {
702             const int size = sizeof(buffer) - prev_part_match;
703             const char *part_pattern = pattern + prev_part_match;
704
705             if (memcmp(buffer, part_pattern, size) == 0)
706                 return buffer_offset - prev_part_match;
707
708             prev_part_match = 0;
709         }
710
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 */
715                 const char *q;
716                 int todo;
717
718                 q = p + 1;
719                 todo = p_end - q;
720                 if (todo == 0 || memcmp(q, pattern + 1, todo) == 0) {
721                     todo++;
722                     if (todo == sizeof(buffer))
723                         /* (2) pattern contained in current buffer */
724                         return buffer_offset;
725
726                     /* (3) partial match */
727                     prev_part_match = todo;
728                     break;
729                 }
730             } else if ((unsigned char)*p == 0xff) {
731                 /* Try to match synch pattern, possible partial contents */
732                 const char *q;
733
734                 q = p + 1;
735                 if (q < p_end) {
736                     if (_is_id3v2_second_synch_byte(*q)) {
737                         /* (2) synch pattern contained in current buffer */
738                         *sync_offset = buffer_offset + (p - buffer);
739                         return -1;
740                     }
741                 } else
742                     /* (3) partial match */
743                     prev_part_match_sync = 1;
744             }
745         }
746
747         if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer))
748             return -1;
749         buffer_offset += sizeof(buffer);
750     }
751
752     return -1;
753 }
754
755 static unsigned int
756 _get_id3v2_frame_header_size(unsigned int version)
757 {
758     switch (version) {
759     case 0:
760     case 1:
761     case 2:
762         return 6;
763     case 3:
764     case 4:
765     default:
766         return 10;
767     }
768 }
769
770 static void
771 _parse_id3v2_frame_header(char *data, unsigned int version, struct id3v2_frame_header *fh)
772 {
773     switch (version) {
774     case 0:
775     case 1:
776     case 2:
777         memcpy(fh->frame_id, data, 3);
778         fh->frame_id[3] = 0;
779         fh->frame_size = _to_uint(data + 3, 3);
780         fh->compression = 0;
781         fh->data_length_indicator = 0;
782         break;
783     case 3:
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;
788         break;
789     case 4:
790     default:
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;
795         break;
796     }
797 }
798
799 static inline void
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)
801 {
802     if (frame_size == 0)
803         return;
804     if (frame_size > s->len) {
805         char *tmp;
806
807         tmp = realloc(s->str, sizeof(char) * (frame_size + 1));
808         if (!tmp)
809             return;
810         s->str = tmp;
811     }
812     memcpy(s->str, frame_data, frame_size);
813     s->str[frame_size] = '\0';
814     s->len = frame_size;
815     if (cs_conv)
816         lms_charset_conv(cs_conv, &s->str, &s->len);
817     if (strip)
818         lms_string_size_strip_and_free(s);
819 }
820
821 static int
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)
823 {
824     static const unsigned char artist_priorities[] = {3, 4, 2, 1};
825     const unsigned int index_max = sizeof(artist_priorities) / sizeof(*artist_priorities);
826
827     if (index >= index_max)
828         return 1;
829
830     if (artist_priorities[index] > info->cur_artist_priority) {
831         struct lms_string_size artist = { };
832
833         _get_id3v2_frame_info(frame_data, frame_size, &artist, cs_conv, 1);
834         if (artist.str) {
835             free(info->artist.str);
836             info->artist = artist;
837             info->cur_artist_priority = artist_priorities[index];
838         }
839     }
840     return 0;
841 }
842
843 static int
844 _get_id3v1_genre(unsigned int genre, struct lms_string_size *out)
845 {
846     if (genre < ID3V1_NUM_GENRES) {
847         unsigned int size, base, len;
848
849         base = id3v1_genres_offsets[genre];
850         size = id3v1_genres_offsets[genre + 1] - base;
851         len = size - 1;
852
853         if (len > out->len) {
854             char *p = realloc(out->str, size);
855             if (!p)
856                 return -2;
857             out->str = p;
858         }
859
860         out->len = len;
861         memcpy(out->str, id3v1_genres_mem + base, size);
862
863         return 0;
864     }
865     return -1;
866 }
867
868 static inline int
869 _parse_id3v1_genre(const char *str_genre, struct lms_string_size *out)
870 {
871     return _get_id3v1_genre(atoi(str_genre), out);
872 }
873
874 static void
875 _get_id3v2_genre(const char *frame_data, unsigned int frame_size, struct lms_string_size *out, lms_charset_conv_t *cs_conv)
876 {
877     unsigned int i, is_number;
878     struct lms_string_size genre = { };
879
880     _get_id3v2_frame_info(frame_data, frame_size, &genre, cs_conv, 1);
881     if (!genre.str)
882         return;
883
884     is_number = (genre.len != 0 && genre.str[0] != '(');
885     if (is_number) {
886         for (i = 0; i < genre.len; ++i) {
887             if (!isdigit(genre.str[i])) {
888                 is_number = 0;
889                 break;
890             }
891         }
892     }
893
894     if (is_number && _parse_id3v1_genre(genre.str, out) == 0) {
895         /* id3v1 genre found */
896         free(genre.str);
897         return;
898     }
899
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. */
906
907     if (genre.len > 1 && genre.str[0] == '(') {
908         char *closing = NULL;
909
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
915                  */
916                 if (_parse_id3v1_genre(genre.str + 1, out) == 0) {
917                     free(genre.str);
918                     return;
919                 }
920             }
921         }
922
923         /* get the string followed by the id3v1 genre */
924         if (!closing)
925             closing = strchr(genre.str, ')');
926
927         if (closing) {
928             closing++;
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);
933             return;
934         }
935     }
936
937     /* pure text */
938     *out = genre;
939 }
940
941 static void
942 _get_id3v2_trackno(const char *frame_data, unsigned int frame_size, struct id3_info *info, lms_charset_conv_t *cs_conv)
943 {
944     struct lms_string_size trackno = { };
945
946     _get_id3v2_frame_info(frame_data, frame_size, &trackno, cs_conv, 0);
947     if (!trackno.str)
948         return;
949     info->trackno = atoi(trackno.str);
950     free(trackno.str);
951 }
952
953 static void
954 _parse_id3v2_frame(struct id3v2_frame_header *fh, const char *frame_data, struct id3_info *info, lms_charset_conv_t **cs_convs)
955 {
956     lms_charset_conv_t *cs_conv;
957     unsigned int text_encoding, frame_size;
958     const char *fid;
959
960     /* ignore frames which contains just the encoding */
961     if (fh->frame_size <= 1)
962         return;
963
964 #if 0
965     fprintf(stderr, "frame id = %.4s frame size = %d text encoding = %d\n",
966             fh->frame_id, fh->frame_size, frame_data[0]);
967 #endif
968
969     /* All used frames start with 'T' */
970     fid = fh->frame_id;
971     if (fid[0] != 'T')
972         return;
973
974     /* Latin1  = 0
975      * UTF16   = 1
976      * UTF16BE = 2
977      * UTF8    = 3
978      * UTF16LE = 4
979      */
980     text_encoding = frame_data[0];
981
982     /* skip first byte - text encoding */
983     frame_data += 1;
984     frame_size = fh->frame_size - 1;
985
986     if (text_encoding < ID3_NUM_ENCODINGS) {
987         if (text_encoding == ID3_ENCODING_UTF16) {
988             /* ignore frames which contains just the encoding */
989             if (frame_size <= 2)
990                 return;
991
992             if (memcmp(frame_data, "\xfe\xff", 2) == 0)
993                 text_encoding = ID3_ENCODING_UTF16BE;
994             else
995                 text_encoding = ID3_ENCODING_UTF16LE;
996             frame_data += 2;
997             frame_size -= 2;
998         }
999         cs_conv = cs_convs[text_encoding];
1000     } else
1001         cs_conv = NULL;
1002
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') {
1008         if (fid[2] == 'E')
1009             _get_id3v2_artist(fid[3] - '1', frame_data, frame_size,
1010                               info, cs_conv);
1011         else if (fid[2] >= '1' && fid[2] <= '4')
1012             _get_id3v2_artist(fid[2] - '1', frame_data, frame_size,
1013                               info, cs_conv);
1014     }
1015     /* TALB, TAL */
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);
1024 }
1025
1026 static int
1027 _parse_id3v2(int fd, long id3v2_offset, struct id3_info *info,
1028              lms_charset_conv_t **cs_convs, off_t *ptag_size)
1029 {
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;
1034     size_t nread;
1035
1036     lseek(fd, id3v2_offset, SEEK_SET);
1037
1038     /* parse header */
1039     if (read(fd, header_data, ID3V2_HEADER_SIZE) != ID3V2_HEADER_SIZE)
1040         return -1;
1041
1042     tag_size = _to_uint_max7b(header_data + 6, 4);
1043     if (tag_size == 0)
1044         return -1;
1045
1046     *ptag_size = tag_size + ID3V2_HEADER_SIZE;
1047
1048     /* parse frames */
1049     major_version = header_data[3];
1050
1051     frame_data_pos = 0;
1052     frame_data_length = tag_size;
1053
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];
1060         bool crc;
1061
1062         if (read(fd, extended_header_data, 4) != 4)
1063             return -1;
1064
1065         extended_header_size = _to_uint(extended_header_data, 4);
1066         crc = extended_header_data[5] & 0x8000;
1067
1068         *ptag_size += extended_header_size + (crc * 4);
1069
1070         lseek(fd, extended_header_size - 6, SEEK_CUR);
1071         frame_data_pos += extended_header_size;
1072         frame_data_length -= extended_header_size;
1073     }
1074
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;
1078
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);
1082         if (nread == 0)
1083             break;
1084
1085         if (nread != frame_header_size)
1086             return -1;
1087
1088         if (frame_header_data[0] == 0)
1089             break;
1090
1091         _parse_id3v2_frame_header(frame_header_data, major_version, &fh);
1092
1093         if (fh.frame_size > 0 &&
1094             !fh.compression &&
1095             fh.frame_id[0] == 'T' &&
1096             memcmp(fh.frame_id, "TXXX", 4) != 0) {
1097             char *frame_data;
1098
1099             if (fh.data_length_indicator)
1100                 lseek(fd, 4, SEEK_CUR);
1101
1102             frame_data = malloc(sizeof(char) * fh.frame_size);
1103             if (read(fd, frame_data, fh.frame_size) != fh.frame_size) {
1104                 free(frame_data);
1105                 return -1;
1106             }
1107
1108             _parse_id3v2_frame(&fh, frame_data, info, cs_convs);
1109             free(frame_data);
1110         }
1111         else {
1112             if (fh.data_length_indicator)
1113                 lseek(fd, fh.frame_size + 4, SEEK_CUR);
1114             else
1115                 lseek(fd, fh.frame_size, SEEK_CUR);
1116         }
1117
1118         frame_data_pos += fh.frame_size + frame_header_size;
1119     }
1120
1121     return 0;
1122 }
1123
1124 static inline void
1125 _id3v1_str_get(struct lms_string_size *s, const char *buf, int maxlen, lms_charset_conv_t *cs_conv)
1126 {
1127     int start, len;
1128     const char *p, *p_end, *p_last;
1129
1130     start = 0;
1131     p_last = NULL;
1132     p_end = buf + maxlen;
1133     for (p = buf; *p != '\0' && p < p_end; p++) {
1134         if (!isspace(*p))
1135             p_last = p;
1136         else if (!p_last)
1137             start++;
1138     }
1139
1140     if (!p_last)
1141         return;
1142
1143     len = (p_last - buf) - start;
1144     if (len < 1)
1145         return;
1146
1147     len++; /* p_last is not included yet */
1148     if ((unsigned)len > s->len) {
1149         char *tmp;
1150
1151         tmp = realloc(s->str, sizeof(char) * (len + 1));
1152         if (!tmp)
1153             return;
1154         s->str = tmp;
1155     }
1156
1157     s->len = len;
1158     memcpy(s->str, buf + start, len);
1159     s->str[len] = '\0';
1160
1161     if (cs_conv)
1162         lms_charset_conv(cs_conv, &s->str, &s->len);
1163 }
1164
1165 static int
1166 _parse_id3v1(int fd, struct id3_info *info, lms_charset_conv_t *cs_conv)
1167 {
1168     struct id3v1_tag tag;
1169     if (read(fd, &tag, sizeof(struct id3v1_tag)) == -1)
1170         return -1;
1171
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];
1183
1184     return 0;
1185 }
1186
1187 static void *
1188 _match(struct plugin *p, const char *path, int len, int base)
1189 {
1190     long i;
1191
1192     i = lms_which_extension(path, len, _exts, LMS_ARRAY_SIZE(_exts));
1193     if (i < 0)
1194       return NULL;
1195     else
1196       return (void*)(i + 1);
1197 }
1198
1199 static int
1200 _parse(struct plugin *plugin, struct lms_context *ctxt, const struct lms_file_info *finfo, void *match)
1201 {
1202     struct id3_info info = {
1203         .trackno = -1,
1204         .cur_artist_priority = -1,
1205     };
1206     struct lms_audio_info audio_info = { };
1207     int r, fd;
1208     long id3v2_offset;
1209     off_t sync_offset = 0;
1210
1211     fd = open(finfo->path, O_RDONLY);
1212     if (fd < 0) {
1213         perror("open");
1214         return -1;
1215     }
1216
1217     id3v2_offset = _find_id3v2(fd, &sync_offset);
1218     if (id3v2_offset >= 0) {
1219         off_t id3v2_size = 3;
1220
1221         sync_offset = id3v2_offset;
1222
1223 #if 0
1224         fprintf(stderr, "id3v2 tag found in file %s with offset %ld\n",
1225                 finfo->path, id3v2_offset);
1226 #endif
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) {
1232 #if 0
1233             fprintf(stderr, "id3v2 invalid in file %s\n", finfo->path);
1234 #endif
1235             id3v2_offset = -1;
1236         }
1237
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;
1241     }
1242
1243     if (id3v2_offset < 0) {
1244         char tag[3];
1245 #if 0
1246         fprintf(stderr, "id3v2 tag not found in file %s. trying id3v1\n",
1247                 finfo->path);
1248 #endif
1249         /* check for id3v1 tag */
1250         if (lseek(fd, -128, SEEK_END) == -1) {
1251             r = -3;
1252             goto done;
1253         }
1254
1255         if (read(fd, &tag, 3) == -1) {
1256             r = -4;
1257             goto done;
1258         }
1259
1260         if (memcmp(tag, "TAG", 3) == 0) {
1261 #if 0
1262             fprintf(stderr, "id3v1 tag found in file %s\n", finfo->path);
1263 #endif
1264             if (_parse_id3v1(fd, &info, ctxt->cs_conv) != 0) {
1265                 r = -5;
1266                 goto done;
1267             }
1268         }
1269     }
1270
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,
1274                            ctxt->cs_conv);
1275
1276     if (info.trackno == -1)
1277         info.trackno = 0;
1278
1279 #if 0
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);
1286 #endif
1287
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;
1294
1295     _parse_mpeg_header(fd, sync_offset, &audio_info, finfo->size);
1296
1297     _fill_dlna_profile(&audio_info);
1298
1299     r = lms_db_audio_add(plugin->audio_db, &audio_info);
1300
1301   done:
1302     posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
1303     close(fd);
1304
1305     free(info.title.str);
1306     free(info.artist.str);
1307     free(info.album.str);
1308     free(info.genre.str);
1309
1310     return r;
1311 }
1312
1313 static int
1314 _setup(struct plugin *plugin, struct lms_context *ctxt)
1315 {
1316     int i;
1317     const char *id3_encodings[ID3_NUM_ENCODINGS] = {
1318         "Latin1",
1319         NULL, /* UTF-16 */
1320         "UTF-16BE",
1321         NULL, /* UTF-8 */
1322         "UTF-16LE",
1323     };
1324
1325     plugin->audio_db = lms_db_audio_new(ctxt->db);
1326     if (!plugin->audio_db)
1327         return -1;
1328
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;
1333             continue;
1334         }
1335         plugin->cs_convs[i] = lms_charset_conv_new_full(0, 0);
1336         if (!plugin->cs_convs[i])
1337             return -1;
1338         lms_charset_conv_add(plugin->cs_convs[i], id3_encodings[i]);
1339     }
1340
1341     return 0;
1342 }
1343
1344 static int
1345 _start(struct plugin *plugin, struct lms_context *ctxt)
1346 {
1347     return lms_db_audio_start(plugin->audio_db);
1348 }
1349
1350 static int
1351 _finish(struct plugin *plugin, struct lms_context *ctxt)
1352 {
1353     int i;
1354
1355     if (plugin->audio_db)
1356         lms_db_audio_free(plugin->audio_db);
1357
1358     for (i = 0; i < ID3_NUM_ENCODINGS; ++i) {
1359         if (plugin->cs_convs[i])
1360             lms_charset_conv_free(plugin->cs_convs[i]);
1361     }
1362
1363     return 0;
1364 }
1365
1366 static int
1367 _close(struct plugin *plugin)
1368 {
1369     free(plugin);
1370     return 0;
1371 }
1372
1373 API struct lms_plugin *
1374 lms_plugin_open(void)
1375 {
1376     struct plugin *plugin;
1377
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;
1386
1387     return (struct lms_plugin *)plugin;
1388 }
1389
1390 API const struct lms_plugin_info *
1391 lms_plugin_info(void)
1392 {
1393     static struct lms_plugin_info info = {
1394         _name,
1395         _cats,
1396         "ID3 v1 and v2 for mp3 files",
1397         PACKAGE_VERSION,
1398         _authors,
1399         "http://lms.garage.maemo.org"
1400     };
1401
1402     return &info;
1403 }