1b8e80941Smrg/************************************************************************** 2b8e80941Smrg * 3b8e80941Smrg * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian. 4b8e80941Smrg * Copyright 2014 Advanced Micro Devices, Inc. 5b8e80941Smrg * All Rights Reserved. 6b8e80941Smrg * 7b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8b8e80941Smrg * copy of this software and associated documentation files (the 9b8e80941Smrg * "Software"), to deal in the Software without restriction, including 10b8e80941Smrg * without limitation the rights to use, copy, modify, merge, publish, 11b8e80941Smrg * distribute, sub license, and/or sell copies of the Software, and to 12b8e80941Smrg * permit persons to whom the Software is furnished to do so, subject to 13b8e80941Smrg * the following conditions: 14b8e80941Smrg * 15b8e80941Smrg * The above copyright notice and this permission notice (including the 16b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions 17b8e80941Smrg * of the Software. 18b8e80941Smrg * 19b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21b8e80941Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22b8e80941Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 23b8e80941Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24b8e80941Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25b8e80941Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26b8e80941Smrg * 27b8e80941Smrg **************************************************************************/ 28b8e80941Smrg 29b8e80941Smrg#include "pipe/p_screen.h" 30b8e80941Smrg 31b8e80941Smrg#include "util/u_video.h" 32b8e80941Smrg#include "util/u_memory.h" 33b8e80941Smrg 34b8e80941Smrg#include "vl/vl_winsys.h" 35b8e80941Smrg 36b8e80941Smrg#include "va_private.h" 37b8e80941Smrg 38b8e80941Smrg#include "util/u_handle_table.h" 39b8e80941Smrg 40b8e80941SmrgDEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) 41b8e80941Smrg 42b8e80941SmrgVAStatus 43b8e80941SmrgvlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles) 44b8e80941Smrg{ 45b8e80941Smrg struct pipe_screen *pscreen; 46b8e80941Smrg enum pipe_video_profile p; 47b8e80941Smrg VAProfile vap; 48b8e80941Smrg 49b8e80941Smrg if (!ctx) 50b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 51b8e80941Smrg 52b8e80941Smrg *num_profiles = 0; 53b8e80941Smrg 54b8e80941Smrg pscreen = VL_VA_PSCREEN(ctx); 55b8e80941Smrg for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_VP9_PROFILE2; ++p) { 56b8e80941Smrg if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4()) 57b8e80941Smrg continue; 58b8e80941Smrg 59b8e80941Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { 60b8e80941Smrg vap = PipeToProfile(p); 61b8e80941Smrg if (vap != VAProfileNone) 62b8e80941Smrg profile_list[(*num_profiles)++] = vap; 63b8e80941Smrg } 64b8e80941Smrg } 65b8e80941Smrg 66b8e80941Smrg /* Support postprocessing through vl_compositor */ 67b8e80941Smrg profile_list[(*num_profiles)++] = VAProfileNone; 68b8e80941Smrg 69b8e80941Smrg return VA_STATUS_SUCCESS; 70b8e80941Smrg} 71b8e80941Smrg 72b8e80941SmrgVAStatus 73b8e80941SmrgvlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, 74b8e80941Smrg VAEntrypoint *entrypoint_list, int *num_entrypoints) 75b8e80941Smrg{ 76b8e80941Smrg struct pipe_screen *pscreen; 77b8e80941Smrg enum pipe_video_profile p; 78b8e80941Smrg 79b8e80941Smrg if (!ctx) 80b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 81b8e80941Smrg 82b8e80941Smrg *num_entrypoints = 0; 83b8e80941Smrg 84b8e80941Smrg if (profile == VAProfileNone) { 85b8e80941Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc; 86b8e80941Smrg return VA_STATUS_SUCCESS; 87b8e80941Smrg } 88b8e80941Smrg 89b8e80941Smrg p = ProfileToPipe(profile); 90b8e80941Smrg if (p == PIPE_VIDEO_PROFILE_UNKNOWN) 91b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 92b8e80941Smrg 93b8e80941Smrg pscreen = VL_VA_PSCREEN(ctx); 94b8e80941Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, 95b8e80941Smrg PIPE_VIDEO_CAP_SUPPORTED)) 96b8e80941Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; 97b8e80941Smrg 98b8e80941Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, 99b8e80941Smrg PIPE_VIDEO_CAP_SUPPORTED)) 100b8e80941Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; 101b8e80941Smrg 102b8e80941Smrg if (num_entrypoints == 0) 103b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 104b8e80941Smrg 105b8e80941Smrg assert(*num_entrypoints <= ctx->max_entrypoints); 106b8e80941Smrg 107b8e80941Smrg return VA_STATUS_SUCCESS; 108b8e80941Smrg} 109b8e80941Smrg 110b8e80941SmrgVAStatus 111b8e80941SmrgvlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, 112b8e80941Smrg VAConfigAttrib *attrib_list, int num_attribs) 113b8e80941Smrg{ 114b8e80941Smrg struct pipe_screen *pscreen; 115b8e80941Smrg int i; 116b8e80941Smrg 117b8e80941Smrg if (!ctx) 118b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 119b8e80941Smrg 120b8e80941Smrg pscreen = VL_VA_PSCREEN(ctx); 121b8e80941Smrg 122b8e80941Smrg for (i = 0; i < num_attribs; ++i) { 123b8e80941Smrg unsigned int value; 124b8e80941Smrg if (entrypoint == VAEntrypointVLD) { 125b8e80941Smrg switch (attrib_list[i].type) { 126b8e80941Smrg case VAConfigAttribRTFormat: 127b8e80941Smrg value = VA_RT_FORMAT_YUV420; 128b8e80941Smrg if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, 129b8e80941Smrg ProfileToPipe(profile), 130b8e80941Smrg PIPE_VIDEO_ENTRYPOINT_BITSTREAM)) 131b8e80941Smrg value |= VA_RT_FORMAT_YUV420_10BPP; 132b8e80941Smrg break; 133b8e80941Smrg default: 134b8e80941Smrg value = VA_ATTRIB_NOT_SUPPORTED; 135b8e80941Smrg break; 136b8e80941Smrg } 137b8e80941Smrg } else if (entrypoint == VAEntrypointEncSlice) { 138b8e80941Smrg switch (attrib_list[i].type) { 139b8e80941Smrg case VAConfigAttribRTFormat: 140b8e80941Smrg value = VA_RT_FORMAT_YUV420; 141b8e80941Smrg break; 142b8e80941Smrg case VAConfigAttribRateControl: 143b8e80941Smrg value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR; 144b8e80941Smrg break; 145b8e80941Smrg case VAConfigAttribEncPackedHeaders: 146b8e80941Smrg value = 0; 147b8e80941Smrg break; 148b8e80941Smrg case VAConfigAttribEncMaxRefFrames: 149b8e80941Smrg value = 1; 150b8e80941Smrg break; 151b8e80941Smrg default: 152b8e80941Smrg value = VA_ATTRIB_NOT_SUPPORTED; 153b8e80941Smrg break; 154b8e80941Smrg } 155b8e80941Smrg } else if (entrypoint == VAEntrypointVideoProc) { 156b8e80941Smrg switch (attrib_list[i].type) { 157b8e80941Smrg case VAConfigAttribRTFormat: 158b8e80941Smrg value = (VA_RT_FORMAT_YUV420 | 159b8e80941Smrg VA_RT_FORMAT_YUV420_10BPP | 160b8e80941Smrg VA_RT_FORMAT_RGB32); 161b8e80941Smrg break; 162b8e80941Smrg default: 163b8e80941Smrg value = VA_ATTRIB_NOT_SUPPORTED; 164b8e80941Smrg break; 165b8e80941Smrg } 166b8e80941Smrg } else { 167b8e80941Smrg value = VA_ATTRIB_NOT_SUPPORTED; 168b8e80941Smrg } 169b8e80941Smrg attrib_list[i].value = value; 170b8e80941Smrg } 171b8e80941Smrg 172b8e80941Smrg return VA_STATUS_SUCCESS; 173b8e80941Smrg} 174b8e80941Smrg 175b8e80941SmrgVAStatus 176b8e80941SmrgvlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, 177b8e80941Smrg VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) 178b8e80941Smrg{ 179b8e80941Smrg vlVaDriver *drv; 180b8e80941Smrg vlVaConfig *config; 181b8e80941Smrg struct pipe_screen *pscreen; 182b8e80941Smrg enum pipe_video_profile p; 183b8e80941Smrg unsigned int supported_rt_formats; 184b8e80941Smrg 185b8e80941Smrg if (!ctx) 186b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 187b8e80941Smrg 188b8e80941Smrg drv = VL_VA_DRIVER(ctx); 189b8e80941Smrg 190b8e80941Smrg if (!drv) 191b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 192b8e80941Smrg 193b8e80941Smrg config = CALLOC(1, sizeof(vlVaConfig)); 194b8e80941Smrg if (!config) 195b8e80941Smrg return VA_STATUS_ERROR_ALLOCATION_FAILED; 196b8e80941Smrg 197b8e80941Smrg if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { 198b8e80941Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_UNKNOWN; 199b8e80941Smrg config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; 200b8e80941Smrg supported_rt_formats = VA_RT_FORMAT_YUV420 | 201b8e80941Smrg VA_RT_FORMAT_YUV420_10BPP | 202b8e80941Smrg VA_RT_FORMAT_RGB32; 203b8e80941Smrg for (int i = 0; i < num_attribs; i++) { 204b8e80941Smrg if (attrib_list[i].type == VAConfigAttribRTFormat) { 205b8e80941Smrg if (attrib_list[i].value & supported_rt_formats) { 206b8e80941Smrg config->rt_format = attrib_list[i].value; 207b8e80941Smrg } else { 208b8e80941Smrg FREE(config); 209b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 210b8e80941Smrg } 211b8e80941Smrg } 212b8e80941Smrg } 213b8e80941Smrg 214b8e80941Smrg /* Default value if not specified in the input attributes. */ 215b8e80941Smrg if (!config->rt_format) 216b8e80941Smrg config->rt_format = supported_rt_formats; 217b8e80941Smrg 218b8e80941Smrg mtx_lock(&drv->mutex); 219b8e80941Smrg *config_id = handle_table_add(drv->htab, config); 220b8e80941Smrg mtx_unlock(&drv->mutex); 221b8e80941Smrg return VA_STATUS_SUCCESS; 222b8e80941Smrg } 223b8e80941Smrg 224b8e80941Smrg p = ProfileToPipe(profile); 225b8e80941Smrg if (p == PIPE_VIDEO_PROFILE_UNKNOWN) { 226b8e80941Smrg FREE(config); 227b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 228b8e80941Smrg } 229b8e80941Smrg 230b8e80941Smrg pscreen = VL_VA_PSCREEN(ctx); 231b8e80941Smrg 232b8e80941Smrg switch (entrypoint) { 233b8e80941Smrg case VAEntrypointVLD: 234b8e80941Smrg if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, 235b8e80941Smrg PIPE_VIDEO_CAP_SUPPORTED)) { 236b8e80941Smrg FREE(config); 237b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 238b8e80941Smrg } 239b8e80941Smrg 240b8e80941Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; 241b8e80941Smrg break; 242b8e80941Smrg 243b8e80941Smrg case VAEntrypointEncSlice: 244b8e80941Smrg if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, 245b8e80941Smrg PIPE_VIDEO_CAP_SUPPORTED)) { 246b8e80941Smrg FREE(config); 247b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 248b8e80941Smrg } 249b8e80941Smrg 250b8e80941Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; 251b8e80941Smrg break; 252b8e80941Smrg 253b8e80941Smrg default: 254b8e80941Smrg FREE(config); 255b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 256b8e80941Smrg } 257b8e80941Smrg 258b8e80941Smrg config->profile = p; 259b8e80941Smrg supported_rt_formats = VA_RT_FORMAT_YUV420; 260b8e80941Smrg if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, p, 261b8e80941Smrg config->entrypoint)) 262b8e80941Smrg supported_rt_formats |= VA_RT_FORMAT_YUV420_10BPP; 263b8e80941Smrg 264b8e80941Smrg for (int i = 0; i <num_attribs ; i++) { 265b8e80941Smrg if (attrib_list[i].type == VAConfigAttribRateControl) { 266b8e80941Smrg if (attrib_list[i].value == VA_RC_CBR) 267b8e80941Smrg config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; 268b8e80941Smrg else if (attrib_list[i].value == VA_RC_VBR) 269b8e80941Smrg config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; 270b8e80941Smrg else 271b8e80941Smrg config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; 272b8e80941Smrg } 273b8e80941Smrg if (attrib_list[i].type == VAConfigAttribRTFormat) { 274b8e80941Smrg if (attrib_list[i].value & supported_rt_formats) { 275b8e80941Smrg config->rt_format = attrib_list[i].value; 276b8e80941Smrg } else { 277b8e80941Smrg FREE(config); 278b8e80941Smrg return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 279b8e80941Smrg } 280b8e80941Smrg } 281b8e80941Smrg } 282b8e80941Smrg 283b8e80941Smrg /* Default value if not specified in the input attributes. */ 284b8e80941Smrg if (!config->rt_format) 285b8e80941Smrg config->rt_format = supported_rt_formats; 286b8e80941Smrg 287b8e80941Smrg mtx_lock(&drv->mutex); 288b8e80941Smrg *config_id = handle_table_add(drv->htab, config); 289b8e80941Smrg mtx_unlock(&drv->mutex); 290b8e80941Smrg 291b8e80941Smrg return VA_STATUS_SUCCESS; 292b8e80941Smrg} 293b8e80941Smrg 294b8e80941SmrgVAStatus 295b8e80941SmrgvlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) 296b8e80941Smrg{ 297b8e80941Smrg vlVaDriver *drv; 298b8e80941Smrg vlVaConfig *config; 299b8e80941Smrg 300b8e80941Smrg if (!ctx) 301b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 302b8e80941Smrg 303b8e80941Smrg drv = VL_VA_DRIVER(ctx); 304b8e80941Smrg 305b8e80941Smrg if (!drv) 306b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 307b8e80941Smrg 308b8e80941Smrg mtx_lock(&drv->mutex); 309b8e80941Smrg config = handle_table_get(drv->htab, config_id); 310b8e80941Smrg 311b8e80941Smrg if (!config) { 312b8e80941Smrg mtx_unlock(&drv->mutex); 313b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 314b8e80941Smrg } 315b8e80941Smrg 316b8e80941Smrg FREE(config); 317b8e80941Smrg handle_table_remove(drv->htab, config_id); 318b8e80941Smrg mtx_unlock(&drv->mutex); 319b8e80941Smrg 320b8e80941Smrg return VA_STATUS_SUCCESS; 321b8e80941Smrg} 322b8e80941Smrg 323b8e80941SmrgVAStatus 324b8e80941SmrgvlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, 325b8e80941Smrg VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) 326b8e80941Smrg{ 327b8e80941Smrg vlVaDriver *drv; 328b8e80941Smrg vlVaConfig *config; 329b8e80941Smrg 330b8e80941Smrg if (!ctx) 331b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 332b8e80941Smrg 333b8e80941Smrg drv = VL_VA_DRIVER(ctx); 334b8e80941Smrg 335b8e80941Smrg if (!drv) 336b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 337b8e80941Smrg 338b8e80941Smrg mtx_lock(&drv->mutex); 339b8e80941Smrg config = handle_table_get(drv->htab, config_id); 340b8e80941Smrg mtx_unlock(&drv->mutex); 341b8e80941Smrg 342b8e80941Smrg if (!config) 343b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 344b8e80941Smrg 345b8e80941Smrg *profile = PipeToProfile(config->profile); 346b8e80941Smrg 347b8e80941Smrg switch (config->entrypoint) { 348b8e80941Smrg case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: 349b8e80941Smrg *entrypoint = VAEntrypointVLD; 350b8e80941Smrg break; 351b8e80941Smrg case PIPE_VIDEO_ENTRYPOINT_ENCODE: 352b8e80941Smrg *entrypoint = VAEntrypointEncSlice; 353b8e80941Smrg break; 354b8e80941Smrg case PIPE_VIDEO_ENTRYPOINT_UNKNOWN: 355b8e80941Smrg *entrypoint = VAEntrypointVideoProc; 356b8e80941Smrg break; 357b8e80941Smrg default: 358b8e80941Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 359b8e80941Smrg } 360b8e80941Smrg 361b8e80941Smrg *num_attribs = 1; 362b8e80941Smrg attrib_list[0].type = VAConfigAttribRTFormat; 363b8e80941Smrg attrib_list[0].value = config->rt_format; 364b8e80941Smrg 365b8e80941Smrg return VA_STATUS_SUCCESS; 366b8e80941Smrg} 367