This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 898b8aa9220a6c71c61f649f55dbf7407f180c2a Author: Lynne <[email protected]> AuthorDate: Sun Jul 12 18:28:45 2026 +0900 Commit: Lynne <[email protected]> CommitDate: Sun Aug 2 22:11:23 2026 +0900 vulkan_ffv1: survive setup failures on preceding frames A frame's private data is allocated before start_frame(), and its free callback runs even if setup failed partway, so partially-initialized private data has to be tolerated everywhere: inter frames reffed the previous frame's slice state without checking it exists, end_frame() waited on a semaphore that was never created, and the free callback read a feedback buffer that was never allocated or written. Inter frames after a failed frame now error out until the next keyframe. Also set the device function pointers before anything can fail, as the free callback needs them. --- libavcodec/vulkan_ffv1.c | 84 +++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/libavcodec/vulkan_ffv1.c b/libavcodec/vulkan_ffv1.c index d61f66455e..d3d1f3b5de 100644 --- a/libavcodec/vulkan_ffv1.c +++ b/libavcodec/vulkan_ffv1.c @@ -136,6 +136,12 @@ static int vk_ffv1_start_frame(AVCodecContext *avctx, fp->crc_checked = f->ec && (avctx->err_recognition & AV_EF_CRCCHECK); + /* The context-less free callback needs these device functions, which + * prepare_frame_sdr() used to set. vp->sem is kept for the next + * non-keyframe's wait and the free callback's CRC readback. */ + vp->wait_semaphores = ctx->s.vkfn.WaitSemaphores; + vp->invalidate_memory_ranges = ctx->s.vkfn.InvalidateMappedMemoryRanges; + /* Host map the input slices data if supported */ if (ctx->s.extensions & FF_VK_EXT_EXTERNAL_HOST_MEMORY) ff_vk_host_map_buffer(&ctx->s, &vp->slices_buf, buffer_ref->data, @@ -154,6 +160,11 @@ static int vk_ffv1_start_frame(AVCodecContext *avctx, return err; } else { FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private; + + /* The previous frame's setup may have failed partway */ + if (!fpl || !fpl->slice_state) + return AVERROR_INVALIDDATA; + fp->slice_state = av_buffer_ref(fpl->slice_state); if (!fp->slice_state) return AVERROR(ENOMEM); @@ -182,12 +193,6 @@ static int vk_ffv1_start_frame(AVCodecContext *avctx, return err; } - /* The context-less free callback needs these device functions, which - * prepare_frame_sdr() used to set. vp->sem is kept for the next - * non-keyframe's wait and the free callback's CRC readback. */ - vp->wait_semaphores = ctx->s.vkfn.WaitSemaphores; - vp->invalidate_memory_ranges = ctx->s.vkfn.InvalidateMappedMemoryRanges; - /* Create a temporaty frame for RGB */ if (is_rgb) { vp->dpb_frame = av_frame_alloc(); @@ -303,9 +308,10 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx) FFv1VulkanDecodePicture *fpl = f->hwaccel_last_picture_private; FFVulkanDecodePicture *vpl = &fpl->vp; - /* Wait on the previous frame */ - RET(ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, vpl->sem_value, - VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT)); + /* Wait on the previous frame, if its decode was ever submitted */ + if (vpl->sem) + RET(ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, vpl->sem_value, + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT)); } RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_state, 1, 1)); @@ -935,39 +941,43 @@ static void vk_ffv1_free_frame_priv(AVRefStructOpaque _hwctx, void *data) FFv1VulkanDecodePicture *fp = data; FFVulkanDecodePicture *vp = &fp->vp; - FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data; - uint8_t *ssp = slice_feedback->mapped_mem + 2*fp->slice_num*sizeof(uint32_t); ff_vk_decode_free_frame(dev_ctx, vp); - /* Invalidate slice/output data if needed */ - if (!(slice_feedback->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { - VkMappedMemoryRange invalidate_data = { - .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, - .memory = slice_feedback->mem, - .offset = 0, - .size = 2*fp->slice_num*sizeof(uint32_t), - }; - vp->invalidate_memory_ranges(hwctx->act_dev, - 1, &invalidate_data); - } + /* No feedback to read if setup failed or the decode was never submitted */ + if (fp->slice_feedback_buf && vp->sem) { + FFVkBuffer *slice_feedback = (FFVkBuffer *)fp->slice_feedback_buf->data; + uint8_t *ssp = slice_feedback->mapped_mem + 2*fp->slice_num*sizeof(uint32_t); + + /* Invalidate slice/output data if needed */ + if (!(slice_feedback->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { + VkMappedMemoryRange invalidate_data = { + .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, + .memory = slice_feedback->mem, + .offset = 0, + .size = 2*fp->slice_num*sizeof(uint32_t), + }; + vp->invalidate_memory_ranges(hwctx->act_dev, + 1, &invalidate_data); + } - int slice_error_cnt = 0; - int crc_mismatch_cnt = 0; - uint32_t max_overread = 0; - for (int i = 0; i < fp->slice_num; i++) { - uint32_t crc_res = 0; - if (fp->crc_checked) - crc_res = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 0); - uint32_t overread = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 4); - max_overread = FFMAX(overread, max_overread); - slice_error_cnt += !!overread; - crc_mismatch_cnt += !!crc_res; + int slice_error_cnt = 0; + int crc_mismatch_cnt = 0; + uint32_t max_overread = 0; + for (int i = 0; i < fp->slice_num; i++) { + uint32_t crc_res = 0; + if (fp->crc_checked) + crc_res = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 0); + uint32_t overread = AV_RN32(ssp + 2*i*sizeof(uint32_t) + 4); + max_overread = FFMAX(overread, max_overread); + slice_error_cnt += !!overread; + crc_mismatch_cnt += !!crc_res; + } + if (slice_error_cnt || crc_mismatch_cnt) + av_log(dev_ctx, AV_LOG_ERROR, "Decode status: %i slices overread (%i bytes max), " + "%i CRCs mismatched\n", + slice_error_cnt, max_overread, crc_mismatch_cnt); } - if (slice_error_cnt || crc_mismatch_cnt) - av_log(dev_ctx, AV_LOG_ERROR, "Decode status: %i slices overread (%i bytes max), " - "%i CRCs mismatched\n", - slice_error_cnt, max_overread, crc_mismatch_cnt); av_buffer_unref(&fp->slice_state); av_buffer_unref(&fp->slice_feedback_buf); _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
