Skip to content

Commit 573d9ce

Browse files
committed
Allow calculating PSNR for Y/U/V components
by requesting this either as a option for all frames in SEncParamExt.bPsnrY (and U/V) or per-frame using SSourcePicture.bPsnrY (and U/V) The resulting data goes into SLayerBSInfo.rPsnr with is a three-element array for the Y/U/V components of the PSNR. This is disabled by default. Also removes the ENABLE_PSNR_CALC preprocessor define in favor of the API. See https://www.researchgate.net/publication/383545049_Low-Complexity_Video_PSNR_Measurement_in_Real-Time_Communication_Products by @YCSun-Meta for a research paper explaining the background.
1 parent 4ab86b8 commit 573d9ce

File tree

4 files changed

+59
-36
lines changed

4 files changed

+59
-36
lines changed

codec/api/wels/codec_app_def.h

+8
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,9 @@ typedef struct TagEncParamExt {
592592
bool bIsLosslessLink; ///< LTR advanced setting
593593
bool bFixRCOverShoot; ///< fix rate control overshooting
594594
int iIdrBitrateRatio; ///< the target bits of IDR is (idr_bitrate_ratio/100) * average target bit per frame.
595+
bool bPsnrY; ///< get Y PSNR stats for the whole video sequence
596+
bool bPsnrU; ///< get U PSNR stats for the whole video sequence
597+
bool bPsnrV; ///< get V PSNR stats for the whole video sequence
595598
} SEncParamExt;
596599

597600
/**
@@ -635,6 +638,7 @@ typedef struct {
635638
int iNalCount; ///< count number of NAL coded already
636639
int* pNalLengthInByte; ///< length of NAL size in byte from 0 to iNalCount-1
637640
unsigned char* pBsBuf; ///< buffer of bitstream contained
641+
float rPsnr[3]; ///< PSNR values for Y/U/V
638642
} SLayerBSInfo, *PLayerBSInfo;
639643

640644
/**
@@ -659,7 +663,11 @@ typedef struct Source_Picture_s {
659663
int iPicWidth; ///< luma picture width in x coordinate
660664
int iPicHeight; ///< luma picture height in y coordinate
661665
long long uiTimeStamp; ///< timestamp of the source picture, unit: millisecond
666+
bool bPsnrY; ///< get Y PSNR for this frame
667+
bool bPsnrU; ///< get U PSNR for this frame
668+
bool bPsnrV; ///< get V PSNR for this frame
662669
} SSourcePicture;
670+
663671
/**
664672
* @brief Structure for bit rate info
665673
*/

codec/encoder/core/inc/as264_common.h

-5
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
#endif//ENABLE_FRAME_DUMP
7575
#endif//__UNITTEST__
7676

77-
//#define ENABLE_PSNR_CALC
7877
//#define STAT_OUTPUT
7978
//#define MB_TYPES_CHECK
8079
//
@@ -88,10 +87,6 @@
8887
//@if !FRAME_INFO_OUTPUT
8988
#if !defined(FRAME_INFO_OUTPUT)
9089

91-
#if defined(ENABLE_PSNR_CALC)
92-
#undef ENABLE_PSNR_CALC
93-
#endif//ENABLE_PSNR_CALC
94-
9590
//#if defined(STAT_OUTPUT)
9691
//#undef STAT_OUTPUT
9792
//#endif//STAT_OUTPUT

codec/encoder/core/inc/param_svc.h

+6
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
180180
param.bIsLosslessLink = false;
181181
param.bFixRCOverShoot = true;
182182
param.iIdrBitrateRatio = IDR_BITRATE_RATIO * 100;
183+
param.bPsnrY = false;
184+
param.bPsnrU = false;
185+
param.bPsnrV = false;
183186
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
184187
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_UNKNOWN;
185188
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_UNKNOWN;
@@ -345,6 +348,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
345348
bIsLosslessLink = pCodingParam.bIsLosslessLink;
346349
bFixRCOverShoot = pCodingParam.bFixRCOverShoot;
347350
iIdrBitrateRatio = pCodingParam.iIdrBitrateRatio;
351+
bPsnrY = pCodingParam.bPsnrY;
352+
bPsnrU = pCodingParam.bPsnrU;
353+
bPsnrV = pCodingParam.bPsnrV;
348354
if (iUsageType == SCREEN_CONTENT_REAL_TIME && !bIsLosslessLink && bEnableLongTermReference) {
349355
bEnableLongTermReference = false;
350356
}

codec/encoder/core/src/encoder_ext.cpp

+45-31
Original file line numberDiff line numberDiff line change
@@ -3445,9 +3445,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
34453445
SLayerBSInfo* pLayerBsInfo = &pFbi->sLayerInfo[0];
34463446
SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
34473447
SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
3448-
#if defined(ENABLE_FRAME_DUMP) || defined(ENABLE_PSNR_CALC)
34493448
SPicture* fsnr = NULL;
3450-
#endif//ENABLE_FRAME_DUMP || ENABLE_PSNR_CALC
34513449
SPicture* pEncPic = NULL; // to be decided later
34523450
#if defined(MT_DEBUG)
34533451
int32_t iDidList[MAX_DEPENDENCY_LAYER] = {0};
@@ -3469,9 +3467,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
34693467
int32_t iCurTid = 0;
34703468
bool bAvcBased = false;
34713469
SLogContext* pLogCtx = & (pCtx->sLogCtx);
3472-
#if defined(ENABLE_PSNR_CALC)
34733470
float fSnrY = .0f, fSnrU = .0f, fSnrV = .0f;
3474-
#endif//ENABLE_PSNR_CALC
34753471

34763472
#if defined(_DEBUG)
34773473
int32_t i = 0, j = 0, k = 0;
@@ -3624,9 +3620,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
36243620
pCtx->eNalPriority = eNalRefIdc;
36253621

36263622
pCtx->pDecPic = pCtx->ppRefPicListExt[iCurDid]->pNextBuffer;
3627-
#if defined(ENABLE_FRAME_DUMP) || defined(ENABLE_PSNR_CALC)
36283623
fsnr = pCtx->pDecPic;
3629-
#endif//#if defined(ENABLE_FRAME_DUMP) || defined(ENABLE_PSNR_CALC)
36303624
pCtx->pDecPic->iPictureType = pCtx->eSliceType;
36313625
pCtx->pDecPic->iFramePoc = pParamInternal->iPOC;
36323626

@@ -3921,26 +3915,30 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
39213915
}
39223916
#endif//ENABLE_FRAME_DUMP
39233917

3924-
#if defined(ENABLE_PSNR_CALC)
3925-
fSnrY = WelsCalcPsnr (fsnr->pData[0],
3926-
fsnr->iLineSize[0],
3927-
pEncPic->pData[0],
3928-
pEncPic->iLineSize[0],
3929-
iCurWidth,
3930-
iCurHeight);
3931-
fSnrU = WelsCalcPsnr (fsnr->pData[1],
3932-
fsnr->iLineSize[1],
3933-
pEncPic->pData[1],
3934-
pEncPic->iLineSize[1],
3935-
(iCurWidth >> 1),
3936-
(iCurHeight >> 1));
3937-
fSnrV = WelsCalcPsnr (fsnr->pData[2],
3938-
fsnr->iLineSize[2],
3939-
pEncPic->pData[2],
3940-
pEncPic->iLineSize[2],
3941-
(iCurWidth >> 1),
3942-
(iCurHeight >> 1));
3943-
#endif//ENABLE_PSNR_CALC
3918+
if (fsnr && (pSvcParam->bPsnrY || pSrcPic->bPsnrY)) {
3919+
fSnrY = WelsCalcPsnr (fsnr->pData[0],
3920+
fsnr->iLineSize[0],
3921+
pEncPic->pData[0],
3922+
pEncPic->iLineSize[0],
3923+
iCurWidth,
3924+
iCurHeight);
3925+
}
3926+
if (fsnr && (pSvcParam->bPsnrU || pSrcPic->bPsnrU)) {
3927+
fSnrU = WelsCalcPsnr (fsnr->pData[1],
3928+
fsnr->iLineSize[1],
3929+
pEncPic->pData[1],
3930+
pEncPic->iLineSize[1],
3931+
(iCurWidth >> 1),
3932+
(iCurHeight >> 1));
3933+
}
3934+
if (fsnr && (pSvcParam->bPsnrV || pSrcPic->bPsnrV)) {
3935+
fSnrV = WelsCalcPsnr (fsnr->pData[2],
3936+
fsnr->iLineSize[2],
3937+
pEncPic->pData[2],
3938+
pEncPic->iLineSize[2],
3939+
(iCurWidth >> 1),
3940+
(iCurHeight >> 1));
3941+
}
39443942

39453943
#if defined(LAYER_INFO_OUTPUT)
39463944
fprintf (stderr, "%2s %5d: %-5d %2s T%1d D%1d Q%-2d QP%3d Y%2.2f U%2.2f V%2.2f %8d bits\n",
@@ -3960,13 +3958,29 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
39603958

39613959
#if defined(STAT_OUTPUT)
39623960

3963-
#if defined(ENABLE_PSNR_CALC)
39643961
{
3965-
pCtx->sStatData[iCurDid][0].sQualityStat.rYPsnr[pCtx->eSliceType] += fSnrY;
3966-
pCtx->sStatData[iCurDid][0].sQualityStat.rUPsnr[pCtx->eSliceType] += fSnrU;
3967-
pCtx->sStatData[iCurDid][0].sQualityStat.rVPsnr[pCtx->eSliceType] += fSnrV;
3962+
if (pSvcParam->bPsnrY) {
3963+
pCtx->sStatData[iCurDid][0].sQualityStat.rYPsnr[pCtx->eSliceType] += fSnrY;
3964+
}
3965+
if (pSvcParam->bPsnrU) {
3966+
pCtx->sStatData[iCurDid][0].sQualityStat.rUPsnr[pCtx->eSliceType] += fSnrU;
3967+
}
3968+
if (pSvcParam->bPsnrV) {
3969+
pCtx->sStatData[iCurDid][0].sQualityStat.rVPsnr[pCtx->eSliceType] += fSnrV;
3970+
}
3971+
}
3972+
pLayerBsInfo->rPsnr[0] = NAN;
3973+
pLayerBsInfo->rPsnr[1] = NAN;
3974+
pLayerBsInfo->rPsnr[2] = NAN;
3975+
if (pSrcPic->bPsnrY) {
3976+
pLayerBsInfo->rPsnr[0] = fSnrY;
3977+
}
3978+
if (pSrcPic->bPsnrU) {
3979+
pLayerBsInfo->rPsnr[1] = fSnrU;
3980+
}
3981+
if (pSrcPic->bPsnrV) {
3982+
pLayerBsInfo->rPsnr[2] = fSnrV;
39683983
}
3969-
#endif//ENABLE_PSNR_CALC
39703984

39713985
#if defined(MB_TYPES_CHECK) //091025, frame output
39723986
if (pCtx->eSliceType == P_SLICE) {

0 commit comments

Comments
 (0)