summaryrefslogtreecommitdiffstats
path: root/stream/stream.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-08-22 18:21:32 +0200
committerwm4 <wm4@nowhere>2013-08-22 18:33:19 +0200
commita790f2133bb785e0c48a7c6cdc730c8b7e8287fb (patch)
treee9b4956bc63f8e8f4afd266cdf0b3a09d44c928a /stream/stream.c
parent28eac7dfb3a1cd67e3349f46c34a9a32465f6e55 (diff)
downloadmpv-a790f2133bb785e0c48a7c6cdc730c8b7e8287fb.tar.bz2
mpv-a790f2133bb785e0c48a7c6cdc730c8b7e8287fb.tar.xz
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.
Diffstat (limited to 'stream/stream.c')
-rw-r--r--stream/stream.c54
1 files changed, 26 insertions, 28 deletions
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)