diff options
Diffstat (limited to 'stream/cache.c')
-rw-r--r-- | stream/cache.c | 58 |
1 files changed, 16 insertions, 42 deletions
diff --git a/stream/cache.c b/stream/cache.c index 91662cec47..197f7d3391 100644 --- a/stream/cache.c +++ b/stream/cache.c @@ -76,7 +76,6 @@ struct priv { int64_t buffer_size; // size of the allocated buffer memory int64_t back_size; // keep back_size amount of old bytes for backward seek int64_t seek_limit; // keep filling cache if distance is less that seek limit - struct byte_meta *bm; // additional per-byte metadata bool seekable; // underlying stream is seekable struct mp_log *log; @@ -116,17 +115,10 @@ struct priv { int stream_cache_fill; struct mp_tags *stream_metadata; char *disc_name; -}; - -// Store additional per-byte metadata. Since per-byte would be way too -// inefficient, store it only for every BYTE_META_CHUNK_SIZE byte. -struct byte_meta { - float stream_pts; + double start_pts; }; enum { - BYTE_META_CHUNK_SIZE = 8 * 1024, - CACHE_INTERRUPTED = -1, CACHE_CTRL_NONE = 0, @@ -134,7 +126,7 @@ enum { CACHE_CTRL_PING = -2, // we should fill buffer only if space>=FILL_LIMIT - FILL_LIMIT = FFMAX(16 * 1024, BYTE_META_CHUNK_SIZE * 2), + FILL_LIMIT = 16 * 1024, }; static int64_t mp_clipi64(int64_t val, int64_t min, int64_t max) @@ -179,6 +171,7 @@ static void cache_drop_contents(struct priv *s) { s->offset = s->min_filepos = s->max_filepos = s->read_filepos; s->eof = false; + s->start_pts = MP_NOPTS_VALUE; } // Copy at most dst_size from the cache at the given absolute file position pos. @@ -278,13 +271,12 @@ static bool cache_fill(struct priv *s) len = stream_read_partial(s->stream, &s->buffer[pos], space); pthread_mutex_lock(&s->mutex); - 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}; + // Do this after reading a block, because at least libdvdnav updates the + // stream position only after actually reading something after a seek. + if (s->start_pts == MP_NOPTS_VALUE) { + double pts; + if (stream_control(s->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) > 0) + s->start_pts = pts; } s->max_filepos += len; @@ -311,11 +303,8 @@ static int resize_cache(struct priv *s, int64_t size) int64_t buffer_size = MPMIN(MPMAX(size, min_size), max_size); unsigned char *buffer = malloc(buffer_size); - struct byte_meta *bm = calloc(buffer_size / BYTE_META_CHUNK_SIZE + 2, - sizeof(struct byte_meta)); - if (!buffer || !bm) { + if (!buffer) { free(buffer); - free(bm); return STREAM_ERROR; } @@ -346,12 +335,10 @@ static int resize_cache(struct priv *s, int64_t size) } free(s->buffer); - free(s->bm); s->buffer_size = buffer_size; s->back_size = buffer_size / 2; s->buffer = buffer; - s->bm = bm; s->idle = false; s->eof = false; @@ -360,9 +347,6 @@ static int resize_cache(struct priv *s, int64_t size) if (s->seek_limit > s->buffer_size - FILL_LIMIT) s->seek_limit = s->buffer_size - FILL_LIMIT; - for (size_t n = 0; n < s->buffer_size / BYTE_META_CHUNK_SIZE + 2; n++) - s->bm[n] = (struct byte_meta){.stream_pts = MP_NOPTS_VALUE}; - return STREAM_OK; } @@ -419,21 +403,10 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg) *(unsigned int *)arg = s->stream_num_chapters; return STREAM_OK; case STREAM_CTRL_GET_CURRENT_TIME: { - if (s->read_filepos >= s->min_filepos && - s->read_filepos <= s->max_filepos && - s->min_filepos < s->max_filepos) - { - 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 pts = s->bm[pos / BYTE_META_CHUNK_SIZE].stream_pts; - *(double *)arg = pts; - return pts == MP_NOPTS_VALUE ? STREAM_UNSUPPORTED : STREAM_OK; - } - return STREAM_UNSUPPORTED; + if (s->start_pts == MP_NOPTS_VALUE) + return STREAM_UNSUPPORTED; + *(double *)arg = s->start_pts; + return STREAM_OK; } case STREAM_CTRL_GET_METADATA: { if (s->stream_metadata) { @@ -642,7 +615,6 @@ static void cache_uninit(stream_t *cache) pthread_mutex_destroy(&s->mutex); pthread_cond_destroy(&s->wakeup); free(s->buffer); - free(s->bm); talloc_free(s); } @@ -657,6 +629,8 @@ int stream_cache_init(stream_t *cache, stream_t *stream, struct priv *s = talloc_zero(NULL, struct priv); s->log = cache->log; + cache_drop_contents(s); + s->seek_limit = opts->seek_min * 1024ULL; if (resize_cache(s, opts->size * 1024ULL) != STREAM_OK) { |