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.)
This commit is contained in:
wm4 2013-06-17 23:39:24 +02:00
parent e8ae0b9852
commit bcdb3c228e
1 changed files with 20 additions and 20 deletions

View File

@ -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");