From 546edf36217573ec6813958552fda9330ac67131 Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Fri, 21 May 2010 15:51:22 +0000 Subject: Move seek() from wma.c to libasf since it's really ASF-specific. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26235 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libasf/asf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ apps/codecs/libasf/asf.h | 5 ++++- 2 files changed, 56 insertions(+), 1 deletion(-) (limited to 'apps/codecs/libasf') diff --git a/apps/codecs/libasf/asf.c b/apps/codecs/libasf/asf.c index 18503218b7..65d3fd8deb 100644 --- a/apps/codecs/libasf/asf.c +++ b/apps/codecs/libasf/asf.c @@ -376,3 +376,55 @@ int asf_get_timestamp(int *duration) return send_time; } + +/*entry point for seeks*/ +int seek(int ms, asf_waveformatex_t* wfx) +{ + int time, duration, delta, temp, count=0; + + /*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; + + if (packet_num > last_packet) { + packet_num = last_packet; + } + + /*calculate byte address of the start of that packet*/ + int packet_offset = packet_num*wfx->packet_size; + + /*seek to estimated packet*/ + ci->seek_buffer(ci->id3->first_frame_offset+packet_offset); + temp = ms; + while (1) + { + /*for very large files it can be difficult and unimportant to find the exact packet*/ + count++; + + /*check the time stamp of our packet*/ + time = asf_get_timestamp(&duration); + DEBUGF("seeked to %d ms with duration %d\n", time, duration); + + if (time < 0) { + /*unknown error, try to recover*/ + DEBUGF("UKNOWN SEEK ERROR\n"); + ci->seek_buffer(ci->id3->first_frame_offset+initial_packet*wfx->packet_size); + /*seek failed so return time stamp of the initial packet*/ + return asf_get_timestamp(&duration); + } + + if ((time+duration>=ms && time<=ms) || count > 10) { + DEBUGF("Found our packet! Now at %d packet\n", packet_num); + return time; + } else { + /*seek again*/ + 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_offset = packet_num*wfx->packet_size; + ci->seek_buffer(ci->id3->first_frame_offset+packet_offset); + } + } +} diff --git a/apps/codecs/libasf/asf.h b/apps/codecs/libasf/asf.h index c15bf4edec..9592618997 100644 --- a/apps/codecs/libasf/asf.h +++ b/apps/codecs/libasf/asf.h @@ -32,7 +32,8 @@ struct asf_waveformatex_s { uint16_t blockalign; uint16_t bitspersample; uint16_t datalen; - uint8_t data[6]; + uint16_t numpackets; + uint8_t data[18]; }; typedef struct asf_waveformatex_s asf_waveformatex_t; @@ -41,5 +42,7 @@ int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlength, int asf_get_timestamp(int *duration); +int seek(int ms, asf_waveformatex_t* wfx); + #endif /* _ASF_H */ -- cgit v1.2.3