PR #22885 opened by Lynne
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22885
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22885.patch

Thanks to the rewrite in February/March, it was much easier to built on top of.


>From 1943f5dacc4250490fe070448416bb3ec07936da Mon Sep 17 00:00:00 2001
From: Lynne <[email protected]>
Date: Wed, 22 Apr 2026 12:54:09 +0200
Subject: [PATCH] vulkan_ffv1: support decoding 32-bit float video

---
 libavcodec/ffv1_vulkan.c                   |  2 +-
 libavcodec/vulkan/ffv1_common.glsl         | 16 ++++++-----
 libavcodec/vulkan/ffv1_dec.comp.glsl       | 11 +++++---
 libavcodec/vulkan/ffv1_dec_setup.comp.glsl | 31 +++++++++++++++++-----
 libavcodec/vulkan/ffv1_enc_setup.comp.glsl |  2 +-
 5 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/libavcodec/ffv1_vulkan.c b/libavcodec/ffv1_vulkan.c
index 2a2226016f..73c2b2a7ce 100644
--- a/libavcodec/ffv1_vulkan.c
+++ b/libavcodec/ffv1_vulkan.c
@@ -41,7 +41,7 @@ void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, 
FFV1Context *f,
     }
 
     int bits = desc->comp[0].depth;
-    SPEC_LIST_ADD(sl,  5, 32, 1 << bits);
+    SPEC_LIST_ADD(sl,  5, 32, (uint32_t)(1ULL << bits));
     SPEC_LIST_ADD(sl,  6, 32, f->colorspace);
     SPEC_LIST_ADD(sl,  7, 32, f->transparency);
     SPEC_LIST_ADD(sl,  8, 32, ff_vk_mt_is_np_rgb(sw_format) &&
diff --git a/libavcodec/vulkan/ffv1_common.glsl 
b/libavcodec/vulkan/ffv1_common.glsl
index 2aad140bf2..f1f18d98a2 100644
--- a/libavcodec/vulkan/ffv1_common.glsl
+++ b/libavcodec/vulkan/ffv1_common.glsl
@@ -100,7 +100,7 @@ struct SliceContext {
     uint slice_coding_mode;
     bool slice_reset_contexts;
 
-    u16vec4 remap_count;
+    u32vec4 remap_count;
 
     /* Decoder-only */
     uint remap;
@@ -142,20 +142,22 @@ u16vec4 get_slice_bits(in SliceContext sc)
 #ifndef FLOAT
     return u16vec4(c_bits, c_bits, c_bits, c_bits);
 #else
-    u16vec4 bits = sc.remap_count;
+    u32vec4 cnt = sc.remap_count;
 #if defined(ENCODE)
     if (remap_mode == 0)
 #elif defined(DECODE)
     if (sc.remap == 0)
 #endif
-        bits = u16vec4(ivec4(rct_offset, rct_offset, rct_offset, rct_offset));
+        cnt = u32vec4(uint(rct_offset), uint(rct_offset),
+                      uint(rct_offset), uint(rct_offset));
 
+    u16vec4 bits = u16vec4(cnt);
     if (sc.slice_coding_mode == 0) {
-        uint16_t max3 = max(bits[0], max(bits[1], bits[2]));
+        uint max3 = max(cnt[0], max(cnt[1], cnt[2]));
         bits = u16vec4(ceil_log2(max3),
-                       ceil_log2(bits[0] + bits[1]),
-                       ceil_log2(bits[0] + bits[2]),
-                       bits[3]);
+                       ceil_log2(cnt[0] + cnt[1]),
+                       ceil_log2(cnt[0] + cnt[2]),
+                       ceil_log2(cnt[3]));
     }
 
     return bits;
diff --git a/libavcodec/vulkan/ffv1_dec.comp.glsl 
b/libavcodec/vulkan/ffv1_dec.comp.glsl
index 0877f699f2..a4ae553ca0 100644
--- a/libavcodec/vulkan/ffv1_dec.comp.glsl
+++ b/libavcodec/vulkan/ffv1_dec.comp.glsl
@@ -279,16 +279,19 @@ void writeout_rgb(uint slice_idx, in SliceContext sc, 
ivec2 sp, int w, int y,
 #ifdef FLOAT
             pix = transform_sample(pix, sc.slice_rct_coef, sc.remap_count[0]);
 #else
-            pix = transform_sample(pix, sc.slice_rct_coef, rct_offset);
+            pix = transform_sample(pix, sc.slice_rct_coef, uint(rct_offset));
 #endif
 
 #ifdef FLOAT
         pix = pix.gbra;
         vec4 pd;
         for (int i = 0; i < color_planes; i++) {
-            uint v = fltmap[slice_idx][i][pix[i] & (rct_offset - 1)];
-            float16_t vf = uint16BitsToFloat16(uint16_t(v));
-            pd[i] = float(vf);
+            uint mask = (1u << ceil_log2(sc.remap_count[i])) - 1u;
+            uint v = fltmap[slice_idx][i][uint(pix[i]) & mask];
+            if (c_bits >= 32)
+                pd[i] = uintBitsToFloat(v);
+            else
+                pd[i] = float(uint16BitsToFloat16(uint16_t(v)));
         }
         pd = pd.brga;
 
diff --git a/libavcodec/vulkan/ffv1_dec_setup.comp.glsl 
b/libavcodec/vulkan/ffv1_dec_setup.comp.glsl
index 7f9e6a28ae..6263cbfb74 100644
--- a/libavcodec/vulkan/ffv1_dec_setup.comp.glsl
+++ b/libavcodec/vulkan/ffv1_dec_setup.comp.glsl
@@ -65,8 +65,9 @@ uint get_usymbol(const uint ctx_off)
 
 void decode_remap(uint slice_idx, inout SliceContext sc)
 {
-    int end = rct_offset - 1;
-    int flip = sc.remap == 2 ? (end >> 1) : 0;
+    uint end = uint(rct_offset - 1);
+    uint flip_mask = end ^ (end >> 1);
+    uint flip = sc.remap == 2 ? (end >> 1) : 0;
 
     for (int p = 0; p < color_planes; p++) {
         int j = 0;
@@ -82,23 +83,39 @@ void decode_remap(uint slice_idx, inout SliceContext sc)
         for (int i = 0; i < NB_CONTEXTS*CONTEXT_SIZE; i++)
             rc_state[i] = uint8_t(128);
 
-        for (uint i = 0; i <= end; ) {
+        bool done = false;
+        uint i = 0;
+        while (!done) {
             uint run = get_usymbol(lu*CONTEXT_SIZE);
             uint run0 = lu != 0 ? 0   : run;
             uint run1 = lu != 0 ? run : 1;
 
+            if (run0 > end - i) {
+                done = true;
+                break;
+            }
             i += run0;
+
             while (run1-- > 0) {
-                if (i - 1 >= end)
+                fltmap[slice_idx][p][j++] = i ^ (((i & flip_mask) != 0) ? 0 : 
flip);
+                if (i == end) {
+                    done = true;
                     break;
-                fltmap[slice_idx][p][j++] = i ^ (((i & 0x8000) != 0) ? 0 : 
flip);
+                }
                 i++;
             }
-            if (lu > 0)
+            if (done)
+                break;
+            if (lu > 0) {
+                if (i == end) {
+                    done = true;
+                    break;
+                }
                 i++;
+            }
             lu ^= int(run == 0);
         }
-        sc.remap_count[p] = uint16_t(j);
+        sc.remap_count[p] = uint(j);
     }
 }
 
diff --git a/libavcodec/vulkan/ffv1_enc_setup.comp.glsl 
b/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
index e1b64a980c..216588e145 100644
--- a/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
+++ b/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
@@ -113,7 +113,7 @@ void encode_histogram_remap(uint slice_idx, inout 
SliceContext sc)
 
         if (run != 0)
             put_usymbol(run, lu*CONTEXT_SIZE);
-        sc.remap_count[p] = U16(j);
+        sc.remap_count[p] = U32(j);
     }
 }
 
-- 
2.52.0

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

Reply via email to