1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-30 02:52:10 +00:00

stream: move file forward skipping to common stream implementation

stream_file.c contains some code meant for forward seeking with pipes.
This simply reads data until the seek position is reached. Move this
code to stream.c. This stops stream_file from doing strange things
(messing with stream internals), and removes the code duplication too.

We also make stream_seek_long() use the new skip code. This is shorter
and much easier to follow than the old code, which basically did strange
things.
This commit is contained in:
wm4 2013-08-22 18:21:32 +02:00
parent 28eac7dfb3
commit a790f2133b
3 changed files with 29 additions and 52 deletions

View File

@ -249,6 +249,9 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
if (s->seek && !(s->flags & MP_STREAM_SEEK))
s->flags |= MP_STREAM_SEEK;
if (s->flags & MP_STREAM_FAST_SKIPPING)
s->flags |= MP_STREAM_SEEK_FW;
s->mode = mode;
s->uncached_type = s->type;
@ -512,6 +515,23 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len)
return rd;
}
static int stream_skip_read(struct stream *s, int64_t len)
{
while (len > 0) {
int x = s->buf_len - s->buf_pos;
if (x == 0) {
if (!stream_fill_buffer(s))
return 0; // EOF
x = s->buf_len - s->buf_pos;
}
if (x > len)
x = len;
s->buf_pos += x;
len -= x;
}
return 1;
}
// Seek function bypassing the local stream buffer.
static int stream_seek_unbuffered(stream_t *s, int64_t newpos)
{
@ -556,26 +576,16 @@ static int stream_seek_long(stream_t *s, int64_t pos)
" new_bufpos=%" PRIX64 " buflen=%X \n",
(int64_t)s->pos, (int64_t)newpos, (int64_t)pos, s->buf_len);
pos -= newpos;
if (stream_seek_unbuffered(s, newpos) >= 0) {
if (!s->seek && (s->flags & MP_STREAM_FAST_SKIPPING) && pos >= s->pos) {
// skipping is handled by generic code below
} else if (stream_seek_unbuffered(s, newpos) >= 0) {
s->pos = oldpos;
return 0;
}
while (s->pos < newpos) {
if (stream_fill_buffer(s) <= 0)
break; // EOF
}
if (pos >= s->pos && stream_skip_read(s, pos - s->pos) > 0)
return 1; // success
while (stream_fill_buffer(s) > 0) {
if (pos <= s->buf_len) {
s->buf_pos = pos; // byte position in sector
s->eof = 0;
return 1;
}
pos -= s->buf_len;
}
// Fill failed, but seek still is a success (partially).
s->buf_pos = 0;
s->buf_len = 0;
@ -624,19 +634,7 @@ int stream_skip(stream_t *s, int64_t len)
}
return r;
}
while (len > 0) {
int x = s->buf_len - s->buf_pos;
if (x == 0) {
if (!stream_fill_buffer(s))
return 0; // EOF
x = s->buf_len - s->buf_pos;
}
if (x > len)
x = len;
s->buf_pos += x;
len -= x;
}
return 1;
return stream_skip_read(s, len);
}
int stream_control(stream_t *s, int cmd, void *arg)

View File

@ -58,6 +58,7 @@ enum streamtype {
#define STREAM_WRITE 1
// stream->flags
#define MP_STREAM_FAST_SKIPPING 1 // allow forward seeks by skipping
#define MP_STREAM_SEEK_BW 2
#define MP_STREAM_SEEK_FW 4
#define MP_STREAM_SEEK (MP_STREAM_SEEK_BW | MP_STREAM_SEEK_FW)

View File

@ -69,26 +69,6 @@ static int seek(stream_t *s, int64_t newpos)
return 1;
}
static int seek_forward(stream_t *s, int64_t newpos)
{
if (newpos < s->pos) {
mp_msg(MSGT_STREAM, MSGL_INFO,
"Cannot seek backward in linear streams!\n");
return 0;
}
while (s->pos < newpos) {
int len = s->fill_buffer(s, s->buffer, STREAM_BUFFER_SIZE);
if (len <= 0) { // EOF
s->buf_pos = s->buf_len = 0;
break;
}
s->buf_pos = 0;
s->buf_len = len;
s->pos += len;
}
return 1;
}
static int control(stream_t *s, int cmd, void *arg)
{
struct priv *p = s->priv;
@ -192,10 +172,8 @@ static int open_f(stream_t *stream, int mode)
len = -1;
#endif
stream->type = STREAMTYPE_FILE;
if (len == -1 && mode == STREAM_READ) {
stream->seek = seek_forward;
stream->flags = MP_STREAM_SEEK_FW;
} else if (len >= 0) {
stream->flags = MP_STREAM_FAST_SKIPPING;
if (len >= 0) {
stream->seek = seek;
stream->end_pos = len;
}