sd_lavc: keep subs on subtitle track switching

Keep the currently displayed subtitles even when the user cycles through
subtitle tracks, and the subtitle is decoded by libavcodec (such as
vobsubs). Do this by not clearing the subtitles on reset(). reset() is
also called on seek, so check the start PTS whether the subtitle should
really be displayed (there's already an end PTS). Note that sd_ass does
essentially something similar.

The existing code has checks for whether the PTS reported by the demuxer
is invalid (MP_NOPTS_VALUE). I don't know under what circumstances this
can happens, so fall back to the old behavior if the PTS is invalid.
This commit is contained in:
wm4 2012-12-12 22:56:41 +01:00
parent 0fba387f72
commit 962a97a2db
2 changed files with 8 additions and 2 deletions

View File

@ -1839,7 +1839,7 @@ static void update_subtitles(struct MPContext *mpctx, double refpts_tl)
while (d_sub->first) {
double subpts_s = ds_get_next_pts(d_sub);
if (subpts_s > curpts_s) {
mp_dbg(MSGT_CPLAYER, MSGL_V,
mp_dbg(MSGT_CPLAYER, MSGL_DBG2,
"Sub early: c_pts=%5.3f s_pts=%5.3f\n",
curpts_s, subpts_s);
// Libass handled subs can be fed to it in advance

View File

@ -36,6 +36,7 @@ struct sd_lavc_priv {
struct sub_bitmap *outbitmaps;
struct osd_bmp_indexed *imgs;
bool bitmaps_changed;
double pts;
double endpts;
};
@ -107,6 +108,7 @@ static void clear(struct sd_lavc_priv *priv)
talloc_free(priv->imgs);
priv->imgs = NULL;
priv->bitmaps_changed = true;
priv->pts = MP_NOPTS_VALUE;
priv->endpts = MP_NOPTS_VALUE;
if (priv->have_sub)
avsubtitle_free(&priv->sub);
@ -165,6 +167,7 @@ static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
b->y = r->y;
}
priv->count = sub.num_rects;
priv->pts = pts;
priv->endpts = endpts;
break;
default:
@ -181,6 +184,8 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
{
struct sd_lavc_priv *priv = sh->context;
if (priv->pts != MP_NOPTS_VALUE && pts < priv->pts)
return;
if (priv->endpts != MP_NOPTS_VALUE && (pts >= priv->endpts ||
pts < priv->endpts - 300))
clear(priv);
@ -213,7 +218,8 @@ static void reset(struct sh_sub *sh, struct osd_state *osd)
{
struct sd_lavc_priv *priv = sh->context;
clear(priv);
if (priv->pts == MP_NOPTS_VALUE)
clear(priv);
// lavc might not do this right for all codecs; may need close+reopen
avcodec_flush_buffers(priv->avctx);
}