From 20dfdcde718932760dccd7cef705d69994d3c5ea Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Mar 2022 13:05:58 +1000 Subject: [PATCH 1/4] gallium/vl: wrap codec support checks in a common function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just is an initial wrapping of all calls into the driver to check for codec support. The idea is to add more to this function to support the meson level disables. Acked-by: Christian König Part-of: --- src/gallium/auxiliary/meson.build | 2 ++ src/gallium/auxiliary/vl/vl_codec.c | 36 +++++++++++++++++++ src/gallium/auxiliary/vl/vl_codec.h | 36 +++++++++++++++++++ .../frontends/omx/bellagio/vid_dec_av1.c | 5 +-- src/gallium/frontends/omx/bellagio/vid_enc.c | 5 +-- src/gallium/frontends/omx/tizonia/h264eprc.c | 5 +-- src/gallium/frontends/va/config.c | 23 +++++------- src/gallium/frontends/vdpau/decode.c | 9 ++--- src/gallium/frontends/vdpau/query.c | 5 +-- 9 files changed, 97 insertions(+), 29 deletions(-) create mode 100644 src/gallium/auxiliary/vl/vl_codec.c create mode 100644 src/gallium/auxiliary/vl/vl_codec.h diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 1a01391d197a..3831dd72dd23 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 000000000000..fc2d41b43ee5 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_codec.c @@ -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. + * + **************************************************************************/ +#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) +{ + 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 000000000000..fb6d82a1940e --- /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_av1.c b/src/gallium/frontends/omx/bellagio/vid_dec_av1.c index 061eebcf7cf8..a0c5c464c149 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 19e5ab0796ee..7c4db0a32b4a 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 b744ebb81a85..29bb80cb3b93 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 9a19632e553e..0850f35fe363 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 ede080b04e41..8e88bfd7251d 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 a1e67e315b4f..158256b961b2 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); -- GitLab From 2c3178329b5356f4ca26497c5e118d4a427705c2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Mar 2022 13:11:42 +1000 Subject: [PATCH 2/4] gallium/omx: add video codec supported hook for decode paths. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These never asked the driver for what was supported. Acked-by: Christian König Part-of: --- src/gallium/frontends/omx/bellagio/vid_dec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gallium/frontends/omx/bellagio/vid_dec.c b/src/gallium/frontends/omx/bellagio/vid_dec.c index 8cca05f675db..08c936cafd3b 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; -- GitLab From 7d969fe9e91e39e03041cdfac69bf33337bc2c96 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 7 Mar 2022 12:37:29 +1000 Subject: [PATCH 3/4] meson: add a video codec support option This allows to turn on/off all hw implementations for a specific video codec across the tree. Patent encumbered codecs can cause problems for distributions due to the nature of at least MPEG-LA licensing. https://jina-liu.medium.com/settle-your-questions-about-h-264-license-cost-once-and-for-all-hopefully-a058c2149256 is probably the best explaination I can find. From a distro pov, codecs are a jigsaw puzzle, you only seem to become a problem well you fit all the pieces. This patch will allow disabling the mesa piece of the puzzle. Reviewed-by: Dylan Baker Part-of: --- .gitlab-ci/meson/build.sh | 1 + meson.build | 8 ++++++++ meson_options.txt | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/.gitlab-ci/meson/build.sh b/.gitlab-ci/meson/build.sh index d052397cf005..a400213d4ee7 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 a544b37b7a55..0760a30d6f69 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 9afe105241f3..4332906853f7 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.' +) -- GitLab From 7ab05e3c3fe34ea7f8d7345b9229c163e42c3600 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Mar 2022 13:12:38 +1000 Subject: [PATCH 4/4] gallium/vl: respect the video codecs configure in meson MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Christian König Part-of: --- src/gallium/auxiliary/vl/vl_codec.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/gallium/auxiliary/vl/vl_codec.c b/src/gallium/auxiliary/vl/vl_codec.c index fc2d41b43ee5..812222260a11 100644 --- a/src/gallium/auxiliary/vl/vl_codec.c +++ b/src/gallium/auxiliary/vl/vl_codec.c @@ -32,5 +32,25 @@ 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); } -- GitLab