aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Haupt <haupt.wolfgang@gmail.com>2021-12-30 12:58:09 +0100
committerWolfgang Haupt <haupt.wolfgang@gmail.com>2022-01-25 19:21:44 +0100
commit2287dbd2934484555a8c2c5ecb75bfd5053b5827 (patch)
tree2a2249e0aaaef2fb3c5cf9f0bfd821b6efddc1cb
parentb8c7377abf42570703c71e5c9f3f2712f110a6cd (diff)
VideoPlayer: VAAPI - Add av1 hw decoding
-rw-r--r--addons/resource.language.en_gb/resources/strings.po11
-rw-r--r--system/settings/linux.xml12
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp14
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp47
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp10
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp5
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;
}