diff options
Diffstat (limited to 'lib/rbcodec/metadata')
-rw-r--r-- | lib/rbcodec/metadata/id3tags.c | 23 | ||||
-rw-r--r-- | lib/rbcodec/metadata/metadata_parsers.h | 1 | ||||
-rw-r--r-- | lib/rbcodec/metadata/mp3.c | 14 | ||||
-rw-r--r-- | lib/rbcodec/metadata/mp3data.c | 26 |
4 files changed, 48 insertions, 16 deletions
diff --git a/lib/rbcodec/metadata/id3tags.c b/lib/rbcodec/metadata/id3tags.c index cda8ce3b7a..8236244d79 100644 --- a/lib/rbcodec/metadata/id3tags.c +++ b/lib/rbcodec/metadata/id3tags.c | |||
@@ -1135,6 +1135,29 @@ void setid3v2title(int fd, struct mp3entry *entry) | |||
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | /* | 1137 | /* |
1138 | * Calculates the size of the ID3v1 tag if any. | ||
1139 | * | ||
1140 | * Arguments: file - the file to search for a tag. | ||
1141 | * | ||
1142 | * Returns: the size of the tag or 0 if none was found | ||
1143 | */ | ||
1144 | int getid3v1len(int fd) | ||
1145 | { | ||
1146 | char buf[4]; | ||
1147 | |||
1148 | if (-1 == lseek(fd, -128, SEEK_END)) | ||
1149 | return 0; | ||
1150 | |||
1151 | if (read(fd, buf, 3) != 3) | ||
1152 | return 0; | ||
1153 | |||
1154 | if (strncmp(buf, "TAG", 3)) | ||
1155 | return 0; | ||
1156 | |||
1157 | return 128; | ||
1158 | } | ||
1159 | |||
1160 | /* | ||
1138 | * Calculates the size of the ID3v2 tag. | 1161 | * Calculates the size of the ID3v2 tag. |
1139 | * | 1162 | * |
1140 | * Arguments: file - the file to search for a tag. | 1163 | * Arguments: file - the file to search for a tag. |
diff --git a/lib/rbcodec/metadata/metadata_parsers.h b/lib/rbcodec/metadata/metadata_parsers.h index 9f03c79bb5..45cf140012 100644 --- a/lib/rbcodec/metadata/metadata_parsers.h +++ b/lib/rbcodec/metadata/metadata_parsers.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #if CONFIG_CODEC == SWCODEC | 22 | #if CONFIG_CODEC == SWCODEC |
23 | char* id3_get_num_genre(unsigned int genre_num); | 23 | char* id3_get_num_genre(unsigned int genre_num); |
24 | #endif | 24 | #endif |
25 | int getid3v1len(int fd); | ||
25 | int getid3v2len(int fd); | 26 | int getid3v2len(int fd); |
26 | bool setid3v1title(int fd, struct mp3entry *entry); | 27 | bool setid3v1title(int fd, struct mp3entry *entry); |
27 | void setid3v2title(int fd, struct mp3entry *entry); | 28 | void setid3v2title(int fd, struct mp3entry *entry); |
diff --git a/lib/rbcodec/metadata/mp3.c b/lib/rbcodec/metadata/mp3.c index 661fea8e51..2096e70898 100644 --- a/lib/rbcodec/metadata/mp3.c +++ b/lib/rbcodec/metadata/mp3.c | |||
@@ -71,7 +71,9 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
71 | if(bytecount < 0) | 71 | if(bytecount < 0) |
72 | return -1; | 72 | return -1; |
73 | 73 | ||
74 | bytecount += entry->id3v2len; | 74 | /* Subtract the meta information from the file size to get |
75 | the true size of the MP3 stream */ | ||
76 | entry->filesize -= entry->id3v1len + entry->id3v2len; | ||
75 | 77 | ||
76 | /* Validate byte count, in case the file has been edited without | 78 | /* Validate byte count, in case the file has been edited without |
77 | * updating the header. | 79 | * updating the header. |
@@ -99,6 +101,9 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
99 | } | 101 | } |
100 | } | 102 | } |
101 | 103 | ||
104 | entry->filesize -= bytecount; | ||
105 | bytecount += entry->id3v2len; | ||
106 | |||
102 | entry->bitrate = info.bitrate; | 107 | entry->bitrate = info.bitrate; |
103 | entry->frequency = info.frequency; | 108 | entry->frequency = info.frequency; |
104 | entry->layer = info.layer; | 109 | entry->layer = info.layer; |
@@ -127,7 +132,7 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
127 | if (info.bitrate < 8) | 132 | if (info.bitrate < 8) |
128 | filetime = 0; | 133 | filetime = 0; |
129 | else | 134 | else |
130 | filetime = (entry->filesize - bytecount) / (info.bitrate / 8); | 135 | filetime = entry->filesize / (info.bitrate >> 3); |
131 | /* bitrate is in kbps so this delivers milliseconds. Doing bitrate / 8 | 136 | /* bitrate is in kbps so this delivers milliseconds. Doing bitrate / 8 |
132 | * instead of filesize * 8 is exact, because mpeg audio bitrates are | 137 | * instead of filesize * 8 is exact, because mpeg audio bitrates are |
133 | * always multiples of 8, and it avoids overflows. */ | 138 | * always multiples of 8, and it avoids overflows. */ |
@@ -163,6 +168,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry) | |||
163 | { | 168 | { |
164 | entry->title = NULL; | 169 | entry->title = NULL; |
165 | entry->filesize = filesize(fd); | 170 | entry->filesize = filesize(fd); |
171 | entry->id3v1len = getid3v1len(fd); | ||
166 | entry->id3v2len = getid3v2len(fd); | 172 | entry->id3v2len = getid3v2len(fd); |
167 | entry->tracknum = 0; | 173 | entry->tracknum = 0; |
168 | entry->discnum = 0; | 174 | entry->discnum = 0; |
@@ -174,10 +180,6 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry) | |||
174 | return false; | 180 | return false; |
175 | entry->length = len; | 181 | entry->length = len; |
176 | 182 | ||
177 | /* Subtract the meta information from the file size to get | ||
178 | the true size of the MP3 stream */ | ||
179 | entry->filesize -= entry->first_frame_offset; | ||
180 | |||
181 | /* only seek to end of file if no id3v2 tags were found */ | 183 | /* only seek to end of file if no id3v2 tags were found */ |
182 | if (!entry->id3v2len) { | 184 | if (!entry->id3v2len) { |
183 | setid3v1title(fd, entry); | 185 | setid3v1title(fd, entry); |
diff --git a/lib/rbcodec/metadata/mp3data.c b/lib/rbcodec/metadata/mp3data.c index 8a134dd534..49f9786c29 100644 --- a/lib/rbcodec/metadata/mp3data.c +++ b/lib/rbcodec/metadata/mp3data.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include "mp3data.h" | 39 | #include "mp3data.h" |
40 | #include "platform.h" | 40 | #include "platform.h" |
41 | 41 | ||
42 | #include "metadata.h" | ||
43 | #include "metadata/metadata_parsers.h" | ||
44 | |||
42 | //#define DEBUG_VERBOSE | 45 | //#define DEBUG_VERBOSE |
43 | 46 | ||
44 | #ifdef DEBUG_VERBOSE | 47 | #ifdef DEBUG_VERBOSE |
@@ -340,7 +343,7 @@ static int buf_getbyte(int fd, unsigned char *c) | |||
340 | static int buf_seek(int fd, int len) | 343 | static int buf_seek(int fd, int len) |
341 | { | 344 | { |
342 | fnf_read_index += len; | 345 | fnf_read_index += len; |
343 | if(fnf_read_index > fnf_buf_len) | 346 | if(fnf_read_index >= fnf_buf_len) |
344 | { | 347 | { |
345 | len = fnf_read_index - fnf_buf_len; | 348 | len = fnf_read_index - fnf_buf_len; |
346 | 349 | ||
@@ -348,23 +351,22 @@ static int buf_seek(int fd, int len) | |||
348 | if(fnf_buf_len < 0) | 351 | if(fnf_buf_len < 0) |
349 | return -1; | 352 | return -1; |
350 | 353 | ||
351 | fnf_read_index = 0; | 354 | fnf_read_index = len; |
352 | fnf_read_index += len; | ||
353 | } | 355 | } |
354 | 356 | ||
355 | if(fnf_read_index > fnf_buf_len) | 357 | if(fnf_read_index >= fnf_buf_len) |
356 | { | 358 | { |
357 | return -1; | 359 | return -1; |
358 | } | 360 | } |
359 | else | 361 | |
360 | return 0; | 362 | return 0; |
361 | } | 363 | } |
362 | 364 | ||
363 | static void buf_init(unsigned char* buf, size_t buflen) | 365 | static void buf_init(unsigned char* buf, size_t buflen) |
364 | { | 366 | { |
365 | fnf_buf = buf; | 367 | fnf_buf = buf; |
366 | fnf_buf_len = buflen; | 368 | fnf_buf_len = buflen; |
367 | fnf_read_index = 0; | 369 | fnf_read_index = buflen; |
368 | } | 370 | } |
369 | 371 | ||
370 | static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset) | 372 | static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset) |
@@ -601,14 +603,18 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
601 | } | 603 | } |
602 | else | 604 | else |
603 | { | 605 | { |
606 | long offset; | ||
607 | |||
604 | VDEBUGF("-- No VBR header --\n"); | 608 | VDEBUGF("-- No VBR header --\n"); |
605 | 609 | ||
606 | /* There was no VBR header found. So, we seek back to beginning and | 610 | /* There was no VBR header found. So, we seek back to beginning and |
607 | * search for the first MPEG frame header of the mp3 stream. */ | 611 | * search for the first MPEG frame header of the mp3 stream. */ |
608 | lseek(fd, -info->frame_size, SEEK_CUR); | 612 | offset = lseek(fd, -info->frame_size, SEEK_CUR); |
609 | result = get_next_header_info(fd, &bytecount, info, false); | 613 | result = get_next_header_info(fd, &bytecount, info, false); |
610 | if(result) | 614 | if(result) |
611 | return result; | 615 | return result; |
616 | |||
617 | info->byte_count = filesize(fd) - getid3v1len(fd) - offset - bytecount; | ||
612 | } | 618 | } |
613 | 619 | ||
614 | return bytecount; | 620 | return bytecount; |
@@ -647,7 +653,7 @@ int count_mp3_frames(int fd, int startpos, int filesize, | |||
647 | num_frames = 0; | 653 | num_frames = 0; |
648 | cnt = 0; | 654 | cnt = 0; |
649 | 655 | ||
650 | while((header = buf_find_next_frame(fd, &bytes, header_template))) { | 656 | while((header = buf_find_next_frame(fd, &bytes, startpos + filesize))) { |
651 | mp3headerinfo(&info, header); | 657 | mp3headerinfo(&info, header); |
652 | 658 | ||
653 | if(!header_template) | 659 | if(!header_template) |
@@ -723,7 +729,7 @@ int create_xing_header(int fd, long startpos, long filesize, | |||
723 | /* Advance from the last seek point to this one */ | 729 | /* Advance from the last seek point to this one */ |
724 | for(j = 0;j < pos - last_pos;j++) | 730 | for(j = 0;j < pos - last_pos;j++) |
725 | { | 731 | { |
726 | header = buf_find_next_frame(fd, &bytes, header_template); | 732 | header = buf_find_next_frame(fd, &bytes, startpos + filesize); |
727 | filepos += bytes; | 733 | filepos += bytes; |
728 | mp3headerinfo(&info, header); | 734 | mp3headerinfo(&info, header); |
729 | buf_seek(fd, info.frame_size-4); | 735 | buf_seek(fd, info.frame_size-4); |