From 0da8f2f4eea877d234cbc88fa394ddfa028ffa94 Mon Sep 17 00:00:00 2001 From: Lynne Date: Sun, 2 Aug 2026 06:30:59 +0900 Subject: [PATCH] vulkan_encode_av1: set primary_ref_frame to a reference name, not a slot primary_ref_frame is an index into the seven reference names, but the code assigned it the reference's DPB slot. The two coincide only while the reference sits in slot 0; once it rotates to slot 1, referenceNameSlotIndices[primary_ref_frame] is -1, which is invalid, and NVIDIA drivers lose the device. Inherited from vaapi_encode_av1, where the same confusion is harmless as the raw frame header maps every reference name to the same slot. Have set_name_slot() return the name it picked and use that. Fixes #20540. --- libavcodec/vulkan_encode_av1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/vulkan_encode_av1.c b/libavcodec/vulkan_encode_av1.c index bb6a1ae04d..67d81d189b 100644 --- a/libavcodec/vulkan_encode_av1.c +++ b/libavcodec/vulkan_encode_av1.c @@ -159,7 +159,7 @@ static int init_pic_rc(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, return 0; } -static void set_name_slot(int slot, int *slot_indices, uint32_t allowed_idx, int group) +static int set_name_slot(int slot, int *slot_indices, uint32_t allowed_idx, int group) { int from = group ? AV1_REF_FRAME_GOLDEN : 0; int to = group ? AV1_REFS_PER_FRAME : AV1_REF_FRAME_GOLDEN; @@ -167,7 +167,7 @@ static void set_name_slot(int slot, int *slot_indices, uint32_t allowed_idx, int for (int i = from; i < to; i++) { if ((slot_indices[i] == -1) && (allowed_idx & (1 << i))) { slot_indices[i] = slot; - return; + return i; } } @@ -377,12 +377,12 @@ static int init_pic_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, for (int i = 0; i < AV1_REFS_PER_FRAME; i++) ap->av1pic_info.ref_frame_idx[i] = ap_ref->slot; - ap->av1pic_info.primary_ref_frame = ap_ref->slot; ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame; rc_group = VK_VIDEO_ENCODE_AV1_RATE_CONTROL_GROUP_PREDICTIVE_KHR; pred_mode = VK_VIDEO_ENCODE_AV1_PREDICTION_MODE_SINGLE_REFERENCE_KHR; ref_name_mask = enc->caps.singleReferenceNameMask; - set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0); + ap->av1pic_info.primary_ref_frame = + set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0); // vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST; @@ -422,11 +422,11 @@ static int init_pic_params(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, ref = pic->refs[0][pic->nb_refs[0] - 1]; ap_ref = ref->codec_priv; ap->last_idr_frame = ap_ref->last_idr_frame; - ap->av1pic_info.primary_ref_frame = ap_ref->slot; ap->av1pic_info.ref_order_hint[ap_ref->slot] = ref->display_order - ap_ref->last_idr_frame; for (int i = 0; i < AV1_REF_FRAME_GOLDEN; i++) ap->av1pic_info.ref_frame_idx[i] = ap_ref->slot; - set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0); + ap->av1pic_info.primary_ref_frame = + set_name_slot(ap_ref->av1pic_info.current_frame_id, name_slots, ref_name_mask, 0); ref = pic->refs[1][pic->nb_refs[1] - 1]; ap_ref = ref->codec_priv;