17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian. 47ec681f3Smrg * Copyright 2014 Advanced Micro Devices, Inc. 57ec681f3Smrg * All Rights Reserved. 67ec681f3Smrg * 77ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87ec681f3Smrg * copy of this software and associated documentation files (the 97ec681f3Smrg * "Software"), to deal in the Software without restriction, including 107ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 117ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 127ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 137ec681f3Smrg * the following conditions: 147ec681f3Smrg * 157ec681f3Smrg * The above copyright notice and this permission notice (including the 167ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 177ec681f3Smrg * of the Software. 187ec681f3Smrg * 197ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 207ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 217ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 227ec681f3Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 237ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 247ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 257ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 267ec681f3Smrg * 277ec681f3Smrg **************************************************************************/ 287ec681f3Smrg 297ec681f3Smrg#include "pipe/p_screen.h" 307ec681f3Smrg 317ec681f3Smrg#include "util/u_video.h" 327ec681f3Smrg#include "util/u_memory.h" 337ec681f3Smrg 347ec681f3Smrg#include "vl/vl_winsys.h" 357ec681f3Smrg 367ec681f3Smrg#include "va_private.h" 377ec681f3Smrg 387ec681f3Smrg#include "util/u_handle_table.h" 397ec681f3Smrg 407ec681f3SmrgDEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) 417ec681f3Smrg 427ec681f3SmrgVAStatus 437ec681f3SmrgvlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles) 447ec681f3Smrg{ 457ec681f3Smrg struct pipe_screen *pscreen; 467ec681f3Smrg enum pipe_video_profile p; 477ec681f3Smrg VAProfile vap; 487ec681f3Smrg 497ec681f3Smrg if (!ctx) 507ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 517ec681f3Smrg 527ec681f3Smrg *num_profiles = 0; 537ec681f3Smrg 547ec681f3Smrg pscreen = VL_VA_PSCREEN(ctx); 557ec681f3Smrg for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_AV1_MAIN; ++p) { 567ec681f3Smrg if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4()) 577ec681f3Smrg continue; 587ec681f3Smrg 597ec681f3Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED) || 607ec681f3Smrg pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) { 617ec681f3Smrg vap = PipeToProfile(p); 627ec681f3Smrg if (vap != VAProfileNone) 637ec681f3Smrg profile_list[(*num_profiles)++] = vap; 647ec681f3Smrg } 657ec681f3Smrg } 667ec681f3Smrg 677ec681f3Smrg /* Support postprocessing through vl_compositor */ 687ec681f3Smrg profile_list[(*num_profiles)++] = VAProfileNone; 697ec681f3Smrg 707ec681f3Smrg return VA_STATUS_SUCCESS; 717ec681f3Smrg} 727ec681f3Smrg 737ec681f3SmrgVAStatus 747ec681f3SmrgvlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, 757ec681f3Smrg VAEntrypoint *entrypoint_list, int *num_entrypoints) 767ec681f3Smrg{ 777ec681f3Smrg struct pipe_screen *pscreen; 787ec681f3Smrg enum pipe_video_profile p; 797ec681f3Smrg 807ec681f3Smrg if (!ctx) 817ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 827ec681f3Smrg 837ec681f3Smrg *num_entrypoints = 0; 847ec681f3Smrg 857ec681f3Smrg if (profile == VAProfileNone) { 867ec681f3Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc; 877ec681f3Smrg return VA_STATUS_SUCCESS; 887ec681f3Smrg } 897ec681f3Smrg 907ec681f3Smrg p = ProfileToPipe(profile); 917ec681f3Smrg if (p == PIPE_VIDEO_PROFILE_UNKNOWN || 927ec681f3Smrg (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && 937ec681f3Smrg !debug_get_option_mpeg4())) 947ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 957ec681f3Smrg 967ec681f3Smrg pscreen = VL_VA_PSCREEN(ctx); 977ec681f3Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, 987ec681f3Smrg PIPE_VIDEO_CAP_SUPPORTED)) 997ec681f3Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; 1007ec681f3Smrg 1017ec681f3Smrg if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, 1027ec681f3Smrg PIPE_VIDEO_CAP_SUPPORTED)) 1037ec681f3Smrg entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; 1047ec681f3Smrg 1057ec681f3Smrg if (*num_entrypoints == 0) 1067ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 1077ec681f3Smrg 1087ec681f3Smrg assert(*num_entrypoints <= ctx->max_entrypoints); 1097ec681f3Smrg 1107ec681f3Smrg return VA_STATUS_SUCCESS; 1117ec681f3Smrg} 1127ec681f3Smrg 1137ec681f3SmrgVAStatus 1147ec681f3SmrgvlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, 1157ec681f3Smrg VAConfigAttrib *attrib_list, int num_attribs) 1167ec681f3Smrg{ 1177ec681f3Smrg struct pipe_screen *pscreen; 1187ec681f3Smrg int i; 1197ec681f3Smrg 1207ec681f3Smrg if (!ctx) 1217ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 1227ec681f3Smrg 1237ec681f3Smrg pscreen = VL_VA_PSCREEN(ctx); 1247ec681f3Smrg 1257ec681f3Smrg for (i = 0; i < num_attribs; ++i) { 1267ec681f3Smrg unsigned int value; 1277ec681f3Smrg if ((entrypoint == VAEntrypointVLD) && 1287ec681f3Smrg (pscreen->get_video_param(pscreen, ProfileToPipe(profile), 1297ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED))) { 1307ec681f3Smrg switch (attrib_list[i].type) { 1317ec681f3Smrg case VAConfigAttribRTFormat: 1327ec681f3Smrg value = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422; 1337ec681f3Smrg if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010, 1347ec681f3Smrg ProfileToPipe(profile), 1357ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_BITSTREAM) || 1367ec681f3Smrg pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, 1377ec681f3Smrg ProfileToPipe(profile), 1387ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_BITSTREAM)) 1397ec681f3Smrg value |= VA_RT_FORMAT_YUV420_10BPP; 1407ec681f3Smrg break; 1417ec681f3Smrg default: 1427ec681f3Smrg value = VA_ATTRIB_NOT_SUPPORTED; 1437ec681f3Smrg break; 1447ec681f3Smrg } 1457ec681f3Smrg } else if ((entrypoint == VAEntrypointEncSlice) && 1467ec681f3Smrg (pscreen->get_video_param(pscreen, ProfileToPipe(profile), 1477ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED))) { 1487ec681f3Smrg switch (attrib_list[i].type) { 1497ec681f3Smrg case VAConfigAttribRTFormat: 1507ec681f3Smrg value = VA_RT_FORMAT_YUV420; 1517ec681f3Smrg if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010, 1527ec681f3Smrg ProfileToPipe(profile), 1537ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_ENCODE) || 1547ec681f3Smrg pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, 1557ec681f3Smrg ProfileToPipe(profile), 1567ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_ENCODE)) 1577ec681f3Smrg value |= VA_RT_FORMAT_YUV420_10BPP; 1587ec681f3Smrg break; 1597ec681f3Smrg case VAConfigAttribRateControl: 1607ec681f3Smrg value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR; 1617ec681f3Smrg break; 1627ec681f3Smrg case VAConfigAttribEncRateControlExt: 1637ec681f3Smrg value = pscreen->get_video_param(pscreen, ProfileToPipe(profile), 1647ec681f3Smrg PIPE_VIDEO_ENTRYPOINT_ENCODE, 1657ec681f3Smrg PIPE_VIDEO_CAP_MAX_TEMPORAL_LAYERS); 1667ec681f3Smrg if (value > 0) { 1677ec681f3Smrg value -= 1; 1687ec681f3Smrg value |= (1 << 8); /* temporal_layer_bitrate_control_flag */ 1697ec681f3Smrg } 1707ec681f3Smrg break; 1717ec681f3Smrg case VAConfigAttribEncPackedHeaders: 1727ec681f3Smrg value = VA_ENC_PACKED_HEADER_NONE; 1737ec681f3Smrg if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_MPEG4_AVC || 1747ec681f3Smrg u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC) 1757ec681f3Smrg value |= VA_ENC_PACKED_HEADER_SEQUENCE; 1767ec681f3Smrg break; 1777ec681f3Smrg case VAConfigAttribEncMaxRefFrames: 1787ec681f3Smrg value = 1; 1797ec681f3Smrg break; 1807ec681f3Smrg default: 1817ec681f3Smrg value = VA_ATTRIB_NOT_SUPPORTED; 1827ec681f3Smrg break; 1837ec681f3Smrg } 1847ec681f3Smrg } else if (entrypoint == VAEntrypointVideoProc) { 1857ec681f3Smrg switch (attrib_list[i].type) { 1867ec681f3Smrg case VAConfigAttribRTFormat: 1877ec681f3Smrg value = (VA_RT_FORMAT_YUV420 | 1887ec681f3Smrg VA_RT_FORMAT_YUV420_10BPP | 1897ec681f3Smrg VA_RT_FORMAT_RGB32); 1907ec681f3Smrg break; 1917ec681f3Smrg default: 1927ec681f3Smrg value = VA_ATTRIB_NOT_SUPPORTED; 1937ec681f3Smrg break; 1947ec681f3Smrg } 1957ec681f3Smrg } else { 1967ec681f3Smrg value = VA_ATTRIB_NOT_SUPPORTED; 1977ec681f3Smrg } 1987ec681f3Smrg attrib_list[i].value = value; 1997ec681f3Smrg } 2007ec681f3Smrg 2017ec681f3Smrg return VA_STATUS_SUCCESS; 2027ec681f3Smrg} 2037ec681f3Smrg 2047ec681f3SmrgVAStatus 2057ec681f3SmrgvlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, 2067ec681f3Smrg VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) 2077ec681f3Smrg{ 2087ec681f3Smrg vlVaDriver *drv; 2097ec681f3Smrg vlVaConfig *config; 2107ec681f3Smrg struct pipe_screen *pscreen; 2117ec681f3Smrg enum pipe_video_profile p; 2127ec681f3Smrg unsigned int supported_rt_formats; 2137ec681f3Smrg 2147ec681f3Smrg if (!ctx) 2157ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 2167ec681f3Smrg 2177ec681f3Smrg drv = VL_VA_DRIVER(ctx); 2187ec681f3Smrg 2197ec681f3Smrg if (!drv) 2207ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 2217ec681f3Smrg 2227ec681f3Smrg config = CALLOC(1, sizeof(vlVaConfig)); 2237ec681f3Smrg if (!config) 2247ec681f3Smrg return VA_STATUS_ERROR_ALLOCATION_FAILED; 2257ec681f3Smrg 2267ec681f3Smrg if (profile == VAProfileNone) { 2277ec681f3Smrg if (entrypoint != VAEntrypointVideoProc) { 2287ec681f3Smrg FREE(config); 2297ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 2307ec681f3Smrg } 2317ec681f3Smrg 2327ec681f3Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_UNKNOWN; 2337ec681f3Smrg config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; 2347ec681f3Smrg supported_rt_formats = VA_RT_FORMAT_YUV420 | 2357ec681f3Smrg VA_RT_FORMAT_YUV420_10BPP | 2367ec681f3Smrg VA_RT_FORMAT_RGB32; 2377ec681f3Smrg for (int i = 0; i < num_attribs; i++) { 2387ec681f3Smrg if (attrib_list[i].type == VAConfigAttribRTFormat) { 2397ec681f3Smrg if (attrib_list[i].value & supported_rt_formats) { 2407ec681f3Smrg config->rt_format = attrib_list[i].value; 2417ec681f3Smrg } else { 2427ec681f3Smrg FREE(config); 2437ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 2447ec681f3Smrg } 2457ec681f3Smrg } else { 2467ec681f3Smrg /*other attrib_types are not supported.*/ 2477ec681f3Smrg FREE(config); 2487ec681f3Smrg return VA_STATUS_ERROR_INVALID_VALUE; 2497ec681f3Smrg } 2507ec681f3Smrg } 2517ec681f3Smrg 2527ec681f3Smrg /* Default value if not specified in the input attributes. */ 2537ec681f3Smrg if (!config->rt_format) 2547ec681f3Smrg config->rt_format = supported_rt_formats; 2557ec681f3Smrg 2567ec681f3Smrg mtx_lock(&drv->mutex); 2577ec681f3Smrg *config_id = handle_table_add(drv->htab, config); 2587ec681f3Smrg mtx_unlock(&drv->mutex); 2597ec681f3Smrg return VA_STATUS_SUCCESS; 2607ec681f3Smrg } 2617ec681f3Smrg 2627ec681f3Smrg p = ProfileToPipe(profile); 2637ec681f3Smrg if (p == PIPE_VIDEO_PROFILE_UNKNOWN || 2647ec681f3Smrg (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && 2657ec681f3Smrg !debug_get_option_mpeg4())) { 2667ec681f3Smrg FREE(config); 2677ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 2687ec681f3Smrg } 2697ec681f3Smrg 2707ec681f3Smrg pscreen = VL_VA_PSCREEN(ctx); 2717ec681f3Smrg 2727ec681f3Smrg switch (entrypoint) { 2737ec681f3Smrg case VAEntrypointVLD: 2747ec681f3Smrg supported_rt_formats = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422; 2757ec681f3Smrg if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, 2767ec681f3Smrg PIPE_VIDEO_CAP_SUPPORTED)) { 2777ec681f3Smrg FREE(config); 2787ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 2797ec681f3Smrg } 2807ec681f3Smrg 2817ec681f3Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; 2827ec681f3Smrg break; 2837ec681f3Smrg 2847ec681f3Smrg case VAEntrypointEncSlice: 2857ec681f3Smrg supported_rt_formats = VA_RT_FORMAT_YUV420; 2867ec681f3Smrg if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, 2877ec681f3Smrg PIPE_VIDEO_CAP_SUPPORTED)) { 2887ec681f3Smrg FREE(config); 2897ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 2907ec681f3Smrg } 2917ec681f3Smrg 2927ec681f3Smrg config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; 2937ec681f3Smrg break; 2947ec681f3Smrg 2957ec681f3Smrg default: 2967ec681f3Smrg FREE(config); 2977ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 2987ec681f3Smrg } 2997ec681f3Smrg 3007ec681f3Smrg config->profile = p; 3017ec681f3Smrg if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010, p, 3027ec681f3Smrg config->entrypoint) || 3037ec681f3Smrg pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, p, 3047ec681f3Smrg config->entrypoint)) 3057ec681f3Smrg supported_rt_formats |= VA_RT_FORMAT_YUV420_10BPP; 3067ec681f3Smrg 3077ec681f3Smrg for (int i = 0; i <num_attribs ; i++) { 3087ec681f3Smrg if (attrib_list[i].type != VAConfigAttribRTFormat && 3097ec681f3Smrg entrypoint == VAEntrypointVLD ) { 3107ec681f3Smrg FREE(config); 3117ec681f3Smrg return VA_STATUS_ERROR_INVALID_VALUE; 3127ec681f3Smrg } 3137ec681f3Smrg if (attrib_list[i].type == VAConfigAttribRateControl) { 3147ec681f3Smrg if (attrib_list[i].value == VA_RC_CBR) 3157ec681f3Smrg config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT; 3167ec681f3Smrg else if (attrib_list[i].value == VA_RC_VBR) 3177ec681f3Smrg config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE; 3187ec681f3Smrg else if (attrib_list[i].value == VA_RC_CQP) 3197ec681f3Smrg config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE; 3207ec681f3Smrg else { 3217ec681f3Smrg FREE(config); 3227ec681f3Smrg return VA_STATUS_ERROR_INVALID_VALUE; 3237ec681f3Smrg } 3247ec681f3Smrg } 3257ec681f3Smrg if (attrib_list[i].type == VAConfigAttribRTFormat) { 3267ec681f3Smrg if (attrib_list[i].value & supported_rt_formats) { 3277ec681f3Smrg config->rt_format = attrib_list[i].value; 3287ec681f3Smrg } else { 3297ec681f3Smrg FREE(config); 3307ec681f3Smrg return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 3317ec681f3Smrg } 3327ec681f3Smrg } 3337ec681f3Smrg if (attrib_list[i].type == VAConfigAttribEncPackedHeaders) { 3347ec681f3Smrg if (attrib_list[i].value > 1 || 3357ec681f3Smrg config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) { 3367ec681f3Smrg FREE(config); 3377ec681f3Smrg return VA_STATUS_ERROR_INVALID_VALUE; 3387ec681f3Smrg } 3397ec681f3Smrg } 3407ec681f3Smrg } 3417ec681f3Smrg 3427ec681f3Smrg /* Default value if not specified in the input attributes. */ 3437ec681f3Smrg if (!config->rt_format) 3447ec681f3Smrg config->rt_format = supported_rt_formats; 3457ec681f3Smrg 3467ec681f3Smrg mtx_lock(&drv->mutex); 3477ec681f3Smrg *config_id = handle_table_add(drv->htab, config); 3487ec681f3Smrg mtx_unlock(&drv->mutex); 3497ec681f3Smrg 3507ec681f3Smrg return VA_STATUS_SUCCESS; 3517ec681f3Smrg} 3527ec681f3Smrg 3537ec681f3SmrgVAStatus 3547ec681f3SmrgvlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) 3557ec681f3Smrg{ 3567ec681f3Smrg vlVaDriver *drv; 3577ec681f3Smrg vlVaConfig *config; 3587ec681f3Smrg 3597ec681f3Smrg if (!ctx) 3607ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 3617ec681f3Smrg 3627ec681f3Smrg drv = VL_VA_DRIVER(ctx); 3637ec681f3Smrg 3647ec681f3Smrg if (!drv) 3657ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 3667ec681f3Smrg 3677ec681f3Smrg mtx_lock(&drv->mutex); 3687ec681f3Smrg config = handle_table_get(drv->htab, config_id); 3697ec681f3Smrg 3707ec681f3Smrg if (!config) { 3717ec681f3Smrg mtx_unlock(&drv->mutex); 3727ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 3737ec681f3Smrg } 3747ec681f3Smrg 3757ec681f3Smrg FREE(config); 3767ec681f3Smrg handle_table_remove(drv->htab, config_id); 3777ec681f3Smrg mtx_unlock(&drv->mutex); 3787ec681f3Smrg 3797ec681f3Smrg return VA_STATUS_SUCCESS; 3807ec681f3Smrg} 3817ec681f3Smrg 3827ec681f3SmrgVAStatus 3837ec681f3SmrgvlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, 3847ec681f3Smrg VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) 3857ec681f3Smrg{ 3867ec681f3Smrg vlVaDriver *drv; 3877ec681f3Smrg vlVaConfig *config; 3887ec681f3Smrg 3897ec681f3Smrg if (!ctx) 3907ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 3917ec681f3Smrg 3927ec681f3Smrg drv = VL_VA_DRIVER(ctx); 3937ec681f3Smrg 3947ec681f3Smrg if (!drv) 3957ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONTEXT; 3967ec681f3Smrg 3977ec681f3Smrg mtx_lock(&drv->mutex); 3987ec681f3Smrg config = handle_table_get(drv->htab, config_id); 3997ec681f3Smrg mtx_unlock(&drv->mutex); 4007ec681f3Smrg 4017ec681f3Smrg if (!config) 4027ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 4037ec681f3Smrg 4047ec681f3Smrg *profile = PipeToProfile(config->profile); 4057ec681f3Smrg 4067ec681f3Smrg switch (config->entrypoint) { 4077ec681f3Smrg case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: 4087ec681f3Smrg *entrypoint = VAEntrypointVLD; 4097ec681f3Smrg break; 4107ec681f3Smrg case PIPE_VIDEO_ENTRYPOINT_ENCODE: 4117ec681f3Smrg *entrypoint = VAEntrypointEncSlice; 4127ec681f3Smrg break; 4137ec681f3Smrg case PIPE_VIDEO_ENTRYPOINT_UNKNOWN: 4147ec681f3Smrg *entrypoint = VAEntrypointVideoProc; 4157ec681f3Smrg break; 4167ec681f3Smrg default: 4177ec681f3Smrg return VA_STATUS_ERROR_INVALID_CONFIG; 4187ec681f3Smrg } 4197ec681f3Smrg 4207ec681f3Smrg *num_attribs = 1; 4217ec681f3Smrg attrib_list[0].type = VAConfigAttribRTFormat; 4227ec681f3Smrg attrib_list[0].value = config->rt_format; 4237ec681f3Smrg 4247ec681f3Smrg return VA_STATUS_SUCCESS; 4257ec681f3Smrg} 426