sd_ass: fix converted subtitles having too-wide borders

Libass commit f08f8ea5 (between 0.16 and 0.17) changed how PlayResX
affects some aspects of rendering.

The libass change fixes a VSFilter compatibility issue which existed
for about two decades, and there are no libass plans to support the
previous behavior, so ultimately we have to adjust the mpv code, and
we can't guarantee to restore the old behavior in all cases.

Starting at this commit, vector drawing coords, font spacing, border
and shadow widths are all affected by PlayResX (specifically, by
the aspect), while previously they were unaffected by PlayResX.

This changed converted sub border and shadow widths in mpv, because
ffmpeg generates the ass with fixed PlayResX of 384 (aspect of 4:3),
and with libass 0.17, if this doesn't match the display aspect, then
borders and shadow were too wide - because most clips aspect is more
than 4:3.

The fact that ffmpeg uses fixed PlayResX of 384 could be considered
an issue, but for now we have no control over it, and ffmpeg doesn't
have the video resolution when it converts an srt source to ass.

So here we adjust PlayResX accordingly so that border/shadows are
now rendered with correct width.

However, regardless of that commit, changing PlayResX also affects
the margin value, so to compensate, we adjust sub-margins-x too.

According to libass devs, this should cover basic srt-to-ass
conversion by ffmpeg to work correctly with libass 0.17.

However, there could be srt extensions which use more complex ass,
and/or ffmpeg conversion of other sub formats (such as aribb24,
aribcaption and movtext), where more things need adjustments.
As of now we don't know what these are, and so we don't really know
what else might remain broken or get broken.
This commit is contained in:
llyyr 2023-06-25 06:10:25 +05:30 committed by avih
parent cab544889a
commit 580f36e436
1 changed files with 28 additions and 0 deletions

View File

@ -450,6 +450,34 @@ static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
if (converted)
ass_track_set_feature(track, ASS_FEATURE_WRAP_UNICODE, 1);
#endif
if (converted) {
bool override_playres = true;
char **ass_force_style_list = opts->ass_force_style_list;
for (int i = 0; ass_force_style_list && ass_force_style_list[i]; i++) {
if (bstr_find0(bstr0(ass_force_style_list[i]), "PlayResX") >= 0)
override_playres = false;
}
// srt to ass conversion from ffmpeg has fixed PlayResX of 384 with an
// aspect of 4:3. Starting with libass f08f8ea5 (pre 0.17) PlayResX
// affects shadow and border widths, among others, so to render borders
// and shadows correctly, we adjust PlayResX according to the DAR.
// But PlayResX also affects margins, so we adjust those too.
// This should ensure basic srt-to-ass ffmpeg conversion has correct
// borders, but there could be other issues with some srt extensions
// and/or different source formats which would be exposed over time.
// Make these adjustments only if the user didn't set PlayResX.
if (override_playres) {
int vidw = dim->w - (dim->ml + dim->mr);
int vidh = dim->h - (dim->mt + dim->mb);
track->PlayResX = track->PlayResY * (double)vidw / MPMAX(vidh, 1);
// ffmpeg and mpv use a default PlayResX of 384 when it is not known,
// this comes from VSFilter.
double fix_margins = track->PlayResX / 384.0;
track->styles->MarginL = round(track->styles->MarginL * fix_margins);
track->styles->MarginR = round(track->styles->MarginR * fix_margins);
}
}
}
static bool has_overrides(char *s)