Commit 352d1bb
committed
decoder: Fix bitstream buffer alignment for all codecs
Fix srcBufferOffset and srcBufferRange alignment to satisfy Vulkan spec
requirements for vkCmdDecodeVideoKHR (VUID-07131, VUID-07139).
Problem
-------
The parser's bitstreamDataOffset and bitstreamDataLen values were passed
directly into VkVideoDecodeInfoKHR without any alignment, causing
validation errors on H.264, H.265, and AV1 (VP9 already handled this).
Parser Buffer Architecture
--------------------------
The NvVideoParser manages bitstream buffers as follows:
1. Buffers are allocated via GetBitstreamBuffer() with size rounded up
to minBitstreamBufferSizeAlignment (typically 256 bytes).
2. The parser fills the buffer with compressed frame data sequentially.
When a frame boundary is detected (end_of_picture), the parser
reports bitstreamDataOffset (where frame data starts in the buffer)
and bitstreamDataLen (exact byte count of the frame's NAL units).
3. The buffer often contains BOTH the current frame's data AND the
beginning of the next frame's data (residual). After the decode
command is submitted, swapBitstreamBuffer() copies this residual
data to a new aligned buffer for the next frame.
4. For H.264/H.265 (NAL-based codecs via VulkanVideoDecoder::
end_of_picture), bitstreamDataOffset is always 0 -- the frame data
starts at the buffer beginning.
5. For VP9, the parser explicitly handles alignment in
VulkanVP9Decoder::ParseFrameHeader (line 251-261): offset is
aligned down, internal offsets are adjusted, and bitstreamDataLen
is aligned up -- all at the parser level.
6. For AV1, bitstreamDataOffset is 0 (set in VulkanAV1Decoder::
end_of_picture).
srcBufferOffset Fix
-------------------
For H.264/H.265/AV1: Assert that bitstreamDataOffset is 0 (enforced
by the parser architecture). Force to 0 as a safety net if violated.
For VP9: Trust the parser's alignment (already correct).
srcBufferRange Fix (per-codec)
------------------------------
H.265, AV1, VP9: Round up bitstreamDataLen to minBitstreamBufferSizeAlignment.
These codecs use explicit slice segment offsets (pSliceSegmentOffsets)
or tile sizes (pTileSizes) for decode boundaries. NVDEC ignores bytes
beyond the last slice/tile, so the residual data in the alignment
padding area is harmless.
H.264: Pass exact bitstreamDataLen WITHOUT rounding up.
NVDEC's H.264 decoder uses srcBufferRange to bound its start-code
scan (searching for 00 00 01 patterns). The buffer's residual area
beyond bitstreamDataLen contains the next frame's data, which starts
with a valid start code. Rounding up exposes this start code to the
NAL scanner, causing decode corruption. Suppress VUID-07139 for H.264.
The proper fix requires handling alignment in the H.264 parser
(like VP9 does), but that is a larger change to NvVideoParser's
ByteStreamParser buffer management.
IMPORTANT: The bytes beyond bitstreamDataLen must NOT be zero-filled.
They contain the next frame's residual data that swapBitstreamBuffer()
copies after the decode returns. Zero-filling destroys this data and
corrupts all subsequent frames.
Also fix VulkanBitstreamBufferImpl::GetSizeAlignment() which incorrectly
returned VkMemoryRequirements::alignment instead of m_bufferSizeAlignment
(the minBitstreamBufferSizeAlignment from VkVideoCapabilitiesKHR).
Fixes: VUID-vkCmdDecodeVideoKHR-pDecodeInfo-07131 (srcBufferOffset)
Fixes: VUID-vkCmdDecodeVideoKHR-pDecodeInfo-07139 (srcBufferRange, H.265/AV1/VP9)
Suppresses: VUID-07139 for H.264 (requires parser-level fix)
Ref: KhronosGroup/Vulkan-ValidationLayers#11531
Ref: #183
Signed-off-by: Tony Zlatinski <tzlatinski@nvidia.com>1 parent 61b7e96 commit 352d1bb
File tree
3 files changed
+60
-6
lines changed- common/libs/VkCodecUtils
- vk_video_decoder/libs/VkVideoDecoder
3 files changed
+60
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
| 225 | + | |
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
447 | 447 | | |
448 | 448 | | |
449 | 449 | | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
450 | 459 | | |
451 | 460 | | |
452 | 461 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
757 | 757 | | |
758 | 758 | | |
759 | 759 | | |
760 | | - | |
761 | 760 | | |
762 | | - | |
763 | | - | |
764 | | - | |
765 | | - | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
766 | 811 | | |
767 | 812 | | |
768 | 813 | | |
| |||
0 commit comments