Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

453 lines
11 KiB

/* *************************************************************************
** 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 */