I think there is an issue with the function AL_sSettings_GetMinLevelHEVC(). Specifically with AL_HEVC_GetLevelFromDPBSize(). It is using the pixRate parameter and I think it should be using the MaxLumaPS as specified in ITU H.265 Annex A, section 4.2 equation (A-2).
I added comments in the code snippets below where I think the computation is wrong.
uMaxSample *= pChParam->tRCParam.uFrameRate; // HERE uMaxSample BECOMES pixRate or MaxLumaSR as labeled in ITU H.265 Annex A table A.9
uLevel = Max(AL_HEVC_GetLevelFromPixRate(uMaxSample), uLevel);
uLevel = Max(AL_HEVC_GetLevelFromBitrate(uBitRate, pChParam->uTier), uLevel);
uLevel = Max(AL_HEVC_GetLevelFromDPBSize(uRequiredDPBSize, uMaxSample), uLevel); // The MaxDpbSize uses the MaxLumaPS to do its comparison NOT MaxLumaSR. Ref. ITU H.265 Annex A section 4.2 equation (A-2)
return uLevel;
}
From HevcLevelLimits.c
/****/
static uint8_t AL_HEVC_GetMaxDpbPicBuf(int maxPixRate, int numPixPerFrame) // The MaxDpbSize uses the MaxLumaPS to do its comparison NOT maxPixRate (MaxLumaSR as per the H.265 label). Ref. ITU H.265 Annex A, section 4.2 equation (A-2)
{
// Values computed from HEVC Annex A - with maxDpbPicBuf = 6
if(numPixPerFrame <= (maxPixRate >> 2))
return 16;
else if(numPixPerFrame <= (maxPixRate >> 1))
return 12;
else if(numPixPerFrame <= ((3 * maxPixRate) >> 2))
return 8;
return 6;
}
/****/
uint8_t AL_HEVC_GetLevelFromDPBSize(int dpbSize, int pixRate) // pixRate here should be MaxLumaPS or "pixPerFrame" NOT pixRate (MaxLumaSR as per H.265 label)
{
for(size_t i = 0; i < NUM_LIMIT(AL_HEVC_MAX_PIX_PER_FRAME); i++)
{
uint8_t maxDpbSize = AL_HEVC_GetMaxDpbPicBuf(AL_HEVC_MAX_PIX_PER_FRAME[i].uLimit, pixRate);
Hi,
I think there is an issue with the function AL_sSettings_GetMinLevelHEVC(). Specifically with AL_HEVC_GetLevelFromDPBSize(). It is using the pixRate parameter and I think it should be using the MaxLumaPS as specified in ITU H.265 Annex A, section 4.2 equation (A-2).
I added comments in the code snippets below where I think the computation is wrong.
Thanks,
Louis
From Settings.c
static uint8_t AL_sSettings_GetMinLevelHEVC(AL_TEncChanParam const pChParam) { uint32_t uMaxSample = pChParam->uWidth pChParam->uHeight;
int iCpbVclFactor = AL_sSettings_GetCpbVclFactor(pChParam->eProfile); int iHbrFactor = AL_sSettings_GetHbrFactor(pChParam->eProfile); int iBrVclFactor = iCpbVclFactor * iHbrFactor; uint32_t uBitRate = (pChParam->tRCParam.uMaxBitRate + (iBrVclFactor - 1)) / iBrVclFactor; uint8_t uRequiredDPBSize = AL_DPBConstraint_GetMaxDPBSize(pChParam);
uint8_t uLevel = AL_HEVC_GetLevelFromFrameSize(uMaxSample);
uMaxSample *= pChParam->tRCParam.uFrameRate; // HERE uMaxSample BECOMES pixRate or MaxLumaSR as labeled in ITU H.265 Annex A table A.9 uLevel = Max(AL_HEVC_GetLevelFromPixRate(uMaxSample), uLevel); uLevel = Max(AL_HEVC_GetLevelFromBitrate(uBitRate, pChParam->uTier), uLevel); uLevel = Max(AL_HEVC_GetLevelFromDPBSize(uRequiredDPBSize, uMaxSample), uLevel); // The MaxDpbSize uses the MaxLumaPS to do its comparison NOT MaxLumaSR. Ref. ITU H.265 Annex A section 4.2 equation (A-2)
return uLevel; }
From HevcLevelLimits.c
/****/ static uint8_t AL_HEVC_GetMaxDpbPicBuf(int maxPixRate, int numPixPerFrame) // The MaxDpbSize uses the MaxLumaPS to do its comparison NOT maxPixRate (MaxLumaSR as per the H.265 label). Ref. ITU H.265 Annex A, section 4.2 equation (A-2) { // Values computed from HEVC Annex A - with maxDpbPicBuf = 6 if(numPixPerFrame <= (maxPixRate >> 2)) return 16; else if(numPixPerFrame <= (maxPixRate >> 1)) return 12; else if(numPixPerFrame <= ((3 * maxPixRate) >> 2)) return 8;
return 6; }
/****/ uint8_t AL_HEVC_GetLevelFromDPBSize(int dpbSize, int pixRate) // pixRate here should be MaxLumaPS or "pixPerFrame" NOT pixRate (MaxLumaSR as per H.265 label) { for(size_t i = 0; i < NUM_LIMIT(AL_HEVC_MAX_PIX_PER_FRAME); i++) { uint8_t maxDpbSize = AL_HEVC_GetMaxDpbPicBuf(AL_HEVC_MAX_PIX_PER_FRAME[i].uLimit, pixRate);
}
return 255; }