|
|
/* *************************************************************************
** INTEL Corporation Proprietary Information ** ** This listing is supplied under the terms of a license ** agreement with INTEL Corporation and may not be copied ** nor disclosed except in accordance with the terms of ** that agreement. ** ** Copyright (c) 1996 Intel Corporation. ** All Rights Reserved. ** **************************************************************************** * * e3stat.cpp * * Description: * This modules contains the encoder statistics routines * * Routines: All routines declared in e3stat.h * StatsFrameSize * InitFrameSizeStats * OutputFrameSizeStats * * StatsUsedQuant * InitQuantStats * OutputQuantStats * * InitPSNRStats * OutputPSNRStats * InitStats * IncrementPSNRCounter * ComputeYPSNR * ComputeVPSNR * ComputeUPSNR * * Data:
// $Header: R:\h26x\h26x\src\enc\e3stat.cpv 1.0 22 Apr 1996 17:46:22 BECHOLS $
// $Log: R:\h26x\h26x\src\enc\e3stat.cpv $
//
// Rev 1.0 22 Apr 1996 17:46:22 BECHOLS
// Initial revision.
//
// Rev 1.1 08 Mar 1996 14:14:26 DBRUCKS
// add framesize stats and fixed PSNR to use energy instead of the signal
//
// Rev 1.0 01 Mar 1996 16:34:40 DBRUCKS
// Initial revision.
*/
#include "precomp.h"
#ifdef ENCODE_STATS
#define MAX_FRAME_SIZE_INDEX 255
static U32 uArrayFrameSize[MAX_FRAME_SIZE_INDEX+1]; static U32 uArrayBitStreamSize[MAX_FRAME_SIZE_INDEX+1]; static int iFrameSizeIndex = 0;
static U32 uQuantCount[32];
#define MAX_PSNR_INDEX 255
static double dArrayYPSNR[MAX_PSNR_INDEX+1]; static double dArrayVPSNR[MAX_PSNR_INDEX+1]; static double dArrayUPSNR[MAX_PSNR_INDEX+1]; static int iPSNRIndex = 0;
static double ComputePSNR(U8 * pu8Input, int iInputPitch, U8 * pu8Output, int iOutputPitch, UN unWidth, UN unHeight);
/************************************************************************
* * StatsFrameSize * * Save the frame size information - with possbily different bitstream * and frame sizes. */ extern void StatsFrameSize(U32 uBitStreamSize, U32 uFrameSize) { ASSERT(uFrameSize >= uBitStreamSize);
if (iFrameSizeIndex <= MAX_FRAME_SIZE_INDEX) { uArrayBitStreamSize[iFrameSizeIndex] = uBitStreamSize; uArrayFrameSize[iFrameSizeIndex] = uFrameSize; iFrameSizeIndex++; /* can grow to one larger than MAX_FRAME_SIZE_INDEX */ } } /* end StatsFrameSize() */
/************************************************************************
* * InitFrameSizeStats */ extern void InitFrameSizeStats() { int i;
for (i = 0; i <= MAX_FRAME_SIZE_INDEX ; i++) { uArrayFrameSize[i] = 0; uArrayBitStreamSize[i] = 0; } iFrameSizeIndex = 0; } /* end InitFrameSizeStats() */
/************************************************************************
* * OutputFrameSizeStats */ extern void OutputFrameSizeStats(char * filename) { U32 uSumBitStream; U32 uSumFrame; FILE * fp; int i;
FX_ENTRY("OutputFrameSizeStats")
ASSERT(iFrameSizeIndex <= (MAX_FRAME_SIZE_INDEX+1)); fp = fopen(filename, "a"); if (fp == NULL) { ERRORMESSAGE(("%s: Error opening stats file\r\n", _fx_)); } else { uSumBitStream = 0; uSumFrame = 0; for (i = 0; i < iFrameSizeIndex ; i++) { uSumFrame += uArrayFrameSize[i]; uSumBitStream += uArrayBitStreamSize[i]; if (uArrayFrameSize[i] != uArrayBitStreamSize[i]) { fprintf(fp, "Frame[%d] Sizes: Frame=%d BitStream=%d Other=%d\n", i, (int) uArrayFrameSize[i], (int) uArrayBitStreamSize[i], (int) (uArrayFrameSize[i] - uArrayBitStreamSize[i])); } else { fprintf(fp,"Frame[%d] Size=%d\n", (int) i, (int) uArrayFrameSize[i]); } } if (iFrameSizeIndex > 0) { if (uSumFrame != uSumBitStream) { fprintf(fp,"Count = %ld Average Sizes: Frm=%f BS=%f Other=%f\n", (long) iFrameSizeIndex, ((float)uSumFrame)/((float)iFrameSizeIndex), ((float)uSumBitStream)/((float)iFrameSizeIndex), ((float)(uSumFrame - uSumBitStream))/((float)iFrameSizeIndex)); } else { fprintf(fp,"Count = %ld Average Size=%f\n", (long) iFrameSizeIndex, ((float)uSumFrame)/((float)iFrameSizeIndex)); } } else { fprintf(fp,"No frame size statistics available\n"); } fclose(fp); } } /* end OutputFrameSizeStats() */
/************************************************************************
* * InitQuantStats */ extern void InitQuantStats() { int i; for (i = 0 ; i < 32 ; i++) { uQuantCount[i] = 0; } } /* end InitQuantStats() */
/************************************************************************
* * StatsUsedQuant */ extern void StatsUsedQuant( int iQuant) { ASSERT(iQuant >= 1 && iQuant <= 31); uQuantCount[iQuant]++; } /* end StatsUsedQuant() */
/************************************************************************
* * OutputQuantStats */ extern void OutputQuantStats(char * filename) { U32 uCount; U32 uTotal; FILE * fp; int i;
FX_ENTRY("OutputQuantStats")
fp = fopen(filename, "a"); if (fp == NULL) { ERRORMESSAGE(("%s: Error opening stats file\r\n", _fx_)); } else { uCount = 0; uTotal = 0; for (i = 0; i < 32 ; i++) { if (uQuantCount[i] > 0) { uCount += uQuantCount[i]; uTotal += (uQuantCount[i] * i); fprintf(fp,"Quant[%d] = %ld\n", (int)i, (long) uQuantCount[i]); } } if (uCount > 0) { fprintf(fp,"Count = %ld Average = %f\n", (long) uCount, ((float)uTotal)/((float)uCount)); } else { fprintf(fp,"No quantization statistics available\n"); } fclose(fp); } } /* end OutputQuantStats() */
/************************************************************************
* * InitPSNRStats - initialize the PSNR data structures */ extern void InitPSNRStats() { int i; for (i = 0; i <= MAX_PSNR_INDEX; i++) { dArrayYPSNR[i] = 0.0; dArrayVPSNR[i] = 0.0; dArrayUPSNR[i] = 0.0; } iPSNRIndex = 0; } /* end InitPSNRStats() */
/************************************************************************
* * OutputPSNRStats - output the PSNR data to the specified file */ extern void OutputPSNRStats( char * filename) { int i; FILE * fp; double dYTotal; double dVTotal; double dUTotal;
FX_ENTRY("OutputPSNRStats")
ASSERT(iPSNRIndex <= (MAX_PSNR_INDEX+1));
fp = fopen(filename, "a"); if (fp == NULL) { ERRORMESSAGE(("%s: Unable to open PSNR output file\r\n", _fx_)); } else { if (iPSNRIndex <= 0) { fprintf(fp,"No PSNR data available\n"); } else { dYTotal = 0.0; dVTotal = 0.0; dUTotal = 0.0; for (i = 0; i < iPSNRIndex ; i++) { dYTotal += dArrayYPSNR[i]; dVTotal += dArrayVPSNR[i]; dUTotal += dArrayUPSNR[i]; fprintf(fp, "YVU#%d = %f %f %f\n", (int)i, dArrayYPSNR[i],dArrayVPSNR[i],dArrayUPSNR[i]); } fprintf(fp, "Average = %f %f %f\n", dYTotal/((double)iPSNRIndex), dVTotal/((double)iPSNRIndex), dUTotal/((double)iPSNRIndex)); } fclose(fp); } } /* end OutputPSNRStats */
/********************************************************************
* * IncrementPSNRCounter() */ extern void IncrementPSNRCounter() { if (iPSNRIndex <= MAX_PSNR_INDEX) { iPSNRIndex++; } } /* end IncrementPSNRCounter() */
/************************************************************************
* * ComputeYPSNR - compute the Y PSNR Value */ extern void ComputeYPSNR( U8 * pu8Input, int iInputPitch, U8 * pu8Output, int iOutputPitch, UN unWidth, UN unHeight) { double dPSNR; if (iPSNRIndex <= MAX_PSNR_INDEX) { dPSNR = ComputePSNR(pu8Input,iInputPitch, pu8Output,iOutputPitch, unWidth,unHeight); dArrayYPSNR[iPSNRIndex] = dPSNR; } } /* end ComputeYPSNR() */
/************************************************************************
* * ComputeVPSNR - compute the V PSNR Value */ extern void ComputeVPSNR( U8 * pu8Input, int iInputPitch, U8 * pu8Output, int iOutputPitch, UN unWidth, UN unHeight) { double dPSNR; if (iPSNRIndex <= MAX_PSNR_INDEX) { dPSNR = ComputePSNR(pu8Input,iInputPitch, pu8Output,iOutputPitch, unWidth,unHeight); dArrayVPSNR[iPSNRIndex] = dPSNR; } } /* end ComputeVPSNR() */
/************************************************************************
* * ComputeUPSNR - compute the U PSNR Value */ extern void ComputeUPSNR( U8 * pu8Input, int iInputPitch, U8 * pu8Output, int iOutputPitch, UN unWidth, UN unHeight) { double dPSNR; if (iPSNRIndex <= MAX_PSNR_INDEX) { dPSNR = ComputePSNR(pu8Input,iInputPitch, pu8Output,iOutputPitch, unWidth,unHeight); dArrayUPSNR[iPSNRIndex] = dPSNR; } } /* end ComputeUPSNR() */
/***************************** STATIC ROUTINES *************************/
/************************************************************************
* * ComputePSNR - compute Peek Signal to Noise Ratio over this plane * * 255*255 * PSNR = 10log ---------------------------- * 10 SUM((I-O)(I-O))/Wdith*Height */ static double ComputePSNR( U8 * pu8Input, int iInputPitch, U8 * pu8Output, int iOutputPitch, UN unWidth, UN unHeight) { UN unW; UN unH; U32 uSum; double dMSE; double dPSNR; double dTemp; int iInput; int iOutput; int iDiff; int iSquareOfDiff;
/* Obtain the sum of the square of the differences
*/ uSum = 0; for (unH = 0; unH < unHeight; unH++) { for (unW = 0; unW < unWidth; unW++) { iInput = (int)*pu8Input++; iOutput = (int)*pu8Output++; iDiff = iInput - iOutput; iSquareOfDiff = iDiff*iDiff; uSum += (U32) iSquareOfDiff; } pu8Input += (iInputPitch - (int)unWidth); pu8Output += (iOutputPitch - (int)unWidth); }
/* Obtain the Mean Squared Error
*/ if (uSum == 0) { dMSE = 0.01; /* a non-zero value */ } else { dMSE = ((double)uSum)/((double)(unWidth*unHeight)); }
/* Obtain PSNR
*/ dTemp = (255.0 * 255.0) / dMSE; dTemp = log10(dTemp); dPSNR = 10.0 * dTemp;
return dPSNR; } /* end ComputePSNR() */
#endif /* ENCODE_STATS */
|