summaryrefslogtreecommitdiffstats
path: root/stream/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/stream.c')
-rw-r--r--stream/stream.c63
1 files changed, 29 insertions, 34 deletions
diff --git a/stream/stream.c b/stream/stream.c
index 0acabe3f52..3ea4d475b7 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -306,7 +306,6 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying,
}
}
- s->flags = 0;
s->mode = flags & (STREAM_READ | STREAM_WRITE);
int r = sinfo->open(s, s->mode);
if (r != STREAM_OK) {
@@ -317,13 +316,7 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying,
if (!s->read_chunk)
s->read_chunk = 4 * (s->sector_size ? s->sector_size : STREAM_BUFFER_SIZE);
- if (!s->seek)
- s->flags &= ~MP_STREAM_SEEK;
- if (s->seek && !(s->flags & MP_STREAM_SEEK))
- s->flags |= MP_STREAM_SEEK;
-
- if (!(s->flags & MP_STREAM_SEEK))
- s->end_pos = 0;
+ assert(s->seekable == !!s->seek);
s->uncached_type = s->type;
@@ -394,7 +387,7 @@ static int stream_reconnect(stream_t *s)
#define RECONNECT_SLEEP_MAX_MS 500
if (!s->streaming)
return 0;
- if (!(s->flags & MP_STREAM_SEEK_FW))
+ if (!s->seekable)
return 0;
int64_t pos = s->pos;
int sleep_ms = 5;
@@ -468,7 +461,9 @@ static int stream_read_unbuffered(stream_t *s, void *buf, int len)
len = 0;
if (len == 0) {
// do not retry if this looks like proper eof
- if (s->eof || (s->end_pos && s->pos == s->end_pos))
+ int64_t size = -1;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &size);
+ if (s->eof || s->pos == size)
goto eof_out;
// just in case this is an error e.g. due to network
@@ -622,11 +617,11 @@ void stream_drop_buffers(stream_t *s)
static int stream_seek_unbuffered(stream_t *s, int64_t newpos)
{
if (newpos != s->pos) {
- if (newpos > s->pos && !(s->flags & MP_STREAM_SEEK_FW)) {
- MP_ERR(s, "Can not seek in this stream\n");
+ if (newpos > s->pos && !s->seekable) {
+ MP_ERR(s, "Cannot seek forward in this stream\n");
return 0;
}
- if (newpos < s->pos && !(s->flags & MP_STREAM_SEEK_BW)) {
+ if (newpos < s->pos && !s->seekable) {
MP_ERR(s, "Cannot seek backward in linear streams!\n");
return 1;
}
@@ -647,7 +642,7 @@ static int stream_seek_long(stream_t *s, int64_t pos)
stream_drop_buffers(s);
if (s->mode == STREAM_WRITE) {
- if (!(s->flags & MP_STREAM_SEEK) || !s->seek(s, pos))
+ if (!s->seekable || !s->seek(s, pos))
return 0;
return 1;
}
@@ -659,9 +654,7 @@ static int stream_seek_long(stream_t *s, int64_t pos)
MP_TRACE(s, "Seek from %" PRId64 " to %" PRId64
" (with offset %d)\n", s->pos, pos, (int)(pos - newpos));
- if (pos >= s->pos && !(s->flags & MP_STREAM_SEEK) &&
- (s->flags & MP_STREAM_FAST_SKIPPING))
- {
+ if (pos >= s->pos && !s->seekable && s->fast_skip) {
// skipping is handled by generic code below
} else if (stream_seek_unbuffered(s, newpos) >= 0) {
return 0;
@@ -708,7 +701,7 @@ int stream_skip(stream_t *s, int64_t len)
int64_t target = stream_tell(s) + len;
if (len < 0)
return stream_seek(s, target);
- if (len > 2 * STREAM_BUFFER_SIZE && (s->flags & MP_STREAM_SEEK_FW)) {
+ if (len > 2 * STREAM_BUFFER_SIZE && s->seekable) {
// Seek to 1 byte before target - this is the only way to distinguish
// skip-to-EOF and skip-past-EOF in general. Successful seeking means
// absolutely nothing, so test by doing a real read of the last byte.
@@ -726,18 +719,19 @@ int stream_control(stream_t *s, int cmd, void *arg)
{
if (!s->control)
return STREAM_UNSUPPORTED;
- return s->control(s, cmd, arg);
-}
-
-void stream_update_size(stream_t *s)
-{
- if (!(s->flags & MP_STREAM_SEEK))
- return;
- uint64_t size;
- if (stream_control(s, STREAM_CTRL_GET_SIZE, &size) == STREAM_OK) {
- if (size > s->end_pos)
- s->end_pos = size;
+ int r = s->control(s, cmd, arg);
+ if (r == STREAM_UNSUPPORTED) {
+ // Fallbacks
+ switch (cmd) {
+ case STREAM_CTRL_GET_SIZE:
+ if (s->end_pos > 0) {
+ *(int64_t *)arg = s->end_pos;
+ return STREAM_OK;
+ }
+ break;
+ }
}
+ return r;
}
void free_stream(stream_t *s)
@@ -804,7 +798,7 @@ int stream_enable_cache(stream_t **stream, struct mp_cache_opts *opts)
stream_t *cache = new_stream();
cache->uncached_type = orig->type;
cache->uncached_stream = orig;
- cache->flags |= MP_STREAM_SEEK;
+ cache->seekable = true;
cache->mode = STREAM_READ;
cache->read_chunk = 4 * STREAM_BUFFER_SIZE;
@@ -815,7 +809,6 @@ int stream_enable_cache(stream_t **stream, struct mp_cache_opts *opts)
cache->safe_origin = orig->safe_origin;
cache->opts = orig->opts;
cache->global = orig->global;
- cache->end_pos = orig->end_pos;
cache->log = mp_log_new(cache, cache->global->log, "cache");
@@ -935,10 +928,12 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
int total_read = 0;
int padding = 1;
char *buf = NULL;
- if (s->end_pos > max_size)
+ int64_t size = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &size);
+ if (size > max_size)
return (struct bstr){NULL, 0};
- if (s->end_pos > 0)
- bufsize = s->end_pos + padding;
+ if (size > 0)
+ bufsize = size + padding;
else
bufsize = 1000;
while (1) {