From 9f6faef60d0b6a063ebbc4db9fbd28383176eb9e Mon Sep 17 00:00:00 2001 From: Toad King Date: Sun, 1 Dec 2024 17:15:36 -0600 Subject: [PATCH] sd_lavc: match video display aspect ratio on SD video in PGS subtitles Previous fixes in bcc3d72 make subtitles on videos with non-square pixel aspect ratios appear incorrect. This can happen on subtitles for SD Blu-rays where the video resolution is 720x480 but the aspect ratio is 4:3. The scaling still applies when the video frame is cropped with filters so the previous fix will still work. Fixes #15415. --- sub/osd.c | 5 +++-- sub/sd_lavc.c | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/sub/osd.c b/sub/osd.c index 989696721c..17b9198cdf 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -540,7 +540,8 @@ struct mp_osd_res osd_get_vo_res(struct osd_state *osd) // fills the whole video area (especially if the video is magnified, e.g. on // fullscreen). If compensate_par is >0, adjust the way the subtitles are // "stretched" on the screen, and letter-box the result. If compensate_par -// is <0, strictly letter-box the subtitles. If it is 0, stretch them. +// is <0, strictly letter-box the subtitles according to the supplied aspect +// ratio. If it is 0, stretch them. void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h, struct mp_osd_res res, double compensate_par) { @@ -550,7 +551,7 @@ void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h, double yscale = (double)vidh / frame_h; if (compensate_par < 0) { assert(res.display_par); - compensate_par = xscale / yscale / res.display_par; + compensate_par = xscale / yscale / res.display_par / compensate_par * -1; } if (compensate_par > 0) xscale /= compensate_par; diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index d646b207c4..3ae7e63c84 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -472,7 +472,24 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res d, video_par = par; } if (priv->avctx->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE) - video_par = -1; + { + // For Blu-ray subs on SD video, try to match the video PAR. + if (priv->video_params.w == 720 && + (priv->video_params.h == 480 || + priv->video_params.h == 576)) + { + double par = priv->video_params.p_w / (double)priv->video_params.p_h; + if (isnormal(par)) + video_par = par * -1; + else + video_par = -1; + } + else + { + // Force letter-boxing on all other Blu-ray subtitles + video_par = -1; + } + } if (opts->stretch_image_subs) d.ml = d.mr = d.mt = d.mb = 0; int w = priv->avctx->width;