summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRudolf Polzer <divVerent@xonotic.org>2013-11-01 16:02:47 +0100
committerRudolf Polzer <divverent@xonotic.org>2013-11-07 12:56:07 +0100
commit633fde4ae541ddfe57f8111fe9b5b1fba89e6fc6 (patch)
treec00e88cd5efb55528a9f34c279101d31cb4b05be
parent49caa0a775be06539a7cd30875f1c80368a7ac55 (diff)
downloadmpv-633fde4ae541ddfe57f8111fe9b5b1fba89e6fc6.tar.bz2
mpv-633fde4ae541ddfe57f8111fe9b5b1fba89e6fc6.tar.xz
sd_lavc, sd_spu: make dvdsub stretching conditional on --stretch-dvd-subs.
We found that the stretching - although it usually improves the looks of the fonts - is incorrect. On DVD, subtitles can cover the full area of the picture, and they have the same pixel aspect as the movie itself. Too bad many commercially released DVDs use bitmap fonts made with the wrong pixel aspect (i.e. assuming 1:1) - --stretch-dvd-subs will make these more pretty then.
-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