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:
parent
94be71eab5
commit
1a5d59498a
1 changed files with 24 additions and 24 deletions
|
|
@ -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,30 +521,31 @@ 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*/
|
||||||
wmadec.last_superframe_len = 0;
|
wmadec.last_superframe_len = 0;
|
||||||
wmadec.last_bitoffset = 0;
|
wmadec.last_bitoffset = 0;
|
||||||
ci->seek_complete();
|
ci->seek_complete();
|
||||||
}
|
}
|
||||||
errcount = 0;
|
errcount = 0;
|
||||||
new_packet:
|
new_packet:
|
||||||
res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &wfx);
|
res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &wfx);
|
||||||
if(res < 0){
|
if(res < 0){
|
||||||
|
|
||||||
/* We'll try to recover from a parse error a certain number of
|
/* We'll try to recover from a parse error a certain number of
|
||||||
* times. If we succeed, the error counter will be reset.
|
* times. If we succeed, the error counter will be reset.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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) {
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
ci->advance_buffer(packetlength);
|
ci->advance_buffer(packetlength);
|
||||||
goto new_packet;
|
goto new_packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if (res > 0) {
|
}else if (res > 0) {
|
||||||
wma_decode_superframe_init(&wmadec,
|
wma_decode_superframe_init(&wmadec,
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue