vcomp/lavc: nvenc no intra-refresh for HEVC/AV1

Since the pulsation issue, it was not much usable, anyways and this
clean-ups the code a bit.

Also the behavior will be now more deterministic - it behaved differently
with patched FFmpeg (most likely GH Linux builds), othewrise differntly.

+ enable the header-inserter if user expliclty requesetd intra-refresh

refers to GH-114
This commit is contained in:
Martin Pulec
2025-06-19 08:44:35 +02:00
parent d9936aac5a
commit 83289a5fb7
2 changed files with 32 additions and 74 deletions

View File

@@ -1,53 +0,0 @@
From 2bd65325dc20ad1ea3111e8a8b8328224fd9ee0a Mon Sep 17 00:00:00 2001
From: Martin Pulec <martin.pulec@cesnet.cz>
Date: Mon, 24 Jul 2023 16:15:29 +0200
Subject: [PATCH] NVENC_INFINITE_GOPLENGTH is useless for UltraGrid (updated)
---
libavcodec/avcodec.h | 3 +++
libavcodec/nvenc.c | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fe41ecc3c9..15bc1f5cec 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3270,4 +3270,7 @@ int avcodec_is_open(AVCodecContext *s);
* @}
*/
+// UltraGrid patch
+#define PATCHED_FF_NVENC_NO_INFINITE_GOP 1
+
#endif /* AVCODEC_AVCODEC_H */
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 0b6417674e..70adc26f08 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1173,7 +1173,6 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
h264->enableIntraRefresh = 1;
h264->intraRefreshPeriod = cc->gopLength;
h264->intraRefreshCnt = cc->gopLength - 1;
- cc->gopLength = NVENC_INFINITE_GOPLENGTH;
#ifdef NVENC_HAVE_SINGLE_SLICE_INTRA_REFRESH
h264->singleSliceIntraRefresh = ctx->single_slice_intra_refresh;
#endif
@@ -1294,7 +1293,6 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
hevc->enableIntraRefresh = 1;
hevc->intraRefreshPeriod = cc->gopLength;
hevc->intraRefreshCnt = cc->gopLength - 1;
- cc->gopLength = NVENC_INFINITE_GOPLENGTH;
#ifdef NVENC_HAVE_SINGLE_SLICE_INTRA_REFRESH
hevc->singleSliceIntraRefresh = ctx->single_slice_intra_refresh;
#endif
@@ -1409,7 +1407,6 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
av1->enableIntraRefresh = 1;
av1->intraRefreshPeriod = cc->gopLength;
av1->intraRefreshCnt = cc->gopLength - 1;
- cc->gopLength = NVENC_INFINITE_GOPLENGTH;
}
av1->idrPeriod = cc->gopLength;
--
2.41.0

View File

@@ -3,7 +3,7 @@
* @author Martin Pulec <pulec@cesnet.cz>
*/
/*
* Copyright (c) 2013-2024 CESNET, z. s. p. o.
* Copyright (c) 2013-2025 CESNET
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -1792,19 +1792,38 @@ static void configure_nvenc(AVCodecContext *codec_ctx, struct setparam_param *pa
}
}
set_forced_idr(codec_ctx, 1);
#ifdef PATCHED_FF_NVENC_NO_INFINITE_GOP
const bool patched_ff = true;
#else
const bool patched_ff = false;
if (param->periodic_intra != 0) {
LOG(LOG_LEVEL_WARNING) << MOD_NAME "FFmpeg not patched, " << (param->periodic_intra != 1 ? "not " : "") << "enabling Intra Refresh.\n";
check_av_opt_set(codec_ctx->priv_data, "forced-idr", 1);
const bool h264 = codec_ctx->codec_id == AV_CODEC_ID_H264;
const bool hevc = codec_ctx->codec_id == AV_CODEC_ID_HEVC;
if (!h264) {
if (param->periodic_intra == 1) {
if (hevc) {
MSG(WARNING,
"Requeseted intra-refresh for NVENC "
"HEVC but there may occur artifacts!\n");
} else {
MSG(WARNING,
"Requeseted intra-refresh for NVENC "
"AV1 but it won't most likely work with UG "
"because of NVENC_INFINITE_GOPLENGTH!\n");
}
}
if (param->periodic_intra == -1) {
MSG(WARNING,
"Intra-refresh won't be enabled for NVENC "
"HEVC/AV1, bitrate variance will be higher!\n");
}
}
#endif
if ((patched_ff && param->periodic_intra != 0) || param->periodic_intra == 1) {
incomp_feature_warn(INCOMP_INTRA_REFRESH, param->periodic_intra);
check_av_opt_set<int>(codec_ctx->priv_data, "intra-refresh", 1);
if ((h264 && param->periodic_intra != 0) ||
param->periodic_intra == 1) {
if (param->header_inserter_req == -1) {
MSG(INFO,
"Auto-enabling header inserter for %s when "
"intra-refresh used.\n", codec_ctx->codec->name);
param->header_inserter_req = 1;
}
param->periodic_intra = 1;
}
check_av_opt_set<const char *>(codec_ctx->priv_data, "rc", DEFAULT_NVENC_RC);
@@ -1817,14 +1836,6 @@ static void configure_nvenc(AVCodecContext *codec_ctx, struct setparam_param *pa
double lavc_rc_buffer_size_factor = DEFAULT_NVENC_RC_BUF_SIZE_FACTOR;
if (const char *val = get_commandline_param("lavc-rc-buffer-size-factor")) {
lavc_rc_buffer_size_factor = stof(val);
} else {
LOG(LOG_LEVEL_WARNING)
<< MOD_NAME
"To reduce NVENC pulsation, you can try \"--param "
"lavc-rc-buffer-size-factor=0\""
" or a small number. 0 or higher value (than default "
<< DEFAULT_NVENC_RC_BUF_SIZE_FACTOR
<< ") may cause frame drops on receiver.\n";
}
codec_ctx->rc_buffer_size =
(int) ((double) codec_ctx->rc_max_rate / param->desc.fps *