Xilinx / vcu-ctrl-sw

Other
38 stars 30 forks source link

Incorrect computation in AL_sSettings_GetMinLevelHEVC #2

Open lpdemers1 opened 4 years ago

lpdemers1 commented 4 years ago

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);

if(dpbSize <= maxDpbSize)
  return AL_HEVC_MAX_PIX_PER_FRAME[i].uLevel;

}

return 255; }