summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst95
-rw-r--r--DOCS/man/vf.rst91
-rw-r--r--options/m_option.c10
-rw-r--r--options/m_option.h8
-rw-r--r--options/options.c22
-rw-r--r--options/options.h5
-rw-r--r--player/command.c141
-rw-r--r--sub/sd_ass.c8
-rw-r--r--video/csputils.c57
-rw-r--r--video/csputils.h13
-rw-r--r--video/decode/dec_video.c10
-rw-r--r--video/filter/vf_format.c31
-rw-r--r--video/mp_image.c14
13 files changed, 210 insertions, 295 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 7c42088c8c..fed1d4ef52 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1995,101 +1995,6 @@ Equalizer
negative of the image with this option. Not supported by all video output
drivers.
-``--colormatrix=<colorspace>``
- Controls the YUV to RGB color space conversion when playing video. There
- are various standards. Normally, BT.601 should be used for SD video, and
- BT.709 for HD video. (This is done by default.) Using incorrect color space
- results in slightly under or over saturated and shifted colors.
-
- The color space conversion is additionally influenced by the related
- options --colormatrix-input-range and --colormatrix-output-range.
-
- These options are not always supported. Different video outputs provide
- varying degrees of support. The ``opengl`` and ``vdpau`` video output
- drivers usually offer full support. The ``xv`` output can set the color
- space if the system video driver supports it, but not input and output
- levels. The ``scale`` video filter can configure color space and input
- levels, but only if the output format is RGB (if the video output driver
- supports RGB output, you can force this with ``-vf scale,format=rgba``).
-
- If this option is set to ``auto`` (which is the default), the video's
- color space flag will be used. If that flag is unset, the color space
- will be selected automatically. This is done using a simple heuristic that
- attempts to distinguish SD and HD video. If the video is larger than
- 1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
- selected.
-
- Available color spaces are:
-
- :auto: automatic selection (default)
- :bt.601: ITU-R BT.601 (SD)
- :bt.709: ITU-R BT.709 (HD)
- :bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
- :bt.2020-cl: ITU-R BT.2020 constant luminance system
- :smpte-240m: SMPTE-240M
-
-``--colormatrix-input-range=<color-range>``
- YUV color levels used with YUV to RGB conversion. This option is only
- necessary when playing broken files which do not follow standard color
- levels or which are flagged wrong. If the video does not specify its
- color range, it is assumed to be limited range.
-
- The same limitations as with --colormatrix apply.
-
- Available color ranges are:
-
- :auto: automatic selection (normally limited range) (default)
- :limited: limited range (16-235 for luma, 16-240 for chroma)
- :full: full range (0-255 for both luma and chroma)
-
-``--colormatrix-output-range=<color-range>``
- RGB color levels used with YUV to RGB conversion. Normally, output devices
- such as PC monitors use full range color levels. However, some TVs and
- video monitors expect studio RGB levels. Providing full range output to a
- device expecting studio level input results in crushed blacks and whites,
- the reverse in dim gray blacks and dim whites.
-
- The same limitations as with ``--colormatrix`` apply.
-
- Available color ranges are:
-
- :auto: automatic selection (equals to full range) (default)
- :limited: limited range (16-235 per component), studio levels
- :full: full range (0-255 per component), PC levels
-
- .. note::
-
- It is advisable to use your graphics driver's color range option
- instead, if available.
-
-``--colormatrix-primaries=<primaries>``
- RGB primaries the source file was encoded with. Normally this should be set
- in the file header, but when playing broken or mistagged files this can be
- used to override the setting. By default, when unset, BT.709 is used for
- all files except those tagged with a BT.2020 color matrix.
-
- This option only affects video output drivers that perform color
- management, for example ``opengl`` with the ``srgb`` or ``icc-profile``
- suboptions set.
-
- If this option is set to ``auto`` (which is the default), the video's
- primaries flag will be used. If that flag is unset, the color space will
- be selected automatically, using the following heuristics: If the
- ``--colormatrix`` is set or determined as BT.2020 or BT.709, the
- corresponding primaries are used. Otherwise, if the video height is
- exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
- BT.601-525 is used. If the video resolution is anything else, BT.709 is
- used.
-
- Available primaries are:
-
- :auto: automatic selection (default)
- :bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
- :bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
- :bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
- :bt.2020: ITU-R BT.2020 (UHD)
-
-
Demuxer
-------
diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst
index 984bdda656..0e944f110e 100644
--- a/DOCS/man/vf.rst
+++ b/DOCS/man/vf.rst
@@ -211,6 +211,97 @@ Available filters are:
``<outfmt>``
Format name that should be substituted for the output. If they do not
have the same bytes per pixel and chroma subsamplimg, it will fail.
+ ``<colormatrix>``
+ Controls the YUV to RGB color space conversion when playing video. There
+ are various standards. Normally, BT.601 should be used for SD video, and
+ BT.709 for HD video. (This is done by default.) Using incorrect color space
+ results in slightly under or over saturated and shifted colors.
+
+ These options are not always supported. Different video outputs provide
+ varying degrees of support. The ``opengl`` and ``vdpau`` video output
+ drivers usually offer full support. The ``xv`` output can set the color
+ space if the system video driver supports it, but not input and output
+ levels. The ``scale`` video filter can configure color space and input
+ levels, but only if the output format is RGB (if the video output driver
+ supports RGB output, you can force this with ``-vf scale,format=rgba``).
+
+ If this option is set to ``auto`` (which is the default), the video's
+ color space flag will be used. If that flag is unset, the color space
+ will be selected automatically. This is done using a simple heuristic that
+ attempts to distinguish SD and HD video. If the video is larger than
+ 1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
+ selected.
+
+ Available color spaces are:
+
+ :auto: automatic selection (default)
+ :bt.601: ITU-R BT.601 (SD)
+ :bt.709: ITU-R BT.709 (HD)
+ :bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
+ :bt.2020-cl: ITU-R BT.2020 constant luminance system
+ :smpte-240m: SMPTE-240M
+
+ ``<colorlevels>``
+ YUV color levels used with YUV to RGB conversion. This option is only
+ necessary when playing broken files which do not follow standard color
+ levels or which are flagged wrong. If the video does not specify its
+ color range, it is assumed to be limited range.
+
+ The same limitations as with ``<colormatrix>`` apply.
+
+ Available color ranges are:
+
+ :auto: automatic selection (normally limited range) (default)
+ :limited: limited range (16-235 for luma, 16-240 for chroma)
+ :full: full range (0-255 for both luma and chroma)
+
+ ``<outputlevels>``
+ RGB color levels used with YUV to RGB conversion. Normally, output devices
+ such as PC monitors use full range color levels. However, some TVs and
+ video monitors expect studio RGB levels. Providing full range output to a
+ device expecting studio level input results in crushed blacks and whites,
+ the reverse in dim gray blacks and dim whites.
+
+ The same limitations as with ``<colormatrix>`` apply.
+
+ Available color ranges are:
+
+ :auto: automatic selection (equals to full range) (default)
+ :limited: limited range (16-235 per component), studio levels
+ :full: full range (0-255 per component), PC levels
+
+ .. note::
+
+ It is advisable to use your graphics driver's color range option
+ instead, if available.
+
+ ``<primaries>``
+ RGB primaries the source file was encoded with. Normally this should be set
+ in the file header, but when playing broken or mistagged files this can be
+ used to override the setting. By default, when unset, BT.709 is used for
+ all files except those tagged with a BT.2020 color matrix.
+
+ This option only affects video output drivers that perform color
+ management, for example ``opengl`` with the ``srgb`` or ``icc-profile``
+ suboptions set.
+
+ If this option is set to ``auto`` (which is the default), the video's
+ primaries flag will be used. If that flag is unset, the color space will
+ be selected automatically, using the following heuristics: If the
+ ``<colormatrix>`` is set or determined as BT.2020 or BT.709, the
+ corresponding primaries are used. Otherwise, if the video height is
+ exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
+ BT.601-525 is used. If the video resolution is anything else, BT.709 is
+ used.
+
+ Available primaries are:
+
+ :auto: automatic selection (default)
+ :bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
+ :bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
+ :bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
+ :bt.2020: ITU-R BT.2020 (UHD)
+
``noformat[=fmt]``
Restricts the color space for the next filter without doing any conversion.
diff --git a/options/m_option.c b/options/m_option.c
index 2b34c4e918..49d78a06d2 100644
--- a/options/m_option.c
+++ b/options/m_option.c
@@ -522,6 +522,16 @@ const struct m_option_type m_option_type_intpair = {
.copy = copy_opt,
};
+const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices,
+ int value)
+{
+ for (const struct m_opt_choice_alternatives *c = choices; c->name; c++) {
+ if (c->value == value)
+ return c->name;
+ }
+ return NULL;
+}
+
static int clamp_choice(const m_option_t *opt, void *val)
{
int v = *(int *)val;
diff --git a/options/m_option.h b/options/m_option.h
index 401d98473d..a07c5a1082 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -165,6 +165,9 @@ struct m_opt_choice_alternatives {
int value;
};
+const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices,
+ int value);
+
// For OPT_STRING_VALIDATE(). Behaves like m_option_type.parse().
typedef int (*m_opt_string_validate_fn)(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param);
@@ -626,6 +629,11 @@ extern const char m_option_path_separator;
OPT_CHOICE_(__VA_ARGS__, .type = &m_option_type_choice)
#define OPT_CHOICE_(optname, varname, flags, choices, ...) \
OPT_GENERAL(int, optname, varname, flags, M_CHOICES(choices), __VA_ARGS__)
+// Variant which takes a pointer to struct m_opt_choice_alternatives directly
+#define OPT_CHOICE_C(optname, varname, flags, choices) \
+ OPT_GENERAL(int, optname, varname, flags, .priv = (void *) \
+ MP_EXPECT_TYPE(const struct m_opt_choice_alternatives*, choices), \
+ .type = &m_option_type_choice)
#define OPT_FLAGS(...) \
OPT_CHOICE_(__VA_ARGS__, .type = &m_option_type_flags)
diff --git a/options/options.c b/options/options.c
index 8c33e4560a..4e01ae27cf 100644
--- a/options/options.c
+++ b/options/options.c
@@ -424,28 +424,6 @@ const m_option_t mp_opts[] = {
OPT_FLOATRANGE("video-align-y", vo.align_y, 0, -1.0, 1.0),
OPT_FLAG("video-unscaled", vo.unscaled, 0),
OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0),
- OPT_CHOICE("colormatrix", requested_colorspace, 0,
- ({"auto", MP_CSP_AUTO},
- {"bt.601", MP_CSP_BT_601},
- {"bt.709", MP_CSP_BT_709},
- {"smpte-240m", MP_CSP_SMPTE_240M},
- {"bt.2020-ncl", MP_CSP_BT_2020_NC},
- {"bt.2020-cl", MP_CSP_BT_2020_C},
- {"YCgCo", MP_CSP_YCGCO})),
- OPT_CHOICE("colormatrix-input-range", requested_input_range, 0,
- ({"auto", MP_CSP_LEVELS_AUTO},
- {"limited", MP_CSP_LEVELS_TV},
- {"full", MP_CSP_LEVELS_PC})),
- OPT_CHOICE("colormatrix-output-range", requested_output_range, 0,
- ({"auto", MP_CSP_LEVELS_AUTO},
- {"limited", MP_CSP_LEVELS_TV},
- {"full", MP_CSP_LEVELS_PC})),
- OPT_CHOICE("colormatrix-primaries", requested_primaries, 0,
- ({"auto", MP_CSP_PRIM_AUTO},
- {"bt.601-525", MP_CSP_PRIM_BT_601_525},
- {"bt.601-625", MP_CSP_PRIM_BT_601_625},
- {"bt.709", MP_CSP_PRIM_BT_709},
- {"bt.2020", MP_CSP_PRIM_BT_2020})),
OPT_CHOICE_OR_INT("video-rotate", video_rotate, 0, 0, 359,
({"no", -1})),
OPT_VID_STEREO_MODE("video-stereo-mode", video_stereo_mode, 0),
diff --git a/options/options.h b/options/options.h
index 15ff9cb8ca..24173168e6 100644
--- a/options/options.h
+++ b/options/options.h
@@ -102,11 +102,6 @@ typedef struct MPOpts {
int cursor_autohide_delay;
int cursor_autohide_fs;
- int requested_colorspace;
- int requested_input_range;
- int requested_output_range;
- int requested_primaries;
-
int video_rotate;
int video_stereo_mode;
diff --git a/player/command.c b/player/command.c
index a2886cdea2..4b4b7ed680 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2182,113 +2182,6 @@ static int video_simple_refresh_property(void *ctx, struct m_property *prop,
return r;
}
-static void append_csp(char **ptr, const char *name, const char *const *names,
- int value)
-{
- const char *cspname = names[value];
- if (name[0] == '*') {
- name++;
- } else if (value == 0) {
- cspname = "unknown";
- }
- *ptr = talloc_asprintf_append(*ptr, "%s: %s\n", name, cspname);
-}
-
-static int mp_property_colormatrix(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- if (action != M_PROPERTY_PRINT)
- return video_refresh_property_helper(prop, action, arg, mpctx);
-
- struct MPOpts *opts = mpctx->opts;
-
- struct mp_image_params vo_csp = {0};
- if (mpctx->video_out)
- vo_control(mpctx->video_out, VOCTRL_GET_COLORSPACE, &vo_csp);
-
- struct mp_image_params vd_csp = {0};
- if (mpctx->d_video)
- vd_csp = mpctx->d_video->decoder_output;
-
- char *res = talloc_strdup(NULL, "");
- append_csp(&res, "*Requested", mp_csp_names, opts->requested_colorspace);
- append_csp(&res, "Video decoder", mp_csp_names, vd_csp.colorspace);
- *(char **)arg = res;
- return M_PROPERTY_OK;
-}
-
-static int mp_property_colormatrix_input_range(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- if (action != M_PROPERTY_PRINT)
- return video_refresh_property_helper(prop, action, arg, mpctx);
-
- struct MPOpts *opts = mpctx->opts;
-
- struct mp_image_params vo_csp = {0};
- if (mpctx->video_out)
- vo_control(mpctx->video_out, VOCTRL_GET_COLORSPACE, &vo_csp);
-
- struct mp_image_params vd_csp = {0};
- if (mpctx->d_video)
- vd_csp = mpctx->d_video->decoder_output;
-
- char *res = talloc_strdup(NULL, "");
- append_csp(&res, "*Requested", mp_csp_levels_names,
- opts->requested_input_range);
- append_csp(&res, "Video decoder", mp_csp_levels_names, vd_csp.colorlevels);
- *(char **)arg = res;
- return M_PROPERTY_OK;
-}
-
-static int mp_property_colormatrix_output_range(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- if (action != M_PROPERTY_PRINT)
- return video_refresh_property_helper(prop, action, arg, mpctx);
-
- struct MPOpts *opts = mpctx->opts;
-
- struct mp_image_params actual = {0};
- if (mpctx->video_out)
- vo_control(mpctx->video_out, VOCTRL_GET_COLORSPACE, &actual);
-
- char *res = talloc_strdup(NULL, "");
- append_csp(&res, "*Requested", mp_csp_levels_names,
- opts->requested_output_range);
- append_csp(&res, "Video output", mp_csp_levels_names, actual.outputlevels);
- *(char **)arg = res;
- return M_PROPERTY_OK;
-}
-
-static int mp_property_primaries(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- if (action != M_PROPERTY_PRINT)
- return video_refresh_property_helper(prop, action, arg, mpctx);
-
- struct MPOpts *opts = mpctx->opts;
-
- struct mp_image_params vo_csp = {0};
- if (mpctx->video_out)
- vo_control(mpctx->video_out, VOCTRL_GET_COLORSPACE, &vo_csp);
-
- struct mp_image_params vd_csp = {0};
- if (mpctx->d_video)
- vd_csp = mpctx->d_video->decoder_output;
-
- char *res = talloc_strdup(NULL, "");
- append_csp(&res, "*Requested", mp_csp_prim_names, opts->requested_primaries);
- append_csp(&res, "Video decoder", mp_csp_prim_names, vd_csp.primaries);
- append_csp(&res, "Video output", mp_csp_prim_names, vo_csp.primaries);
- *(char **)arg = res;
- return M_PROPERTY_OK;
-}
-
// Update options which are managed through VOCTRL_GET/SET_PANSCAN.
static int panscan_property_helper(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -2491,10 +2384,16 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg)
{"dh", SUB_PROP_INT(p.d_h)},
{"aspect", SUB_PROP_FLOAT(dar)},
{"par", SUB_PROP_FLOAT(dar / sar)},
- {"colormatrix", SUB_PROP_STR(mp_csp_names[p.colorspace])},
- {"colorlevels", SUB_PROP_STR(mp_csp_levels_names[p.colorlevels])},
- {"primaries", SUB_PROP_STR(mp_csp_prim_names[p.primaries])},
- {"chroma-location", SUB_PROP_STR(mp_chroma_names[p.chroma_location])},
+ {"colormatrix",
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_names, p.colorspace))},
+ {"colorlevels",
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_levels_names, p.colorlevels))},
+ {"outputlevels",
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_levels_names, p.outputlevels))},
+ {"primaries",
+ SUB_PROP_STR(m_opt_choice_str(mp_csp_prim_names, p.primaries))},
+ {"chroma-location",
+ SUB_PROP_STR(m_opt_choice_str(mp_chroma_names, p.chroma_location))},
{"rotate", SUB_PROP_INT(p.rotate)},
{0}
};
@@ -3437,10 +3336,6 @@ static const struct m_property mp_properties[] = {
{"fullscreen", mp_property_fullscreen},
{"deinterlace", mp_property_deinterlace},
{"field-dominance", mp_property_generic_option},
- {"colormatrix", mp_property_colormatrix},
- {"colormatrix-input-range", mp_property_colormatrix_input_range},
- {"colormatrix-output-range", mp_property_colormatrix_output_range},
- {"colormatrix-primaries", mp_property_primaries},
{"ontop", mp_property_ontop},
{"border", mp_property_border},
{"on-all-workspaces", mp_property_all_workspaces},
@@ -3534,10 +3429,6 @@ static const struct m_property mp_properties[] = {
TRACK_FF("ff-aid", STREAM_AUDIO),
TRACK_FF("ff-sid", STREAM_SUB),
- M_PROPERTY_ALIAS("video", "vid"),
- M_PROPERTY_ALIAS("audio", "aid"),
- M_PROPERTY_ALIAS("sub", "sid"),
-
{"window-minimized", mp_property_win_minimized},
{"display-names", mp_property_display_names},
{"display-fps", mp_property_display_fps},
@@ -3552,6 +3443,15 @@ static const struct m_property mp_properties[] = {
{"option-info", mp_property_option_info},
{"property-list", mp_property_list},
+ // compatibility
+ M_PROPERTY_ALIAS("video", "vid"),
+ M_PROPERTY_ALIAS("audio", "aid"),
+ M_PROPERTY_ALIAS("sub", "sid"),
+ M_PROPERTY_ALIAS("colormatrix", "video-params/colormatrix"),
+ M_PROPERTY_ALIAS("colormatrix-input-range", "video-params/colorlevels"),
+ M_PROPERTY_ALIAS("colormatrix-output-range", "video-params/outputlevels"),
+ M_PROPERTY_ALIAS("colormatrix-primaries", "video-params/primaries"),
+
{0},
};
@@ -3575,7 +3475,8 @@ static const char *const *const mp_event_property_change[] = {
E(MPV_EVENT_VIDEO_RECONFIG, "video-out-params", "video-params",
"video-format", "video-codec", "video-bitrate", "dwidth", "dheight",
"width", "height", "fps", "aspect", "vo-configured", "current-vo",
- "detected-hwdec"),
+ "detected-hwdec", "colormatrix", "colormatrix-input-range",
+ "colormatrix-output-range", "colormatrix-primaries"),
E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate",
"samplerate", "channels", "audio", "volume", "mute", "balance",
"volume-restore-data", "current-ao"),
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index dc5a913435..4840594986 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -459,9 +459,11 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
int msgl = basic_conv ? MSGL_V : MSGL_WARN;
ctx->last_params = params;
MP_MSG(sd, msgl, "mangling colors like vsfilter: "
- "RGB -> %s %s -> %s %s -> RGB\n", mp_csp_names[csp],
- mp_csp_levels_names[levels], mp_csp_names[params.colorspace],
- mp_csp_levels_names[params.colorlevels]);
+ "RGB -> %s %s -> %s %s -> RGB\n",
+ m_opt_choice_str(mp_csp_names, csp),
+ m_opt_choice_str(mp_csp_levels_names, levels),
+ m_opt_choice_str(mp_csp_names, params.colorspace),
+ m_opt_choice_str(mp_csp_names, params.colorlevels));
}
// Conversion that VSFilter would use
diff --git a/video/csputils.c b/video/csputils.c
index c10cfe5a7c..f8613399c8 100644
--- a/video/csputils.c
+++ b/video/csputils.c
@@ -37,32 +37,36 @@
#include "mp_image.h"
#include "csputils.h"
-
-const char *const mp_csp_names[MP_CSP_COUNT] = {
- "auto",
- "bt.601",
- "bt.709",
- "smpte-240m",
- "bt.2020-ncl",
- "bt.2020-cl",
- "rgb",
- "xyz",
- "ycgco",
+#include "options/m_option.h"
+
+const struct m_opt_choice_alternatives mp_csp_names[] = {
+ {"auto", MP_CSP_AUTO},
+ {"bt.601", MP_CSP_BT_601},
+ {"bt.709", MP_CSP_BT_709},
+ {"smpte-240m", MP_CSP_SMPTE_240M},
+ {"bt.2020-ncl", MP_CSP_BT_2020_NC},
+ {"bt.2020-cl", MP_CSP_BT_2020_C},
+ {"rgb", MP_CSP_RGB},
+ {"xyz", MP_CSP_XYZ},
+ {"ycgco", MP_CSP_YCGCO},
+ {0}
};
-const char *const mp_csp_levels_names[MP_CSP_LEVELS_COUNT] = {
- "auto",
- "limited",
- "full",
+const struct m_opt_choice_alternatives mp_csp_levels_names[] = {
+ {"auto", MP_CSP_LEVELS_AUTO},
+ {"limited", MP_CSP_LEVELS_TV},
+ {"full", MP_CSP_LEVELS_PC},
+ {0}
};
-const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT] = {
- "auto",
- "bt.601-525",
- "bt.601-625",
- "bt.709",
- "bt.2020",
- "bt.470 m",
+const struct m_opt_choice_alternatives mp_csp_prim_names[] = {
+ {"auto", MP_CSP_PRIM_AUTO},
+ {"bt.601-525", MP_CSP_PRIM_BT_601_525},
+ {"bt.601-625", MP_CSP_PRIM_BT_601_625},
+ {"bt.709", MP_CSP_PRIM_BT_709},
+ {"bt.2020", MP_CSP_PRIM_BT_2020},
+ {"bt.470m", MP_CSP_PRIM_BT_470M},
+ {0}
};
const char *const mp_csp_trc_names[MP_CSP_TRC_COUNT] = {
@@ -81,10 +85,11 @@ const char *const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = {
"gamma",
};
-const char *const mp_chroma_names[MP_CHROMA_COUNT] = {
- "unknown",
- "mpeg2/4/h264",
- "mpeg1/jpeg",
+const struct m_opt_choice_alternatives mp_chroma_names[] = {
+ {"unknown", MP_CHROMA_AUTO},
+ {"mpeg2/4/h264",MP_CHROMA_LEFT},
+ {"mpeg1/jpeg", MP_CHROMA_CENTER},
+ {0}
};
// The short name _must_ match with what vf_stereo3d accepts (if supported).
diff --git a/video/csputils.h b/video/csputils.h
index a68c106549..14acf03be5 100644
--- a/video/csputils.h
+++ b/video/csputils.h
@@ -27,6 +27,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include "options/m_option.h"
+
/* NOTE: the csp and levels AUTO values are converted to specific ones
* above vf/vo level. At least vf_scale relies on all valid settings being
* nonzero at vf/vo level.
@@ -45,8 +47,7 @@ enum mp_csp {
MP_CSP_COUNT
};
-// Any enum mp_csp value is a valid index (except MP_CSP_COUNT)
-extern const char *const mp_csp_names[MP_CSP_COUNT];
+extern const struct m_opt_choice_alternatives mp_csp_names[];
enum mp_csp_levels {
MP_CSP_LEVELS_AUTO,
@@ -55,8 +56,7 @@ enum mp_csp_levels {
MP_CSP_LEVELS_COUNT,
};
-// Any enum mp_csp_levels value is a valid index (except MP_CSP_LEVELS_COUNT)
-extern const char *const mp_csp_levels_names[MP_CSP_LEVELS_COUNT];
+extern const struct m_opt_choice_alternatives mp_csp_levels_names[];
enum mp_csp_prim {
MP_CSP_PRIM_AUTO,
@@ -68,8 +68,7 @@ enum mp_csp_prim {
MP_CSP_PRIM_COUNT
};
-// Any enum mp_csp_prim value is a valid index (except MP_CSP_PRIM_COUNT)
-extern const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT];
+extern const struct m_opt_choice_alternatives mp_csp_prim_names[];
enum mp_csp_trc {
MP_CSP_TRC_AUTO,
@@ -149,7 +148,7 @@ enum mp_chroma_location {
MP_CHROMA_COUNT,
};
-extern const char *const mp_chroma_names[MP_CHROMA_COUNT];
+extern const struct m_opt_choice_alternatives mp_chroma_names[];
enum mp_csp_equalizer_param {
MP_CSP_EQ_BRIGHTNESS,
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index c578ccadcc..11a36bb7ef 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -412,17 +412,7 @@ int video_reconfig_filters(struct dec_video *d_video,
if (force_aspect >= 0.0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
- // Apply user overrides
- if (opts->requested_colorspace != MP_CSP_AUTO)
- p.colorspace = opts->requested_colorspace;
- if (opts->requested_input_range != MP_CSP_LEVELS_AUTO)
- p.colorlevels = opts->requested_input_range;
- p.outputlevels = opts->requested_output_range;
- if (opts->requested_primaries != MP_CSP_PRIM_AUTO)
- p.primaries = opts->requested_primaries;
-
// Detect colorspace from resolution.
- // Make sure the user-overrides are consistent (no RGB csp for YUV, etc.).
mp_image_params_guess_csp(&p);
// Time to config libvo!
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index a638cb37a1..8b86c35489 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -33,6 +33,11 @@
struct vf_priv_s {
int fmt;
int outfmt;
+ int colormatrix;
+ int colorlevels;
+ int outputlevels;
+ int primaries;
+ int chroma_location;
};
static bool is_compatible(int fmt1, int fmt2)
@@ -69,9 +74,26 @@ static int query_format(struct vf_instance *vf, unsigned int fmt)
static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
struct mp_image_params *out)
{
+ struct vf_priv_s *p = vf->priv;
+
*out = *in;
- if (vf->priv->outfmt)
- out->imgfmt = vf->priv->outfmt;
+
+ if (p->outfmt)
+ out->imgfmt = p->outfmt;
+ if (p->colormatrix)
+ out->colorspace = p->colormatrix;
+ if (p->colorlevels)
+ out->colorlevels = p->colorlevels;
+ if (p->outputlevels)
+ out->outputlevels = p->outputlevels;
+ if (p->primaries)
+ out->primaries = p->primaries;
+ if (p->chroma_location)
+ out->chroma_location = p->chroma_location;
+
+ // Make sure the user-overrides are consistent (no RGB csp for YUV, etc.).
+ mp_image_params_guess_csp(out);
+
return 0;
}
@@ -94,6 +116,11 @@ static int vf_open(vf_instance_t *vf)
static const m_option_t vf_opts_fields[] = {
OPT_IMAGEFORMAT("fmt", fmt, 0),
OPT_IMAGEFORMAT("outfmt", outfmt, 0),
+ OPT_CHOICE_C("colormatrix", colormatrix, 0, mp_csp_names),
+ OPT_CHOICE_C("colorlevels", colorlevels, 0, mp_csp_levels_names),
+ OPT_CHOICE_C("outputlevels", outputlevels, 0, mp_csp_levels_names),
+ OPT_CHOICE_C("primaries", primaries, 0, mp_csp_prim_names),
+ OPT_CHOICE_C("chroma-location", chroma_location, 0, mp_chroma_names),
{0}
};
diff --git a/video/mp_image.c b/video/mp_image.c
index 0e378cb311..da644d57fe 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -446,11 +446,15 @@ char *mp_image_params_to_str_buf(char *b, size_t bs,
if (p->w != p->d_w || p->h != p->d_h)
mp_snprintf_cat(b, bs, "->%dx%d", p->d_w, p->d_h);
mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt));
- mp_snprintf_cat(b, bs, " %s/%s", mp_csp_names[p->colorspace],
- mp_csp_levels_names[p->colorlevels]);
- mp_snprintf_cat(b, bs, " CL=%s", mp_chroma_names[p->chroma_location]);
- if (p->outputlevels)
- mp_snprintf_cat(b, bs, " out=%s", mp_csp_levels_names[p->outputlevels]);
+ mp_snprintf_cat(b, bs, " %s/%s",
+ m_opt_choice_str(mp_csp_names, p->colorspace),
+ m_opt_choice_str(mp_csp_levels_names, p->colorlevels));
+ mp_snprintf_cat(b, bs, " CL=%s",
+ m_opt_choice_str(mp_chroma_names, p->chroma_location));
+ if (p->outputlevels) {
+ mp_snprintf_cat(b, bs, " out=%s",
+ m_opt_choice_str(mp_csp_levels_names, p->outputlevels));
+ }
if (p->rotate)
mp_snprintf_cat(b, bs, " rot=%d", p->rotate);
if (p->stereo_in > 0 || p->stereo_out > 0) {