summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-17 23:39:24 +0200
committerwm4 <wm4@nowhere>2013-06-18 02:19:15 +0200
commitbcdb3c228e76ccc7419129378882fbd7fab7f653 (patch)
tree09bedd34654796ce00219b5e79fa19557f4923f7 /stream
parente8ae0b985218b8c35172567391bad528b3a07009 (diff)
downloadmpv-bcdb3c228e76ccc7419129378882fbd7fab7f653.tar.bz2
mpv-bcdb3c228e76ccc7419129378882fbd7fab7f653.tar.xz
cache: fix stream_pts caching
Or rather, keep hacking it until it somehow works. The problem here was that trying to avoid calling STREAM_CTRL_GET_CURRENT_TIME too often didn't really work, so the cache sometimes returned incorrect times. Also try to avoid the situation that looking up the time with an advanced read position doesn't really work, as well as when trying to look it up when EOF or cache end has been reached. In that case we have read_filepos == max_filepos, which is "outside" of the cache, but querying the time is still valid. Should also fix the issue that demuxing streams with demux_lavf and if STREAM_CTRL_GET_CURRENT_TIME is not supported messed up the reported playback position. This stuff is still not sane, but the way the player tries to fix the playback time and how the DVD/BD stream inputs return the current time based on the current byte position isn't sane to begin with. So, let's leave it at bad hacks. The two changes that touch s->eof are unrelated and basically of cosmetic nature (separate commit would be too noisy.)
Diffstat (limited to 'stream')
-rw-r--r--stream/cache.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/stream/cache.c b/stream/cache.c
index 8f9dbcf206..d93d539494 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -110,7 +110,7 @@ struct byte_meta {
};
enum {
- BYTE_META_CHUNK_SIZE = 16 * 1024,
+ BYTE_META_CHUNK_SIZE = 8 * 1024,
CACHE_INTERRUPTED = -1,
@@ -181,7 +181,7 @@ static int cache_wakeup_and_wait(struct priv *s, double *retry_time)
static void cache_drop_contents(struct priv *s)
{
s->offset = s->min_filepos = s->max_filepos = s->read_filepos;
- s->eof = 0;
+ s->eof = false;
}
// Runs in the main thread
@@ -280,15 +280,13 @@ static bool cache_fill(struct priv *s)
len = stream_read_partial(s->stream, &s->buffer[pos], space);
pthread_mutex_lock(&s->mutex);
- int m1 = pos / BYTE_META_CHUNK_SIZE;
- int m2 = (s->buffer_size + pos - 1) % s->buffer_size / BYTE_META_CHUNK_SIZE;
- if (m1 != m2) {
- double pts;
- if (stream_control(s->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) <= 0)
- pts = MP_NOPTS_VALUE;
- s->bm[m1] = (struct byte_meta) {
- .stream_pts = pts,
- };
+ double pts;
+ if (stream_control(s->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) <= 0)
+ pts = MP_NOPTS_VALUE;
+ for (int64_t b_pos = pos; b_pos < pos + len + BYTE_META_CHUNK_SIZE;
+ b_pos += BYTE_META_CHUNK_SIZE)
+ {
+ s->bm[b_pos / BYTE_META_CHUNK_SIZE] = (struct byte_meta){.stream_pts = pts};
}
s->max_filepos += len;
@@ -347,17 +345,20 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
return s->stream_manages_timeline ? STREAM_OK : STREAM_UNSUPPORTED;
case STREAM_CTRL_GET_CURRENT_TIME: {
if (s->read_filepos >= s->min_filepos &&
- s->read_filepos <= s->max_filepos)
+ s->read_filepos <= s->max_filepos &&
+ s->min_filepos < s->max_filepos)
{
- int64_t pos = s->read_filepos - s->offset;
+ int64_t fpos = FFMIN(s->read_filepos, s->max_filepos - 1);
+ int64_t pos = fpos - s->offset;
if (pos < 0)
pos += s->buffer_size;
else if (pos >= s->buffer_size)
pos -= s->buffer_size;
- *(double *)arg = s->bm[pos / BYTE_META_CHUNK_SIZE].stream_pts;
- return STREAM_OK;
+ double pts = s->bm[pos / BYTE_META_CHUNK_SIZE].stream_pts;
+ *(double *)arg = pts;
+ return pts == MP_NOPTS_VALUE ? STREAM_UNSUPPORTED : STREAM_OK;
}
- break;
+ return STREAM_UNSUPPORTED;
}
}
return STREAM_ERROR;
@@ -390,7 +391,6 @@ static void cache_execute_control(struct priv *s)
} else if (pos_changed || (ok && control_needs_flush(s->control))) {
mp_msg(MSGT_CACHE, MSGL_V, "Dropping cache due to control()\n");
s->read_filepos = stream_tell(s->stream);
- s->eof = false;
s->control_flush = true;
cache_drop_contents(s);
}
@@ -537,12 +537,12 @@ int stream_cache_init(stream_t *cache, stream_t *stream, int64_t size,
struct priv *s = talloc_zero(NULL, struct priv);
//64kb min_size
- s->buffer_size = FFMAX(size, 64 * 1024);
- s->fill_limit = 16 * 1024;
+ s->fill_limit = FFMAX(16 * 1024, BYTE_META_CHUNK_SIZE * 2);
+ s->buffer_size = FFMAX(size, s->fill_limit * 4);
s->back_size = s->buffer_size / 2;
s->buffer = malloc(s->buffer_size);
- s->bm = malloc((s->buffer_size / BYTE_META_CHUNK_SIZE + 1) *
+ s->bm = malloc((s->buffer_size / BYTE_META_CHUNK_SIZE + 2) *
sizeof(struct byte_meta));
if (!s->buffer || !s->bm) {
mp_msg(MSGT_CACHE, MSGL_ERR, "Failed to allocate cache buffer.\n");