1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4 * Copyright 2014 Advanced Micro Devices, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #include "pipe/p_screen.h"
31 #include "util/u_video.h"
32 #include "util/u_memory.h"
34 #include "vl/vl_winsys.h"
36 #include "va_private.h"
38 #include "util/u_handle_table.h"
40 DEBUG_GET_ONCE_BOOL_OPTION(mpeg4
, "VAAPI_MPEG4_ENABLED", false)
43 vlVaQueryConfigProfiles(VADriverContextP ctx
, VAProfile
*profile_list
, int *num_profiles
)
45 struct pipe_screen
*pscreen
;
46 enum pipe_video_profile p
;
50 return VA_STATUS_ERROR_INVALID_CONTEXT
;
54 pscreen
= VL_VA_PSCREEN(ctx
);
55 for (p
= PIPE_VIDEO_PROFILE_MPEG2_SIMPLE
; p
<= PIPE_VIDEO_PROFILE_VP9_PROFILE2
; ++p
) {
56 if (u_reduce_video_profile(p
) == PIPE_VIDEO_FORMAT_MPEG4
&& !debug_get_option_mpeg4())
59 if (pscreen
->get_video_param(pscreen
, p
, PIPE_VIDEO_ENTRYPOINT_BITSTREAM
, PIPE_VIDEO_CAP_SUPPORTED
)) {
60 vap
= PipeToProfile(p
);
61 if (vap
!= VAProfileNone
)
62 profile_list
[(*num_profiles
)++] = vap
;
66 /* Support postprocessing through vl_compositor */
67 profile_list
[(*num_profiles
)++] = VAProfileNone
;
69 return VA_STATUS_SUCCESS
;
73 vlVaQueryConfigEntrypoints(VADriverContextP ctx
, VAProfile profile
,
74 VAEntrypoint
*entrypoint_list
, int *num_entrypoints
)
76 struct pipe_screen
*pscreen
;
77 enum pipe_video_profile p
;
80 return VA_STATUS_ERROR_INVALID_CONTEXT
;
84 if (profile
== VAProfileNone
) {
85 entrypoint_list
[(*num_entrypoints
)++] = VAEntrypointVideoProc
;
86 return VA_STATUS_SUCCESS
;
89 p
= ProfileToPipe(profile
);
90 if (p
== PIPE_VIDEO_PROFILE_UNKNOWN
)
91 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
;
93 pscreen
= VL_VA_PSCREEN(ctx
);
94 if (pscreen
->get_video_param(pscreen
, p
, PIPE_VIDEO_ENTRYPOINT_BITSTREAM
,
95 PIPE_VIDEO_CAP_SUPPORTED
))
96 entrypoint_list
[(*num_entrypoints
)++] = VAEntrypointVLD
;
98 if (pscreen
->get_video_param(pscreen
, p
, PIPE_VIDEO_ENTRYPOINT_ENCODE
,
99 PIPE_VIDEO_CAP_SUPPORTED
))
100 entrypoint_list
[(*num_entrypoints
)++] = VAEntrypointEncSlice
;
102 if (num_entrypoints
== 0)
103 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
;
105 assert(*num_entrypoints
<= ctx
->max_entrypoints
);
107 return VA_STATUS_SUCCESS
;
111 vlVaGetConfigAttributes(VADriverContextP ctx
, VAProfile profile
, VAEntrypoint entrypoint
,
112 VAConfigAttrib
*attrib_list
, int num_attribs
)
114 struct pipe_screen
*pscreen
;
118 return VA_STATUS_ERROR_INVALID_CONTEXT
;
120 pscreen
= VL_VA_PSCREEN(ctx
);
122 for (i
= 0; i
< num_attribs
; ++i
) {
124 if ((entrypoint
== VAEntrypointVLD
) &&
125 (pscreen
->get_video_param(pscreen
, ProfileToPipe(profile
),
126 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
, PIPE_VIDEO_CAP_SUPPORTED
))) {
127 switch (attrib_list
[i
].type
) {
128 case VAConfigAttribRTFormat
:
129 value
= VA_RT_FORMAT_YUV420
| VA_RT_FORMAT_YUV422
;
130 if (pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P010
,
131 ProfileToPipe(profile
),
132 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) ||
133 pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P016
,
134 ProfileToPipe(profile
),
135 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
))
136 value
|= VA_RT_FORMAT_YUV420_10BPP
;
139 value
= VA_ATTRIB_NOT_SUPPORTED
;
142 } else if ((entrypoint
== VAEntrypointEncSlice
) &&
143 (pscreen
->get_video_param(pscreen
, ProfileToPipe(profile
),
144 PIPE_VIDEO_ENTRYPOINT_ENCODE
, PIPE_VIDEO_CAP_SUPPORTED
))) {
145 switch (attrib_list
[i
].type
) {
146 case VAConfigAttribRTFormat
:
147 value
= VA_RT_FORMAT_YUV420
;
148 if (pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P010
,
149 ProfileToPipe(profile
),
150 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) ||
151 pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P016
,
152 ProfileToPipe(profile
),
153 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
))
154 value
|= VA_RT_FORMAT_YUV420_10BPP
;
156 case VAConfigAttribRateControl
:
157 value
= VA_RC_CQP
| VA_RC_CBR
| VA_RC_VBR
;
159 case VAConfigAttribEncPackedHeaders
:
162 case VAConfigAttribEncMaxRefFrames
:
166 value
= VA_ATTRIB_NOT_SUPPORTED
;
169 } else if (entrypoint
== VAEntrypointVideoProc
) {
170 switch (attrib_list
[i
].type
) {
171 case VAConfigAttribRTFormat
:
172 value
= (VA_RT_FORMAT_YUV420
|
173 VA_RT_FORMAT_YUV420_10BPP
|
177 value
= VA_ATTRIB_NOT_SUPPORTED
;
181 value
= VA_ATTRIB_NOT_SUPPORTED
;
183 attrib_list
[i
].value
= value
;
186 return VA_STATUS_SUCCESS
;
190 vlVaCreateConfig(VADriverContextP ctx
, VAProfile profile
, VAEntrypoint entrypoint
,
191 VAConfigAttrib
*attrib_list
, int num_attribs
, VAConfigID
*config_id
)
195 struct pipe_screen
*pscreen
;
196 enum pipe_video_profile p
;
197 unsigned int supported_rt_formats
;
200 return VA_STATUS_ERROR_INVALID_CONTEXT
;
202 drv
= VL_VA_DRIVER(ctx
);
205 return VA_STATUS_ERROR_INVALID_CONTEXT
;
207 config
= CALLOC(1, sizeof(vlVaConfig
));
209 return VA_STATUS_ERROR_ALLOCATION_FAILED
;
211 if (profile
== VAProfileNone
&& entrypoint
== VAEntrypointVideoProc
) {
212 config
->entrypoint
= PIPE_VIDEO_ENTRYPOINT_UNKNOWN
;
213 config
->profile
= PIPE_VIDEO_PROFILE_UNKNOWN
;
214 supported_rt_formats
= VA_RT_FORMAT_YUV420
|
215 VA_RT_FORMAT_YUV420_10BPP
|
217 for (int i
= 0; i
< num_attribs
; i
++) {
218 if (attrib_list
[i
].type
== VAConfigAttribRTFormat
) {
219 if (attrib_list
[i
].value
& supported_rt_formats
) {
220 config
->rt_format
= attrib_list
[i
].value
;
223 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT
;
228 /* Default value if not specified in the input attributes. */
229 if (!config
->rt_format
)
230 config
->rt_format
= supported_rt_formats
;
232 mtx_lock(&drv
->mutex
);
233 *config_id
= handle_table_add(drv
->htab
, config
);
234 mtx_unlock(&drv
->mutex
);
235 return VA_STATUS_SUCCESS
;
238 p
= ProfileToPipe(profile
);
239 if (p
== PIPE_VIDEO_PROFILE_UNKNOWN
) {
241 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
;
244 pscreen
= VL_VA_PSCREEN(ctx
);
246 switch (entrypoint
) {
247 case VAEntrypointVLD
:
248 if (!pscreen
->get_video_param(pscreen
, p
, PIPE_VIDEO_ENTRYPOINT_BITSTREAM
,
249 PIPE_VIDEO_CAP_SUPPORTED
)) {
251 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
;
254 config
->entrypoint
= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
;
257 case VAEntrypointEncSlice
:
258 if (!pscreen
->get_video_param(pscreen
, p
, PIPE_VIDEO_ENTRYPOINT_ENCODE
,
259 PIPE_VIDEO_CAP_SUPPORTED
)) {
261 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
;
264 config
->entrypoint
= PIPE_VIDEO_ENTRYPOINT_ENCODE
;
269 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT
;
273 supported_rt_formats
= VA_RT_FORMAT_YUV420
| VA_RT_FORMAT_YUV422
;
274 if (pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P010
, p
,
275 config
->entrypoint
) ||
276 pscreen
->is_video_format_supported(pscreen
, PIPE_FORMAT_P016
, p
,
278 supported_rt_formats
|= VA_RT_FORMAT_YUV420_10BPP
;
280 for (int i
= 0; i
<num_attribs
; i
++) {
281 if (attrib_list
[i
].type
== VAConfigAttribRateControl
) {
282 if (attrib_list
[i
].value
== VA_RC_CBR
)
283 config
->rc
= PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT
;
284 else if (attrib_list
[i
].value
== VA_RC_VBR
)
285 config
->rc
= PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE
;
287 config
->rc
= PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE
;
289 if (attrib_list
[i
].type
== VAConfigAttribRTFormat
) {
290 if (attrib_list
[i
].value
& supported_rt_formats
) {
291 config
->rt_format
= attrib_list
[i
].value
;
294 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT
;
299 /* Default value if not specified in the input attributes. */
300 if (!config
->rt_format
)
301 config
->rt_format
= supported_rt_formats
;
303 mtx_lock(&drv
->mutex
);
304 *config_id
= handle_table_add(drv
->htab
, config
);
305 mtx_unlock(&drv
->mutex
);
307 return VA_STATUS_SUCCESS
;
311 vlVaDestroyConfig(VADriverContextP ctx
, VAConfigID config_id
)
317 return VA_STATUS_ERROR_INVALID_CONTEXT
;
319 drv
= VL_VA_DRIVER(ctx
);
322 return VA_STATUS_ERROR_INVALID_CONTEXT
;
324 mtx_lock(&drv
->mutex
);
325 config
= handle_table_get(drv
->htab
, config_id
);
328 mtx_unlock(&drv
->mutex
);
329 return VA_STATUS_ERROR_INVALID_CONFIG
;
333 handle_table_remove(drv
->htab
, config_id
);
334 mtx_unlock(&drv
->mutex
);
336 return VA_STATUS_SUCCESS
;
340 vlVaQueryConfigAttributes(VADriverContextP ctx
, VAConfigID config_id
, VAProfile
*profile
,
341 VAEntrypoint
*entrypoint
, VAConfigAttrib
*attrib_list
, int *num_attribs
)
347 return VA_STATUS_ERROR_INVALID_CONTEXT
;
349 drv
= VL_VA_DRIVER(ctx
);
352 return VA_STATUS_ERROR_INVALID_CONTEXT
;
354 mtx_lock(&drv
->mutex
);
355 config
= handle_table_get(drv
->htab
, config_id
);
356 mtx_unlock(&drv
->mutex
);
359 return VA_STATUS_ERROR_INVALID_CONFIG
;
361 *profile
= PipeToProfile(config
->profile
);
363 switch (config
->entrypoint
) {
364 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
:
365 *entrypoint
= VAEntrypointVLD
;
367 case PIPE_VIDEO_ENTRYPOINT_ENCODE
:
368 *entrypoint
= VAEntrypointEncSlice
;
370 case PIPE_VIDEO_ENTRYPOINT_UNKNOWN
:
371 *entrypoint
= VAEntrypointVideoProc
;
374 return VA_STATUS_ERROR_INVALID_CONFIG
;
378 attrib_list
[0].type
= VAConfigAttribRTFormat
;
379 attrib_list
[0].value
= config
->rt_format
;
381 return VA_STATUS_SUCCESS
;