surface: add more fine-grained allocation helper.

Add new gst_vaapi_surface_new_full() helper function that allocates
VA surface from a GstVideoInfo template in argument. Additional flags
may include ways to
- allocate linear storage (GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE) ;
- allocate with fixed strides (GST_VAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) ;
- allocate with fixed offsets (GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS).
This commit is contained in:
Gwenole Beauchesne 2015-01-27 11:16:34 +01:00
parent 334dd704b6
commit 4ebfba0d49
2 changed files with 111 additions and 26 deletions

View file

@ -127,16 +127,19 @@ error_unsupported_chroma_type:
}
static gboolean
gst_vaapi_surface_create_with_format (GstVaapiSurface * surface,
GstVideoFormat format, guint width, guint height)
gst_vaapi_surface_create_full (GstVaapiSurface * surface,
const GstVideoInfo * vip, guint flags)
{
#if VA_CHECK_VERSION(0,34,0)
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface);
const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip);
VASurfaceID surface_id;
VAStatus status;
guint chroma_type, va_chroma_format;
guint chroma_type, va_chroma_format, i;
const VAImageFormat *va_format;
VASurfaceAttrib attrib;
VASurfaceAttrib attribs[3], *attrib;
VASurfaceAttribExternalBuffers extbuf;
gboolean extbuf_needed = FALSE;
va_format = gst_vaapi_video_format_to_va_format (format);
if (!va_format)
@ -150,22 +153,57 @@ gst_vaapi_surface_create_with_format (GstVaapiSurface * surface,
if (!va_chroma_format)
goto error_unsupported_format;
attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
attrib.type = VASurfaceAttribPixelFormat;
attrib.value.type = VAGenericValueTypeInteger;
attrib.value.value.i = va_format->fourcc;
memset (&extbuf, 0, sizeof (extbuf));
extbuf.pixel_format = va_format->fourcc;
extbuf.width = GST_VIDEO_INFO_WIDTH (vip);
extbuf.height = GST_VIDEO_INFO_HEIGHT (vip);
extbuf_needed = !!(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE);
extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip);
if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) {
for (i = 0; i < extbuf.num_planes; i++)
extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i);
extbuf_needed = TRUE;
}
if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) {
for (i = 0; i < extbuf.num_planes; i++)
extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i);
extbuf_needed = TRUE;
}
attrib = attribs;
attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
attrib->type = VASurfaceAttribPixelFormat;
attrib->value.type = VAGenericValueTypeInteger;
attrib->value.value.i = va_format->fourcc;
attrib++;
if (extbuf_needed) {
attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
attrib->type = VASurfaceAttribMemoryType;
attrib->value.type = VAGenericValueTypeInteger;
attrib->value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
attrib++;
attrib->flags = VA_SURFACE_ATTRIB_SETTABLE;
attrib->type = VASurfaceAttribExternalBufferDescriptor;
attrib->value.type = VAGenericValueTypePointer;
attrib->value.value.p = &extbuf;
attrib++;
}
GST_VAAPI_DISPLAY_LOCK (display);
status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display),
va_chroma_format, width, height, &surface_id, 1, &attrib, 1);
va_chroma_format, extbuf.width, extbuf.height, &surface_id, 1,
attribs, attrib - attribs);
GST_VAAPI_DISPLAY_UNLOCK (display);
if (!vaapi_check_status (status, "vaCreateSurfaces()"))
return FALSE;
surface->format = format;
surface->chroma_type = chroma_type;
surface->width = width;
surface->height = height;
surface->width = extbuf.width;
surface->height = extbuf.height;
GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id));
GST_VAAPI_OBJECT_ID (surface) = surface_id;
@ -217,6 +255,42 @@ error:
return NULL;
}
/**
* gst_vaapi_surface_new_full:
* @display: a #GstVaapiDisplay
* @vip: the pointer to a #GstVideoInfo
* @flags: (optional) allocation flags
*
* Creates a new #GstVaapiSurface with the specified video information
* and optional #GstVaapiSurfaceAllocFlags
*
* Return value: the newly allocated #GstVaapiSurface object, or %NULL
* if creation of VA surface with explicit pixel format is not
* supported or failed.
*/
GstVaapiSurface *
gst_vaapi_surface_new_full (GstVaapiDisplay * display,
const GstVideoInfo * vip, guint flags)
{
GstVaapiSurface *surface;
GST_DEBUG ("size %ux%u, format %s, flags 0x%08x", GST_VIDEO_INFO_WIDTH (vip),
GST_VIDEO_INFO_HEIGHT (vip),
gst_vaapi_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)), flags);
surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
if (!surface)
return NULL;
if (!gst_vaapi_surface_create_full (surface, vip, flags))
goto error;
return surface;
error:
gst_vaapi_object_unref (surface);
return NULL;
}
/**
* gst_vaapi_surface_new_with_format:
* @display: a #GstVaapiDisplay
@ -235,22 +309,10 @@ GstVaapiSurface *
gst_vaapi_surface_new_with_format (GstVaapiDisplay * display,
GstVideoFormat format, guint width, guint height)
{
GstVaapiSurface *surface;
GstVideoInfo vi;
GST_DEBUG ("size %ux%u, format %s", width, height,
gst_vaapi_video_format_to_string (format));
surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
if (!surface)
return NULL;
if (!gst_vaapi_surface_create_with_format (surface, format, width, height))
goto error;
return surface;
error:
gst_vaapi_object_unref (surface);
return NULL;
gst_video_info_set_format (&vi, format, width, height);
return gst_vaapi_surface_new_full (display, &vi, 0);
}
/**

View file

@ -141,6 +141,25 @@ typedef enum
GST_VAAPI_COLOR_STANDARD_MASK = 0x0000003c, /* 4 bits */
} GstVaapiSurfaceRenderFlags;
/**
* GstVaapiSurfaceAllocFlags:
* @GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE: forces allocation
* with linear storage. Default behaviour matches native
* requirements, and thus could be tiled.
* @GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES: force allocation with
* the supplied strides information from #GstVideoInfo
* @GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS: force allocation with
* the supplied offsets information from #GstVideoInfo
*
* The set of optional allocation flags for gst_vaapi_surface_new_full().
*/
typedef enum
{
GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE = 1 << 0,
GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES = 1 << 1,
GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS = 1 << 2,
} GstVaapiSurfaceAllocFlags;
#define GST_VAAPI_SURFACE(obj) \
((GstVaapiSurface *)(obj))
@ -151,6 +170,10 @@ GstVaapiSurface *
gst_vaapi_surface_new (GstVaapiDisplay * display,
GstVaapiChromaType chroma_type, guint width, guint height);
GstVaapiSurface *
gst_vaapi_surface_new_full (GstVaapiDisplay * display,
const GstVideoInfo * vip, guint flags);
GstVaapiSurface *
gst_vaapi_surface_new_with_format (GstVaapiDisplay * display,
GstVideoFormat format, guint width, guint height);