stream_dvdnav: emit a one-shot EOF at source jump boundaries
Menu activations, HOP_CHANNEL and VTS changes jump the source position. On this strictly forward stream the demuxer cannot tell where the old content ends, so buffered pre-jump data would mix with post-jump data. Return a single EOF at the boundary so the demuxer drains and resets before any new content flows.
This commit is contained in:
1 parent
dbe496e6be
commit
582810ac1d
1 file changed
+17
-6
+17
-6
@@ -79,6 +79,7 @@ struct priv {
|
||||
uint32_t hl_palette[4]; // 0xAARRGGBB for SPU pixel values 0..3
|
||||
uint32_t nav_change_id;
|
||||
uint32_t discontinuity_id; // bumped on actions that may jump
|
||||
bool pending_drain; // emit one EOF at the next jump boundary
|
||||
int src_w, src_h; // video resolution in pixels
|
||||
int auto_actioned_button; // last auto-activated button; 0 if none
|
||||
|
||||
@@ -468,6 +469,13 @@ static void do_nav_cmd(stream_t *stream, struct stream_nav_cmd *cmd)
|
||||
update_highlight(priv);
|
||||
}
|
||||
|
||||
// Mark a source-position jump.
|
||||
static void bump_discontinuity(struct priv *priv)
|
||||
{
|
||||
priv->discontinuity_id++;
|
||||
priv->pending_drain = true;
|
||||
}
|
||||
|
||||
static void handle_nav_cmd(stream_t *stream, struct stream_nav_cmd *cmd)
|
||||
{
|
||||
struct priv *priv = stream->priv;
|
||||
@@ -477,7 +485,7 @@ static void handle_nav_cmd(stream_t *stream, struct stream_nav_cmd *cmd)
|
||||
bool activated = stream_nav_action_activates(cmd->action) ||
|
||||
priv->auto_actioned_button != prev_auto;
|
||||
if (priv->still_active && activated)
|
||||
priv->discontinuity_id++;
|
||||
bump_discontinuity(priv);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,6 +567,10 @@ static int fill_buffer(stream_t *s, void *buf, int max_len)
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (priv->pending_drain) {
|
||||
priv->pending_drain = false;
|
||||
return 0;
|
||||
}
|
||||
int len = -1;
|
||||
int event = DVDNAV_NOP;
|
||||
if (dvdnav_get_next_block(dvdnav, buf, &event, &len) != DVDNAV_STATUS_OK)
|
||||
@@ -613,7 +625,7 @@ static int fill_buffer(stream_t *s, void *buf, int max_len)
|
||||
break;
|
||||
case DVDNAV_HOP_CHANNEL:
|
||||
// Bump discontinuity_id so the playloop flushes the cache.
|
||||
priv->discontinuity_id++;
|
||||
bump_discontinuity(priv);
|
||||
break;
|
||||
case DVDNAV_HIGHLIGHT:
|
||||
update_highlight(priv);
|
||||
@@ -638,8 +650,7 @@ static int fill_buffer(stream_t *s, void *buf, int max_len)
|
||||
MP_WARN(s, "Requested title not found\n");
|
||||
}
|
||||
// VTS change is a title-set boundary, flush.
|
||||
refresh_video_resolution(priv);
|
||||
priv->discontinuity_id++;
|
||||
bump_discontinuity(priv);
|
||||
break;
|
||||
}
|
||||
case DVDNAV_CELL_CHANGE: {
|
||||
@@ -780,13 +791,13 @@ static int control(stream_t *stream, int cmd, void *arg)
|
||||
if (dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root)
|
||||
!= DVDNAV_STATUS_OK)
|
||||
break;
|
||||
priv->discontinuity_id++;
|
||||
bump_discontinuity(priv);
|
||||
stream_drop_buffers(stream);
|
||||
return STREAM_OK;
|
||||
}
|
||||
if (dvdnav_title_play(priv->dvdnav, title + 1) != DVDNAV_STATUS_OK)
|
||||
break;
|
||||
priv->discontinuity_id++;
|
||||
bump_discontinuity(priv);
|
||||
stream_drop_buffers(stream);
|
||||
return STREAM_OK;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user