[MPlayer-dev-eng] BUG: flac fails to decode under low memory conditions
Michael Niedermayer
michaelni at gmx.at
Fri Feb 4 12:54:24 CET 2005
Hi
On Thursday 03 February 2005 23:41, elupus wrote:
> Hi,
>
> To begin with, sorry for my poor excuse for mailing client. Wasn't too keen
> on switching to something else, just for this message :).
>
> Anyway found a bug in flac.c. Had been digging around qoute a couple of
> times to figure out why flac files would play fine in mplayer on win32,
> however not in our special version of it on the xbox. Sometimes it'd work
> but most of the time it would fail. Seems it's related to how much free
> memmory is available, and as we have very limited memory on the xbox it
> shows up. It works fine aslong as realloc returns the same pointer as it
> got, but if the memloacation moved, it will fail (which only happens when
> we have less memmory available.)
>
> In flac.c, function flac_decode_frame this code exists
>
> if(1 && s->max_framesize){//FIXME truncated
> buf_size= FFMIN(buf_size, s->max_framesize -
> s->bitstream_size); input_buf_size= buf_size;
> .....
> memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size],
> buf, buf_size);
> buf= &s->bitstream[s->bitstream_index];
> buf_size += s->bitstream_size;
> s->bitstream_size= buf_size;
>
> if(buf_size < s->max_framesize){
> return input_buf_size;
> }
> }
>
> init_get_bits(&s->gb, buf, buf_size*8);
>
> This is where s->gb is inited to have it's buffer point to the same mem
> area as buf, ie part of s->bitstream. Somewhat later in that function there
> is a loop which finds all header data.
>
> do {
> metadata_last = get_bits(&s->gb, 1);
> metadata_type = get_bits(&s->gb, 7);
> metadata_size = get_bits_long(&s->gb, 24);
> .....
> if(metadata_size){
> switch(metadata_type)
> {
> case METADATA_TYPE_STREAMINFO:
> metadata_streaminfo(s);
> dump_headers(s);
> break;
> default:
> for(i=0; i<metadata_size; i++)
> skip_bits(&s->gb, 8);
> }
> }
> } while(!metadata_last);
>
> When a stream info is found it calls the metadata_streaminfo function,
> which in the end calls allocate_buffers(s). This function will make this
> call.
>
> s->bitstream= av_fast_realloc(s->bitstream,
> &s->allocated_bitstream_size, s->max_framesize);
>
> Which incidently happens to be the same memory area as s->gb points to. So
> aslong as realloc manages to get the same memory area back, all is fine,
> however if not, when we get back to the loop looking for header, the call
> metadata_last = get_bits(&s->gb, 1), will fail as s->gb has been
> deallocated be realloc. Not entirly sure how to fix this as I don't entirly
> understand the code, but i suppose it probably just be to reinit s->gb to
> the new memlocation.
fixed, please test
[...]
--
Michael
"nothing is evil in the beginning. Even Sauron was not so." -- Elrond
More information about the MPlayer-dev-eng
mailing list