diff options
-rw-r--r-- | DOCS/man/options.rst | 95 | ||||
-rw-r--r-- | DOCS/man/vf.rst | 91 | ||||
-rw-r--r-- | options/m_option.c | 10 | ||||
-rw-r--r-- | options/m_option.h | 8 | ||||
-rw-r--r-- | options/options.c | 22 | ||||
-rw-r--r-- | options/options.h | 5 | ||||
-rw-r--r-- | player/command.c | 141 | ||||
-rw-r--r-- | sub/sd_ass.c | 8 | ||||
-rw-r--r-- | video/csputils.c | 57 | ||||
-rw-r--r-- | video/csputils.h | 13 | ||||
-rw-r--r-- | video/decode/dec_video.c | 10 | ||||
-rw-r--r-- | video/filter/vf_format.c | 31 | ||||
-rw-r--r-- | video/mp_image.c | 14 |
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) { |