gl/upload: implement lazy init

Rename init_format to set_format
This commit is contained in:
Matthew Waters 2014-05-08 13:46:29 +10:00 committed by Tim-Philipp Müller
parent cda89d7ce0
commit 6c1a4e30c4
8 changed files with 55 additions and 117 deletions

View file

@ -693,17 +693,9 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
gst_object_unref (glimage_sink->upload); gst_object_unref (glimage_sink->upload);
glimage_sink->upload = gst_object_ref (GST_GL_BUFFER_POOL (newpool)->upload); glimage_sink->upload = gst_object_ref (GST_GL_BUFFER_POOL (newpool)->upload);
if (!gst_gl_upload_init_format (glimage_sink->upload, &vinfo)) gst_gl_upload_set_format (glimage_sink->upload, &vinfo);
goto upload_error;
return TRUE; return TRUE;
upload_error:
{
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
("%s", "Failed to initialize upload resources"), (NULL));
return FALSE;
}
} }
static GstFlowReturn static GstFlowReturn

View file

@ -175,21 +175,9 @@ gst_gl_buffer_pool_start (GstBufferPool * pool)
GstGLBufferPool *glpool = GST_GL_BUFFER_POOL_CAST (pool); GstGLBufferPool *glpool = GST_GL_BUFFER_POOL_CAST (pool);
GstGLBufferPoolPrivate *priv = glpool->priv; GstGLBufferPoolPrivate *priv = glpool->priv;
#if GST_GL_HAVE_PLATFORM_EGL gst_gl_upload_set_format (glpool->upload, &priv->info);
if (priv->want_eglimage)
return GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
#endif
if (!gst_gl_upload_init_format (glpool->upload, &priv->info))
goto upload_error;
return GST_BUFFER_POOL_CLASS (parent_class)->start (pool); return GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
upload_error:
{
GST_WARNING_OBJECT (glpool, "Failed to initialize upload");
return FALSE;
}
} }
/* This function handles GstBuffer creation */ /* This function handles GstBuffer creation */

View file

@ -1136,8 +1136,7 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
} else { } else {
filter->upload = gst_gl_upload_new (filter->context); filter->upload = gst_gl_upload_new (filter->context);
} }
if (!gst_gl_upload_init_format (filter->upload, &filter->in_info)) gst_gl_upload_set_format (filter->upload, &filter->in_info);
goto upload_error;
gst_caps_unref (in_caps); gst_caps_unref (in_caps);
gst_caps_unref (out_caps); gst_caps_unref (out_caps);
@ -1152,15 +1151,6 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
gst_gl_filter_filter_texture (filter, inbuf, outbuf); gst_gl_filter_filter_texture (filter, inbuf, outbuf);
return GST_FLOW_OK; return GST_FLOW_OK;
upload_error:
{
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, ("Failed to init upload"),
(NULL));
gst_object_unref (filter->upload);
filter->upload = NULL;
return GST_FLOW_ERROR;
}
} }
/* convenience functions to simplify filter development */ /* convenience functions to simplify filter development */

View file

@ -673,8 +673,8 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, src->tex_id, 0); GL_TEXTURE_2D, src->tex_id, 0);
if (!gst_gl_context_check_framebuffer_status (src->context)) // if (!gst_gl_context_check_framebuffer_status (src->context))
goto fbo_error; // goto fbo_error;
gl->BindTexture (GL_TEXTURE_2D, tex_id); gl->BindTexture (GL_TEXTURE_2D, tex_id);
if (copy_params->respecify) { if (copy_params->respecify) {

View file

@ -1685,12 +1685,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
if (!pad->upload) { if (!pad->upload) {
pad->upload = gst_gl_upload_new (mix->context); pad->upload = gst_gl_upload_new (mix->context);
if (!gst_gl_upload_init_format (pad->upload, &pad->in_info)) { gst_gl_upload_set_format (pad->upload, &pad->in_info);
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s",
"Failed to init upload format"), (NULL));
res = FALSE;
goto out;
}
} }
if (!gst_gl_upload_perform_with_buffer (pad->upload, mixcol->buffer, if (!gst_gl_upload_perform_with_buffer (pad->upload, mixcol->buffer,

View file

@ -50,11 +50,12 @@
static gboolean _upload_memory (GstGLUpload * upload); static gboolean _upload_memory (GstGLUpload * upload);
//static gboolean _do_upload_fill (GstGLContext * context, GstGLUpload * upload); //static gboolean _do_upload_fill (GstGLContext * context, GstGLUpload * upload);
//static gboolean _do_upload_make (GstGLContext * context, GstGLUpload * upload); //static gboolean _do_upload_make (GstGLContext * context, GstGLUpload * upload);
static void _init_upload (GstGLContext * context, GstGLUpload * upload); static void _init_upload (GstGLUpload * upload);
//static gboolean _init_upload_fbo (GstGLContext * context, GstGLUpload * upload); //static gboolean _init_upload_fbo (GstGLContext * context, GstGLUpload * upload);
static gboolean _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, static gboolean _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload,
GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]);
static void _do_upload_with_meta (GstGLContext * context, GstGLUpload * upload); static void _do_upload_with_meta (GstGLContext * context, GstGLUpload * upload);
static void gst_gl_upload_reset (GstGLUpload * upload);
/* *INDENT-OFF* */ /* *INDENT-OFF* */
@ -94,6 +95,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug);
G_DEFINE_TYPE_WITH_CODE (GstGLUpload, gst_gl_upload, G_TYPE_OBJECT, DEBUG_INIT); G_DEFINE_TYPE_WITH_CODE (GstGLUpload, gst_gl_upload, G_TYPE_OBJECT, DEBUG_INIT);
static void gst_gl_upload_finalize (GObject * object); static void gst_gl_upload_finalize (GObject * object);
#define GST_GL_UPLOAD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ #define GST_GL_UPLOAD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
GST_TYPE_GL_UPLOAD, GstGLUploadPrivate)) GST_TYPE_GL_UPLOAD, GstGLUploadPrivate))
@ -113,6 +115,8 @@ gst_gl_upload_init (GstGLUpload * upload)
upload->context = NULL; upload->context = NULL;
upload->priv->tex_id = 0; upload->priv->tex_id = 0;
gst_video_info_set_format (&upload->in_info, GST_VIDEO_FORMAT_ENCODED, 0, 0);
g_mutex_init (&upload->lock); g_mutex_init (&upload->lock);
} }
@ -142,19 +146,7 @@ gst_gl_upload_finalize (GObject * object)
upload = GST_GL_UPLOAD (object); upload = GST_GL_UPLOAD (object);
if (upload->priv->tex_id) { gst_gl_upload_reset (upload);
gst_gl_context_del_texture (upload->context, &upload->priv->tex_id);
upload->priv->tex_id = 0;
}
if (upload->convert) {
gst_object_unref (upload->convert);
}
if (upload->out_tex) {
gst_memory_unref ((GstMemory *) upload->out_tex);
upload->out_tex = NULL;
}
if (upload->context) { if (upload->context) {
gst_object_unref (upload->context); gst_object_unref (upload->context);
@ -166,8 +158,27 @@ gst_gl_upload_finalize (GObject * object)
G_OBJECT_CLASS (gst_gl_upload_parent_class)->finalize (object); G_OBJECT_CLASS (gst_gl_upload_parent_class)->finalize (object);
} }
static gboolean static void
_gst_gl_upload_init_format_unlocked (GstGLUpload * upload, gst_gl_upload_reset (GstGLUpload * upload)
{
if (upload->priv->tex_id) {
gst_gl_context_del_texture (upload->context, &upload->priv->tex_id);
upload->priv->tex_id = 0;
}
if (upload->convert) {
gst_object_unref (upload->convert);
upload->convert = NULL;
}
if (upload->out_tex) {
gst_memory_unref ((GstMemory *) upload->out_tex);
upload->out_tex = NULL;
}
}
static void
_gst_gl_upload_set_format_unlocked (GstGLUpload * upload,
GstVideoInfo *in_info) GstVideoInfo *in_info)
{ {
g_return_val_if_fail (upload != NULL, FALSE); g_return_val_if_fail (upload != NULL, FALSE);
@ -176,49 +187,38 @@ _gst_gl_upload_init_format_unlocked (GstGLUpload * upload,
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (in_info) != g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (in_info) !=
GST_VIDEO_FORMAT_ENCODED, FALSE); GST_VIDEO_FORMAT_ENCODED, FALSE);
if (upload->initted) { if (gst_video_info_is_equal (&upload->in_info, in_info))
return TRUE; return;
}
gst_gl_upload_reset (upload);
upload->convert = gst_gl_color_convert_new (upload->context);
upload->in_info = *in_info; upload->in_info = *in_info;
upload->initted = FALSE;
gst_gl_context_thread_add (upload->context,
(GstGLContextThreadFunc) _init_upload, upload);
upload->initted = upload->priv->result;
return upload->initted;
} }
/** /**
* gst_gl_upload_init_format: * gst_gl_upload_set_format:
* @upload: a #GstGLUpload * @upload: a #GstGLUpload
* @in_info: input #GstVideoInfo * @in_info: input #GstVideoInfo
* *
* Initializes @upload with the information required for upload. * Initializes @upload with the information required for upload.
*
* Returns: whether the initialization was successful
*/ */
gboolean void
gst_gl_upload_init_format (GstGLUpload * upload, GstVideoInfo * in_info) gst_gl_upload_set_format (GstGLUpload * upload, GstVideoInfo * in_info)
{ {
gboolean ret;
g_mutex_lock (&upload->lock); g_mutex_lock (&upload->lock);
ret = _gst_gl_upload_init_format_unlocked (upload, in_info); _gst_gl_upload_set_format_unlocked (upload, in_info);
g_mutex_unlock (&upload->lock); g_mutex_unlock (&upload->lock);
return ret;
} }
/** /**
* gst_gl_upload_get_format: * gst_gl_upload_get_format:
* @upload: a #GstGLUpload * @upload: a #GstGLUpload
* *
* Returns: (transfer none): The #GstVideoInfo set by gst_gl_upload_init_format() * Returns: (transfer none): The #GstVideoInfo set by gst_gl_upload_set_format()
*/ */
GstVideoInfo * GstVideoInfo *
gst_gl_upload_get_format (GstGLUpload * upload) gst_gl_upload_get_format (GstGLUpload * upload)
@ -367,8 +367,7 @@ _do_upload_for_meta (GstGLUpload * upload, GstVideoGLTextureUploadMeta * meta)
gst_video_info_set_format (&in_info, v_format, width, height); gst_video_info_set_format (&in_info, v_format, width, height);
if (!_gst_gl_upload_init_format_unlocked (upload, &in_info)) _gst_gl_upload_set_format_unlocked (upload, &in_info);
return FALSE;
} }
/* GstGLMemory */ /* GstGLMemory */
@ -549,7 +548,7 @@ gst_gl_upload_add_video_gl_texture_upload_meta (GstGLUpload * upload,
* @data: where the downloaded data should go * @data: where the downloaded data should go
* *
* Uploads @data into @texture_id. data size and format is specified by * Uploads @data into @texture_id. data size and format is specified by
* the #GstVideoInfo<!-- -->s passed to gst_gl_upload_init_format() * the #GstVideoInfo<!-- -->s passed to gst_gl_upload_set_format()
* *
* Returns: whether the upload was successful * Returns: whether the upload was successful
*/ */
@ -603,13 +602,13 @@ _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload,
/* Called in the gl thread */ /* Called in the gl thread */
static void static void
_init_upload (GstGLContext * context, GstGLUpload * upload) _init_upload (GstGLUpload * upload)
{ {
GstGLFuncs *gl; GstGLFuncs *gl;
GstVideoFormat v_format; GstVideoFormat v_format;
GstVideoInfo out_info; GstVideoInfo out_info;
gl = context->gl_vtable; gl = upload->context->gl_vtable;
v_format = GST_VIDEO_INFO_FORMAT (&upload->in_info); v_format = GST_VIDEO_INFO_FORMAT (&upload->in_info);
@ -617,7 +616,7 @@ _init_upload (GstGLContext * context, GstGLUpload * upload)
gst_video_format_to_string (v_format)); gst_video_format_to_string (v_format));
if (!gl->CreateProgramObject && !gl->CreateProgram) { if (!gl->CreateProgramObject && !gl->CreateProgram) {
gst_gl_context_set_error (context, gst_gl_context_set_error (upload->context,
"Cannot upload YUV formats without OpenGL shaders"); "Cannot upload YUV formats without OpenGL shaders");
goto error; goto error;
} }
@ -650,6 +649,9 @@ _upload_memory (GstGLUpload * upload)
in_width = GST_VIDEO_INFO_WIDTH (&upload->in_info); in_width = GST_VIDEO_INFO_WIDTH (&upload->in_info);
in_height = GST_VIDEO_INFO_HEIGHT (&upload->in_info); in_height = GST_VIDEO_INFO_HEIGHT (&upload->in_info);
if (!upload->initted)
_init_upload (upload);
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) { for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) {
if (!gst_memory_map ((GstMemory *) upload->in_tex[i], &map_infos[i], if (!gst_memory_map ((GstMemory *) upload->in_tex[i], &map_infos[i],
GST_MAP_READ | GST_MAP_GL)) { GST_MAP_READ | GST_MAP_GL)) {

View file

@ -77,7 +77,7 @@ struct _GstGLUploadClass
GstGLUpload * gst_gl_upload_new (GstGLContext * context); GstGLUpload * gst_gl_upload_new (GstGLContext * context);
gboolean gst_gl_upload_init_format (GstGLUpload * upload, GstVideoInfo * in_info); void gst_gl_upload_set_format (GstGLUpload * upload, GstVideoInfo * in_info);
GstVideoInfo * gst_gl_upload_get_format (GstGLUpload * upload); GstVideoInfo * gst_gl_upload_get_format (GstGLUpload * upload);
gboolean gst_gl_upload_add_video_gl_texture_upload_meta (GstGLUpload * upload, GstBuffer * buffer); gboolean gst_gl_upload_add_video_gl_texture_upload_meta (GstGLUpload * upload, GstBuffer * buffer);

View file

@ -224,34 +224,6 @@ draw_render (gpointer data)
context_class->swap_buffers (context); context_class->swap_buffers (context);
} }
GST_START_TEST (test_shader_compile)
{
const gchar *formats[] = { "RGB", "RGBx", "RGBA", "BGR", "BGRx", "BGRA",
"xRGB", "xBGR", "ARGB", "ABGR", "Y444", "I420", "YV12", "Y42B", "Y41B",
"NV12", "NV21", "YUY2", "UYVY", "AYUV", "GRAY8", "GRAY16_LE", "GRAY16_BE"
};
guint i;
gboolean res;
for (i = 0; i < G_N_ELEMENTS (formats); i++) {
GstVideoInfo info;
GstVideoFormat v_format;
v_format = gst_video_format_from_string (formats[i]);
gst_video_info_set_format (&info, v_format, 320, 240);
res = gst_gl_upload_init_format (upload, &info);
fail_if (res == FALSE, "Failed to init upload for video format %s\n",
formats[i]);
gst_object_unref (upload);
upload = gst_gl_upload_new (context);
}
}
GST_END_TEST;
GST_START_TEST (test_upload_data) GST_START_TEST (test_upload_data)
{ {
gpointer data[GST_VIDEO_MAX_PLANES] = { rgba_data, NULL, NULL, NULL }; gpointer data[GST_VIDEO_MAX_PLANES] = { rgba_data, NULL, NULL, NULL };
@ -264,7 +236,7 @@ GST_START_TEST (test_upload_data)
gst_gl_context_gen_texture (context, &tex_id, GST_VIDEO_FORMAT_RGBA, WIDTH, gst_gl_context_gen_texture (context, &tex_id, GST_VIDEO_FORMAT_RGBA, WIDTH,
HEIGHT); HEIGHT);
gst_gl_upload_init_format (upload, &in_info); gst_gl_upload_set_format (upload, &in_info);
res = gst_gl_upload_perform_with_data (upload, tex_id, data); res = gst_gl_upload_perform_with_data (upload, tex_id, data);
fail_if (res == FALSE, "Failed to upload buffer: %s\n", fail_if (res == FALSE, "Failed to upload buffer: %s\n",
@ -301,7 +273,7 @@ GST_START_TEST (test_upload_buffer)
rgba_data, NULL, NULL); rgba_data, NULL, NULL);
gst_buffer_append_memory (buffer, (GstMemory *) gl_mem); gst_buffer_append_memory (buffer, (GstMemory *) gl_mem);
gst_gl_upload_init_format (upload, &in_info); gst_gl_upload_set_format (upload, &in_info);
res = gst_gl_upload_perform_with_buffer (upload, buffer, &tex_id); res = gst_gl_upload_perform_with_buffer (upload, buffer, &tex_id);
fail_if (res == FALSE, "Failed to upload buffer: %s\n", fail_if (res == FALSE, "Failed to upload buffer: %s\n",
@ -343,7 +315,7 @@ GST_START_TEST (test_upload_meta_producer)
gst_gl_context_gen_texture (context, &tex_ids[0], GST_VIDEO_FORMAT_RGBA, gst_gl_context_gen_texture (context, &tex_ids[0], GST_VIDEO_FORMAT_RGBA,
WIDTH, HEIGHT); WIDTH, HEIGHT);
gst_gl_upload_init_format (upload, &in_info); gst_gl_upload_set_format (upload, &in_info);
gst_buffer_add_video_meta_full (buffer, 0, GST_VIDEO_FORMAT_RGBA, WIDTH, gst_buffer_add_video_meta_full (buffer, 0, GST_VIDEO_FORMAT_RGBA, WIDTH,
HEIGHT, 1, in_info.offset, in_info.stride); HEIGHT, 1, in_info.offset, in_info.stride);
gst_gl_upload_add_video_gl_texture_upload_meta (upload, buffer); gst_gl_upload_add_video_gl_texture_upload_meta (upload, buffer);
@ -379,7 +351,6 @@ gst_gl_upload_suite (void)
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);
tcase_add_checked_fixture (tc_chain, setup, teardown); tcase_add_checked_fixture (tc_chain, setup, teardown);
tcase_add_test (tc_chain, test_shader_compile);
tcase_add_test (tc_chain, test_upload_data); tcase_add_test (tc_chain, test_upload_data);
tcase_add_test (tc_chain, test_upload_buffer); tcase_add_test (tc_chain, test_upload_buffer);
tcase_add_test (tc_chain, test_upload_meta_producer); tcase_add_test (tc_chain, test_upload_meta_producer);