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:
parent
28eac7dfb3
commit
a790f2133b
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user