From 977c326c59138198f190e1367f5fd8de29f83273 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 9 May 2014 18:07:03 +1000 Subject: [PATCH] gl/colorconvert: implement lazy init --- gst-libs/gst/gl/gstglcolorconvert.c | 184 +++++++++++++++++++----------------- gst-libs/gst/gl/gstglcolorconvert.h | 6 +- gst-libs/gst/gl/gstgldownload.c | 5 +- gst-libs/gst/gl/gstglupload.c | 4 +- 4 files changed, 103 insertions(+), 96 deletions(-) diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index 9bc7b60..ff7cf8c 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -48,9 +48,8 @@ #define USING_GLES3(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES3) static void _do_convert (GstGLContext * context, GstGLColorConvert * convert); -static void _init_convert (GstGLContext * context, GstGLColorConvert * convert); -static gboolean _init_convert_fbo (GstGLContext * context, - GstGLColorConvert * convert); +static gboolean _init_convert (GstGLColorConvert * convert); +static gboolean _init_convert_fbo (GstGLColorConvert * convert); static gboolean _gst_gl_color_convert_perform_unlocked (GstGLColorConvert * convert, GstGLMemory * in_tex[GST_VIDEO_MAX_PLANES], GstGLMemory * out_tex[GST_VIDEO_MAX_PLANES]); @@ -377,6 +376,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_color_convert_debug); G_DEFINE_TYPE_WITH_CODE (GstGLColorConvert, gst_gl_color_convert, GST_TYPE_OBJECT, DEBUG_INIT); static void gst_gl_color_convert_finalize (GObject * object); +static void gst_gl_color_convert_reset (GstGLColorConvert * convert); #define GST_GL_COLOR_CONVERT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ GST_TYPE_GL_COLOR_CONVERT, GstGLColorConvertPrivate)) @@ -415,6 +415,9 @@ gst_gl_color_convert_new (GstGLContext * context) priv = convert->priv; priv->draw = _do_convert_draw; + gst_video_info_set_format (&convert->in_info, GST_VIDEO_FORMAT_ENCODED, 0, 0); + gst_video_info_set_format (&convert->out_info, GST_VIDEO_FORMAT_ENCODED, 0, + 0); return convert; } @@ -423,10 +426,26 @@ static void gst_gl_color_convert_finalize (GObject * object) { GstGLColorConvert *convert; - guint i; convert = GST_GL_COLOR_CONVERT (object); + gst_gl_color_convert_reset (convert); + + if (convert->context) { + gst_object_unref (convert->context); + convert->context = NULL; + } + + g_mutex_clear (&convert->lock); + + G_OBJECT_CLASS (gst_gl_color_convert_parent_class)->finalize (object); +} + +static void +gst_gl_color_convert_reset (GstGLColorConvert * convert) +{ + guint i; + if (convert->fbo || convert->depth_buffer) { gst_gl_context_del_fbo (convert->context, convert->fbo, convert->depth_buffer); @@ -449,69 +468,49 @@ gst_gl_color_convert_finalize (GObject * object) gst_memory_unref ((GstMemory *) convert->priv->scratch); convert->priv->scratch = NULL; } - - if (convert->context) { - gst_object_unref (convert->context); - convert->context = NULL; - } - - g_mutex_clear (&convert->lock); - - G_OBJECT_CLASS (gst_gl_color_convert_parent_class)->finalize (object); } -static gboolean -_gst_gl_color_convert_init_format_unlocked (GstGLColorConvert * convert, +static void +_gst_gl_color_convert_set_format_unlocked (GstGLColorConvert * convert, GstVideoInfo * in_info, GstVideoInfo * out_info) { - g_return_val_if_fail (convert != NULL, FALSE); - g_return_val_if_fail (in_info, FALSE); - g_return_val_if_fail (out_info, FALSE); - g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (in_info) != - GST_VIDEO_FORMAT_UNKNOWN, FALSE); - g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (in_info) != - GST_VIDEO_FORMAT_ENCODED, FALSE); - g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (out_info) != - GST_VIDEO_FORMAT_UNKNOWN, FALSE); - g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (out_info) != - GST_VIDEO_FORMAT_ENCODED, FALSE); - - if (convert->initted) { - return TRUE; - } else { - convert->initted = TRUE; - } + g_return_if_fail (convert != NULL); + g_return_if_fail (in_info); + g_return_if_fail (out_info); + g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) != + GST_VIDEO_FORMAT_UNKNOWN); + g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) != + GST_VIDEO_FORMAT_ENCODED); + g_return_if_fail (GST_VIDEO_INFO_FORMAT (out_info) != + GST_VIDEO_FORMAT_UNKNOWN); + g_return_if_fail (GST_VIDEO_INFO_FORMAT (out_info) != + GST_VIDEO_FORMAT_ENCODED); + + if (gst_video_info_is_equal (&convert->in_info, in_info) && + gst_video_info_is_equal (&convert->out_info, out_info)) + return; + gst_gl_color_convert_reset (convert); convert->in_info = *in_info; convert->out_info = *out_info; - - gst_gl_context_thread_add (convert->context, - (GstGLContextThreadFunc) _init_convert, convert); - - return convert->priv->result; + convert->initted = FALSE; } /** - * gst_gl_color_convert_init_format: + * gst_gl_color_convert_set_format: * @convert: a #GstGLColorConvert * @in_info: input #GstVideoInfo * @out_info: output #GstVideoInfo * * Initializes @convert with the information required for conversion. - * - * Returns: whether the initialization was successful */ -gboolean -gst_gl_color_convert_init_format (GstGLColorConvert * convert, +void +gst_gl_color_convert_set_format (GstGLColorConvert * convert, GstVideoInfo * in_info, GstVideoInfo * out_info) { - gboolean ret; - g_mutex_lock (&convert->lock); - ret = _gst_gl_color_convert_init_format_unlocked (convert, in_info, out_info); + _gst_gl_color_convert_set_format_unlocked (convert, in_info, out_info); g_mutex_unlock (&convert->lock); - - return ret; } /** @@ -522,7 +521,7 @@ gst_gl_color_convert_init_format (GstGLColorConvert * convert, * * Converts the data contained in in_tex into out_tex using the formats * specified by the #GstVideoInfos passed to - * gst_gl_color_convert_init_format() + * gst_gl_color_convert_set_format() * * Returns: whether the conversion was successful */ @@ -676,7 +675,7 @@ fail: } static void -_RGB_to_RGB (GstGLContext * context, GstGLColorConvert * convert) +_RGB_to_RGB (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info); @@ -695,7 +694,7 @@ _RGB_to_RGB (GstGLContext * context, GstGLColorConvert * convert) } static void -_YUV_to_RGB (GstGLContext * context, GstGLColorConvert * convert) +_YUV_to_RGB (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info); @@ -743,7 +742,8 @@ _YUV_to_RGB (GstGLContext * context, GstGLColorConvert * convert) info->in_n_textures = 1; info->shader_tex_names[1] = "Ytex"; info->shader_tex_names[0] = "UVtex"; - convert->priv->scratch = (GstGLMemory *) gst_gl_memory_alloc (context, + convert->priv->scratch = + (GstGLMemory *) gst_gl_memory_alloc (convert->context, GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA, GST_VIDEO_INFO_WIDTH (&convert->in_info), GST_VIDEO_INFO_HEIGHT (&convert->in_info), @@ -769,7 +769,8 @@ _YUV_to_RGB (GstGLContext * context, GstGLColorConvert * convert) info->in_n_textures = 1; info->shader_tex_names[1] = "Ytex"; info->shader_tex_names[0] = "UVtex"; - convert->priv->scratch = (GstGLMemory *) gst_gl_memory_alloc (context, + convert->priv->scratch = + (GstGLMemory *) gst_gl_memory_alloc (convert->context, GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA, GST_VIDEO_INFO_WIDTH (&convert->in_info), GST_VIDEO_INFO_HEIGHT (&convert->in_info), @@ -797,7 +798,7 @@ _YUV_to_RGB (GstGLContext * context, GstGLColorConvert * convert) } static void -_RGB_to_YUV (GstGLContext * context, GstGLColorConvert * convert) +_RGB_to_YUV (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info); @@ -868,7 +869,7 @@ _RGB_to_YUV (GstGLContext * context, GstGLColorConvert * convert) } static void -_RGB_to_GRAY (GstGLContext * context, GstGLColorConvert * convert) +_RGB_to_GRAY (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info); @@ -896,7 +897,7 @@ _RGB_to_GRAY (GstGLContext * context, GstGLColorConvert * convert) } static void -_GRAY_to_RGB (GstGLContext * context, GstGLColorConvert * convert) +_GRAY_to_RGB (GstGLColorConvert * convert) { struct ConvertInfo *info = &convert->priv->convert_info; GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info); @@ -932,53 +933,56 @@ _GRAY_to_RGB (GstGLContext * context, GstGLColorConvert * convert) } /* Called in the gl thread */ -void -_init_convert (GstGLContext * context, GstGLColorConvert * convert) +static gboolean +_init_convert (GstGLColorConvert * convert) { GstGLFuncs *gl; gboolean res; struct ConvertInfo *info = &convert->priv->convert_info; gint i; - gl = context->gl_vtable; + gl = convert->context->gl_vtable; + + if (convert->initted) + return TRUE; GST_INFO ("Initializing color conversion from %s to %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)), gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->out_info))); if (!gl->CreateProgramObject && !gl->CreateProgram) { - gst_gl_context_set_error (context, + gst_gl_context_set_error (convert->context, "Cannot perform color conversion without OpenGL shaders"); goto error; } if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) { if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) { - _RGB_to_RGB (context, convert); + _RGB_to_RGB (convert); } } if (GST_VIDEO_INFO_IS_YUV (&convert->in_info)) { if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) { - _YUV_to_RGB (context, convert); + _YUV_to_RGB (convert); } } if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) { if (GST_VIDEO_INFO_IS_YUV (&convert->out_info)) { - _RGB_to_YUV (context, convert); + _RGB_to_YUV (convert); } } if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) { if (GST_VIDEO_INFO_IS_GRAY (&convert->out_info)) { - _RGB_to_GRAY (context, convert); + _RGB_to_GRAY (convert); } } if (GST_VIDEO_INFO_IS_GRAY (&convert->in_info)) { if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) { - _GRAY_to_RGB (context, convert); + _GRAY_to_RGB (convert); } } @@ -986,15 +990,16 @@ _init_convert (GstGLContext * context, GstGLColorConvert * convert) goto unhandled_format; /* multiple draw targets not supported on GLES2...yet */ - if (info->out_n_textures > 1 && (!gl->DrawBuffers || USING_GLES2 (context))) { + if (info->out_n_textures > 1 && (!gl->DrawBuffers || + USING_GLES2 (convert->context))) { g_free (info->frag_prog); GST_ERROR ("Conversion requires output to multiple draw buffers"); goto incompatible_api; } res = - gst_gl_context_gen_shader (context, text_vertex_shader, info->frag_prog, - &convert->shader); + gst_gl_context_gen_shader (convert->context, text_vertex_shader, + info->frag_prog, &convert->shader); g_free (info->frag_prog); if (!res) goto error; @@ -1033,55 +1038,56 @@ _init_convert (GstGLContext * context, GstGLColorConvert * convert) gst_gl_shader_set_uniform_1f (convert->shader, "width", GST_VIDEO_INFO_WIDTH (&convert->in_info)); - gst_gl_context_clear_shader (context); + gst_gl_context_clear_shader (convert->context); - if (!_init_convert_fbo (context, convert)) { + if (!_init_convert_fbo (convert)) { goto error; } gl->BindTexture (GL_TEXTURE_2D, 0); - convert->priv->result = TRUE; - return; + convert->initted = TRUE; + + return TRUE; unhandled_format: - gst_gl_context_set_error (context, "Don't know how to convert from %s to %s", + gst_gl_context_set_error (convert->context, + "Don't know how to convert from %s to %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)), gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->out_info))); error: - convert->priv->result = FALSE; - return; + return FALSE; incompatible_api: { - gst_gl_context_set_error (context, "Converting from %s to %s requires " + gst_gl_context_set_error (convert->context, + "Converting from %s to %s requires " "functionality that the current OpenGL setup does not support", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)), gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->out_info))); - convert->priv->result = FALSE; - return; + return FALSE; } } /* called by _init_convert (in the gl thread) */ -gboolean -_init_convert_fbo (GstGLContext * context, GstGLColorConvert * convert) +static gboolean +_init_convert_fbo (GstGLColorConvert * convert) { GstGLFuncs *gl; guint out_width, out_height; GLuint fake_texture = 0; /* a FBO must hava texture to init */ - gl = context->gl_vtable; + gl = convert->context->gl_vtable; out_width = GST_VIDEO_INFO_WIDTH (&convert->out_info); out_height = GST_VIDEO_INFO_HEIGHT (&convert->out_info); if (!gl->GenFramebuffers) { /* turn off the pipeline because Frame buffer object is a not present */ - gst_gl_context_set_error (context, + gst_gl_context_set_error (convert->context, "Context, EXT_framebuffer_object supported: no"); return FALSE; } @@ -1095,13 +1101,13 @@ _init_convert_fbo (GstGLContext * context, GstGLColorConvert * convert) /* setup the render buffer for depth */ gl->GenRenderbuffers (1, &convert->depth_buffer); gl->BindRenderbuffer (GL_RENDERBUFFER, convert->depth_buffer); - if (USING_OPENGL (context)) { + if (USING_OPENGL (convert->context)) { gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, out_width, out_height); gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, out_width, out_height); } - if (USING_GLES2 (context)) { + if (USING_GLES2 (convert->context)) { gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, out_width, out_height); } @@ -1124,13 +1130,14 @@ _init_convert_fbo (GstGLContext * context, GstGLColorConvert * convert) gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, convert->depth_buffer); - if (USING_OPENGL (context)) { + if (USING_OPENGL (convert->context)) { gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, convert->depth_buffer); } - if (!gst_gl_context_check_framebuffer_status (context)) { - gst_gl_context_set_error (context, "GL framebuffer status incomplete"); + if (!gst_gl_context_check_framebuffer_status (convert->context)) { + gst_gl_context_set_error (convert->context, + "GL framebuffer status incomplete"); return FALSE; } @@ -1157,6 +1164,11 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert) in_width = GST_VIDEO_INFO_WIDTH (&convert->in_info); in_height = GST_VIDEO_INFO_HEIGHT (&convert->in_info); + if (!_init_convert (convert)) { + convert->priv->result = FALSE; + return; + } + GST_TRACE ("converting to textures:%p,%p,%p,%p dimensions:%ux%u, " "from textures:%p,%p,%p,%p dimensions:%ux%u", convert->out_tex[0], convert->out_tex[1], convert->out_tex[2], convert->out_tex[3], diff --git a/gst-libs/gst/gl/gstglcolorconvert.h b/gst-libs/gst/gl/gstglcolorconvert.h index d259c28..44f68c6 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.h +++ b/gst-libs/gst/gl/gstglcolorconvert.h @@ -101,9 +101,9 @@ struct _GstGLColorConvertClass GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context); -gboolean gst_gl_color_convert_init_format (GstGLColorConvert * convert, - GstVideoInfo * in_info, - GstVideoInfo * out_info); +void gst_gl_color_convert_set_format (GstGLColorConvert * convert, + GstVideoInfo * in_info, + GstVideoInfo * out_info); void gst_gl_color_convert_set_texture_scaling (GstGLColorConvert * convert, gfloat scaling[GST_VIDEO_MAX_PLANES][2]); diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c index 15586ab..5128c0a 100644 --- a/gst-libs/gst/gl/gstgldownload.c +++ b/gst-libs/gst/gl/gstgldownload.c @@ -338,11 +338,8 @@ _init_download (GstGLContext * context, GstGLDownload * download) gst_video_info_set_format (&in_info, GST_VIDEO_FORMAT_RGBA, out_width, out_height); - download->priv->result = - gst_gl_color_convert_init_format (download->convert, &in_info, + gst_gl_color_convert_set_format (download->convert, &in_info, &download->info); - if (!download->priv->result) - return; download->priv->result = TRUE; } diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index 3261d96..eaa34fe 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -625,9 +625,7 @@ _init_upload (GstGLUpload * upload) GST_VIDEO_INFO_WIDTH (&upload->in_info), GST_VIDEO_INFO_HEIGHT (&upload->in_info)); - if (!gst_gl_color_convert_init_format (upload->convert, &upload->in_info, - &out_info)) - goto error; + gst_gl_color_convert_set_format (upload->convert, &upload->in_info, &out_info); upload->initted = TRUE; -- 2.7.4