summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c3
-rw-r--r--demux/demux_lavf.c25
-rw-r--r--demux/demux_mkv.c17
-rw-r--r--demux/demux_raw.c9
-rw-r--r--player/command.c11
-rw-r--r--player/misc.c6
-rw-r--r--player/playloop.c9
-rw-r--r--stream/cache.c16
-rw-r--r--stream/stream.c63
-rw-r--r--stream/stream.h17
-rw-r--r--stream/stream_bluray.c1
-rw-r--r--stream/stream_cdda.c1
-rw-r--r--stream/stream_dvdnav.c1
-rw-r--r--stream/stream_file.c7
-rw-r--r--stream/stream_lavf.c16
-rw-r--r--stream/stream_memory.c5
-rw-r--r--stream/stream_rar.c2
-rw-r--r--stream/stream_smb.c6
-rw-r--r--stream/stream_vcd.c1
19 files changed, 112 insertions, 104 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 4da1adb134..ba231b5af6 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -587,8 +587,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.type = desc->type,
.stream = stream,
.stream_pts = MP_NOPTS_VALUE,
- .seekable = (stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK &&
- stream->end_pos > 0,
+ .seekable = stream->seekable,
.accurate_seek = true,
.filepos = -1,
.opts = global->opts,
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index b5a6ef998c..2b43f4f27f 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -135,17 +135,18 @@ static int64_t mp_seek(void *opaque, int64_t pos, int whence)
return -1;
MP_DBG(demuxer, "mp_seek(%p, %"PRId64", %d)\n",
stream, pos, whence);
- if (whence == SEEK_CUR)
+ if (whence == SEEK_END || whence == AVSEEK_SIZE) {
+ int64_t end;
+ if (stream_control(stream, STREAM_CTRL_GET_SIZE, &end) != STREAM_OK)
+ return -1;
+ if (whence == AVSEEK_SIZE)
+ return end;
+ pos += end;
+ } else if (whence == SEEK_CUR) {
pos += stream_tell(stream);
- else if (whence == SEEK_END && stream->end_pos > 0)
- pos += stream->end_pos;
- else if (whence == SEEK_SET)
- /* ok */;
- else if (whence == AVSEEK_SIZE && stream->end_pos > 0) {
- stream_update_size(stream);
- return stream->end_pos;
- } else
+ } else if (whence != SEEK_SET) {
return -1;
+ }
if (pos < 0)
return -1;
@@ -824,11 +825,13 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags)
if (flags & SEEK_FACTOR) {
struct stream *s = demuxer->stream;
- if (s->end_pos > 0 && demuxer->ts_resets_possible &&
+ int64_t end = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &end);
+ if (end > 0 && demuxer->ts_resets_possible &&
!(priv->avif->flags & AVFMT_NO_BYTE_SEEK))
{
avsflags |= AVSEEK_FLAG_BYTE;
- priv->last_pts = s->end_pos * rel_seek_secs;
+ priv->last_pts = end * rel_seek_secs;
} else if (priv->avfc->duration != 0 &&
priv->avfc->duration != AV_NOPTS_VALUE)
{
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 20864aa297..4b08ce2a13 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -1058,7 +1058,9 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer)
(unsigned)seek->seek_id, pos);
get_header_element(demuxer, seek->seek_id, pos);
// This is nice to warn against incomplete files.
- if (pos >= s->end_pos)
+ int64_t end = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &end);
+ if (pos >= end)
MP_WARN(demuxer, "SeekHead position beyond "
"end of file - incomplete file?\n");
}
@@ -1723,7 +1725,9 @@ static int read_mkv_segment_header(demuxer_t *demuxer, int64_t *segment_end)
MP_VERBOSE(demuxer, " (skipping)\n");
if (*segment_end <= 0)
break;
- if (*segment_end >= s->end_pos)
+ int64_t end = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &end);
+ if (*segment_end >= end)
return 0;
if (!stream_seek(s, *segment_end)) {
MP_WARN(demuxer, "Failed to seek in file\n");
@@ -1794,7 +1798,9 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
}
MP_VERBOSE(demuxer, "Seeking to %"PRIu64" to read header element 0x%x.\n",
elem->pos, (unsigned)elem->id);
- if (elem->pos >= s->end_pos) {
+ int64_t end = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &end);
+ if (elem->pos >= end) {
MP_WARN(demuxer, "SeekHead position beyond "
"end of file - incomplete file?\n");
continue;
@@ -2748,7 +2754,10 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
return;
}
- target_filepos = (uint64_t) (s->end_pos * rel_seek_secs);
+ int64_t size = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &size);
+
+ target_filepos = (uint64_t) (size * rel_seek_secs);
for (i = 0; i < mkv_d->num_indexes; i++)
if (mkv_d->indexes[i].tnum == v_tnum)
if ((index == NULL)
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index 9d649c07a0..3c605e3f96 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -214,8 +214,8 @@ static void raw_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
{
struct priv *p = demuxer->priv;
stream_t *s = demuxer->stream;
- stream_update_size(s);
- int64_t end = s->end_pos;
+ int64_t end = 0;
+ stream_control(s, STREAM_CTRL_GET_SIZE, &end);
int64_t pos = (flags & SEEK_ABSOLUTE) ? 0 : stream_tell(s);
if (flags & SEEK_FACTOR)
pos += end * rel_seek_secs;
@@ -235,9 +235,8 @@ static int raw_control(demuxer_t *demuxer, int cmd, void *arg)
switch (cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH: {
stream_t *s = demuxer->stream;
- stream_update_size(s);
- int64_t end = s->end_pos;
- if (!end)
+ int64_t end = 0;
+ if (stream_control(s, STREAM_CTRL_GET_SIZE, &end) != STREAM_OK)
return DEMUXER_CTRL_DONTKNOW;
*((double *) arg) = (end / p->frame_size) / p->frame_rate;
diff --git a/player/command.c b/player/command.c
index 9c690d38ae..4619062bf5 100644
--- a/player/command.c
+++ b/player/command.c
@@ -206,12 +206,12 @@ static int mp_property_file_size(m_option_t *prop, int action, void *arg,
if (!mpctx->stream)
return M_PROPERTY_UNAVAILABLE;
- int64_t size = mpctx->stream->end_pos;
+ int64_t size;
+ if (stream_control(mpctx->stream, STREAM_CTRL_GET_SIZE, &size) != STREAM_OK)
+ return M_PROPERTY_UNAVAILABLE;
switch (action) {
case M_PROPERTY_GET: {
- if (size <= 0)
- break;
*(int64_t *)arg = size;
return M_PROPERTY_OK;
}
@@ -301,10 +301,7 @@ static int mp_property_stream_pos(m_option_t *prop, int action, void *arg,
static int mp_property_stream_end(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- struct stream *stream = mpctx->stream;
- if (!stream)
- return M_PROPERTY_UNAVAILABLE;
- return m_property_int64_ro(prop, action, arg, stream->end_pos);
+ return mp_property_file_size(prop, action, arg, mpctx);
}
// Does some magic to handle "<name>/full" as time formatted with milliseconds.
diff --git a/player/misc.c b/player/misc.c
index e3cf70f81e..6eae646242 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -169,14 +169,16 @@ void stream_dump(struct MPContext *mpctx)
stream_t *stream = mpctx->stream;
assert(stream && filename);
+ int64_t size = 0;
+ stream_control(stream, STREAM_CTRL_GET_SIZE, &size);
+
stream_set_capture_file(stream, filename);
while (mpctx->stop_play == KEEP_PLAYING && !stream->eof) {
if (!opts->quiet && ((stream->pos / (1024 * 1024)) % 2) == 1) {
uint64_t pos = stream->pos;
- uint64_t end = stream->end_pos;
MP_MSG(mpctx, MSGL_STATUS, "Dumping %lld/%lld...",
- (long long int)pos, (long long int)end);
+ (long long int)pos, (long long int)size);
}
stream_fill_buffer(stream);
for (;;) {
diff --git a/player/playloop.c b/player/playloop.c
index dea78c5571..964f112b6d 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -472,11 +472,12 @@ double get_current_pos_ratio(struct MPContext *mpctx, bool use_range)
ans = MPCLAMP((pos - start) / len, 0, 1);
} else {
struct stream *s = demuxer->stream;
- int64_t size = s->end_pos;
- int64_t fpos = demuxer->filepos >= 0 ?
- demuxer->filepos : stream_tell(demuxer->stream);
- if (size > 0)
+ int64_t size;
+ if (stream_control(s, STREAM_CTRL_GET_SIZE, &size) > 0 && size > 0) {
+ int64_t fpos =
+ demuxer->filepos >= 0 ? demuxer->filepos : stream_tell(s);
ans = MPCLAMP(fpos / (double)size, 0, 1);
+ }
}
if (use_range) {
if (mpctx->opts->play_frames > 0)
diff --git a/stream/cache.c b/stream/cache.c
index ad1277fb85..bd9712e341 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -364,6 +364,7 @@ static int resize_cache(struct priv *s, int64_t size)
static void update_cached_controls(struct priv *s)
{
unsigned int ui;
+ int64_t i64;
double d;
char **m;
char *t;
@@ -388,8 +389,9 @@ static void update_cached_controls(struct priv *s)
talloc_free(s->disc_name);
s->disc_name = talloc_steal(s, t);
}
- stream_update_size(s->stream);
- s->stream_size = s->stream->end_pos;
+ s->stream_size = -1;
+ if (stream_control(s->stream, STREAM_CTRL_GET_SIZE, &i64) == STREAM_OK)
+ s->stream_size = i64;
}
// the core might call these every frame, so cache them...
@@ -410,10 +412,13 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
*(double *)arg = s->stream_time_length;
return s->stream_time_length ? STREAM_OK : STREAM_UNSUPPORTED;
case STREAM_CTRL_GET_START_TIME:
+ if (s->stream_start_time == MP_NOPTS_VALUE)
+ return STREAM_UNSUPPORTED;
*(double *)arg = s->stream_start_time;
- return s->stream_start_time !=
- MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED;
+ return STREAM_OK;
case STREAM_CTRL_GET_SIZE:
+ if (s->stream_size < 0)
+ return STREAM_UNSUPPORTED;
*(int64_t *)arg = s->stream_size;
return STREAM_OK;
case STREAM_CTRL_MANAGES_TIMELINE:
@@ -692,8 +697,7 @@ int stream_cache_init(stream_t *cache, stream_t *stream,
if (min > s->buffer_size - FILL_LIMIT)
min = s->buffer_size - FILL_LIMIT;
- s->seekable = (stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK &&
- stream->end_pos > 0;
+ s->seekable = stream->seekable;
if (pthread_create(&s->cache_thread, NULL, cache_thread, s) != 0) {
MP_ERR(s, "Starting cache process/thread failed: %s.\n",
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) {
diff --git a/stream/stream.h b/stream/stream.h
index 2182de2526..5fc4c58579 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -57,12 +57,6 @@ enum streamtype {
// flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE)
#define STREAM_NO_FILTERS 2
-// 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)
-
#define STREAM_NO_MATCH -2
#define STREAM_UNSUPPORTED -1
#define STREAM_ERROR 0
@@ -143,11 +137,11 @@ typedef struct stream {
enum streamtype type; // see STREAMTYPE_*
enum streamtype uncached_type; // if stream is cache, type of wrapped str.
- int flags; // MP_STREAM_SEEK_* or'ed flags
int sector_size; // sector size (seek will be aligned on this size if non 0)
int read_chunk; // maximum amount of data to read at once to limit latency
unsigned int buf_pos, buf_len;
- int64_t pos, end_pos;
+ int64_t pos;
+ uint64_t end_pos; // static size; use STREAM_CTRL_GET_SIZE instead
int eof;
int mode; //STREAM_READ or STREAM_WRITE
bool streaming; // known to be a network stream if true
@@ -157,8 +151,10 @@ typedef struct stream {
char *mime_type; // when HTTP streaming is used
char *demuxer; // request demuxer to be used
char *lavf_type; // name of expected demuxer type for lavf
- bool safe_origin; // used for playlists that can be opened safely
- bool allow_caching; // stream cache makes sense
+ bool seekable : 1; // presence of general byte seeking support
+ bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
+ bool safe_origin : 1; // used for playlists that can be opened safely
+ bool allow_caching : 1; // stream cache makes sense
struct mp_log *log;
struct MPOpts *opts;
struct mpv_global *global;
@@ -219,7 +215,6 @@ struct mpv_global;
struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
int max_size);
int stream_control(stream_t *s, int cmd, void *arg);
-void stream_update_size(stream_t *s);
void free_stream(stream_t *s);
struct stream *stream_create(const char *url, int flags, struct mpv_global *global);
struct stream *stream_open(const char *filename, struct mpv_global *global);
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index cabfbecab8..0ca87403b4 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -801,7 +801,6 @@ static int bluray_stream_open(stream_t *s, int mode)
s->type = STREAMTYPE_BLURAY;
s->end_pos = bd_get_title_size(bd);
s->sector_size = BLURAY_SECTOR_SIZE;
- s->flags = MP_STREAM_SEEK;
s->priv = b;
MP_VERBOSE(s, "Blu-ray successfully opened.\n");
diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c
index 6f1c747483..856c9736d2 100644
--- a/stream/stream_cdda.c
+++ b/stream/stream_cdda.c
@@ -396,6 +396,7 @@ static int open_cdda(stream_t *st, int m)
st->fill_buffer = fill_buffer;
st->seek = seek;
+ st->seekable = true;
st->control = control;
st->close = close_cdda;
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
index 504aa065e1..fdaf38e640 100644
--- a/stream/stream_dvdnav.c
+++ b/stream/stream_dvdnav.c
@@ -719,7 +719,6 @@ static int open_s(stream_t *stream, int mode)
dvdnav_angle_change(priv->dvdnav, dvd_angle);
stream->sector_size = 2048;
- stream->flags = STREAM_READ;
stream->fill_buffer = fill_buffer;
stream->control = control;
stream->close = stream_dvdnav_close;
diff --git a/stream/stream_file.c b/stream/stream_file.c
index c714f5739d..528cf1a6e3 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -96,9 +96,10 @@ static int control(stream_t *s, int cmd, void *arg)
size = lseek(p->fd, 0, SEEK_END);
lseek(p->fd, s->pos, SEEK_SET);
if (size != (off_t)-1) {
- *(uint64_t *)arg = size;
+ *(int64_t *)arg = size;
return 1;
}
+ break;
}
}
return STREAM_UNSUPPORTED;
@@ -276,10 +277,10 @@ static int open_f(stream_t *stream, int mode)
len = -1;
#endif
stream->type = STREAMTYPE_FILE;
- stream->flags = MP_STREAM_FAST_SKIPPING;
+ stream->fast_skip = true;
if (len >= 0) {
stream->seek = seek;
- stream->end_pos = len;
+ stream->seekable = true;
}
MP_VERBOSE(stream, "File size is %" PRId64 " bytes\n", len);
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index c9e714fce4..509aaa3e70 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -89,8 +89,8 @@ static int control(stream_t *s, int cmd, void *arg)
switch(cmd) {
case STREAM_CTRL_GET_SIZE:
size = avio_size(avio);
- if(size >= 0) {
- *(uint64_t *)arg = size;
+ if (size >= 0) {
+ *(int64_t *)arg = size;
return 1;
}
break;
@@ -136,6 +136,9 @@ static int open_f(stream_t *stream, int mode)
AVDictionary *dict = NULL;
void *temp = talloc_new(NULL);
+ stream->seek = NULL;
+ stream->seekable = false;
+
if (mode == STREAM_READ)
flags = AVIO_FLAG_READ;
else if (mode == STREAM_WRITE)
@@ -161,7 +164,6 @@ static int open_f(stream_t *stream, int mode)
* this (the rtsp demuxer's probe function checks for a "rtsp:"
* filename prefix), so it has to be handled specially here.
*/
- stream->seek = NULL;
stream->demuxer = "lavf";
stream->lavf_type = "rtsp";
talloc_free(temp);
@@ -238,12 +240,8 @@ static int open_f(stream_t *stream, int mode)
stream->lavf_type = "flv";
}
stream->priv = avio;
- int64_t size = avio_size(avio);
- if (size >= 0)
- stream->end_pos = size;
- stream->seek = seek;
- if (!avio->seekable)
- stream->seek = NULL;
+ stream->seekable = avio->seekable;
+ stream->seek = stream->seekable ? seek : NULL;
stream->fill_buffer = fill_buffer;
stream->write_buffer = write_buffer;
stream->control = control;
diff --git a/stream/stream_memory.c b/stream/stream_memory.c
index ff2b42e020..df01d2956e 100644
--- a/stream/stream_memory.c
+++ b/stream/stream_memory.c
@@ -43,11 +43,13 @@ static int control(stream_t *s, int cmd, void *arg)
{
struct priv *p = s->priv;
switch(cmd) {
+ case STREAM_CTRL_GET_SIZE:
+ *(int64_t *)arg = p->data.len;
+ return 1;
case STREAM_CTRL_SET_CONTENTS: ;
bstr *data = (bstr *)arg;
talloc_free(p->data.start);
p->data = bstrdup(s, *data);
- s->end_pos = p->data.len;
return 1;
}
return STREAM_UNSUPPORTED;
@@ -57,6 +59,7 @@ static int open_f(stream_t *stream, int mode)
{
stream->fill_buffer = fill_buffer;
stream->seek = seek;
+ stream->seekable = true;
stream->control = control;
stream->read_chunk = 1024 * 1024;
diff --git a/stream/stream_rar.c b/stream/stream_rar.c
index cae5e02020..24687523e2 100644
--- a/stream/stream_rar.c
+++ b/stream/stream_rar.c
@@ -133,6 +133,7 @@ static int rar_entry_open(stream_t *stream, int mode)
stream->end_pos = file->size;
stream->fill_buffer = rar_entry_fill_buffer;
stream->seek = rar_entry_seek;
+ stream->seekable = true;
stream->close = rar_entry_close;
stream->control = rar_entry_control;
@@ -190,6 +191,7 @@ static int rar_filter_open(stream_t *stream, int mode)
stream->end_pos = m->end_pos;
stream->fill_buffer = rar_filter_fill_buffer;
stream->seek = rar_filter_seek;
+ stream->seekable = true;
stream->close = rar_filter_close;
stream->safe_origin = true;
diff --git a/stream/stream_smb.c b/stream/stream_smb.c
index ab32ea0d3a..6b79d072dd 100644
--- a/stream/stream_smb.c
+++ b/stream/stream_smb.c
@@ -45,10 +45,11 @@ static int control(stream_t *s, int cmd, void *arg) {
off_t size = smbc_lseek(p->fd,0,SEEK_END);
smbc_lseek(p->fd,s->pos,SEEK_SET);
if(size != (off_t)-1) {
- *(uint64_t *)arg = size;
+ *(int64_t *)arg = size;
return 1;
}
}
+ break;
}
return STREAM_UNSUPPORTED;
}
@@ -131,9 +132,8 @@ static int open_f (stream_t *stream, int mode)
smbc_lseek (fd, 0, SEEK_SET);
}
if(len > 0 || mode == STREAM_WRITE) {
- stream->flags |= MP_STREAM_SEEK;
+ stream->seekable = true;
stream->seek = seek;
- if(mode == STREAM_READ) stream->end_pos = len;
}
priv->fd = fd;
stream->fill_buffer = fill_buffer;
diff --git a/stream/stream_vcd.c b/stream/stream_vcd.c
index a61fc04376..23b95cf3c6 100644
--- a/stream/stream_vcd.c
+++ b/stream/stream_vcd.c
@@ -169,6 +169,7 @@ static int open_s(stream_t *stream,int mode)
stream->fill_buffer = fill_buffer;
stream->seek = seek;
+ stream->seekable = true;
stream->close = close_s;
stream->demuxer = "lavf"; // mpegps ( or "vcd"?)