Mercurial > mplayer.hg
comparison libvo/gl_common.c @ 18655:6aa0b26d584b
Add yuv to rgb conversion using a 3D lookup texture
author | reimar |
---|---|
date | Thu, 08 Jun 2006 19:02:56 +0000 |
parents | 5af43a16abc3 |
children | e813d4014acd |
comparison
equal
deleted
inserted
replaced
18654:9fb5e9cdcae8 | 18655:6aa0b26d584b |
---|---|
721 "TEX result.color.g, res.gaaa, texture[%c], 2D;" | 721 "TEX result.color.g, res.gaaa, texture[%c], 2D;" |
722 "ADD res.a, res.a, 0.25;" | 722 "ADD res.a, res.a, 0.25;" |
723 "TEX result.color.b, res.baaa, texture[%c], 2D;" | 723 "TEX result.color.b, res.baaa, texture[%c], 2D;" |
724 "END"; | 724 "END"; |
725 | 725 |
726 static const char *yuv_lookup3d_prog_template = | |
727 "TEX result.color, yuv, texture[%c], 3D;" | |
728 "END"; | |
729 | |
726 static void create_scaler_textures(int scaler, int *texu, char *texs) { | 730 static void create_scaler_textures(int scaler, int *texu, char *texs) { |
727 switch (scaler) { | 731 switch (scaler) { |
728 case YUV_SCALER_BILIN: | 732 case YUV_SCALER_BILIN: |
729 break; | 733 break; |
730 case YUV_SCALER_BICUB: | 734 case YUV_SCALER_BICUB: |
735 default: | 739 default: |
736 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler); | 740 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler); |
737 } | 741 } |
738 } | 742 } |
739 | 743 |
744 static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness, | |
745 float contrast, float uvcos, float uvsin, | |
746 float rgamma, float ggamma, float bgamma) { | |
747 int i, j, k; | |
748 float step = 1.0 / size; | |
749 float y, u, v, u_, v_; | |
750 float r, g, b; | |
751 v = -0.5; | |
752 for (i = -1; i <= size; i++) { | |
753 u = -0.5; | |
754 for (j = -1; j <= size; j++) { | |
755 y = -(16.0 / 255.0); | |
756 for (k = -1; k <= size; k++) { | |
757 u_ = uvcos * u + uvsin * v; | |
758 v_ = uvcos * v + uvsin * u; | |
759 r = 1.164 * y + 1.596 * v_; | |
760 g = 1.164 * y - 0.391 * u_ - 0.813 * v_; | |
761 b = 1.164 * y + 2.018 * u_ ; | |
762 r = pow(contrast * (r - 0.5) + 0.5 + brightness, 1.0 / rgamma); | |
763 g = pow(contrast * (g - 0.5) + 0.5 + brightness, 1.0 / ggamma); | |
764 b = pow(contrast * (b - 0.5) + 0.5 + brightness, 1.0 / bgamma); | |
765 if (r > 1) r = 1; | |
766 if (r < 0) r = 0; | |
767 if (g > 1) g = 1; | |
768 if (g < 0) g = 0; | |
769 if (b > 1) b = 1; | |
770 if (b < 0) b = 0; | |
771 *map++ = 255 * r; | |
772 *map++ = 255 * g; | |
773 *map++ = 255 * b; | |
774 y += (k == -1 || k == size - 1) ? step / 2 : step; | |
775 } | |
776 u += (j == -1 || j == size - 1) ? step / 2 : step; | |
777 } | |
778 v += (i == -1 || i == size - 1) ? step / 2 : step; | |
779 } | |
780 } | |
781 | |
740 static void gen_gamma_map(unsigned char *map, int size, float gamma); | 782 static void gen_gamma_map(unsigned char *map, int size, float gamma); |
741 | 783 |
742 //! resolution of texture for gamma lookup table | 784 //! resolution of texture for gamma lookup table |
743 #define LOOKUP_RES 512 | 785 #define LOOKUP_RES 512 |
786 //! resolution for 3D yuv->rgb conversion lookup table | |
787 #define LOOKUP_3DRES 32 | |
744 static void create_conv_textures(int conv, int *texu, char *texs, | 788 static void create_conv_textures(int conv, int *texu, char *texs, |
745 int brightness, int contrast, int uvcos, int uvsin, | 789 int brightness, int contrast, int uvcos, int uvsin, |
746 int rgamma, int ggamma, int bgamma) { | 790 int rgamma, int ggamma, int bgamma) { |
747 unsigned char *lookup_data = NULL; | 791 unsigned char *lookup_data = NULL; |
748 switch (conv) { | 792 switch (conv) { |
760 LOOKUP_RES, 4, 0); | 804 LOOKUP_RES, 4, 0); |
761 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data, | 805 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data, |
762 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0); | 806 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0); |
763 ActiveTexture(GL_TEXTURE0); | 807 ActiveTexture(GL_TEXTURE0); |
764 texs[0] += '0'; | 808 texs[0] += '0'; |
809 break; | |
810 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: | |
811 { | |
812 int sz = LOOKUP_3DRES + 2; // texture size including borders | |
813 if (!TexImage3D) { | |
814 mp_msg(MSGT_VO, MSGL_ERR, "[gl] Missing 3D texture function!\n"); | |
815 break; | |
816 } | |
817 texs[0] = (*texu)++; | |
818 ActiveTexture(GL_TEXTURE0 + texs[0]); | |
819 lookup_data = malloc(3 * sz * sz * sz); | |
820 gen_yuv2rgb_map(lookup_data, LOOKUP_3DRES, brightness, contrast, | |
821 uvcos, uvsin, rgamma, ggamma, bgamma); | |
822 glAdjustAlignment(sz); | |
823 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | |
824 TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1, | |
825 GL_RGB, GL_UNSIGNED_BYTE, lookup_data); | |
826 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0); | |
827 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
828 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
829 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); | |
830 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); | |
831 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); | |
832 ActiveTexture(GL_TEXTURE0); | |
833 texs[0] += '0'; | |
834 } | |
765 break; | 835 break; |
766 default: | 836 default: |
767 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv); | 837 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv); |
768 } | 838 } |
769 if (lookup_data) | 839 if (lookup_data) |
927 case YUV_CONVERSION_FRAGMENT_LOOKUP: | 997 case YUV_CONVERSION_FRAGMENT_LOOKUP: |
928 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template, | 998 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template, |
929 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, | 999 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, |
930 conv_texs[0], conv_texs[0], conv_texs[0]); | 1000 conv_texs[0], conv_texs[0], conv_texs[0]); |
931 break; | 1001 break; |
1002 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: | |
1003 snprintf(prog_pos, prog_remain, yuv_lookup3d_prog_template, conv_texs[0]); | |
1004 break; | |
932 default: | 1005 default: |
933 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); | 1006 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); |
934 break; | 1007 break; |
935 } | 1008 } |
936 mp_msg(MSGT_VO, MSGL_V, "[gl] generated fragment program:\n%s\n", yuv_prog); | 1009 mp_msg(MSGT_VO, MSGL_V, "[gl] generated fragment program:\n%s\n", yuv_prog); |
981 break; | 1054 break; |
982 case YUV_CONVERSION_COMBINERS_ATI: | 1055 case YUV_CONVERSION_COMBINERS_ATI: |
983 glSetupYUVCombinersATI(uvcos, uvsin); | 1056 glSetupYUVCombinersATI(uvcos, uvsin); |
984 break; | 1057 break; |
985 case YUV_CONVERSION_FRAGMENT_LOOKUP: | 1058 case YUV_CONVERSION_FRAGMENT_LOOKUP: |
1059 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: | |
986 case YUV_CONVERSION_FRAGMENT: | 1060 case YUV_CONVERSION_FRAGMENT: |
987 case YUV_CONVERSION_FRAGMENT_POW: | 1061 case YUV_CONVERSION_FRAGMENT_POW: |
988 glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, | 1062 glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, |
989 rgamma, ggamma, bgamma, type, | 1063 rgamma, ggamma, bgamma, type, |
990 target == GL_TEXTURE_RECTANGLE, | 1064 target == GL_TEXTURE_RECTANGLE, |
1018 ActiveTexture(GL_TEXTURE2); | 1092 ActiveTexture(GL_TEXTURE2); |
1019 glEnable(target); | 1093 glEnable(target); |
1020 ActiveTexture(GL_TEXTURE0); | 1094 ActiveTexture(GL_TEXTURE0); |
1021 glEnable(GL_FRAGMENT_SHADER_ATI); | 1095 glEnable(GL_FRAGMENT_SHADER_ATI); |
1022 break; | 1096 break; |
1097 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: | |
1023 case YUV_CONVERSION_FRAGMENT_LOOKUP: | 1098 case YUV_CONVERSION_FRAGMENT_LOOKUP: |
1024 case YUV_CONVERSION_FRAGMENT_POW: | 1099 case YUV_CONVERSION_FRAGMENT_POW: |
1025 case YUV_CONVERSION_FRAGMENT: | 1100 case YUV_CONVERSION_FRAGMENT: |
1026 glEnable(GL_FRAGMENT_PROGRAM); | 1101 glEnable(GL_FRAGMENT_PROGRAM); |
1027 break; | 1102 break; |
1051 ActiveTexture(GL_TEXTURE2); | 1126 ActiveTexture(GL_TEXTURE2); |
1052 glDisable(target); | 1127 glDisable(target); |
1053 ActiveTexture(GL_TEXTURE0); | 1128 ActiveTexture(GL_TEXTURE0); |
1054 glDisable(GL_FRAGMENT_SHADER_ATI); | 1129 glDisable(GL_FRAGMENT_SHADER_ATI); |
1055 break; | 1130 break; |
1131 case YUV_CONVERSION_FRAGMENT_LOOKUP3D: | |
1056 case YUV_CONVERSION_FRAGMENT_LOOKUP: | 1132 case YUV_CONVERSION_FRAGMENT_LOOKUP: |
1057 case YUV_CONVERSION_FRAGMENT_POW: | 1133 case YUV_CONVERSION_FRAGMENT_POW: |
1058 case YUV_CONVERSION_FRAGMENT: | 1134 case YUV_CONVERSION_FRAGMENT: |
1059 glDisable(GL_FRAGMENT_PROGRAM); | 1135 glDisable(GL_FRAGMENT_PROGRAM); |
1060 break; | 1136 break; |