comparison libvo/gl_common.c @ 26834:aadfce1c25c8

Use a struct instead of a huge and further growing argument list.
author reimar
date Sat, 24 May 2008 11:03:00 +0000
parents 802c489f77f0
children ba086caf1230
comparison
equal deleted inserted replaced
26833:77003eb2d9a8 26834:aadfce1c25c8
864 } 864 }
865 } 865 }
866 866
867 static void gen_gamma_map(unsigned char *map, int size, float gamma); 867 static void gen_gamma_map(unsigned char *map, int size, float gamma);
868 868
869 static void get_yuv2rgb_coeffs(float brightness, float contrast, float uvcos, float uvsin, 869 static void get_yuv2rgb_coeffs(gl_conversion_params_t *params,
870 float *ry, float *ru, float *rv, float *rc, 870 float *ry, float *ru, float *rv, float *rc,
871 float *gy, float *gu, float *gv, float *gc, 871 float *gy, float *gu, float *gv, float *gc,
872 float *by, float *bu, float *bv, float *bc) { 872 float *by, float *bu, float *bv, float *bc) {
873 *ry = 1.164 * contrast; 873 float uvcos = params->saturation * cos(params->hue);
874 *gy = 1.164 * contrast; 874 float uvsin = params->saturation * sin(params->hue);
875 *by = 1.164 * contrast; 875 *ry = 1.164 * params->contrast;
876 *gy = 1.164 * params->contrast;
877 *by = 1.164 * params->contrast;
876 *ru = 0 * uvcos + 1.596 * uvsin; 878 *ru = 0 * uvcos + 1.596 * uvsin;
877 *rv = 0 * uvsin + 1.596 * uvcos; 879 *rv = 0 * uvsin + 1.596 * uvcos;
878 *gu = -0.391 * uvcos + -0.813 * uvsin; 880 *gu = -0.391 * uvcos + -0.813 * uvsin;
879 *gv = -0.391 * uvsin + -0.813 * uvcos; 881 *gv = -0.391 * uvsin + -0.813 * uvcos;
880 *bu = 2.018 * uvcos + 0 * uvsin; 882 *bu = 2.018 * uvcos + 0 * uvsin;
881 *bv = 2.018 * uvsin + 0 * uvcos; 883 *bv = 2.018 * uvsin + 0 * uvcos;
882 *rc = (-16 * *ry + (-128) * *ru + (-128) * *rv) / 255.0 + brightness; 884 *rc = (-16 * *ry + (-128) * *ru + (-128) * *rv) / 255.0 + params->brightness;
883 *gc = (-16 * *gy + (-128) * *gu + (-128) * *gv) / 255.0 + brightness; 885 *gc = (-16 * *gy + (-128) * *gu + (-128) * *gv) / 255.0 + params->brightness;
884 *bc = (-16 * *by + (-128) * *bu + (-128) * *bv) / 255.0 + brightness; 886 *bc = (-16 * *by + (-128) * *bu + (-128) * *bv) / 255.0 + params->brightness;
885 // these "center" contrast control so that e.g. a contrast of 0 887 // these "center" contrast control so that e.g. a contrast of 0
886 // leads to a grey image, not a black one 888 // leads to a grey image, not a black one
887 *rc += 0.5 - contrast / 2.0; 889 *rc += 0.5 - params->contrast / 2.0;
888 *gc += 0.5 - contrast / 2.0; 890 *gc += 0.5 - params->contrast / 2.0;
889 *bc += 0.5 - contrast / 2.0; 891 *bc += 0.5 - params->contrast / 2.0;
890 } 892 }
891 893
892 //! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map 894 //! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map
893 #define GMAP_SIZE (1024) 895 #define GMAP_SIZE (1024)
894 /** 896 /**
901 * \param uvsin desired hue/saturation adjustment for conversion 903 * \param uvsin desired hue/saturation adjustment for conversion
902 * \param rgamma desired red gamma adjustment for conversion 904 * \param rgamma desired red gamma adjustment for conversion
903 * \param ggamma desired green gamma adjustment for conversion 905 * \param ggamma desired green gamma adjustment for conversion
904 * \param bgamma desired blue gamma adjustment for conversion 906 * \param bgamma desired blue gamma adjustment for conversion
905 */ 907 */
906 static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness, 908 static void gen_yuv2rgb_map(gl_conversion_params_t *params, unsigned char *map, int size) {
907 float contrast, float uvcos, float uvsin,
908 float rgamma, float ggamma, float bgamma) {
909 int i, j, k; 909 int i, j, k;
910 float step = 1.0 / size; 910 float step = 1.0 / size;
911 float y, u, v; 911 float y, u, v;
912 float r, g, b; 912 float r, g, b;
913 float ry, ru, rv, rc; 913 float ry, ru, rv, rc;
914 float gy, gu, gv, gc; 914 float gy, gu, gv, gc;
915 float by, bu, bv, bc; 915 float by, bu, bv, bc;
916 unsigned char gmaps[3][GMAP_SIZE]; 916 unsigned char gmaps[3][GMAP_SIZE];
917 gen_gamma_map(gmaps[0], GMAP_SIZE, rgamma); 917 gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma);
918 gen_gamma_map(gmaps[1], GMAP_SIZE, ggamma); 918 gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma);
919 gen_gamma_map(gmaps[2], GMAP_SIZE, bgamma); 919 gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma);
920 get_yuv2rgb_coeffs(brightness, contrast, uvcos, uvsin, 920 get_yuv2rgb_coeffs(params,
921 &ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc); 921 &ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc);
922 ry *= GMAP_SIZE - 1; ru *= GMAP_SIZE - 1; rv *= GMAP_SIZE - 1; rc *= GMAP_SIZE - 1; 922 ry *= GMAP_SIZE - 1; ru *= GMAP_SIZE - 1; rv *= GMAP_SIZE - 1; rc *= GMAP_SIZE - 1;
923 gy *= GMAP_SIZE - 1; gu *= GMAP_SIZE - 1; gv *= GMAP_SIZE - 1; gc *= GMAP_SIZE - 1; 923 gy *= GMAP_SIZE - 1; gu *= GMAP_SIZE - 1; gv *= GMAP_SIZE - 1; gc *= GMAP_SIZE - 1;
924 by *= GMAP_SIZE - 1; bu *= GMAP_SIZE - 1; bv *= GMAP_SIZE - 1; bc *= GMAP_SIZE - 1; 924 by *= GMAP_SIZE - 1; bu *= GMAP_SIZE - 1; bv *= GMAP_SIZE - 1; bc *= GMAP_SIZE - 1;
925 v = 0; 925 v = 0;
962 * \param uvsin desired hue/saturation adjustment for conversion 962 * \param uvsin desired hue/saturation adjustment for conversion
963 * \param rgamma desired red gamma adjustment for conversion 963 * \param rgamma desired red gamma adjustment for conversion
964 * \param ggamma desired green gamma adjustment for conversion 964 * \param ggamma desired green gamma adjustment for conversion
965 * \param bgamma desired blue gamma adjustment for conversion 965 * \param bgamma desired blue gamma adjustment for conversion
966 */ 966 */
967 static void create_conv_textures(int conv, int *texu, char *texs, 967 static void create_conv_textures(gl_conversion_params_t *params, int *texu, char *texs) {
968 float brightness, float contrast, float uvcos, float uvsin,
969 float rgamma, float ggamma, float bgamma) {
970 unsigned char *lookup_data = NULL; 968 unsigned char *lookup_data = NULL;
969 int conv = YUV_CONVERSION(params->type);
971 switch (conv) { 970 switch (conv) {
972 case YUV_CONVERSION_FRAGMENT: 971 case YUV_CONVERSION_FRAGMENT:
973 case YUV_CONVERSION_FRAGMENT_POW: 972 case YUV_CONVERSION_FRAGMENT_POW:
974 break; 973 break;
975 case YUV_CONVERSION_FRAGMENT_LOOKUP: 974 case YUV_CONVERSION_FRAGMENT_LOOKUP:
976 texs[0] = (*texu)++; 975 texs[0] = (*texu)++;
977 ActiveTexture(GL_TEXTURE0 + texs[0]); 976 ActiveTexture(GL_TEXTURE0 + texs[0]);
978 lookup_data = malloc(4 * LOOKUP_RES); 977 lookup_data = malloc(4 * LOOKUP_RES);
979 gen_gamma_map(lookup_data, LOOKUP_RES, rgamma); 978 gen_gamma_map(lookup_data, LOOKUP_RES, params->rgamma);
980 gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, ggamma); 979 gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->ggamma);
981 gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, bgamma); 980 gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->bgamma);
982 glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LINEAR, 981 glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LINEAR,
983 LOOKUP_RES, 4, 0); 982 LOOKUP_RES, 4, 0);
984 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data, 983 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data,
985 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0); 984 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0);
986 ActiveTexture(GL_TEXTURE0); 985 ActiveTexture(GL_TEXTURE0);
994 break; 993 break;
995 } 994 }
996 texs[0] = (*texu)++; 995 texs[0] = (*texu)++;
997 ActiveTexture(GL_TEXTURE0 + texs[0]); 996 ActiveTexture(GL_TEXTURE0 + texs[0]);
998 lookup_data = malloc(3 * sz * sz * sz); 997 lookup_data = malloc(3 * sz * sz * sz);
999 gen_yuv2rgb_map(lookup_data, LOOKUP_3DRES, brightness, contrast, 998 gen_yuv2rgb_map(params, lookup_data, LOOKUP_3DRES);
1000 uvcos, uvsin, rgamma, ggamma, bgamma);
1001 glAdjustAlignment(sz); 999 glAdjustAlignment(sz);
1002 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 1000 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1003 TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1, 1001 TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1,
1004 GL_RGB, GL_UNSIGNED_BYTE, lookup_data); 1002 GL_RGB, GL_UNSIGNED_BYTE, lookup_data);
1005 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0); 1003 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0);
1160 * \param uvcos used for saturation and hue adjustment 1158 * \param uvcos used for saturation and hue adjustment
1161 * \param uvsin used for saturation and hue adjustment 1159 * \param uvsin used for saturation and hue adjustment
1162 * \param lookup use fragment program that uses texture unit 4 to 1160 * \param lookup use fragment program that uses texture unit 4 to
1163 * do additional conversion via lookup. 1161 * do additional conversion via lookup.
1164 */ 1162 */
1165 static void glSetupYUVFragprog(float brightness, float contrast, 1163 static void glSetupYUVFragprog(gl_conversion_params_t *params) {
1166 float uvcos, float uvsin, float rgamma, 1164 int type = params->type;
1167 float ggamma, float bgamma, int type, int rect, 1165 int texw = params->texw;
1168 int texw, int texh) { 1166 int texh = params->texh;
1167 int rect = params->target == GL_TEXTURE_RECTANGLE;
1169 static const char prog_hdr[] = 1168 static const char prog_hdr[] =
1170 "!!ARBfp1.0\n" 1169 "!!ARBfp1.0\n"
1171 "OPTION ARB_precision_hint_fastest;" 1170 "OPTION ARB_precision_hint_fastest;"
1172 // all scaler variables must go here so they aren't defined 1171 // all scaler variables must go here so they aren't defined
1173 // multiple times when the same scaler is used more than once 1172 // multiple times when the same scaler is used more than once
1182 // this is the conversion matrix, with y, u, v factors 1181 // this is the conversion matrix, with y, u, v factors
1183 // for red, green, blue and the constant offsets 1182 // for red, green, blue and the constant offsets
1184 float ry, ru, rv, rc; 1183 float ry, ru, rv, rc;
1185 float gy, gu, gv, gc; 1184 float gy, gu, gv, gc;
1186 float by, bu, bv, bc; 1185 float by, bu, bv, bc;
1187 create_conv_textures(YUV_CONVERSION(type), &cur_texu, conv_texs, 1186 create_conv_textures(params, &cur_texu, conv_texs);
1188 brightness, contrast, uvcos, uvsin, rgamma, ggamma, bgamma);
1189 create_scaler_textures(YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs); 1187 create_scaler_textures(YUV_LUM_SCALER(type), &cur_texu, lum_scale_texs);
1190 if (YUV_CHROM_SCALER(type) == YUV_LUM_SCALER(type)) 1188 if (YUV_CHROM_SCALER(type) == YUV_LUM_SCALER(type))
1191 memcpy(chrom_scale_texs, lum_scale_texs, sizeof(chrom_scale_texs)); 1189 memcpy(chrom_scale_texs, lum_scale_texs, sizeof(chrom_scale_texs));
1192 else 1190 else
1193 create_scaler_textures(YUV_CHROM_SCALER(type), &cur_texu, chrom_scale_texs); 1191 create_scaler_textures(YUV_CHROM_SCALER(type), &cur_texu, chrom_scale_texs);
1208 '0', 'r', rect, texw, texh); 1206 '0', 'r', rect, texw, texh);
1209 add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs, 1207 add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
1210 '1', 'g', rect, texw / 2, texh / 2); 1208 '1', 'g', rect, texw / 2, texh / 2);
1211 add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs, 1209 add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
1212 '2', 'b', rect, texw / 2, texh / 2); 1210 '2', 'b', rect, texw / 2, texh / 2);
1213 get_yuv2rgb_coeffs(brightness, contrast, uvcos, uvsin, 1211 get_yuv2rgb_coeffs(params,
1214 &ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc); 1212 &ry, &ru, &rv, &rc, &gy, &gu, &gv, &gc, &by, &bu, &bv, &bc);
1215 switch (YUV_CONVERSION(type)) { 1213 switch (YUV_CONVERSION(type)) {
1216 case YUV_CONVERSION_FRAGMENT: 1214 case YUV_CONVERSION_FRAGMENT:
1217 snprintf(prog_pos, prog_remain, yuv_prog_template, 1215 snprintf(prog_pos, prog_remain, yuv_prog_template,
1218 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc); 1216 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc);
1219 break; 1217 break;
1220 case YUV_CONVERSION_FRAGMENT_POW: 1218 case YUV_CONVERSION_FRAGMENT_POW:
1221 snprintf(prog_pos, prog_remain, yuv_pow_prog_template, 1219 snprintf(prog_pos, prog_remain, yuv_pow_prog_template,
1222 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, 1220 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc,
1223 (float)1.0 / rgamma, (float)1.0 / bgamma, (float)1.0 / bgamma); 1221 (float)1.0 / params->rgamma, (float)1.0 / params->bgamma, (float)1.0 / params->bgamma);
1224 break; 1222 break;
1225 case YUV_CONVERSION_FRAGMENT_LOOKUP: 1223 case YUV_CONVERSION_FRAGMENT_LOOKUP:
1226 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template, 1224 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template,
1227 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, 1225 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc,
1228 conv_texs[0], conv_texs[0], conv_texs[0]); 1226 conv_texs[0], conv_texs[0], conv_texs[0]);
1273 * \param rgamma gamma value for red channel 1271 * \param rgamma gamma value for red channel
1274 * \param ggamma gamma value for green channel 1272 * \param ggamma gamma value for green channel
1275 * \param bgamma gamma value for blue channel 1273 * \param bgamma gamma value for blue channel
1276 * \ingroup glconversion 1274 * \ingroup glconversion
1277 */ 1275 */
1278 void glSetupYUVConversion(GLenum target, int type, 1276 void glSetupYUVConversion(gl_conversion_params_t *params) {
1279 float brightness, float contrast, 1277 float uvcos = params->saturation * cos(params->hue);
1280 float hue, float saturation, 1278 float uvsin = params->saturation * sin(params->hue);
1281 float rgamma, float ggamma, float bgamma, 1279 switch (YUV_CONVERSION(params->type)) {
1282 int texw, int texh) {
1283 float uvcos = saturation * cos(hue);
1284 float uvsin = saturation * sin(hue);
1285 switch (YUV_CONVERSION(type)) {
1286 case YUV_CONVERSION_COMBINERS: 1280 case YUV_CONVERSION_COMBINERS:
1287 glSetupYUVCombiners(uvcos, uvsin); 1281 glSetupYUVCombiners(uvcos, uvsin);
1288 break; 1282 break;
1289 case YUV_CONVERSION_COMBINERS_ATI: 1283 case YUV_CONVERSION_COMBINERS_ATI:
1290 glSetupYUVCombinersATI(uvcos, uvsin); 1284 glSetupYUVCombinersATI(uvcos, uvsin);
1291 break; 1285 break;
1292 case YUV_CONVERSION_FRAGMENT_LOOKUP: 1286 case YUV_CONVERSION_FRAGMENT_LOOKUP:
1293 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: 1287 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
1294 case YUV_CONVERSION_FRAGMENT: 1288 case YUV_CONVERSION_FRAGMENT:
1295 case YUV_CONVERSION_FRAGMENT_POW: 1289 case YUV_CONVERSION_FRAGMENT_POW:
1296 glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, 1290 glSetupYUVFragprog(params);
1297 rgamma, ggamma, bgamma, type,
1298 target == GL_TEXTURE_RECTANGLE,
1299 texw, texh);
1300 break; 1291 break;
1301 default: 1292 default:
1302 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); 1293 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(params->type));
1303 } 1294 }
1304 } 1295 }
1305 1296
1306 /** 1297 /**
1307 * \brief enable the specified YUV conversion 1298 * \brief enable the specified YUV conversion