diff options
author | Wolfgang Haupt <haupt.wolfgang@gmail.com> | 2021-12-30 12:58:09 +0100 |
---|---|---|
committer | Wolfgang Haupt <haupt.wolfgang@gmail.com> | 2022-01-25 19:21:44 +0100 |
commit | 2287dbd2934484555a8c2c5ecb75bfd5053b5827 (patch) | |
tree | 2a2249e0aaaef2fb3c5cf9f0bfd821b6efddc1cb | |
parent | b8c7377abf42570703c71e5c9f3f2712f110a6cd (diff) |
VideoPlayer: VAAPI - Add av1 hw decoding
-rw-r--r-- | addons/resource.language.en_gb/resources/strings.po | 11 | ||||
-rw-r--r-- | system/settings/linux.xml | 12 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 14 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp | 47 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 10 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp | 5 |
9 files changed, 89 insertions, 14 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 2b91aa9675..772983f0dd 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -7356,6 +7356,17 @@ msgctxt "#13467" msgid "Unlimited / 1080 (>30Hz)" msgstr "" +#: system/settings/settings.xml +msgctxt "#13468" +msgid "Use AV1 VAAPI" +msgstr "" + +#. Description of setting with label #13468 "Use AV1 VAAPI" +#: system/settings/settings.xml +msgctxt "#13469" +msgid "Enable this option to use hardware acceleration for the AV1 codec. If disabled the CPU will be used instead." +msgstr "" + #empty strings from id 13468 to 13504 #: system/settings/settings.xml diff --git a/system/settings/linux.xml b/system/settings/linux.xml index 1f729fc60f..531974f3f4 100644 --- a/system/settings/linux.xml +++ b/system/settings/linux.xml @@ -137,6 +137,18 @@ <default>true</default> <control type="toggle" /> </setting> + <setting id="videoplayer.usevaapiav1" type="boolean" parent="videoplayer.usevaapi" label="13468" help="13469"> + <requirement>HAVE_LIBVA</requirement> + <visible>false</visible> + <dependencies> + <dependency type="enable"> + <condition setting="videoplayer.usevaapi" operator="is">true</condition> + </dependency> + </dependencies> + <level>3</level> + <default>true</default> + <control type="toggle" /> + </setting> <setting id="videoplayer.prefervaapirender" type="boolean" parent="videoplayer.usevaapi" label="13457" help="36433"> <requirement>HAVE_LIBVA</requirement> <visible>false</visible> diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index 795300cadb..2684df3f2f 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -326,7 +326,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_hints = hints; m_options = options; - AVCodec* pCodec; + AVCodec* pCodec = nullptr; m_iOrientation = hints.orientation; @@ -336,7 +336,16 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_processInfo.SetSwDeinterlacingMethods(); m_processInfo.SetVideoInterlaced(false); - pCodec = avcodec_find_decoder(hints.codec); + // libdav1d av1 sw decoding is implemented as a separate decoder + // in ffmpeg which is always found first when calling `avcodec_find_decoder`. + // To get hwaccels we look for decoders registered for `av1`. + // The decoder state check is needed to succesfully fallback to sw decoding if + // necessary. + if (hints.codec == AV_CODEC_ID_AV1 && m_decoderState != STATE_HW_FAILED) + pCodec = avcodec_find_decoder_by_name("av1"); + + if (!pCodec) + pCodec = avcodec_find_decoder(hints.codec); if(pCodec == NULL) { @@ -381,6 +390,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_pCodecContext->coded_height = hints.height; m_pCodecContext->coded_width = hints.width; m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel; + m_pCodecContext->bits_per_raw_sample = hints.bitdepth; if( hints.extradata && hints.extrasize > 0 ) { diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp index 37c7015b28..b860993072 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp @@ -54,6 +54,7 @@ using namespace std::chrono_literals; #define NUM_RENDER_PICS 7 constexpr auto SETTING_VIDEOPLAYER_USEVAAPI = "videoplayer.usevaapi"; +constexpr auto SETTING_VIDEOPLAYER_USEVAAPIAV1 = "videoplayer.usevaapiav1"; constexpr auto SETTING_VIDEOPLAYER_USEVAAPIHEVC = "videoplayer.usevaapihevc"; constexpr auto SETTING_VIDEOPLAYER_USEVAAPIMPEG2 = "videoplayer.usevaapimpeg2"; constexpr auto SETTING_VIDEOPLAYER_USEVAAPIMPEG4 = "videoplayer.usevaapimpeg4"; @@ -532,14 +533,15 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A // check if user wants to decode this format with VAAPI std::map<AVCodecID, std::string> settings_map = { - { AV_CODEC_ID_H263, SETTING_VIDEOPLAYER_USEVAAPIMPEG4 }, - { AV_CODEC_ID_MPEG4, SETTING_VIDEOPLAYER_USEVAAPIMPEG4 }, - { AV_CODEC_ID_WMV3, SETTING_VIDEOPLAYER_USEVAAPIVC1 }, - { AV_CODEC_ID_VC1, SETTING_VIDEOPLAYER_USEVAAPIVC1 }, - { AV_CODEC_ID_MPEG2VIDEO, SETTING_VIDEOPLAYER_USEVAAPIMPEG2 }, - { AV_CODEC_ID_VP8, SETTING_VIDEOPLAYER_USEVAAPIVP8 }, - { AV_CODEC_ID_VP9, SETTING_VIDEOPLAYER_USEVAAPIVP9 }, - { AV_CODEC_ID_HEVC, SETTING_VIDEOPLAYER_USEVAAPIHEVC }, + {AV_CODEC_ID_H263, SETTING_VIDEOPLAYER_USEVAAPIMPEG4}, + {AV_CODEC_ID_MPEG4, SETTING_VIDEOPLAYER_USEVAAPIMPEG4}, + {AV_CODEC_ID_WMV3, SETTING_VIDEOPLAYER_USEVAAPIVC1}, + {AV_CODEC_ID_VC1, SETTING_VIDEOPLAYER_USEVAAPIVC1}, + {AV_CODEC_ID_MPEG2VIDEO, SETTING_VIDEOPLAYER_USEVAAPIMPEG2}, + {AV_CODEC_ID_VP8, SETTING_VIDEOPLAYER_USEVAAPIVP8}, + {AV_CODEC_ID_VP9, SETTING_VIDEOPLAYER_USEVAAPIVP9}, + {AV_CODEC_ID_HEVC, SETTING_VIDEOPLAYER_USEVAAPIHEVC}, + {AV_CODEC_ID_AV1, SETTING_VIDEOPLAYER_USEVAAPIAV1}, }; auto entry = settings_map.find(avctx->codec_id); @@ -585,6 +587,7 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A m_vaapiConfig.surfaceWidth = avctx->coded_width; m_vaapiConfig.surfaceHeight = avctx->coded_height; m_vaapiConfig.aspect = avctx->sample_aspect_ratio; + m_vaapiConfig.bitDepth = avctx->bits_per_raw_sample; m_DisplayState = VAAPI_OPEN; m_vaapiConfigured = false; m_presentPicture = nullptr; @@ -672,6 +675,20 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A if (!m_vaapiConfig.context->SupportsProfile(profile)) return false; break; +#if VA_CHECK_VERSION(1, 8, 0) + case AV_CODEC_ID_AV1: + { + if (avctx->profile == FF_PROFILE_AV1_MAIN) + profile = VAProfileAV1Profile0; + else if (avctx->profile == FF_PROFILE_AV1_HIGH) + profile = VAProfileAV1Profile1; + else + profile = VAProfileNone; + if (!m_vaapiConfig.context->SupportsProfile(profile)) + return false; + break; + } +#endif default: return false; } @@ -696,6 +713,8 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A m_vaapiConfig.maxReferences = 16; else if (avctx->codec_id == AV_CODEC_ID_VP9) m_vaapiConfig.maxReferences = 8; + else if (avctx->codec_id == AV_CODEC_ID_AV1) + m_vaapiConfig.maxReferences = 18; else m_vaapiConfig.maxReferences = 2; @@ -1134,7 +1153,12 @@ bool CDecoder::ConfigVAAPI() unsigned int format = VA_RT_FORMAT_YUV420; std::int32_t pixelFormat = VA_FOURCC_NV12; - if (m_vaapiConfig.profile == VAProfileHEVCMain10) + if ((m_vaapiConfig.profile == VAProfileHEVCMain10 +#if VA_CHECK_VERSION(1, 8, 0) + || m_vaapiConfig.profile == VAProfileAV1Profile0 +#endif + ) && + m_vaapiConfig.bitDepth == 10) { format = VA_RT_FORMAT_YUV420_10BPP; pixelFormat = VA_FOURCC_P010; @@ -1256,11 +1280,12 @@ void CDecoder::Register(IVaapiWinSystem *winSystem, bool deepColor) if (!settings) return; - constexpr std::array<const char*, 8> vaapiSettings = { + constexpr std::array<const char*, 9> vaapiSettings = { SETTING_VIDEOPLAYER_USEVAAPI, SETTING_VIDEOPLAYER_USEVAAPIMPEG4, SETTING_VIDEOPLAYER_USEVAAPIVC1, SETTING_VIDEOPLAYER_USEVAAPIMPEG2, SETTING_VIDEOPLAYER_USEVAAPIVP8, SETTING_VIDEOPLAYER_USEVAAPIVP9, - SETTING_VIDEOPLAYER_USEVAAPIHEVC, SETTING_VIDEOPLAYER_PREFERVAAPIRENDER}; + SETTING_VIDEOPLAYER_USEVAAPIHEVC, SETTING_VIDEOPLAYER_PREFERVAAPIRENDER, + SETTING_VIDEOPLAYER_USEVAAPIAV1}; for (const auto vaapiSetting : vaapiSettings) { diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h index 8f966849d3..001f1bf00e 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h @@ -115,6 +115,7 @@ struct CVaapiConfig VAConfigAttrib attrib; CProcessInfo *processInfo; bool driverIsMesa; + int bitDepth; }; /** diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h index 031b2cfe35..a16d2fe192 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h @@ -138,6 +138,7 @@ public: int iOrientation = 0; // orientation of the video in degrees counter clockwise int iBitsPerPixel = 0; int iBitRate = 0; + int bitDepth = 0; AVColorSpace colorSpace = AVCOL_SPC_UNSPECIFIED; AVColorRange colorRange = AVCOL_RANGE_UNSPECIFIED; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 20ad677057..ad3c1c2d21 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -668,6 +668,8 @@ std::string CDVDDemuxClient::GetStreamCodecName(int iStreamId) strName = "vp9"; else if (stream->codec == AV_CODEC_ID_HEVC) strName = "hevc"; + else if (stream->codec == AV_CODEC_ID_AV1) + strName = "av1"; } return strName; } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 7790befe56..8700c87b86 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -33,6 +33,11 @@ #include <sstream> #include <utility> +extern "C" +{ +#include "libavutil/pixdesc.h" +} + #ifdef HAVE_LIBBLURAY #include "DVDInputStreams/DVDInputStreamBluray.h" #endif @@ -1639,6 +1644,11 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iOrientation = 0; st->iBitsPerPixel = pStream->codecpar->bits_per_coded_sample; st->iBitRate = static_cast<int>(pStream->codecpar->bit_rate); + st->bitDepth = 8; + const AVPixFmtDescriptor* desc = + av_pix_fmt_desc_get(static_cast<AVPixelFormat>(pStream->codecpar->format)); + if (desc != nullptr && desc->comp != nullptr) + st->bitDepth = desc->comp[0].depth; st->colorPrimaries = pStream->codecpar->color_primaries; st->colorSpace = pStream->codecpar->color_space; diff --git a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp index f4293ae7fc..f3a833a2aa 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp @@ -105,6 +105,7 @@ bool CVideoPlayerVideo::OpenStream(CDVDStreamInfo hint) if (hint.extrasize == 0) { // codecs which require extradata + // clang-format off if (hint.codec == AV_CODEC_ID_NONE || hint.codec == AV_CODEC_ID_MPEG1VIDEO || hint.codec == AV_CODEC_ID_MPEG2VIDEO || @@ -112,7 +113,9 @@ bool CVideoPlayerVideo::OpenStream(CDVDStreamInfo hint) hint.codec == AV_CODEC_ID_HEVC || hint.codec == AV_CODEC_ID_MPEG4 || hint.codec == AV_CODEC_ID_WMV3 || - hint.codec == AV_CODEC_ID_VC1) + hint.codec == AV_CODEC_ID_VC1 || + hint.codec == AV_CODEC_ID_AV1) + // clang-format on return false; } |