From a790f2133bb785e0c48a7c6cdc730c8b7e8287fb Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 22 Aug 2013 18:21:32 +0200 Subject: 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. --- stream/stream.c | 54 +++++++++++++++++++++++++--------------------------- stream/stream.h | 1 + stream/stream_file.c | 26 ++----------------------- 3 files changed, 29 insertions(+), 52 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 45bc7997a1..f735329cdd 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -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) diff --git a/stream/stream.h b/stream/stream.h index 7a9b6ab909..f19ab4203f 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -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) diff --git a/stream/stream_file.c b/stream/stream_file.c index cb8d4e2dbf..a8dcf8fbdb 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -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; } -- cgit v1.2.3