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