ECM-9.0 issue with JVET_Z0136_OOB when SIMD optimizations are off
There seems to be a conflict in InterPrediction::applyBiOptFlow with JVET_Z0136_OOB functionality when SIMD optimizations are off. The following lines are called in both SIMD and non-SIMD case:
if (bioDx == 4)
{
g_pelBufOP.addAvg4(srcY0Temp, src0Stride, srcY1Temp, src1Stride, dstY + dstBlockOffset,
dstStride, bioDx, bioDy, shiftNum, offset, clpRng, pSubMcMask, width, isOOBTmp);
}
else
{
g_pelBufOP.addAvg8(srcY0Temp, src0Stride, srcY1Temp, src1Stride, dstY + dstBlockOffset,
dstStride, bioDx, bioDy, shiftNum, offset, clpRng, pSubMcMask, width, isOOBTmp);
}
However, addAvg4 and addAvg8 only include OOB handling in the case of SIMD optimizations. Otherwise, the OOB handling is expected to happen outside of these functions. As a possible fix, the blocks could be wrapped to PelBuf objects and PelBuf.addAvg could be used to do the averaging in the non-SIMD case as that seems to include proper OOB handling:
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
if (bioDx == 4)
{
g_pelBufOP.addAvg4(srcY0Temp, src0Stride, srcY1Temp, src1Stride, dstY + dstBlockOffset,
dstStride, bioDx, bioDy, shiftNum, offset, clpRng, pSubMcMask, width, isOOBTmp);
}
else
{
g_pelBufOP.addAvg8(srcY0Temp, src0Stride, srcY1Temp, src1Stride, dstY + dstBlockOffset,
dstStride, bioDx, bioDy, shiftNum, offset, clpRng, pSubMcMask, width, isOOBTmp);
}
#else
PelBuf pelBufDest = PelBuf(dstY + dstBlockOffset, dstStride, bioDx, bioDy);
CPelBuf pelBufSrc0 = CPelBuf(srcY0Temp, src0Stride, bioDx, bioDy);
CPelBuf pelBufSrc1 = CPelBuf(srcY1Temp, src1Stride, bioDx, bioDy);
pelBufDest.addAvg(pelBufSrc0, pelBufSrc1, clpRng, pSubMcMask, width, isOOBTmp);
#endif
Would be good if experts more familiar with JVET_Z0136_OOB could verify if this is meaningful or if some other fix would server better.