From bb79853d20a57114ad030c15120c017ed7bd5030 Mon Sep 17 00:00:00 2001
From: Mengkejiergeli Ba <mengkejiergeli.ba@intel.com>
Date: Wed, 8 Jun 2022 12:31:56 +0800
Subject: [PATCH] msdkvpp : Use va pool at linux path and system pool for
 windows

We use msdkvpp's own pool to allocate buffers instead of external frame
allocator mfxFrameAllocator.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2498>
---
 .../gst-plugins-bad/sys/msdk/gstmsdkvpp.c     | 160 +++++++++---------
 .../gst-plugins-bad/sys/msdk/gstmsdkvpp.h     |   2 -
 2 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.c b/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.c
index 118450278c..b0950d1169 100644
--- a/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.c
+++ b/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.c
@@ -64,6 +64,7 @@
 
 #ifndef _WIN32
 #include "gstmsdkallocator_libva.h"
+#include <gst/va/gstvaallocator.h>
 #if VA_CHECK_VERSION(1, 4, 1)
 #undef EXT_FORMATS
 #define EXT_FORMATS     ", BGR10A2_LE"
@@ -407,59 +408,88 @@ gst_msdkvpp_prepare_output_buffer (GstBaseTransform * trans,
   return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR;
 }
 
+#ifndef _WIN32
+static GstBufferPool *
+gst_msdk_create_va_pool (GstVideoInfo * info, GstMsdkContext * msdk_context,
+    gboolean use_dmabuf, guint min_buffers)
+{
+  GstBufferPool *pool = NULL;
+  GstAllocator *allocator;
+  GArray *formats = NULL;
+  GstAllocationParams alloc_params = { 0, 31, 0, 0 };
+  GstVaDisplay *display = NULL;
+  GstCaps *aligned_caps = NULL;
+
+  display = (GstVaDisplay *) gst_msdk_context_get_display (msdk_context);
+
+  if (use_dmabuf)
+    allocator = gst_va_dmabuf_allocator_new (display);
+  else {
+    formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
+    g_array_append_val (formats, GST_VIDEO_INFO_FORMAT (info));
+    allocator = gst_va_allocator_new (display, formats);
+  }
+  if (!allocator) {
+    GST_ERROR ("Failed to create allocator");
+    if (formats)
+      g_array_unref (formats);
+    return NULL;
+  }
+  aligned_caps = gst_video_info_to_caps (info);
+  pool =
+      gst_va_pool_new_with_config (aligned_caps,
+      GST_VIDEO_INFO_SIZE (info), min_buffers, 0,
+      VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC, GST_VA_FEATURE_AUTO,
+      allocator, &alloc_params);
+
+  gst_object_unref (allocator);
+  gst_caps_unref (aligned_caps);
+
+  return pool;
+}
+#endif
+
 static GstBufferPool *
 gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction,
     GstCaps * caps, guint min_num_buffers)
 {
   GstBufferPool *pool = NULL;
   GstStructure *config;
-  GstAllocator *allocator = NULL;
   GstVideoInfo info;
   GstVideoInfo *pool_info = NULL;
   GstVideoAlignment align;
-  GstAllocationParams params = { 0, 31, 0, 0, };
-  mfxFrameAllocResponse *alloc_resp = NULL;
   gboolean use_dmabuf = FALSE;
 
   if (direction == GST_PAD_SINK) {
-    alloc_resp = &thiz->in_alloc_resp;
     pool_info = &thiz->sinkpad_buffer_pool_info;
     use_dmabuf = thiz->use_sinkpad_dmabuf;
   } else if (direction == GST_PAD_SRC) {
-    alloc_resp = &thiz->out_alloc_resp;
     pool_info = &thiz->srcpad_buffer_pool_info;
     use_dmabuf = thiz->use_srcpad_dmabuf;
   }
 
-  pool = gst_msdk_buffer_pool_new (thiz->context, alloc_resp);
-  if (!pool)
-    goto error_no_pool;
-
-  if (!gst_video_info_from_caps (&info, caps))
+  if (!gst_video_info_from_caps (&info, caps)) {
     goto error_no_video_info;
+  }
 
   gst_msdk_set_video_alignment (&info, 0, 0, &align);
   gst_video_info_align (&info, &align);
 
-  if (use_dmabuf)
-    allocator =
-        gst_msdk_dmabuf_allocator_new (thiz->context, &info, alloc_resp);
-  else if (thiz->use_video_memory)
-    allocator = gst_msdk_video_allocator_new (thiz->context, &info, alloc_resp);
+#ifndef _WIN32
+  pool = gst_msdk_create_va_pool (&info, thiz->context, use_dmabuf,
+      min_num_buffers);
+#else
+  /* Currently use system pool for windows path */
+  if (!thiz->use_video_memory)
+    pool = gst_video_buffer_pool_new ();
   else
-    allocator = gst_msdk_system_allocator_new (&info);
+    GST_ERROR_OBJECT (thiz, "D3D video memory pool is not implemented");
+#endif
 
-  if (!allocator)
-    goto error_no_allocator;
+  if (!pool)
+    goto error_no_pool;
 
   config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
-  /* we do not support dynamic buffer count change */
-  gst_buffer_pool_config_set_params (config, caps, info.size, min_num_buffers,
-      min_num_buffers);
-
-  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
-  gst_buffer_pool_config_add_option (config,
-      GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
   if (thiz->use_video_memory) {
     gst_buffer_pool_config_add_option (config,
         GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY);
@@ -468,14 +498,17 @@ gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction,
           GST_BUFFER_POOL_OPTION_MSDK_USE_DMABUF);
   }
 
+  gst_buffer_pool_config_set_params (config, caps,
+      GST_VIDEO_INFO_SIZE (&info), min_num_buffers, 0);
+  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+  gst_buffer_pool_config_add_option (config,
+      GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
   gst_buffer_pool_config_set_video_alignment (config, &align);
-  gst_buffer_pool_config_set_allocator (config, allocator, &params);
-  gst_object_unref (allocator);
 
   if (!gst_buffer_pool_set_config (pool, config))
     goto error_pool_config;
 
-  /* Updating pool_info with aligned info of allocator */
+  /* Updating pool_info with info which used to config pool */
   *pool_info = info;
 
   return pool;
@@ -491,17 +524,10 @@ error_no_video_info:
     gst_object_unref (pool);
     return NULL;
   }
-error_no_allocator:
-  {
-    GST_INFO_OBJECT (thiz, "Failed to create allocator");
-    gst_object_unref (pool);
-    return NULL;
-  }
 error_pool_config:
   {
     GST_INFO_OBJECT (thiz, "Failed to set config");
     gst_object_unref (pool);
-    gst_object_unref (allocator);
     return NULL;
   }
 }
@@ -556,21 +582,11 @@ create_src_pool (GstMsdkVPP * thiz, GstQuery * query, GstCaps * caps)
     min_buffers = SRC_POOL_SIZE_DEFAULT;
   }
 
-  /* Always create a pool for vpp out buffers. Each of the msdk element
-   * has to create it's own mfxsurfacepool which is an msdk constraint.
-   * For eg: Each Msdk component (vpp, dec and enc) will invoke the external
-   * Frame allocator for video-memory usage.So sharing the pool between
-   * gst-msdk elements might not be a good idea, rather each element
-   * can check the buffer type (whether it is from msdk-buffer pool)
-   * to make sure there is no copy. Since we share the context between
-   * msdk elements, using buffers from one sdk's framealloator in another
-   * sdk-components is perfectly fine */
-  gst_msdk_frame_free (thiz->context, &thiz->out_alloc_resp);
-
+  /* Always create a pool for vpp out buffers. For vpp, we don't use
+   * external mfxFrameAllocator for video-memory allocation. */
   request = thiz->request[1];
   min_buffers += thiz->async_depth + request.NumFrameSuggested;
   request.NumFrameSuggested = min_buffers;
-  gst_msdk_frame_alloc (thiz->context, &request, &thiz->out_alloc_resp);
 
   pool = gst_msdkvpp_create_buffer_pool (thiz, GST_PAD_SRC, caps, min_buffers);
   if (!pool)
@@ -700,7 +716,6 @@ get_surface_from_pool (GstMsdkVPP * thiz, GstBufferPool * pool,
     GstBufferPoolAcquireParams * params)
 {
   GstBuffer *new_buffer;
-  mfxFrameSurface1 *new_surface;
   GstMsdkSurface *msdk_surface = NULL;
 
   if (!gst_buffer_pool_is_active (pool) &&
@@ -713,24 +728,16 @@ get_surface_from_pool (GstMsdkVPP * thiz, GstBufferPool * pool,
     GST_ERROR_OBJECT (pool, "failed to acquire a buffer from pool");
     return NULL;
   }
-
-  if (gst_msdk_is_msdk_buffer (new_buffer)) {
-    new_surface = gst_msdk_get_surface_from_buffer (new_buffer);
-    msdk_surface = g_slice_new0 (GstMsdkSurface);
-    msdk_surface->surface = new_surface;
-    msdk_surface->buf = new_buffer;
-  } else {
 #ifndef _WIN32
-    msdk_surface = gst_msdk_import_to_msdk_surface (new_buffer, thiz->context,
-        &thiz->sinkpad_info);
-    if (msdk_surface)
-      msdk_surface->buf = new_buffer;
-    else {
-      GST_ERROR_OBJECT (pool, "Failed to get msdk surface");
-      return NULL;
-    }
+  msdk_surface = gst_msdk_import_to_msdk_surface (new_buffer, thiz->context,
+      &thiz->sinkpad_info);
+#else
+  msdk_surface = gst_msdk_import_sys_mem_to_msdk_surface
+      (new_buffer, thiz->sinkpad_buffer_pool_info);
 #endif
-  }
+
+  if (msdk_surface)
+    msdk_surface->buf = new_buffer;
 
   return msdk_surface;
 }
@@ -836,10 +843,13 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
 #ifndef _WIN32
     out_surface = gst_msdk_import_to_msdk_surface (outbuf, thiz->context,
         &thiz->srcpad_info);
+#else
+    out_surface =
+        gst_msdk_import_sys_mem_to_msdk_surface (outbuf, thiz->srcpad_info);
+#endif
     if (out_surface)
       out_surface->buf = gst_buffer_ref (outbuf);
-#endif
-    if (!out_surface) {
+    else {
       GST_ERROR_OBJECT (thiz, "Failed to get msdk outsurface!");
       free_msdk_surface (in_surface);
       return GST_FLOW_ERROR;
@@ -926,12 +936,14 @@ gst_msdkvpp_transform (GstBaseTransform * trans, GstBuffer * inbuf,
 #ifndef _WIN32
         out_surface = gst_msdk_import_to_msdk_surface (outbuf, thiz->context,
             &thiz->srcpad_info);
+#else
+        out_surface =
+            gst_msdk_import_sys_mem_to_msdk_surface (outbuf, thiz->srcpad_info);
+#endif
         if (out_surface) {
           out_surface->buf = gst_buffer_ref (outbuf);
           create_new_surface = TRUE;
-        }
-#endif
-        if (!out_surface) {
+        } else {
           GST_ERROR_OBJECT (thiz, "Failed to get msdk outsurface!");
           release_in_surface (thiz, in_surface, locked_by_others);
           return GST_FLOW_ERROR;
@@ -976,11 +988,6 @@ gst_msdkvpp_close (GstMsdkVPP * thiz)
   if (!thiz->context)
     return;
 
-  if (thiz->use_video_memory) {
-    gst_msdk_frame_free (thiz->context, &thiz->in_alloc_resp);
-    gst_msdk_frame_free (thiz->context, &thiz->out_alloc_resp);
-  }
-
   GST_DEBUG_OBJECT (thiz, "Closing VPP 0x%p", thiz->context);
   status = MFXVideoVPP_Close (gst_msdk_context_get_session (thiz->context));
   if (status != MFX_ERR_NONE && status != MFX_ERR_NOT_INITIALIZED) {
@@ -1130,10 +1137,6 @@ gst_msdkvpp_initialize (GstMsdkVPP * thiz)
    * fail
    */
   if (thiz->initialized) {
-    if (thiz->use_video_memory) {
-      gst_msdk_frame_free (thiz->context, &thiz->in_alloc_resp);
-    }
-
     MFXVideoVPP_Close (session);
 
     memset (&thiz->param, 0, sizeof (thiz->param));
@@ -1216,7 +1219,6 @@ gst_msdkvpp_initialize (GstMsdkVPP * thiz)
     request[0].Type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
     if (thiz->use_sinkpad_dmabuf)
       request[0].Type |= MFX_MEMTYPE_EXPORT_FRAME;
-    gst_msdk_frame_alloc (thiz->context, &(request[0]), &thiz->in_alloc_resp);
 
     /* Output surface pool pre-allocation */
     request[1].Type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
diff --git a/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.h b/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.h
index de96177d86..4be2b90dad 100644
--- a/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.h
+++ b/subprojects/gst-plugins-bad/sys/msdk/gstmsdkvpp.h
@@ -92,8 +92,6 @@ struct _GstMsdkVPP
   GstMsdkContext *old_context;
   mfxVideoParam param;
   guint in_num_surfaces;
-  mfxFrameAllocResponse in_alloc_resp;
-  mfxFrameAllocResponse out_alloc_resp;
 
   gboolean initialized;
   gboolean use_video_memory;