sub: make --sub-fix-timing configurable

Instead of hardcoding the threshold and keep duration in a header,
expose them as options for users to configure and set old hardcoded
values as the new defaults for those options.
This commit is contained in:
llyyr authored and Kacper Michajłow committed 2025-10-05 21:35:20 +02:00
1 parent df4bd5d1c8
commit be5e606377
7 files changed
+24 -9

No files matched your search

@@ -0,0 +1,2 @@
add `--sub-fix-timing-threshold`
add `--sub-fix-timing-keep`
+13 -2
View File
@@ -2885,8 +2885,19 @@ Subtitles
``--sub-fix-timing=<yes|no>``
Adjust subtitle timing is to remove minor gaps or overlaps between
subtitles (if the difference is smaller than 210 ms, the gap or overlap
is removed).
subtitles.
See also: ``--sub-fix-timing-threshold`` and ``--sub-fix-timing-keep``.
``--sub-fix-timing-threshold=<amount>``
Set the threshold in milliseconds for fixing subtitle timing (default: 210).
If the gap between two subtitle events is smaller than this, the gap is
removed.
``--sub-fix-timing-keep=<amount>``
Set the minimum duration in milliseconds for subtitle events to be
considered for timing fixes (default: 400). If a subtitle event has a
duration smaller than this, its timing is not changed.
``--sub-forced-events-only=<yes|no>``
Enabling this displays only forced events within subtitle streams. Only
+4
View File
@@ -304,6 +304,8 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"stretch-image-subs-to-screen", OPT_BOOL(stretch_image_subs)},
{"image-subs-video-resolution", OPT_BOOL(image_subs_video_res)},
{"sub-fix-timing", OPT_BOOL(sub_fix_timing)},
{"sub-fix-timing-threshold", OPT_INT(sub_fix_timing_threshold)},
{"sub-fix-timing-keep", OPT_INT(sub_fix_timing_keep)},
{"sub-stretch-durations", OPT_BOOL(sub_stretch_durations)},
{"sub-gauss", OPT_FLOAT(sub_gauss), M_RANGE(0.0, 3.0)},
{"sub-gray", OPT_BOOL(sub_gray)},
@@ -351,6 +353,8 @@ const struct m_sub_options mp_subtitle_sub_opts = {
.defaults = &(OPT_BASE_STRUCT){
.sub_speed = 1.0,
.ass_enabled = true,
.sub_fix_timing_threshold = 210,
.sub_fix_timing_keep = 400,
.sub_scale_by_window = true,
.sub_use_margins = true,
.sub_scale_with_window = true,
+2
View File
@@ -102,6 +102,8 @@ struct mp_subtitle_opts {
bool stretch_image_subs;
bool image_subs_video_res;
bool sub_fix_timing;
int sub_fix_timing_threshold;
int sub_fix_timing_keep;
bool sub_stretch_durations;
bool sub_scale_by_window;
bool sub_scale_with_window;
-4
View File
@@ -5,10 +5,6 @@
#include "demux/packet.h"
#include "misc/bstr.h"
// up to 210 ms overlaps or gaps are removed
#define SUB_GAP_THRESHOLD 0.210
// don't change timings if durations are smaller
#define SUB_GAP_KEEP 0.4
// slight offset when sub seeking or sub stepping
#define SUB_SEEK_OFFSET 0.01
#define SUB_SEEK_WITHOUT_VIDEO_OFFSET 0.1
+2 -2
View File
@@ -670,8 +670,8 @@ static long long find_timestamp(struct sd *sd, double pts)
// Try to fix small gaps and overlaps.
ASS_Track *track = priv->ass_track;
int threshold = SUB_GAP_THRESHOLD * 1000;
int keep = SUB_GAP_KEEP * 1000;
int threshold = sd->opts->sub_fix_timing_threshold;
int keep = sd->opts->sub_fix_timing_keep;
// Find the "current" event.
ASS_Event *ev[2] = {0};
+1 -1
View File
@@ -374,7 +374,7 @@ static void decode(struct sd *sd, struct demux_packet *packet)
if (prev->endpts == MP_NOPTS_VALUE || prev->endpts > pts)
prev->endpts = pts;
if (opts->sub_fix_timing && pts - prev->endpts <= SUB_GAP_THRESHOLD)
if (opts->sub_fix_timing && pts - prev->endpts <= opts->sub_fix_timing_threshold / 1000.0)
prev->endpts = pts;
for (int n = 0; n < priv->num_seekpoints; n++) {