summaryrefslogtreecommitdiffstats
path: root/libvo/csputils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/csputils.c')
-rw-r--r--libvo/csputils.c98
1 files changed, 88 insertions, 10 deletions
diff --git a/libvo/csputils.c b/libvo/csputils.c
index 831e5c774a..6656e5e196 100644
--- a/libvo/csputils.c
+++ b/libvo/csputils.c
@@ -32,6 +32,27 @@
#include "csputils.h"
+char * const mp_csp_names[MP_CSP_COUNT] = {
+ "Autoselect",
+ "BT.601 (SD)",
+ "BT.709 (HD)",
+ "SMPTE-240M",
+};
+
+char * const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = {
+ "brightness",
+ "contrast",
+ "hue",
+ "saturation",
+ "gamma",
+};
+
+
+enum mp_csp mp_csp_guess_colorspace(int width, int height)
+{
+ return width >= 1280 || height > 576 ? MP_CSP_BT_709 : MP_CSP_BT_601;
+}
+
/**
* \brief little helper function to create a lookup table for gamma
* \param map buffer to create map into
@@ -98,8 +119,8 @@ static void luma_coeffs(float m[3][4], float lr, float lg, float lb)
*/
void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4])
{
- int format = params->format;
- if (format <= MP_CSP_DEFAULT || format >= MP_CSP_COUNT)
+ int format = params->colorspace.format;
+ if (format <= MP_CSP_AUTO || format >= MP_CSP_COUNT)
format = MP_CSP_BT_601;
switch (format) {
case MP_CSP_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
@@ -119,25 +140,35 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4])
m[i][COL_V] = huesin * u + huecos * m[i][COL_V];
}
- int levelconv = params->levelconv;
- if (levelconv < 0 || levelconv >= MP_CSP_LEVELCONV_COUNT)
- levelconv = MP_CSP_LEVELCONV_TV_TO_PC;
+ int levels_in = params->colorspace.levels_in;
+ if (levels_in <= MP_CSP_LEVELS_AUTO || levels_in >= MP_CSP_LEVELS_COUNT)
+ levels_in = MP_CSP_LEVELS_TV;
// The values below are written in 0-255 scale
struct yuvlevels { double ymin, ymax, cmin, cmid; }
yuvlim = { 16, 235, 16, 128 },
- yuvfull = { 16, 235, 1, 128 }, // '1' to make it symmetric around 128
+ yuvfull = { 0, 255, 1, 128 }, // '1' to make it symmetric around 128
yuvlev;
+ switch (levels_in) {
+ case MP_CSP_LEVELS_TV: yuvlev = yuvlim; break;
+ case MP_CSP_LEVELS_PC: yuvlev = yuvfull; break;
+ default:
+ abort();
+ }
+
+ int levels_out = params->colorspace.levels_out;
+ if (levels_out <= MP_CSP_LEVELS_AUTO || levels_out >= MP_CSP_LEVELS_COUNT)
+ levels_out = MP_CSP_LEVELS_PC;
struct rgblevels { double min, max; }
rgblim = { 16, 235 },
rgbfull = { 0, 255 },
rgblev;
- switch (levelconv) {
- case MP_CSP_LEVELCONV_TV_TO_PC: yuvlev = yuvlim; rgblev = rgbfull; break;
- case MP_CSP_LEVELCONV_PC_TO_TV: yuvlev = yuvfull; rgblev = rgblim; break;
- case MP_CSP_LEVELCONV_TV_TO_TV: yuvlev = yuvlim; rgblev = rgblim; break;
+ switch (levels_out) {
+ case MP_CSP_LEVELS_TV: rgblev = rgblim; break;
+ case MP_CSP_LEVELS_PC: rgblev = rgbfull; break;
default:
abort();
}
+
double ymul = (rgblev.max - rgblev.min) / (yuvlev.ymax - yuvlev.ymin);
double cmul = (rgblev.max - rgblev.min) / (yuvlev.cmid - yuvlev.cmin) / 2;
for (int i = 0; i < 3; i++) {
@@ -205,3 +236,50 @@ void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int si
v += (i == -1 || i == size - 1) ? step / 2 : step;
}
}
+
+// Copy settings from eq into params.
+void mp_csp_copy_equalizer_values(struct mp_csp_params *params,
+ const struct mp_csp_equalizer *eq)
+{
+ params->brightness = eq->values[MP_CSP_EQ_BRIGHTNESS] / 100.0;
+ params->contrast = (eq->values[MP_CSP_EQ_CONTRAST] + 100) / 100.0;
+ params->hue = eq->values[MP_CSP_EQ_HUE] / 100.0 * 3.1415927;
+ params->saturation = (eq->values[MP_CSP_EQ_SATURATION] + 100) / 100.0;
+ float gamma = exp(log(8.0) * eq->values[MP_CSP_EQ_GAMMA] / 100.0);
+ params->rgamma = gamma;
+ params->ggamma = gamma;
+ params->bgamma = gamma;
+}
+
+static int find_eq(int capabilities, const char *name)
+{
+ for (int i = 0; i < MP_CSP_EQ_COUNT; i++) {
+ if (strcmp(name, mp_csp_equalizer_names[i]) == 0)
+ return ((1 << i) & capabilities) ? i : -1;
+ }
+ return -1;
+}
+
+int mp_csp_equalizer_get(struct mp_csp_equalizer *eq, const char *property,
+ int *out_value)
+{
+ int index = find_eq(eq->capabilities, property);
+ if (index < 0)
+ return -1;
+
+ *out_value = eq->values[index];
+
+ return 0;
+}
+
+int mp_csp_equalizer_set(struct mp_csp_equalizer *eq, const char *property,
+ int value)
+{
+ int index = find_eq(eq->capabilities, property);
+ if (index < 0)
+ return 0;
+
+ eq->values[index] = value;
+
+ return 1;
+}