[578/906] {up,down}load: add variants that can be called in the gl thread
authorMatthew Waters <ystreet00@gmail.com>
Tue, 18 Sep 2012 11:39:21 +0000 (21:39 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:25 +0000 (19:31 +0000)
gst-libs/gst/gl/gstgldownload.c
gst-libs/gst/gl/gstgldownload.h
gst-libs/gst/gl/gstglupload.c
gst-libs/gst/gl/gstglupload.h

index 3a66533..c485984 100644 (file)
@@ -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)
 {
index 405d33b..81d2f97 100644 (file)
@@ -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
 
index fefe2b0..61a999d 100644 (file)
@@ -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)
index ad18eaf..a8a2dab 100644 (file)
@@ -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__ */