[481/906] feature checking: error out instead of doing nothing if an OpenGL feature is not present

Fix bug #572767
This commit is contained in:
Julien Isorce 2011-11-24 16:02:32 +01:00 committed by Tim-Philipp Müller
parent b30da1699a
commit 7c79cc5c41
5 changed files with 165 additions and 88 deletions

View file

@ -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");
}
}

View file

@ -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__ */

View file

@ -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;
}

View file

@ -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);

View file

@ -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);