PR #23860 opened by David Rosca (nowrep)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23860
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23860.patch

# Summary of changes

Fixes auto detect of level when not specified. Also fixes using level and tier 
options, which were previously ignored.

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->



>From df174aa52764330786197b95d72e79cdfb51c17e Mon Sep 17 00:00:00 2001
From: David Rosca <[email protected]>
Date: Mon, 20 Jul 2026 15:39:40 +0200
Subject: [PATCH 1/2] avcodec/vulkan_encode_av1: fix level auto-detection using
 zero dimensions

Move level guessing from init_profile() to init_sequence_headers(),
where base_ctx->surface_width/height are already initialized.

init_profile() is called from ff_vulkan_encode_init() before the
surface dimensions are set, so ff_av1_guess_level() always received
zeros and selected the lowest level (2.0). init_sequence_headers()
runs after ff_vulkan_encode_init() returns, matching how H.264 and
H.265 Vulkan encoders handle level detection.

Co-Authored-By: Claude Opus 4
---
 libavcodec/vulkan_encode_av1.c | 50 ++++++++++++++++------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/libavcodec/vulkan_encode_av1.c b/libavcodec/vulkan_encode_av1.c
index 1f38e691f1..994fc33cc1 100644
--- a/libavcodec/vulkan_encode_av1.c
+++ b/libavcodec/vulkan_encode_av1.c
@@ -593,7 +593,6 @@ static int init_profile(AVCodecContext *avctx,
     FFVulkanEncodeContext *ctx = &enc->common;
     FFVulkanContext *s = &ctx->s;
     FFVulkanFunctions *vk = &ctx->s.vkfn;
-    FFHWBaseEncodeContext *base_ctx = &ctx->base;
 
     VkVideoEncodeAV1CapabilitiesKHR av1_caps = {
         .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
@@ -631,31 +630,6 @@ static int init_profile(AVCodecContext *avctx,
     };
     profile->pNext = &enc->profile;
 
-    /* Set level */
-    if (avctx->level == AV_LEVEL_UNKNOWN) {
-        const AV1LevelDescriptor *level;
-        float framerate = 0.0;
-
-        if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
-            framerate = av_q2d(avctx->framerate);
-
-        level = ff_av1_guess_level(avctx->bit_rate, enc->seq_tier,
-                                   base_ctx->surface_width, 
base_ctx->surface_height,
-                                   enc->tile_rows * enc->tile_cols,
-                                   enc->tile_cols, framerate);
-        if (level) {
-            av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
-            enc->seq_level_idx = level->level_idx;
-        } else {
-            av_log(avctx, AV_LOG_VERBOSE, "Stream will not conform to "
-                   "any normal level, using level 7.3 by default.\n");
-            enc->seq_level_idx = STD_VIDEO_AV1_LEVEL_7_3;
-            enc->seq_tier = 1;
-        }
-    } else {
-        enc->seq_level_idx = ff_vk_av1_level_to_vk(avctx->level);
-    }
-
     /* User has explicitly specified a profile. */
     if (avctx->profile != AV_PROFILE_UNKNOWN)
         return 0;
@@ -750,6 +724,30 @@ static av_cold int init_sequence_headers(AVCodecContext 
*avctx)
     if (!desc)
         return AVERROR(EINVAL);
 
+    if (avctx->level == AV_LEVEL_UNKNOWN) {
+        const AV1LevelDescriptor *level;
+        float framerate = 0.0;
+
+        if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
+            framerate = av_q2d(avctx->framerate);
+
+        level = ff_av1_guess_level(avctx->bit_rate, enc->seq_tier,
+                                   base_ctx->surface_width, 
base_ctx->surface_height,
+                                   enc->tile_rows * enc->tile_cols,
+                                   enc->tile_cols, framerate);
+        if (level) {
+            av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
+            enc->seq_level_idx = level->level_idx;
+        } else {
+            av_log(avctx, AV_LOG_VERBOSE, "Stream will not conform to "
+                   "any normal level, using level 7.3 by default.\n");
+            enc->seq_level_idx = STD_VIDEO_AV1_LEVEL_7_3;
+            enc->seq_tier = 1;
+        }
+    } else {
+        enc->seq_level_idx = ff_vk_av1_level_to_vk(avctx->level);
+    }
+
     seq_obu->header.obu_type = AV1_OBU_SEQUENCE_HEADER;
     *seq = (AV1RawSequenceHeader) {
         .seq_profile = avctx->profile,
-- 
2.52.0


>From 4daca1c115abfbe551240403d2b4c4f001ce76f2 Mon Sep 17 00:00:00 2001
From: David Rosca <[email protected]>
Date: Mon, 20 Jul 2026 15:45:52 +0200
Subject: [PATCH 2/2] avcodec/vulkan_encode_av1: fix level and tier option
 handling

Copy opts.level into avctx->level (matching H.264/H.265 encoders),
so the -level command line option is actually used. Also initialize
enc->seq_tier from opts.tier so the -tier option takes effect.

The -level option values (0-23) already match the StdVideoAV1Level
enum directly, so assign avctx->level to seq_level_idx without going
through ff_vk_av1_level_to_vk() which expects AV1 spec-style level
numbers (20, 21, 30, ...).

Co-Authored-By: Claude Opus 4
---
 libavcodec/vulkan_encode_av1.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavcodec/vulkan_encode_av1.c b/libavcodec/vulkan_encode_av1.c
index 994fc33cc1..bb6a1ae04d 100644
--- a/libavcodec/vulkan_encode_av1.c
+++ b/libavcodec/vulkan_encode_av1.c
@@ -724,6 +724,8 @@ static av_cold int init_sequence_headers(AVCodecContext 
*avctx)
     if (!desc)
         return AVERROR(EINVAL);
 
+    enc->seq_tier = enc->common.opts.tier;
+
     if (avctx->level == AV_LEVEL_UNKNOWN) {
         const AV1LevelDescriptor *level;
         float framerate = 0.0;
@@ -745,7 +747,7 @@ static av_cold int init_sequence_headers(AVCodecContext 
*avctx)
             enc->seq_tier = 1;
         }
     } else {
-        enc->seq_level_idx = ff_vk_av1_level_to_vk(avctx->level);
+        enc->seq_level_idx = avctx->level;
     }
 
     seq_obu->header.obu_type = AV1_OBU_SEQUENCE_HEADER;
@@ -1229,6 +1231,8 @@ static av_cold int vulkan_encode_av1_init(AVCodecContext 
*avctx)
 
     if (avctx->profile == AV_PROFILE_UNKNOWN)
         avctx->profile = enc->common.opts.profile;
+    if (avctx->level == AV_LEVEL_UNKNOWN)
+        avctx->level = enc->common.opts.level;
 
     enc->caps = (VkVideoEncodeAV1CapabilitiesKHR) {
         .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_CAPABILITIES_KHR,
-- 
2.52.0

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

Reply via email to