From 1c3f1ad46bf85fd825c1c8a1cc4192246a32d004 Mon Sep 17 00:00:00 2001 From: sys_mediadev Date: Mon, 12 Aug 2024 01:55:26 +0000 Subject: [PATCH] [CP] Fix erroneous cross-segment start code. Fix erroneous cross-segment start code. A slice NAL can be divided in to 1) encrypted 16-byte aligned segment and 2) not aligned the trailing bytes. The original MergeEncryptedNalUnit can only prevent erroneous starting code placed completely inside a segment. The bug in this case is that, a `00 01` is at the start of the 2nd segment of a slice, and when the 1st segment's last encrypted byte is encrypted to `00`, it forms a erroneous cross-segment start code `00 00 01`, which leads to erroneous header parsing. This PR add additional check for cross-segment start code in PXP's h265 header parsing. Previously, when parsed NAL unit's length is less than segment's length, if the additional bytes in that segment is all 0, it would be considered trailing 0, and simple expand the NAL units to cover the entire segment. In this PR, we check bytes across segment to make sure there is no cross-segment `00 00 01`. --- .../mfx_lib/pxp/src/mfx_pxp_h265_nal_spl.cpp | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/_studio/mfx_lib/pxp/src/mfx_pxp_h265_nal_spl.cpp b/_studio/mfx_lib/pxp/src/mfx_pxp_h265_nal_spl.cpp index c83b9c3764..b52b60cc85 100644 --- a/_studio/mfx_lib/pxp/src/mfx_pxp_h265_nal_spl.cpp +++ b/_studio/mfx_lib/pxp/src/mfx_pxp_h265_nal_spl.cpp @@ -83,13 +83,38 @@ namespace UMC_HEVC_DECODER // additional 00 at the end of NAL uint8_t* end_nal_ptr = (uint8_t*)nalUnit->GetBufferPointer() + nalUnit->GetBufferSize(); uint32_t end_nal_index = 0; + + uint32_t currSegment = pxpva->m_curSegment; uint32_t ext_buf_size = cur_segment_length - nalUnit->GetBufferSize(); - while (end_nal_index < ext_buf_size && *end_nal_ptr == 0) + uint8_t extEndByte = 0; + uint32_t indexNewSeg = 0; + while (end_nal_index < ext_buf_size) { + extEndByte = *end_nal_ptr; + if(extEndByte != 0) + { + break; + } end_nal_ptr++; end_nal_index++; + indexNewSeg++; + if(end_nal_index == ext_buf_size) + { + ++currSegment; + indexNewSeg = 0; + uint32_t numSegments = static_cast(pxpva->GetPXPParams())->num_segments; + if(currSegment < numSegments) + { + ext_buf_size += (static_cast(pxpva->GetPXPParams())->segment_info + currSegment)->segment_length; + } + else + { + break; + } + } } - if (end_nal_index >= ext_buf_size) + + if (extEndByte != 1 || (currSegment > pxpva->m_curSegment && indexNewSeg > 1)) // No start code follow, or the following start code is in complete different segment { nalUnit->SetBufferPointer((uint8_t*)nalUnit->GetBufferPointer(), cur_segment_length); nalUnit->SetDataSize(cur_segment_length);