From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 2980341143 for ; Sun, 14 Aug 2022 21:34:00 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8E02A68B962; Mon, 15 Aug 2022 00:33:34 +0300 (EEST) Received: from mail.overt.org (mail.overt.org [157.230.92.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6228E68B8AD for ; Mon, 15 Aug 2022 00:33:25 +0300 (EEST) Received: from authenticated-user (mail.overt.org [157.230.92.47]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mail.overt.org (Postfix) with ESMTPSA id 2CC823F89E; Sun, 14 Aug 2022 16:33:23 -0500 (CDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=overt.org; s=mail; t=1660512803; bh=YQ7FLcY+iuHGS1ba4qkrUzP0r3Z+4a9SNHu0Zb/5lgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jYyuDqTCqckFTB5IMOpjSoQMXs2jbVHuBzziKFyBx43KcwPDRh858O+VCFrgvQOTN J5aoqM7qsWWvCfJqa1tgkhfx6JyMrpSnvSJ9yPRFcfQBUvvo0c0JnwJTo6dzgt18Gf hRsPX8zHzuU83J/6aJXcPSeRvNc2a1pUf00d6TuELipqVds65mKXHYcu9RPdQpNjk1 s9jmMem4ZLQogw6A0RvYgAUWukr4ok2rfrCjONxWdGGzxPlRUv785Ne1lEm9Y8Vnc2 K3v+ycroDK/FxGcbaNInJFQftPF46RpyI+ZKLBOsECMixeLqMEphyQ5nl450VVAKoV LwsykjLlGKrgg== From: Philip Langdale To: ffmpeg-devel@ffmpeg.org Date: Sun, 14 Aug 2022 14:33:12 -0700 Message-Id: <20220814213313.37948-3-philipl@overt.org> In-Reply-To: <20220814213313.37948-1-philipl@overt.org> References: <20220814213313.37948-1-philipl@overt.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/3] lavc/vaapi: Add support for remaining 10/12bit profiles X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Philip Langdale Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: With the necessary pixel formats defined, we can now expose support for the remaining 10/12bit combinations that VAAPI can handle. Specifically, we are adding support for: * HEVC ** 12bit 420 ** 10bit 422 ** 12bit 422 ** 10bit 444 ** 12bit 444 * VP9 ** 10bit 422 ** 10bit 444 These obviously require actual hardware support to be usable, but where that exists, it is now enabled. I had to make some adjustments to the encode logic for matching bit depth as the existing code assumed that the picture depth and the pixel format depth were always the same, which is not true for 12bit content which uses 16bit pixel formats. Signed-off-by: Philip Langdale --- libavcodec/hevcdec.c | 8 ++++++++ libavcodec/vaapi_decode.c | 13 +++++++++++++ libavcodec/vaapi_encode.c | 19 +++++++++++++++---- libavcodec/vaapi_encode_h265.c | 10 ++++++++-- libavcodec/vaapi_encode_vp9.c | 4 +++- libavcodec/vaapi_hevc.c | 11 ++++++++++- libavutil/hwcontext_vaapi.c | 12 ++++++++++++ 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index f1be8af2cd..1a895800a6 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -481,11 +481,19 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV444P12: +#if CONFIG_HEVC_VAAPI_HWACCEL + *fmt++ = AV_PIX_FMT_VAAPI; +#endif #if CONFIG_HEVC_VDPAU_HWACCEL *fmt++ = AV_PIX_FMT_VDPAU; #endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; +#endif + break; + case AV_PIX_FMT_YUV422P12: +#if CONFIG_HEVC_VAAPI_HWACCEL + *fmt++ = AV_PIX_FMT_VAAPI; #endif break; } diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index bc2d3ed803..9ba7dfd886 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -262,16 +262,28 @@ static const struct { MAP(YUY2, YUYV422), #ifdef VA_FOURCC_Y210 MAP(Y210, Y210), +#endif +#ifdef VA_FOURCC_Y216 + MAP(Y216, Y216), #endif // 4:4:0 MAP(422V, YUV440P), // 4:4:4 MAP(444P, YUV444P), MAP(AYUV, VUYA), +#ifdef VA_FOURCC_Y410 + MAP(Y410, Y410), +#endif +#ifdef VA_FOURCC_Y416 + MAP(Y416, Y416), +#endif // 4:2:0 10-bit #ifdef VA_FOURCC_P010 MAP(P010, P010), #endif +#ifdef VA_FOURCC_P016 + MAP(P016, P016), +#endif #ifdef VA_FOURCC_I010 MAP(I010, YUV420P10), #endif @@ -415,6 +427,7 @@ static const struct { #if VA_CHECK_VERSION(0, 39, 0) MAP(VP9, VP9_1, VP9Profile1 ), MAP(VP9, VP9_2, VP9Profile2 ), + MAP(VP9, VP9_3, VP9Profile3 ), #endif #if VA_CHECK_VERSION(1, 8, 0) MAP(AV1, AV1_MAIN, AV1Profile0), diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index f13daa5cff..1cf11c4cd5 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1305,7 +1305,11 @@ static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = { { "YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 }, { "YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 }, #if VA_CHECK_VERSION(1, 2, 0) + { "YUV420_12", VA_RT_FORMAT_YUV420_12, 12, 3, 1, 1 }, { "YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 }, + { "YUV422_12", VA_RT_FORMAT_YUV422_12, 12, 3, 1, 0 }, + { "YUV444_10", VA_RT_FORMAT_YUV444_10, 10, 4, 0, 0 }, + { "YUV444_12", VA_RT_FORMAT_YUV444_12, 12, 4, 0, 0 }, #endif { "YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 }, { "AYUV", VA_RT_FORMAT_YUV444, 8, 4, 0, 0 }, @@ -1342,7 +1346,7 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) VAConfigAttrib rt_format_attr; const VAAPIEncodeRTFormat *rt_format; const char *profile_string, *entrypoint_string; - int i, j, n, depth, err; + int i, j, n, depth, logical_depth, err; if (ctx->low_power) { @@ -1365,7 +1369,9 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) } depth = desc->comp[0].depth; for (i = 1; i < desc->nb_components; i++) { - if (desc->comp[i].depth != depth) { + // We do not apply this depth requirement to the fourth component as + // that will be the alpha channel when present, which can be smaller. + if (i < 3 && desc->comp[i].depth != depth) { av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n", desc->name); return AVERROR(EINVAL); @@ -1391,8 +1397,11 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) av_assert0(ctx->codec->profiles); for (i = 0; (ctx->codec->profiles[i].av_profile != FF_PROFILE_UNKNOWN); i++) { + profile = &ctx->codec->profiles[i]; - if (depth != profile->depth || + // Look for a 16bit format if the profile depth is > 10bit + logical_depth = profile->depth > 10 ? 16 : profile->depth; + if (depth != logical_depth || desc->nb_components != profile->nb_components) continue; if (desc->nb_components > 1 && @@ -1476,7 +1485,9 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) { rt_format = &vaapi_encode_rt_formats[i]; - if (rt_format->depth == depth && + // Look for a 16bit pixel format if the rt format depth is > 10bit + logical_depth = rt_format->depth > 10 ? 16 : rt_format->depth; + if (logical_depth == depth && rt_format->nb_components == profile->nb_components && rt_format->log2_chroma_w == profile->log2_chroma_w && rt_format->log2_chroma_h == profile->log2_chroma_h) diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 1de323af78..1a65fb9ebf 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -283,7 +283,9 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) return AVERROR(EINVAL); } } - bit_depth = desc->comp[0].depth; + // Bit depth must be taken from the profile, as the pixel format will be + // 16bit for >= 12bit content. + bit_depth = ctx->profile->depth; // VPS @@ -1276,10 +1278,14 @@ static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { { FF_PROFILE_HEVC_REXT, 10, 3, 1, 1, VAProfileHEVCMain10 }, #endif #if VA_CHECK_VERSION(1, 2, 0) + { FF_PROFILE_HEVC_REXT, 12, 3, 1, 1, VAProfileHEVCMain12 }, { FF_PROFILE_HEVC_REXT, 8, 3, 1, 0, VAProfileHEVCMain422_10 }, { FF_PROFILE_HEVC_REXT, 10, 3, 1, 0, VAProfileHEVCMain422_10 }, - // Four channels because this uses the AYUV format which has Alpha + { FF_PROFILE_HEVC_REXT, 12, 3, 1, 0, VAProfileHEVCMain422_12 }, + // Four channels because these use formats which have Alpha { FF_PROFILE_HEVC_REXT, 8, 4, 0, 0, VAProfileHEVCMain444 }, + { FF_PROFILE_HEVC_REXT, 10, 4, 0, 0, VAProfileHEVCMain444_10 }, + { FF_PROFILE_HEVC_REXT, 12, 4, 0, 0, VAProfileHEVCMain444_12 }, #endif { FF_PROFILE_UNKNOWN } }; diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c index 9b455e10c9..e6c7f01f11 100644 --- a/libavcodec/vaapi_encode_vp9.c +++ b/libavcodec/vaapi_encode_vp9.c @@ -228,9 +228,11 @@ static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx) static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = { { FF_PROFILE_VP9_0, 8, 3, 1, 1, VAProfileVP9Profile0 }, - // Four channels because this uses the AYUV format which has Alpha + // Four channels because this uses a format which has Alpha { FF_PROFILE_VP9_1, 8, 4, 0, 0, VAProfileVP9Profile1 }, { FF_PROFILE_VP9_2, 10, 3, 1, 1, VAProfileVP9Profile2 }, + // Four channels because this uses a format which has Alpha + { FF_PROFILE_VP9_3, 10, 4, 0, 0, VAProfileVP9Profile3 }, { FF_PROFILE_UNKNOWN } }; diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c index d82975979a..20fb36adfa 100644 --- a/libavcodec/vaapi_hevc.c +++ b/libavcodec/vaapi_hevc.c @@ -567,15 +567,24 @@ VAProfile ff_vaapi_parse_hevc_rext_profile(AVCodecContext *avctx) } #if VA_CHECK_VERSION(1, 2, 0) - if (!strcmp(profile->name, "Main 4:2:2 10") || + if (!strcmp(profile->name, "Main 12") || + !strcmp(profile->name, "Main 12 Intra")) + return VAProfileHEVCMain12; + else if (!strcmp(profile->name, "Main 4:2:2 10") || !strcmp(profile->name, "Main 4:2:2 10 Intra")) return VAProfileHEVCMain422_10; + else if (!strcmp(profile->name, "Main 4:2:2 12") || + !strcmp(profile->name, "Main 4:2:2 12 Intra")) + return VAProfileHEVCMain422_12; else if (!strcmp(profile->name, "Main 4:4:4") || !strcmp(profile->name, "Main 4:4:4 Intra")) return VAProfileHEVCMain444; else if (!strcmp(profile->name, "Main 4:4:4 10") || !strcmp(profile->name, "Main 4:4:4 10 Intra")) return VAProfileHEVCMain444_10; + else if (!strcmp(profile->name, "Main 4:4:4 12") || + !strcmp(profile->name, "Main 4:4:4 12 Intra")) + return VAProfileHEVCMain444_12; #else av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is " "not supported with this VA version.\n", profile->name); diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 2ee5145727..c3e79907fd 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -121,6 +121,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = { MAP(YUY2, YUV422, YUYV422, 0), #ifdef VA_FOURCC_Y210 MAP(Y210, YUV422_10, Y210, 0), +#endif +#ifdef VA_FOURCC_Y216 + MAP(Y216, YUV422_12, Y216, 0), #endif MAP(411P, YUV411, YUV411P, 0), MAP(422V, YUV422, YUV440P, 0), @@ -129,6 +132,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = { MAP(Y800, YUV400, GRAY8, 0), #ifdef VA_FOURCC_P010 MAP(P010, YUV420_10BPP, P010, 0), +#endif +#ifdef VA_FOURCC_P016 + MAP(P016, YUV420_12, P016, 0), #endif MAP(BGRA, RGB32, BGRA, 0), MAP(BGRX, RGB32, BGR0, 0), @@ -143,6 +149,12 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = { #ifdef VA_FOURCC_X2R10G10B10 MAP(X2R10G10B10, RGB32_10, X2RGB10, 0), #endif +#ifdef VA_FOURCC_Y410 + MAP(Y410, YUV444_10, Y410, 0), +#endif +#ifdef VA_FOURCC_Y416 + MAP(Y416, YUV444_12, Y416, 0), +#endif }; #undef MAP -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".