stream_dvdnav: add support for still frames
DVDNAV_STILL_FRAME means the VM is holding a frame indefinitely (menu pages, some logos) or for a timed duration. Report the indefinite case via nav state so the player holds playback at EOF instead of ending the file, and skip timed stills, which would otherwise stall playback.
This commit is contained in:
1 parent
fbcced5bf0
commit
3897b3a579
5 files changed
+83
-11
No files matched your search
@@ -447,6 +447,8 @@ typedef struct MPContext {
|
||||
struct screenshot_ctx *screenshot_ctx;
|
||||
struct command_ctx *command_ctx;
|
||||
struct disc_nav_state *disc_nav;
|
||||
// Demuxer parked on an indefinite still frame (DVD/BD menu).
|
||||
bool disc_nav_still_frame;
|
||||
struct encode_lavc_context *encode_lavc_ctx;
|
||||
|
||||
struct mp_option_callback *option_callbacks;
|
||||
|
||||
@@ -46,6 +46,10 @@ struct disc_nav_state {
|
||||
uint32_t bd_last_change_id;
|
||||
struct mp_osd_res bd_last_vo_res;
|
||||
|
||||
// Last menu-overlay change_id we forced an OSD redraw for.
|
||||
uint32_t last_overlay_change_id;
|
||||
bool overlay_change_seen;
|
||||
|
||||
// Last observed disc-nav discontinuity counter (bumped by the stream
|
||||
// backend on user nav actions and on libbluray/libdvdnav-internal
|
||||
// playlist/title/cell transitions).
|
||||
@@ -441,6 +445,11 @@ void disc_nav_update(struct MPContext *mpctx)
|
||||
struct disc_nav_state *st = get_state(mpctx);
|
||||
struct stream_nav_state nav = {0};
|
||||
bool have = s && stream_control(s, STREAM_CTRL_GET_NAV_STATE, &nav) >= 1;
|
||||
bool still = have && nav.still_active;
|
||||
if (s && still != mpctx->disc_nav_still_frame)
|
||||
MP_VERBOSE(s, "still_frame %d->%d\n",
|
||||
mpctx->disc_nav_still_frame, still);
|
||||
mpctx->disc_nav_still_frame = still;
|
||||
if (!have) {
|
||||
if (st->overlay_visible) {
|
||||
osd_set_bitmaps(mpctx->osd, OSDTYPE_DISC_MENU, NULL);
|
||||
@@ -450,6 +459,7 @@ void disc_nav_update(struct MPContext *mpctx)
|
||||
st->bd_last_change_id = 0;
|
||||
st->bd_last_vo_res = (struct mp_osd_res){0};
|
||||
st->menu_selected_track = NULL;
|
||||
st->overlay_change_seen = false;
|
||||
if (st->menu_active_seen && st->last_menu_active) {
|
||||
st->last_menu_active = false;
|
||||
mp_notify_property(mpctx, "disc-menu-active");
|
||||
@@ -477,6 +487,12 @@ void disc_nav_update(struct MPContext *mpctx)
|
||||
ensure_menu_sub_selection(mpctx, nav.menu_active);
|
||||
}
|
||||
|
||||
if (!st->overlay_change_seen || nav.change_id != st->last_overlay_change_id) {
|
||||
st->overlay_change_seen = true;
|
||||
st->last_overlay_change_id = nav.change_id;
|
||||
osd_changed(mpctx->osd);
|
||||
}
|
||||
|
||||
if (visible != st->overlay_visible) {
|
||||
MP_VERBOSE(s, "overlay %s\n", visible ? "on" : "off");
|
||||
if (visible) {
|
||||
|
||||
@@ -1238,6 +1238,10 @@ static void handle_eof(struct MPContext *mpctx)
|
||||
bool prevent_eof =
|
||||
mpctx->paused && mpctx->video_out && vo_has_frame(mpctx->video_out) &&
|
||||
!mpctx->vo_chain->is_coverart;
|
||||
/* A disc menu parked on an infinite still frame reports EOF so the decoder
|
||||
* drains and the menu frame is shown. Hold it until the user navigates,
|
||||
* rather than ending the file. */
|
||||
prevent_eof |= mpctx->disc_nav_still_frame;
|
||||
/* It's possible for the user to simultaneously switch both audio
|
||||
* and video streams to "disabled" at runtime. Handle this by waiting
|
||||
* rather than immediately stopping playback due to EOF.
|
||||
|
||||
Reference in new issue
Block a user