summaryrefslogtreecommitdiff
path: root/lib/rbcodec
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec')
-rw-r--r--lib/rbcodec/codecs/libasf/asf.c14
-rw-r--r--lib/rbcodec/codecs/libasf/asf.h2
-rw-r--r--lib/rbcodec/metadata/asf.c30
3 files changed, 33 insertions, 13 deletions
diff --git a/lib/rbcodec/codecs/libasf/asf.c b/lib/rbcodec/codecs/libasf/asf.c
index 4e3235a422..5f6456a2cb 100644
--- a/lib/rbcodec/codecs/libasf/asf.c
+++ b/lib/rbcodec/codecs/libasf/asf.c
@@ -386,11 +386,17 @@ int asf_get_timestamp(int *duration)
386int asf_seek(int ms, asf_waveformatex_t* wfx) 386int asf_seek(int ms, asf_waveformatex_t* wfx)
387{ 387{
388 int time, duration, delta, temp, count=0; 388 int time, duration, delta, temp, count=0;
389 int bitrate = ci->id3->bitrate*1000/8;
389 390
390 /*estimate packet number from bitrate*/ 391 /*estimate packet number from bitrate*/
391 int initial_packet = ci->curpos/wfx->packet_size; 392 int initial_packet = ci->curpos/wfx->packet_size;
392 int packet_num = (((int64_t)ms)*(wfx->bitrate>>3))/wfx->packet_size/1000; 393 int packet_num = (((int64_t)ms)*(bitrate))/wfx->packet_size/1000;
393 int last_packet = ci->id3->filesize / wfx->packet_size; 394 /*subtract header size in case theres a lot of metadata*/
395 int last_packet = (ci->id3->filesize-ci->id3->first_frame_offset) / wfx->packet_size;
396
397 /*
398 DEBUGF("bitrate: %d\n", bitrate);
399 DEBUGF("attempting seek to: %d ms, initialp: %d, lastp: %d, estimating packet: %d, packet size: %d\n", ms, initial_packet, last_packet, packet_num, wfx->packet_size);*/
394 400
395 if (packet_num > last_packet) { 401 if (packet_num > last_packet) {
396 packet_num = last_packet; 402 packet_num = last_packet;
@@ -409,7 +415,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx)
409 415
410 /*check the time stamp of our packet*/ 416 /*check the time stamp of our packet*/
411 time = asf_get_timestamp(&duration); 417 time = asf_get_timestamp(&duration);
412 /*DEBUGF("seeked to %d ms with duration %d\n", time, duration);*/ 418 /*DEBUGF("seeked to %d ms (%d) with duration %d\n", time,packet_num, duration);*/
413 419
414 if (time < 0) { 420 if (time < 0) {
415 /*unknown error, try to recover*/ 421 /*unknown error, try to recover*/
@@ -427,7 +433,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx)
427 delta = ms-time; 433 delta = ms-time;
428 /*estimate new packet number from bitrate and our current position*/ 434 /*estimate new packet number from bitrate and our current position*/
429 temp += delta; 435 temp += delta;
430 packet_num = ((temp/1000)*(wfx->bitrate>>3) - (wfx->packet_size>>1))/wfx->packet_size; //round down! 436 packet_num = ((temp/1000)*(bitrate) - (wfx->packet_size<<1))/wfx->packet_size; //round down!
431 packet_offset = packet_num*wfx->packet_size; 437 packet_offset = packet_num*wfx->packet_size;
432 ci->seek_buffer(ci->id3->first_frame_offset+packet_offset); 438 ci->seek_buffer(ci->id3->first_frame_offset+packet_offset);
433 } 439 }
diff --git a/lib/rbcodec/codecs/libasf/asf.h b/lib/rbcodec/codecs/libasf/asf.h
index a7d384cf3d..2398a44eab 100644
--- a/lib/rbcodec/codecs/libasf/asf.h
+++ b/lib/rbcodec/codecs/libasf/asf.h
@@ -33,7 +33,7 @@ struct asf_waveformatex_s {
33 uint16_t blockalign; 33 uint16_t blockalign;
34 uint16_t bitspersample; 34 uint16_t bitspersample;
35 uint16_t datalen; 35 uint16_t datalen;
36 uint16_t numpackets; 36 uint64_t numpackets;
37 uint8_t data[46]; 37 uint8_t data[46];
38}; 38};
39typedef struct asf_waveformatex_s asf_waveformatex_t; 39typedef struct asf_waveformatex_s asf_waveformatex_t;
diff --git a/lib/rbcodec/metadata/asf.c b/lib/rbcodec/metadata/asf.c
index 469a5739d2..50e021b6a4 100644
--- a/lib/rbcodec/metadata/asf.c
+++ b/lib/rbcodec/metadata/asf.c
@@ -275,16 +275,16 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
275 275
276 fileprop = 1; 276 fileprop = 1;
277 277
278 /* Get the number of logical packets - uint16_t at offset 31 278 /* Get the number of logical packets - uint64_t at offset 32
279 * (Big endian byte order) */ 279 * (little endian byte order) */
280 lseek(fd, 31, SEEK_CUR); 280 lseek(fd, 32, SEEK_CUR);
281 read_uint16be(fd, &wfx->numpackets); 281 read_uint64le(fd, &wfx->numpackets);
282 //DEBUGF("read packets: %llx %lld\n", wfx->numpackets, wfx->numpackets);
282 283
283 /* Now get the play duration - uint64_t at offset 40 */ 284 /* Now get the play duration - uint64_t at offset 40 */
284 lseek(fd, 7, SEEK_CUR); 285 //lseek(fd, 4, SEEK_CUR);
285 read_uint64le(fd, &play_duration); 286 read_uint64le(fd, &play_duration);
286 id3->length = play_duration / 10000; 287 id3->length = play_duration / 10000;
287
288 //DEBUGF("****** length = %lums\n", id3->length); 288 //DEBUGF("****** length = %lums\n", id3->length);
289 289
290 /* Read the packet size - uint32_t at offset 68 */ 290 /* Read the packet size - uint32_t at offset 68 */
@@ -338,8 +338,22 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
338 read_uint16le(fd, &wfx->bitspersample); 338 read_uint16le(fd, &wfx->bitspersample);
339 read_uint16le(fd, &wfx->datalen); 339 read_uint16le(fd, &wfx->datalen);
340 340
341 /* Round bitrate to the nearest kbit */ 341 /*sanity check the included bitrate by comparing to file size and length*/
342 id3->bitrate = (wfx->bitrate + 500) / 1000; 342 unsigned int estimated_bitrate = (wfx->packet_size*wfx->numpackets)/id3->length*8000;
343
344 /*in theory we could just use the estimated bitrate always,
345 but its safer to underestimate*/
346 if( wfx->bitrate > estimated_bitrate)
347 {
348 /* Round bitrate to the nearest kbit */
349 id3->bitrate = (estimated_bitrate + 500) / 1000;
350 }
351 else
352 {
353 /* Round bitrate to the nearest kbit */
354 id3->bitrate = (wfx->bitrate + 500) / 1000;
355 }
356 /*DEBUGF("bitrate: %d estimated: %d\n", wfx->bitrate, estimated_bitrate);*/
343 id3->frequency = wfx->rate; 357 id3->frequency = wfx->rate;
344 358
345 if (wfx->codec_id == ASF_CODEC_ID_WMAV1) { 359 if (wfx->codec_id == ASF_CODEC_ID_WMAV1) {