PR #23436 opened by Diego de Souza (ddesouza)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23436
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23436.patch

- Check B-frame ref mode capabilities via bitmask (EACH/MIDDLE/HIERARCHICAL)
- Expose b_ref_mode hierarchical option in AV1 encoder when supported

Signed-off-by: Eshed Ram <[email protected]>
Signed-off-by: Sergey Struzh <[email protected]>
Signed-off-by: Nathan Sala <[email protected]>
Signed-off-by: Diego de Souza <[email protected]>


>From 01d894d9771dc9726ccbd2ffc64d1986db05597e Mon Sep 17 00:00:00 2001
From: Diego de Souza <[email protected]>
Date: Thu, 5 Mar 2026 23:08:34 +0100
Subject: [PATCH] avcodec/nvenc: add AV1 hierarchical B-frame reference mode
 support

- Check B-frame ref mode capabilities via bitmask (EACH/MIDDLE/HIERARCHICAL)
- Expose b_ref_mode hierarchical option in AV1 encoder when supported

Signed-off-by: Eshed Ram <[email protected]>
Signed-off-by: Sergey Struzh <[email protected]>
Signed-off-by: Nathan Sala <[email protected]>
Signed-off-by: Diego de Souza <[email protected]>
---
 libavcodec/nvenc.c     | 22 +++++++++++++++++++++-
 libavcodec/nvenc.h     |  1 +
 libavcodec/nvenc_av1.c |  7 +++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 4c59034af7..8f78c7fe21 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -590,10 +590,30 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
 
 #ifdef NVENC_HAVE_BFRAME_REF_MODE
     tmp = (ctx->b_ref_mode >= 0) ? ctx->b_ref_mode : 
NV_ENC_BFRAME_REF_MODE_DISABLED;
+    switch (tmp) {
+    case NV_ENC_BFRAME_REF_MODE_DISABLED:
+    case NV_ENC_BFRAME_REF_MODE_EACH:
+    case NV_ENC_BFRAME_REF_MODE_MIDDLE:
+#ifdef NVENC_HAVE_AV1_HGOP_SUPPORT
+    case NV_ENC_BFRAME_REF_MODE_HIERARCHICAL:
+#endif
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Invalid b_ref_mode value %d\n", tmp);
+        return AVERROR(EINVAL);
+    }
     ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE);
-    if (tmp == NV_ENC_BFRAME_REF_MODE_EACH && ret != 1 && ret != 3) {
+    if (tmp == NV_ENC_BFRAME_REF_MODE_EACH && (ret & 0x1) == 0) {
         av_log(avctx, AV_LOG_WARNING, "Each B frame as reference is not 
supported\n");
         return AVERROR(ENOSYS);
+    } else if (tmp == NV_ENC_BFRAME_REF_MODE_MIDDLE && (ret & 0x2) == 0) {
+        av_log(avctx, AV_LOG_WARNING, "Middle B frames as references are not 
supported\n");
+        return AVERROR(ENOSYS);
+#ifdef NVENC_HAVE_AV1_HGOP_SUPPORT
+    } else if (tmp == NV_ENC_BFRAME_REF_MODE_HIERARCHICAL && (ret & 0x4) == 0) 
{
+        av_log(avctx, AV_LOG_WARNING, "Hierarchical B frames as references are 
not supported\n");
+        return AVERROR(ENOSYS);
+#endif
     } else if (tmp != NV_ENC_BFRAME_REF_MODE_DISABLED && ret == 0) {
         av_log(avctx, AV_LOG_WARNING, "B frames as references are not 
supported\n");
         return AVERROR(ENOSYS);
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 46f1d9f4c4..32d4648f75 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -114,6 +114,7 @@ typedef void ID3D11Device;
 // SDK 13.1 compile time feature checks
 #if NVENCAPI_CHECK_VERSION(13, 1)
 #define NVENC_NEW_COUNTING_TYPE
+#define NVENC_HAVE_AV1_HGOP_SUPPORT
 #endif
 
 typedef struct NvencSurface
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 98fcc76e39..9f77dc2d92 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -140,10 +140,17 @@ static const AVOption options[] = {
     { "aq-strength",  "When Spatial AQ is enabled, this field is used to 
specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive)",
                                                             
OFFSET(aq_strength),  AV_OPT_TYPE_INT,   { .i64 = 8 }, 1, 15, VE },
     { "weighted_pred","Enable weighted prediction",         
OFFSET(weighted_pred),AV_OPT_TYPE_BOOL,  { .i64 = 0 }, 0, 1, VE },
+#ifdef NVENC_HAVE_AV1_HGOP_SUPPORT
+    { "b_ref_mode",   "Use B frames as references",         
OFFSET(b_ref_mode),   AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 
NV_ENC_BFRAME_REF_MODE_HIERARCHICAL, VE, .unit = "b_ref_mode" },
+#else
     { "b_ref_mode",   "Use B frames as references",         
OFFSET(b_ref_mode),   AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 
NV_ENC_BFRAME_REF_MODE_MIDDLE, VE, .unit = "b_ref_mode" },
+#endif
     { "disabled",     "B frames will not be used for reference", 0,            
   AV_OPT_TYPE_CONST, { .i64 = NV_ENC_BFRAME_REF_MODE_DISABLED }, 0, 0, VE, 
.unit = "b_ref_mode" },
     { "each",         "Each B frame will be used for reference", 0,            
   AV_OPT_TYPE_CONST, { .i64 = NV_ENC_BFRAME_REF_MODE_EACH }, 0, 0, VE, .unit = 
"b_ref_mode" },
     { "middle",       "Every other B-frame as Altref2 reference, except last 
in Altref interval", 0, AV_OPT_TYPE_CONST, { .i64 = 
NV_ENC_BFRAME_REF_MODE_MIDDLE }, 0, 0, VE, .unit = "b_ref_mode" },
+#ifdef NVENC_HAVE_AV1_HGOP_SUPPORT
+    { "hierarchical", "B frames are used as references in a hierarchical 
manner", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_BFRAME_REF_MODE_HIERARCHICAL }, 
0, 0, VE, .unit = "b_ref_mode" },
+#endif
     { "dpb_size",     "Specifies the DPB size used for encoding (0 means 
automatic)",
                                                             OFFSET(dpb_size),  
   AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, VE },
     { "ldkfs",        "Low delay key frame scale; Specifies the Scene Change 
frame size increase allowed in case of single frame VBV and CBR",
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to