vaapivideomemory: use an image pool to cache objects.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 24 Jul 2014 04:46:22 +0000 (06:46 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 24 Jul 2014 04:55:26 +0000 (06:55 +0200)
Use an image pool to hold VA images to be used for downloads/uploads
of contents for the associated surface.

This is an optmization for size. So, instead of creating as many VA
images as there are buffers (then VA surfaces) allocated, we only
maintain a minimal set of live VA images, thus preserving memory
resources.

gst/vaapi/gstvaapivideomemory.c
gst/vaapi/gstvaapivideomemory.h

index 1788125..dfbb9c5 100644 (file)
@@ -21,6 +21,8 @@
  */
 
 #include "gst/vaapi/sysdeps.h"
+#include <gst/vaapi/gstvaapisurfacepool.h>
+#include <gst/vaapi/gstvaapiimagepool.h>
 #include "gstvaapivideomemory.h"
 
 GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory);
@@ -35,6 +37,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapivideomemory);
 /* --- GstVaapiVideoMemory                                              --- */
 /* ------------------------------------------------------------------------ */
 
+static void
+gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem);
+
 static guchar *
 get_image_data(GstVaapiImage *image)
 {
@@ -73,10 +78,10 @@ ensure_image(GstVaapiVideoMemory *mem)
     }
 
     if (!mem->image) {
-        GstVaapiDisplay * const display =
-            gst_vaapi_video_meta_get_display(mem->meta);
+        GstVaapiVideoAllocator * const allocator =
+            GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator);
 
-        mem->image = new_image(display, mem->image_info);
+        mem->image = gst_vaapi_video_pool_get_object(allocator->image_pool);
         if (!mem->image)
             return FALSE;
     }
@@ -283,20 +288,33 @@ static void
 gst_vaapi_video_memory_free(GstVaapiVideoMemory *mem)
 {
     mem->surface = NULL;
+    gst_vaapi_video_memory_reset_image(mem);
     gst_vaapi_surface_proxy_replace(&mem->proxy, NULL);
-    gst_vaapi_object_replace(&mem->image, NULL);
     gst_vaapi_video_meta_unref(mem->meta);
     gst_object_unref(GST_MEMORY_CAST(mem)->allocator);
     g_slice_free(GstVaapiVideoMemory, mem);
 }
 
 void
+gst_vaapi_video_memory_reset_image(GstVaapiVideoMemory *mem)
+{
+    GstVaapiVideoAllocator * const allocator =
+        GST_VAAPI_VIDEO_ALLOCATOR_CAST(GST_MEMORY_CAST(mem)->allocator);
+
+    if (mem->use_direct_rendering)
+        gst_vaapi_object_replace(&mem->image, NULL);
+    else if (mem->image) {
+        gst_vaapi_video_pool_put_object(allocator->image_pool, mem->image);
+        mem->image = NULL;
+    }
+}
+
+void
 gst_vaapi_video_memory_reset_surface(GstVaapiVideoMemory *mem)
 {
     mem->surface = NULL;
+    gst_vaapi_video_memory_reset_image(mem);
     gst_vaapi_surface_proxy_replace(&mem->proxy, NULL);
-    if (mem->use_direct_rendering)
-        gst_vaapi_object_replace(&mem->image, NULL);
     gst_vaapi_video_meta_set_surface_proxy(mem->meta, NULL);
 }
 
@@ -474,6 +492,7 @@ gst_vaapi_video_allocator_finalize(GObject *object)
         GST_VAAPI_VIDEO_ALLOCATOR_CAST(object);
 
     gst_vaapi_video_pool_replace(&allocator->surface_pool, NULL);
+    gst_vaapi_video_pool_replace(&allocator->image_pool, NULL);
 
     G_OBJECT_CLASS(gst_vaapi_video_allocator_parent_class)->finalize(object);
 }
@@ -595,7 +614,7 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip)
     allocator->surface_pool = gst_vaapi_surface_pool_new(display,
         &allocator->surface_info);
     if (!allocator->surface_pool)
-        goto error_create_pool;
+        goto error_create_surface_pool;
 
     allocator->image_info = *vip;
     if (GST_VIDEO_INFO_FORMAT(vip) == GST_VIDEO_FORMAT_ENCODED)
@@ -616,13 +635,24 @@ gst_vaapi_video_allocator_new(GstVaapiDisplay *display, const GstVideoInfo *vip)
         } while (0);
         gst_vaapi_object_unref(image);
     }
+
+    allocator->image_pool = gst_vaapi_image_pool_new(display,
+        &allocator->image_info);
+    if (!allocator->image_pool)
+        goto error_create_image_pool;
     return GST_ALLOCATOR_CAST(allocator);
 
     /* ERRORS */
-error_create_pool:
+error_create_surface_pool:
     {
         GST_ERROR("failed to allocate VA surface pool");
         gst_object_unref(allocator);
         return NULL;
     }
+error_create_image_pool:
+    {
+        GST_ERROR("failed to allocate VA image pool");
+        gst_object_unref(allocator);
+        return NULL;
+    }
 }
index d58501d..587d443 100644 (file)
@@ -26,7 +26,7 @@
 #include <gst/gstallocator.h>
 #include <gst/video/video-info.h>
 #include <gst/vaapi/gstvaapidisplay.h>
-#include <gst/vaapi/gstvaapisurfacepool.h>
+#include <gst/vaapi/gstvaapivideopool.h>
 #include "gstvaapivideometa.h"
 
 G_BEGIN_DECLS
@@ -137,6 +137,7 @@ struct _GstVaapiVideoAllocator {
     GstVideoInfo        surface_info;
     GstVaapiVideoPool  *surface_pool;
     GstVideoInfo        image_info;
+    GstVaapiVideoPool  *image_pool;
     gboolean            has_direct_rendering;
 };