summaryrefslogtreecommitdiffstats
path: root/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'command.c')
-rw-r--r--command.c140
1 files changed, 107 insertions, 33 deletions
diff --git a/command.c b/command.c
index e9fc49fd17..789b60186c 100644
--- a/command.c
+++ b/command.c
@@ -41,6 +41,7 @@
#include "libmpcodecs/vd.h"
#include "mp_osd.h"
#include "libvo/video_out.h"
+#include "libvo/csputils.h"
#include "sub/font_load.h"
#include "playtree.h"
#include "libao2/audio_out.h"
@@ -1152,48 +1153,114 @@ static int mp_property_deinterlace(m_option_t *prop, int action,
return m_property_flag_ro(prop, action, arg, value);
}
-static int mp_property_yuv_colorspace(m_option_t *prop, int action,
+static int colormatrix_property_helper(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
- if (!mpctx->sh_video || !mpctx->sh_video->vfilter)
- return M_PROPERTY_UNAVAILABLE;
+ int r = mp_property_generic_option(prop, action, arg, mpctx);
+ // testing for an actual change is too much effort
+ switch (action) {
+ case M_PROPERTY_SET:
+ case M_PROPERTY_STEP_UP:
+ case M_PROPERTY_STEP_DOWN:
+ if (mpctx->sh_video)
+ set_video_colorspace(mpctx->sh_video);
+ break;
+ }
+ return r;
+}
- struct vf_instance *vf = mpctx->sh_video->vfilter;
- int colorspace;
+static int mp_property_colormatrix(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
switch (action) {
- case M_PROPERTY_GET:
- if (!arg)
- return M_PROPERTY_ERROR;
- if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, arg) != true)
- return M_PROPERTY_UNAVAILABLE;
- return M_PROPERTY_OK;
case M_PROPERTY_PRINT:
if (!arg)
return M_PROPERTY_ERROR;
- if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &colorspace) != true)
- return M_PROPERTY_UNAVAILABLE;
- char *const names[] = {
- "BT.601 (SD)", "BT.709 (HD)", "SMPTE-240M"
- };
- if (colorspace < 0 || colorspace >= sizeof(names) / sizeof(names[0]))
- *(char **)arg = talloc_strdup(NULL, mp_gtext("unknown"));
- else
- *(char **)arg = talloc_strdup(NULL, names[colorspace]);
+ struct mp_csp_details actual = { .format = -1 };
+ char *req_csp = mp_csp_names[opts->requested_colorspace];
+ char *real_csp = NULL;
+ if (mpctx->sh_video) {
+ struct vf_instance *vf = mpctx->sh_video->vfilter;
+ if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &actual) == true) {
+ real_csp = mp_csp_names[actual.format];
+ } else {
+ real_csp = "Unknown";
+ }
+ }
+ char *res;
+ if (opts->requested_colorspace == MP_CSP_AUTO && real_csp) {
+ // Caveat: doesn't handle the case when the autodetected colorspace
+ // is different from the actual colorspace as used by the
+ // VO - the OSD will display the VO colorspace without
+ // indication that it doesn't match the requested colorspace.
+ res = talloc_asprintf(NULL, "Auto (%s)", real_csp);
+ } else if (opts->requested_colorspace == actual.format || !real_csp) {
+ res = talloc_strdup(NULL, req_csp);
+ } else
+ res = talloc_asprintf(NULL, mp_gtext("%s, but %s used"),
+ req_csp, real_csp);
+ *(char **)arg = res;
return M_PROPERTY_OK;
- case M_PROPERTY_SET:
+ default:;
+ return colormatrix_property_helper(prop, action, arg, mpctx);
+ }
+}
+
+static int levels_property_helper(int offset, m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ char *optname = prop->priv;
+ const struct m_option *opt = m_config_get_option(mpctx->mconfig,
+ bstr(optname));
+ int *valptr = (int *)m_option_get_ptr(opt, &mpctx->opts);
+
+ switch (action) {
+ case M_PROPERTY_PRINT:
if (!arg)
return M_PROPERTY_ERROR;
- M_PROPERTY_CLAMP(prop, *(int *) arg);
- vf->control(vf, VFCTRL_SET_YUV_COLORSPACE, arg);
- return M_PROPERTY_OK;
- case M_PROPERTY_STEP_UP:;
- if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &colorspace) != true)
- return M_PROPERTY_UNAVAILABLE;
- colorspace += 1;
- vf->control(vf, VFCTRL_SET_YUV_COLORSPACE, &colorspace);
+ struct mp_csp_details actual = {0};
+ int actual_level = -1;
+ char *req_level = m_option_print(opt, valptr);
+ char *real_level = NULL;
+ if (mpctx->sh_video) {
+ struct vf_instance *vf = mpctx->sh_video->vfilter;
+ if (vf->control(vf, VFCTRL_GET_YUV_COLORSPACE, &actual) == true) {
+ actual_level = *(enum mp_csp_levels *)(((char *)&actual) + offset);
+ real_level = m_option_print(opt, &actual_level);
+ } else {
+ real_level = talloc_strdup(NULL, "Unknown");
+ }
+ }
+ char *res;
+ if (*valptr == MP_CSP_LEVELS_AUTO && real_level) {
+ res = talloc_asprintf(NULL, "Auto (%s)", real_level);
+ } else if (*valptr == actual_level || !real_level) {
+ res = talloc_strdup(NULL, real_level);
+ } else
+ res = talloc_asprintf(NULL, mp_gtext("%s, but %s used"),
+ req_level, real_level);
+ talloc_free(req_level);
+ talloc_free(real_level);
+ *(char **)arg = res;
return M_PROPERTY_OK;
+ default:;
+ return colormatrix_property_helper(prop, action, arg, mpctx);
}
- return M_PROPERTY_NOT_IMPLEMENTED;
+}
+
+static int mp_property_colormatrix_input_range(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ return levels_property_helper(offsetof(struct mp_csp_details, levels_in),
+ prop, action, arg, mpctx);
+}
+
+static int mp_property_colormatrix_output_range(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ return levels_property_helper(offsetof(struct mp_csp_details, levels_out),
+ prop, action, arg, mpctx);
}
static int mp_property_capture(m_option_t *prop, int action,
@@ -2267,8 +2334,12 @@ static const m_option_t mp_properties[] = {
M_OPT_RANGE, 0, 1, NULL },
{ "deinterlace", mp_property_deinterlace, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
- { "yuv_colorspace", mp_property_yuv_colorspace, CONF_TYPE_INT,
- M_OPT_RANGE, 0, 2, NULL },
+ { "colormatrix", mp_property_colormatrix, &m_option_type_choice,
+ 0, 0, 0, "colormatrix" },
+ { "colormatrix_input_range", mp_property_colormatrix_input_range, &m_option_type_choice,
+ 0, 0, 0, "colormatrix-input-range" },
+ { "colormatrix_output_range", mp_property_colormatrix_output_range, &m_option_type_choice,
+ 0, 0, 0, "colormatrix-output-range" },
{ "ontop", mp_property_ontop, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
{ "rootwin", mp_property_rootwin, CONF_TYPE_FLAG,
@@ -2430,7 +2501,9 @@ static struct property_osd_display {
{ "border", 0, -1, _("Border: %s") },
{ "framedropping", 0, -1, _("Framedropping: %s") },
{ "deinterlace", 0, -1, _("Deinterlace: %s") },
- { "yuv_colorspace", 0, -1, _("YUV colorspace: %s") },
+ { "colormatrix", 0, -1, _("YUV colormatrix: %s") },
+ { "colormatrix_input_range", 0, -1, _("YUV input range: %s") },
+ { "colormatrix_output_range", 0, -1, _("RGB output range: %s") },
{ "gamma", OSD_BRIGHTNESS, -1, _("Gamma") },
{ "brightness", OSD_BRIGHTNESS, -1, _("Brightness") },
{ "contrast", OSD_CONTRAST, -1, _("Contrast") },
@@ -2473,6 +2546,7 @@ static int show_property_osd(MPContext *mpctx, const char *pname)
for (p = property_osd_display; p->name; p++)
if (!strcmp(p->name, pname))
break;
+
if (!p->name)
return -1;