1 /*
2  *  gstvaapiutils_core.c - VA-API utilities (Core, MT-safe)
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2011-2014 Intel Corporation
7  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free
21  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301 USA
23  */
24 
25 #include "sysdeps.h"
26 #include "gstvaapicompat.h"
27 #include "gstvaapiimage.h"
28 #include "gstvaapiutils.h"
29 #include "gstvaapiutils_core.h"
30 #include "gstvaapidisplay_priv.h"
31 
32 #define DEBUG 1
33 #include "gstvaapidebug.h"
34 
35 /**
36  * gst_vaapi_get_config_attribute:
37  * @display: a #GstVaapiDisplay
38  * @profile: a VA profile
39  * @entrypoint: a VA entrypoint
40  * @type: a VA config attribute type
41  * @out_value_ptr: return location for the config attribute value
42  *
43  * Determines the value for the VA config attribute @type and the
44  * given @profile/@entrypoint pair. If @out_value_ptr is %NULL, then
45  * this functions acts as a way to query whether the underlying VA
46  * driver supports the specified attribute @type, no matter the
47  * returned value.
48  *
49  * Note: this function only returns success if the VA driver does
50  * actually know about this config attribute type and that it returned
51  * a valid value for it.
52  *
53  * Return value: %TRUE if the VA driver knows about the requested
54  *   config attribute and returned a valid value, %FALSE otherwise
55  */
56 gboolean
gst_vaapi_get_config_attribute(GstVaapiDisplay * display,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttribType type,guint * out_value_ptr)57 gst_vaapi_get_config_attribute (GstVaapiDisplay * display, VAProfile profile,
58     VAEntrypoint entrypoint, VAConfigAttribType type, guint * out_value_ptr)
59 {
60   VAConfigAttrib attrib;
61   VAStatus status;
62 
63   g_return_val_if_fail (display != NULL, FALSE);
64 
65   GST_VAAPI_DISPLAY_LOCK (display);
66   attrib.type = type;
67   status = vaGetConfigAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
68       profile, entrypoint, &attrib, 1);
69   GST_VAAPI_DISPLAY_UNLOCK (display);
70   if (!vaapi_check_status (status, "vaGetConfigAttributes()"))
71     return FALSE;
72   if (attrib.value == VA_ATTRIB_NOT_SUPPORTED)
73     return FALSE;
74 
75   if (out_value_ptr)
76     *out_value_ptr = attrib.value;
77   return TRUE;
78 }
79 
80 /**
81  * gst_vaapi_get_surface_formats:
82  * @display: a #GstVaapiDisplay
83  * @config: a #VAConfigID
84  *
85  * Gets surface formats for the supplied config.
86  *
87  * This function will query for all the supported formats for the
88  * supplied VA @config.
89  *
90  * Return value: (transfer full): a #GArray of #GstVideoFormats or %NULL
91  */
92 GArray *
gst_vaapi_get_surface_formats(GstVaapiDisplay * display,VAConfigID config)93 gst_vaapi_get_surface_formats (GstVaapiDisplay * display, VAConfigID config)
94 {
95   VASurfaceAttrib *surface_attribs = NULL;
96   guint i, num_surface_attribs = 0;
97   VAStatus va_status;
98   GArray *formats;
99 
100   if (config == VA_INVALID_ID)
101     return NULL;
102 
103   GST_VAAPI_DISPLAY_LOCK (display);
104   va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
105       config, NULL, &num_surface_attribs);
106   GST_VAAPI_DISPLAY_UNLOCK (display);
107   if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()"))
108     return NULL;
109 
110   surface_attribs = g_malloc (num_surface_attribs * sizeof (*surface_attribs));
111   if (!surface_attribs)
112     return NULL;
113 
114   GST_VAAPI_DISPLAY_LOCK (display);
115   va_status = vaQuerySurfaceAttributes (GST_VAAPI_DISPLAY_VADISPLAY (display),
116       config, surface_attribs, &num_surface_attribs);
117   GST_VAAPI_DISPLAY_UNLOCK (display);
118   if (!vaapi_check_status (va_status, "vaQuerySurfaceAttributes()"))
119     return NULL;
120 
121   formats = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat),
122       num_surface_attribs);
123   if (!formats)
124     goto error;
125 
126   for (i = 0; i < num_surface_attribs; i++) {
127     const VASurfaceAttrib *const attrib = &surface_attribs[i];
128     GstVideoFormat fmt;
129 
130     if (attrib->type != VASurfaceAttribPixelFormat)
131       continue;
132     if (!(attrib->flags & VA_SURFACE_ATTRIB_SETTABLE))
133       continue;
134 
135     fmt = gst_vaapi_video_format_from_va_fourcc (attrib->value.value.i);
136     if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
137       continue;
138     g_array_append_val (formats, fmt);
139   }
140 
141   if (formats->len == 0) {
142     g_array_unref (formats);
143     formats = NULL;
144   }
145 
146   g_free (surface_attribs);
147   return formats;
148 
149   /* ERRORS */
150 error:
151   {
152     g_free (surface_attribs);
153   }
154   return NULL;
155 }
156