diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index b95ce640c5..c1ca070eab 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -466,6 +466,8 @@ gst_gl_display_init (GstGLDisplay * display, GstGLDisplayClass * klass) " gl_FragColor = texture2D( s_texture, v_texCoord );\n" "} \n"; #endif + + display->error_message = NULL; } static void @@ -532,6 +534,11 @@ gst_gl_display_finalize (GObject * object) display->use_fbo_scene_cb_v2 = NULL; if (display->use_fbo_stuff) display->use_fbo_stuff = NULL; + + if (display->error_message) { + g_free (display->error_message); + display->error_message = NULL; + } } @@ -540,6 +547,22 @@ gst_gl_display_finalize (GObject * object) //------------------------------------------------------------ /* Called in the gl thread */ + +void +gst_gl_display_set_error (GstGLDisplay * display, const char *format, ...) +{ + va_list args; + + if (display->error_message) + g_free (display->error_message); + + va_start (args, format); + display->error_message = g_strdup_vprintf (format, args); + va_end (args); + + display->isAlive = FALSE; +} + gpointer gst_gl_display_thread_create_context (GstGLDisplay * display) { @@ -549,8 +572,7 @@ gst_gl_display_thread_create_context (GstGLDisplay * display) display->gl_window = gst_gl_window_new (display->external_gl_context); if (!display->gl_window) { - display->isAlive = FALSE; - GST_ERROR_OBJECT (display, "Failed to create gl window"); + gst_gl_display_set_error (display, "Failed to create gl window"); g_cond_signal (display->cond_create_context); gst_gl_display_unlock (display); return NULL; @@ -563,9 +585,8 @@ gst_gl_display_thread_create_context (GstGLDisplay * display) #endif if (err != GLEW_OK) { #ifndef OPENGL_ES2 - GST_ERROR_OBJECT (display, "Failed to init GLEW: %s", + gst_gl_display_set_error (display, "Failed to init GLEW: %s", glewGetErrorString (err)); - display->isAlive = FALSE; #endif } else { //OpenGL > 1.2.0 and Glew > 1.4.0 @@ -600,13 +621,12 @@ gst_gl_display_thread_create_context (GstGLDisplay * display) && opengl_version_minor < 2) || (GLEW_VERSION_MAJOR < 2 && GLEW_VERSION_MAJOR >= 1 && GLEW_VERSION_MINOR < 4)) { //turn off the pipeline, the old drivers are not yet supported - GST_WARNING ("Required OpenGL >= 1.2.0 and Glew >= 1.4.0"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Required OpenGL >= 1.2.0 and Glew >= 1.4.0"); } #else if (!GL_ES_VERSION_2_0) { - GST_WARNING ("Required OpenGL ES > 2.0"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, "Required OpenGL ES > 2.0"); } #endif } @@ -788,11 +808,10 @@ gst_gl_display_thread_init_redisplay (GstGLDisplay * display) gst_gl_shader_compile (display->redisplay_shader, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; } else { display->redisplay_attr_position_loc = gst_gl_shader_get_attribute_location (display->redisplay_shader, @@ -861,7 +880,8 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) #ifndef OPENGL_ES2 if (!gst_gl_shader_compile_and_check (display->shader_upload_YUY2, text_shader_upload_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for uploading YUY2"); g_object_unref (G_OBJECT (display->shader_upload_YUY2)); display->shader_upload_YUY2 = NULL; } @@ -873,11 +893,10 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) gst_gl_shader_compile (display->shader_upload_YUY2, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_upload_YUY2)); display->shader_upload_YUY2 = NULL; } else { @@ -906,7 +925,8 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) #ifndef OPENGL_ES2 if (!gst_gl_shader_compile_and_check (display->shader_upload_UYVY, text_shader_upload_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for uploading UYVY"); g_object_unref (G_OBJECT (display->shader_upload_UYVY)); display->shader_upload_UYVY = NULL; } @@ -918,11 +938,10 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) gst_gl_shader_compile (display->shader_upload_UYVY, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_upload_UYVY)); display->shader_upload_UYVY = NULL; } else { @@ -960,7 +979,8 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) if (!gst_gl_shader_compile_and_check (display->shader_upload_I420_YV12, text_shader_upload_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for uploading I420 or YV12"); g_object_unref (G_OBJECT (display->shader_upload_I420_YV12)); display->shader_upload_I420_YV12 = NULL; } @@ -972,11 +992,10 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) gst_gl_shader_compile (display->shader_upload_I420_YV12, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_upload_I420_YV12)); display->shader_upload_I420_YV12 = NULL; } else { @@ -998,7 +1017,8 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) if (!gst_gl_shader_compile_and_check (display->shader_upload_AYUV, display->text_shader_upload_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for uploading AYUV"); g_object_unref (G_OBJECT (display->shader_upload_AYUV)); display->shader_upload_AYUV = NULL; } @@ -1010,11 +1030,10 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) gst_gl_shader_compile (display->shader_upload_AYUV, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_upload_AYUV)); display->shader_upload_AYUV = NULL; } else { @@ -1055,9 +1074,8 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) case GST_VIDEO_FORMAT_AYUV: //turn off the pipeline because //MESA only support YUY2 and UYVY - GST_WARNING - ("Your MESA version only supports YUY2 and UYVY (GLSL is required for others yuv formats"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Your MESA version only supports YUY2 and UYVY (GLSL is required for others yuv formats)"); break; default: g_assert_not_reached (); @@ -1074,16 +1092,12 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display) GST_GL_DISPLAY_CONVERSION_MATRIX; //turn off the pipeline because we do not support it yet - GST_WARNING - ("Colorspace conversion using Color Matrix is not yet supported"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Colorspace conversion using Color Matrix is not yet supported"); } else { - GST_WARNING ("Context, ARB_fragment_shader supported: no"); - GST_WARNING ("Context, GLEW_ARB_imaging supported: no"); - GST_WARNING ("Context, GLEW_MESA_ycbcr_texture supported: no"); - //turn off the pipeline because colorspace conversion is not possible - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "ARB_fragment_shader supported, GLEW_ARB_imaging supported, GLEW_MESA_ycbcr_texture supported, not supported"); } } break; @@ -1298,8 +1312,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) } else { //turn off the pipeline because Frame buffer object is a requirement when using filters //or when using GLSL colorspace conversion - GST_WARNING ("Context, EXT_framebuffer_object supported: no"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Context, EXT_framebuffer_object supported: no"); } } break; @@ -1332,11 +1346,10 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) gst_gl_shader_compile (display->shader_download_RGB, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_download_RGB)); display->shader_download_RGB = NULL; } else { @@ -1376,7 +1389,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) #ifndef OPENGL_ES2 if (!gst_gl_shader_compile_and_check (display->shader_download_YUY2, text_shader_download_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for downloading YUY2"); g_object_unref (G_OBJECT (display->shader_download_YUY2)); display->shader_download_YUY2 = NULL; } @@ -1388,11 +1402,10 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) gst_gl_shader_compile (display->shader_download_YUY2, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_download_YUY2)); display->shader_download_YUY2 = NULL; } else { @@ -1417,7 +1430,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) #ifndef OPENGL_ES2 if (!gst_gl_shader_compile_and_check (display->shader_download_UYVY, text_shader_download_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for downloading UYVY"); g_object_unref (G_OBJECT (display->shader_download_UYVY)); display->shader_download_UYVY = NULL; } @@ -1429,11 +1443,10 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) gst_gl_shader_compile (display->shader_download_UYVY, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_download_UYVY)); display->shader_download_UYVY = NULL; } else { @@ -1455,7 +1468,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) (display->shader_download_I420_YV12, display->text_shader_download_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for downloading I420 or YV12"); g_object_unref (G_OBJECT (display->shader_download_I420_YV12)); display->shader_download_I420_YV12 = NULL; } @@ -1467,7 +1481,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) if (!gst_gl_shader_compile_and_check (display->shader_download_AYUV, display->text_shader_download_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) { - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Failed to initialize shader for downloading AYUV"); g_object_unref (G_OBJECT (display->shader_download_AYUV)); display->shader_download_AYUV = NULL; } @@ -1479,11 +1494,10 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) gst_gl_shader_compile (display->shader_download_AYUV, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->shader_download_AYUV)); display->shader_download_AYUV = NULL; } else { @@ -1501,8 +1515,8 @@ gst_gl_display_thread_init_download (GstGLDisplay * display) } } else { //turn off the pipeline because colorspace conversion is not possible - GST_WARNING ("Context, ARB_fragment_shader supported: no"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Context, ARB_fragment_shader supported: no"); } } break; @@ -1555,8 +1569,8 @@ gst_gl_display_thread_gen_fbo (GstGLDisplay * display) if (!GLEW_EXT_framebuffer_object) { //turn off the pipeline because Frame buffer object is a not present - GST_WARNING ("Context, EXT_framebuffer_object supported: no"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Context, EXT_framebuffer_object not supported"); return; } //setup FBO @@ -1752,7 +1766,6 @@ gst_gl_display_thread_gen_shader (GstGLDisplay * display) if (GLEW_ARB_fragment_shader) { if (display->gen_shader_vertex_source || display->gen_shader_fragment_source) { - gboolean isAlive = TRUE; GError *error = NULL; display->gen_shader = gst_gl_shader_new (); @@ -1767,22 +1780,17 @@ gst_gl_display_thread_gen_shader (GstGLDisplay * display) gst_gl_shader_compile (display->gen_shader, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (display, "%s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); - isAlive = FALSE; - } - - if (!isAlive) { - display->isAlive = FALSE; g_object_unref (G_OBJECT (display->gen_shader)); display->gen_shader = NULL; } } } else { - GST_WARNING ("One of the filter required ARB_fragment_shader"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "One of the filter required ARB_fragment_shader"); display->gen_shader = NULL; } } @@ -1956,9 +1964,7 @@ gst_gl_display_on_draw (GstGLDisplay * display) void gst_gl_display_on_close (GstGLDisplay * display) { - GST_INFO ("on close"); - - display->isAlive = FALSE; + gst_gl_display_set_error (display, "Output window was closed"); } @@ -2143,10 +2149,12 @@ gst_gl_display_new (void) /* Create an opengl context (one context for one GstGLDisplay) */ -void +gboolean gst_gl_display_create_context (GstGLDisplay * display, gulong external_gl_context) { + gboolean isAlive = FALSE; + gst_gl_display_lock (display); if (!display->gl_window) { @@ -2161,7 +2169,11 @@ gst_gl_display_create_context (GstGLDisplay * display, GST_INFO ("gl thread created"); } + isAlive = display->isAlive; + gst_gl_display_unlock (display); + + return isAlive; } @@ -2192,6 +2204,7 @@ gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, display->keep_aspect_ratio = keep_aspect_ratio; if (display->gl_window) gst_gl_window_draw (display->gl_window, window_width, window_height); + isAlive = display->isAlive; } gst_gl_display_unlock (display); @@ -2266,10 +2279,12 @@ gst_gl_display_del_texture (GstGLDisplay * display, GLuint texture, GLint width, /* Called by the first gl element of a video/x-raw-gl flow */ -void +gboolean gst_gl_display_init_upload (GstGLDisplay * display, GstVideoFormat video_format, guint gl_width, guint gl_height, gint video_width, gint video_height) { + gboolean isAlive = FALSE; + gst_gl_display_lock (display); display->upload_video_format = video_format; display->upload_width = gl_width; @@ -2278,7 +2293,10 @@ gst_gl_display_init_upload (GstGLDisplay * display, GstVideoFormat video_format, display->upload_data_height = video_height; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_init_upload), display); + isAlive = display->isAlive; gst_gl_display_unlock (display); + + return isAlive; } @@ -2298,6 +2316,7 @@ gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture, display->upload_data = data; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_do_upload), display); + isAlive = display->isAlive; } gst_gl_display_unlock (display); @@ -2306,17 +2325,22 @@ gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture, /* Called by the gldownload and glcolorscale element */ -void +gboolean gst_gl_display_init_download (GstGLDisplay * display, GstVideoFormat video_format, gint width, gint height) { + gboolean isAlive = FALSE; + gst_gl_display_lock (display); display->download_video_format = video_format; display->download_width = width; display->download_height = height; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_init_download), display); + isAlive = display->isAlive; gst_gl_display_unlock (display); + + return isAlive; } @@ -2337,6 +2361,7 @@ gst_gl_display_do_download (GstGLDisplay * display, GLuint texture, display->ouput_texture_height = height; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_do_download), display); + isAlive = display->isAlive; } gst_gl_display_unlock (display); @@ -2345,10 +2370,12 @@ gst_gl_display_do_download (GstGLDisplay * display, GLuint texture, /* Called by gltestsrc and glfilter */ -void +gboolean gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height, GLuint * fbo, GLuint * depthbuffer) { + gboolean isAlive = FALSE; + gst_gl_display_lock (display); if (display->isAlive) { display->gen_fbo_width = width; @@ -2357,8 +2384,11 @@ gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height, GST_GL_WINDOW_CB (gst_gl_display_thread_gen_fbo), display); *fbo = display->generated_fbo; *depthbuffer = display->generated_depth_buffer; + isAlive = display->isAlive; } gst_gl_display_unlock (display); + + return isAlive; } @@ -2400,6 +2430,7 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width, display->input_texture = input_texture; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_use_fbo), display); + isAlive = display->isAlive; } gst_gl_display_unlock (display); @@ -2425,6 +2456,7 @@ gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width, display->use_fbo_stuff = stuff; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_use_fbo_v2), display); + isAlive = display->isAlive; } gst_gl_display_unlock (display); @@ -2445,22 +2477,27 @@ gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer) /* Called by glfilter */ -void +gboolean gst_gl_display_gen_shader (GstGLDisplay * display, const gchar * shader_vertex_source, const gchar * shader_fragment_source, GstGLShader ** shader) { + gboolean isAlive = FALSE; + gst_gl_display_lock (display); display->gen_shader_vertex_source = shader_vertex_source; display->gen_shader_fragment_source = shader_fragment_source; gst_gl_window_send_message (display->gl_window, GST_GL_WINDOW_CB (gst_gl_display_thread_gen_shader), display); + isAlive = display->isAlive; if (shader) *shader = display->gen_shader; display->gen_shader = NULL; display->gen_shader_vertex_source = NULL; display->gen_shader_fragment_source = NULL; gst_gl_display_unlock (display); + + return isAlive; } @@ -2611,8 +2648,8 @@ gst_gl_display_thread_init_upload_fbo (GstGLDisplay * display) gst_gl_display_thread_do_upload_make (display); } else { //turn off the pipeline because Frame buffer object is a not present - GST_WARNING ("Context, EXT_framebuffer_object supported: no"); - display->isAlive = FALSE; + gst_gl_display_set_error (display, + "Context, EXT_framebuffer_object supported: no"); } } diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 2ba0ef785d..5645b9dab0 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -40,6 +40,7 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY)) #define GST_IS_GL_DISPLAY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_DISPLAY)) +#define GST_GL_DISPLAY_CAST(obj) ((GstGLDisplay*)(obj)) typedef struct _GstGLDisplay GstGLDisplay; typedef struct _GstGLDisplayClass GstGLDisplayClass; @@ -77,6 +78,8 @@ typedef void (*GstGLDisplayThreadFunc) (GstGLDisplay * display, gpointer data); typedef void (*GLCB) (gint, gint, guint, gpointer stuff); typedef void (*GLCB_V2) (gpointer stuff); +#define GST_GL_DISPLAY_ERR_MSG(obj) (GST_GL_DISPLAY_CAST(obj)->error_message) + struct _GstGLDisplay { GObject object; @@ -224,6 +227,8 @@ struct _GstGLDisplay GstGLShader *shader_download_RGB; #endif + gchar *error_message; + }; @@ -240,7 +245,7 @@ GType gst_gl_display_get_type (void); //------------------------------------------------------------ GstGLDisplay *gst_gl_display_new (void); -void gst_gl_display_create_context (GstGLDisplay * display, +gboolean gst_gl_display_create_context (GstGLDisplay * display, gulong external_gl_context); gboolean gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture, gint gl_width, gint gl_height, gint window_width, gint window_height, @@ -254,17 +259,17 @@ void gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture, void gst_gl_display_del_texture (GstGLDisplay * display, GLuint texture, GLint width, GLint height); -void gst_gl_display_init_upload (GstGLDisplay * display, +gboolean gst_gl_display_init_upload (GstGLDisplay * display, GstVideoFormat video_format, guint gl_width, guint gl_height, gint video_width, gint video_height); gboolean gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture, gint data_width, gint data_height, gpointer data); -void gst_gl_display_init_download (GstGLDisplay * display, +gboolean gst_gl_display_init_download (GstGLDisplay * display, GstVideoFormat video_format, gint width, gint height); gboolean gst_gl_display_do_download (GstGLDisplay * display, GLuint texture, gint width, gint height, gpointer data); -void gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height, +gboolean gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height, GLuint * fbo, GLuint * depthbuffer); gboolean gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width, gint texture_fbo_height, GLuint fbo, GLuint depth_buffer, @@ -278,7 +283,7 @@ gboolean gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_wid void gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer); -void gst_gl_display_gen_shader (GstGLDisplay * display, +gboolean gst_gl_display_gen_shader (GstGLDisplay * display, const gchar * shader_vertex_source, const gchar * shader_fragment_source, GstGLShader ** shader); void gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader); @@ -292,6 +297,9 @@ void gst_gl_display_set_client_data (GstGLDisplay * display, gpointer data); gulong gst_gl_display_get_internal_gl_context (GstGLDisplay * display); void gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate); +/* Must be called inside a lock/unlock on display, or within the glthread */ +void gst_gl_display_set_error (GstGLDisplay * display, const char * format, ...); + G_END_DECLS #endif /* __GST_GL_H__ */ diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 1141a977ed..683792e7e8 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -263,8 +263,12 @@ gst_gl_filter_start (GstBaseTransform * bt) else { /* this gl filter is a sink in terms of the gl chain */ filter->display = gst_gl_display_new (); - gst_gl_display_create_context (filter->display, + isPerformed = gst_gl_display_create_context (filter->display, filter->external_gl_context); + + if (!isPerformed) + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (filter->display)), (NULL)); } } @@ -391,22 +395,39 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps, ret = gst_gl_buffer_parse_caps (outcaps, &filter->width, &filter->height); + if (!ret) { + GST_DEBUG ("bad caps"); + return FALSE; + } //blocking call, generate a FBO - gst_gl_display_gen_fbo (filter->display, filter->width, filter->height, + ret = gst_gl_display_gen_fbo (filter->display, filter->width, filter->height, &filter->fbo, &filter->depthbuffer); + if (!ret) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (filter->display)), (NULL)); + return FALSE; + } + if (filter_class->display_init_cb != NULL) { gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl, filter); } if (filter_class->onInitFBO) - filter_class->onInitFBO (filter); - - if (filter_class->set_caps) - filter_class->set_caps (filter, incaps, outcaps); + ret = filter_class->onInitFBO (filter); if (!ret) { - GST_DEBUG ("bad caps"); + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (filter->display)), (NULL)); + return FALSE; + } + + if (filter_class->set_caps) + ret = filter_class->set_caps (filter, incaps, outcaps); + + if (!ret) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (filter->display)), (NULL)); return FALSE; } diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h index 41bdc70a19..7430dfdb84 100644 --- a/gst-libs/gst/gl/gstglfilter.h +++ b/gst-libs/gst/gl/gstglfilter.h @@ -45,7 +45,7 @@ typedef gboolean (*GstGLFilterSetCaps) (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps); typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter, GstGLBuffer *inbuf, GstGLBuffer *outbuf); -typedef void (*GstGLFilterOnInitFBO) (GstGLFilter *filter); +typedef gboolean (*GstGLFilterOnInitFBO) (GstGLFilter *filter); typedef void (*GstGLFilterOnReset) (GstGLFilter *filter); typedef void (*GstGLFilterOnStart) (GstGLFilter *filter); typedef void (*GstGLFilterOnStop) (GstGLFilter *filter); diff --git a/gst-libs/gst/gl/gstglmixer.c b/gst-libs/gst/gl/gstglmixer.c index 476a02f519..deedd103d3 100644 --- a/gst-libs/gst/gl/gstglmixer.c +++ b/gst-libs/gst/gl/gstglmixer.c @@ -627,12 +627,18 @@ gst_gl_mixer_query (GstPad * pad, GstQuery * query) gst_gl_display_activate_gl_context (foreign_display, FALSE); - gst_gl_display_create_context (sink_pad->display, foreign_gl_context); + res = + gst_gl_display_create_context (sink_pad->display, + foreign_gl_context); gst_gl_display_activate_gl_context (foreign_display, TRUE); - gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, - sink_pad->display, NULL); + if (res) + gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, + sink_pad->display, NULL); + else + GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (sink_pad->display)), (NULL)); /* does not work: * res = gst_pad_query_default (GST_PAD_CAST (sink_pad), query);*/ @@ -695,8 +701,13 @@ gst_gl_mixer_setcaps (GstPad * pad, GstCaps * caps) GST_GL_MIXER_STATE_UNLOCK (mix); - gst_gl_display_gen_fbo (mix->display, mix->width, mix->height, - &mix->fbo, &mix->depthbuffer); + if (!gst_gl_display_gen_fbo (mix->display, mix->width, mix->height, + &mix->fbo, &mix->depthbuffer)) { + GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (mix->display)), (NULL)); + gst_object_unref (mix); + return FALSE; + } if (mixer_class->set_caps) mixer_class->set_caps (mix, caps); diff --git a/gst/gl/effects/gstgleffectbulge.c b/gst/gl/effects/gstgleffectbulge.c index 57e8ed4f76..d2629253c0 100644 --- a/gst/gl/effects/gstgleffectbulge.c +++ b/gst/gl/effects/gstgleffectbulge.c @@ -35,8 +35,14 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "bulge0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - bulge_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + bulge_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize bulge shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectfisheye.c b/gst/gl/effects/gstgleffectfisheye.c index ec7e873ab6..dbfe764ecb 100644 --- a/gst/gl/effects/gstgleffectfisheye.c +++ b/gst/gl/effects/gstgleffectfisheye.c @@ -35,8 +35,14 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "fisheye0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - fisheye_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + fisheye_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize fisheye shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectglow.c b/gst/gl/effects/gstgleffectglow.c index d4cf6d2e2a..225e336b50 100644 --- a/gst/gl/effects/gstgleffectglow.c +++ b/gst/gl/effects/gstgleffectglow.c @@ -38,8 +38,14 @@ gst_gl_effects_glow_step_one (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "glow0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - luma_threshold_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + luma_threshold_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize luma threshold shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -74,8 +80,14 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, kernel_ready = TRUE; } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize hconv7 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -107,8 +119,14 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "glow2", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize vcon7 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -140,8 +158,14 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "glow3", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sum_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + sum_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize sum shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectlumatocurve.c b/gst/gl/effects/gstgleffectlumatocurve.c index aafabec5df..5cd3ef26a8 100644 --- a/gst/gl/effects/gstgleffectlumatocurve.c +++ b/gst/gl/effects/gstgleffectlumatocurve.c @@ -35,8 +35,14 @@ gst_gl_effects_luma_to_curve (GstGLEffects * effects, g_hash_table_insert (effects->shaderstable, "lumamap0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize luma to curve shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectmirror.c b/gst/gl/effects/gstgleffectmirror.c index 4cb39ea6c4..3964590dfe 100644 --- a/gst/gl/effects/gstgleffectmirror.c +++ b/gst/gl/effects/gstgleffectmirror.c @@ -42,10 +42,14 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture, gst_gl_shader_compile (shader, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize mirror shader, %s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), + (NULL)); } else { effects->draw_attr_position_loc = gst_gl_shader_get_attribute_location (shader, "a_position"); @@ -55,10 +59,15 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture, } #endif } - #ifndef OPENGL_ES2 - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - mirror_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + mirror_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize mirror shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectrgbtocurve.c b/gst/gl/effects/gstgleffectrgbtocurve.c index e3138a7e3f..f397536689 100644 --- a/gst/gl/effects/gstgleffectrgbtocurve.c +++ b/gst/gl/effects/gstgleffectrgbtocurve.c @@ -35,8 +35,14 @@ gst_gl_effects_rgb_to_curve (GstGLEffects * effects, g_hash_table_insert (effects->shaderstable, "rgbmap0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - rgb_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + rgb_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize rgb to curve shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectsin.c b/gst/gl/effects/gstgleffectsin.c index 42a5e795b8..fe8843f2ee 100644 --- a/gst/gl/effects/gstgleffectsin.c +++ b/gst/gl/effects/gstgleffectsin.c @@ -35,8 +35,14 @@ gst_gl_effects_sin_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "sin0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sin_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + sin_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize sin shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectsquare.c b/gst/gl/effects/gstgleffectsquare.c index d23b0e9049..19fd0e0d72 100644 --- a/gst/gl/effects/gstgleffectsquare.c +++ b/gst/gl/effects/gstgleffectsquare.c @@ -35,8 +35,14 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "square0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize square shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectsqueeze.c b/gst/gl/effects/gstgleffectsqueeze.c index e1e80f86dd..b6c1b9aab5 100644 --- a/gst/gl/effects/gstgleffectsqueeze.c +++ b/gst/gl/effects/gstgleffectsqueeze.c @@ -42,10 +42,14 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gst_gl_shader_compile (shader, &error); if (error) { - GST_ERROR ("%s", error->message); + gst_gl_display_set_error (effects->display, + "Failed to initialize squeeze shader, %s", error->message); g_error_free (error); error = NULL; gst_gl_shader_use (NULL); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), + (NULL)); } else { effects->draw_attr_position_loc = gst_gl_shader_get_attribute_location (shader, "a_position"); @@ -55,11 +59,15 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, } #endif } - #ifndef OPENGL_ES2 - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - squeeze_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); - + if (!gst_gl_shader_compile_and_check (shader, + squeeze_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize squeeze shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); #endif diff --git a/gst/gl/effects/gstgleffectstretch.c b/gst/gl/effects/gstgleffectstretch.c index 95a1467762..ef28bfd77a 100644 --- a/gst/gl/effects/gstgleffectstretch.c +++ b/gst/gl/effects/gstgleffectstretch.c @@ -35,8 +35,14 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "stretch0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - stretch_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + stretch_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize stretch shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffecttunnel.c b/gst/gl/effects/gstgleffecttunnel.c index 66ad49ba8b..3d0ec94882 100644 --- a/gst/gl/effects/gstgleffecttunnel.c +++ b/gst/gl/effects/gstgleffecttunnel.c @@ -35,8 +35,14 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "tunnel0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - tunnel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + tunnel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize tunnel shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffecttwirl.c b/gst/gl/effects/gstgleffecttwirl.c index 9ab93d7c88..02db522450 100644 --- a/gst/gl/effects/gstgleffecttwirl.c +++ b/gst/gl/effects/gstgleffecttwirl.c @@ -35,8 +35,14 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "twirl0", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - twirl_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + twirl_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize twirl shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/effects/gstgleffectxray.c b/gst/gl/effects/gstgleffectxray.c index 5b7cc1d47f..1badfbf4f1 100644 --- a/gst/gl/effects/gstgleffectxray.c +++ b/gst/gl/effects/gstgleffectxray.c @@ -54,8 +54,14 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, kernel_ready = TRUE; } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize hconv7 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -87,8 +93,14 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray2", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize vconv7 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -121,8 +133,14 @@ gst_gl_effects_xray_desaturate (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray_desat", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - desaturate_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + desaturate_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize desaturate shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -152,8 +170,14 @@ gst_gl_effects_xray_sobel_hconv (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray_sob_hconv", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sep_sobel_hconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + sep_sobel_hconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize sobel hvonc3 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -183,8 +207,14 @@ gst_gl_effects_xray_sobel_vconv (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray_sob_vconv", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sep_sobel_vconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + sep_sobel_vconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize sobel vconv3 shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -214,8 +244,14 @@ gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray_sob_len", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize seobel length shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -248,8 +284,14 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray4", shader); } - g_return_if_fail (gst_gl_shader_compile_and_check (shader, - multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (shader, + multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (effects)->display, + "Failed to initialize multiply shader"); + GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (effects)->display)), (NULL)); + return; + } glMatrixMode (GL_PROJECTION); glLoadIdentity (); diff --git a/gst/gl/gstglbumper.c b/gst/gl/gstglbumper.c index 63bfe9a9aa..12efe7dc37 100644 --- a/gst/gl/gstglbumper.c +++ b/gst/gl/gstglbumper.c @@ -67,7 +67,7 @@ static void gst_gl_bumper_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_bumper_reset (GstGLFilter * filter); -static void gst_gl_bumper_init_shader (GstGLFilter * filter); +static gboolean gst_gl_bumper_init_shader (GstGLFilter * filter); static gboolean gst_gl_bumper_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_bumper_callback (gint width, gint height, guint texture, @@ -349,13 +349,13 @@ gst_gl_bumper_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_bumper_init_shader (GstGLFilter * filter) { GstGLBumper *bumper = GST_GL_BUMPER (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, bumper_v_src, bumper_f_src, + return gst_gl_display_gen_shader (filter->display, bumper_v_src, bumper_f_src, &bumper->shader); } diff --git a/gst/gl/gstglcolorscale.c b/gst/gl/gstglcolorscale.c index ffdfe1e154..930a26d3dc 100644 --- a/gst/gl/gstglcolorscale.c +++ b/gst/gl/gstglcolorscale.c @@ -390,19 +390,33 @@ gst_gl_colorscale_set_caps (GstBaseTransform * bt, GstCaps * incaps, colorscale->display = gst_gl_display_new (); //init unvisible opengl context - gst_gl_display_create_context (colorscale->display, 0); + ret = gst_gl_display_create_context (colorscale->display, 0); + if (!ret) { + GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (colorscale->display)), (NULL)); + return FALSE; + } //blocking call, init colorspace conversion if needed - gst_gl_display_init_upload (colorscale->display, + ret = gst_gl_display_init_upload (colorscale->display, colorscale->input_video_format, colorscale->output_video_width, colorscale->output_video_height, colorscale->input_video_width, colorscale->input_video_height); + if (!ret) { + GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (colorscale->display)), (NULL)); + return FALSE; + } //blocking call, init colorspace conversion if needed - gst_gl_display_init_download (colorscale->display, + ret = gst_gl_display_init_download (colorscale->display, colorscale->output_video_format, colorscale->output_video_width, colorscale->output_video_height); + if (!ret) + GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (colorscale->display)), (NULL)); + return ret; } diff --git a/gst/gl/gstgldeinterlace.c b/gst/gl/gstgldeinterlace.c index b34af713f5..9deebb45c2 100644 --- a/gst/gl/gstgldeinterlace.c +++ b/gst/gl/gstgldeinterlace.c @@ -58,100 +58,20 @@ static void gst_gl_deinterlace_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_deinterlace_reset (GstGLFilter * filter); -static void gst_gl_deinterlace_init_shader (GstGLFilter * filter); +static gboolean gst_gl_deinterlace_init_shader (GstGLFilter * filter); static gboolean gst_gl_deinterlace_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_deinterlace_callback (gint width, gint height, guint texture, gpointer stuff); -static const gchar *greedyh_fragment_source = - "#extension GL_ARB_texture_rectangle : enable\n" - "uniform sampler2DRect tex;\n" - "uniform sampler2DRect tex_prev;\n" - "uniform float max_comb;\n" - "uniform float motion_threshold;\n" - "uniform float motion_sense;\n" - "uniform int width;\n" - "uniform int height;\n" - "" - "void main () {\n" - " vec2 texcoord = gl_TexCoord[0].xy;\n" - " if (int(mod(texcoord.y, 2.0)) == 0)\n" - " gl_FragColor = vec4(texture2DRect(tex_prev, texcoord).rgb, 1.0);\n" - " else {\n" - "" // cannot have __ in a var so __ is replaced by _a - " vec2 texcoord_L1_a1, texcoord_L3_a1, texcoord_L1, texcoord_L3, texcoord_L1_1, texcoord_L3_1;\n" - " vec3 L1_a1, L3_a1, L1, L3, L1_1, L3_1;\n" - "" - " texcoord_L1 = vec2(texcoord.x, texcoord.y - 1.0);\n" - " texcoord_L3 = vec2(texcoord.x, texcoord.y + 1.0);\n" - " L1 = texture2DRect(tex_prev, texcoord_L1).rgb;\n" - " L3 = texture2DRect(tex_prev, texcoord_L3).rgb;\n" - " if (int(ceil(texcoord.x)) == width && int(ceil(texcoord.y)) == height) {\n" - " L1_1 = L1;\n" - " L3_1 = L3;\n" - " } else {\n" - " texcoord_L1_1 = vec2(texcoord.x + 1.0, texcoord.y - 1.0);\n" - " texcoord_L3_1 = vec2(texcoord.x + 1.0, texcoord.y + 1.0);\n" - " L1_1 = texture2DRect(tex_prev, texcoord_L1_1).rgb;\n" - " L3_1 = texture2DRect(tex_prev, texcoord_L3_1).rgb;\n" - " }\n" - " if (int(ceil(texcoord.x + texcoord.y)) == 0) {\n" - " L1_a1 = L1;\n" - " L3_a1 = L3;\n" - " } else {\n" - " texcoord_L1_a1 = vec2(texcoord.x - 1.0, texcoord.y - 1.0);\n" - " texcoord_L3_a1 = vec2(texcoord.x - 1.0, texcoord.y + 1.0);\n" - " L1_a1 = texture2DRect(tex_prev, texcoord_L1_a1).rgb;\n" - " L3_a1 = texture2DRect(tex_prev, texcoord_L3_a1).rgb;\n" - " }\n" - "" - "" //STEP 1 - " vec3 avg_a1 = (L1_a1 + L3_a1) / 2.0;\n" - " vec3 avg = (L1 + L3) / 2.0;\n" - " vec3 avg_1 = (L1_1 + L3_1) / 2.0;\n" - "" - " vec3 avg_s = (avg_a1 + avg_1) / 2.0;\n" - "" - " vec3 avg_sc = (avg_s + avg) / 2.0;\n" - "" - " vec3 L2 = texture2DRect(tex, texcoord).rgb;\n" - " vec3 LP2 = texture2DRect(tex_prev, texcoord).rgb;\n" - "" - " vec3 best;\n" - "" - " if (abs(L2.r - avg_sc.r) < abs(LP2.r - avg_sc.r)) {\n" - " best.r = L2.r;\n" - " } else {\n" - " best.r = LP2.r;\n" - " }\n" - "" - " if (abs(L2.g - avg_sc.g) < abs(LP2.g - avg_sc.g)) {\n" - " best.g = L2.g;\n" - " } else {\n" - " best.g = LP2.g;\n" - " }\n" - "" - " if (abs(L2.b - avg_sc.b) < abs(LP2.b - avg_sc.b)) {\n" - " best.b = L2.b;\n" - " } else {\n" - " best.b = LP2.b;\n" - " }\n" - "" - "" //STEP 2 - " vec3 last;\n" - " last.r = clamp(best.r, max(min(L1.r, L3.r) - max_comb, 0.0), min(max(L1.r, L3.r) + max_comb, 1.0));\n" - " last.g = clamp(best.g, max(min(L1.g, L3.g) - max_comb, 0.0), min(max(L1.g, L3.g) + max_comb, 1.0));\n" - " last.b = clamp(best.b, max(min(L1.b, L3.b) - max_comb, 0.0), min(max(L1.b, L3.b) + max_comb, 1.0));\n" - "" - "" //STEP 3 +static const gchar *greedyh_fragment_source = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" "uniform sampler2DRect tex_prev;\n" "uniform float max_comb;\n" "uniform float motion_threshold;\n" "uniform float motion_sense;\n" "uniform int width;\n" "uniform int height;\n" "" "void main () {\n" " vec2 texcoord = gl_TexCoord[0].xy;\n" " if (int(mod(texcoord.y, 2.0)) == 0)\n" " gl_FragColor = vec4(texture2DRect(tex_prev, texcoord).rgb, 1.0);\n" " else {\n" "" // cannot have __ in a var so __ is replaced by _a + " vec2 texcoord_L1_a1, texcoord_L3_a1, texcoord_L1, texcoord_L3, texcoord_L1_1, texcoord_L3_1;\n" " vec3 L1_a1, L3_a1, L1, L3, L1_1, L3_1;\n" "" " texcoord_L1 = vec2(texcoord.x, texcoord.y - 1.0);\n" " texcoord_L3 = vec2(texcoord.x, texcoord.y + 1.0);\n" " L1 = texture2DRect(tex_prev, texcoord_L1).rgb;\n" " L3 = texture2DRect(tex_prev, texcoord_L3).rgb;\n" " if (int(ceil(texcoord.x)) == width && int(ceil(texcoord.y)) == height) {\n" " L1_1 = L1;\n" " L3_1 = L3;\n" " } else {\n" " texcoord_L1_1 = vec2(texcoord.x + 1.0, texcoord.y - 1.0);\n" " texcoord_L3_1 = vec2(texcoord.x + 1.0, texcoord.y + 1.0);\n" " L1_1 = texture2DRect(tex_prev, texcoord_L1_1).rgb;\n" " L3_1 = texture2DRect(tex_prev, texcoord_L3_1).rgb;\n" " }\n" " if (int(ceil(texcoord.x + texcoord.y)) == 0) {\n" " L1_a1 = L1;\n" " L3_a1 = L3;\n" " } else {\n" " texcoord_L1_a1 = vec2(texcoord.x - 1.0, texcoord.y - 1.0);\n" " texcoord_L3_a1 = vec2(texcoord.x - 1.0, texcoord.y + 1.0);\n" " L1_a1 = texture2DRect(tex_prev, texcoord_L1_a1).rgb;\n" " L3_a1 = texture2DRect(tex_prev, texcoord_L3_a1).rgb;\n" " }\n" "" "" //STEP 1 + " vec3 avg_a1 = (L1_a1 + L3_a1) / 2.0;\n" " vec3 avg = (L1 + L3) / 2.0;\n" " vec3 avg_1 = (L1_1 + L3_1) / 2.0;\n" "" " vec3 avg_s = (avg_a1 + avg_1) / 2.0;\n" "" " vec3 avg_sc = (avg_s + avg) / 2.0;\n" "" " vec3 L2 = texture2DRect(tex, texcoord).rgb;\n" " vec3 LP2 = texture2DRect(tex_prev, texcoord).rgb;\n" "" " vec3 best;\n" "" " if (abs(L2.r - avg_sc.r) < abs(LP2.r - avg_sc.r)) {\n" " best.r = L2.r;\n" " } else {\n" " best.r = LP2.r;\n" " }\n" "" " if (abs(L2.g - avg_sc.g) < abs(LP2.g - avg_sc.g)) {\n" " best.g = L2.g;\n" " } else {\n" " best.g = LP2.g;\n" " }\n" "" " if (abs(L2.b - avg_sc.b) < abs(LP2.b - avg_sc.b)) {\n" " best.b = L2.b;\n" " } else {\n" " best.b = LP2.b;\n" " }\n" "" "" //STEP 2 + " vec3 last;\n" " last.r = clamp(best.r, max(min(L1.r, L3.r) - max_comb, 0.0), min(max(L1.r, L3.r) + max_comb, 1.0));\n" " last.g = clamp(best.g, max(min(L1.g, L3.g) - max_comb, 0.0), min(max(L1.g, L3.g) + max_comb, 1.0));\n" " last.b = clamp(best.b, max(min(L1.b, L3.b) - max_comb, 0.0), min(max(L1.b, L3.b) + max_comb, 1.0));\n" "" "" //STEP 3 " const vec3 luma = vec3 (0.299011, 0.586987, 0.114001);" " float mov = min(max(abs(dot(L2 - LP2, luma)) - motion_threshold, 0.0) * motion_sense, 1.0);\n" " last = last * (1.0 - mov) + avg_sc * mov;\n" - "" - " gl_FragColor = vec4(last, 1.0);\n" - " }\n" - "}\n"; + "" " gl_FragColor = vec4(last, 1.0);\n" " }\n" "}\n"; static void gst_gl_deinterlace_base_init (gpointer klass) @@ -195,7 +115,6 @@ gst_gl_deinterlace_reset (GstGLFilter * filter) gst_buffer_unref (GST_BUFFER_CAST (deinterlace_filter->gl_buffer_prev)); deinterlace_filter->gl_buffer_prev = NULL; } - //blocking call, wait the opengl thread has destroyed the shader gst_gl_display_del_shader (filter->display, deinterlace_filter->shader); } @@ -226,13 +145,13 @@ gst_gl_deinterlace_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_deinterlace_init_shader (GstGLFilter * filter) { GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, greedyh_fragment_source, + return gst_gl_display_gen_shader (filter->display, 0, greedyh_fragment_source, &deinterlace_filter->shader); } @@ -252,7 +171,8 @@ gst_gl_deinterlace_filter (GstGLFilter * filter, GstGLBuffer * inbuf, if (deinterlace_filter->gl_buffer_prev) gst_buffer_unref (GST_BUFFER_CAST (deinterlace_filter->gl_buffer_prev)); - deinterlace_filter->gl_buffer_prev = GST_GL_BUFFER (gst_buffer_ref (GST_BUFFER_CAST (inbuf))); + deinterlace_filter->gl_buffer_prev = + GST_GL_BUFFER (gst_buffer_ref (GST_BUFFER_CAST (inbuf))); return TRUE; } @@ -283,12 +203,17 @@ gst_gl_deinterlace_callback (gint width, gint height, guint texture, gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); - gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb", 5.0f/255.0f); - gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold", 25.0f/255.0f); - gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense", 30.0f/255.0f); + gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb", + 5.0f / 255.0f); + gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold", + 25.0f / 255.0f); + gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense", + 30.0f / 255.0f); - gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "width", filter->width); - gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "height", filter->height); + gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "width", + filter->width); + gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "height", + filter->height); glBegin (GL_QUADS); glMultiTexCoord2iARB (GL_TEXTURE0_ARB, 0, 0); diff --git a/gst/gl/gstgldifferencematte.c b/gst/gl/gstgldifferencematte.c index 101d2d4729..cac415434c 100644 --- a/gst/gl/gstgldifferencematte.c +++ b/gst/gl/gstgldifferencematte.c @@ -98,16 +98,45 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter * filter) differencematte->shader[i] = gst_gl_shader_new (); } - g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[0], - difference_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); - g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[1], - hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (differencematte->shader[0], + difference_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (differencematte)->display, + "Failed to initialize difference shader"); + GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (differencematte)->display)), + (NULL)); + return; + } - g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[2], - vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (differencematte->shader[1], + hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (differencematte)->display, + "Failed to initialize hconv7 shader"); + GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (differencematte)->display)), + (NULL)); + return; + } - g_return_if_fail (gst_gl_shader_compile_and_check (differencematte->shader[3], - texture_interp_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + if (!gst_gl_shader_compile_and_check (differencematte->shader[2], + vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (differencematte)->display, + "Failed to initialize vconv7 shader"); + GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (differencematte)->display)), + (NULL)); + return; + } + + if (!gst_gl_shader_compile_and_check (differencematte->shader[3], + texture_interp_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { + gst_gl_display_set_error (GST_GL_FILTER (differencematte)->display, + "Failed to initialize interp shader"); + GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (GST_GL_FILTER (differencematte)->display)), + (NULL)); + return; + } } /* free resources that need a gl context */ diff --git a/gst/gl/gstgldownload.c b/gst/gl/gstgldownload.c index ef1c75d355..4d0e512b90 100644 --- a/gst/gl/gstgldownload.c +++ b/gst/gl/gstgldownload.c @@ -255,7 +255,11 @@ gst_gl_download_start (GstBaseTransform * bt) GstGLDownload *download = GST_GL_DOWNLOAD (bt); download->display = gst_gl_display_new (); - gst_gl_display_create_context (download->display, 0); + if (!gst_gl_display_create_context (download->display, 0)) { + GST_ELEMENT_ERROR (download, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (download->display)), (NULL)); + return FALSE; + } return TRUE; } @@ -346,8 +350,11 @@ gst_gl_download_set_caps (GstBaseTransform * bt, GstCaps * incaps, return FALSE; } //blocking call, init color space conversion if needed - gst_gl_display_init_download (download->display, download->video_format, + ret = gst_gl_display_init_download (download->display, download->video_format, download->width, download->height); + if (!ret) + GST_ELEMENT_ERROR (download, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (download->display)), (NULL)); return ret; } diff --git a/gst/gl/gstgleffects.c b/gst/gl/gstgleffects.c index 961dddc576..853b2549a4 100644 --- a/gst/gl/gstgleffects.c +++ b/gst/gl/gstgleffects.c @@ -58,7 +58,7 @@ static void gst_gl_effects_get_property (GObject * object, guint prop_id, static void gst_gl_effects_init_resources (GstGLFilter * filter); static void gst_gl_effects_reset_resources (GstGLFilter * filter); -static void gst_gl_effects_on_init_gl_context (GstGLFilter * filter); +static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter); static void gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data); @@ -431,12 +431,12 @@ gst_gl_effects_init_resources (GstGLFilter * filter) } } -static void +static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter) { //check that your hardware supports shader //if not the pipeline correctly shut down - gst_gl_display_gen_shader (filter->display, 0, 0, NULL); + return gst_gl_display_gen_shader (filter->display, 0, 0, NULL); } static gboolean diff --git a/gst/gl/gstglfilterblur.c b/gst/gl/gstglfilterblur.c index 39675ecbef..8da91401e1 100644 --- a/gst/gl/gstglfilterblur.c +++ b/gst/gl/gstglfilterblur.c @@ -54,7 +54,7 @@ static void gst_gl_filterblur_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_filter_filterblur_reset (GstGLFilter * filter); -static void gst_gl_filterblur_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filterblur_init_shader (GstGLFilter * filter); static gboolean gst_gl_filterblur_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_filterblur_hcallback (gint width, gint height, guint texture, @@ -167,18 +167,20 @@ gst_gl_filterblur_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_filterblur_init_shader (GstGLFilter * filter) { GstGLFilterBlur *blur_filter = GST_GL_FILTERBLUR (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, hconv7_fragment_source, - &blur_filter->shader0); + if (!gst_gl_display_gen_shader (filter->display, 0, hconv7_fragment_source, + &blur_filter->shader0)); + return FALSE; //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, vconv7_fragment_source, - &blur_filter->shader1); + if (!gst_gl_display_gen_shader (filter->display, 0, vconv7_fragment_source, + &blur_filter->shader1)); + return FALSE; } static gboolean diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index d49c35da90..d7aab201ce 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -76,7 +76,7 @@ static gboolean gst_gl_filter_cube_set_caps (GstGLFilter * filter, GstCaps * incaps, GstCaps * outcaps); #ifdef OPENGL_ES2 static void gst_gl_filter_cube_reset (GstGLFilter * filter); -static void gst_gl_filter_cube_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filter_cube_init_shader (GstGLFilter * filter); #endif static gboolean gst_gl_filter_cube_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); @@ -266,13 +266,13 @@ gst_gl_filter_cube_reset (GstGLFilter * filter) gst_gl_display_del_shader (filter->display, cube_filter->shader); } -static void +static gboolean gst_gl_filter_cube_init_shader (GstGLFilter * filter) { GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, cube_v_src, cube_f_src, + return gst_gl_display_gen_shader (filter->display, cube_v_src, cube_f_src, &cube_filter->shader); } #endif diff --git a/gst/gl/gstglfilterglass.c b/gst/gl/gstglfilterglass.c index 73ad866db4..f57b592a8d 100644 --- a/gst/gl/gstglfilterglass.c +++ b/gst/gl/gstglfilterglass.c @@ -63,7 +63,7 @@ static void gst_gl_filter_glass_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_filter_glass_reset (GstGLFilter * filter); -static void gst_gl_filter_glass_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filter_glass_init_shader (GstGLFilter * filter); static gboolean gst_gl_filter_glass_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); @@ -166,13 +166,13 @@ gst_gl_filter_glass_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_filter_glass_init_shader (GstGLFilter * filter) { GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, glass_fragment_source, + return gst_gl_display_gen_shader (filter->display, 0, glass_fragment_source, &glass_filter->shader); } diff --git a/gst/gl/gstglfilterlaplacian.c b/gst/gl/gstglfilterlaplacian.c index 79de5bb8ab..9f92713df4 100644 --- a/gst/gl/gstglfilterlaplacian.c +++ b/gst/gl/gstglfilterlaplacian.c @@ -58,7 +58,7 @@ static void gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_filter_laplacian_reset (GstGLFilter * filter); -static void gst_gl_filter_laplacian_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filter_laplacian_init_shader (GstGLFilter * filter); static gboolean gst_gl_filter_laplacian_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_filter_laplacian_callback (gint width, gint height, @@ -163,14 +163,14 @@ gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_filter_laplacian_init_shader (GstGLFilter * filter) { GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, convolution_fragment_source, - &laplacian_filter->shader); + return gst_gl_display_gen_shader (filter->display, 0, + convolution_fragment_source, &laplacian_filter->shader); } static gboolean diff --git a/gst/gl/gstglfiltershader.c b/gst/gl/gstglfiltershader.c index 2bc3c7453c..00f4498fc9 100644 --- a/gst/gl/gstglfiltershader.c +++ b/gst/gl/gstglfiltershader.c @@ -78,7 +78,7 @@ static void gst_gl_filter_filtershader_reset (GstGLFilter * filter); static void gst_gl_filtershader_load_shader (char *filename, char **storage); static void gst_gl_filtershader_load_variables (char *filename, char **storage); -static void gst_gl_filtershader_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filtershader_init_shader (GstGLFilter * filter); static gboolean gst_gl_filtershader_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_filtershader_hcallback (gint width, gint height, @@ -327,7 +327,7 @@ gst_gl_filtershader_variables_parse (GstGLShader * shader, gchar * variables) } -static void +static gboolean gst_gl_filtershader_init_shader (GstGLFilter * filter) { @@ -337,13 +337,9 @@ gst_gl_filtershader_init_shader (GstGLFilter * filter) &hfilter_fragment_source); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, hfilter_fragment_source, - &filtershader->shader0); - - if (!filtershader->shader0) { - GST_ERROR ("Fragment Shader compilation failed."); - exit (1); - } + if (!gst_gl_display_gen_shader (filter->display, 0, hfilter_fragment_source, + &filtershader->shader0)); + return FALSE; filtershader->compiled = 1; diff --git a/gst/gl/gstglfiltersobel.c b/gst/gl/gstglfiltersobel.c index 8876ffdf83..53d5b3dcd6 100644 --- a/gst/gl/gstglfiltersobel.c +++ b/gst/gl/gstglfiltersobel.c @@ -60,7 +60,7 @@ static void gst_gl_filtersobel_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_gl_filter_filtersobel_reset (GstGLFilter * filter); -static void gst_gl_filtersobel_init_shader (GstGLFilter * filter); +static gboolean gst_gl_filtersobel_init_shader (GstGLFilter * filter); static gboolean gst_gl_filtersobel_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); @@ -192,20 +192,27 @@ gst_gl_filtersobel_get_property (GObject * object, guint prop_id, } } -static void +static gboolean gst_gl_filtersobel_init_shader (GstGLFilter * filter) { GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter); + gboolean ret = TRUE; //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (filter->display, 0, desaturate_fragment_source, + ret = + gst_gl_display_gen_shader (filter->display, 0, desaturate_fragment_source, &filtersobel->desat); - gst_gl_display_gen_shader (filter->display, 0, + ret &= + gst_gl_display_gen_shader (filter->display, 0, sep_sobel_hconv3_fragment_source, &filtersobel->hconv); - gst_gl_display_gen_shader (filter->display, 0, + ret &= + gst_gl_display_gen_shader (filter->display, 0, sep_sobel_vconv3_fragment_source, &filtersobel->vconv); - gst_gl_display_gen_shader (filter->display, 0, + ret &= + gst_gl_display_gen_shader (filter->display, 0, sep_sobel_length_fragment_source, &filtersobel->len); + + return ret; } static gboolean diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index bbf900e061..0f939c872e 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -414,10 +414,16 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition) break; case GST_STATE_CHANGE_READY_TO_PAUSED: if (!glimage_sink->display) { + gboolean ok = FALSE; glimage_sink->display = gst_gl_display_new (); /* init opengl context */ - gst_gl_display_create_context (glimage_sink->display, 0); + ok = gst_gl_display_create_context (glimage_sink->display, 0); + if (!ok) { + GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (glimage_sink->display)), (NULL)); + return GST_STATE_CHANGE_FAILURE; + } } break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -517,8 +523,14 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) return FALSE; /* init colorspace conversion if needed */ - gst_gl_display_init_upload (glimage_sink->display, format, + ok = gst_gl_display_init_upload (glimage_sink->display, format, width, height, width, height); + + if (!ok) { + GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (glimage_sink->display)), (NULL)); + return FALSE; + } } gst_gl_display_set_client_reshape_callback (glimage_sink->display, @@ -637,8 +649,11 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) glimage_sink->window_width, glimage_sink->window_height, glimage_sink->keep_aspect_ratio)) return GST_FLOW_OK; - else - return GST_FLOW_UNEXPECTED; + else { + GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (glimage_sink->display)), (NULL)); + return GST_FLOW_ERROR; + } } diff --git a/gst/gl/gstglmosaic.c b/gst/gl/gstglmosaic.c index 2c27836c14..bd2df38c28 100644 --- a/gst/gl/gstglmosaic.c +++ b/gst/gl/gstglmosaic.c @@ -186,10 +186,8 @@ gst_gl_mosaic_init_shader (GstGLMixer * mixer, GstCaps * outcaps) GstGLMosaic *mosaic = GST_GL_MOSAIC (mixer); //blocking call, wait the opengl thread has compiled the shader - gst_gl_display_gen_shader (mixer->display, mosaic_v_src, mosaic_f_src, + return gst_gl_display_gen_shader (mixer->display, mosaic_v_src, mosaic_f_src, &mosaic->shader); - - return TRUE; } static gboolean diff --git a/gst/gl/gstgltestsrc.c b/gst/gl/gstgltestsrc.c index 83463a683a..15ea18dc98 100644 --- a/gst/gl/gstgltestsrc.c +++ b/gst/gl/gstgltestsrc.c @@ -364,11 +364,9 @@ no_framerate: static gboolean gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps) { - gboolean res; + gboolean res = FALSE; gint width, height, rate_denominator, rate_numerator; - GstGLTestSrc *gltestsrc; - - gltestsrc = GST_GL_TEST_SRC (bsrc); + GstGLTestSrc *gltestsrc = GST_GL_TEST_SRC (bsrc); GST_DEBUG ("setcaps"); @@ -387,8 +385,12 @@ gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps) gltestsrc->rate_numerator, gltestsrc->rate_denominator); - gst_gl_display_gen_fbo (gltestsrc->display, gltestsrc->width, + res = gst_gl_display_gen_fbo (gltestsrc->display, gltestsrc->width, gltestsrc->height, &gltestsrc->fbo, &gltestsrc->depthbuffer); + + if (!res) + GST_ELEMENT_ERROR (gltestsrc, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (gltestsrc->display)), (NULL)); } return res; } @@ -643,7 +645,11 @@ gst_gl_test_src_start (GstBaseSrc * basesrc) else { /* this gl filter is a sink in terms of the gl chain */ src->display = gst_gl_display_new (); - gst_gl_display_create_context (src->display, 0); + isPerformed = gst_gl_display_create_context (src->display, 0); + + if (!isPerformed) + GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (src->display)), (NULL)); } } diff --git a/gst/gl/gstglupload.c b/gst/gl/gstglupload.c index 8975a102dd..531ba25bdb 100644 --- a/gst/gl/gstglupload.c +++ b/gst/gl/gstglupload.c @@ -298,8 +298,12 @@ gst_gl_upload_start (GstBaseTransform * bt) else { /* this gl filter is a sink in terms of the gl chain */ upload->display = gst_gl_display_new (); - gst_gl_display_create_context (upload->display, + isPerformed = gst_gl_display_create_context (upload->display, upload->external_gl_context); + + if (!isPerformed) + GST_ELEMENT_ERROR (upload, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (upload->display)), (NULL)); } } @@ -499,10 +503,14 @@ gst_gl_upload_set_caps (GstBaseTransform * bt, GstCaps * incaps, return FALSE; } //init colorspace conversion if needed - gst_gl_display_init_upload (upload->display, upload->video_format, + ret = gst_gl_display_init_upload (upload->display, upload->video_format, upload->gl_width, upload->gl_height, upload->video_width, upload->video_height); + if (!ret) + GST_ELEMENT_ERROR (upload, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (upload->display)), (NULL)); + return ret; }