summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst13
-rw-r--r--mpvcore/options.c1
-rw-r--r--mpvcore/options.h1
-rw-r--r--sub/sd_lavc.c4
-rw-r--r--sub/sd_spu.c33
-rw-r--r--sub/spudec.c9
-rw-r--r--sub/spudec.h2
7 files changed, 55 insertions, 8 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index e1253ce17b..50f0b1e998 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -2088,6 +2088,19 @@ OPTIONS
``--start='#2' --end='#4'``
Plays chapters 2 and 3, and exits.
+``--stretch-dvd-subs=<yes|no>``
+ Stretch DVD subtitles when playing anamorphic videos for better looking
+ fonts on badly mastered DVDs. This switch has no effect when the
+ video is stored with square pixels - which for DVD input cannot be the case
+ though.
+
+ Many studios tend to use bitmap fonts designed for square pixels when
+ authoring DVDs, causing the fonts to look stretched on playback on DVD
+ players. This option fixes them, however at the price of possibly
+ misaligning sume subtitles (e.g. sign translations).
+
+ Disabled by default.
+
``--ssf=<mode>``
Specifies software scaler parameters.
diff --git a/mpvcore/options.c b/mpvcore/options.c
index 52cfa6fd52..e8c82c447f 100644
--- a/mpvcore/options.c
+++ b/mpvcore/options.c
@@ -531,6 +531,7 @@ const m_option_t mp_opts[] = {
OPT_FLAG("autosub", sub_auto, 0),
OPT_FLAG("sub-visibility", sub_visibility, 0),
OPT_FLAG("sub-forced-only", forced_subs_only, 0),
+ OPT_FLAG("stretch-dvd-subs", stretch_dvd_subs, 0),
OPT_FLAG_CONSTANTS("sub-fix-timing", suboverlap_enabled, 0, 1, 0),
OPT_CHOICE("autosub-match", sub_match_fuzziness, 0,
({"exact", 0}, {"fuzzy", 1}, {"all", 2})),
diff --git a/mpvcore/options.h b/mpvcore/options.h
index 4a58a0e10d..e6df87f4b8 100644
--- a/mpvcore/options.h
+++ b/mpvcore/options.h
@@ -148,6 +148,7 @@ typedef struct MPOpts {
float sub_fps;
float sub_speed;
int forced_subs_only;
+ int stretch_dvd_subs;
char *quvi_format;
// subreader.c
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 2cce6ea4cd..40039314a1 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -207,6 +207,7 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
struct sub_bitmaps *res)
{
struct sd_lavc_priv *priv = sd->priv;
+ struct MPOpts *opts = sd->opts;
if (priv->pts != MP_NOPTS_VALUE && pts < priv->pts)
return;
@@ -223,7 +224,8 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
int vidh = d.h - d.mt - d.mb;
double xscale = (double)vidw / inw;
double yscale = (double)vidh / inh;
- if (priv->avctx->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
+ if (priv->avctx->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
+ opts->stretch_dvd_subs) {
// For DVD subs, try to keep the subtitle PAR at display PAR.
double video_par =
(priv->video_params.d_w / (double)priv->video_params.d_h)
diff --git a/sub/sd_spu.c b/sub/sd_spu.c
index 52e2b728ed..717e4652b9 100644
--- a/sub/sd_spu.c
+++ b/sub/sd_spu.c
@@ -21,12 +21,14 @@
#include "talloc.h"
#include "mpvcore/options.h"
#include "demux/stheader.h"
+#include "video/mp_image.h"
#include "sd.h"
#include "sub.h"
#include "spudec.h"
struct sd_spu_priv {
void *spudec;
+ struct mp_image_params video_params;
};
static bool is_dvd_sub(const char *t)
@@ -72,8 +74,22 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
spudec_set_forced_subs_only(priv->spudec, opts->forced_subs_only);
spudec_heartbeat(priv->spudec, pts * 90000);
- if (spudec_visible(priv->spudec))
- spudec_get_indexed(priv->spudec, &d, res);
+ if (spudec_visible(priv->spudec)) {
+ double xscale = 1;
+ double yscale = 1;
+ if (opts->stretch_dvd_subs) {
+ // For DVD subs, try to keep the subtitle PAR at display PAR.
+ double video_par =
+ (priv->video_params.d_w / (double)priv->video_params.d_h)
+ / (priv->video_params.w / (double)priv->video_params.h);
+ if (video_par > 1.0) {
+ xscale /= video_par;
+ } else {
+ yscale *= video_par;
+ }
+ }
+ spudec_get_indexed(priv->spudec, &d, xscale, yscale, res);
+ }
}
static void reset(struct sd *sd)
@@ -91,12 +107,25 @@ static void uninit(struct sd *sd)
talloc_free(priv);
}
+static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
+{
+ struct sd_spu_priv *priv = sd->priv;
+ switch (cmd) {
+ case SD_CTRL_SET_VIDEO_PARAMS:
+ priv->video_params = *(struct mp_image_params *)arg;
+ return CONTROL_OK;
+ default:
+ return CONTROL_UNKNOWN;
+ }
+}
+
const struct sd_functions sd_spu = {
.name = "spu",
.supports_format = supports_format,
.init = init,
.decode = decode,
.get_bitmaps = get_bitmaps,
+ .control = control,
.reset = reset,
.uninit = uninit,
};
diff --git a/sub/spudec.c b/sub/spudec.c
index 56d7ca1eae..5d58b3664c 100644
--- a/sub/spudec.c
+++ b/sub/spudec.c
@@ -644,6 +644,7 @@ void spudec_set_forced_subs_only(void * const this, const unsigned int flag)
}
void spudec_get_indexed(void *this, struct mp_osd_res *dim,
+ double xstretch, double ystretch,
struct sub_bitmaps *res)
{
spudec_handle_t *spu = this;
@@ -656,10 +657,10 @@ void spudec_get_indexed(void *this, struct mp_osd_res *dim,
if (spudec_visible(spu) && !empty) {
double xscale = (double) (dim->w - dim->ml - dim->mr) / spu->orig_frame_width;
double yscale = (double) (dim->h - dim->mt - dim->mb) / spu->orig_frame_height;
- part->x = part->x * xscale + dim->ml;
- part->y = part->y * yscale + dim->mt;
- part->dw = part->w * xscale;
- part->dh = part->h * yscale;
+ part->x = part->x * xscale * xstretch + dim->ml + dim->w * (0.5 - 0.5 * xstretch);
+ part->y = part->y * yscale * ystretch + dim->mt + dim->h * (0.5 - 0.5 * ystretch);
+ part->dw = part->w * xscale * xstretch;
+ part->dh = part->h * yscale * ystretch;
res->num_parts = 1;
res->scaled = true;
}
diff --git a/sub/spudec.h b/sub/spudec.h
index 3a44bd1e2e..55071d823e 100644
--- a/sub/spudec.h
+++ b/sub/spudec.h
@@ -26,7 +26,7 @@ struct mp_osd_res;
void spudec_heartbeat(void *this, unsigned int pts100);
void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100);
-void spudec_get_indexed(void *this, struct mp_osd_res *dim, struct sub_bitmaps *res);
+void spudec_get_indexed(void *this, struct mp_osd_res *dim, double xstretch, double ystretch, struct sub_bitmaps *res);
void *spudec_new_scaled(unsigned int frame_width, unsigned int frame_height, uint8_t *extradata, int extradata_len);
void spudec_free(void *this);
void spudec_reset(void *this); // called after seek