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 "/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"?)