[MPlayer-dev-eng] [PATCH] Fix incomplete loading of playlists of certain sizes

Joel Klinghed the_jk at yahoo.com
Fri Jul 31 00:43:14 CEST 2015

On Thu, 30 Jul 2015 10:28:56 +0200
Reimar Döffinger <Reimar.Doeffinger at gmx.de> wrote:

> On Thu, Jul 30, 2015 at 12:52:09AM +0200, Joel Klinghed wrote:
> > Hi,
> > 
> > the bug this patches fixes appears when you have playlist files of a
> > size larger than the buffer size used by playtreeparser.c but
> > smaller than the buffer size used by stream.c.
> > What happens is that the whole playlist file is read by stream.c in
> > and put in the stream buffer by stream_fill_buffer() and
> > stream->eof is set to true. However, playtreeparser.c only fills
> > it's own buffer and then upon seeing stream->eof being true, treats
> > the playlist as ended even tho the stream buffer still contains
> > data.
> stream_fill_buffer does not set eof, only stream_read_internal does.
> stream_read_internal should only be called when the stream
> buffer is empty, and will only set eof if it cannot read any further
> data, i.e. the current position really is the end of the file.
> So something is wrong with your explanation.
> One potential issue is that seeking back from EOF will not unset
> EOF, that needs to be done separately, so maybe that is what
> causes the issue you see?

My description was a bit lacking in details;

playlist file is 2022 bytes.

playtreeparser.c reads the first line in play_tree_parser_get_line(),
calling stream_read(BUF_STEP=1024).

stream_read() ends up calling stream_fill_buffer() as the stream
buffer is empty. stream_fill_buffer() calls
stream_read_internal(STREAM_BUFFER_SIZE=4096) which returns 2022 bytes
stream_fill_buffer() then calls
stream_read_internal(STREAM_BUFFER_MIN=2048) as the length returned by
the first call to stream_read_internal returned less than
STREAM_BUFFER_MIN. The second call to stream_read_internal sets
stream->eof to true as there is no data left in the file.
stream_fill_buffer() now returns as the last call
to stream_read_internal() returned 0.

Back to play_tree_parser_get_line() that got the 1024 bytes it asked
from stream_read().
The stream now has 998 bytes left in its buffer and eof set to true.
Next call to play_tree_parser_get_line() will not call stream_read() as
stream->eof is true.

I should really have mentioned stream_fill_buffer() calling
stream_read_internal() twice because the file is smaller than
STREAM_BUFFER_MIN as the cause.

Regards, Joel Klinghed

More information about the MPlayer-dev-eng mailing list