summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-03-30 23:52:28 +0200
committerwm4 <wm4@nowhere>2015-03-31 00:09:03 +0200
commit27715b7dd18c4a393b8483b8048cb957172e776b (patch)
tree1a0c9fbcab9591fd451f1525f5fe6613d15a7b7e
parent273afdc3a4dc775e427b282f0e30c9a6ae167e06 (diff)
downloadmpv-27715b7dd18c4a393b8483b8048cb957172e776b.tar.bz2
mpv-27715b7dd18c4a393b8483b8048cb957172e776b.tar.xz
video: move colorspace overrides to vf_format, simplify
Remove the colorspace-related top-level options, add them to vf_format. They are rather obscure and not needed often, so it's better to get them out of the way. In particular, this gets rid of the semi-complicated logic in command.c (most of which was needed for OSD display and the direct feedback from the VO). It removes the duplicated color-related name mappings. This removes the ability to write the colormatrix and related properties. Since filters can be changed at runtime, there's no loss of functionality, except that you can't cycle automatically through the color constants anymore (but who needs to do this). This also changes the type of the mp_csp_names and related variables, so they can directly be used with OPT_CHOICE. This probably ended up a bit awkward, for the sake of not adding a new option type which would have used the previous format.
-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) {