mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-02 22:46:35 +00:00
227 lines
6.7 KiB
C
227 lines
6.7 KiB
C
/*
|
|
* gstvaapiutils_core.c - VA-API utilities (Core, MT-safe)
|
|
*
|
|
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
|
|
* Copyright (C) 2011-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 "gstvaapicompat.h"
|
|
#include "gstvaapiimage.h"
|
|
#include "gstvaapiutils.h"
|
|
#include "gstvaapiutils_core.h"
|
|
#include "gstvaapidisplay_priv.h"
|
|
|
|
#define DEBUG 1
|
|
#include "gstvaapidebug.h"
|
|
|
|
/**
|
|
* gst_vaapi_get_config_attribute:
|
|
* @display: a #GstVaapiDisplay
|
|
* @profile: a VA profile
|
|
* @entrypoint: a VA entrypoint
|
|
* @type: a VA config attribute type
|
|
* @out_value_ptr: return location for the config attribute value
|
|
*
|
|
* Determines the value for the VA config attribute @type and the
|
|
* given @profile/@entrypoint pair. If @out_value_ptr is %NULL, then
|
|
* this functions acts as a way to query whether the underlying VA
|
|
* driver supports the specified attribute @type, no matter the
|
|
* returned value.
|
|
*
|
|
* Note: this function only returns success if the VA driver does
|
|
* actually know about this config attribute type and that it returned
|
|
* a valid value for it.
|
|
*
|
|
* Return value: %TRUE if the VA driver knows about the requested
|
|
* config attribute and returned a valid value, %FALSE otherwise
|
|
*/
|
|
gboolean
|
|
gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile,
|
|
VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr)
|
|
{
|
|
VAConfigAttrib attrib;
|
|
VAStatus status;
|
|
|
|
g_return_val_if_fail (display != NULL, FALSE);
|
|
|
|
GST_VAAPI_DISPLAY_LOCK (display);
|
|
attrib.type = type;
|
|
status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
|
profile, entrypoint, &attrib, 1);
|
|
GST_VAAPI_DISPLAY_UNLOCK (display);
|
|
if (!vaapi_check_status (status, "vaGetConfigAttributes()"))
|
|
return FALSE;
|
|
if (attrib.value == VA_ATTRIB_NOT_SUPPORTED)
|
|
return FALSE;
|
|
|
|
if (out_value_ptr)
|
|
*out_value_ptr = attrib.value;
|
|
return TRUE;
|
|
}
|
|
|
|
static VASurfaceAttrib *
|
|
get_surface_attributes (GstVaapiDisplay * display, VAConfigID config,
|
|
guint * num_attribs)
|
|
{
|
|
VASurfaceAttrib *surface_attribs = NULL;
|
|
guint num_surface_attribs = 0;
|
|
VAStatus va_status;
|
|
|
|
if (config == VA_INVALID_ID)
|
|
goto error;
|
|
|
|
GST_VAAPI_DISPLAY_LOCK (display);
|
|
va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
|
config, NULL, &num_surface_attribs);
|
|
GST_VAAPI_DISPLAY_UNLOCK (display);
|
|
if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()"))
|
|
goto error;
|
|
|
|
surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs));
|
|
if (!surface_attribs)
|
|
goto error;
|
|
|
|
GST_VAAPI_DISPLAY_LOCK (display);
|
|
va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
|
config, surface_attribs, &num_surface_attribs);
|
|
GST_VAAPI_DISPLAY_UNLOCK (display);
|
|
if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()"))
|
|
goto error;
|
|
|
|
if (num_attribs)
|
|
*num_attribs = num_surface_attribs;
|
|
return surface_attribs;
|
|
|
|
/* ERRORS */
|
|
error:
|
|
{
|
|
if (num_attribs)
|
|
*num_attribs = -1;
|
|
if (surface_attribs)
|
|
g_free (surface_attribs);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gst_vaapi_config_surface_attribures_get:
|
|
* @display: a #GstVaapiDisplay
|
|
* @config: a #VAConfigID
|
|
*
|
|
* Retrieves the possible surface attributes for the supplied config.
|
|
*
|
|
* Returns: (transfer full): returns a #GstVaapiConfigSurfaceAttributes
|
|
**/
|
|
GstVaapiConfigSurfaceAttributes *
|
|
gst_vaapi_config_surface_attributes_get (GstVaapiDisplay * display,
|
|
VAConfigID config)
|
|
{
|
|
VASurfaceAttrib *surface_attribs;
|
|
guint i, num_pixel_formats = 0, num_surface_attribs = 0;
|
|
GstVaapiConfigSurfaceAttributes *attribs = NULL;
|
|
|
|
surface_attribs =
|
|
get_surface_attributes (display, config, &num_surface_attribs);
|
|
if (!surface_attribs)
|
|
return NULL;
|
|
|
|
attribs = g_slice_new0 (GstVaapiConfigSurfaceAttributes);
|
|
if (!attribs)
|
|
goto error;
|
|
|
|
for (i = 0; i < num_surface_attribs; i++) {
|
|
const VASurfaceAttrib *const attrib = &surface_attribs[i];
|
|
|
|
switch (attrib->type) {
|
|
case VASurfaceAttribPixelFormat:
|
|
if ((attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) {
|
|
GstVideoFormat fmt;
|
|
|
|
fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i);
|
|
if (fmt != GST_VIDEO_FORMAT_UNKNOWN)
|
|
num_pixel_formats++;
|
|
}
|
|
break;
|
|
case VASurfaceAttribMinWidth:
|
|
attribs->min_width = attrib->value.value.i;
|
|
break;
|
|
case VASurfaceAttribMinHeight:
|
|
attribs->min_height = attrib->value.value.i;
|
|
break;
|
|
case VASurfaceAttribMaxWidth:
|
|
attribs->max_width = attrib->value.value.i;
|
|
break;
|
|
case VASurfaceAttribMaxHeight:
|
|
attribs->max_height = attrib->value.value.i;
|
|
break;
|
|
case VASurfaceAttribMemoryType:
|
|
attribs->mem_types = attrib->value.value.i;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (num_pixel_formats == 0) {
|
|
attribs->formats = NULL;
|
|
} else {
|
|
attribs->formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat),
|
|
num_pixel_formats);
|
|
|
|
for (i = 0; i < num_surface_attribs; i++) {
|
|
const VASurfaceAttrib *const attrib = &surface_attribs[i];
|
|
GstVideoFormat fmt;
|
|
|
|
if (attrib->type != VASurfaceAttribPixelFormat)
|
|
continue;
|
|
if (!(attrib->flags & VA_SURFACE_ATTRIB_SETTABLE))
|
|
continue;
|
|
|
|
fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i);
|
|
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
|
continue;
|
|
g_array_append_val (attribs->formats, fmt);
|
|
}
|
|
}
|
|
|
|
g_free (surface_attribs);
|
|
return attribs;
|
|
|
|
/* ERRORS */
|
|
error:
|
|
{
|
|
g_free (surface_attribs);
|
|
gst_vaapi_config_surface_attributes_free (attribs);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
gst_vaapi_config_surface_attributes_free (GstVaapiConfigSurfaceAttributes *
|
|
attribs)
|
|
{
|
|
if (!attribs)
|
|
return;
|
|
|
|
if (attribs->formats)
|
|
g_array_unref (attribs->formats);
|
|
g_slice_free (GstVaapiConfigSurfaceAttributes, attribs);
|
|
}
|