This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit b2128d4c6ba19a299ceda380a5a2a1b5fd1077d2 Author: Lynne <[email protected]> AuthorDate: Wed Sep 23 08:39:03 2026 +0900 Commit: Lynne <[email protected]> CommitDate: Thu Sep 24 11:05:24 2026 +0900 proresenc_kostya_vulkan: fix constant quantizer mode The estimate stored its results at index 0, where the tables held the constant quantizer's matrix, but the encoder looked both up at the quantizer itself. The slice sizes never matched the coded slices, and below 16 every coefficient was divided by an empty matrix. Fill the tables with every quantizer's matrix, estimate with the constant quantizer while keeping index 0, and skip the overquant search. --- libavcodec/proresenc_kostya_vulkan.c | 16 ++++++---------- libavcodec/vulkan/prores_ks_encode_slice.comp.glsl | 3 ++- libavcodec/vulkan/prores_ks_estimate_slice.comp.glsl | 7 +++++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libavcodec/proresenc_kostya_vulkan.c b/libavcodec/proresenc_kostya_vulkan.c index c07bca1426..ff4df910c5 100644 --- a/libavcodec/proresenc_kostya_vulkan.c +++ b/libavcodec/proresenc_kostya_vulkan.c @@ -253,7 +253,7 @@ static int init_estimate_slice_pipeline(ProresVulkanContext *pv, FFVulkanShader* pv->estimate_slices_per_wg = dim_x / pv->ctx.num_planes; - SPEC_LIST_CREATE(sl, 8, 8 * sizeof(uint32_t)) + SPEC_LIST_CREATE(sl, 9, 9 * sizeof(uint32_t)) SPEC_LIST_ADD(sl, 0, 32, pv->ctx.mbs_per_slice); SPEC_LIST_ADD(sl, 1, 32, pv->ctx.chroma_factor); SPEC_LIST_ADD(sl, 2, 32, pv->ctx.alpha_bits); @@ -262,6 +262,7 @@ static int init_estimate_slice_pipeline(ProresVulkanContext *pv, FFVulkanShader* SPEC_LIST_ADD(sl, 5, 32, pv->ctx.force_quant ? 0 : pv->ctx.profile_info->min_quant); SPEC_LIST_ADD(sl, 6, 32, pv->ctx.force_quant ? 0 : pv->ctx.profile_info->max_quant); SPEC_LIST_ADD(sl, 7, 32, pv->ctx.bits_per_mb); + SPEC_LIST_ADD(sl, 8, 32, pv->ctx.force_quant); ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl, (uint32_t []) { dim_x, 1, 1 }, required ? dim_x : 0); @@ -346,13 +347,14 @@ static int init_encode_slice_pipeline(ProresVulkanContext *pv, FFVulkanShader* s FFVulkanContext *vkctx = &pv->vkctx; FFVulkanDescriptorSetBinding *desc; - SPEC_LIST_CREATE(sl, 6, 6 * sizeof(uint32_t)) + SPEC_LIST_CREATE(sl, 7, 7 * sizeof(uint32_t)) SPEC_LIST_ADD(sl, 0, 32, pv->ctx.mbs_per_slice); SPEC_LIST_ADD(sl, 1, 32, pv->ctx.chroma_factor); SPEC_LIST_ADD(sl, 2, 32, pv->ctx.alpha_bits); SPEC_LIST_ADD(sl, 3, 32, pv->ctx.num_planes); SPEC_LIST_ADD(sl, 4, 32, pv->ctx.slices_per_picture); - SPEC_LIST_ADD(sl, 5, 32, pv->ctx.force_quant ? pv->ctx.force_quant : pv->ctx.profile_info->max_quant); + SPEC_LIST_ADD(sl, 5, 32, pv->ctx.profile_info->max_quant); + SPEC_LIST_ADD(sl, 6, 32, pv->ctx.force_quant); ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl, (uint32_t []) { 64, 1, 1 }, 0); @@ -1066,13 +1068,7 @@ static av_cold int encode_init(AVCodecContext *avctx) VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)); RET(ff_vk_map_buffer(vkctx, &pv->prores_data_tables_buf, (void *)&pv->tables, 0)); - for (q = 0; q < MAX_STORED_Q; ++q) { - for (i = 0; i < 64; i++) { - pv->tables->qmat[q][i] = ctx->quants[q][ctx->scantable[i]]; - pv->tables->qmat_chroma[q][i] = ctx->quants_chroma[q][ctx->scantable[i]]; - } - } - for (q = MAX_STORED_Q; q < 128; ++q) { + for (q = 0; q < 128; ++q) { for (i = 0; i < 64; i++) { pv->tables->qmat[q][i] = ctx->quant_mat[ctx->scantable[i]] * q; pv->tables->qmat_chroma[q][i] = ctx->quant_chroma_mat[ctx->scantable[i]] * q; diff --git a/libavcodec/vulkan/prores_ks_encode_slice.comp.glsl b/libavcodec/vulkan/prores_ks_encode_slice.comp.glsl index a974e51d9e..c3f3c7b8f2 100644 --- a/libavcodec/vulkan/prores_ks_encode_slice.comp.glsl +++ b/libavcodec/vulkan/prores_ks_encode_slice.comp.glsl @@ -32,6 +32,7 @@ layout (constant_id = 2) const int alpha_bits = 0; layout (constant_id = 3) const int num_planes = 0; layout (constant_id = 4) const int slices_per_picture = 0; layout (constant_id = 5) const int max_quant = 0; +layout (constant_id = 6) const int force_quant = 0; struct SliceData { uint32_t mbs_per_slice; @@ -242,7 +243,7 @@ void main() uint plane = gl_GlobalInvocationID.y; int q = scores[slice].quant; - int q_idx = min(q, max_quant + 1); + int q_idx = force_quant != 0 ? 0 : min(q, max_quant + 1); ivec4 bits = scores[slice].bits[q_idx]; int slice_hdr_size = 2 * num_planes; int slice_size = slice_hdr_size + ((bits.x + bits.y + bits.z + bits.w) / 8); diff --git a/libavcodec/vulkan/prores_ks_estimate_slice.comp.glsl b/libavcodec/vulkan/prores_ks_estimate_slice.comp.glsl index be0f95a9bd..28807c5186 100644 --- a/libavcodec/vulkan/prores_ks_estimate_slice.comp.glsl +++ b/libavcodec/vulkan/prores_ks_estimate_slice.comp.glsl @@ -37,6 +37,7 @@ layout (constant_id = 4) const int slices_per_picture = 0; layout (constant_id = 5) const int min_quant = 0; layout (constant_id = 6) const int max_quant = 0; layout (constant_id = 7) const int bits_per_mb = 0; +layout (constant_id = 8) const int force_quant = 0; struct SliceData { uint32_t mbs_per_slice; @@ -242,6 +243,8 @@ void main() [[maximally_reconverges]] uint slice = gl_WorkGroupID.x * slices_per_wg + gl_LocalInvocationID.x / num_planes; uint plane = gl_LocalInvocationID.x % num_planes; uint q = min_quant + gl_GlobalInvocationID.y; + /* A constant quantiser is estimated once, and stored at index 0 */ + uint quant = force_quant != 0 ? uint(force_quant) : q; if (gl_LocalInvocationID.x >= slices_per_wg * num_planes || slice >= slices_per_picture) return; @@ -251,7 +254,7 @@ void main() [[maximally_reconverges]] if (plane == 3) bits = estimate_alpha_plane(slice); else - bits = estimate_slice_plane(error, slice, plane, q); + bits = estimate_slice_plane(error, slice, plane, quant); /* Write results to score buffer */ scores[slice].bits[q][plane] = FFALIGN(bits, 8); @@ -275,7 +278,7 @@ void main() [[maximally_reconverges]] scores[slice].total_bits[q] = total_bits; scores[slice].total_score[q] = total_score; - if (q != max_quant) + if (force_quant != 0 || q != max_quant) return; /* Task threads that computed max_quant to also compute overquant if necessary */ -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
