diff options
Diffstat (limited to 'lib/rbcodec/metadata/rm.c')
-rw-r--r-- | lib/rbcodec/metadata/rm.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/lib/rbcodec/metadata/rm.c b/lib/rbcodec/metadata/rm.c index 2a5a2892a3..1e33f0b0ac 100644 --- a/lib/rbcodec/metadata/rm.c +++ b/lib/rbcodec/metadata/rm.c | |||
@@ -89,7 +89,7 @@ static char* fourcc2str(uint32_t f) | |||
89 | } | 89 | } |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | 92 | static int real_read_audio_stream_info(int fd, RMContext *rmctx) |
93 | { | 93 | { |
94 | int skipped = 0; | 94 | int skipped = 0; |
95 | uint32_t version; | 95 | uint32_t version; |
@@ -111,6 +111,7 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
111 | DEBUGF(" version=0x%04lx\n",((version >> 16) & 0xff)); | 111 | DEBUGF(" version=0x%04lx\n",((version >> 16) & 0xff)); |
112 | if (((version >> 16) & 0xff) == 3) { | 112 | if (((version >> 16) & 0xff) == 3) { |
113 | /* Very old version */ | 113 | /* Very old version */ |
114 | return -1; | ||
114 | } else { | 115 | } else { |
115 | #ifdef SIMULATOR | 116 | #ifdef SIMULATOR |
116 | real_read_object_header(fd, &obj); | 117 | real_read_object_header(fd, &obj); |
@@ -218,7 +219,7 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
218 | return skipped; | 219 | return skipped; |
219 | } | 220 | } |
220 | 221 | ||
221 | static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | 222 | static inline int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) |
222 | { | 223 | { |
223 | struct real_object_t obj; | 224 | struct real_object_t obj; |
224 | int res; | 225 | int res; |
@@ -242,6 +243,7 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | |||
242 | uint32_t max_bitrate; | 243 | uint32_t max_bitrate; |
243 | uint16_t num_streams; | 244 | uint16_t num_streams; |
244 | uint32_t next_data_off; | 245 | uint32_t next_data_off; |
246 | uint16_t pkt_version; | ||
245 | uint8_t header_end; | 247 | uint8_t header_end; |
246 | 248 | ||
247 | memset(&obj,0,sizeof(obj)); | 249 | memset(&obj,0,sizeof(obj)); |
@@ -250,6 +252,35 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | |||
250 | 252 | ||
251 | if (obj.fourcc == FOURCC('.','r','a',0xfd)) | 253 | if (obj.fourcc == FOURCC('.','r','a',0xfd)) |
252 | { | 254 | { |
255 | lseek(fd, 4, SEEK_SET); | ||
256 | skipped = real_read_audio_stream_info(fd, rmctx); | ||
257 | if (skipped > 0 && rmctx->codec_type == CODEC_AC3) | ||
258 | { | ||
259 | read_uint8(fd,&len); | ||
260 | skipped += (int)read_string(fd, id3->id3v1buf[0], sizeof(id3->id3v1buf[0]), '\0', len); | ||
261 | read_uint8(fd,&len); | ||
262 | skipped += (int)read_string(fd, id3->id3v1buf[1], sizeof(id3->id3v1buf[1]), '\0', len); | ||
263 | read_uint8(fd,&len); | ||
264 | skipped += (int)read_string(fd, id3->id3v1buf[2], sizeof(id3->id3v1buf[2]), '\0', len); | ||
265 | read_uint8(fd,&len); | ||
266 | skipped += (int)read_string(fd, id3->id3v1buf[3], sizeof(id3->id3v1buf[3]), '\0', len); | ||
267 | rmctx->data_offset = skipped + 8; | ||
268 | rmctx->bit_rate = rmctx->block_align * rmctx->sample_rate / 192; | ||
269 | if (rmctx->block_align) | ||
270 | rmctx->nb_packets = (filesize(fd) - rmctx->data_offset) / rmctx->block_align; | ||
271 | if (rmctx->sample_rate) | ||
272 | rmctx->duration = (uint32_t)(256LL * 6 * 1000 * rmctx->nb_packets / rmctx->sample_rate); | ||
273 | rmctx->flags |= RM_RAW_DATASTREAM; | ||
274 | |||
275 | DEBUGF(" data_offset = %ld\n",rmctx->data_offset); | ||
276 | DEBUGF(" avg_bitrate = %ld\n",rmctx->bit_rate); | ||
277 | DEBUGF(" duration = %ld\n",rmctx->duration); | ||
278 | DEBUGF(" title=\"%s\"\n",id3->id3v1buf[0]); | ||
279 | DEBUGF(" author=\"%s\"\n",id3->id3v1buf[1]); | ||
280 | DEBUGF(" copyright=\"%s\"\n",id3->id3v1buf[2]); | ||
281 | DEBUGF(" comment=\"%s\"\n",id3->id3v1buf[3]); | ||
282 | return 0; | ||
283 | } | ||
253 | /* Very old .ra format - not yet supported */ | 284 | /* Very old .ra format - not yet supported */ |
254 | return -1; | 285 | return -1; |
255 | } | 286 | } |
@@ -305,6 +336,8 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | |||
305 | DEBUGF(" data_offset = %ld\n",rmctx->data_offset); | 336 | DEBUGF(" data_offset = %ld\n",rmctx->data_offset); |
306 | DEBUGF(" num_streams = %d\n",num_streams); | 337 | DEBUGF(" num_streams = %d\n",num_streams); |
307 | DEBUGF(" flags=0x%04x\n",rmctx->flags); | 338 | DEBUGF(" flags=0x%04x\n",rmctx->flags); |
339 | |||
340 | rmctx->flags &= 0x00FF; | ||
308 | break; | 341 | break; |
309 | 342 | ||
310 | case FOURCC('C','O','N','T'): | 343 | case FOURCC('C','O','N','T'): |
@@ -409,7 +442,22 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | |||
409 | 442 | ||
410 | DEBUGF(" data_nb_packets = %ld\n",rmctx->nb_packets); | 443 | DEBUGF(" data_nb_packets = %ld\n",rmctx->nb_packets); |
411 | DEBUGF(" next DATA offset = %ld\n",next_data_off); | 444 | DEBUGF(" next DATA offset = %ld\n",next_data_off); |
412 | header_end = 1; | 445 | |
446 | if (!next_data_off) | ||
447 | { | ||
448 | if (rmctx->duration == 0 && rmctx->bit_rate != 0) | ||
449 | { | ||
450 | rmctx->duration = (uint32_t)(8000LL * rmctx->nb_packets * rmctx->block_align / rmctx->bit_rate); | ||
451 | DEBUGF(" estimated duration = %ld\n",rmctx->duration); | ||
452 | } | ||
453 | read_uint16be(fd, &pkt_version); | ||
454 | skipped += 2; | ||
455 | DEBUGF(" pkt_version=0x%04x\n", pkt_version); | ||
456 | if (pkt_version) | ||
457 | rmctx->flags |= RM_PKT_V1; | ||
458 | rmctx->data_offset = curpos; | ||
459 | header_end = 1; | ||
460 | } | ||
413 | break; | 461 | break; |
414 | } | 462 | } |
415 | if(header_end) break; | 463 | if(header_end) break; |
@@ -456,7 +504,7 @@ bool get_rm_metadata(int fd, struct mp3entry* id3) | |||
456 | 504 | ||
457 | id3->channels = rmctx->nb_channels; | 505 | id3->channels = rmctx->nb_channels; |
458 | id3->extradata_size = rmctx->extradata_size; | 506 | id3->extradata_size = rmctx->extradata_size; |
459 | id3->bitrate = rmctx->bit_rate / 1000; | 507 | id3->bitrate = (rmctx->bit_rate + 500) / 1000; |
460 | id3->frequency = rmctx->sample_rate; | 508 | id3->frequency = rmctx->sample_rate; |
461 | id3->length = rmctx->duration; | 509 | id3->length = rmctx->duration; |
462 | id3->filesize = filesize(fd); | 510 | id3->filesize = filesize(fd); |