diff --git a/player/command.c b/player/command.c index 52718d60ae..c95e7d1315 100644 --- a/player/command.c +++ b/player/command.c @@ -4588,7 +4588,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re // 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); + a[0] += 0.01 * (a[1] >= 0 ? 1 : -1); mark_seek(mpctx); queue_seek(mpctx, MPSEEK_RELATIVE, a[0], MPSEEK_EXACT, false); set_osd_function(mpctx, (a[0] > 0) ? OSD_FFW : OSD_REW); diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 2da69e937e..4fbabaf864 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -398,15 +398,15 @@ static double step_sub(struct sd *sd, double now, int movement) struct sd_lavc_priv *priv = sd->priv; int best = -1; double target = now; - int direction = movement > 0 ? 1 : -1; + int direction = (movement > 0 ? 1 : -1) * !!movement; - if (movement == 0 || priv->num_seekpoints == 0) + if (priv->num_seekpoints == 0) return MP_NOPTS_VALUE; qsort(priv->seekpoints, priv->num_seekpoints, sizeof(priv->seekpoints[0]), compare_seekpoint); - while (movement) { + do { int closest = -1; double closest_time = 0; for (int i = 0; i < priv->num_seekpoints; i++) { @@ -420,13 +420,20 @@ static double step_sub(struct sd *sd, double now, int movement) closest_time = end; } } - } else { + } else if (direction > 0) { if (start > target) { if (closest < 0 || start < closest_time) { closest = i; closest_time = start; } } + } else { + if (start < target) { + if (closest < 0 || start >= closest_time) { + closest = i; + closest_time = start; + } + } } } if (closest < 0) @@ -434,7 +441,7 @@ static double step_sub(struct sd *sd, double now, int movement) target = closest_time + direction; best = closest; movement -= direction; - } + } while (movement); return best < 0 ? 0 : priv->seekpoints[best].pts - now; }