command: sub_seek: avoid getting stuck

First, don't try to seek if the result is 0 (i.e. nothing found, or
subtitle event happens to be exactly on spot).

Second, since we never can make sure that we actually seek to the exact
subtitle PTS (seeking "snaps" to video PTS), offset the seek by 10ms.
Since most subtitle events are longer than 10ms, this should work fine.
This commit is contained in:
wm4 2013-10-07 17:16:03 +02:00
parent ccdaecfc5c
commit de6eace6e9
2 changed files with 10 additions and 2 deletions

View File

@ -2502,6 +2502,11 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
set_osd_tmsg(mpctx, OSD_MSG_SUB_DELAY, osdl, osd_duration,
"Sub delay: %d ms", ROUND(opts->sub_delay * 1000));
} else {
// We can easily get stuck by failing to seek to the video
// frame which actually shows the sub first (because video
// frame PTS and sub PTS rarely match exactly). Add some
// rounding for the mess of it.
a[0] += 0.01 * (a[1] > 0 ? 1 : -1);
queue_seek(mpctx, MPSEEK_RELATIVE, a[0], 1);
set_osd_function(mpctx, (a[0] > 0) ? OSD_FFW : OSD_REW);
if (bar_osd)

View File

@ -289,8 +289,11 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
switch (cmd) {
case SD_CTRL_SUB_STEP: {
double *a = arg;
a[0] = ass_step_sub(ctx->ass_track, a[0] * 1000 + .5, a[1]) / 1000.0;
return CONTROL_OK;
long long res = ass_step_sub(ctx->ass_track, a[0] * 1000 + 0.5, a[1]);
if (!res)
return false;
a[0] = res / 1000.0;
return true;
case SD_CTRL_SET_VIDEO_PARAMS:
ctx->video_params = *(struct mp_image_params *)arg;
return CONTROL_OK;