msdk: Add method to export dmabuf to VASurface
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>
Thu, 31 May 2018 00:22:49 +0000 (16:22 -0800)
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>
Thu, 31 May 2018 00:22:49 +0000 (16:22 -0800)
Exporting DRM_PRIME fd to VASurface requires direct
invocation of VA api VACreateSurface with
VASurfaceAttribExternalBufferDescriptor and other
necessary surface attributes.

https://bugzilla.gnome.org/show_bug.cgi?id=794817

sys/msdk/gstmsdkallocator_libva.c
sys/msdk/gstmsdkallocator_libva.h

index 63d81b2..9ecc3ab 100644 (file)
@@ -374,3 +374,94 @@ gst_msdk_get_dmabuf_info_from_surface (mfxFrameSurface1 * surface,
 
   return TRUE;
 }
+
+gboolean
+gst_msdk_export_dmabuf_to_vasurface (GstMsdkContext * context,
+    GstVideoInfo * vinfo, gint fd, VASurfaceID * surface_id)
+{
+  GstVideoFormat format;
+  guint width, height, size, i;
+  unsigned long extbuf_handle;
+  guint va_fourcc = 0, va_chroma = 0;
+  VASurfaceAttrib attribs[2], *attrib;
+  VASurfaceAttribExternalBuffers extbuf;
+  VAStatus va_status;
+  mfxStatus status = MFX_ERR_NONE;
+
+  g_return_val_if_fail (context != NULL, FALSE);
+  g_return_val_if_fail (vinfo != NULL, FALSE);
+  g_return_val_if_fail (fd >= 0, FALSE);
+
+  extbuf_handle = (guintptr) (fd);
+
+  format = GST_VIDEO_INFO_FORMAT (vinfo);
+  width = GST_VIDEO_INFO_WIDTH (vinfo);
+  height = GST_VIDEO_INFO_HEIGHT (vinfo);
+  size = GST_VIDEO_INFO_SIZE (vinfo);
+
+  /* Fixme: Move to common format handling util */
+  switch (format) {
+    case GST_VIDEO_FORMAT_NV12:
+      va_chroma = VA_RT_FORMAT_YUV420;
+      va_fourcc = VA_FOURCC_NV12;
+      break;
+    case GST_VIDEO_FORMAT_BGRA:
+      va_chroma = VA_RT_FORMAT_YUV444;
+      va_fourcc = VA_FOURCC_BGRA;
+      break;
+    case GST_VIDEO_FORMAT_YUY2:
+      va_chroma = VA_RT_FORMAT_YUV422;
+      va_fourcc = VA_FOURCC_YUY2;
+      break;
+    default:
+      goto error_unsupported_format;
+  }
+
+  /* Fill the VASurfaceAttribExternalBuffers */
+  extbuf.pixel_format = va_fourcc;
+  extbuf.width = width;
+  extbuf.height = height;
+  extbuf.data_size = size;
+  extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vinfo);
+  for (i = 0; i < extbuf.num_planes; i++) {
+    extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i);
+    extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i);
+  }
+  extbuf.buffers = (uintptr_t *) & extbuf_handle;
+  extbuf.num_buffers = 1;
+  extbuf.flags = 0;
+  extbuf.private_data = NULL;
+
+  /* Fill the Surface Attributes */
+  attrib = attribs;
+  attrib->type = VASurfaceAttribMemoryType;
+  attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
+  attrib->value.type = VAGenericValueTypeInteger;
+  attrib->value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
+  attrib++;
+  attrib->type = VASurfaceAttribExternalBufferDescriptor;
+  attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
+  attrib->value.type = VAGenericValueTypePointer;
+  attrib->value.value.p = &extbuf;
+  attrib++;
+
+  va_status = vaCreateSurfaces (gst_msdk_context_get_handle (context),
+      va_chroma, width, height, surface_id, 1, attribs, attrib - attribs);
+  status = gst_msdk_get_mfx_status_from_va_status (va_status);
+  if (status != MFX_ERR_NONE)
+    goto error_create_surface;
+
+  return TRUE;
+
+error_unsupported_format:
+  {
+    GST_ERROR ("Unsupported Video format %s, Can't export dmabuf to vaSurface",
+        gst_video_format_to_string (format));
+    return FALSE;
+  }
+error_create_surface:
+  {
+    GST_ERROR ("Failed to create the VASurface from DRM_PRIME FD");
+    return FALSE;
+  }
+}
index 8600260..b30eaf3 100644 (file)
@@ -41,6 +41,10 @@ G_BEGIN_DECLS
 gboolean
 gst_msdk_get_dmabuf_info_from_surface (mfxFrameSurface1 * surface, gint *handle, gsize *size);
 
+gboolean
+gst_msdk_export_dmabuf_to_vasurface (GstMsdkContext *context,
+    GstVideoInfo *vinfo, gint fd, VASurfaceID *surface_id);
+
 G_END_DECLS
 
 #endif /* GST_MSDK_ALLOCATOR_LIBVA_H_ */