This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository ffmpeg.
The following commit(s) were added to refs/heads/master by this push:
new fd25b35dd2 vulkan_ffv1: support decoding 32-bit float video
fd25b35dd2 is described below
commit fd25b35dd2c0655754d912b6e85843c6ccdfd0c3
Author: Lynne <[email protected]>
AuthorDate: Wed Apr 22 12:54:09 2026 +0200
Commit: Lynne <[email protected]>
CommitDate: Mon May 11 05:32:41 2026 +0900
vulkan_ffv1: support decoding 32-bit float video
Sponsored-by: Sovereign Tech Fund
---
libavcodec/ffv1_vulkan.c | 2 +-
libavcodec/vulkan/ffv1_common.glsl | 16 ++---
libavcodec/vulkan/ffv1_dec.comp.glsl | 9 ++-
libavcodec/vulkan/ffv1_dec_setup.comp.glsl | 94 +++++++++++++++++++++++-------
libavcodec/vulkan/ffv1_enc_setup.comp.glsl | 2 +-
5 files changed, 89 insertions(+), 34 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 0133911319..8580a0777f 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;
+ i32vec4 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..82835e8f92 100644
--- a/libavcodec/vulkan/ffv1_dec.comp.glsl
+++ b/libavcodec/vulkan/ffv1_dec.comp.glsl
@@ -286,9 +286,12 @@ void writeout_rgb(uint slice_idx, in SliceContext sc,
ivec2 sp, int w, int y,
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..ff57c57dc3 100644
--- a/libavcodec/vulkan/ffv1_dec_setup.comp.glsl
+++ b/libavcodec/vulkan/ffv1_dec_setup.comp.glsl
@@ -23,7 +23,7 @@
#pragma shader_stage(compute)
#extension GL_GOOGLE_include_directive : require
-#define NB_CONTEXTS 2
+#define NB_CONTEXTS 6
#include "common.glsl"
#include "ffv1_common.glsl"
@@ -63,42 +63,92 @@ uint get_usymbol(const uint ctx_off)
return a;
}
+int get_isymbol(const uint ctx_off)
+{
+ if (get_rac(rc_state[ctx_off]))
+ return 0;
+
+ int e = 0;
+ while (get_rac(rc_state[ctx_off + 1 + min(e, 9)])) // 1..10
+ e++;
+
+ int a = 1;
+ for (int i = e - 1; i >= 0; i--) {
+ a <<= 1;
+ a |= int(get_rac(rc_state[ctx_off + 22 + min(i, 9)])); // 22..31
+ }
+
+ return get_rac(rc_state[ctx_off + 11 + min(e, 10)]) ? -a : a;
+}
+
+shared int mul[4096 + 1];
+
+int decode_current_mul(uint ctx_off, int mul_count, int64_t i)
+{
+ int ndx = int((i * int64_t(mul_count)) >> 32);
+ if (mul[ndx] < 0)
+ mul[ndx] = int(get_usymbol(ctx_off)) & 0x3FFFFFFF;
+ return mul[ndx];
+}
+
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;
int lu = 0;
[[unroll]]
- for (int i = 0; i < NB_CONTEXTS; i++)
- rc_state[i] = uint8_t(128);
+ for (int k = 0; k < NB_CONTEXTS*CONTEXT_SIZE; k++)
+ rc_state[k] = uint8_t(128);
- get_usymbol(0);
+ int mul_count = int(get_usymbol(0));
+ if (mul_count > 4096) {
+ sc.remap_count[p] = j;
+ return;
+ }
+ for (int mi = 0; mi < mul_count; mi++)
+ mul[mi] = -1;
+ mul[mul_count] = 1;
[[unroll]]
- for (int i = 0; i < NB_CONTEXTS*CONTEXT_SIZE; i++)
- rc_state[i] = uint8_t(128);
-
- for (uint i = 0; i <= end; ) {
- uint run = get_usymbol(lu*CONTEXT_SIZE);
- uint run0 = lu != 0 ? 0 : run;
- uint run1 = lu != 0 ? run : 1;
-
- i += run0;
- while (run1-- > 0) {
- if (i - 1 >= end)
+ for (int k = 0; k < NB_CONTEXTS*CONTEXT_SIZE; k++)
+ rc_state[k] = uint8_t(128);
+
+ int current_mul = 1;
+ int64_t i = 0;
+ while (i <= int64_t(end)) {
+ uint run = get_usymbol(uint(lu*3 + 0)*CONTEXT_SIZE);
+ uint run0 = lu != 0 ? 0u : run;
+ uint run1 = lu != 0 ? run : 1u;
+
+ i += int64_t(run0) * int64_t(current_mul);
+
+ while (run1 > 0u) {
+ run1--;
+ if (current_mul > 1) {
+ int delta = get_isymbol(uint(lu*3 + 1)*CONTEXT_SIZE);
+ if (delta <= -current_mul || delta > current_mul/2) {
+ sc.remap_count[p] = j;
+ return;
+ }
+ i += int64_t(current_mul - 1 + delta);
+ }
+ if (i - 1 >= int64_t(end))
break;
- fltmap[slice_idx][p][j++] = i ^ (((i & 0x8000) != 0) ? 0 :
flip);
+ uint iv = uint(i);
+ fltmap[slice_idx][p][j++] = iv ^ (((iv & flip_mask) != 0u) ?
0u : flip);
i++;
+ current_mul = decode_current_mul(uint(2)*CONTEXT_SIZE,
mul_count, i);
}
- if (lu > 0)
- i++;
- lu ^= int(run == 0);
+ if (lu != 0)
+ i += int64_t(current_mul);
+ lu ^= int(run == 0u);
}
- sc.remap_count[p] = uint16_t(j);
+ sc.remap_count[p] = j;
}
}
diff --git a/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
b/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
index e1b64a980c..53a8d7f13f 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] = int(j);
}
}
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]