1
0
Fork 0
forked from len0rd/rockbox

Fix overflow when seeking in long files wma. Also, add a simple sanity check when seeking.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15851 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Giacomelli 2007-11-30 00:46:32 +00:00
parent 94be71eab5
commit 1a5d59498a

View file

@ -386,7 +386,7 @@ static int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlen
/*entry point for seeks*/ /*entry point for seeks*/
static int seek(int ms, asf_waveformatex_t* wfx){ static int seek(int ms, asf_waveformatex_t* wfx){
int time, duration, delta, temp; int time, duration, delta, temp, count=0;
/*estimate packet number from bitrate*/ /*estimate packet number from bitrate*/
int initial_packet = ci->curpos/wfx->packet_size; int initial_packet = ci->curpos/wfx->packet_size;
@ -396,7 +396,6 @@ static int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlen
if(packet_num > last_packet){ if(packet_num > last_packet){
packet_num = last_packet; packet_num = last_packet;
} }
/*calculate byte address of the start of that packet*/ /*calculate byte address of the start of that packet*/
int packet_offset = packet_num*wfx->packet_size; int packet_offset = packet_num*wfx->packet_size;
@ -404,6 +403,8 @@ static int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlen
ci->seek_buffer(ci->id3->first_frame_offset+packet_offset); ci->seek_buffer(ci->id3->first_frame_offset+packet_offset);
temp = ms; temp = ms;
while(1){ 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*/ /*check the time stamp of our packet*/
time = get_timestamp(&duration); time = get_timestamp(&duration);
@ -416,7 +417,7 @@ static int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlen
return ms; return ms;
} }
if(time+duration>=ms && time<=ms){ if((time+duration>=ms && time<=ms) || count > 10){
/*the get_timestamp function advances us 12 bytes past the packet start*/ /*the get_timestamp function advances us 12 bytes past the packet start*/
ci->seek_buffer(ci->curpos-12); ci->seek_buffer(ci->curpos-12);
DEBUGF("Found our packet! Now at %d packet\n", packet_num); DEBUGF("Found our packet! Now at %d packet\n", packet_num);
@ -424,14 +425,10 @@ static int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlen
}else { }else {
/*seek again*/ /*seek again*/
delta = ms-time; delta = ms-time;
DEBUGF("delta is %d ms\n", delta);
/*estimate new packet number from bitrate and our current position*/ /*estimate new packet number from bitrate and our current position*/
temp += delta; temp += delta;
packet_num = (temp*(wfx->bitrate>>3)/1000 - (wfx->packet_size>>1))/wfx->packet_size; //round down! packet_num = ((temp/1000)*(wfx->bitrate>>3) - (wfx->packet_size>>1))/wfx->packet_size; //round down!
DEBUGF("updated Packet_num is %d\n", packet_num);
packet_offset = packet_num*wfx->packet_size; packet_offset = packet_num*wfx->packet_size;
ci->seek_buffer(ci->id3->first_frame_offset+packet_offset); ci->seek_buffer(ci->id3->first_frame_offset+packet_offset);
} }
} }
@ -524,6 +521,7 @@ next_track:
ci->seek_complete(); ci->seek_complete();
goto next_track; goto next_track;
} }
DEBUGF("Seek returned %d\n", time);
ci->set_elapsed(elapsedtime); ci->set_elapsed(elapsedtime);
/*flush the wma decoder state*/ /*flush the wma decoder state*/
@ -558,10 +556,12 @@ new_packet:
wmares = wma_decode_superframe_frame(&wmadec, wmares = wma_decode_superframe_frame(&wmadec,
decoded, decoded,
audiobuf, audiobufsize); audiobuf, audiobufsize);
ci->yield (); ci->yield ();
if (wmares < 0){ if (wmares < 0){
/* Do the above, but for errors in decode.*/ /* Do the above, but for errors in decode.
*/
errcount++; errcount++;
DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount); DEBUGF("WMA decode error %d, errcount %d\n",wmares, errcount);
if (errcount > 5) { if (errcount > 5) {