diff --git a/.gitlab-ci/meson/build.sh b/.gitlab-ci/meson/build.sh index d052397cf005f233ca6cf21fb1f6d9df9b1268c0..a400213d4ee7b8d793633d4dabfe192555e9effb 100755 --- a/.gitlab-ci/meson/build.sh +++ b/.gitlab-ci/meson/build.sh @@ -71,6 +71,7 @@ meson _build --native-file=native.file \ ${GALLIUM_ST} \ -D gallium-drivers=${GALLIUM_DRIVERS:-[]} \ -D vulkan-drivers=${VULKAN_DRIVERS:-[]} \ + -D video-codecs=h264dec,h264enc,h265dec,h265enc,vc1dec \ -D werror=true \ ${EXTRA_OPTION} cd _build diff --git a/meson.build b/meson.build index a544b37b7a551374855021dfae4c88b5dee0f8bc..0760a30d6f694f6a077e33f4d9d0286a658463b1 100644 --- a/meson.build +++ b/meson.build @@ -320,6 +320,11 @@ if with_vulkan_beta pre_args += '-DVK_ENABLE_BETA_EXTENSIONS' endif +_codecs = get_option('video-codecs') +foreach c : ['vc1dec', 'h264dec', 'h264enc', 'h265dec', 'h265enc'] + pre_args += '-DVIDEO_CODEC_@0@=@1@'.format(c.to_upper(), _codecs.contains(c).to_int()) +endforeach + _platforms = get_option('platforms') if _platforms.contains('auto') if system_has_kms_drm @@ -2273,6 +2278,9 @@ if with_gbm endif lines += '' +lines += 'Video Codecs: ' + ' '.join(_codecs) +lines += '' + if with_any_vk lines += 'Vulkan drivers: ' + ' '.join(_vulkan_drivers) lines += 'Vulkan ICD dir: ' + with_vulkan_icd_dir diff --git a/meson_options.txt b/meson_options.txt index 9afe105241f355b20ab3eeeef30580f35b2de4e1..4332906853f7c2442bbe14c021a1383729adc888 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -527,3 +527,12 @@ option( value : 'disabled', description : 'Build the intel-clc compiler (required for ray queries).' ) +option( + 'video-codecs', + type : 'array', + value : [], + choices: [ + 'vc1dec', 'h264dec', 'h264enc', 'h265dec', 'h265enc' + ], + description : 'List of patent encumbered codecs to build support for. Distros might want to consult their legal department before enabling these. This is used for all video APIs (vaapi, vdpau, vulkan). Non-patent encumbered codecs will be enabled by default.' +) diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 1a01391d197a90984c3437caecc43c45e14df6a0..3831dd72dd2327d323ac2a1b810a25f04411fdb2 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -426,6 +426,8 @@ endif files_libgalliumvl = files( 'vl/vl_bicubic_filter.c', 'vl/vl_bicubic_filter.h', + 'vl/vl_codec.c', + 'vl/vl_codec.h', 'vl/vl_compositor.c', 'vl/vl_compositor.h', 'vl/vl_compositor_gfx.c', diff --git a/src/gallium/auxiliary/vl/vl_codec.c b/src/gallium/auxiliary/vl/vl_codec.c new file mode 100644 index 0000000000000000000000000000000000000000..812222260a11597324578a4d30b238b8509f7cb5 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_codec.c @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2022 Red Hat + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +#include "pipe/p_video_codec.h" + +#include "vl_codec.h" + +bool vl_codec_supported(struct pipe_screen *screen, + enum pipe_video_profile profile, + bool encode) +{ + if (profile == PIPE_VIDEO_PROFILE_VC1_SIMPLE || + profile == PIPE_VIDEO_PROFILE_VC1_MAIN || + profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) { + return VIDEO_CODEC_VC1DEC ? true : false; + } + if (profile >= PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE && + profile <= PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444) { + if (encode) + return VIDEO_CODEC_H264ENC ? true : false; + else + return VIDEO_CODEC_H264DEC ? true : false; + } + if (profile >= PIPE_VIDEO_PROFILE_HEVC_MAIN && + profile <= PIPE_VIDEO_PROFILE_HEVC_MAIN_444) { + if (encode) + return VIDEO_CODEC_H265ENC ? true : false; + else + return VIDEO_CODEC_H265DEC ? true : false; + } + + return screen->get_video_param(screen, profile, encode ? PIPE_VIDEO_ENTRYPOINT_ENCODE : PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED); +} diff --git a/src/gallium/auxiliary/vl/vl_codec.h b/src/gallium/auxiliary/vl/vl_codec.h new file mode 100644 index 0000000000000000000000000000000000000000..fb6d82a1940e8ccf9fdb81403709fea1980953d6 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_codec.h @@ -0,0 +1,36 @@ +/************************************************************************** + * + * Copyright 2022 Red Hat + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +#ifndef VL_CODEC_H +#define VL_CODEC_H + +struct pipe_screen; + +bool vl_codec_supported(struct pipe_screen *pscreen, + enum pipe_video_profile profile, + bool encode); + +#endif diff --git a/src/gallium/frontends/omx/bellagio/vid_dec.c b/src/gallium/frontends/omx/bellagio/vid_dec.c index 8cca05f675dbba352001d5a2fc8fc3628c46e90b..08c936cafd3b4e6fc7054c166c0184190922bb36 100644 --- a/src/gallium/frontends/omx/bellagio/vid_dec.c +++ b/src/gallium/frontends/omx/bellagio/vid_dec.c @@ -51,6 +51,8 @@ #include "vl/vl_video_buffer.h" #include "util/vl_vlc.h" +#include "vl/vl_codec.h" + #include "entrypoint.h" #include "vid_dec.h" #include "vid_omx_common.h" @@ -198,6 +200,10 @@ static OMX_ERRORTYPE vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING nam return OMX_ErrorInsufficientResources; screen = priv->screen->pscreen; + + if (!vl_codec_supported(screen, priv->profile, false)) + return OMX_ErrorInsufficientResources; + priv->pipe = pipe_create_multimedia_context(screen); if (!priv->pipe) return OMX_ErrorInsufficientResources; diff --git a/src/gallium/frontends/omx/bellagio/vid_dec_av1.c b/src/gallium/frontends/omx/bellagio/vid_dec_av1.c index 061eebcf7cf8150f4ed7131f857d01067bde628d..a0c5c464c1495ef5d0fa18a239c6446cc8bb5001 100644 --- a/src/gallium/frontends/omx/bellagio/vid_dec_av1.c +++ b/src/gallium/frontends/omx/bellagio/vid_dec_av1.c @@ -30,6 +30,8 @@ #include "util/u_video.h" #include "vl/vl_video_buffer.h" +#include "vl/vl_codec.h" + #include "entrypoint.h" #include "vid_dec.h" #include "vid_dec_av1.h" @@ -2133,8 +2135,7 @@ static struct dec_av1_task *dec_av1_BeginFrame(vid_dec_PrivateType *priv) pscreen = omx_screen->pscreen; assert(pscreen); - supported = pscreen->get_video_param(pscreen, priv->profile, - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED); + supported = vl_codec_supported(pscreen, priv->profile, false); assert(supported && "AV1 is not supported"); templat.profile = priv->profile; diff --git a/src/gallium/frontends/omx/bellagio/vid_enc.c b/src/gallium/frontends/omx/bellagio/vid_enc.c index 19e5ab0796eec0953b6beba3635bf4ed0fa9e576..7c4db0a32b4ae13ab2d986b11a16147bdaf8638a 100644 --- a/src/gallium/frontends/omx/bellagio/vid_enc.c +++ b/src/gallium/frontends/omx/bellagio/vid_enc.c @@ -50,6 +50,8 @@ #include "pipe/p_video_codec.h" #include "util/u_memory.h" +#include "vl/vl_codec.h" + #include "entrypoint.h" #include "vid_enc.h" #include "vid_omx_common.h" @@ -153,8 +155,7 @@ static OMX_ERRORTYPE vid_enc_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING nam return OMX_ErrorInsufficientResources; screen = priv->screen->pscreen; - if (!screen->get_video_param(screen, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, - PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + if (!vl_codec_supported(screen, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, true)) return OMX_ErrorBadParameter; priv->s_pipe = pipe_create_multimedia_context(screen); diff --git a/src/gallium/frontends/omx/tizonia/h264eprc.c b/src/gallium/frontends/omx/tizonia/h264eprc.c index b744ebb81a85af0c720745ea41559c5f31367c9a..29bb80cb3b933677af125d6f77b943537422489e 100644 --- a/src/gallium/frontends/omx/tizonia/h264eprc.c +++ b/src/gallium/frontends/omx/tizonia/h264eprc.c @@ -33,6 +33,8 @@ #include "pipe/p_video_codec.h" #include "util/u_memory.h" +#include "vl/vl_codec.h" + #include "entrypoint.h" #include "h264e.h" #include "h264eprc.h" @@ -399,8 +401,7 @@ static OMX_ERRORTYPE h264e_prc_create_encoder(void *ap_obj) return OMX_ErrorInsufficientResources; screen = priv->screen->pscreen; - if (!screen->get_video_param(screen, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, - PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + if (!vl_codec_supported(screen, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, true)) return OMX_ErrorBadParameter; priv->s_pipe = pipe_create_multimedia_context(screen); diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index 9a19632e553ee0ad2f98564bbc2edf260e035321..0850f35fe363b5df4c6a4284c14d5c2d7ce54f71 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -32,6 +32,7 @@ #include "util/u_memory.h" #include "vl/vl_winsys.h" +#include "vl/vl_codec.h" #include "va_private.h" @@ -56,8 +57,8 @@ vlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_ if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4()) continue; - if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED) || - pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) { + if (vl_codec_supported(pscreen, p, false) || + vl_codec_supported(pscreen, p, true)) { vap = PipeToProfile(p); if (vap != VAProfileNone) profile_list[(*num_profiles)++] = vap; @@ -94,12 +95,10 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTED)) + if (vl_codec_supported(pscreen, p, false)) entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; - if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, - PIPE_VIDEO_CAP_SUPPORTED)) + if (vl_codec_supported(pscreen, p, true)) entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; if (*num_entrypoints == 0) @@ -125,8 +124,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en for (i = 0; i < num_attribs; ++i) { unsigned int value; if ((entrypoint == VAEntrypointVLD) && - (pscreen->get_video_param(pscreen, ProfileToPipe(profile), - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED))) { + (vl_codec_supported(pscreen, ProfileToPipe(profile), false))) { switch (attrib_list[i].type) { case VAConfigAttribRTFormat: value = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422; @@ -143,8 +141,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en break; } } else if ((entrypoint == VAEntrypointEncSlice) && - (pscreen->get_video_param(pscreen, ProfileToPipe(profile), - PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED))) { + (vl_codec_supported(pscreen, ProfileToPipe(profile), true))) { switch (attrib_list[i].type) { case VAConfigAttribRTFormat: value = VA_RT_FORMAT_YUV420; @@ -271,8 +268,7 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin switch (entrypoint) { case VAEntrypointVLD: supported_rt_formats = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422; - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTED)) { + if (!vl_codec_supported(pscreen, p, false)) { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; } @@ -282,8 +278,7 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin case VAEntrypointEncSlice: supported_rt_formats = VA_RT_FORMAT_YUV420; - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, - PIPE_VIDEO_CAP_SUPPORTED)) { + if (!vl_codec_supported(pscreen, p, true)) { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; } diff --git a/src/gallium/frontends/vdpau/decode.c b/src/gallium/frontends/vdpau/decode.c index ede080b04e413a5fd81038c1b9395a0d1bb166e9..8e88bfd7251dfad2de9f74b369672b9c6f9f5a28 100644 --- a/src/gallium/frontends/vdpau/decode.c +++ b/src/gallium/frontends/vdpau/decode.c @@ -32,6 +32,7 @@ #include "util/vl_vlc.h" +#include "vl/vl_codec.h" #include "vdpau_private.h" /** @@ -73,13 +74,7 @@ vlVdpDecoderCreate(VdpDevice device, mtx_lock(&dev->mutex); - supported = screen->get_video_param - ( - screen, - templat.profile, - PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTED - ); + supported = vl_codec_supported(screen, templat.profile, false); if (!supported) { mtx_unlock(&dev->mutex); return VDP_STATUS_INVALID_DECODER_PROFILE; diff --git a/src/gallium/frontends/vdpau/query.c b/src/gallium/frontends/vdpau/query.c index a1e67e315b4ffd84c12f3bc4832f3252cd6ecd3f..158256b961b26439dac24ac09bed20a052f0ecb3 100644 --- a/src/gallium/frontends/vdpau/query.c +++ b/src/gallium/frontends/vdpau/query.c @@ -33,6 +33,8 @@ #include "pipe/p_defines.h" #include "util/u_debug.h" +#include "vl/vl_codec.h" + /** * Retrieve the VDPAU version implemented by the backend. */ @@ -196,8 +198,7 @@ vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile, } mtx_lock(&dev->mutex); - *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, - PIPE_VIDEO_CAP_SUPPORTED); + *is_supported = vl_codec_supported(pscreen, p_profile, false); if (*is_supported) { *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_MAX_WIDTH);