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

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1996 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ****************************************************************************
  13. *
  14. * e3stat.cpp
  15. *
  16. * Description:
  17. * This modules contains the encoder statistics routines
  18. *
  19. * Routines: All routines declared in e3stat.h
  20. * StatsFrameSize
  21. * InitFrameSizeStats
  22. * OutputFrameSizeStats
  23. *
  24. * StatsUsedQuant
  25. * InitQuantStats
  26. * OutputQuantStats
  27. *
  28. * InitPSNRStats
  29. * OutputPSNRStats
  30. * InitStats
  31. * IncrementPSNRCounter
  32. * ComputeYPSNR
  33. * ComputeVPSNR
  34. * ComputeUPSNR
  35. *
  36. * Data:
  37. // $Header: R:\h26x\h26x\src\enc\e3stat.cpv 1.0 22 Apr 1996 17:46:22 BECHOLS $
  38. // $Log: R:\h26x\h26x\src\enc\e3stat.cpv $
  39. //
  40. // Rev 1.0 22 Apr 1996 17:46:22 BECHOLS
  41. // Initial revision.
  42. //
  43. // Rev 1.1 08 Mar 1996 14:14:26 DBRUCKS
  44. // add framesize stats and fixed PSNR to use energy instead of the signal
  45. //
  46. // Rev 1.0 01 Mar 1996 16:34:40 DBRUCKS
  47. // Initial revision.
  48. */
  49. #include "precomp.h"
  50. #ifdef ENCODE_STATS
  51. #define MAX_FRAME_SIZE_INDEX 255
  52. static U32 uArrayFrameSize[MAX_FRAME_SIZE_INDEX+1];
  53. static U32 uArrayBitStreamSize[MAX_FRAME_SIZE_INDEX+1];
  54. static int iFrameSizeIndex = 0;
  55. static U32 uQuantCount[32];
  56. #define MAX_PSNR_INDEX 255
  57. static double dArrayYPSNR[MAX_PSNR_INDEX+1];
  58. static double dArrayVPSNR[MAX_PSNR_INDEX+1];
  59. static double dArrayUPSNR[MAX_PSNR_INDEX+1];
  60. static int iPSNRIndex = 0;
  61. static double ComputePSNR(U8 * pu8Input,
  62. int iInputPitch,
  63. U8 * pu8Output,
  64. int iOutputPitch,
  65. UN unWidth,
  66. UN unHeight);
  67. /************************************************************************
  68. *
  69. * StatsFrameSize
  70. *
  71. * Save the frame size information - with possbily different bitstream
  72. * and frame sizes.
  73. */
  74. extern void StatsFrameSize(U32 uBitStreamSize, U32 uFrameSize)
  75. {
  76. ASSERT(uFrameSize >= uBitStreamSize);
  77. if (iFrameSizeIndex <= MAX_FRAME_SIZE_INDEX)
  78. {
  79. uArrayBitStreamSize[iFrameSizeIndex] = uBitStreamSize;
  80. uArrayFrameSize[iFrameSizeIndex] = uFrameSize;
  81. iFrameSizeIndex++; /* can grow to one larger than MAX_FRAME_SIZE_INDEX */
  82. }
  83. } /* end StatsFrameSize() */
  84. /************************************************************************
  85. *
  86. * InitFrameSizeStats
  87. */
  88. extern void InitFrameSizeStats()
  89. {
  90. int i;
  91. for (i = 0; i <= MAX_FRAME_SIZE_INDEX ; i++)
  92. {
  93. uArrayFrameSize[i] = 0;
  94. uArrayBitStreamSize[i] = 0;
  95. }
  96. iFrameSizeIndex = 0;
  97. } /* end InitFrameSizeStats() */
  98. /************************************************************************
  99. *
  100. * OutputFrameSizeStats
  101. */
  102. extern void OutputFrameSizeStats(char * filename)
  103. {
  104. U32 uSumBitStream;
  105. U32 uSumFrame;
  106. FILE * fp;
  107. int i;
  108. FX_ENTRY("OutputFrameSizeStats")
  109. ASSERT(iFrameSizeIndex <= (MAX_FRAME_SIZE_INDEX+1));
  110. fp = fopen(filename, "a");
  111. if (fp == NULL)
  112. {
  113. ERRORMESSAGE(("%s: Error opening stats file\r\n", _fx_));
  114. }
  115. else
  116. {
  117. uSumBitStream = 0;
  118. uSumFrame = 0;
  119. for (i = 0; i < iFrameSizeIndex ; i++)
  120. {
  121. uSumFrame += uArrayFrameSize[i];
  122. uSumBitStream += uArrayBitStreamSize[i];
  123. if (uArrayFrameSize[i] != uArrayBitStreamSize[i])
  124. {
  125. fprintf(fp, "Frame[%d] Sizes: Frame=%d BitStream=%d Other=%d\n",
  126. i, (int) uArrayFrameSize[i], (int) uArrayBitStreamSize[i],
  127. (int) (uArrayFrameSize[i] - uArrayBitStreamSize[i]));
  128. }
  129. else
  130. {
  131. fprintf(fp,"Frame[%d] Size=%d\n", (int) i, (int) uArrayFrameSize[i]);
  132. }
  133. }
  134. if (iFrameSizeIndex > 0)
  135. {
  136. if (uSumFrame != uSumBitStream)
  137. {
  138. fprintf(fp,"Count = %ld Average Sizes: Frm=%f BS=%f Other=%f\n",
  139. (long) iFrameSizeIndex,
  140. ((float)uSumFrame)/((float)iFrameSizeIndex),
  141. ((float)uSumBitStream)/((float)iFrameSizeIndex),
  142. ((float)(uSumFrame - uSumBitStream))/((float)iFrameSizeIndex));
  143. }
  144. else
  145. {
  146. fprintf(fp,"Count = %ld Average Size=%f\n", (long) iFrameSizeIndex,
  147. ((float)uSumFrame)/((float)iFrameSizeIndex));
  148. }
  149. }
  150. else
  151. {
  152. fprintf(fp,"No frame size statistics available\n");
  153. }
  154. fclose(fp);
  155. }
  156. } /* end OutputFrameSizeStats() */
  157. /************************************************************************
  158. *
  159. * InitQuantStats
  160. */
  161. extern void InitQuantStats()
  162. {
  163. int i;
  164. for (i = 0 ; i < 32 ; i++)
  165. {
  166. uQuantCount[i] = 0;
  167. }
  168. } /* end InitQuantStats() */
  169. /************************************************************************
  170. *
  171. * StatsUsedQuant
  172. */
  173. extern void StatsUsedQuant(
  174. int iQuant)
  175. {
  176. ASSERT(iQuant >= 1 && iQuant <= 31);
  177. uQuantCount[iQuant]++;
  178. } /* end StatsUsedQuant() */
  179. /************************************************************************
  180. *
  181. * OutputQuantStats
  182. */
  183. extern void OutputQuantStats(char * filename)
  184. {
  185. U32 uCount;
  186. U32 uTotal;
  187. FILE * fp;
  188. int i;
  189. FX_ENTRY("OutputQuantStats")
  190. fp = fopen(filename, "a");
  191. if (fp == NULL)
  192. {
  193. ERRORMESSAGE(("%s: Error opening stats file\r\n", _fx_));
  194. }
  195. else
  196. {
  197. uCount = 0;
  198. uTotal = 0;
  199. for (i = 0; i < 32 ; i++)
  200. {
  201. if (uQuantCount[i] > 0)
  202. {
  203. uCount += uQuantCount[i];
  204. uTotal += (uQuantCount[i] * i);
  205. fprintf(fp,"Quant[%d] = %ld\n",
  206. (int)i, (long) uQuantCount[i]);
  207. }
  208. }
  209. if (uCount > 0)
  210. {
  211. fprintf(fp,"Count = %ld Average = %f\n",
  212. (long) uCount, ((float)uTotal)/((float)uCount));
  213. }
  214. else
  215. {
  216. fprintf(fp,"No quantization statistics available\n");
  217. }
  218. fclose(fp);
  219. }
  220. } /* end OutputQuantStats() */
  221. /************************************************************************
  222. *
  223. * InitPSNRStats - initialize the PSNR data structures
  224. */
  225. extern void InitPSNRStats()
  226. {
  227. int i;
  228. for (i = 0; i <= MAX_PSNR_INDEX; i++)
  229. {
  230. dArrayYPSNR[i] = 0.0;
  231. dArrayVPSNR[i] = 0.0;
  232. dArrayUPSNR[i] = 0.0;
  233. }
  234. iPSNRIndex = 0;
  235. } /* end InitPSNRStats() */
  236. /************************************************************************
  237. *
  238. * OutputPSNRStats - output the PSNR data to the specified file
  239. */
  240. extern void OutputPSNRStats(
  241. char * filename)
  242. {
  243. int i;
  244. FILE * fp;
  245. double dYTotal;
  246. double dVTotal;
  247. double dUTotal;
  248. FX_ENTRY("OutputPSNRStats")
  249. ASSERT(iPSNRIndex <= (MAX_PSNR_INDEX+1));
  250. fp = fopen(filename, "a");
  251. if (fp == NULL)
  252. {
  253. ERRORMESSAGE(("%s: Unable to open PSNR output file\r\n", _fx_));
  254. }
  255. else
  256. {
  257. if (iPSNRIndex <= 0)
  258. {
  259. fprintf(fp,"No PSNR data available\n");
  260. }
  261. else
  262. {
  263. dYTotal = 0.0;
  264. dVTotal = 0.0;
  265. dUTotal = 0.0;
  266. for (i = 0; i < iPSNRIndex ; i++)
  267. {
  268. dYTotal += dArrayYPSNR[i];
  269. dVTotal += dArrayVPSNR[i];
  270. dUTotal += dArrayUPSNR[i];
  271. fprintf(fp, "YVU#%d = %f %f %f\n", (int)i,
  272. dArrayYPSNR[i],dArrayVPSNR[i],dArrayUPSNR[i]);
  273. }
  274. fprintf(fp, "Average = %f %f %f\n",
  275. dYTotal/((double)iPSNRIndex),
  276. dVTotal/((double)iPSNRIndex),
  277. dUTotal/((double)iPSNRIndex));
  278. }
  279. fclose(fp);
  280. }
  281. } /* end OutputPSNRStats */
  282. /********************************************************************
  283. *
  284. * IncrementPSNRCounter()
  285. */
  286. extern void IncrementPSNRCounter()
  287. {
  288. if (iPSNRIndex <= MAX_PSNR_INDEX)
  289. {
  290. iPSNRIndex++;
  291. }
  292. } /* end IncrementPSNRCounter() */
  293. /************************************************************************
  294. *
  295. * ComputeYPSNR - compute the Y PSNR Value
  296. */
  297. extern void ComputeYPSNR(
  298. U8 * pu8Input,
  299. int iInputPitch,
  300. U8 * pu8Output,
  301. int iOutputPitch,
  302. UN unWidth,
  303. UN unHeight)
  304. {
  305. double dPSNR;
  306. if (iPSNRIndex <= MAX_PSNR_INDEX)
  307. {
  308. dPSNR = ComputePSNR(pu8Input,iInputPitch,
  309. pu8Output,iOutputPitch,
  310. unWidth,unHeight);
  311. dArrayYPSNR[iPSNRIndex] = dPSNR;
  312. }
  313. } /* end ComputeYPSNR() */
  314. /************************************************************************
  315. *
  316. * ComputeVPSNR - compute the V PSNR Value
  317. */
  318. extern void ComputeVPSNR(
  319. U8 * pu8Input,
  320. int iInputPitch,
  321. U8 * pu8Output,
  322. int iOutputPitch,
  323. UN unWidth,
  324. UN unHeight)
  325. {
  326. double dPSNR;
  327. if (iPSNRIndex <= MAX_PSNR_INDEX)
  328. {
  329. dPSNR = ComputePSNR(pu8Input,iInputPitch,
  330. pu8Output,iOutputPitch,
  331. unWidth,unHeight);
  332. dArrayVPSNR[iPSNRIndex] = dPSNR;
  333. }
  334. } /* end ComputeVPSNR() */
  335. /************************************************************************
  336. *
  337. * ComputeUPSNR - compute the U PSNR Value
  338. */
  339. extern void ComputeUPSNR(
  340. U8 * pu8Input,
  341. int iInputPitch,
  342. U8 * pu8Output,
  343. int iOutputPitch,
  344. UN unWidth,
  345. UN unHeight)
  346. {
  347. double dPSNR;
  348. if (iPSNRIndex <= MAX_PSNR_INDEX)
  349. {
  350. dPSNR = ComputePSNR(pu8Input,iInputPitch,
  351. pu8Output,iOutputPitch,
  352. unWidth,unHeight);
  353. dArrayUPSNR[iPSNRIndex] = dPSNR;
  354. }
  355. } /* end ComputeUPSNR() */
  356. /***************************** STATIC ROUTINES *************************/
  357. /************************************************************************
  358. *
  359. * ComputePSNR - compute Peek Signal to Noise Ratio over this plane
  360. *
  361. * 255*255
  362. * PSNR = 10log ----------------------------
  363. * 10 SUM((I-O)(I-O))/Wdith*Height
  364. */
  365. static double ComputePSNR(
  366. U8 * pu8Input,
  367. int iInputPitch,
  368. U8 * pu8Output,
  369. int iOutputPitch,
  370. UN unWidth,
  371. UN unHeight)
  372. {
  373. UN unW;
  374. UN unH;
  375. U32 uSum;
  376. double dMSE;
  377. double dPSNR;
  378. double dTemp;
  379. int iInput;
  380. int iOutput;
  381. int iDiff;
  382. int iSquareOfDiff;
  383. /* Obtain the sum of the square of the differences
  384. */
  385. uSum = 0;
  386. for (unH = 0; unH < unHeight; unH++)
  387. {
  388. for (unW = 0; unW < unWidth; unW++)
  389. {
  390. iInput = (int)*pu8Input++;
  391. iOutput = (int)*pu8Output++;
  392. iDiff = iInput - iOutput;
  393. iSquareOfDiff = iDiff*iDiff;
  394. uSum += (U32) iSquareOfDiff;
  395. }
  396. pu8Input += (iInputPitch - (int)unWidth);
  397. pu8Output += (iOutputPitch - (int)unWidth);
  398. }
  399. /* Obtain the Mean Squared Error
  400. */
  401. if (uSum == 0)
  402. {
  403. dMSE = 0.01; /* a non-zero value */
  404. }
  405. else
  406. {
  407. dMSE = ((double)uSum)/((double)(unWidth*unHeight));
  408. }
  409. /* Obtain PSNR
  410. */
  411. dTemp = (255.0 * 255.0) / dMSE;
  412. dTemp = log10(dTemp);
  413. dPSNR = 10.0 * dTemp;
  414. return dPSNR;
  415. } /* end ComputePSNR() */
  416. #endif /* ENCODE_STATS */