• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4  * Copyright 2014 Advanced Micro Devices, Inc.
5  * All Rights Reserved.
6  *
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:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  *
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.
26  *
27  **************************************************************************/
28 
29 #include "pipe/p_screen.h"
30 
31 #include "util/u_video.h"
32 #include "util/u_memory.h"
33 
34 #include "vl/vl_winsys.h"
35 
36 #include "va_private.h"
37 
38 #include "util/u_handle_table.h"
39 
40 DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false)
41 
42 VAStatus
vlVaQueryConfigProfiles(VADriverContextP ctx,VAProfile * profile_list,int * num_profiles)43 vlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles)
44 {
45    struct pipe_screen *pscreen;
46    enum pipe_video_profile p;
47    VAProfile vap;
48 
49    if (!ctx)
50       return VA_STATUS_ERROR_INVALID_CONTEXT;
51 
52    *num_profiles = 0;
53 
54    pscreen = VL_VA_PSCREEN(ctx);
55    for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_JPEG_BASELINE; ++p) {
56       if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4())
57          continue;
58 
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;
63       }
64    }
65 
66    /* Support postprocessing through vl_compositor */
67    profile_list[(*num_profiles)++] = VAProfileNone;
68 
69    return VA_STATUS_SUCCESS;
70 }
71 
72 VAStatus
vlVaQueryConfigEntrypoints(VADriverContextP ctx,VAProfile profile,VAEntrypoint * entrypoint_list,int * num_entrypoints)73 vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile,
74                            VAEntrypoint *entrypoint_list, int *num_entrypoints)
75 {
76    struct pipe_screen *pscreen;
77    enum pipe_video_profile p;
78 
79    if (!ctx)
80       return VA_STATUS_ERROR_INVALID_CONTEXT;
81 
82    *num_entrypoints = 0;
83 
84    if (profile == VAProfileNone) {
85       entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc;
86       return VA_STATUS_SUCCESS;
87    }
88 
89    p = ProfileToPipe(profile);
90    if (p == PIPE_VIDEO_PROFILE_UNKNOWN)
91       return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
92 
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;
97 
98    if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
99 				PIPE_VIDEO_CAP_SUPPORTED))
100       entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice;
101 
102    if (num_entrypoints == 0)
103       return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
104 
105    assert(*num_entrypoints <= ctx->max_entrypoints);
106 
107    return VA_STATUS_SUCCESS;
108 }
109 
110 VAStatus
vlVaGetConfigAttributes(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)111 vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
112                         VAConfigAttrib *attrib_list, int num_attribs)
113 {
114    struct pipe_screen *pscreen;
115    int i;
116 
117    if (!ctx)
118       return VA_STATUS_ERROR_INVALID_CONTEXT;
119 
120    pscreen = VL_VA_PSCREEN(ctx);
121 
122    for (i = 0; i < num_attribs; ++i) {
123       unsigned int value;
124       if (entrypoint == VAEntrypointVLD) {
125          switch (attrib_list[i].type) {
126          case VAConfigAttribRTFormat:
127             value = VA_RT_FORMAT_YUV420;
128 	    if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016,
129                                                    ProfileToPipe(profile),
130                                                    PIPE_VIDEO_ENTRYPOINT_BITSTREAM))
131 		value |= VA_RT_FORMAT_YUV420_10BPP;
132             break;
133          default:
134             value = VA_ATTRIB_NOT_SUPPORTED;
135             break;
136          }
137       } else if (entrypoint == VAEntrypointEncSlice) {
138          switch (attrib_list[i].type) {
139          case VAConfigAttribRTFormat:
140             value = VA_RT_FORMAT_YUV420;
141             break;
142          case VAConfigAttribRateControl:
143             value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR;
144             break;
145          case VAConfigAttribEncPackedHeaders:
146             value = 0;
147             break;
148          case VAConfigAttribEncMaxRefFrames:
149             value = 1;
150             break;
151          default:
152             value = VA_ATTRIB_NOT_SUPPORTED;
153             break;
154          }
155       } else if (entrypoint == VAEntrypointVideoProc) {
156          switch (attrib_list[i].type) {
157          case VAConfigAttribRTFormat:
158             value = (VA_RT_FORMAT_YUV420 |
159                      VA_RT_FORMAT_YUV420_10BPP |
160                      VA_RT_FORMAT_RGB32);
161             break;
162          default:
163             value = VA_ATTRIB_NOT_SUPPORTED;
164             break;
165          }
166       } else {
167          value = VA_ATTRIB_NOT_SUPPORTED;
168       }
169       attrib_list[i].value = value;
170    }
171 
172    return VA_STATUS_SUCCESS;
173 }
174 
175 VAStatus
vlVaCreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)176 vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
177                  VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id)
178 {
179    vlVaDriver *drv;
180    vlVaConfig *config;
181    struct pipe_screen *pscreen;
182    enum pipe_video_profile p;
183    unsigned int supported_rt_formats;
184 
185    if (!ctx)
186       return VA_STATUS_ERROR_INVALID_CONTEXT;
187 
188    drv = VL_VA_DRIVER(ctx);
189 
190    if (!drv)
191       return VA_STATUS_ERROR_INVALID_CONTEXT;
192 
193    config = CALLOC(1, sizeof(vlVaConfig));
194    if (!config)
195       return VA_STATUS_ERROR_ALLOCATION_FAILED;
196 
197    if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) {
198       config->entrypoint = PIPE_VIDEO_ENTRYPOINT_UNKNOWN;
199       config->profile = PIPE_VIDEO_PROFILE_UNKNOWN;
200       supported_rt_formats = VA_RT_FORMAT_YUV420 |
201                              VA_RT_FORMAT_YUV420_10BPP |
202                              VA_RT_FORMAT_RGB32;
203       for (int i = 0; i < num_attribs; i++) {
204          if (attrib_list[i].type == VAConfigAttribRTFormat) {
205             if (attrib_list[i].value & supported_rt_formats) {
206                config->rt_format = attrib_list[i].value;
207             } else {
208                FREE(config);
209                return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
210             }
211          }
212       }
213 
214       /* Default value if not specified in the input attributes. */
215       if (!config->rt_format)
216          config->rt_format = supported_rt_formats;
217 
218       mtx_lock(&drv->mutex);
219       *config_id = handle_table_add(drv->htab, config);
220       mtx_unlock(&drv->mutex);
221       return VA_STATUS_SUCCESS;
222    }
223 
224    p = ProfileToPipe(profile);
225    if (p == PIPE_VIDEO_PROFILE_UNKNOWN) {
226       FREE(config);
227       return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
228    }
229 
230    pscreen = VL_VA_PSCREEN(ctx);
231 
232    switch (entrypoint) {
233    case VAEntrypointVLD:
234       if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
235 				    PIPE_VIDEO_CAP_SUPPORTED)) {
236          FREE(config);
237          return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
238       }
239 
240       config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
241       break;
242 
243    case VAEntrypointEncSlice:
244       if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE,
245 				    PIPE_VIDEO_CAP_SUPPORTED)) {
246          FREE(config);
247          return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
248       }
249 
250       config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE;
251       break;
252 
253    default:
254       FREE(config);
255       return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
256    }
257 
258    config->profile = p;
259    supported_rt_formats = VA_RT_FORMAT_YUV420;
260    if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, p,
261 					  config->entrypoint))
262       supported_rt_formats |= VA_RT_FORMAT_YUV420_10BPP;
263 
264    for (int i = 0; i <num_attribs ; i++) {
265       if (attrib_list[i].type == VAConfigAttribRateControl) {
266          if (attrib_list[i].value == VA_RC_CBR)
267             config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT;
268          else if (attrib_list[i].value == VA_RC_VBR)
269             config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE;
270          else
271             config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE;
272       }
273       if (attrib_list[i].type == VAConfigAttribRTFormat) {
274          if (attrib_list[i].value & supported_rt_formats) {
275             config->rt_format = attrib_list[i].value;
276          } else {
277             FREE(config);
278             return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
279          }
280       }
281    }
282 
283    /* Default value if not specified in the input attributes. */
284    if (!config->rt_format)
285       config->rt_format = supported_rt_formats;
286 
287    mtx_lock(&drv->mutex);
288    *config_id = handle_table_add(drv->htab, config);
289    mtx_unlock(&drv->mutex);
290 
291    return VA_STATUS_SUCCESS;
292 }
293 
294 VAStatus
vlVaDestroyConfig(VADriverContextP ctx,VAConfigID config_id)295 vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id)
296 {
297    vlVaDriver *drv;
298    vlVaConfig *config;
299 
300    if (!ctx)
301       return VA_STATUS_ERROR_INVALID_CONTEXT;
302 
303    drv = VL_VA_DRIVER(ctx);
304 
305    if (!drv)
306       return VA_STATUS_ERROR_INVALID_CONTEXT;
307 
308    mtx_lock(&drv->mutex);
309    config = handle_table_get(drv->htab, config_id);
310 
311    if (!config) {
312       mtx_unlock(&drv->mutex);
313       return VA_STATUS_ERROR_INVALID_CONFIG;
314    }
315 
316    FREE(config);
317    handle_table_remove(drv->htab, config_id);
318    mtx_unlock(&drv->mutex);
319 
320    return VA_STATUS_SUCCESS;
321 }
322 
323 VAStatus
vlVaQueryConfigAttributes(VADriverContextP ctx,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)324 vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile,
325                           VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs)
326 {
327    vlVaDriver *drv;
328    vlVaConfig *config;
329 
330    if (!ctx)
331       return VA_STATUS_ERROR_INVALID_CONTEXT;
332 
333    drv = VL_VA_DRIVER(ctx);
334 
335    if (!drv)
336       return VA_STATUS_ERROR_INVALID_CONTEXT;
337 
338    mtx_lock(&drv->mutex);
339    config = handle_table_get(drv->htab, config_id);
340    mtx_unlock(&drv->mutex);
341 
342    if (!config)
343       return VA_STATUS_ERROR_INVALID_CONFIG;
344 
345    *profile = PipeToProfile(config->profile);
346 
347    switch (config->entrypoint) {
348    case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
349       *entrypoint = VAEntrypointVLD;
350       break;
351    case PIPE_VIDEO_ENTRYPOINT_ENCODE:
352       *entrypoint = VAEntrypointEncSlice;
353       break;
354    case PIPE_VIDEO_ENTRYPOINT_UNKNOWN:
355       *entrypoint = VAEntrypointVideoProc;
356       break;
357    default:
358       return VA_STATUS_ERROR_INVALID_CONFIG;
359    }
360 
361    *num_attribs = 1;
362    attrib_list[0].type = VAConfigAttribRTFormat;
363    attrib_list[0].value = config->rt_format;
364 
365    return VA_STATUS_SUCCESS;
366 }
367