mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
[130/906] use GstGLShader in the GLSL colorspace conversion
This commit is contained in:
parent
93722cac7d
commit
3d3ba97c4d
6 changed files with 250 additions and 212 deletions
|
@ -62,7 +62,6 @@ void gst_gl_display_on_draw (void);
|
||||||
void gst_gl_display_on_close (void);
|
void gst_gl_display_on_close (void);
|
||||||
void gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture);
|
void gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture);
|
||||||
void gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture);
|
void gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture);
|
||||||
GLhandleARB gst_gl_display_load_fragment_shader (gchar* textFProgram);
|
|
||||||
void gst_gl_display_check_framebuffer_status (void);
|
void gst_gl_display_check_framebuffer_status (void);
|
||||||
|
|
||||||
/* To not make gst_gl_display_thread_do_upload
|
/* To not make gst_gl_display_thread_do_upload
|
||||||
|
@ -212,24 +211,24 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
|
|
||||||
//action gen and del shader
|
//action gen and del shader
|
||||||
display->gen_text_shader = NULL;
|
display->gen_text_shader = NULL;
|
||||||
display->gen_handle_shader = 0;
|
display->gen_shader = NULL;
|
||||||
display->del_handle_shader = 0;
|
display->del_shader = NULL;
|
||||||
|
|
||||||
//fragement shader upload
|
//fragement shader upload
|
||||||
display->GLSLProgram_YUY2 = 0;
|
display->shader_upload_YUY2 = NULL;
|
||||||
display->GLSLProgram_UYVY = 0;
|
display->shader_upload_UYVY = NULL;
|
||||||
display->GLSLProgram_I420_YV12 = 0;
|
display->shader_upload_I420_YV12 = NULL;
|
||||||
display->GLSLProgram_AYUV = 0;
|
display->shader_upload_AYUV = NULL;
|
||||||
|
|
||||||
//fragement shader download
|
//fragement shader download
|
||||||
display->GLSLProgram_to_YUY2 = 0;
|
display->shader_download_YUY2 = NULL;
|
||||||
display->GLSLProgram_to_UYVY = 0;
|
display->shader_download_UYVY = NULL;
|
||||||
display->GLSLProgram_to_I420_YV12 = 0;
|
display->shader_download_I420_YV12 = NULL;
|
||||||
display->GLSLProgram_to_AYUV = 0;
|
display->shader_download_AYUV = NULL;
|
||||||
|
|
||||||
//YUY2:r,g,a
|
//YUY2:r,g,a
|
||||||
//UYVY:a,b,r
|
//UYVY:a,b,r
|
||||||
display->textFProgram_YUY2_UYVY =
|
display->text_shader_upload_YUY2_UYVY =
|
||||||
"uniform sampler2DRect Ytex, UVtex;\n"
|
"uniform sampler2DRect Ytex, UVtex;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" float fx, fy, y, u, v, r, g, b;\n"
|
" float fx, fy, y, u, v, r, g, b;\n"
|
||||||
|
@ -247,7 +246,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
" gl_FragColor = vec4(r, g, b, 1.0);\n"
|
" gl_FragColor = vec4(r, g, b, 1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
display->textFProgram_I420_YV12 =
|
display->text_shader_upload_I420_YV12 =
|
||||||
"uniform sampler2DRect Ytex,Utex,Vtex;\n"
|
"uniform sampler2DRect Ytex,Utex,Vtex;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" float r,g,b,y,u,v;\n"
|
" float r,g,b,y,u,v;\n"
|
||||||
|
@ -264,7 +263,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
" gl_FragColor=vec4(r,g,b,1.0);\n"
|
" gl_FragColor=vec4(r,g,b,1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
display->textFProgram_AYUV =
|
display->text_shader_upload_AYUV =
|
||||||
"uniform sampler2DRect tex;\n"
|
"uniform sampler2DRect tex;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" float r,g,b,y,u,v;\n"
|
" float r,g,b,y,u,v;\n"
|
||||||
|
@ -283,7 +282,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
|
|
||||||
//YUY2:y2,u,y1,v
|
//YUY2:y2,u,y1,v
|
||||||
//UYVY:v,y1,u,y2
|
//UYVY:v,y1,u,y2
|
||||||
display->textFProgram_to_YUY2_UYVY =
|
display->text_shader_download_YUY2_UYVY =
|
||||||
"uniform sampler2DRect tex;\n"
|
"uniform sampler2DRect tex;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n"
|
" float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n"
|
||||||
|
@ -306,7 +305,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
" gl_FragColor=vec4(%s);\n"
|
" gl_FragColor=vec4(%s);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
display->textFProgram_to_I420_YV12 =
|
display->text_shader_download_I420_YV12 =
|
||||||
"uniform sampler2DRect tex;\n"
|
"uniform sampler2DRect tex;\n"
|
||||||
"uniform float w, h;\n"
|
"uniform float w, h;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
|
@ -330,7 +329,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
|
||||||
" gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n"
|
" gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
display->textFProgram_to_AYUV =
|
display->text_shader_download_AYUV =
|
||||||
"uniform sampler2DRect tex;\n"
|
"uniform sampler2DRect tex;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" float r,g,b,y,u,v;\n"
|
" float r,g,b,y,u,v;\n"
|
||||||
|
@ -728,14 +727,46 @@ gst_gl_display_thread_destroy_context (GstGLDisplay *display)
|
||||||
case GST_GL_DISPLAY_CONVERSION_GLSL:
|
case GST_GL_DISPLAY_CONVERSION_GLSL:
|
||||||
{
|
{
|
||||||
glUseProgramObjectARB (0);
|
glUseProgramObjectARB (0);
|
||||||
glDeleteObjectARB (display->GLSLProgram_YUY2);
|
if (display->shader_upload_YUY2)
|
||||||
glDeleteObjectARB (display->GLSLProgram_UYVY);
|
{
|
||||||
glDeleteObjectARB (display->GLSLProgram_I420_YV12);
|
g_object_unref (G_OBJECT (display->shader_upload_YUY2));
|
||||||
glDeleteObjectARB (display->GLSLProgram_AYUV);
|
display->shader_upload_YUY2 = NULL;
|
||||||
glDeleteObjectARB (display->GLSLProgram_to_YUY2);
|
}
|
||||||
glDeleteObjectARB (display->GLSLProgram_to_UYVY);
|
if (display->shader_upload_UYVY)
|
||||||
glDeleteObjectARB (display->GLSLProgram_to_I420_YV12);
|
{
|
||||||
glDeleteObjectARB (display->GLSLProgram_to_AYUV);
|
g_object_unref (G_OBJECT (display->shader_upload_UYVY));
|
||||||
|
display->shader_upload_UYVY = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_upload_I420_YV12)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_I420_YV12));
|
||||||
|
display->shader_upload_I420_YV12 = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_upload_AYUV)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_AYUV));
|
||||||
|
display->shader_upload_AYUV = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_download_YUY2)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_YUY2));
|
||||||
|
display->shader_download_YUY2 = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_download_UYVY)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_UYVY));
|
||||||
|
display->shader_download_UYVY = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_download_I420_YV12)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_I420_YV12));
|
||||||
|
display->shader_download_I420_YV12 = NULL;
|
||||||
|
}
|
||||||
|
if (display->shader_download_AYUV)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_AYUV));
|
||||||
|
display->shader_download_AYUV = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -921,28 +952,58 @@ gst_gl_display_thread_init_upload (GstGLDisplay *display)
|
||||||
{
|
{
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
{
|
{
|
||||||
gchar program[2048];
|
gchar text_shader_upload_YUY2[2048];
|
||||||
sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a');
|
sprintf (text_shader_upload_YUY2, display->text_shader_upload_YUY2_UYVY, 'r', 'g', 'a');
|
||||||
display->GLSLProgram_YUY2 = gst_gl_display_load_fragment_shader (program);
|
|
||||||
|
display->shader_upload_YUY2 = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_upload_YUY2,
|
||||||
|
text_shader_upload_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_YUY2));
|
||||||
|
display->shader_upload_YUY2 = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
{
|
{
|
||||||
gchar program[2048];
|
gchar text_shader_upload_UYVY[2048];
|
||||||
sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r');
|
sprintf (text_shader_upload_UYVY, display->text_shader_upload_YUY2_UYVY, 'a', 'b', 'r');
|
||||||
display->GLSLProgram_UYVY = gst_gl_display_load_fragment_shader (program);
|
|
||||||
|
display->shader_upload_UYVY = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_upload_UYVY,
|
||||||
|
text_shader_upload_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_UYVY));
|
||||||
|
display->shader_upload_UYVY = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
case GST_VIDEO_FORMAT_YV12:
|
case GST_VIDEO_FORMAT_YV12:
|
||||||
display->GLSLProgram_I420_YV12 = gst_gl_display_load_fragment_shader (display->textFProgram_I420_YV12);
|
display->shader_upload_I420_YV12 = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_upload_I420_YV12,
|
||||||
|
display->text_shader_upload_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_I420_YV12));
|
||||||
|
display->shader_upload_I420_YV12 = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
display->GLSLProgram_AYUV = gst_gl_display_load_fragment_shader (display->textFProgram_AYUV);
|
display->shader_upload_AYUV = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_upload_AYUV,
|
||||||
|
display->text_shader_upload_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_upload_AYUV));
|
||||||
|
display->shader_upload_AYUV = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//check if YCBCR MESA is available
|
//check if YCBCR MESA is available
|
||||||
else if (GLEW_MESA_ycbcr_texture)
|
else if (GLEW_MESA_ycbcr_texture)
|
||||||
|
@ -978,6 +1039,9 @@ gst_gl_display_thread_init_upload (GstGLDisplay *display)
|
||||||
g_print ("Context %d, GLEW_ARB_imaging supported: yes\n", display->glutWinId);
|
g_print ("Context %d, GLEW_ARB_imaging supported: yes\n", display->glutWinId);
|
||||||
|
|
||||||
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MATRIX;
|
display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MATRIX;
|
||||||
|
|
||||||
|
//turn off the pipeline because we do not support it yet
|
||||||
|
display->isAlive = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1164,24 +1228,54 @@ gst_gl_display_thread_init_download (GstGLDisplay *display)
|
||||||
{
|
{
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
{
|
{
|
||||||
gchar program[2048];
|
gchar text_shader_download_YUY2[2048];
|
||||||
sprintf (program, display->textFProgram_to_YUY2_UYVY, "y2,u,y1,v");
|
sprintf (text_shader_download_YUY2, display->text_shader_download_YUY2_UYVY, "y2,u,y1,v");
|
||||||
display->GLSLProgram_to_YUY2 = gst_gl_display_load_fragment_shader (program);
|
|
||||||
|
display->shader_download_YUY2 = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_download_YUY2,
|
||||||
|
text_shader_download_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_YUY2));
|
||||||
|
display->shader_download_YUY2 = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
{
|
{
|
||||||
gchar program[2048];
|
gchar text_shader_download_UYVY[2048];
|
||||||
sprintf (program, display->textFProgram_to_YUY2_UYVY, "v,y1,u,y2");
|
sprintf (text_shader_download_UYVY, display->text_shader_download_YUY2_UYVY, "v,y1,u,y2");
|
||||||
display->GLSLProgram_to_UYVY = gst_gl_display_load_fragment_shader (program);
|
|
||||||
|
display->shader_download_UYVY = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_download_UYVY,
|
||||||
|
text_shader_download_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_UYVY));
|
||||||
|
display->shader_download_UYVY = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
case GST_VIDEO_FORMAT_YV12:
|
case GST_VIDEO_FORMAT_YV12:
|
||||||
display->GLSLProgram_to_I420_YV12 = gst_gl_display_load_fragment_shader (display->textFProgram_to_I420_YV12);
|
display->shader_download_I420_YV12 = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_download_I420_YV12,
|
||||||
|
display->text_shader_download_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_I420_YV12));
|
||||||
|
display->shader_download_I420_YV12 = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
display->GLSLProgram_to_AYUV = gst_gl_display_load_fragment_shader (display->textFProgram_to_AYUV);
|
display->shader_download_AYUV = gst_gl_shader_new ();
|
||||||
|
if(!gst_gl_shader_compile_and_check (display->shader_download_AYUV,
|
||||||
|
display->text_shader_download_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->shader_download_AYUV));
|
||||||
|
display->shader_download_AYUV = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@ -1356,8 +1450,18 @@ gst_gl_display_thread_gen_shader (GstGLDisplay* display)
|
||||||
{
|
{
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
if (GLEW_ARB_fragment_shader)
|
if (GLEW_ARB_fragment_shader)
|
||||||
display->gen_handle_shader =
|
{
|
||||||
gst_gl_display_load_fragment_shader (display->gen_text_shader);
|
display->gen_shader = gst_gl_shader_new ();
|
||||||
|
|
||||||
|
if (!gst_gl_shader_compile_and_check (display->gen_shader,
|
||||||
|
display->gen_text_shader,
|
||||||
|
GST_GL_SHADER_FRAGMENT_SOURCE))
|
||||||
|
{
|
||||||
|
display->isAlive = FALSE;
|
||||||
|
g_object_unref (G_OBJECT (display->gen_shader));
|
||||||
|
display->gen_shader = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_print ("One of the filter required ARB_fragment_shader\n");
|
g_print ("One of the filter required ARB_fragment_shader\n");
|
||||||
|
@ -1372,7 +1476,8 @@ static void
|
||||||
gst_gl_display_thread_del_shader (GstGLDisplay* display)
|
gst_gl_display_thread_del_shader (GstGLDisplay* display)
|
||||||
{
|
{
|
||||||
glutSetWindow (display->glutWinId);
|
glutSetWindow (display->glutWinId);
|
||||||
glDeleteObjectARB (display->del_handle_shader);
|
g_object_unref (G_OBJECT (display->del_shader));
|
||||||
|
display->del_shader = NULL;
|
||||||
g_cond_signal (display->cond_del_shader);
|
g_cond_signal (display->cond_del_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1587,40 +1692,6 @@ gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* called in the gl thread */
|
|
||||||
GLhandleARB
|
|
||||||
gst_gl_display_load_fragment_shader (gchar* textFProgram)
|
|
||||||
{
|
|
||||||
GLhandleARB FHandle = 0;
|
|
||||||
GLhandleARB PHandle = 0;
|
|
||||||
gchar s[32768];
|
|
||||||
GLint i = 0;
|
|
||||||
|
|
||||||
//Set up program objects
|
|
||||||
PHandle = glCreateProgramObjectARB ();
|
|
||||||
|
|
||||||
//Compile the shader
|
|
||||||
FHandle = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB);
|
|
||||||
glShaderSourceARB (FHandle, 1, (const GLcharARB**)&textFProgram, NULL);
|
|
||||||
glCompileShaderARB (FHandle);
|
|
||||||
|
|
||||||
//Print the compilation log
|
|
||||||
glGetObjectParameterivARB (FHandle, GL_OBJECT_COMPILE_STATUS_ARB, &i);
|
|
||||||
glGetInfoLogARB (FHandle, sizeof(s)/sizeof(char), NULL, s);
|
|
||||||
GST_DEBUG ("Compile Log: %s", s);
|
|
||||||
|
|
||||||
//link the shader
|
|
||||||
glAttachObjectARB (PHandle, FHandle);
|
|
||||||
glLinkProgramARB (PHandle);
|
|
||||||
|
|
||||||
//Print the link log
|
|
||||||
glGetInfoLogARB (PHandle, sizeof(s)/sizeof(char), NULL, s);
|
|
||||||
GST_DEBUG ("Link Log: %s", s);
|
|
||||||
|
|
||||||
return PHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* called in the gl thread */
|
/* called in the gl thread */
|
||||||
void
|
void
|
||||||
gst_gl_display_check_framebuffer_status(void)
|
gst_gl_display_check_framebuffer_status(void)
|
||||||
|
@ -1897,23 +1968,23 @@ gst_gl_display_del_fbo (GstGLDisplay* display, GLuint fbo,
|
||||||
|
|
||||||
/* Called by glfilter */
|
/* Called by glfilter */
|
||||||
void
|
void
|
||||||
gst_gl_display_gen_shader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader)
|
gst_gl_display_gen_shader (GstGLDisplay* display, const gchar* textShader, GstGLShader** shader)
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
display->gen_text_shader = textShader;
|
display->gen_text_shader = textShader;
|
||||||
gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_GEN_SHADER, display);
|
gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_GEN_SHADER, display);
|
||||||
g_cond_wait (display->cond_gen_shader, display->mutex);
|
g_cond_wait (display->cond_gen_shader, display->mutex);
|
||||||
*handleShader = display->gen_handle_shader;
|
*shader = display->gen_shader;
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Called by glfilter */
|
/* Called by glfilter */
|
||||||
void
|
void
|
||||||
gst_gl_display_del_shader (GstGLDisplay* display, GLhandleARB shader)
|
gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader)
|
||||||
{
|
{
|
||||||
gst_gl_display_lock (display);
|
gst_gl_display_lock (display);
|
||||||
display->del_handle_shader = shader;
|
display->del_shader = shader;
|
||||||
gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_DEL_SHADER, display);
|
gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_DEL_SHADER, display);
|
||||||
g_cond_wait (display->cond_del_shader, display->mutex);
|
g_cond_wait (display->cond_del_shader, display->mutex);
|
||||||
gst_gl_display_unlock (display);
|
gst_gl_display_unlock (display);
|
||||||
|
@ -2251,28 +2322,28 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
{
|
{
|
||||||
gint i=0;
|
gint i=0;
|
||||||
GLhandleARB GLSLProgram_YUY2_UYVY = 0;
|
|
||||||
|
GstGLShader* shader_upload_YUY2_UYVY = NULL;
|
||||||
|
|
||||||
switch (video_format)
|
switch (video_format)
|
||||||
{
|
{
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
GLSLProgram_YUY2_UYVY = display->GLSLProgram_YUY2;
|
shader_upload_YUY2_UYVY = display->shader_upload_YUY2;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
GLSLProgram_YUY2_UYVY = display->GLSLProgram_UYVY;
|
shader_upload_YUY2_UYVY = display->shader_upload_UYVY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
glUseProgramObjectARB (GLSLProgram_YUY2_UYVY);
|
gst_gl_shader_use (shader_upload_YUY2_UYVY);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||||
i = glGetUniformLocationARB (GLSLProgram_YUY2_UYVY, "UVtex");
|
gst_gl_shader_set_uniform_1i (shader_upload_YUY2_UYVY, "UVtex", 1);
|
||||||
glUniform1iARB (i, 1);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2280,8 +2351,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (GLSLProgram_YUY2_UYVY, "Ytex");
|
gst_gl_shader_set_uniform_1i (shader_upload_YUY2_UYVY, "Ytex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2295,14 +2365,13 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
{
|
{
|
||||||
gint i=0;
|
gint i=0;
|
||||||
|
|
||||||
glUseProgramObjectARB (display->GLSLProgram_I420_YV12);
|
gst_gl_shader_use (display->shader_upload_I420_YV12);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Utex");
|
gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Utex", 1);
|
||||||
glUniform1iARB (i, 1);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2310,8 +2379,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE2_ARB);
|
glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Vtex");
|
gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Vtex", 2);
|
||||||
glUniform1iARB (i, 2);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_v);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_v);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2319,8 +2387,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Ytex");
|
gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Ytex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2333,14 +2400,13 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture,
|
||||||
{
|
{
|
||||||
gint i=0;
|
gint i=0;
|
||||||
|
|
||||||
glUseProgramObjectARB (display->GLSLProgram_AYUV);
|
gst_gl_shader_use (display->shader_upload_AYUV);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_AYUV, "tex");
|
gst_gl_shader_set_uniform_1i (display->shader_upload_AYUV, "tex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -2433,15 +2499,15 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display)
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
{
|
{
|
||||||
gint i=0;
|
gint i=0;
|
||||||
GLhandleARB GLSLProgram_to_YUY2_UYVY = 0;
|
GstGLShader* shader_download_YUY2_UYVY = NULL;
|
||||||
|
|
||||||
switch (video_format)
|
switch (video_format)
|
||||||
{
|
{
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
GLSLProgram_to_YUY2_UYVY = display->GLSLProgram_to_YUY2;
|
shader_download_YUY2_UYVY = display->shader_download_YUY2;
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
GLSLProgram_to_YUY2_UYVY = display->GLSLProgram_to_UYVY;
|
shader_download_YUY2_UYVY = display->shader_download_UYVY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@ -2452,14 +2518,13 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display)
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgramObjectARB (GLSLProgram_to_YUY2_UYVY);
|
gst_gl_shader_use (shader_download_YUY2_UYVY);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (GLSLProgram_to_YUY2_UYVY, "tex");
|
gst_gl_shader_set_uniform_1i (shader_download_YUY2_UYVY, "tex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2474,18 +2539,17 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display)
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgramObjectARB (display->GLSLProgram_to_I420_YV12);
|
gst_gl_shader_use (display->shader_download_I420_YV12);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "tex");
|
gst_gl_shader_set_uniform_1i (display->shader_download_I420_YV12, "tex", 0);
|
||||||
glUniform1iARB (i, 0);
|
gst_gl_shader_set_uniform_1f (display->shader_download_I420_YV12, "w",
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "w");
|
(gfloat)display->ouput_texture_width);
|
||||||
glUniform1fARB (i, (gfloat)display->ouput_texture_width);
|
gst_gl_shader_set_uniform_1f (display->shader_download_I420_YV12, "h",
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "h");
|
(gfloat)display->ouput_texture_height);
|
||||||
glUniform1fARB (i, (gfloat)display->ouput_texture_height);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2499,14 +2563,13 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display)
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgramObjectARB (display->GLSLProgram_to_AYUV);
|
gst_gl_shader_use (display->shader_download_AYUV);
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (display->GLSLProgram_to_AYUV, "tex");
|
gst_gl_shader_set_uniform_1i (display->shader_download_AYUV, "tex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2529,6 +2592,9 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display)
|
||||||
|
|
||||||
glDrawBuffer(GL_NONE);
|
glDrawBuffer(GL_NONE);
|
||||||
|
|
||||||
|
//dot not check if GLSL is available
|
||||||
|
//because for now download is not available
|
||||||
|
//without GLSL
|
||||||
glUseProgramObjectARB (0);
|
glUseProgramObjectARB (0);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
#include "gstglshader.h"
|
||||||
|
|
||||||
#define GST_TYPE_GL_DISPLAY \
|
#define GST_TYPE_GL_DISPLAY \
|
||||||
(gst_gl_display_get_type())
|
(gst_gl_display_get_type())
|
||||||
#define GST_GL_DISPLAY(obj) \
|
#define GST_GL_DISPLAY(obj) \
|
||||||
|
@ -204,31 +206,31 @@ struct _GstGLDisplay {
|
||||||
GLuint ouput_texture_height;
|
GLuint ouput_texture_height;
|
||||||
|
|
||||||
//action gen and del shader
|
//action gen and del shader
|
||||||
gchar* gen_text_shader;
|
const gchar* gen_text_shader;
|
||||||
GLhandleARB gen_handle_shader;
|
GstGLShader* gen_shader;
|
||||||
GLhandleARB del_handle_shader;
|
GstGLShader* del_shader;
|
||||||
|
|
||||||
//fragement shader upload
|
//fragement shader upload
|
||||||
gchar* textFProgram_YUY2_UYVY;
|
gchar* text_shader_upload_YUY2_UYVY;
|
||||||
GLhandleARB GLSLProgram_YUY2;
|
GstGLShader* shader_upload_YUY2;
|
||||||
GLhandleARB GLSLProgram_UYVY;
|
GstGLShader* shader_upload_UYVY;
|
||||||
|
|
||||||
gchar* textFProgram_I420_YV12;
|
gchar* text_shader_upload_I420_YV12;
|
||||||
GLhandleARB GLSLProgram_I420_YV12;
|
GstGLShader* shader_upload_I420_YV12;
|
||||||
|
|
||||||
gchar* textFProgram_AYUV;
|
gchar* text_shader_upload_AYUV;
|
||||||
GLhandleARB GLSLProgram_AYUV;
|
GstGLShader* shader_upload_AYUV;
|
||||||
|
|
||||||
//fragement shader download
|
//fragement shader download
|
||||||
gchar* textFProgram_to_YUY2_UYVY;
|
gchar* text_shader_download_YUY2_UYVY;
|
||||||
GLhandleARB GLSLProgram_to_YUY2;
|
GstGLShader* shader_download_YUY2;
|
||||||
GLhandleARB GLSLProgram_to_UYVY;
|
GstGLShader* shader_download_UYVY;
|
||||||
|
|
||||||
gchar* textFProgram_to_I420_YV12;
|
gchar* text_shader_download_I420_YV12;
|
||||||
GLhandleARB GLSLProgram_to_I420_YV12;
|
GstGLShader* shader_download_I420_YV12;
|
||||||
|
|
||||||
gchar* textFProgram_to_AYUV;
|
gchar* text_shader_download_AYUV;
|
||||||
GLhandleARB GLSLProgram_to_AYUV;
|
GstGLShader* shader_download_AYUV;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,8 +280,8 @@ void gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint
|
||||||
void gst_gl_display_del_fbo (GstGLDisplay* display, GLuint fbo,
|
void gst_gl_display_del_fbo (GstGLDisplay* display, GLuint fbo,
|
||||||
GLuint depth_buffer);
|
GLuint depth_buffer);
|
||||||
|
|
||||||
void gst_gl_display_gen_shader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader);
|
void gst_gl_display_gen_shader (GstGLDisplay* display, const gchar* textShader, GstGLShader** shader);
|
||||||
void gst_gl_display_del_shader (GstGLDisplay* display, GLhandleARB shader);
|
void gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader);
|
||||||
|
|
||||||
void gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId);
|
void gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId);
|
||||||
void gst_gl_display_set_client_reshape_callback (GstGLDisplay* display, CRCB cb);
|
void gst_gl_display_set_client_reshape_callback (GstGLDisplay* display, CRCB cb);
|
||||||
|
|
|
@ -55,6 +55,37 @@ static gboolean gst_gl_filter_edge_filter (GstGLFilter * filter,
|
||||||
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
|
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
|
||||||
static void gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer stuff);
|
static void gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer stuff);
|
||||||
|
|
||||||
|
static const gchar *sobel_fragment_source =
|
||||||
|
"uniform sampler2DRect tex;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" const int N = 8;\n"
|
||||||
|
" const vec2 delta[N] = vec2[N](\n"
|
||||||
|
" vec2( -1.0, -1.0 ),\n"
|
||||||
|
" vec2( -1.0 , 0.0 ),\n"
|
||||||
|
" vec2( -1.0 , 1.0 ),\n"
|
||||||
|
" vec2( 0.0 , 1.0 ),\n"
|
||||||
|
" vec2( 1.0 , 1.0 ),\n"
|
||||||
|
" vec2( 1.0 , 0.0 ),\n"
|
||||||
|
" vec2( 1.0 , -1.0 ),\n"
|
||||||
|
" vec2( 0.0 , -1.0 )\n"
|
||||||
|
" );\n"
|
||||||
|
" const float filterH[N] = float[N]\n"
|
||||||
|
" (-1.0, 0.0, 1.0, 2.0, 1.0, 0.0, -1.0, -2.0);\n"
|
||||||
|
" const float filterV[N] = float[N]\n"
|
||||||
|
" (-1.0, -2.0, -1.0, 0.0, 1.0, 2.0, 1.0, 0.0);\n"
|
||||||
|
" float gH = 0.0;\n"
|
||||||
|
" float gV = 0.0;\n"
|
||||||
|
" int i;\n"
|
||||||
|
" vec2 nxy = gl_TexCoord[0].xy;\n"
|
||||||
|
" for (i = 0; i < N; i++) {\n"
|
||||||
|
" vec4 vcolor_i = texture2DRect(tex, nxy + delta[i]);\n"
|
||||||
|
" float gray_i = (vcolor_i.r + vcolor_i.g + vcolor_i.b) / 3.0;\n"
|
||||||
|
" gH += gH + filterH[i] * gray_i;\n"
|
||||||
|
" gV += gV + filterV[i] * gray_i;\n"
|
||||||
|
" }\n"
|
||||||
|
" float g = sqrt(gH * gH + gV * gV) / 256.0;\n"
|
||||||
|
" gl_FragColor = vec4(g, g, g, 1.0);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_filter_edge_base_init (gpointer klass)
|
gst_gl_filter_edge_base_init (gpointer klass)
|
||||||
|
@ -82,38 +113,7 @@ static void
|
||||||
gst_gl_filter_edge_init (GstGLFilterEdge* filter,
|
gst_gl_filter_edge_init (GstGLFilterEdge* filter,
|
||||||
GstGLFilterEdgeClass* klass)
|
GstGLFilterEdgeClass* klass)
|
||||||
{
|
{
|
||||||
filter->handleShader = 0;
|
filter->shader = NULL;
|
||||||
filter->textShader =
|
|
||||||
"uniform sampler2DRect tex;\n"
|
|
||||||
"void main(void) {\n"
|
|
||||||
" const int N = 8;\n"
|
|
||||||
" const vec2 delta[N] = vec2[N](\n"
|
|
||||||
" vec2( -1.0, -1.0 ),\n"
|
|
||||||
" vec2( -1.0 , 0.0 ),\n"
|
|
||||||
" vec2( -1.0 , 1.0 ),\n"
|
|
||||||
" vec2( 0.0 , 1.0 ),\n"
|
|
||||||
" vec2( 1.0 , 1.0 ),\n"
|
|
||||||
" vec2( 1.0 , 0.0 ),\n"
|
|
||||||
" vec2( 1.0 , -1.0 ),\n"
|
|
||||||
" vec2( 0.0 , -1.0 )\n"
|
|
||||||
" );\n"
|
|
||||||
" const float filterH[N] = float[N]\n"
|
|
||||||
" (-1.0, 0.0, 1.0, 2.0, 1.0, 0.0, -1.0, -2.0);\n"
|
|
||||||
" const float filterV[N] = float[N]\n"
|
|
||||||
" (-1.0, -2.0, -1.0, 0.0, 1.0, 2.0, 1.0, 0.0);\n"
|
|
||||||
" float gH = 0.0;\n"
|
|
||||||
" float gV = 0.0;\n"
|
|
||||||
" int i;\n"
|
|
||||||
" vec2 nxy = gl_TexCoord[0].xy;\n"
|
|
||||||
" for (i = 0; i < N; i++) {\n"
|
|
||||||
" vec4 vcolor_i = texture2DRect(tex, nxy + delta[i]);\n"
|
|
||||||
" float gray_i = (vcolor_i.r + vcolor_i.g + vcolor_i.b) / 3.0;\n"
|
|
||||||
" gH += gH + filterH[i] * gray_i;\n"
|
|
||||||
" gV += gV + filterV[i] * gray_i;\n"
|
|
||||||
" }\n"
|
|
||||||
" float g = sqrt(gH * gH + gV * gV) / 256.0;\n"
|
|
||||||
" gl_FragColor = vec4(g, g, g, 1.0);\n"
|
|
||||||
"}\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -121,8 +121,8 @@ gst_gl_filter_edge_reset (GstGLFilter* filter)
|
||||||
{
|
{
|
||||||
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter);
|
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter);
|
||||||
|
|
||||||
//blocking call, wait the opengl thread has destroyed the shader program
|
//blocking call, wait the opengl thread has destroyed the shader
|
||||||
gst_gl_display_del_shader (filter->display, edge_filter->handleShader);
|
gst_gl_display_del_shader (filter->display, edge_filter->shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -159,7 +159,7 @@ gst_gl_filter_edge_init_shader (GstGLFilter* filter)
|
||||||
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE (filter);
|
GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE (filter);
|
||||||
|
|
||||||
//blocking call, wait the opengl thread has compiled the shader program
|
//blocking call, wait the opengl thread has compiled the shader program
|
||||||
gst_gl_display_gen_shader (filter->display, edge_filter->textShader, &edge_filter->handleShader);
|
gst_gl_display_gen_shader (filter->display, sobel_fragment_source, &edge_filter->shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -188,11 +188,10 @@ gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer st
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
glUseProgramObjectARB (edge_filter->handleShader);
|
gst_gl_shader_use (edge_filter->shader);
|
||||||
|
|
||||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
i = glGetUniformLocationARB (edge_filter->handleShader, "tex");
|
gst_gl_shader_set_uniform_1i (edge_filter->shader, "tex", 0);
|
||||||
glUniform1iARB (i, 0);
|
|
||||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
|
|
||||||
glBegin (GL_QUADS);
|
glBegin (GL_QUADS);
|
||||||
|
|
|
@ -38,9 +38,7 @@ typedef struct _GstGLFilterEdgeClass GstGLFilterEdgeClass;
|
||||||
struct _GstGLFilterEdge
|
struct _GstGLFilterEdge
|
||||||
{
|
{
|
||||||
GstGLFilter filter;
|
GstGLFilter filter;
|
||||||
|
GstGLShader *shader;
|
||||||
gchar* textShader;
|
|
||||||
GLhandleARB handleShader;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLFilterEdgeClass
|
struct _GstGLFilterEdgeClass
|
||||||
|
|
|
@ -62,8 +62,7 @@ static const gchar *convolution_fragment_source =
|
||||||
"uniform float norm_offset;"
|
"uniform float norm_offset;"
|
||||||
"uniform float kernel[9];"
|
"uniform float kernel[9];"
|
||||||
"void main () {"
|
"void main () {"
|
||||||
" const int N = 9;"
|
" vec2 offset[9] = vec2[9] ("
|
||||||
" const vec2 offset[N] = vec2[N] ("
|
|
||||||
" vec2(-1.0,-1.0), vec2( 0.0,-1.0), vec2( 1.0,-1.0),"
|
" vec2(-1.0,-1.0), vec2( 0.0,-1.0), vec2( 1.0,-1.0),"
|
||||||
" vec2(-1.0, 0.0), vec2( 0.0, 0.0), vec2( 1.0, 0.0),"
|
" vec2(-1.0, 0.0), vec2( 0.0, 0.0), vec2( 1.0, 0.0),"
|
||||||
" vec2(-1.0, 1.0), vec2( 0.0, 1.0), vec2( 1.0, 1.0) );"
|
" vec2(-1.0, 1.0), vec2( 0.0, 1.0), vec2( 1.0, 1.0) );"
|
||||||
|
@ -105,26 +104,16 @@ static void
|
||||||
gst_gl_filter_laplacian_init (GstGLFilterLaplacian* filter,
|
gst_gl_filter_laplacian_init (GstGLFilterLaplacian* filter,
|
||||||
GstGLFilterLaplacianClass* klass)
|
GstGLFilterLaplacianClass* klass)
|
||||||
{
|
{
|
||||||
|
filter->shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_filter_laplacian_reset (GstGLFilter* filter)
|
gst_gl_filter_laplacian_reset (GstGLFilter* filter)
|
||||||
{
|
{
|
||||||
//GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN(filter);
|
GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN(filter);
|
||||||
|
|
||||||
//I commented the following line to avoid a crash for now
|
//blocking call, wait the opengl thread has destroyed the shader
|
||||||
//It crashs because when unreferencing the GstGLShader
|
gst_gl_display_del_shader (filter->display, laplacian_filter->shader);
|
||||||
//if ref is down to 0 it causes a finalize then a gst_gl_shader_release
|
|
||||||
//then a glDeleteObjectARB
|
|
||||||
//and this glDeleteObjectARB must be executed in by (in) the gl thread
|
|
||||||
//How to do that so ? Easy, using the gst_gl_display_del_shader method
|
|
||||||
//but I have not modified it yet (*1*) to use GstGLShader
|
|
||||||
//I'll do that soon so just comment the following line for now
|
|
||||||
//g_object_unref (G_OBJECT (laplacian_filter->shader));
|
|
||||||
|
|
||||||
//blocking call, wait the opengl thread has destroyed the GstGLShader
|
|
||||||
//Commented for the reason *1*
|
|
||||||
//gst_gl_display_del_shader (filter->display, laplacian_filter->shader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -158,14 +147,10 @@ gst_gl_filter_laplacian_get_property (GObject* object, guint prop_id,
|
||||||
static void
|
static void
|
||||||
gst_gl_filter_laplacian_init_shader (GstGLFilter* filter)
|
gst_gl_filter_laplacian_init_shader (GstGLFilter* filter)
|
||||||
{
|
{
|
||||||
// GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
|
GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
|
||||||
|
|
||||||
// at the moment I do everything in the laplacian_callback
|
//blocking call, wait the opengl thread has compiled the shader
|
||||||
// ok, then for the same reason *1* explained in the
|
gst_gl_display_gen_shader (filter->display, convolution_fragment_source, &laplacian_filter->shader);
|
||||||
// gst_gl_filter_laplacian_reset method I comment the following line
|
|
||||||
|
|
||||||
//blocking call, wait the opengl thread has destroyed the shader program
|
|
||||||
//gst_gl_display_del_shader (filter->display, laplacian_filter->shader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -197,17 +182,6 @@ gst_gl_filter_laplacian_callback (gint width, gint height, guint texture, gpoint
|
||||||
glMatrixMode (GL_PROJECTION);
|
glMatrixMode (GL_PROJECTION);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
|
||||||
/* compile and link the shader (if not done previously) */
|
|
||||||
//FIXME: do it in the gst_gl_filter_laplacian_init_shader method
|
|
||||||
if (!laplacian_filter->shader)
|
|
||||||
{
|
|
||||||
laplacian_filter->shader = gst_gl_shader_new ();
|
|
||||||
|
|
||||||
g_return_if_fail (
|
|
||||||
gst_gl_shader_compile_and_check (laplacian_filter->shader, convolution_fragment_source,
|
|
||||||
GST_GL_SHADER_FRAGMENT_SOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_gl_shader_use (laplacian_filter->shader);
|
gst_gl_shader_use (laplacian_filter->shader);
|
||||||
|
|
||||||
glActiveTexture (GL_TEXTURE0);
|
glActiveTexture (GL_TEXTURE0);
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#define _GST_GL_FILTERLAPLACIAN_H_
|
#define _GST_GL_FILTERLAPLACIAN_H_
|
||||||
|
|
||||||
#include <gstglfilter.h>
|
#include <gstglfilter.h>
|
||||||
#include <gstglshader.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue