From 7c79cc5c419da8d15735c26a04c14072c99777f2 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Thu, 24 Nov 2011 16:02:32 +0100 Subject: [PATCH] [481/906] feature checking: error out instead of doing nothing if an OpenGL feature is not present Fix bug #572767 --- gst-libs/gst/gl/gstgldisplay.c | 177 +++++++++++++++++++++++++---------------- gst-libs/gst/gl/gstgldisplay.h | 18 +++-- gst-libs/gst/gl/gstglfilter.c | 31 ++++++-- gst-libs/gst/gl/gstglfilter.h | 2 +- gst-libs/gst/gl/gstglmixer.c | 21 +++-- 5 files changed, 163 insertions(+), 86 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index b95ce64..c1ca070 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 2ba0ef7..5645b9d 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 1141a97..683792e 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); + ret = filter_class->onInitFBO (filter); + + if (!ret) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, + (GST_GL_DISPLAY_ERR_MSG (filter->display)), (NULL)); + return FALSE; + } if (filter_class->set_caps) - filter_class->set_caps (filter, incaps, outcaps); + ret = filter_class->set_caps (filter, incaps, outcaps); if (!ret) { - GST_DEBUG ("bad caps"); + 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 41bdc70..7430dfd 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 476a02f..deedd10 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); -- 2.7.4