From d0293d9f0c88dedbd437edf4a4e1c2f9240c9548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 12 Jul 2013 14:20:05 +0200 Subject: [PATCH] [745/906] gl: Simplify and optimize YUV conversion shaders a bit --- gst-libs/gst/gl/gstgldownload.c | 127 ++++++++++++++++---------------- gst-libs/gst/gl/gstglupload.c | 120 +++++++++++++++--------------- 2 files changed, 124 insertions(+), 123 deletions(-) diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c index f7ab882389..dcd39c967c 100644 --- a/gst-libs/gst/gl/gstgldownload.c +++ b/gst-libs/gst/gl/gstgldownload.c @@ -73,30 +73,33 @@ static void _do_download_draw_yuv_gles2 (GstGLDisplay * display, /* *INDENT-OFF* */ +#define RGB_TO_YUV_COEFFICIENTS \ + "const vec3 offset = vec3(0.0625, 0.5, 0.5);\n" \ + "const vec3 ycoeff = vec3(0.256816, 0.504154, 0.0979137);\n" \ + "const vec3 ucoeff = vec3(-0.148246, -0.29102, 0.439266);\n" \ + "const vec3 vcoeff = vec3(0.439271, -0.367833, -0.071438);\n" +#if GST_GL_HAVE_OPENGL /* YUY2:y2,u,y1,v UYVY:v,y1,u,y2 */ -#if GST_GL_HAVE_OPENGL static gchar *text_shader_YUY2_UYVY_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" + RGB_TO_YUV_COEFFICIENTS "void main(void) {\n" - " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" + " vec3 rgb1, rgb2;\n" + " float fx,fy,y1,y2,u,v;\n" " fx = gl_TexCoord[0].x;\n" " fy = gl_TexCoord[0].y;\n" - " r=texture2DRect(tex,vec2(fx*2.0,fy)).r;\n" - " g=texture2DRect(tex,vec2(fx*2.0,fy)).g;\n" - " b=texture2DRect(tex,vec2(fx*2.0,fy)).b;\n" - " r2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).r;\n" - " g2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).g;\n" - " b2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).b;\n" - " y1=0.299011*r + 0.586987*g + 0.114001*b;\n" - " y2=0.299011*r2 + 0.586987*g2 + 0.114001*b2;\n" - " u=-0.148246*r -0.29102*g + 0.439266*b;\n" - " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" - " y1=0.858885*y1 + 0.0625;\n" - " y2=0.858885*y2 + 0.0625;\n" - " u=u + 0.5;\n" - " v=v + 0.5;\n" + " rgb1=texture2DRect(tex,vec2(fx*2.0,fy)).rgb;\n" + " rgb2=texture2DRect(tex,vec2(fx*2.0+1.0,fy)).rgb;\n" + " y1=dot(rgb1, ycoeff);\n" + " y2=dot(rgb2, ycoeff);\n" + " u=dot(rgb1, ucoeff);\n" + " v=dot(rgb1, vcoeff);\n" + " y1+=offset.x;\n" + " y2+=offset.x;\n" + " u+=offset.y;\n" + " v+=offset.z;\n" " gl_FragColor=vec4(%s);\n" "}\n"; @@ -104,22 +107,20 @@ static gchar *text_shader_I420_YV12_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" "uniform float w, h;\n" + RGB_TO_YUV_COEFFICIENTS "void main(void) {\n" - " float r,g,b,r2,b2,g2,y,u,v;\n" + " vec3 rgb1, rgb2;\n" + " float y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" " vec2 nxy2=nxy*2.0;\n" - " r=texture2DRect(tex,nxy).r;\n" - " g=texture2DRect(tex,nxy).g;\n" - " b=texture2DRect(tex,nxy).b;\n" - " r2=texture2DRect(tex,nxy2).r;\n" - " g2=texture2DRect(tex,nxy2).g;\n" - " b2=texture2DRect(tex,nxy2).b;\n" - " y=0.299011*r + 0.586987*g + 0.114001*b;\n" - " u=-0.148246*r2 -0.29102*g2 + 0.439266*b2;\n" - " v=0.439271*r2 - 0.367833*g2 - 0.071438*b2 ;\n" - " y=0.858885*y + 0.0625;\n" - " u=u + 0.5;\n" - " v=v + 0.5;\n" + " rgb1=texture2DRect(tex,nxy).rgb;\n" + " rgb2=texture2DRect(tex,nxy2).rgb;\n" + " y=dot(rgb1, ycoeff);\n" + " u=dot(rgb2, ucoeff);\n" + " v=dot(rgb2, vcoeff);\n" + " y+=offset.x;\n" + " u+=offset.y;\n" + " v+=offset.z;\n" " gl_FragData[0] = vec4(y, 0.0, 0.0, 1.0);\n" " gl_FragData[1] = vec4(u, 0.0, 0.0, 1.0);\n" " gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n" @@ -128,18 +129,18 @@ static gchar *text_shader_I420_YV12_opengl = static gchar *text_shader_AYUV_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" + RGB_TO_YUV_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 rgb;\n" + " float y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" - " r=texture2DRect(tex,nxy).r;\n" - " g=texture2DRect(tex,nxy).g;\n" - " b=texture2DRect(tex,nxy).b;\n" - " y=0.299011*r + 0.586987*g + 0.114001*b;\n" - " u=-0.148246*r -0.29102*g + 0.439266*b;\n" - " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" - " y=0.858885*y + 0.0625;\n" - " u=u + 0.5;\n" - " v=v + 0.5;\n" + " rgb=texture2DRect(tex,nxy).rgb;\n" + " y=dot(rgb, ycoeff);\n" + " u=dot(rgb, ucoeff);\n" + " v=dot(rgb, vcoeff);\n" + " y+=offset.x;\n" + " u+=offset.y;\n" + " v+=offset.z;\n" " gl_FragColor=vec4(y,u,v,1.0);\n" "}\n"; @@ -151,24 +152,22 @@ static gchar *text_shader_YUY2_UYVY_gles2 = "precision mediump float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" + RGB_TO_YUV_COEFFICIENTS "void main(void) {\n" - " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" + " vec3 rgb1, rgb2;\n" + " float fx,fy,y1,y2,u,v;\n" " fx = v_texCoord.x;\n" " fy = v_texCoord.y;\n" - " r=texture2D(tex,vec2(fx*2.0,fy)).r;\n" - " g=texture2D(tex,vec2(fx*2.0,fy)).g;\n" - " b=texture2D(tex,vec2(fx*2.0,fy)).b;\n" - " r2=texture2D(tex,vec2(fx*2.0+1.0,fy)).r;\n" - " g2=texture2D(tex,vec2(fx*2.0+1.0,fy)).g;\n" - " b2=texture2D(tex,vec2(fx*2.0+1.0,fy)).b;\n" - " y1=0.299011*r + 0.586987*g + 0.114001*b;\n" - " y2=0.299011*r2 + 0.586987*g2 + 0.114001*b2;\n" - " u=-0.148246*r -0.29102*g + 0.439266*b;\n" - " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" - " y1=0.858885*y1 + 0.0625;\n" - " y2=0.858885*y2 + 0.0625;\n" - " u=u + 0.5;\n" - " v=v + 0.5;\n" + " rgb1=texture2D(tex,vec2(fx*2.0,fy)).rgb;\n" + " rgb2=texture2D(tex,vec2(fx*2.0+1.0,fy)).rgb;\n" + " y1=dot(rgb1, ycoeff);\n" + " y2=dot(rgb2, ycoeff);\n" + " u=dot(rgb1, ucoeff);\n" + " v=dot(rgb1, vcoeff);\n" + " y1+=offset.x;\n" + " y2+=offset.x;\n" + " u+=offset.y;\n" + " v+=offset.z;\n" " gl_FragColor=vec4(%s);\n" "}\n"; @@ -181,18 +180,18 @@ static gchar *text_shader_AYUV_gles2 = "precision mediump float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" + RGB_TO_YUV_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 rgb;\n" + " float y,u,v;\n" " vec2 nxy=v_texCoord.xy;\n" - " r=texture2D(tex,nxy).r;\n" - " g=texture2D(tex,nxy).g;\n" - " b=texture2D(tex,nxy).b;\n" - " y=0.299011*r + 0.586987*g + 0.114001*b;\n" - " u=-0.148246*r -0.29102*g + 0.439266*b;\n" - " v=0.439271*r - 0.367833*g - 0.071438*b ;\n" - " y=0.858885*y + 0.0625;\n" - " u=u + 0.5;\n" - " v=v + 0.5;\n" + " rgb=texture2D(tex,nxy).rgb;\n" + " y=dot(rgb, ycoeff);\n" + " u=dot(rgb, ucoeff);\n" + " v=dot(rgb, vcoeff);\n" + " y+=offset.x;\n" + " u+=offset.y;\n" + " v+=offset.z;\n" " gl_FragColor=vec4(1.0,y,u,v);\n" "}\n"; diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index 8b58709564..89dbbe3cc2 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -70,25 +70,31 @@ static void _do_upload_draw_gles2 (GstGLDisplay * display, /* *INDENT-OFF* */ +#define YUV_TO_RGB_COEFFICIENTS \ + "const vec3 offset = vec3(-0.0625, -0.5, -0.5);\n" \ + "const vec3 rcoeff = vec3(1.164, 0.000, 1.596);\n" \ + "const vec3 gcoeff = vec3(1.164,-0.391,-0.813);\n" \ + "const vec3 bcoeff = vec3(1.164, 2.018, 0.000);\n" + #if GST_GL_HAVE_OPENGL /* YUY2:r,g,a UYVY:a,b,r */ static gchar *text_shader_YUY2_UYVY_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect Ytex, UVtex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" - " float fx, fy, y, u, v, r, g, b;\n" + " vec3 yuv;\n" + " float fx, fy, r, g, b;\n" " fx = gl_TexCoord[0].x;\n" " fy = gl_TexCoord[0].y;\n" - " y = texture2DRect(Ytex,vec2(fx,fy)).%c;\n" - " u = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" - " v = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" - " y=1.164*(y-0.0627);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r = y+1.5958*v;\n" - " g = y-0.39173*u-0.81290*v;\n" - " b = y+2.017*u;\n" + " yuv.x = texture2DRect(Ytex,vec2(fx,fy)).%c;\n" + " yuv.y = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" + " yuv.z = texture2DRect(UVtex,vec2(fx*0.5,fy)).%c;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n"; @@ -97,36 +103,34 @@ static gchar *text_shader_YUY2_UYVY_opengl = static gchar *text_shader_I420_YV12_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect Ytex,Utex,Vtex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 yuv;\n" + " float r,g,b;\n" " vec2 nxy = gl_TexCoord[0].xy;\n" - " y=texture2DRect(Ytex,nxy%s).r;\n" - " u=texture2DRect(Utex,nxy%s).r;\n" - " v=texture2DRect(Vtex,nxy*0.5).r;\n" - " y=1.1643*(y-0.0625);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r=y+1.5958*v;\n" - " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" + " yuv.x=texture2DRect(Ytex,nxy%s).r;\n" + " yuv.y=texture2DRect(Utex,nxy%s).r;\n" + " yuv.z=texture2DRect(Vtex,nxy*0.5).r;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; static gchar *text_shader_AYUV_opengl = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 yuv;\n" + " float r,g,b;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" - " y=texture2DRect(tex,nxy).r;\n" - " u=texture2DRect(tex,nxy).g;\n" - " v=texture2DRect(tex,nxy).b;\n" - " y=1.1643*(y-0.0625);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r=y+1.5958*v;\n" - " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" + " yuv=texture2DRect(tex,nxy).rgb;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; @@ -140,19 +144,19 @@ static gchar *text_shader_YUY2_UYVY_gles2 = "precision mediump float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D Ytex, UVtex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" + " vec3 yuv;\n" " float fx, fy, y, u, v, r, g, b;\n" " fx = v_texCoord.x;\n" " fy = v_texCoord.y;\n" - " y = texture2D(Ytex,vec2(fx,fy)).%c;\n" - " u = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" - " v = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" - " y=1.164*(y-0.0627);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r = y+1.5958*v;\n" - " g = y-0.39173*u-0.81290*v;\n" - " b = y+2.017*u;\n" + " yuv.x = texture2D(Ytex,vec2(fx,fy)).%c;\n" + " yuv.y = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" + " yuv.z = texture2D(UVtex,vec2(fx*0.5,fy)).%c;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n"; @@ -160,18 +164,18 @@ static gchar *text_shader_I420_YV12_gles2 = "precision mediump float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D Ytex,Utex,Vtex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 yuv;\n" + " float r, g, b;\n" " vec2 nxy = v_texCoord.xy;\n" - " y=texture2D(Ytex,nxy).r;\n" - " u=texture2D(Utex,nxy).r;\n" - " v=texture2D(Vtex,nxy).r;\n" - " y=1.1643*(y-0.0625);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r=y+1.5958*v;\n" - " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" + " yuv.x=texture2D(Ytex,nxy).r;\n" + " yuv.y=texture2D(Utex,nxy).r;\n" + " yuv.z=texture2D(Vtex,nxy).r;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; @@ -179,18 +183,16 @@ static gchar *text_shader_AYUV_gles2 = "precision mediump float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D tex;\n" + YUV_TO_RGB_COEFFICIENTS "void main(void) {\n" - " float r,g,b,y,u,v;\n" + " vec3 yuv;\n" + " float r,g,b;\n" " vec2 nxy = v_texCoord.xy;\n" - " y=texture2D(tex,nxy).g;\n" - " u=texture2D(tex,nxy).b;\n" - " v=texture2D(tex,nxy).a;\n" - " y=1.1643*(y-0.0625);\n" - " u=u-0.5;\n" - " v=v-0.5;\n" - " r=y+1.5958*v;\n" - " g=y-0.39173*u-0.81290*v;\n" - " b=y+2.017*u;\n" + " yuv=texture2D(tex,nxy).gba;\n" + " yuv+=offset;\n" + " r = dot(yuv, rcoeff);\n" + " g = dot(yuv, gcoeff);\n" + " b = dot(yuv, bcoeff);\n" " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n";