From 75734e663c4e917665824e44ff60f24e2f79c7e1 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 18 Sep 2012 21:39:21 +1000 Subject: [PATCH] [578/906] {up,down}load: add variants that can be called in the gl thread --- gst-libs/gst/gl/gstgldownload.c | 193 ++++++++++++++++++++++++++++++++++++---- gst-libs/gst/gl/gstgldownload.h | 24 +++-- gst-libs/gst/gl/gstglupload.c | 156 ++++++++++++++++++++++++++++++-- gst-libs/gst/gl/gstglupload.h | 19 ++-- 4 files changed, 355 insertions(+), 37 deletions(-) diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c index 3a66533..c485984 100644 --- a/gst-libs/gst/gl/gstgldownload.c +++ b/gst-libs/gst/gl/gstgldownload.c @@ -37,6 +37,8 @@ static void _init_download_shader (GstGLDisplay * display, GstGLDownload * download); static gboolean gst_gl_download_perform_with_data_unlocked (GstGLDownload * download, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); +static gboolean gst_gl_download_perform_with_data_unlocked_thread (GstGLDownload + * download, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); /* YUY2:y2,u,y1,v UYVY:v,y1,u,y2 */ @@ -240,19 +242,36 @@ gst_gl_download_finalize (GObject * object) g_mutex_clear (&download->lock); } -gboolean -gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, +static inline gboolean +_init_format_pre (GstGLDownload * download, GstVideoFormat v_format, guint width, guint height) { - GstVideoInfo info; - g_return_val_if_fail (download != NULL, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE); g_return_val_if_fail (width > 0 && height > 0, FALSE); + return TRUE; +} + +gboolean +gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, + guint width, guint height) +{ + GstVideoInfo info; + + if (!_init_format_pre (download, v_format, width, height)) + return FALSE; + g_mutex_lock (&download->lock); + if (download->initted) { + g_mutex_unlock (&download->lock); + return FALSE; + } else { + download->initted = TRUE; + } + gst_video_info_set_format (&info, v_format, width, height); download->info = info; @@ -266,13 +285,37 @@ gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, } gboolean -gst_gl_download_perform_with_memory (GstGLDownload * download, - GstGLMemory * gl_mem) +gst_gl_download_init_format_thread (GstGLDownload * download, + GstVideoFormat v_format, guint width, guint height) { - gpointer data[GST_VIDEO_MAX_PLANES]; - guint i; - gboolean ret; + GstVideoInfo info; + + if (!_init_format_pre (download, v_format, width, height)) + return FALSE; + + g_mutex_lock (&download->lock); + + if (download->initted) { + g_mutex_unlock (&download->lock); + return FALSE; + } else { + download->initted = TRUE; + } + + gst_video_info_set_format (&info, v_format, width, height); + + download->info = info; + + _init_download (download->display, download); + + g_mutex_unlock (&download->lock); + return TRUE; +} + +static inline gboolean +_perform_with_memory_pre (GstGLDownload * download, GstGLMemory * gl_mem) +{ g_return_val_if_fail (download != NULL, FALSE); if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_DOWNLOAD_INITTED)) @@ -282,6 +325,20 @@ gst_gl_download_perform_with_memory (GstGLDownload * download, return FALSE; } + return TRUE; +} + +gboolean +gst_gl_download_perform_with_memory (GstGLDownload * download, + GstGLMemory * gl_mem) +{ + gpointer data[GST_VIDEO_MAX_PLANES]; + guint i; + gboolean ret; + + if (!_perform_with_memory_pre (download, gl_mem)) + return FALSE; + g_mutex_lock (&download->lock); for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&download->info); i++) { @@ -317,9 +374,9 @@ gst_gl_download_perform_with_data (GstGLDownload * download, GLuint texture_id, return ret; } -static gboolean -gst_gl_download_perform_with_data_unlocked (GstGLDownload * download, - GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +static inline gboolean +_perform_with_data_unlocked_pre (GstGLDownload * download, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]) { guint i; @@ -339,24 +396,96 @@ gst_gl_download_perform_with_data_unlocked (GstGLDownload * download, download->data[i] = data[i]; } + return TRUE; +} + +static gboolean +gst_gl_download_perform_with_data_unlocked (GstGLDownload * download, + GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +{ + if (!_perform_with_data_unlocked_pre (download, texture_id, data)) + return FALSE; + gst_gl_display_thread_add (download->display, (GstGLDisplayThreadFunc) _do_download, download); return TRUE; } -GstGLDownload * -gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height) +gboolean +gst_gl_download_perform_with_memory_thread (GstGLDownload * download, + GstGLMemory * gl_mem) +{ + gpointer data[GST_VIDEO_MAX_PLANES]; + guint i; + gboolean ret; + + if (!_perform_with_memory_pre (download, gl_mem)) + return FALSE; + + g_mutex_lock (&download->lock); + + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&download->info); i++) { + data[i] = (guint8 *) gl_mem->data + + GST_VIDEO_INFO_PLANE_OFFSET (&download->info, i); + } + + ret = + gst_gl_download_perform_with_data_unlocked_thread (download, + gl_mem->tex_id, data); + + GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD); + + g_mutex_unlock (&download->lock); + + return ret; +} + +gboolean +gst_gl_download_perform_with_data_thread (GstGLDownload * download, + GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +{ + gboolean ret; + + g_return_val_if_fail (download != NULL, FALSE); + + g_mutex_lock (&download->lock); + + ret = gst_gl_download_perform_with_data_unlocked_thread (download, + texture_id, data); + + g_mutex_unlock (&download->lock); + + return ret; +} + +static gboolean +gst_gl_download_perform_with_data_unlocked_thread (GstGLDownload * download, + GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +{ + if (!_perform_with_data_unlocked_pre (download, texture_id, data)) + return FALSE; + + _do_download (download->display, download); + + return TRUE; +} + +static inline guint64 * +_gen_key (GstVideoFormat v_format, guint width, guint height) { - GstGLDownload *ret; guint64 *key; /* this limits the width and the height to 2^29-1 = 536870911 */ key = g_malloc (sizeof (guint64 *)); *key = v_format | ((guint64) width << 6) | ((guint64) height << 35); + return key; +} - gst_gl_display_lock (display); +static inline GstGLDownload * +_find_download (GstGLDisplay * display, guint64 * key) +{ + GstGLDownload *ret; ret = g_hash_table_lookup (display->downloads, key); @@ -366,11 +495,41 @@ gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, g_hash_table_insert (display->downloads, key, ret); } + return ret; +} + +GstGLDownload * +gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height) +{ + GstGLDownload *ret; + guint64 *key; + + key = _gen_key (v_format, width, height); + + gst_gl_display_lock (display); + + ret = _find_download (display, key); + gst_gl_display_unlock (display); return ret; } +GstGLDownload * +gst_gl_display_find_download_thread (GstGLDisplay * display, + GstVideoFormat v_format, guint width, guint height) +{ + GstGLDownload *ret; + guint64 *key; + + key = _gen_key (v_format, width, height); + + ret = _find_download (display, key); + + return ret; +} + static void _init_download (GstGLDisplay * display, GstGLDownload * download) { diff --git a/gst-libs/gst/gl/gstgldownload.h b/gst-libs/gst/gl/gstgldownload.h index 405d33b..81d2f97 100644 --- a/gst-libs/gst/gl/gstgldownload.h +++ b/gst-libs/gst/gl/gstgldownload.h @@ -53,6 +53,7 @@ struct _GstGLDownload GstGLDisplay *display; gpointer data[GST_VIDEO_MAX_PLANES]; + gboolean initted; /* used for the conversion */ GLuint fbo; @@ -88,14 +89,23 @@ struct _GstGLDownloadClass GstGLDownload * gst_gl_download_new (GstGLDisplay * display); -gboolean gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, - guint width, guint height); -gboolean gst_gl_download_perform_with_memory (GstGLDownload * download, GstGLMemory * gl_mem); -gboolean gst_gl_download_perform_with_data (GstGLDownload * download, GLuint texture_id, - gpointer data[GST_VIDEO_MAX_PLANES]); +gboolean gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, + guint width, guint height); +gboolean gst_gl_download_init_format_thread (GstGLDownload * download, GstVideoFormat v_format, + guint width, guint height); -GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height); +gboolean gst_gl_download_perform_with_memory_thread (GstGLDownload * download, GstGLMemory * gl_mem); +gboolean gst_gl_download_perform_with_data_thread (GstGLDownload * download, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]); + +gboolean gst_gl_download_perform_with_memory (GstGLDownload * download, GstGLMemory * gl_mem); +gboolean gst_gl_download_perform_with_data (GstGLDownload * download, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]); + +GstGLDownload * gst_gl_display_find_download_thread (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height); +GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height); G_END_DECLS diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index fefe2b0..61a999d 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -35,6 +35,8 @@ static void _init_upload (GstGLDisplay * display, GstGLUpload * upload); static void _init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload); static gboolean gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); +static gboolean gst_gl_upload_perform_with_data_unlocked_thread (GstGLUpload * + upload, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); /* YUY2:r,g,a UYVY:a,b,r */ @@ -249,6 +251,37 @@ gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format, } gboolean +gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format, + guint width, guint height) +{ + GstVideoInfo info; + + g_return_val_if_fail (upload != NULL, FALSE); + g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); + g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE); + g_return_val_if_fail (width > 0 && height > 0, FALSE); + + g_mutex_lock (&upload->lock); + + if (upload->initted) { + g_mutex_unlock (&upload->lock); + return FALSE; + } else { + upload->initted = TRUE; + } + + gst_video_info_set_format (&info, v_format, width, height); + + upload->info = info; + + _init_upload (upload->display, upload); + + g_mutex_unlock (&upload->lock); + + return TRUE; +} + +gboolean gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem) { gpointer data[GST_VIDEO_MAX_PLANES]; @@ -296,8 +329,8 @@ gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint texture_id, return ret; } -static gboolean -gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, +static inline gboolean +_perform_with_data_unlocked_pre (GstGLUpload * upload, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) { guint i; @@ -318,23 +351,102 @@ gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, upload->data[i] = data[i]; } + return TRUE; +} + +static gboolean +gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, + GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +{ + if (!_perform_with_data_unlocked_pre (upload, texture_id, data)) + return FALSE; + gst_gl_display_thread_add (upload->display, (GstGLDisplayThreadFunc) _do_upload, upload); return TRUE; } -GstGLUpload * -gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height) +gboolean +gst_gl_upload_perform_with_memory_thread (GstGLUpload * upload, + GstGLMemory * gl_mem) +{ + gpointer data[GST_VIDEO_MAX_PLANES]; + guint i; + gboolean ret; + + g_return_val_if_fail (upload != NULL, FALSE); + + if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_UPLOAD_INITTED)) + return FALSE; + + if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) + return FALSE; + + g_mutex_lock (&upload->lock); + + for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) { + data[i] = (guint8 *) gl_mem->data + + GST_VIDEO_INFO_PLANE_OFFSET (&upload->info, i); + } + + ret = + gst_gl_upload_perform_with_data_unlocked_thread (upload, gl_mem->tex_id, + data); + + GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD); + + g_mutex_unlock (&upload->lock); + + return ret; +} + +gboolean +gst_gl_upload_perform_with_data_thread (GstGLUpload * upload, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]) +{ + gboolean ret; + + g_return_val_if_fail (upload != NULL, FALSE); + + g_mutex_lock (&upload->lock); + + ret = + gst_gl_upload_perform_with_data_unlocked_thread (upload, texture_id, + data); + + g_mutex_unlock (&upload->lock); + + return ret; +} + +static gboolean +gst_gl_upload_perform_with_data_unlocked_thread (GstGLUpload * upload, + GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) +{ + if (!_perform_with_data_unlocked_pre (upload, texture_id, data)) + return FALSE; + + _do_upload (upload->display, upload); + + return TRUE; +} + +static inline guint64 * +_gen_key (GstVideoFormat v_format, guint width, guint height) { - GstGLUpload *ret; guint64 *key; + /* this limits the width and the height to 2^29-1 = 536870911 */ key = g_malloc (sizeof (guint64 *)); *key = v_format | ((guint64) width << 6) | ((guint64) height << 35); + return key; +} - gst_gl_display_lock (display); +static inline GstGLUpload * +_find_upload (GstGLDisplay * display, guint64 * key) +{ + GstGLUpload *ret; ret = g_hash_table_lookup (display->uploads, key); @@ -344,11 +456,41 @@ gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, g_hash_table_insert (display->uploads, key, ret); } + return ret; +} + +GstGLUpload * +gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height) +{ + GstGLUpload *ret; + guint64 *key; + + key = _gen_key (v_format, width, height); + + gst_gl_display_lock (display); + + ret = _find_upload (display, key); + gst_gl_display_unlock (display); return ret; } +GstGLUpload * +gst_gl_display_find_upload_thread (GstGLDisplay * display, + GstVideoFormat v_format, guint width, guint height) +{ + GstGLUpload *ret; + guint64 *key; + + key = _gen_key (v_format, width, height); + + ret = _find_upload (display, key); + + return ret; +} + /* Called in the gl thread */ void _init_upload (GstGLDisplay * display, GstGLUpload * upload) diff --git a/gst-libs/gst/gl/gstglupload.h b/gst-libs/gst/gl/gstglupload.h index ad18eaf..a8a2dab 100644 --- a/gst-libs/gst/gl/gstglupload.h +++ b/gst-libs/gst/gl/gstglupload.h @@ -91,14 +91,21 @@ GstGLUpload * gst_gl_upload_new (GstGLDisplay * display); gboolean gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format, guint width, guint height); - -gboolean gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem); -gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint texture_id, - gpointer data[GST_VIDEO_MAX_PLANES]); - -GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, +gboolean gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format, guint width, guint height); +gboolean gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem); +gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]); +gboolean gst_gl_upload_perform_with_memory_thread (GstGLUpload * upload, GstGLMemory * gl_mem); +gboolean gst_gl_upload_perform_with_data_thread (GstGLUpload * upload, GLuint texture_id, + gpointer data[GST_VIDEO_MAX_PLANES]); + +GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height); +GstGLUpload * gst_gl_display_find_upload_thread (GstGLDisplay * display, GstVideoFormat v_format, + guint width, guint height); + G_END_DECLS #endif /* __GST_GL_UPLOAD_H__ */ -- 2.7.4