summaryrefslogtreecommitdiffstats
path: root/sub/sd_ass.c
diff options
context:
space:
mode:
authorllyyr <llyyr.public@gmail.com>2023-06-25 06:10:25 +0530
committeravih <avih@users.noreply.github.com>2023-07-16 21:02:54 +0300
commit580f36e436225aa01bc3da03bd94882a983af3d6 (patch)
treebb9ead6461366fee1ceb4b7bdeef76a7394e5b26 /sub/sd_ass.c
parentcab544889a6ce2dd48a5859b54ccfd807518bd92 (diff)
downloadmpv-580f36e436225aa01bc3da03bd94882a983af3d6.tar.bz2
mpv-580f36e436225aa01bc3da03bd94882a983af3d6.tar.xz
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.
Diffstat (limited to 'sub/sd_ass.c')
-rw-r--r--sub/sd_ass.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 2189f0cebe..e4e5652875 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -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)