Skip to content

Commit 3ef4fd1

Browse files
committed
decoder: Fix AV1 encoder crash with B-frames (show existing frame handling)
When encoding AV1 with B-frames (consecutiveBFrameCount > 0), the encoder creates "show existing frame" P-frames that display previously encoded frames. These frames have bShowExistingFrame=true. The issue was in ProcessDpb(): - frameEncodeEncodeOrderNum is only assigned in StartOfVideoCodingEncodeOrder when bShowExistingFrame=false - ProcessDpb called InvalidateStaleReferenceFrames() with the uninitialized frameEncodeEncodeOrderNum (UINT64_MAX) before checking bShowExistingFrame - This triggered the assertion: frameEncodeEncodeOrderNum <= UINT32_MAX Fix: Move the bShowExistingFrame early return check before the assertion and InvalidateStaleReferenceFrames() call. Show existing frames don't need stale reference invalidation since they don't encode a new frame. Command line that triggered this crash: vk-video-enc-test -i input.yuv -c av1 --inputWidth 352 --inputHeight 288 \ --inputChromaSubsampling 420 --numFrames 30 -o output.ivf \ --gopFrameCount 16 --consecutiveBFrameCount 3 This fixes the AV1_gop_16_b3 encoder test. Signed-off-by: Tony Zlatinski <tzlatinski@nvidia.com>
1 parent 5d0059e commit 3ef4fd1

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,12 @@ VkResult VkVideoEncoderAV1::ProcessDpb(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
227227
assert(dpbIndx >= 0);
228228

229229
m_dpbAV1->ConfigureRefBufUpdate(pFrameInfo->bShownKeyFrameOrSwitch, pFrameInfo->bShowExistingFrame, frameUpdateType);
230-
assert(pFrameInfo->frameEncodeEncodeOrderNum <= std::numeric_limits<uint32_t>::max());
231-
m_dpbAV1->InvalidateStaleReferenceFrames(static_cast<uint32_t>(pFrameInfo->frameEncodeEncodeOrderNum), pFrameInfo->picOrderCntVal, &m_stateAV1.m_sequenceHeader);
232-
pFrameInfo->stdPictureInfo.refresh_frame_flags = (uint8_t)m_dpbAV1->GetRefreshFrameFlags(pFrameInfo->bShownKeyFrameOrSwitch, pFrameInfo->bShowExistingFrame);
233230

231+
// For show existing frame, skip stale reference invalidation and return early.
232+
// Show existing frames don't have a valid frameEncodeEncodeOrderNum since they
233+
// don't represent a new encoded frame - they just display a previously encoded one.
234234
if (pFrameInfo->bShowExistingFrame) {
235+
pFrameInfo->stdPictureInfo.refresh_frame_flags = (uint8_t)m_dpbAV1->GetRefreshFrameFlags(pFrameInfo->bShownKeyFrameOrSwitch, pFrameInfo->bShowExistingFrame);
235236
m_dpbAV1->DpbPictureEnd(dpbIndx, encodeFrameInfo->setupImageResource/*nullptr*/, &m_stateAV1.m_sequenceHeader,
236237
pFrameInfo->bShowExistingFrame, pFrameInfo->bShownKeyFrameOrSwitch,
237238
pFrameInfo->stdPictureInfo.flags.error_resilient_mode,
@@ -240,6 +241,10 @@ VkResult VkVideoEncoderAV1::ProcessDpb(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
240241
return VK_SUCCESS;
241242
}
242243

244+
assert(pFrameInfo->frameEncodeEncodeOrderNum <= std::numeric_limits<uint32_t>::max());
245+
m_dpbAV1->InvalidateStaleReferenceFrames(static_cast<uint32_t>(pFrameInfo->frameEncodeEncodeOrderNum), pFrameInfo->picOrderCntVal, &m_stateAV1.m_sequenceHeader);
246+
pFrameInfo->stdPictureInfo.refresh_frame_flags = (uint8_t)m_dpbAV1->GetRefreshFrameFlags(pFrameInfo->bShownKeyFrameOrSwitch, pFrameInfo->bShowExistingFrame);
247+
243248
// setup recon picture (pSetupReferenceSlot)
244249
bool success = m_dpbImagePool->GetAvailableImage(encodeFrameInfo->setupImageResource,
245250
VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR);

0 commit comments

Comments
 (0)