player: force update of cache properties even on inactive demuxer cache

When the demuxer cache read until the end of the stream, and was
finished and completely inactive, the cache properties were not updated
anymore via MP_EVENT_CACHE_UPDATE.

Unfortunately, many cache properties depend on the current playback
position, such as cache-duration or fw-bytes. This is especially visible
on the OSC. If everything was cached, seeking around didn't update the
displayed forward cache duration.

That means checking demuxer_reader_state.idle is not enough. You also
need to check whether the current playback position changed.

Fix this by explicitly using the current playback position, and update
the properties if it changed "enough". "Enough" is 1 second of media
time in this example, which may or may not be appropriate.

In general, this could probably be done better. There are many other
triggers that change the cache state and that are not covered. For now
I'm content with getting rid of the obvious problems.

I think the OSC problem in particular was caused by changing it from
polling to using property change notifications.
This commit is contained in:
wm4 2020-03-05 22:23:43 +01:00
parent 777615f1a3
commit c032db6185
2 changed files with 7 additions and 1 deletions

View File

@ -428,6 +428,7 @@ typedef struct MPContext {
bool demux_underrun;
double cache_stop_time;
int cache_buffer;
double cache_update_pts;
// Set after showing warning about decoding being too slow for realtime
// playback rate. Used to avoid showing it multiple times.

View File

@ -244,6 +244,7 @@ void reset_playback_state(struct MPContext *mpctx)
mpctx->restart_complete = false;
mpctx->paused_for_cache = false;
mpctx->cache_buffer = 100;
mpctx->cache_update_pts = MP_NOPTS_VALUE;
encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
@ -751,6 +752,8 @@ static void handle_update_cache(struct MPContext *mpctx)
// Also update cache properties.
bool busy = !s.idle;
if (fabs(mpctx->cache_update_pts - mpctx->playback_pts) >= 1.0)
busy = true;
if (busy || mpctx->next_cache_update > 0) {
if (mpctx->next_cache_update <= now) {
mpctx->next_cache_update = busy ? now + 0.25 : 0;
@ -781,8 +784,10 @@ static void handle_update_cache(struct MPContext *mpctx)
if (s.eof && !busy)
prefetch_next(mpctx);
if (force_update)
if (force_update) {
mpctx->cache_update_pts = mpctx->playback_pts;
mp_notify(mpctx, MP_EVENT_CACHE_UPDATE, NULL);
}
}
int get_cache_buffering_percentage(struct MPContext *mpctx)