mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-10 03:19:40 +00:00
011f9bd6cb
Add new gst_vaapi_surface_new_with_dma_buf_handle() helper function to allow for creating VA surfaces from a foreign DRM PRIME fd. The resulting VA surface owns the supplied buffer handle. https://bugzilla.gnome.org/show_bug.cgi?id=735362
152 lines
5 KiB
C
152 lines
5 KiB
C
/*
|
|
* gstvaapisurface_drm.c - VA surface abstraction (DRM interop)
|
|
*
|
|
* Copyright (C) 2014 Intel Corporation
|
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "sysdeps.h"
|
|
#include "gstvaapisurface_drm.h"
|
|
#include "gstvaapisurface_priv.h"
|
|
#include "gstvaapiimage_priv.h"
|
|
#include "gstvaapibufferproxy_priv.h"
|
|
|
|
static GstVaapiBufferProxy *
|
|
gst_vaapi_surface_get_drm_buf_handle (GstVaapiSurface * surface, guint type)
|
|
{
|
|
GstVaapiBufferProxy *proxy;
|
|
GstVaapiImage *image;
|
|
|
|
image = gst_vaapi_surface_derive_image (surface);
|
|
if (!image)
|
|
goto error_derive_image;
|
|
|
|
proxy =
|
|
gst_vaapi_buffer_proxy_new_from_object (GST_VAAPI_OBJECT (surface),
|
|
image->internal_image.buf, type, gst_vaapi_object_unref, image);
|
|
if (!proxy)
|
|
goto error_alloc_export_buffer;
|
|
return proxy;
|
|
|
|
/* ERRORS */
|
|
error_derive_image:
|
|
GST_ERROR ("failed to extract image handle from surface");
|
|
return NULL;
|
|
error_alloc_export_buffer:
|
|
GST_ERROR ("failed to allocate export buffer proxy");
|
|
gst_vaapi_object_unref (image);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_surface_get_dma_buf_handle:
|
|
* @surface: a #GstVaapiSurface
|
|
*
|
|
* If the underlying VA driver implementation supports it, this
|
|
* function allows for returning a suitable dma_buf (DRM) buffer
|
|
* handle as a #GstVaapiBufferProxy instance. The resulting buffer
|
|
* handle is live until the last reference to the proxy gets
|
|
* released. Besides, any further change to the parent VA @surface may
|
|
* fail.
|
|
*
|
|
* Return value: the underlying buffer as a #GstVaapiBufferProxy
|
|
* instance.
|
|
*/
|
|
GstVaapiBufferProxy *
|
|
gst_vaapi_surface_get_dma_buf_handle (GstVaapiSurface * surface)
|
|
{
|
|
g_return_val_if_fail (surface != NULL, NULL);
|
|
|
|
return gst_vaapi_surface_get_drm_buf_handle (surface,
|
|
GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF);
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_surface_get_gem_buf_handle:
|
|
* @surface: a #GstVaapiSurface
|
|
*
|
|
* If the underlying VA driver implementation supports it, this
|
|
* function allows for returning a suitable GEM buffer handle as a
|
|
* #GstVaapiBufferProxy instance. The resulting buffer handle is live
|
|
* until the last reference to the proxy gets released. Besides, any
|
|
* further change to the parent VA @surface may fail.
|
|
*
|
|
* Return value: the underlying buffer as a #GstVaapiBufferProxy
|
|
* instance.
|
|
*/
|
|
GstVaapiBufferProxy *
|
|
gst_vaapi_surface_get_gem_buf_handle (GstVaapiSurface * surface)
|
|
{
|
|
g_return_val_if_fail (surface != NULL, NULL);
|
|
|
|
return gst_vaapi_surface_get_drm_buf_handle (surface,
|
|
GST_VAAPI_BUFFER_MEMORY_TYPE_GEM_BUF);
|
|
}
|
|
|
|
static void
|
|
fill_video_info (GstVideoInfo * vip, GstVideoFormat format, guint width,
|
|
guint height, gsize offset[GST_VIDEO_MAX_PLANES],
|
|
gint stride[GST_VIDEO_MAX_PLANES])
|
|
{
|
|
guint i;
|
|
|
|
gst_video_info_init (vip);
|
|
gst_video_info_set_format (vip, format, width, height);
|
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vip); i++) {
|
|
GST_VIDEO_INFO_PLANE_OFFSET (vip, i) = offset[i];
|
|
GST_VIDEO_INFO_PLANE_STRIDE (vip, i) = stride[i];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_surface_new_with_dma_buf_handle:
|
|
* @display: a #GstVaapiDisplay
|
|
* @fd: the DRM PRIME file descriptor
|
|
* @size: the underlying DRM buffer size
|
|
* @format: the desired surface format
|
|
* @width: the desired surface width in pixels
|
|
* @height: the desired surface height in pixels
|
|
* @offset: the offsets to each plane
|
|
* @stride: the pitches for each plane
|
|
*
|
|
* Creates a new #GstVaapiSurface with an external DRM PRIME file
|
|
* descriptor. The newly created VA surfaces owns the supplied buffer
|
|
* handle.
|
|
*
|
|
* Return value: the newly allocated #GstVaapiSurface object, or %NULL
|
|
* if creation from DRM PRIME fd failed, or is not supported
|
|
*/
|
|
GstVaapiSurface *
|
|
gst_vaapi_surface_new_with_dma_buf_handle (GstVaapiDisplay * display,
|
|
gint fd, guint size, GstVideoFormat format, guint width, guint height,
|
|
gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES])
|
|
{
|
|
GstVaapiBufferProxy *proxy;
|
|
GstVaapiSurface *surface;
|
|
GstVideoInfo vi;
|
|
|
|
proxy = gst_vaapi_buffer_proxy_new ((gintptr) fd,
|
|
GST_VAAPI_BUFFER_MEMORY_TYPE_DMA_BUF, size, NULL, NULL);
|
|
if (!proxy)
|
|
return NULL;
|
|
|
|
fill_video_info (&vi, format, width, height, offset, stride);
|
|
surface = gst_vaapi_surface_new_from_buffer_proxy (display, proxy, &vi);
|
|
gst_vaapi_buffer_proxy_unref (proxy);
|
|
return surface;
|
|
}
|