PR #23162 opened by Timo Rothenpieler (BtbN) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23162 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23162.patch
Last time this was attempted, it failed because nvenc did not properly write the second SPS/PPS/... with the information about the alpha layer. Maybe this is fixed now, so time for another attempt. >From e5adb5249f70bb6832324e573bdff09e2218bcba Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler <[email protected]> Date: Mon, 14 Nov 2022 23:10:34 +0100 Subject: [PATCH] avcodec/nvenc: add hevc alpha channel support --- libavcodec/nvenc.c | 37 +++++++++++++++++++++++++++++++++++++ libavcodec/nvenc.h | 7 +++++++ libavcodec/nvenc_hevc.c | 4 ++++ 3 files changed, 48 insertions(+) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e9ca6e01fd..9037a73691 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -69,6 +69,7 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { #endif AV_PIX_FMT_YUV444P10MSB, AV_PIX_FMT_YUV444P16, // Truncated to 10bits + AV_PIX_FMT_VUYA, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_0BGR32, @@ -119,6 +120,7 @@ const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = { pix_fmt == AV_PIX_FMT_GBRP || \ pix_fmt == AV_PIX_FMT_GBRP10MSB || \ pix_fmt == AV_PIX_FMT_GBRP16 || \ + (!ctx->use_alpha && pix_fmt == AV_PIX_FMT_VUYA) || \ (ctx->rgb_mode == NVENC_RGB_MODE_444 && IS_RGB(pix_fmt))) #define IS_YUV422(pix_fmt) (pix_fmt == AV_PIX_FMT_NV16 || \ @@ -688,6 +690,29 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) } #endif + if (ctx->use_alpha) { +#ifdef NVENC_HAVE_ALPHA_SUPPORT + ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_ALPHA_LAYER_ENCODING); +#else + ret = 0; +#endif + if (!ret) { + av_log(avctx, AV_LOG_WARNING, "Alpha layer encoding not supported by the device\n"); + return AVERROR(ENOSYS); + } + + if (ctx->data_pix_fmt != AV_PIX_FMT_RGB32 && ctx->data_pix_fmt != AV_PIX_FMT_BGR32 && + ctx->data_pix_fmt != AV_PIX_FMT_VUYA) { + av_log(avctx, AV_LOG_WARNING, "Alpha channel encoding is only supported for 8 bit ARGB/BGRA/VUYA formats\n"); + return AVERROR(EINVAL); + } + + if (ctx->weighted_pred) { + av_log(avctx, AV_LOG_WARNING, "Alpha channel encoding is not supported with weighted prediction\n"); + return AVERROR(EINVAL); + } + } + return 0; } @@ -1272,6 +1297,11 @@ static av_cold int nvenc_setup_rate_control(AVCodecContext *avctx) ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; } +#ifdef NVENC_HAVE_ALPHA_SUPPORT + if (ctx->alpha_ratio > 0) + ctx->encode_config.rcParams.alphaLayerBitrateRatio = ctx->alpha_ratio; +#endif + return 0; } @@ -1666,6 +1696,11 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx) } #endif +#ifdef NVENC_HAVE_ALPHA_SUPPORT + if (ctx->use_alpha) + hevc->enableAlphaLayerEncoding = 1; +#endif + return 0; } @@ -2025,6 +2060,8 @@ static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt) case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUV444P10MSB: return NV_ENC_BUFFER_FORMAT_YUV444_10BIT; + case AV_PIX_FMT_VUYA: + return NV_ENC_BUFFER_FORMAT_AYUV; case AV_PIX_FMT_0RGB32: case AV_PIX_FMT_RGB32: return NV_ENC_BUFFER_FORMAT_ARGB; diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 069ba82bc9..a8623b44eb 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -73,6 +73,11 @@ typedef void ID3D11Device; #define NVENC_HAVE_HEVC_CONSTRAINED_ENCODING #endif +// SDK 11.0 compile time feature checks +#if NVENCAPI_CHECK_VERSION(11, 0) +#define NVENC_HAVE_ALPHA_SUPPORT +#endif + // SDK 11.1 compile time feature checks #if NVENCAPI_CHECK_VERSION(11, 1) #define NVENC_HAVE_QP_CHROMA_OFFSETS @@ -321,6 +326,8 @@ typedef struct NvencContext int cbr_padding; int multiview, multiview_supported; int display_sei_sent; + int use_alpha; + int alpha_ratio; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 31624f45b1..0f0c0392f7 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -244,6 +244,10 @@ static const AVOption options[] = { { "4", "Enabled with number of horizontal strips forced to 4 when number of NVENCs > 3", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_SPLIT_FOUR_FORCED_MODE }, 0, 0, VE, .unit = "split_encode_mode" }, #endif #endif + { "alpha", "Enable encoding of alpha layer (ARGB/BGRA/VUYA input only)", + OFFSET(use_alpha), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "alpha_ratio", "Bitrate allocation ratio, n:1 between base and alpha layer", + OFFSET(alpha_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { NULL } }; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
