mirror of
https://github.com/mpv-player/mpv
synced 2025-01-09 01:36:25 +01:00
Simplify and and speedup generation of yuv2rgb and gamma map tables
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19172 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
a759a80397
commit
da1390fcc0
@ -759,36 +759,69 @@ static void create_scaler_textures(int scaler, int *texu, char *texs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_gamma_map(unsigned char *map, int size, float gamma);
|
||||||
|
|
||||||
|
static void get_yuv2rgb_coeffs(float brightness, float contrast, float uvcos, float uvsin,
|
||||||
|
float *ry, float *ru, float *rv, float *rc,
|
||||||
|
float *gy, float *gu, float *gv, float *gc,
|
||||||
|
float *by, float *bu, float *bv, float *bc) {
|
||||||
|
*ry = 1.164 * contrast;
|
||||||
|
*gy = 1.164 * contrast;
|
||||||
|
*by = 1.164 * contrast;
|
||||||
|
*ru = 0 * uvcos + 1.596 * uvsin;
|
||||||
|
*rv = 0 * uvsin + 1.596 * uvcos;
|
||||||
|
*gu = -0.391 * uvcos + -0.813 * uvsin;
|
||||||
|
*gv = -0.391 * uvsin + -0.813 * uvcos;
|
||||||
|
*bu = 2.018 * uvcos + 0 * uvsin;
|
||||||
|
*bv = 2.018 * uvsin + 0 * uvcos;
|
||||||
|
*rc = (-16 * *ry + (-128) * *ru + (-128) * *rv) / 255.0 + brightness;
|
||||||
|
*gc = (-16 * *gy + (-128) * *gu + (-128) * *gv) / 255.0 + brightness;
|
||||||
|
*bc = (-16 * *by + (-128) * *bu + (-128) * *bv) / 255.0 + brightness;
|
||||||
|
// these "center" contrast control so that e.g. a contrast of 0
|
||||||
|
// leads to a grey image, not a black one
|
||||||
|
*rc += 0.5 - contrast / 2.0;
|
||||||
|
*gc += 0.5 - contrast / 2.0;
|
||||||
|
*bc += 0.5 - contrast / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GMAP_SIZE (1024)
|
||||||
static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness,
|
static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness,
|
||||||
float contrast, float uvcos, float uvsin,
|
float contrast, float uvcos, float uvsin,
|
||||||
float rgamma, float ggamma, float bgamma) {
|
float rgamma, float ggamma, float bgamma) {
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
float step = 1.0 / size;
|
float step = 1.0 / size;
|
||||||
float y, u, v, u_, v_;
|
float y, u, v;
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
v = -0.5;
|
float ry, ru, rv, rc;
|
||||||
|
float gy, gu, gv, gc;
|
||||||
|
float by, bu, bv, bc;
|
||||||
|
unsigned char gmaps[3][GMAP_SIZE];
|
||||||
|
gen_gamma_map(gmaps[0], GMAP_SIZE, rgamma);
|
||||||
|
gen_gamma_map(gmaps[1], GMAP_SIZE, ggamma);
|
||||||
|
gen_gamma_map(gmaps[2], GMAP_SIZE, bgamma);
|
||||||
|
get_yuv2rgb_coeffs(brightness, contrast, uvcos, uvsin,
|
||||||
|
&ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc);
|
||||||
|
ry *= GMAP_SIZE - 1; ru *= GMAP_SIZE - 1; rv *= GMAP_SIZE - 1; rc *= GMAP_SIZE - 1;
|
||||||
|
gy *= GMAP_SIZE - 1; gu *= GMAP_SIZE - 1; gv *= GMAP_SIZE - 1; gc *= GMAP_SIZE - 1;
|
||||||
|
by *= GMAP_SIZE - 1; bu *= GMAP_SIZE - 1; bv *= GMAP_SIZE - 1; bc *= GMAP_SIZE - 1;
|
||||||
|
v = 0;
|
||||||
for (i = -1; i <= size; i++) {
|
for (i = -1; i <= size; i++) {
|
||||||
u = -0.5;
|
u = 0;
|
||||||
for (j = -1; j <= size; j++) {
|
for (j = -1; j <= size; j++) {
|
||||||
y = -(16.0 / 255.0);
|
y = 0;
|
||||||
for (k = -1; k <= size; k++) {
|
for (k = -1; k <= size; k++) {
|
||||||
u_ = uvcos * u + uvsin * v;
|
r = ry * y + ru * u + rv * v + rc;
|
||||||
v_ = uvcos * v + uvsin * u;
|
g = gy * y + gu * u + gv * v + gc;
|
||||||
r = 1.164 * y + 1.596 * v_;
|
b = by * y + bu * u + bv * v + bc;
|
||||||
g = 1.164 * y - 0.391 * u_ - 0.813 * v_;
|
if (r > GMAP_SIZE - 1) r = GMAP_SIZE - 1;
|
||||||
b = 1.164 * y + 2.018 * u_ ;
|
|
||||||
r = pow(contrast * (r - 0.5) + 0.5 + brightness, 1.0 / rgamma);
|
|
||||||
g = pow(contrast * (g - 0.5) + 0.5 + brightness, 1.0 / ggamma);
|
|
||||||
b = pow(contrast * (b - 0.5) + 0.5 + brightness, 1.0 / bgamma);
|
|
||||||
if (r > 1) r = 1;
|
|
||||||
if (r < 0) r = 0;
|
if (r < 0) r = 0;
|
||||||
if (g > 1) g = 1;
|
if (g > GMAP_SIZE - 1) g = GMAP_SIZE - 1;
|
||||||
if (g < 0) g = 0;
|
if (g < 0) g = 0;
|
||||||
if (b > 1) b = 1;
|
if (b > GMAP_SIZE - 1) b = GMAP_SIZE - 1;
|
||||||
if (b < 0) b = 0;
|
if (b < 0) b = 0;
|
||||||
*map++ = 255 * r;
|
*map++ = gmaps[0][(int)r];
|
||||||
*map++ = 255 * g;
|
*map++ = gmaps[1][(int)g];
|
||||||
*map++ = 255 * b;
|
*map++ = gmaps[2][(int)b];
|
||||||
y += (k == -1 || k == size - 1) ? step / 2 : step;
|
y += (k == -1 || k == size - 1) ? step / 2 : step;
|
||||||
}
|
}
|
||||||
u += (j == -1 || j == size - 1) ? step / 2 : step;
|
u += (j == -1 || j == size - 1) ? step / 2 : step;
|
||||||
@ -797,8 +830,6 @@ static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_gamma_map(unsigned char *map, int size, float gamma);
|
|
||||||
|
|
||||||
//! resolution of texture for gamma lookup table
|
//! resolution of texture for gamma lookup table
|
||||||
#define LOOKUP_RES 512
|
#define LOOKUP_RES 512
|
||||||
//! resolution for 3D yuv->rgb conversion lookup table
|
//! resolution for 3D yuv->rgb conversion lookup table
|
||||||
@ -985,23 +1016,8 @@ static void glSetupYUVFragprog(float brightness, float contrast,
|
|||||||
'1', 'g', rect, texw / 2, texh / 2);
|
'1', 'g', rect, texw / 2, texh / 2);
|
||||||
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
||||||
'2', 'b', rect, texw / 2, texh / 2);
|
'2', 'b', rect, texw / 2, texh / 2);
|
||||||
ry = 1.164 * contrast;
|
get_yuv2rgb_coeffs(brightness, contrast, uvcos, uvsin,
|
||||||
gy = 1.164 * contrast;
|
&ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc);
|
||||||
by = 1.164 * contrast;
|
|
||||||
ru = 0 * uvcos + 1.596 * uvsin;
|
|
||||||
rv = 0 * uvsin + 1.596 * uvcos;
|
|
||||||
gu = -0.391 * uvcos + -0.813 * uvsin;
|
|
||||||
gv = -0.391 * uvsin + -0.813 * uvcos;
|
|
||||||
bu = 2.018 * uvcos + 0 * uvsin;
|
|
||||||
bv = 2.018 * uvsin + 0 * uvcos;
|
|
||||||
rc = (-16 * ry + (-128) * ru + (-128) * rv) / 255.0 + brightness;
|
|
||||||
gc = (-16 * gy + (-128) * gu + (-128) * gv) / 255.0 + brightness;
|
|
||||||
bc = (-16 * by + (-128) * bu + (-128) * bv) / 255.0 + brightness;
|
|
||||||
// these "center" contrast control so that e.g. a contrast of 0
|
|
||||||
// leads to a grey image, not a black one
|
|
||||||
rc += 0.5 - contrast / 2.0;
|
|
||||||
gc += 0.5 - contrast / 2.0;
|
|
||||||
bc += 0.5 - contrast / 2.0;
|
|
||||||
switch (YUV_CONVERSION(type)) {
|
switch (YUV_CONVERSION(type)) {
|
||||||
case YUV_CONVERSION_FRAGMENT:
|
case YUV_CONVERSION_FRAGMENT:
|
||||||
snprintf(prog_pos, prog_remain, yuv_prog_template,
|
snprintf(prog_pos, prog_remain, yuv_prog_template,
|
||||||
@ -1036,6 +1052,11 @@ static void glSetupYUVFragprog(float brightness, float contrast,
|
|||||||
*/
|
*/
|
||||||
static void gen_gamma_map(unsigned char *map, int size, float gamma) {
|
static void gen_gamma_map(unsigned char *map, int size, float gamma) {
|
||||||
int i;
|
int i;
|
||||||
|
if (gamma == 1.0) {
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
map[i] = 255 * i / (size - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
gamma = 1.0 / gamma;
|
gamma = 1.0 / gamma;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
float tmp = (float)i / (size - 1.0);
|
float tmp = (float)i / (size - 1.0);
|
||||||
|
Loading…
Reference in New Issue
Block a user