Yuck: fix MP3 sync compatibility with DWI for certain mildly corrupt MP3s.
This used to work; I just noticed that it broke at some point, though I'm not sure when. Most of these changes is just reordering code.
This commit is contained in:
@@ -391,7 +391,42 @@ int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
|
|||||||
ret=mad_header_decode( &mad->Frame.header,&mad->Stream );
|
ret=mad_header_decode( &mad->Frame.header,&mad->Stream );
|
||||||
else
|
else
|
||||||
ret=mad_frame_decode( &mad->Frame,&mad->Stream );
|
ret=mad_frame_decode( &mad->Frame,&mad->Stream );
|
||||||
if( mad->Stream.error == MAD_ERROR_BADDATAPTR && mad->first_frame )
|
|
||||||
|
if( ret == -1 && (mad->Stream.error == MAD_ERROR_BUFLEN || mad->Stream.error == MAD_ERROR_BUFPTR) )
|
||||||
|
{
|
||||||
|
if( bytes_read > 25000 )
|
||||||
|
{
|
||||||
|
/* We've read this much without actually getting a frame; error. */
|
||||||
|
SetError( "Can't find data" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = fill_buffer();
|
||||||
|
if( ret <= 0 )
|
||||||
|
return ret;
|
||||||
|
bytes_read += ret;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mad->Stream.error == MAD_ERROR_LOSTSYNC)
|
||||||
|
{
|
||||||
|
/* This might be an ID3V2 tag. */
|
||||||
|
const int tagsize = id3_tag_query(mad->Stream.this_frame,
|
||||||
|
mad->Stream.bufend - mad->Stream.this_frame);
|
||||||
|
|
||||||
|
if( tagsize )
|
||||||
|
{
|
||||||
|
mad_stream_skip(&mad->Stream, tagsize);
|
||||||
|
|
||||||
|
/* Don't count the tagsize against the max-read-per-call figure. */
|
||||||
|
bytes_read -= tagsize;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mad->Stream.error == MAD_ERROR_BADDATAPTR || mad->Stream.error == MAD_ERROR_LOSTSYNC )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Something's corrupt. One cause of this is cutting an MP3 in the middle
|
* Something's corrupt. One cause of this is cutting an MP3 in the middle
|
||||||
@@ -399,11 +434,8 @@ int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
|
|||||||
* frames that have been removed. The frame is valid--we can get a header from
|
* frames that have been removed. The frame is valid--we can get a header from
|
||||||
* it, we just can't synth useful data.
|
* it, we just can't synth useful data.
|
||||||
*
|
*
|
||||||
* BASS pretends the bad frame is silent. Let's emulate that if we're at the
|
* BASS pretends the bad frames are silent. Emulate that, for compatibility.
|
||||||
* beginning, since that's probably a cut. The only time I've seen this in
|
|
||||||
* the middle of a stream is a corruption, which will probably lose sync anyway.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = 0; /* pretend success */
|
ret = 0; /* pretend success */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,23 +471,6 @@ int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mad->Stream.error == MAD_ERROR_LOSTSYNC)
|
|
||||||
{
|
|
||||||
/* This might be an ID3V2 tag. */
|
|
||||||
const int tagsize = id3_tag_query(mad->Stream.this_frame,
|
|
||||||
mad->Stream.bufend - mad->Stream.this_frame);
|
|
||||||
|
|
||||||
if( tagsize )
|
|
||||||
{
|
|
||||||
mad_stream_skip(&mad->Stream, tagsize);
|
|
||||||
|
|
||||||
/* Don't count the tagsize against the max-read-per-call figure. */
|
|
||||||
bytes_read -= tagsize;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( mad->Stream.error == MAD_ERROR_BADCRC )
|
if( mad->Stream.error == MAD_ERROR_BADCRC )
|
||||||
{
|
{
|
||||||
/* XXX untested */
|
/* XXX untested */
|
||||||
@@ -465,29 +480,12 @@ int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mad->Stream.error == MAD_ERROR_BUFLEN || mad->Stream.error == MAD_ERROR_BUFPTR )
|
if( !MAD_RECOVERABLE(mad->Stream.error) )
|
||||||
{
|
{
|
||||||
if( bytes_read > 25000 )
|
/* We've received an unrecoverable error. */
|
||||||
{
|
SetError( mad_stream_errorstr(&mad->Stream) );
|
||||||
/* We've read this much without actually getting a frame; error. */
|
return -1;
|
||||||
SetError( "Can't find data" );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = fill_buffer();
|
|
||||||
if( ret <= 0 )
|
|
||||||
return ret;
|
|
||||||
bytes_read += ret;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If it's some other recoverable error, just keep going. */
|
|
||||||
if( MAD_RECOVERABLE(mad->Stream.error) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SetError( mad_stream_errorstr(&mad->Stream) );
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user