support multiple threads for vaapivideopool
authorWind Yuan <feng.yuan@intel.com>
Tue, 29 Nov 2011 02:31:02 +0000 (10:31 +0800)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:09 +0000 (15:37 +0800)
gst-libs/gst/vaapi/gstvaapivideopool.c

index 774305e..69723ad 100644 (file)
@@ -37,6 +37,10 @@ G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT)
                                  GST_VAAPI_TYPE_VIDEO_POOL,    \
                                  GstVaapiVideoPoolPrivate))
 
+#define VAAPI_VIDEO_POOL_LOCK(mutex)    g_static_rec_mutex_lock(mutex)
+#define VAAPI_VIDEO_POOL_UNLOCK(mutex)  g_static_rec_mutex_unlock(mutex)
+
+
 struct _GstVaapiVideoPoolPrivate {
     GstVaapiDisplay    *display;
     GQueue              free_objects;
@@ -44,6 +48,8 @@ struct _GstVaapiVideoPoolPrivate {
     GstCaps            *caps;
     guint               used_count;
     guint               capacity;
+
+    GStaticRecMutex     mutex;
 };
 
 enum {
@@ -226,6 +232,7 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool)
     priv->capacity      = 0;
 
     g_queue_init(&priv->free_objects);
+    g_static_rec_mutex_init(&priv->mutex);
 }
 
 /**
@@ -295,24 +302,32 @@ gpointer
 gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
 {
     GstVaapiVideoPoolPrivate *priv;
-    gpointer object;
+    gpointer object = NULL;
 
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
 
     priv = pool->priv;
+
+    VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
     if (priv->capacity && priv->used_count >= priv->capacity)
-        return NULL;
+        goto end;
 
     object = g_queue_pop_head(&priv->free_objects);
     if (!object) {
+        VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
         object = gst_vaapi_video_pool_alloc_object(pool);
+        VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
         if (!object)
-            return NULL;
+            goto end;
     }
 
     ++priv->used_count;
     priv->used_objects = g_list_prepend(priv->used_objects, object);
-    return g_object_ref(object);
+    g_object_ref(object);
+
+  end:
+    VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
+    return object;
 }
 
 /**
@@ -335,14 +350,19 @@ gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
     g_return_if_fail(G_IS_OBJECT(object));
 
     priv = pool->priv;
+
+    VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
     elem = g_list_find(priv->used_objects, object);
     if (!elem)
-        return;
+        goto end;
 
     g_object_unref(object);
     --priv->used_count;
     priv->used_objects = g_list_delete_link(priv->used_objects, elem);
     g_queue_push_tail(&priv->free_objects, object);
+
+  end:
+    VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
 }
 
 /**
@@ -362,7 +382,10 @@ gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object)
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
     g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
 
+    VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
     g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object));
+    VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+
     return TRUE;
 }
 
@@ -403,9 +426,14 @@ gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects)
 guint
 gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool)
 {
+    guint size;
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
 
-    return g_queue_get_length(&pool->priv->free_objects);
+
+    VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+    size = g_queue_get_length(&pool->priv->free_objects);
+    VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+    return size;
 }
 
 /**
@@ -424,23 +452,31 @@ gboolean
 gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n)
 {
     guint i, num_allocated;
+    gboolean ret = TRUE;
 
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
 
+    VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+
     num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count;
     if (n < num_allocated)
-        return TRUE;
+        goto end;
 
     if ((n -= num_allocated) > pool->priv->capacity)
         n = pool->priv->capacity;
 
     for (i = num_allocated; i < n; i++) {
         gpointer const object = gst_vaapi_video_pool_alloc_object(pool);
-        if (!object)
-            return FALSE;
+        if (!object) {
+            ret = FALSE;
+            goto end;
+        }
         g_queue_push_tail(&pool->priv->free_objects, object);
     }
-    return TRUE;
+    ret = TRUE;
+  end:
+    VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+    return ret;
 }
 
 /**
@@ -455,9 +491,12 @@ gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n)
 guint
 gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool)
 {
+    guint capacity;
     g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
-
-    return pool->priv->capacity;
+    VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+    capacity = pool->priv->capacity;
+    VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+    return capacity;
 }
 
 /**
@@ -471,6 +510,7 @@ void
 gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity)
 {
     g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
-
+    VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
     pool->priv->capacity = capacity;
+    VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
 }