mirror of
https://github.com/mpv-player/mpv
synced 2025-01-01 20:32:13 +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))
|
if (s->seek && !(s->flags & MP_STREAM_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->mode = mode;
|
||||||
|
|
||||||
s->uncached_type = s->type;
|
s->uncached_type = s->type;
|
||||||
@ -512,6 +515,23 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len)
|
|||||||
return rd;
|
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.
|
// Seek function bypassing the local stream buffer.
|
||||||
static int stream_seek_unbuffered(stream_t *s, int64_t newpos)
|
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",
|
" new_bufpos=%" PRIX64 " buflen=%X \n",
|
||||||
(int64_t)s->pos, (int64_t)newpos, (int64_t)pos, s->buf_len);
|
(int64_t)s->pos, (int64_t)newpos, (int64_t)pos, s->buf_len);
|
||||||
|
|
||||||
pos -= newpos;
|
if (!s->seek && (s->flags & MP_STREAM_FAST_SKIPPING) && pos >= s->pos) {
|
||||||
|
// skipping is handled by generic code below
|
||||||
if (stream_seek_unbuffered(s, newpos) >= 0) {
|
} else if (stream_seek_unbuffered(s, newpos) >= 0) {
|
||||||
s->pos = oldpos;
|
s->pos = oldpos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s->pos < newpos) {
|
if (pos >= s->pos && stream_skip_read(s, pos - s->pos) > 0)
|
||||||
if (stream_fill_buffer(s) <= 0)
|
return 1; // success
|
||||||
break; // EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
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).
|
// Fill failed, but seek still is a success (partially).
|
||||||
s->buf_pos = 0;
|
s->buf_pos = 0;
|
||||||
s->buf_len = 0;
|
s->buf_len = 0;
|
||||||
@ -624,19 +634,7 @@ int stream_skip(stream_t *s, int64_t len)
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
while (len > 0) {
|
return stream_skip_read(s, len);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_control(stream_t *s, int cmd, void *arg)
|
int stream_control(stream_t *s, int cmd, void *arg)
|
||||||
|
@ -58,6 +58,7 @@ enum streamtype {
|
|||||||
#define STREAM_WRITE 1
|
#define STREAM_WRITE 1
|
||||||
|
|
||||||
// stream->flags
|
// stream->flags
|
||||||
|
#define MP_STREAM_FAST_SKIPPING 1 // allow forward seeks by skipping
|
||||||
#define MP_STREAM_SEEK_BW 2
|
#define MP_STREAM_SEEK_BW 2
|
||||||
#define MP_STREAM_SEEK_FW 4
|
#define MP_STREAM_SEEK_FW 4
|
||||||
#define MP_STREAM_SEEK (MP_STREAM_SEEK_BW | MP_STREAM_SEEK_FW)
|
#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;
|
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)
|
static int control(stream_t *s, int cmd, void *arg)
|
||||||
{
|
{
|
||||||
struct priv *p = s->priv;
|
struct priv *p = s->priv;
|
||||||
@ -192,10 +172,8 @@ static int open_f(stream_t *stream, int mode)
|
|||||||
len = -1;
|
len = -1;
|
||||||
#endif
|
#endif
|
||||||
stream->type = STREAMTYPE_FILE;
|
stream->type = STREAMTYPE_FILE;
|
||||||
if (len == -1 && mode == STREAM_READ) {
|
stream->flags = MP_STREAM_FAST_SKIPPING;
|
||||||
stream->seek = seek_forward;
|
if (len >= 0) {
|
||||||
stream->flags = MP_STREAM_SEEK_FW;
|
|
||||||
} else if (len >= 0) {
|
|
||||||
stream->seek = seek;
|
stream->seek = seek;
|
||||||
stream->end_pos = len;
|
stream->end_pos = len;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user