mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-09 14:14:39 +02:00
avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC
This commit extends the support for Temporal Filtering in NVENC for AV1 and H.264 codecs. For natural videos with noise, NVENC temporal filtering improves video coding efficiency by 4-5%. Signed-off-by: Diego de Souza <ddesouza@nvidia.com> Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
parent
ed80e55586
commit
a583f7e2fd
@ -627,7 +627,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
#ifdef NVENC_HAVE_TEMPORAL_FILTER
|
||||
#if defined(NVENC_HAVE_TEMPORAL_FILTER) || defined(NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER)
|
||||
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_TEMPORAL_FILTER);
|
||||
if(ctx->tf_level > 0 && ret <= 0) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Temporal filtering not supported by the device\n");
|
||||
@ -1383,6 +1383,25 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
|
||||
h264->numRefL1 = avctx->refs;
|
||||
#endif
|
||||
|
||||
#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
|
||||
if (ctx->tf_level >= 0) {
|
||||
h264->tfLevel = ctx->tf_level;
|
||||
|
||||
switch (ctx->tf_level)
|
||||
{
|
||||
case NV_ENC_TEMPORAL_FILTER_LEVEL_0:
|
||||
case NV_ENC_TEMPORAL_FILTER_LEVEL_4:
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid temporal filtering level.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (ctx->encode_config.frameIntervalP < 5)
|
||||
av_log(avctx, AV_LOG_WARNING, "Temporal filtering needs at least 4 B-Frames (-bf 4).\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1608,6 +1627,25 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
|
||||
av1->numFwdRefs = avctx->refs;
|
||||
av1->numBwdRefs = avctx->refs;
|
||||
|
||||
#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
|
||||
if (ctx->tf_level >= 0) {
|
||||
av1->tfLevel = ctx->tf_level;
|
||||
|
||||
switch (ctx->tf_level)
|
||||
{
|
||||
case NV_ENC_TEMPORAL_FILTER_LEVEL_0:
|
||||
case NV_ENC_TEMPORAL_FILTER_LEVEL_4:
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid temporal filtering level.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (ctx->encode_config.frameIntervalP < 5)
|
||||
av_log(avctx, AV_LOG_WARNING, "Temporal filtering needs at least 4 B-Frames (-bf 4).\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -98,6 +98,7 @@ typedef void ID3D11Device;
|
||||
#define NVENC_HAVE_H264_10BIT_SUPPORT
|
||||
#define NVENC_HAVE_422_SUPPORT
|
||||
#define NVENC_HAVE_AV1_UHQ_TUNING
|
||||
#define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
|
||||
#endif
|
||||
|
||||
typedef struct NvencSurface
|
||||
|
@ -152,6 +152,12 @@ static const AVOption options[] = {
|
||||
OFFSET(extra_sei), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
|
||||
{ "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
|
||||
{ "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
|
||||
#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
|
||||
{ "tf_level", "Specifies the strength of the temporal filtering",
|
||||
OFFSET(tf_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
|
||||
{ "0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_0 }, 0, 0, VE, .unit = "tf_level" },
|
||||
{ "4", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_4 }, 0, 0, VE, .unit = "tf_level" },
|
||||
#endif
|
||||
#ifdef NVENC_HAVE_LOOKAHEAD_LEVEL
|
||||
{ "lookahead_level", "Specifies the lookahead level. Higher level may improve quality at the expense of performance.",
|
||||
OFFSET(lookahead_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT, VE, .unit = "lookahead_level" },
|
||||
|
@ -224,6 +224,12 @@ static const AVOption options[] = {
|
||||
OFFSET(max_slice_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
|
||||
{ "constrained-encoding", "Enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices",
|
||||
OFFSET(constrained_encoding), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
|
||||
#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
|
||||
{ "tf_level", "Specifies the strength of the temporal filtering",
|
||||
OFFSET(tf_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
|
||||
{ "0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_0 }, 0, 0, VE, .unit = "tf_level" },
|
||||
{ "4", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_4 }, 0, 0, VE, .unit = "tf_level" },
|
||||
#endif
|
||||
#ifdef NVENC_HAVE_LOOKAHEAD_LEVEL
|
||||
{ "lookahead_level", "Specifies the lookahead level. Higher level may improve quality at the expense of performance.",
|
||||
OFFSET(lookahead_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT, VE, .unit = "lookahead_level" },
|
||||
|
Loading…
x
Reference in New Issue
Block a user