options: add secondary-sub-delay

Add --secondary-sub-delay option and decouple --sub-delay from secondary
subtitles. This produces desirable behavior in most cases as secondary
and primary subtitles tracks tend to be timed independently of one
another.

This feature is implemented by turning the sub_delay field in
mp_subtitle_opts into an array of 2 floats. From here the track index is
either passed around or derived when sub_delay is needed. There are some
cases in dec_sub.c where it is possible for dec_sub.order (equivalent to
track index) to be -1. In these cases, sub_delay is inferred as 0.
This commit is contained in:
Ripose
2023-11-22 20:13:57 -07:00
committed by sfan5
parent a3f505d4cb
commit dea512ea38
7 changed files with 33 additions and 12 deletions

View File

@@ -92,9 +92,10 @@ static void update_subtitle_speed(struct dec_sub *sub)
static double pts_to_subtitle(struct dec_sub *sub, double pts)
{
struct mp_subtitle_opts *opts = sub->opts;
float delay = sub->order < 0 ? 0.0f : opts->sub_delay[sub->order];
if (pts != MP_NOPTS_VALUE)
pts = (pts * sub->play_dir - opts->sub_delay) / sub->sub_speed;
pts = (pts * sub->play_dir - delay) / sub->sub_speed;
return pts;
}
@@ -102,9 +103,10 @@ static double pts_to_subtitle(struct dec_sub *sub, double pts)
static double pts_from_subtitle(struct dec_sub *sub, double pts)
{
struct mp_subtitle_opts *opts = sub->opts;
float delay = sub->order < 0 ? 0.0f : opts->sub_delay[sub->order];
if (pts != MP_NOPTS_VALUE)
pts = (pts * sub->sub_speed + opts->sub_delay) * sub->play_dir;
pts = (pts * sub->sub_speed + delay) * sub->play_dir;
return pts;
}
@@ -291,7 +293,8 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts, bool force)
break;
// (Use this mechanism only if sub_delay matters to avoid corner cases.)
double min_pts = sub->opts->sub_delay < 0 || force ? video_pts : MP_NOPTS_VALUE;
float delay = sub->order < 0 ? 0.0f : sub->opts->sub_delay[sub->order];
double min_pts = delay < 0 || force ? video_pts : MP_NOPTS_VALUE;
struct demux_packet *pkt;
int st = demux_read_packet_async_until(sub->sh, min_pts, &pkt);