mirror of
https://github.com/mpv-player/mpv
synced 2025-05-08 03:05:15 +00:00
Reworked YUV2RGB fragment program setup in preparation for upcoming patches
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18620 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
82cb987e54
commit
0965bcee43
@ -607,65 +607,105 @@ static void glSetupYUVCombinersATI(float uvcos, float uvsin) {
|
|||||||
EndFragmentShader();
|
EndFragmentShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *bilin_filt_template =
|
||||||
|
"TEX yuv.%c, fragment.texcoord[%c], texture[%c], %s;";
|
||||||
|
|
||||||
static const char *yuv_prog_template =
|
static const char *yuv_prog_template =
|
||||||
"!!ARBfp1.0\n"
|
|
||||||
"OPTION ARB_precision_hint_fastest;"
|
|
||||||
"PARAM ycoef = {%.4f, %.4f, %.4f};"
|
"PARAM ycoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM ucoef = {%.4f, %.4f, %.4f};"
|
"PARAM ucoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM vcoef = {%.4f, %.4f, %.4f};"
|
"PARAM vcoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM offsets = {%.4f, %.4f, %.4f};"
|
"PARAM offsets = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM gamma = {%.4f, %.4f, %.4f};"
|
"TEMP res;"
|
||||||
"TEMP res, y, u, v;"
|
"MAD res.rgb, yuv.rrrr, ycoef, offsets;"
|
||||||
"TEX y, fragment.texcoord[0], texture[0], %s;"
|
"MAD res.rgb, yuv.gggg, ucoef, res;"
|
||||||
"MAD res, y, ycoef, offsets;"
|
"MAD result.color.rgb, yuv.bbbb, vcoef, res;"
|
||||||
"TEX u, fragment.texcoord[1], texture[1], %s;"
|
|
||||||
"MAD res, u, ucoef, res;"
|
|
||||||
"TEX v, fragment.texcoord[2], texture[2], %s;"
|
|
||||||
"MAD result.color, v, vcoef, res;"
|
|
||||||
"END";
|
"END";
|
||||||
|
|
||||||
static const char *yuv_pow_prog_template =
|
static const char *yuv_pow_prog_template =
|
||||||
"!!ARBfp1.0\n"
|
|
||||||
"OPTION ARB_precision_hint_fastest;"
|
|
||||||
"PARAM ycoef = {%.4f, %.4f, %.4f};"
|
"PARAM ycoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM ucoef = {%.4f, %.4f, %.4f};"
|
"PARAM ucoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM vcoef = {%.4f, %.4f, %.4f};"
|
"PARAM vcoef = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM offsets = {%.4f, %.4f, %.4f};"
|
"PARAM offsets = {%.4f, %.4f, %.4f};"
|
||||||
"PARAM gamma = {%.4f, %.4f, %.4f};"
|
"PARAM gamma = {%.4f, %.4f, %.4f};"
|
||||||
"TEMP res, y, u, v;"
|
"TEMP res;"
|
||||||
"TEX y, fragment.texcoord[0], texture[0], %s;"
|
"MAD res.rgb, yuv.rrrr, ycoef, offsets;"
|
||||||
"MAD res, y, ycoef, offsets;"
|
"MAD res.rgb, yuv.gggg, ucoef, res;"
|
||||||
"TEX u, fragment.texcoord[1], texture[1], %s;"
|
"MAD_SAT res.rgb, yuv.bbbb, vcoef, res;"
|
||||||
"MAD res, u, ucoef, res;"
|
|
||||||
"TEX v, fragment.texcoord[2], texture[2], %s;"
|
|
||||||
"MAD_SAT res, v, vcoef, res;"
|
|
||||||
"POW result.color.r, res.r, gamma.r;"
|
"POW result.color.r, res.r, gamma.r;"
|
||||||
"POW result.color.g, res.g, gamma.g;"
|
"POW result.color.g, res.g, gamma.g;"
|
||||||
"POW result.color.b, res.b, gamma.b;"
|
"POW result.color.b, res.b, gamma.b;"
|
||||||
"END";
|
"END";
|
||||||
|
|
||||||
static const char *yuv_lookup_prog_template =
|
static const char *yuv_lookup_prog_template =
|
||||||
"!!ARBfp1.0\n"
|
|
||||||
"OPTION ARB_precision_hint_fastest;"
|
|
||||||
"PARAM ycoef = {%.4f, %.4f, %.4f, 0};"
|
"PARAM ycoef = {%.4f, %.4f, %.4f, 0};"
|
||||||
"PARAM ucoef = {%.4f, %.4f, %.4f, 0};"
|
"PARAM ucoef = {%.4f, %.4f, %.4f, 0};"
|
||||||
"PARAM vcoef = {%.4f, %.4f, %.4f, 0};"
|
"PARAM vcoef = {%.4f, %.4f, %.4f, 0};"
|
||||||
"PARAM offsets = {%.4f, %.4f, %.4f, 0.125};"
|
"PARAM offsets = {%.4f, %.4f, %.4f, 0.125};"
|
||||||
"PARAM gamma = {%.4f, %.4f, %.4f};"
|
"TEMP res;"
|
||||||
"TEMP res, y, u, v;"
|
"MAD res, yuv.rrrr, ycoef, offsets;"
|
||||||
"TEX y, fragment.texcoord[0], texture[0], %s;"
|
"MAD res.rgb, yuv.gggg, ucoef, res;"
|
||||||
"MAD res, y, ycoef, offsets;"
|
"MAD res.rgb, yuv.bbbb, vcoef, res;"
|
||||||
"TEX u, fragment.texcoord[1], texture[1], %s;"
|
"TEX result.color.r, res.raaa, texture[%c], 2D;"
|
||||||
"MAD res, u, ucoef, res;"
|
|
||||||
"TEX v, fragment.texcoord[2], texture[2], %s;"
|
|
||||||
"MAD res, v, vcoef, res;"
|
|
||||||
"TEX result.color.r, res.raaa, texture[3], 2D;"
|
|
||||||
"ADD res.a, res.a, 0.25;"
|
"ADD res.a, res.a, 0.25;"
|
||||||
"TEX result.color.g, res.gaaa, texture[3], 2D;"
|
"TEX result.color.g, res.gaaa, texture[%c], 2D;"
|
||||||
"ADD res.a, res.a, 0.25;"
|
"ADD res.a, res.a, 0.25;"
|
||||||
"TEX result.color.b, res.baaa, texture[3], 2D;"
|
"TEX result.color.b, res.baaa, texture[%c], 2D;"
|
||||||
"END";
|
"END";
|
||||||
|
|
||||||
|
static void create_scaler_textures(int scaler, int *texu, char *texs) {
|
||||||
|
switch (scaler) {
|
||||||
|
case YUV_SCALER_BILIN:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_gamma_map(unsigned char *map, int size, float gamma);
|
||||||
|
|
||||||
|
//! resolution of texture for gamma lookup table
|
||||||
|
#define LOOKUP_RES 512
|
||||||
|
static void create_conv_textures(int conv, int *texu, char *texs,
|
||||||
|
int brightness, int contrast, int uvcos, int uvsin,
|
||||||
|
int rgamma, int ggamma, int bgamma) {
|
||||||
|
unsigned char *lookup_data = NULL;
|
||||||
|
switch (conv) {
|
||||||
|
case YUV_CONVERSION_FRAGMENT:
|
||||||
|
case YUV_CONVERSION_FRAGMENT_POW:
|
||||||
|
break;
|
||||||
|
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
||||||
|
texs[0] = (*texu)++;
|
||||||
|
ActiveTexture(GL_TEXTURE0 + texs[0]);
|
||||||
|
lookup_data = malloc(4 * LOOKUP_RES);
|
||||||
|
gen_gamma_map(lookup_data, LOOKUP_RES, rgamma);
|
||||||
|
gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, ggamma);
|
||||||
|
gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, bgamma);
|
||||||
|
glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LINEAR,
|
||||||
|
LOOKUP_RES, 4, 0);
|
||||||
|
glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data,
|
||||||
|
LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0);
|
||||||
|
ActiveTexture(GL_TEXTURE0);
|
||||||
|
texs[0] += '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv);
|
||||||
|
}
|
||||||
|
if (lookup_data)
|
||||||
|
free(lookup_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_scaler(int scaler, char **prog_pos, int *remain, char *texs,
|
||||||
|
char in_tex, char out_comp, int rect, int texw, int texh) {
|
||||||
|
switch (scaler) {
|
||||||
|
case YUV_SCALER_BILIN:
|
||||||
|
snprintf(*prog_pos, *remain, bilin_filt_template, out_comp, in_tex,
|
||||||
|
in_tex, rect ? "RECT" : "2D");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*remain -= strlen(*prog_pos);
|
||||||
|
*prog_pos += strlen(*prog_pos);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief setup a fragment program that will do YUV->RGB conversion
|
* \brief setup a fragment program that will do YUV->RGB conversion
|
||||||
* \param brightness brightness adjustment offset
|
* \param brightness brightness adjustment offset
|
||||||
@ -677,37 +717,48 @@ static const char *yuv_lookup_prog_template =
|
|||||||
*/
|
*/
|
||||||
static void glSetupYUVFragprog(float brightness, float contrast,
|
static void glSetupYUVFragprog(float brightness, float contrast,
|
||||||
float uvcos, float uvsin, float rgamma,
|
float uvcos, float uvsin, float rgamma,
|
||||||
float ggamma, float bgamma, int type, int rect) {
|
float ggamma, float bgamma, int type, int rect,
|
||||||
char yuv_prog[1000];
|
int texw, int texh) {
|
||||||
const char *prog_template = yuv_prog_template;
|
char yuv_prog[4000] =
|
||||||
char *tex_type = rect ? "RECT" : "2D";
|
"!!ARBfp1.0\n"
|
||||||
int lookup = 0;
|
"OPTION ARB_precision_hint_fastest;"
|
||||||
|
// all scaler variables must go here so they aren't defined
|
||||||
|
// multiple times when the same scaler is used more than once
|
||||||
|
"TEMP yuv;";
|
||||||
|
int prog_remain = sizeof(yuv_prog) - strlen(yuv_prog);
|
||||||
|
char *prog_pos = &yuv_prog[strlen(yuv_prog)];
|
||||||
|
int cur_texu = 3;
|
||||||
|
char lum_scale_texs[1];
|
||||||
|
char chrom_scale_texs[1];
|
||||||
|
char conv_texs[1];
|
||||||
GLint i;
|
GLint i;
|
||||||
// this is the conversion matrix, with y, u, v factors
|
// this is the conversion matrix, with y, u, v factors
|
||||||
// for red, green, blue and the constant offsets
|
// for red, green, blue and the constant offsets
|
||||||
float ry, ru, rv, rc;
|
float ry, ru, rv, rc;
|
||||||
float gy, gu, gv, gc;
|
float gy, gu, gv, gc;
|
||||||
float by, bu, bv, bc;
|
float by, bu, bv, bc;
|
||||||
switch (type) {
|
create_scaler_textures(YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs);
|
||||||
case YUV_CONVERSION_FRAGMENT_POW:
|
if (YUV_CHROM_SCALER(type) == YUV_LUM_SCALER(type))
|
||||||
prog_template = yuv_pow_prog_template;
|
memcpy(chrom_scale_texs, lum_scale_texs, sizeof(chrom_scale_texs));
|
||||||
break;
|
else
|
||||||
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
create_scaler_textures(YUV_CHROM_SCALER(type), &cur_texu, chrom_scale_texs);
|
||||||
prog_template = yuv_lookup_prog_template;
|
create_conv_textures(YUV_CONVERSION(type), &cur_texu, conv_texs,
|
||||||
lookup = 1;
|
brightness, contrast, uvcos, uvsin, rgamma, ggamma, bgamma);
|
||||||
break;
|
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &i);
|
||||||
}
|
if (i < cur_texu)
|
||||||
glGetIntegerv (GL_MAX_TEXTURE_UNITS, &i);
|
|
||||||
if (i < 3)
|
|
||||||
mp_msg(MSGT_VO, MSGL_ERR,
|
mp_msg(MSGT_VO, MSGL_ERR,
|
||||||
"[gl] 3 texture units needed for YUV fragment support (found %i)\n", i);
|
"[gl] %i texture units needed for this type of YUV fragment support (found %i)\n",
|
||||||
if (lookup && i < 4)
|
cur_texu, i);
|
||||||
mp_msg(MSGT_VO, MSGL_ERR,
|
|
||||||
"[gl] 4 texture units needed for YUV fragment support with lookup (found %i)\n", i);
|
|
||||||
if (!ProgramString) {
|
if (!ProgramString) {
|
||||||
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] ProgramString function missing!\n");
|
mp_msg(MSGT_VO, MSGL_FATAL, "[gl] ProgramString function missing!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
add_scaler(YUV_LUM_SCALER(type), &prog_pos, &prog_remain, lum_scale_texs,
|
||||||
|
'0', 'r', rect, texw, texh);
|
||||||
|
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
||||||
|
'1', 'g', rect, texw / 2, texh / 2);
|
||||||
|
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
|
||||||
|
'2', 'b', rect, texw / 2, texh / 2);
|
||||||
ry = 1.164 * contrast;
|
ry = 1.164 * contrast;
|
||||||
gy = 1.164 * contrast;
|
gy = 1.164 * contrast;
|
||||||
by = 1.164 * contrast;
|
by = 1.164 * contrast;
|
||||||
@ -725,11 +776,26 @@ static void glSetupYUVFragprog(float brightness, float contrast,
|
|||||||
rc += 0.5 - contrast / 2.0;
|
rc += 0.5 - contrast / 2.0;
|
||||||
gc += 0.5 - contrast / 2.0;
|
gc += 0.5 - contrast / 2.0;
|
||||||
bc += 0.5 - contrast / 2.0;
|
bc += 0.5 - contrast / 2.0;
|
||||||
rgamma = 1.0 / rgamma;
|
switch (YUV_CONVERSION(type)) {
|
||||||
ggamma = 1.0 / ggamma;
|
case YUV_CONVERSION_FRAGMENT:
|
||||||
bgamma = 1.0 / bgamma;
|
snprintf(prog_pos, prog_remain, yuv_prog_template,
|
||||||
snprintf(yuv_prog, 1000, prog_template, ry, gy, by, ru, gu, bu, rv, gv, bv,
|
ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc);
|
||||||
rc, gc, bc, rgamma, bgamma, bgamma, tex_type, tex_type, tex_type);
|
break;
|
||||||
|
case YUV_CONVERSION_FRAGMENT_POW:
|
||||||
|
snprintf(prog_pos, prog_remain, yuv_pow_prog_template,
|
||||||
|
ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc,
|
||||||
|
(float)1.0 / rgamma, (float)1.0 / bgamma, (float)1.0 / bgamma);
|
||||||
|
break;
|
||||||
|
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
||||||
|
snprintf(prog_pos, prog_remain, yuv_lookup_prog_template,
|
||||||
|
ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc,
|
||||||
|
conv_texs[0], conv_texs[0], conv_texs[0]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mp_msg(MSGT_VO, MSGL_V, "[gl] generated fragment program:\n%s\n", yuv_prog);
|
||||||
ProgramString(GL_FRAGMENT_PROGRAM, GL_PROGRAM_FORMAT_ASCII,
|
ProgramString(GL_FRAGMENT_PROGRAM, GL_PROGRAM_FORMAT_ASCII,
|
||||||
strlen(yuv_prog), yuv_prog);
|
strlen(yuv_prog), yuv_prog);
|
||||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION, &i);
|
glGetIntegerv(GL_PROGRAM_ERROR_POSITION, &i);
|
||||||
@ -757,9 +823,6 @@ static void gen_gamma_map(unsigned char *map, int size, float gamma) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! resolution of texture for gamma lookup table
|
|
||||||
#define LOOKUP_RES 512
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief setup YUV->RGB conversion
|
* \brief setup YUV->RGB conversion
|
||||||
* \param target texture target for Y, U and V textures (e.g. GL_TEXTURE_2D)
|
* \param target texture target for Y, U and V textures (e.g. GL_TEXTURE_2D)
|
||||||
@ -776,10 +839,11 @@ static void gen_gamma_map(unsigned char *map, int size, float gamma) {
|
|||||||
void glSetupYUVConversion(GLenum target, int type,
|
void glSetupYUVConversion(GLenum target, int type,
|
||||||
float brightness, float contrast,
|
float brightness, float contrast,
|
||||||
float hue, float saturation,
|
float hue, float saturation,
|
||||||
float rgamma, float ggamma, float bgamma) {
|
float rgamma, float ggamma, float bgamma,
|
||||||
|
int texw, int texh) {
|
||||||
float uvcos = saturation * cos(hue);
|
float uvcos = saturation * cos(hue);
|
||||||
float uvsin = saturation * sin(hue);
|
float uvsin = saturation * sin(hue);
|
||||||
switch (type) {
|
switch (YUV_CONVERSION(type)) {
|
||||||
case YUV_CONVERSION_COMBINERS:
|
case YUV_CONVERSION_COMBINERS:
|
||||||
glSetupYUVCombiners(uvcos, uvsin);
|
glSetupYUVCombiners(uvcos, uvsin);
|
||||||
break;
|
break;
|
||||||
@ -787,24 +851,15 @@ void glSetupYUVConversion(GLenum target, int type,
|
|||||||
glSetupYUVCombinersATI(uvcos, uvsin);
|
glSetupYUVCombinersATI(uvcos, uvsin);
|
||||||
break;
|
break;
|
||||||
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
case YUV_CONVERSION_FRAGMENT_LOOKUP:
|
||||||
{
|
|
||||||
unsigned char lookup_data[4 * LOOKUP_RES];
|
|
||||||
gen_gamma_map(lookup_data, LOOKUP_RES, rgamma);
|
|
||||||
gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, ggamma);
|
|
||||||
gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, bgamma);
|
|
||||||
ActiveTexture(GL_TEXTURE3);
|
|
||||||
glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LINEAR,
|
|
||||||
LOOKUP_RES, 4, 0);
|
|
||||||
glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data,
|
|
||||||
LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0);
|
|
||||||
ActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
|
||||||
case YUV_CONVERSION_FRAGMENT:
|
case YUV_CONVERSION_FRAGMENT:
|
||||||
case YUV_CONVERSION_FRAGMENT_POW:
|
case YUV_CONVERSION_FRAGMENT_POW:
|
||||||
glSetupYUVFragprog(brightness, contrast, uvcos, uvsin,
|
glSetupYUVFragprog(brightness, contrast, uvcos, uvsin,
|
||||||
rgamma, ggamma, bgamma, type,
|
rgamma, ggamma, bgamma, type,
|
||||||
target == GL_TEXTURE_RECTANGLE);
|
target == GL_TEXTURE_RECTANGLE,
|
||||||
|
texw, texh);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,7 +871,7 @@ void glSetupYUVConversion(GLenum target, int type,
|
|||||||
*/
|
*/
|
||||||
void glEnableYUVConversion(GLenum target, int type) {
|
void glEnableYUVConversion(GLenum target, int type) {
|
||||||
if (type <= 0) return;
|
if (type <= 0) return;
|
||||||
switch (type) {
|
switch (YUV_CONVERSION(type)) {
|
||||||
case YUV_CONVERSION_COMBINERS:
|
case YUV_CONVERSION_COMBINERS:
|
||||||
ActiveTexture(GL_TEXTURE1);
|
ActiveTexture(GL_TEXTURE1);
|
||||||
glEnable(target);
|
glEnable(target);
|
||||||
@ -849,7 +904,7 @@ void glEnableYUVConversion(GLenum target, int type) {
|
|||||||
*/
|
*/
|
||||||
void glDisableYUVConversion(GLenum target, int type) {
|
void glDisableYUVConversion(GLenum target, int type) {
|
||||||
if (type <= 0) return;
|
if (type <= 0) return;
|
||||||
switch (type) {
|
switch (YUV_CONVERSION(type)) {
|
||||||
case YUV_CONVERSION_COMBINERS:
|
case YUV_CONVERSION_COMBINERS:
|
||||||
ActiveTexture(GL_TEXTURE1);
|
ActiveTexture(GL_TEXTURE1);
|
||||||
glDisable(target);
|
glDisable(target);
|
||||||
|
@ -223,11 +223,28 @@ void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
|
|||||||
#define YUV_CONVERSION_FRAGMENT_LOOKUP 4
|
#define YUV_CONVERSION_FRAGMENT_LOOKUP 4
|
||||||
//! use ATI specific register combiners ("fragment program")
|
//! use ATI specific register combiners ("fragment program")
|
||||||
#define YUV_CONVERSION_COMBINERS_ATI 5
|
#define YUV_CONVERSION_COMBINERS_ATI 5
|
||||||
|
//! use normal bilinear scaling for textures
|
||||||
|
#define YUV_SCALER_BILIN 0
|
||||||
|
//! mask for conversion type
|
||||||
|
#define YUV_CONVERSION_MASK 0xF
|
||||||
|
//! mask for scaler type
|
||||||
|
#define YUV_SCALER_MASK 0xF
|
||||||
|
//! shift value for luminance scaler type
|
||||||
|
#define YUV_LUM_SCALER_SHIFT 8
|
||||||
|
//! shift value for chrominance scaler type
|
||||||
|
#define YUV_CHROM_SCALER_SHIFT 12
|
||||||
|
//! extract conversion out of type
|
||||||
|
#define YUV_CONVERSION(t) (t & YUV_CONVERSION_MASK)
|
||||||
|
//! extract luminance scaler out of type
|
||||||
|
#define YUV_LUM_SCALER(t) ((t >> YUV_LUM_SCALER_SHIFT) & YUV_SCALER_MASK)
|
||||||
|
//! extract chrominance scaler out of type
|
||||||
|
#define YUV_CHROM_SCALER(t) ((t >> YUV_CHROM_SCALER_SHIFT) & YUV_SCALER_MASK)
|
||||||
/** \} */
|
/** \} */
|
||||||
void glSetupYUVConversion(GLenum target, int type,
|
void glSetupYUVConversion(GLenum target, int type,
|
||||||
float brightness, float contrast,
|
float brightness, float contrast,
|
||||||
float hue, float saturation,
|
float hue, float saturation,
|
||||||
float rgamma, float ggamma, float bgamma);
|
float rgamma, float ggamma, float bgamma,
|
||||||
|
int texw, int texh);
|
||||||
void glEnableYUVConversion(GLenum target, int type);
|
void glEnableYUVConversion(GLenum target, int type);
|
||||||
void glDisableYUVConversion(GLenum target, int type);
|
void glDisableYUVConversion(GLenum target, int type);
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ static int osd_color;
|
|||||||
|
|
||||||
static int use_aspect;
|
static int use_aspect;
|
||||||
static int use_yuv;
|
static int use_yuv;
|
||||||
|
static int lscale;
|
||||||
|
static int cscale;
|
||||||
|
static int yuvconvtype;
|
||||||
static int use_rectangle;
|
static int use_rectangle;
|
||||||
static int err_shown;
|
static int err_shown;
|
||||||
static uint32_t image_width;
|
static uint32_t image_width;
|
||||||
@ -156,8 +159,9 @@ static void update_yuvconv(void) {
|
|||||||
float rgamma = exp(log(8.0) * eq_rgamma / 100.0);
|
float rgamma = exp(log(8.0) * eq_rgamma / 100.0);
|
||||||
float ggamma = exp(log(8.0) * eq_ggamma / 100.0);
|
float ggamma = exp(log(8.0) * eq_ggamma / 100.0);
|
||||||
float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
|
float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
|
||||||
glSetupYUVConversion(gl_target, use_yuv, bri, cont, hue, sat,
|
glSetupYUVConversion(gl_target, yuvconvtype, bri, cont, hue, sat,
|
||||||
rgamma, ggamma, bgamma);
|
rgamma, ggamma, bgamma,
|
||||||
|
texture_width, texture_height);
|
||||||
if (custom_prog) {
|
if (custom_prog) {
|
||||||
FILE *f = fopen(custom_prog, "r");
|
FILE *f = fopen(custom_prog, "r");
|
||||||
if (!f)
|
if (!f)
|
||||||
@ -511,13 +515,13 @@ flip_page(void)
|
|||||||
|
|
||||||
glColor3f(1,1,1);
|
glColor3f(1,1,1);
|
||||||
if (image_format == IMGFMT_YV12)
|
if (image_format == IMGFMT_YV12)
|
||||||
glEnableYUVConversion(gl_target, use_yuv);
|
glEnableYUVConversion(gl_target, yuvconvtype);
|
||||||
glDrawTex(0, 0, image_width, image_height,
|
glDrawTex(0, 0, image_width, image_height,
|
||||||
0, 0, image_width, image_height,
|
0, 0, image_width, image_height,
|
||||||
texture_width, texture_height,
|
texture_width, texture_height,
|
||||||
use_rectangle == 1, image_format == IMGFMT_YV12, mpi_flipped);
|
use_rectangle == 1, image_format == IMGFMT_YV12, mpi_flipped);
|
||||||
if (image_format == IMGFMT_YV12)
|
if (image_format == IMGFMT_YV12)
|
||||||
glDisableYUVConversion(gl_target, use_yuv);
|
glDisableYUVConversion(gl_target, yuvconvtype);
|
||||||
|
|
||||||
if (osdtexCnt > 0) {
|
if (osdtexCnt > 0) {
|
||||||
// set special rendering parameters
|
// set special rendering parameters
|
||||||
@ -685,6 +689,8 @@ static opt_t subopts[] = {
|
|||||||
{"slice-height", OPT_ARG_INT, &slice_height, (opt_test_f)int_non_neg},
|
{"slice-height", OPT_ARG_INT, &slice_height, (opt_test_f)int_non_neg},
|
||||||
{"rectangle", OPT_ARG_INT, &use_rectangle,(opt_test_f)int_non_neg},
|
{"rectangle", OPT_ARG_INT, &use_rectangle,(opt_test_f)int_non_neg},
|
||||||
{"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg},
|
{"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg},
|
||||||
|
{"lscale", OPT_ARG_INT, &lscale, (opt_test_f)int_non_neg},
|
||||||
|
{"cscale", OPT_ARG_INT, &cscale, (opt_test_f)int_non_neg},
|
||||||
{"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL},
|
{"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL},
|
||||||
{"swapinterval", OPT_ARG_INT, &swap_interval,NULL},
|
{"swapinterval", OPT_ARG_INT, &swap_interval,NULL},
|
||||||
{"customprog", OPT_ARG_MSTRZ,&custom_prog, NULL},
|
{"customprog", OPT_ARG_MSTRZ,&custom_prog, NULL},
|
||||||
@ -702,6 +708,8 @@ static int preinit(const char *arg)
|
|||||||
scaled_osd = 0;
|
scaled_osd = 0;
|
||||||
use_aspect = 1;
|
use_aspect = 1;
|
||||||
use_yuv = 0;
|
use_yuv = 0;
|
||||||
|
lscale = 0;
|
||||||
|
cscale = 0;
|
||||||
use_rectangle = 0;
|
use_rectangle = 0;
|
||||||
use_glFinish = 0;
|
use_glFinish = 0;
|
||||||
swap_interval = 1;
|
swap_interval = 1;
|
||||||
@ -757,6 +765,7 @@ static int preinit(const char *arg)
|
|||||||
gl_target = GL_TEXTURE_2D;
|
gl_target = GL_TEXTURE_2D;
|
||||||
if (slice_height == -1)
|
if (slice_height == -1)
|
||||||
slice_height = use_yuv ? 16 : 4;
|
slice_height = use_yuv ? 16 : 4;
|
||||||
|
yuvconvtype = use_yuv | lscale << YUV_LUM_SCALER_SHIFT | cscale << YUV_CHROM_SCALER_SHIFT;
|
||||||
if (many_fmts)
|
if (many_fmts)
|
||||||
mp_msg (MSGT_VO, MSGL_INFO, "[gl] using extended formats. "
|
mp_msg (MSGT_VO, MSGL_INFO, "[gl] using extended formats. "
|
||||||
"Use -vo gl:nomanyfmts if playback fails.\n");
|
"Use -vo gl:nomanyfmts if playback fails.\n");
|
||||||
|
@ -773,7 +773,8 @@ static int initGl(uint32_t d_width, uint32_t d_height)
|
|||||||
BindProgram(GL_FRAGMENT_PROGRAM, fragprog);
|
BindProgram(GL_FRAGMENT_PROGRAM, fragprog);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
glSetupYUVConversion(GL_TEXTURE_2D, use_yuv, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0);
|
glSetupYUVConversion(GL_TEXTURE_2D, use_yuv, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
|
||||||
|
texture_width, texture_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_set_antialias(0);
|
gl_set_antialias(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user