summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-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 4e3235a..5f6456a 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)
int asf_seek(int ms, asf_waveformatex_t* wfx)
{
int time, duration, delta, temp, count=0;
+ int bitrate = ci->id3->bitrate*1000/8;
/*estimate packet number from bitrate*/
int initial_packet = ci->curpos/wfx->packet_size;
- int packet_num = (((int64_t)ms)*(wfx->bitrate>>3))/wfx->packet_size/1000;
- int last_packet = ci->id3->filesize / wfx->packet_size;
+ int packet_num = (((int64_t)ms)*(bitrate))/wfx->packet_size/1000;
+ /*subtract header size in case theres a lot of metadata*/
+ int last_packet = (ci->id3->filesize-ci->id3->first_frame_offset) / wfx->packet_size;
+
+ /*
+ DEBUGF("bitrate: %d\n", bitrate);
+ 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);*/
if (packet_num > last_packet) {
packet_num = last_packet;
@@ -409,7 +415,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx)
/*check the time stamp of our packet*/
time = asf_get_timestamp(&duration);
- /*DEBUGF("seeked to %d ms with duration %d\n", time, duration);*/
+ /*DEBUGF("seeked to %d ms (%d) with duration %d\n", time,packet_num, duration);*/
if (time < 0) {
/*unknown error, try to recover*/
@@ -427,7 +433,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx)
delta = ms-time;
/*estimate new packet number from bitrate and our current position*/
temp += delta;
- packet_num = ((temp/1000)*(wfx->bitrate>>3) - (wfx->packet_size>>1))/wfx->packet_size; //round down!
+ packet_num = ((temp/1000)*(bitrate) - (wfx->packet_size<<1))/wfx->packet_size; //round down!
packet_offset = packet_num*wfx->packet_size;
ci->seek_buffer(ci->id3->first_frame_offset+packet_offset);
}
diff --git a/lib/rbcodec/codecs/libasf/asf.h b/lib/rbcodec/codecs/libasf/asf.h
index a7d384c..2398a44 100644
--- a/lib/rbcodec/codecs/libasf/asf.h
+++ b/lib/rbcodec/codecs/libasf/asf.h
@@ -33,7 +33,7 @@ struct asf_waveformatex_s {
uint16_t blockalign;
uint16_t bitspersample;
uint16_t datalen;
- uint16_t numpackets;
+ uint64_t numpackets;
uint8_t data[46];
};
typedef struct asf_waveformatex_s asf_waveformatex_t;
diff --git a/lib/rbcodec/metadata/asf.c b/lib/rbcodec/metadata/asf.c
index 469a573..50e021b 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,
fileprop = 1;
- /* Get the number of logical packets - uint16_t at offset 31
- * (Big endian byte order) */
- lseek(fd, 31, SEEK_CUR);
- read_uint16be(fd, &wfx->numpackets);
+ /* Get the number of logical packets - uint64_t at offset 32
+ * (little endian byte order) */
+ lseek(fd, 32, SEEK_CUR);
+ read_uint64le(fd, &wfx->numpackets);
+ //DEBUGF("read packets: %llx %lld\n", wfx->numpackets, wfx->numpackets);
/* Now get the play duration - uint64_t at offset 40 */
- lseek(fd, 7, SEEK_CUR);
+ //lseek(fd, 4, SEEK_CUR);
read_uint64le(fd, &play_duration);
id3->length = play_duration / 10000;
-
//DEBUGF("****** length = %lums\n", id3->length);
/* Read the packet size - uint32_t at offset 68 */
@@ -338,8 +338,22 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
read_uint16le(fd, &wfx->bitspersample);
read_uint16le(fd, &wfx->datalen);
- /* Round bitrate to the nearest kbit */
- id3->bitrate = (wfx->bitrate + 500) / 1000;
+ /*sanity check the included bitrate by comparing to file size and length*/
+ unsigned int estimated_bitrate = (wfx->packet_size*wfx->numpackets)/id3->length*8000;
+
+ /*in theory we could just use the estimated bitrate always,
+ but its safer to underestimate*/
+ if( wfx->bitrate > estimated_bitrate)
+ {
+ /* Round bitrate to the nearest kbit */
+ id3->bitrate = (estimated_bitrate + 500) / 1000;
+ }
+ else
+ {
+ /* Round bitrate to the nearest kbit */
+ id3->bitrate = (wfx->bitrate + 500) / 1000;
+ }
+ /*DEBUGF("bitrate: %d estimated: %d\n", wfx->bitrate, estimated_bitrate);*/
id3->frequency = wfx->rate;
if (wfx->codec_id == ASF_CODEC_ID_WMAV1) {