1 /*
2 * Copyright (C) 2019 Jean-Luc Barriere
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Strongly inspired by the source code of the parser from lightmediascanner.
18 * See https://github.com/profusion/lightmediascanner
19 */
20 #include "id3parser.h"
21 #include "id3v1genres.h"
22 #include "mediafile.h"
23 #include "mediainfo.h"
24 #include "byteorder.h"
25 #include "packed.h"
26
27 #include <QDebug>
28 #include <cstdio>
29 #include <cassert>
30
31 #define ID3V2_HEADER_SIZE 10
32 #define ID3V2_FOOTER_SIZE 10
33
34 using namespace mediascanner;
35
36 static const char * _exts[] = {
37 "MP3", "AAC",
38 #ifdef ENABLE_MEDIA_MP2
39 "MP2",
40 #endif
41 };
42 static int _exts_len = sizeof(_exts) / sizeof(const char*);
43
match(const QFileInfo & fileInfo)44 bool ID3Parser::match(const QFileInfo& fileInfo)
45 {
46 QString path = fileInfo.suffix().toUpper();
47 for (int i = 0; i < _exts_len; ++i)
48 {
49 if (path == _exts[i])
50 return true;
51 }
52 return false;
53 }
54
55 typedef QByteArray(*cs_conv_t)(const char * data, unsigned size);
56
57 static const unsigned id3_num_encodings = 5;
58
59 enum ID3Encoding
60 {
61 Latin1 = 0,
62 UTF16 = 1,
63 UTF16BE = 2,
64 UTF8 = 3,
65 UTF16LE = 4,
66 };
67
68 struct ID3Iinfo
69 {
70 QByteArray title;
71 QByteArray album;
72 QByteArray genre;
73 QByteArray artist;
74 QByteArray composer;
75 int artist_priority;
76 int track_no;
77 bool has_art;
78 };
79
80 struct ID3v2FrameHeader
81 {
82 char frame_id[4];
83 unsigned int frame_size;
84 int compression;
85 int data_length_indicator;
86 };
87
88 PACK (
89 struct ID3v1Tag
90 {
91 char title[30];
92 char artist[30];
93 char album[30];
94 char year[4];
95 char comments[30];
96 unsigned char genre;
97 });
98
99 static QByteArray _cs_conv_latin1(const char * data, unsigned size);
100 static QByteArray _cs_conv_utf16(const char * data, unsigned size);
101 static QByteArray _cs_conv_utf16be(const char * data, unsigned size);
102 static QByteArray _cs_conv_utf8(const char * data, unsigned size);
103 static QByteArray _cs_conv_utf16le(const char * data, unsigned size);
104 static long _find_id3v2(FILE * fp, off_t * sync_offset);
105 static int _parse_id3v2(FILE * fp, long id3v2_offset, ID3Iinfo * info, off_t * ptag_size);
106 static int _parse_id3v1(FILE * fp, ID3Iinfo * info, cs_conv_t csconv);
107 static int _parse_mpeg_header(FILE * fp, off_t off, MediaInfo * audio_info, size_t size);
108
parse(MediaFile * file,MediaInfo * info,bool debug)109 bool ID3Parser::parse(MediaFile * file, MediaInfo * info, bool debug)
110 {
111 ID3Iinfo id3info;
112 id3info.track_no = -1;
113 id3info.artist_priority = 0;
114 id3info.has_art = false;
115
116 int r = 0;
117 long id3v2_offset;
118 off_t sync_offset = 0;
119
120 std::string path(file->filePath.toUtf8().constData());
121 FILE * fp = fopen(path.c_str(), "rb");
122 if (!fp)
123 return false;
124
125 id3v2_offset = _find_id3v2(fp, &sync_offset);
126 if (id3v2_offset >= 0)
127 {
128 off_t id3v2_size = 3;
129
130 sync_offset = id3v2_offset;
131
132 if (_parse_id3v2(fp, id3v2_offset, &id3info, &id3v2_size) != 0 ||
133 id3info.title.isEmpty() ||
134 id3info.artist.isEmpty() ||
135 id3info.album.isEmpty() ||
136 id3info.genre.isEmpty() ||
137 id3info.track_no == -1)
138 {
139 id3v2_offset = -1;
140 }
141
142 /* Even if we later failed to parse the ID3, we want to look for sync
143 * frame only after the tag */
144 sync_offset += id3v2_size;
145 }
146
147 if (id3v2_offset < 0)
148 {
149 char tag[3];
150 /* check for id3v1 tag */
151 if (fseek(fp, -128, SEEK_END) != 0)
152 {
153 r = -3;
154 goto done;
155 }
156
157 if (fread(&tag, 1, 3, fp) != 3)
158 {
159 r = -4;
160 goto done;
161 }
162
163 if (memcmp(tag, "TAG", 3) == 0)
164 {
165 if (_parse_id3v1(fp, &id3info, _cs_conv_utf8) != 0)
166 {
167 r = -5;
168 goto done;
169 }
170 }
171 }
172
173 info->container = file->suffix.toLower();
174 info->title = id3info.title.isEmpty() ? file->baseName : id3info.title;
175 info->album = id3info.album;
176 info->genre = id3info.genre;
177 info->artist = id3info.artist;
178 info->trackNo = id3info.track_no > 0 ? id3info.track_no : 0;
179 info->hasArt = id3info.has_art;
180
181 r = _parse_mpeg_header(fp, sync_offset, info, file->size);
182
183 done:
184 fclose(fp);
185 return (r == 0);
186 }
187
_cs_conv_latin1(const char * data,unsigned size)188 static QByteArray _cs_conv_latin1(const char * data, unsigned size)
189 {
190 return QString::fromLatin1(QByteArray(data, size)).toUtf8();
191 }
192
_cs_conv_utf16(const char * data,unsigned size)193 static QByteArray _cs_conv_utf16(const char * data, unsigned size)
194 {
195 return QString::fromUtf16((const char16_t*) data, size / 2).toUtf8();
196 }
197
_cs_conv_utf16be(const char * data,unsigned size)198 static QByteArray _cs_conv_utf16be(const char * data, unsigned size)
199 {
200 static const char * _BOM = "\xfe\xff";
201 if (memcmp(data, _BOM, 2) == 0)
202 return _cs_conv_utf16(data, size);
203 QByteArray buf;
204 buf.append(_BOM).append(data, size);
205 return _cs_conv_utf16(buf.constData(), buf.length());
206 }
207
_cs_conv_utf8(const char * data,unsigned size)208 static QByteArray _cs_conv_utf8(const char * data, unsigned size)
209 {
210 return QByteArray(data, size);
211 }
212
_cs_conv_utf16le(const char * data,unsigned size)213 static QByteArray _cs_conv_utf16le(const char * data, unsigned size)
214 {
215 static const char * _BOM = "\xff\xfe";
216 if (memcmp(data, _BOM, 2) == 0)
217 return _cs_conv_utf16(data, size);
218 QByteArray buf;
219 buf.append(_BOM).append(data, size);
220 return _cs_conv_utf16(buf.constData(), buf.length());
221 }
222
223 static cs_conv_t _cs_conv[] = {_cs_conv_latin1, _cs_conv_utf16, _cs_conv_utf16be, _cs_conv_utf8, _cs_conv_utf16le};
224
_to_uint(const char * data,int data_size)225 static unsigned int _to_uint(const char * data, int data_size)
226 {
227 unsigned int sum = 0;
228 unsigned int last, i;
229
230 last = data_size > 4 ? 3 : data_size - 1;
231
232 for (i = 0; i <= last; i++)
233 sum |= ((unsigned char) data[i]) << ((last - i) * 8);
234
235 return sum;
236 }
237
_to_uint_max7b(const char * data,int data_size)238 static unsigned int _to_uint_max7b(const char * data, int data_size)
239 {
240 unsigned int sum = 0;
241 unsigned int last, i;
242
243 last = data_size > 4 ? 3 : data_size - 1;
244
245 for (i = 0; i <= last; i++)
246 sum |= ((unsigned char) data[i]) << ((last - i) * 7);
247
248 return sum;
249 }
250
_is_id3v2_second_synch_byte(unsigned char byte)251 static inline int _is_id3v2_second_synch_byte(unsigned char byte)
252 {
253 if (byte == 0xff)
254 return 0;
255 if ((byte & 0xe0) == 0xe0)
256 return 1;
257 return 0;
258 }
259
260 /**
261 * Returns the offset in fd to the position after the ID3 tag
262 */
_find_id3v2(FILE * fp,off_t * sync_offset)263 static long _find_id3v2(FILE * fp, off_t * sync_offset)
264 {
265 static const char pattern[3] = {'I', 'D', '3'};
266 char buffer[3];
267 unsigned int prev_part_match, prev_part_match_sync = 0;
268 long buffer_offset;
269
270 if (fread(buffer, 1, sizeof(buffer), fp) != sizeof(buffer))
271 return -1;
272
273 if (memcmp(buffer, pattern, sizeof(pattern)) == 0)
274 return 0;
275
276 /* This loop is the crux of the find method. There are three cases that we
277 * want to account for:
278 * (1) The previously searched buffer contained a partial match of the
279 * search pattern and we want to see if the next one starts with the
280 * remainder of that pattern.
281 *
282 * (2) The search pattern is wholly contained within the current buffer.
283 *
284 * (3) The current buffer ends with a partial match of the pattern. We will
285 * note this for use in the next iteration, where we will check for the rest
286 * of the pattern.
287 */
288 buffer_offset = 0;
289 prev_part_match_sync = 0;
290 prev_part_match = 0;
291 for(;;)
292 {
293 const char *p, *p_end;
294
295 /* (1) previous partial match */
296 if (prev_part_match_sync)
297 {
298 if (_is_id3v2_second_synch_byte(buffer[0]))
299 {
300 *sync_offset = buffer_offset - 1;
301 return -1;
302 }
303 prev_part_match_sync = 0;
304 }
305
306 if (prev_part_match)
307 {
308 const int size = sizeof(buffer) - prev_part_match;
309 const char *part_pattern = pattern + prev_part_match;
310
311 if (memcmp(buffer, part_pattern, size) == 0)
312 return buffer_offset - prev_part_match;
313
314 prev_part_match = 0;
315 }
316
317 p_end = buffer + sizeof(buffer);
318 for (p = buffer; p < p_end; p++)
319 {
320 if (*p == pattern[0])
321 {
322 /* Try to match pattern, possible partial contents */
323 const char *q;
324 int todo;
325
326 q = p + 1;
327 todo = p_end - q;
328 if (todo == 0 || memcmp(q, pattern + 1, todo) == 0)
329 {
330 todo++;
331 if (todo == sizeof(buffer))
332 /* (2) pattern contained in current buffer */
333 return buffer_offset;
334
335 /* (3) partial match */
336 prev_part_match = todo;
337 break;
338 }
339 }
340 else if ((unsigned char) *p == 0xff)
341 {
342 /* Try to match synch pattern, possible partial contents */
343 const char *q;
344
345 q = p + 1;
346 if (q < p_end)
347 {
348 if (_is_id3v2_second_synch_byte(*q))
349 {
350 /* (2) synch pattern contained in current buffer */
351 *sync_offset = buffer_offset + (p - buffer);
352 return -1;
353 }
354 }
355 else
356 /* (3) partial match */
357 prev_part_match_sync = 1;
358 }
359 }
360
361 if (fread(buffer, 1, sizeof(buffer), fp) != sizeof(buffer))
362 return -1;
363 buffer_offset += sizeof(buffer);
364 }
365 }
366
_get_id3v2_frame_header_size(unsigned int version)367 static unsigned int _get_id3v2_frame_header_size(unsigned int version)
368 {
369 switch (version)
370 {
371 case 0:
372 case 1:
373 case 2:
374 return 6;
375 case 3:
376 case 4:
377 default:
378 return 10;
379 }
380 }
381
_parse_id3v2_frame_header(char * data,unsigned int version,struct ID3v2FrameHeader * fh)382 static void _parse_id3v2_frame_header(char * data, unsigned int version, struct ID3v2FrameHeader * fh)
383 {
384 switch (version)
385 {
386 case 0:
387 case 1:
388 case 2:
389 memcpy(fh->frame_id, data, 3);
390 fh->frame_id[3] = 0;
391 fh->frame_size = _to_uint(data + 3, 3);
392 fh->compression = 0;
393 fh->data_length_indicator = 0;
394 break;
395 case 3:
396 memcpy(fh->frame_id, data, 4);
397 fh->frame_size = _to_uint(data + 4, 4);
398 fh->compression = data[9] & 0x40;
399 fh->data_length_indicator = 0;
400 break;
401 case 4:
402 default:
403 memcpy(fh->frame_id, data, 4);
404 fh->frame_size = _to_uint(data + 4, 4);
405 fh->compression = data[9] & 0x4;
406 fh->data_length_indicator = data[9] & 0x1;
407 break;
408 }
409 }
410
_get_id3v2_frame_info(const char * frame_data,unsigned int frame_size,QByteArray * str,cs_conv_t csconv,int strip)411 static inline void _get_id3v2_frame_info(const char * frame_data, unsigned int frame_size, QByteArray * str, cs_conv_t csconv, int strip)
412 {
413 if (frame_size == 0)
414 return;
415 if (strip)
416 *str = csconv(frame_data, frame_size).trimmed();
417 else
418 *str = csconv(frame_data, frame_size);
419 }
420
_get_id3v2_artist(unsigned int index,const char * frame_data,unsigned int frame_size,ID3Iinfo * info,cs_conv_t csconv)421 static int _get_id3v2_artist(unsigned int index, const char * frame_data, unsigned int frame_size, ID3Iinfo * info, cs_conv_t csconv)
422 {
423 static const unsigned char artist_priorities[] = {3, 4, 2, 1};
424 const unsigned int index_max = sizeof(artist_priorities) / sizeof(*artist_priorities);
425
426 if (index >= index_max)
427 return -1;
428
429 if (artist_priorities[index] > info->artist_priority)
430 {
431 QByteArray artist;
432 _get_id3v2_frame_info(frame_data, frame_size, &artist, csconv, 1);
433 if (!artist.isEmpty())
434 {
435 info->artist = artist;
436 info->artist_priority = artist_priorities[index];
437 }
438 }
439 return 0;
440 }
441
_get_id3v1_genre(unsigned int genre,QByteArray * out)442 static int _get_id3v1_genre(unsigned int genre, QByteArray * out)
443 {
444 if (genre < id3v1_genres_len)
445 {
446 out->clear();
447 out->append(id3v1_genres_str[genre]);
448 return 0;
449 }
450 return -1;
451 }
452
_parse_id3v1_genre(const char * str_genre,QByteArray * out)453 static inline int _parse_id3v1_genre(const char * str_genre, QByteArray * out)
454 {
455 return _get_id3v1_genre(atoi(str_genre), out);
456 }
457
_get_id3v2_genre(const char * frame_data,unsigned int frame_size,QByteArray * out,cs_conv_t csconv)458 static void _get_id3v2_genre(const char * frame_data, unsigned int frame_size, QByteArray * out, cs_conv_t csconv)
459 {
460 unsigned int i, is_number;
461 QByteArray genre;
462
463 _get_id3v2_frame_info(frame_data, frame_size, &genre, csconv, 1);
464 if (genre.isEmpty())
465 return;
466
467 is_number = (genre.length() != 0 && genre.at(0) != '(');
468 if (is_number)
469 {
470 for (i = 0; i < genre.length(); ++i)
471 {
472 if (!isdigit(genre.at(i)))
473 {
474 is_number = 0;
475 break;
476 }
477 }
478 }
479
480 if (is_number && _parse_id3v1_genre(genre.constData(), out) == 0)
481 {
482 /* id3v1 genre found */
483 return;
484 }
485
486 /* ID3v2.3 "content type" can contain a ID3v1 genre number in parenthesis at
487 * the beginning of the field. If this is all that the field contains, do a
488 * translation from that number to the name and return that. If there is a
489 * string following the ID3v1 genre number, that is considered to be
490 * authoritative and we return that instead. Or finally, the field may
491 * simply be free text, in which case we just return the value. */
492
493 if (genre.length() > 1 && genre.at(0) == '(')
494 {
495 int closing = 0;
496 while (closing < genre.length() && genre.at(closing) != ')') ++closing;
497
498 if (closing < genre.length())
499 {
500 if (closing == genre.length() - 1)
501 {
502 /* ) is the last character and only appears once in the
503 * string get the id3v1 genre enclosed by parentheses
504 */
505 if (_parse_id3v1_genre(genre.constData() + 1, out) == 0)
506 {
507 return;
508 }
509 }
510 else
511 {
512 ++closing;
513 out->clear();
514 out->append(genre.constData() + closing, genre.length() - closing);
515 return;
516 }
517 }
518 }
519
520 /* pure text */
521 *out = genre;
522 }
523
_get_id3v2_trackno(const char * frame_data,unsigned int frame_size,ID3Iinfo * info,cs_conv_t csconv)524 static void _get_id3v2_trackno(const char * frame_data, unsigned int frame_size, ID3Iinfo * info, cs_conv_t csconv)
525 {
526 QByteArray buf;
527 _get_id3v2_frame_info(frame_data, frame_size, &buf, csconv, 0);
528 if (buf.isEmpty())
529 return;
530 info->track_no = atoi(buf.constData());
531 }
532
_parse_id3v2_frame(struct ID3v2FrameHeader * fh,const char * frame_data,ID3Iinfo * info)533 static void _parse_id3v2_frame(struct ID3v2FrameHeader * fh, const char * frame_data, ID3Iinfo * info)
534 {
535 cs_conv_t csconv;
536 unsigned int text_encoding, frame_size;
537 const char *fid;
538
539 /* ignore frames which contains just the encoding */
540 if (fh->frame_size <= 1)
541 return;
542
543 /* All used frames start with 'T' */
544 fid = fh->frame_id;
545 if (fid[0] != 'T')
546 return;
547
548 text_encoding = frame_data[0];
549
550 /* skip first byte - text encoding */
551 frame_data += 1;
552 frame_size = fh->frame_size - 1;
553
554 if (text_encoding < id3_num_encodings)
555 csconv = _cs_conv[text_encoding];
556 else
557 csconv = _cs_conv[0];
558
559 /* ID3v2.2 used 3 bytes for the frame id, so let's check it */
560 if ((fid[1] == 'T' && fid[2] == '2') ||
561 (fid[1] == 'I' && fid[2] == 'T' && fid[3] == '2'))
562 _get_id3v2_frame_info(frame_data, frame_size, &info->title, csconv, 1);
563 else if (fid[1] == 'P')
564 {
565 if (fid[2] == 'E')
566 _get_id3v2_artist(fid[3] - '1', frame_data, frame_size, info, csconv);
567 else if (fid[2] >= '1' && fid[2] <= '4')
568 _get_id3v2_artist(fid[2] - '1', frame_data, frame_size, info, csconv);
569 }
570 /* TALB, TAL */
571 else if (fid[1] == 'A' && fid[2] == 'L')
572 _get_id3v2_frame_info(frame_data, frame_size, &info->album, csconv, 1);
573 /* TCOM (Composer) */
574 else if (fid[1] == 'C' && fid[2] == 'O' && fid[3] == 'M')
575 _get_id3v2_frame_info(frame_data, frame_size, &info->composer, csconv, 1);
576 /* TCON (Content/Genre) */
577 else if (fid[1] == 'C' && fid[2] == 'O' && fid[3] == 'N')
578 _get_id3v2_genre(frame_data, frame_size, &info->genre, csconv);
579 else if (fid[1] == 'R' && (fid[2] == 'K' ||
580 (fid[2] == 'C' && fid[3] == 'K')))
581 _get_id3v2_trackno(frame_data, frame_size, info, csconv);
582 }
583
_parse_id3v2(FILE * fp,long id3v2_offset,ID3Iinfo * info,off_t * ptag_size)584 static int _parse_id3v2(FILE * fp, long id3v2_offset, ID3Iinfo * info, off_t * ptag_size)
585 {
586 char header_data[10], frame_header_data[10];
587 unsigned int tag_size, major_version, frame_data_pos, frame_data_length, frame_header_size;
588 int extended_header, footer_present;
589 struct ID3v2FrameHeader fh;
590 size_t nread;
591
592 fseek(fp, id3v2_offset, SEEK_SET);
593
594 /* parse header */
595 if (fread(header_data, 1, ID3V2_HEADER_SIZE, fp) != ID3V2_HEADER_SIZE)
596 return -1;
597
598 tag_size = _to_uint_max7b(header_data + 6, 4);
599 if (tag_size == 0)
600 return -1;
601
602 *ptag_size = tag_size + ID3V2_HEADER_SIZE;
603
604 /* parse frames */
605 major_version = header_data[3];
606
607 frame_data_pos = 0;
608 frame_data_length = tag_size;
609
610 /* check for extended header */
611 extended_header = header_data[5] & 0x20; /* bit 6 */
612 if (extended_header)
613 {
614 /* skip extended header */
615 unsigned int extended_header_size;
616 char extended_header_data[6];
617 bool crc;
618
619 if (fread(extended_header_data, 1, 4, fp) != 4)
620 return -1;
621
622 extended_header_size = _to_uint(extended_header_data, 4);
623 crc = extended_header_data[5] & 0x8000;
624
625 *ptag_size += extended_header_size + (crc * 4);
626
627 fseek(fp, extended_header_size - 6, SEEK_CUR);
628 frame_data_pos += extended_header_size;
629 frame_data_length -= extended_header_size;
630 }
631
632 footer_present = header_data[5] & 0x8; /* bit 4 */
633 if (footer_present && frame_data_length > ID3V2_FOOTER_SIZE)
634 frame_data_length -= ID3V2_FOOTER_SIZE;
635
636 frame_header_size = _get_id3v2_frame_header_size(major_version);
637 while (frame_data_pos < frame_data_length - frame_header_size)
638 {
639 nread = fread(frame_header_data, 1, frame_header_size, fp);
640 if (nread == 0)
641 break;
642
643 if (nread != frame_header_size)
644 return -1;
645
646 if (frame_header_data[0] == 0)
647 break;
648
649 _parse_id3v2_frame_header(frame_header_data, major_version, &fh);
650
651 if (fh.frame_size > 0 &&
652 !fh.compression &&
653 fh.frame_id[0] == 'T' &&
654 memcmp(fh.frame_id, "TXXX", 4) != 0)
655 {
656 char *frame_data;
657
658 if (fh.data_length_indicator)
659 fseek(fp, 4, SEEK_CUR);
660
661 frame_data = (char*) malloc(sizeof(char) * fh.frame_size);
662 if (fread(frame_data, 1, fh.frame_size, fp) != (int) fh.frame_size)
663 {
664 free(frame_data);
665 return -1;
666 }
667
668 _parse_id3v2_frame(&fh, frame_data, info);
669 free(frame_data);
670 }
671 else
672 {
673 if (major_version == 0x2 && memcmp(fh.frame_id, "PIC", 3) == 0)
674 info->has_art = true;
675 else if (major_version > 0x2 && major_version < 0x5 && memcmp(fh.frame_id, "APIC", 4) == 0)
676 info->has_art = true;
677
678 if (fh.data_length_indicator)
679 fseek(fp, fh.frame_size + 4, SEEK_CUR);
680 else
681 fseek(fp, fh.frame_size, SEEK_CUR);
682 }
683
684 frame_data_pos += fh.frame_size + frame_header_size;
685 }
686
687 return 0;
688 }
689
_id3v1_str_get(QByteArray * str,const char * buf,int maxlen,cs_conv_t csconv)690 static inline void _id3v1_str_get(QByteArray * str, const char * buf, int maxlen, cs_conv_t csconv)
691 {
692 int start, len;
693 const char *p, *p_end, *p_last;
694
695 start = 0;
696 p_last = NULL;
697 p_end = buf + maxlen;
698 for (p = buf; *p != '\0' && p < p_end; p++)
699 {
700 if (!isspace(*p))
701 p_last = p;
702 else if (!p_last)
703 start++;
704 }
705
706 if (!p_last)
707 return;
708
709 len = (p_last - buf) - start;
710 if (len < 1)
711 return;
712
713 ++len; /* p_last is not included yet */
714 *str = csconv(buf + start, len);
715 }
716
_parse_id3v1(FILE * fp,ID3Iinfo * info,cs_conv_t csconv)717 static int _parse_id3v1(FILE * fp, ID3Iinfo * info, cs_conv_t csconv)
718 {
719 struct ID3v1Tag tag;
720 if (fread(&tag, 1, sizeof(struct ID3v1Tag), fp) != sizeof(struct ID3v1Tag))
721 return -1;
722
723 if (info->title.isEmpty())
724 _id3v1_str_get(&info->title, tag.title, sizeof(tag.title), csconv);
725 if (info->artist.isEmpty())
726 _id3v1_str_get(&info->artist, tag.artist, sizeof(tag.artist), csconv);
727 if (info->album.isEmpty())
728 _id3v1_str_get(&info->album, tag.album, sizeof(tag.album), csconv);
729 if (info->genre.isEmpty())
730 _get_id3v1_genre(tag.genre, &info->genre);
731 if (info->track_no == -1 &&
732 tag.comments[28] == '\0' && tag.comments[29] != '\0')
733 info->track_no = (unsigned char) tag.comments[29];
734
735 return 0;
736 }
737
738 ////////////////////////////////////////////////////////////////////////////////
739 ////
740 //// MPEG Audio info
741 ////
742
743 #define MPEG_HEADER_SIZE 4
744 #define N_FRAMES_BITRATE_ESTIMATE 512
745 #define N_FRAMES_CBR_ESTIMATE 128
746
747 enum mpeg_audio_version
748 {
749 MPEG_AUDIO_VERSION_1 = 0,
750 MPEG_AUDIO_VERSION_2,
751 MPEG_AUDIO_VERSION_2_5,
752 MPEG_AUDIO_VERSION_4,
753 MPEG_AUDIO_VERSION_COUNT
754 };
755
756 enum mpeg_audio_layer
757 {
758 MPEG_AUDIO_LAYER_1 = 0,
759 MPEG_AUDIO_LAYER_2,
760 MPEG_AUDIO_LAYER_3,
761 MPEG_AUDIO_LAYER_AAC,
762 MPEG_AUDIO_LAYER_COUNT
763 };
764
765 struct mpeg_header
766 {
767 enum mpeg_audio_version version;
768 enum mpeg_audio_layer layer;
769 bool crc;
770 bool padding;
771 uint8_t channels;
772 uint8_t sampling_rate_idx;
773 uint8_t codec_idx;
774 unsigned int bitrate_idx;
775 unsigned int bitrate;
776 unsigned int length;
777 bool cbr;
778 };
779
780 static const char * _codecs[] = {
781 /* mp3 */
782 "mpeg1layer1",
783 "mpeg1layer2",
784 "mpeg1layer3",
785 "mpeg2layer1",
786 "mpeg2layer2",
787 "mpeg2layer3",
788 "mpeg2.5layer1",
789 "mpeg2.5layer2",
790 "mpeg2.5layer3",
791
792 /* aac */
793 #define MPEG_CODEC_AAC_START 9
794 "mpeg2aac", // mpeg2aac-main
795 "mpeg2aac", // mpeg2aac-lc
796 "mpeg2aac", // mpeg2aac-ssr
797 "mpeg2aac", // mpeg2aac-ltp
798 "mpeg4aac", // mpeg4aac-main
799 "mpeg4aac", // mpeg4aac-lc
800 "mpeg4aac", // mpeg4aac-ssr
801 "mpeg4aac", // mpeg4aac-ltp
802 ""
803 };
804
805 /* Ordered according to AAC index, take care with mp3 */
806 static int _sample_rates[16] = {
807 96000, 88200, 64000,
808
809 /* Frequencies available on mp3, */
810 48000, 44100, 32000,
811 24000, 22050, 16000,
812 12000, 11025, 8000,
813
814 7350, /* reserved, zeroed */
815 };
816
817 static unsigned int
818 _bitrate_table[MPEG_AUDIO_VERSION_COUNT][MPEG_AUDIO_LAYER_COUNT][16] = {
819 /*MPEG_AUDIO_VERSION_1*/
820 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0,
821 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0,
822 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0,
823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
824 /*MPEG_AUDIO_VERSION_2*/
825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
826 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0,
827 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0,
828 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
829 /*MPEG_AUDIO_VERSION_2_5*/
830 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
831 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0,
832 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0,
833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834 /*MPEG_AUDIO_VERSION_4*/
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 };
840
841 static unsigned int
842 _samples_per_frame_table[MPEG_AUDIO_VERSION_COUNT][MPEG_AUDIO_LAYER_COUNT] = {
843 384, 1152, 1152, 0,
844 384, 1152, 576, 0,
845 384, 1152, 576, 0,
846 0, 0, 0, 0,
847 };
848
849 static int _fill_mpeg_header(struct mpeg_header * hdr, const uint8_t b[4]);
850 static int _fill_aac_header(struct mpeg_header * hdr, const uint8_t b[4]);
851 static int _fill_mp3_header(struct mpeg_header *hdr, const uint8_t b[4]);
852 static int _parse_vbr_headers(FILE * fp, off_t mpeg_offset, struct mpeg_header * hdr);
853 static int _estimate_mp3_bitrate_from_frames(FILE * fp, off_t mpeg_offset, struct mpeg_header * orig_hdr);
854
_parse_mpeg_header(FILE * fp,off_t off,MediaInfo * audio_info,size_t size)855 static int _parse_mpeg_header(FILE * fp, off_t off, MediaInfo * audio_info, size_t size)
856 {
857 uint8_t buffer[32];
858 const uint8_t *p, *p_end;
859 unsigned int prev_read;
860 struct mpeg_header hdr = {};
861 int r;
862
863 fseek(fp, off, SEEK_SET);
864
865 /* Find sync word */
866 prev_read = 0;
867 do
868 {
869 int nread = fread(buffer + prev_read, 1, sizeof(buffer) - prev_read, fp);
870 if (nread < MPEG_HEADER_SIZE)
871 return -1;
872
873 p = buffer;
874 p_end = buffer + nread;
875 off += nread - prev_read;
876 while (p < p_end && (p = (const uint8_t*) memchr(p, 0xff, p_end - p)))
877 {
878 /* poor man's ring buffer since the needle is small (4 bytes) */
879 if (p > p_end - MPEG_HEADER_SIZE)
880 {
881 memcpy(buffer, p, p_end - p);
882 break;
883 }
884
885 if (_is_id3v2_second_synch_byte(*(p + 1)))
886 {
887 off -= (p_end - p);
888 goto found;
889 }
890
891 p++;
892 }
893 prev_read = p ? p_end - p : 0;
894 }
895 while (1);
896
897 found:
898 if (_fill_mpeg_header(&hdr, p) < 0)
899 {
900 qWarning("%s: Invalid field in file, ignoring.", __FUNCTION__);
901 return 0;
902 }
903
904 if (hdr.layer == MPEG_AUDIO_LAYER_AAC)
905 r = _fill_aac_header(&hdr, p);
906 else
907 {
908 if ((r = _fill_mp3_header(&hdr, p) < 0) ||
909 (r = _parse_vbr_headers(fp, off, &hdr) < 0))
910 return r;
911
912 if (hdr.cbr)
913 hdr.bitrate = _bitrate_table[hdr.version][hdr.layer][hdr.bitrate_idx] * 1000;
914 else if (!hdr.bitrate)
915 {
916 r = _estimate_mp3_bitrate_from_frames(fp, off, &hdr);
917 if (r < 0)
918 return r;
919 }
920
921 if (!hdr.length && hdr.bitrate > 0)
922 hdr.length = (8 * (size - off)) / hdr.bitrate;
923 }
924
925 if (r < 0)
926 return r;
927
928 audio_info->codec.append(_codecs[hdr.codec_idx]);
929 audio_info->sampleRate = _sample_rates[hdr.sampling_rate_idx];
930 audio_info->channels = hdr.channels;
931 audio_info->bitRate = hdr.bitrate;
932 audio_info->duration = hdr.length;
933
934 return 0;
935 }
936
_fill_mpeg_header(struct mpeg_header * hdr,const uint8_t b[4])937 static int _fill_mpeg_header(struct mpeg_header * hdr, const uint8_t b[4])
938 {
939 unsigned int version = (b[1] & 0x18) >> 3;
940 unsigned int layer = (b[1] & 0x06) >> 1;
941
942 switch (layer)
943 {
944 case 0x0:
945 if (version == 0x2 || version == 0x3)
946 hdr->layer = MPEG_AUDIO_LAYER_AAC;
947 else
948 return -1;
949 break;
950 case 0x1:
951 hdr->layer = MPEG_AUDIO_LAYER_3;
952 break;
953 case 0x2:
954 hdr->layer = MPEG_AUDIO_LAYER_2;
955 break;
956 case 0x3:
957 hdr->layer = MPEG_AUDIO_LAYER_1;
958 break;
959 }
960
961 switch (version)
962 {
963 case 0x0:
964 hdr->version = MPEG_AUDIO_VERSION_2_5;
965 break;
966 case 0x1:
967 return -1;
968 case 0x2:
969 if (layer == 0x0)
970 hdr->version = MPEG_AUDIO_VERSION_4;
971 else
972 hdr->version = MPEG_AUDIO_VERSION_2;
973 break;
974 case 0x3:
975 if (layer == 0x0)
976 hdr->version = MPEG_AUDIO_VERSION_2;
977 else
978 hdr->version = MPEG_AUDIO_VERSION_1;
979 }
980
981 hdr->crc = !(b[1] & 0x1);
982 hdr->padding = b[2] & 0x2;
983
984 return 0;
985 }
986
_fill_aac_header(struct mpeg_header * hdr,const uint8_t b[4])987 static int _fill_aac_header(struct mpeg_header * hdr, const uint8_t b[4])
988 {
989 unsigned int profile;
990
991 hdr->sampling_rate_idx = (b[2] & 0x3c) >> 2;
992
993 profile = (b[2] & 0xc0) >> 6;
994 hdr->codec_idx = MPEG_CODEC_AAC_START + profile;
995 if (hdr->version == MPEG_AUDIO_VERSION_4)
996 hdr->codec_idx += 4;
997
998 hdr->channels = ((b[2] & 0x1) << 2) | ((b[3] & 0xc0) >> 6);
999 return 0;
1000 }
1001
_fill_mp3_header(struct mpeg_header * hdr,const uint8_t b[4])1002 static inline int _fill_mp3_header(struct mpeg_header * hdr, const uint8_t b[4])
1003 {
1004 unsigned int bitrate_idx = (b[2] & 0xf0) >> 4;
1005
1006 hdr->sampling_rate_idx = (b[2] & 0x0c) >> 2;
1007
1008 if (hdr->sampling_rate_idx == 0x3)
1009 return -1;
1010 /*
1011 * Sampling rate frequency index
1012 * bits MPEG1 MPEG2 MPEG2.5
1013 * 00 44100 Hz 22050 Hz 11025 Hz
1014 * 01 48000 Hz 24000 Hz 12000 Hz
1015 * 10 32000 Hz 16000 Hz 8000 Hz
1016 * 11 reserv. reserv. reserv.
1017 */
1018
1019 /* swap 0x1 and 0x0 */
1020 if (hdr->sampling_rate_idx < 0x2)
1021 hdr->sampling_rate_idx = !hdr->sampling_rate_idx;
1022 hdr->sampling_rate_idx += 3 * hdr->version + 3;
1023
1024 hdr->codec_idx = hdr->version * 3 + hdr->layer;
1025
1026 hdr->channels = (b[3] & 0xc0) >> 6;
1027 hdr->channels = hdr->channels == 0x3 ? 1 : 2;
1028
1029 hdr->bitrate_idx = bitrate_idx;
1030
1031 return 0;
1032 }
1033
_parse_vbr_headers(FILE * fp,off_t mpeg_offset,struct mpeg_header * hdr)1034 static int _parse_vbr_headers(FILE * fp, off_t mpeg_offset, struct mpeg_header * hdr)
1035 {
1036 unsigned int sampling_rate, samples_per_frame, flags, nframes = 0, size = 0;
1037 int xing_offset_table[2][2] = {/* [(version == 1)][channels == 1)] */
1038 { 17, 9},
1039 { 32, 17}
1040 };
1041 uint8_t buf[18];
1042 off_t xing_offset;
1043
1044 /* Try Xing first since it's the most likely to be there */
1045 xing_offset = mpeg_offset + 4 + 2 * hdr->crc
1046 + xing_offset_table[(hdr->version == 1)][(hdr->channels == 1)];
1047
1048 fseek(fp, xing_offset, SEEK_SET);
1049 if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf))
1050 return -1;
1051
1052 hdr->cbr = (memcmp(buf, "Info", 4) == 0);
1053 if (hdr->cbr || memcmp(buf, "Xing", 4) == 0)
1054 {
1055 flags = buf[7];
1056
1057 if (flags & 1)
1058 nframes = read32be(&buf[8]);
1059 if (flags & 2)
1060 size = read32be(&buf[8 + !!(flags & 1) * 4]);
1061
1062 goto proceed;
1063 }
1064
1065 /* VBRI is found in files encoded by Fraunhofer Encoder. Fixed location: 32
1066 * bytes after the mpeg header */
1067 fseek(fp, mpeg_offset + 36, SEEK_SET);
1068 if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf))
1069 return -1;
1070
1071 if (memcmp(buf, "VBRI", 4) == 0 && read16be(buf) == 1)
1072 {
1073 size = read32be(&buf[10]);
1074 nframes = read32be(&buf[14]);
1075
1076 goto proceed;
1077 }
1078
1079 return 0;
1080
1081 proceed:
1082 samples_per_frame = _samples_per_frame_table[hdr->version][hdr->layer];
1083 sampling_rate = _sample_rates[hdr->sampling_rate_idx];
1084
1085 assert(sampling_rate != 0);
1086
1087 hdr->length = (nframes * samples_per_frame) / sampling_rate;
1088
1089 if (hdr->length)
1090 hdr->bitrate = (8 * size) / (1000 * hdr->length);
1091
1092 return 0;
1093 }
1094
_estimate_mp3_bitrate_from_frames(FILE * fp,off_t mpeg_offset,struct mpeg_header * orig_hdr)1095 static int _estimate_mp3_bitrate_from_frames(FILE * fp, off_t mpeg_offset, struct mpeg_header * orig_hdr)
1096 {
1097 struct mpeg_header hdr = *orig_hdr;
1098 off_t offset = mpeg_offset;
1099 unsigned int sum = 0, i;
1100 int r;
1101 bool cbr = true;
1102 /* For Layer I slot is 32 bits long, for Layer II and Layer III slot is 8
1103 * bits long.
1104 * [layer == 1] */
1105 unsigned int padding_size_table[2] = {1, 4};
1106 unsigned int samples_per_frame, sampling_rate;
1107
1108 samples_per_frame = _samples_per_frame_table[hdr.version][hdr.layer];
1109 sampling_rate = _sample_rates[hdr.sampling_rate_idx];
1110 assert(sampling_rate != 0);
1111
1112 for (i = 0; i < N_FRAMES_BITRATE_ESTIMATE;)
1113 {
1114 unsigned int bitrate, padding_size;
1115 unsigned int framesize;
1116 uint8_t buf[4];
1117
1118 bitrate = _bitrate_table[hdr.version][hdr.layer][hdr.bitrate_idx];
1119 if (cbr && bitrate == hdr.bitrate && i > N_FRAMES_CBR_ESTIMATE)
1120 {
1121 i = 1;
1122 sum = bitrate;
1123 break;
1124 }
1125
1126 sum += bitrate;
1127 i++;
1128
1129 padding_size = hdr.padding ? padding_size_table[hdr.layer == 1] : 0;
1130
1131 framesize = 4; /* mpeg header */
1132 framesize += (samples_per_frame / 8) * bitrate * 1000;
1133 framesize /= sampling_rate;
1134 framesize += (padding_size * samples_per_frame);
1135
1136 offset += framesize;
1137
1138 fseek(fp, offset, SEEK_SET);
1139 r = fread(buf, 1, sizeof(buf), fp);
1140
1141 if (r < 0)
1142 {
1143 qWarning("%s: ERROR reading frame header at %#x", __FUNCTION__, (unsigned int) offset);
1144 break;
1145 }
1146 if (!r)
1147 break;
1148
1149 if (buf[0] != 0xff || !_is_id3v2_second_synch_byte(buf[1]) ||
1150 _fill_mpeg_header(&hdr, buf) < 0 ||
1151 _fill_mp3_header(&hdr, buf) < 0)
1152 {
1153 break;
1154 }
1155 }
1156
1157 orig_hdr->bitrate = sum / i * 1000;
1158
1159 return 0;
1160 }
1161