diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp index 93209af9..a220be15 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp @@ -1916,9 +1916,10 @@ VkResult VkVideoEncoder::RecordVideoCodingCmd(VkSharedBaseObjcontrolCmd}; vkDevCtx->CmdControlVideoCodingKHR(cmdBuf, &renderControlInfo); + assert(encodeFrameInfo->pControlCmdChain); + m_beginRateControlInfo = *(VkVideoEncodeRateControlInfoKHR*)encodeFrameInfo->pControlCmdChain; - // Do not walk the chain, otherwise we end up creating a loop here. - m_beginRateControlInfo.pNext = NULL; + const_cast(static_cast(m_beginRateControlInfo.pNext))->pNext = NULL; } if (m_videoMaintenance1FeaturesSupported) @@ -1929,13 +1930,10 @@ VkResult VkVideoEncoder::RecordVideoCodingCmd(VkSharedBaseObjencodeInfo; - vk::ChainNextVkStruct(*pStruct, videoInlineQueryInfoKHR); - vkDevCtx->CmdEncodeVideoKHR(cmdBuf, &encodeFrameInfo->encodeInfo); + vk::ChainNextVkStruct(encodeFrameInfo->encodeInfo, videoInlineQueryInfoKHR); - // Remove the stack pointer from the chain, causes a use after free otherwise in GetEncodeFrameInfoH264 - encodeFrameInfo->encodeInfo.pNext = videoInlineQueryInfoKHR.pNext; + vkDevCtx->CmdEncodeVideoKHR(cmdBuf, &encodeFrameInfo->encodeInfo); } else { diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.h b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.h index dacc2929..7d0d99a9 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.h @@ -56,10 +56,7 @@ class VkVideoEncoder : public VkVideoRefCountBase { struct VkVideoEncodeFrameInfo : public VkVideoRefCountBase { - VkStructureType GetType() { - return (encodeInfo.pNext == nullptr) ? - VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR : reinterpret_cast(encodeInfo.pNext)->sType; - } + virtual VkVideoCodecOperationFlagBitsKHR GetCodecType() const = 0; VkVideoEncodeFrameInfo(const void* pNext = nullptr) : encodeInfo{ VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR, pNext} @@ -253,7 +250,8 @@ class VkVideoEncoder : public VkVideoRefCountBase { virtual void Reset(bool releaseResources = true) { // Clear and check state assert(encodeInfo.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR); - assert(encodeInfo.pNext != nullptr); + + encodeInfo.pNext = nullptr; if ((frameInputOrderNum == (uint64_t)-1) && (frameEncodeInputOrderNum == (uint64_t)-1) && diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.h b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.h index 968d83f4..8c2b9680 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.h @@ -48,6 +48,10 @@ class VkVideoEncoderAV1 : public VkVideoEncoder VkVideoEncodeAV1RateControlInfoKHR rateControlInfoAV1; VkVideoEncodeAV1RateControlLayerInfoKHR rateControlLayersInfoAV1[1]; + VkVideoCodecOperationFlagBitsKHR GetCodecType() const override { + return VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR; + } + VkVideoEncodeFrameInfoAV1() : VkVideoEncodeFrameInfo(&pictureInfo) , pictureInfo{ VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR } @@ -69,12 +73,16 @@ class VkVideoEncoderAV1 : public VkVideoEncoder pictureInfo.pStdPictureInfo = &stdPictureInfo; } - virtual void Reset(bool releaseResources = true) { + virtual void Reset(bool releaseResources = true) override { pictureInfo.pNext = nullptr; // Reset the base first VkVideoEncodeFrameInfo::Reset(releaseResources); + + // After resetting the base structure parameters, start building the pNext chain again + assert(pictureInfo.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR); + encodeInfo.pNext = &pictureInfo; } virtual ~VkVideoEncodeFrameInfoAV1() { @@ -184,7 +192,7 @@ class VkVideoEncoderAV1 : public VkVideoEncoder private: VkVideoEncodeFrameInfoAV1* GetEncodeFrameInfoAV1(VkSharedBaseObj& encodeFrameInfo) { - assert(VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PICTURE_INFO_KHR == encodeFrameInfo->GetType()); + assert(VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR == encodeFrameInfo->GetCodecType()); VkVideoEncodeFrameInfo* pEncodeFrameInfo = encodeFrameInfo; return (VkVideoEncodeFrameInfoAV1*)pEncodeFrameInfo; } diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH264.h b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH264.h index 0eb79335..5abf3947 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH264.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH264.h @@ -48,6 +48,10 @@ class VkVideoEncoderH264 : public VkVideoEncoder { StdVideoEncodeH264RefListModEntry refList1ModOperations[MAX_REFFERENCES]; StdVideoEncodeH264RefPicMarkingEntry refPicMarkingEntry[MAX_MEM_MGMNT_CTRL_OPS_COMMANDS]; + VkVideoCodecOperationFlagBitsKHR GetCodecType() const override { + return VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR; + } + VkVideoEncodeFrameInfoH264() : VkVideoEncodeFrameInfo(&pictureInfo) , pictureInfo { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR } @@ -81,13 +85,16 @@ class VkVideoEncoderH264 : public VkVideoEncoder { stdDpbSlotInfo->pStdReferenceInfo = stdReferenceInfo; }; - virtual void Reset(bool releaseResources = true) { + virtual void Reset(bool releaseResources = true) override { pictureInfo.pNext = nullptr; // Reset the base first VkVideoEncodeFrameInfo::Reset(releaseResources); + // After resetting the base structure parameters, start building the pNext chain again + encodeInfo.pNext = &pictureInfo; + // Clear and check state assert(pictureInfo.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR); assert(naluSliceInfo[0].sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_INFO_KHR); @@ -153,7 +160,7 @@ class VkVideoEncoderH264 : public VkVideoEncoder { private: VkVideoEncodeFrameInfoH264* GetEncodeFrameInfoH264(VkSharedBaseObj& encodeFrameInfo) { - assert(VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR == encodeFrameInfo->GetType()); + assert(VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR == encodeFrameInfo->GetCodecType()); VkVideoEncodeFrameInfo* pEncodeFrameInfo = encodeFrameInfo; return (VkVideoEncodeFrameInfoH264*)pEncodeFrameInfo; } diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH265.h b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH265.h index 6d829250..5faad859 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH265.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderH265.h @@ -46,6 +46,10 @@ class VkVideoEncoderH265 : public VkVideoEncoder { StdVideoEncodeH265ReferenceInfo stdReferenceInfo[MAX_REFFERENCES]; VkVideoEncodeH265DpbSlotInfoKHR stdDpbSlotInfo[MAX_REFFERENCES]; + VkVideoCodecOperationFlagBitsKHR GetCodecType() const override { + return VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR; + } + VkVideoEncodeFrameInfoH265() : VkVideoEncodeFrameInfo(&pictureInfo) , pictureInfo { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR } @@ -80,13 +84,16 @@ class VkVideoEncoderH265 : public VkVideoEncoder { stdDpbSlotInfo->pStdReferenceInfo = stdReferenceInfo; }; - virtual void Reset(bool releaseResources = true) { + virtual void Reset(bool releaseResources = true) override { pictureInfo.pNext = nullptr; // Reset the base first VkVideoEncodeFrameInfo::Reset(releaseResources); + // After resetting the base structure parameters, start building the pNext chain again + encodeInfo.pNext = &pictureInfo; + // Clear and check state assert(pictureInfo.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR); assert(naluSliceSegmentInfo[0].sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_INFO_KHR); @@ -148,7 +155,7 @@ class VkVideoEncoderH265 : public VkVideoEncoder { private: VkVideoEncodeFrameInfoH265* GetEncodeFrameInfoH265(VkSharedBaseObj& encodeFrameInfo) { - assert(VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR == encodeFrameInfo->GetType()); + assert(VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR == encodeFrameInfo->GetCodecType()); VkVideoEncodeFrameInfo* pEncodeFrameInfo = encodeFrameInfo; return (VkVideoEncodeFrameInfoH265*)pEncodeFrameInfo; }