1
mirror of https://github.com/mpv-player/mpv synced 2024-10-18 10:25:02 +02:00

Add bicubic texture scaling

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18623 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
reimar 2006-06-07 14:07:32 +00:00
parent fd77a846b8
commit 1b0b329dd7
3 changed files with 99 additions and 1 deletions

View File

@ -3077,6 +3077,16 @@ At least three texture units are needed.
Provides saturation and hue control. Provides saturation and hue control.
This method is fast but inexact. This method is fast but inexact.
.RE .RE
.IPs [l|c]scaler=<n>
Select the scaling function to use (seperately for luma and chroma).
Only valid for yuv modes 2, 3 and 4.
.RSss
0: Use simple linear filtering (default)
.br
1: Use bicubic filtering (better quality).
Older cards will not be able to handle this for chroma at least in fullscreen mode.
Also needs one additional texture unit.
.RE
.IPs customprog=<filename> .IPs customprog=<filename>
Load a custom fragment program from <filename>. Load a custom fragment program from <filename>.
See TOOLS/edgedect.fp for an example. See TOOLS/edgedect.fp for an example.

View File

@ -607,9 +607,78 @@ static void glSetupYUVCombinersATI(float uvcos, float uvsin) {
EndFragmentShader(); EndFragmentShader();
} }
static void store_weights(float x, GLfloat *dst) {
float w0 = (((-1 * x + 3) * x - 3) * x + 1) / 6;
float w1 = ((( 3 * x - 6) * x + 0) * x + 4) / 6;
float w2 = (((-3 * x + 3) * x + 3) * x + 1) / 6;
float w3 = ((( 1 * x + 0) * x + 0) * x + 0) / 6;
*dst++ = 1 + x - w1 / (w0 + w1);
*dst++ = 1 - x + w3 / (w2 + w3);
*dst++ = w0 + w1;
*dst++ = 0;
}
//! to avoid artefacts this should be rather large
#define LOOKUP_BSPLINE_RES (1024)
/**
* \brief creates the 1D lookup texture needed for fast higher-order filtering
* \param unit texture unit to attach texture to
*/
static void gen_spline_lookup_tex(GLenum unit) {
GLfloat tex[4 * (LOOKUP_BSPLINE_RES + 2)];
GLfloat *tp = &tex[4];
int i;
for (i = 0; i < LOOKUP_BSPLINE_RES; i++) {
float x = (float)(i + 0.5) / LOOKUP_BSPLINE_RES;
store_weights(x, tp);
tp += 4;
}
store_weights(0, tex);
store_weights(1, &tex[4 * (LOOKUP_BSPLINE_RES + 1)]);
ActiveTexture(unit);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16, LOOKUP_BSPLINE_RES + 2, 1, GL_RGBA, GL_FLOAT, tex);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_PRIORITY, 1.0);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
ActiveTexture(GL_TEXTURE0);
}
static const char *bilin_filt_template = static const char *bilin_filt_template =
"TEX yuv.%c, fragment.texcoord[%c], texture[%c], %s;"; "TEX yuv.%c, fragment.texcoord[%c], texture[%c], %s;";
#define BICUB_FILT_MAIN(textype) \
/* first y-interpolation */ \
"SUB coord.xy, fragment.texcoord[%c], parmx.rara;" \
"SUB coord.zw, coord.xyxy, parmy.arar;" \
"TEX a.r, coord.zwzw, texture[%c], "textype";" \
"ADD coord.zw, coord.xyxy, parmy.agag;" \
"TEX a.g, coord.zwzw, texture[%c], "textype";" \
"LRP a.b, parmy.b, a.rrrr, a.gggg;" \
/* second y-interpolation */ \
"ADD coord.xy, fragment.texcoord[%c], parmx.gaga;" \
"SUB coord.zw, coord.xyxy, parmy.arar;" \
"TEX a.r, coord.zwzw, texture[%c], "textype";" \
"ADD coord.zw, coord.xyxy, parmy.agag;" \
"TEX a.g, coord.zwzw, texture[%c], "textype";" \
"LRP a.a, parmy.b, a.rrrr, a.gggg;" \
/* x-interpolation */ \
"LRP yuv.%c, parmx.b, a.bbbb, a.aaaa;"
static const char *bicub_filt_template_2D =
"MAD coord.xy, fragment.texcoord[%c], {%f, %f}, {0.5, 0.5};"
"TEX parmx, coord.x, texture[%c], 1D;"
"MUL parmx.rg, parmx, {%f, %f};"
"TEX parmy, coord.y, texture[%c], 1D;"
"MUL parmy.rg, parmy, {%f, %f};"
BICUB_FILT_MAIN("2D");
static const char *bicub_filt_template_RECT =
"ADD coord, fragment.texcoord[%c], {0.5, 0.5};"
"TEX parmx, coord.x, texture[%c], 1D;"
"TEX parmy, coord.y, texture[%c], 1D;"
BICUB_FILT_MAIN("RECT");
static const char *yuv_prog_template = static const char *yuv_prog_template =
"PARAM ycoef = {%.4f, %.4f, %.4f};" "PARAM ycoef = {%.4f, %.4f, %.4f};"
"PARAM ucoef = {%.4f, %.4f, %.4f};" "PARAM ucoef = {%.4f, %.4f, %.4f};"
@ -656,6 +725,11 @@ static void create_scaler_textures(int scaler, int *texu, char *texs) {
switch (scaler) { switch (scaler) {
case YUV_SCALER_BILIN: case YUV_SCALER_BILIN:
break; break;
case YUV_SCALER_BICUB:
texs[0] = (*texu)++;
gen_spline_lookup_tex(GL_TEXTURE0 + texs[0]);
texs[0] += '0';
break;
default: default:
mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler); mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler);
} }
@ -701,6 +775,18 @@ static void add_scaler(int scaler, char **prog_pos, int *remain, char *texs,
snprintf(*prog_pos, *remain, bilin_filt_template, out_comp, in_tex, snprintf(*prog_pos, *remain, bilin_filt_template, out_comp, in_tex,
in_tex, rect ? "RECT" : "2D"); in_tex, rect ? "RECT" : "2D");
break; break;
case YUV_SCALER_BICUB:
if (rect)
snprintf(*prog_pos, *remain, bicub_filt_template_RECT,
in_tex, texs[0], texs[0],
in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp);
else
snprintf(*prog_pos, *remain, bicub_filt_template_2D,
in_tex, (float)texw, (float)texh,
texs[0], (float)1.0 / texw, (float)1.0 / texw,
texs[0], (float)1.0 / texh, (float)1.0 / texh,
in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp);
break;
} }
*remain -= strlen(*prog_pos); *remain -= strlen(*prog_pos);
*prog_pos += strlen(*prog_pos); *prog_pos += strlen(*prog_pos);
@ -724,7 +810,7 @@ static void glSetupYUVFragprog(float brightness, float contrast,
"OPTION ARB_precision_hint_fastest;" "OPTION ARB_precision_hint_fastest;"
// all scaler variables must go here so they aren't defined // all scaler variables must go here so they aren't defined
// multiple times when the same scaler is used more than once // multiple times when the same scaler is used more than once
"TEMP yuv;"; "TEMP coord, parmx, parmy, a, yuv;";
int prog_remain = sizeof(yuv_prog) - strlen(yuv_prog); int prog_remain = sizeof(yuv_prog) - strlen(yuv_prog);
char *prog_pos = &yuv_prog[strlen(yuv_prog)]; char *prog_pos = &yuv_prog[strlen(yuv_prog)];
int cur_texu = 3; int cur_texu = 3;

View File

@ -225,6 +225,8 @@ void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
#define YUV_CONVERSION_COMBINERS_ATI 5 #define YUV_CONVERSION_COMBINERS_ATI 5
//! use normal bilinear scaling for textures //! use normal bilinear scaling for textures
#define YUV_SCALER_BILIN 0 #define YUV_SCALER_BILIN 0
//! use higher quality bicubic scaling for textures
#define YUV_SCALER_BICUB 1
//! mask for conversion type //! mask for conversion type
#define YUV_CONVERSION_MASK 0xF #define YUV_CONVERSION_MASK 0xF
//! mask for scaler type //! mask for scaler type