CXvid.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // CXvid.cpp: implementation of the CXvid class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "XvidQuantsParser.h"
  6. #include "CXvid.h"
  7. #include <time.h>
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CXvid::CXvid()
  17. {
  18. quants = NULL;
  19. isOpened = false;
  20. isAnalysed = false;
  21. }
  22. //------------------------------------------------------------------------------
  23. CXvid::~CXvid()
  24. {
  25. if (quants != NULL)
  26. {
  27. delete[] quants;
  28. quants = NULL;
  29. }
  30. }
  31. //------------------------------------------------------------------------------
  32. //打开Xvid文件
  33. int CXvid::Open(CString filepath)
  34. {
  35. HIC hic; // HIC和ICINFO定义在VfW.H - Video for Windows头文件
  36. ICINFO icinfo; // 一般在Microsoft Visual StudioVC98Include目录下
  37. //InputFileAVI类
  38. InputFileAVI* inputAVI = new InputFileAVI(false);
  39. inputAVI->Init((char*)(LPCTSTR)filepath);
  40. VideoSourceAVI* inputVideoAVI;
  41. inputVideoAVI = (VideoSourceAVI*)inputAVI->videoSrc;
  42. //验证XVID中的fourCC
  43. hic = inputVideoAVI->getDecompressorHandle(); //得到当前文件的解码器句柄
  44. ICGetInfo(hic, &icinfo, sizeof(ICINFO));
  45. if(!icinfo.fccHandler == mmioFOURCC('X','V','I','D'))
  46. {
  47. AfxMessageBox("Not a valid Xvid AVI File!");
  48. return 1;
  49. }
  50. //得到这个AVI文件的信息
  51. //得到每秒钟的帧数
  52. fps = (float)inputVideoAVI->streamInfo.dwRate / (float)inputVideoAVI->streamInfo.dwScale;
  53. height = inputVideoAVI->getImageFormat()->biHeight; //视频的高度
  54. width = inputVideoAVI->getImageFormat()->biWidth; //视频的宽度
  55. nframes = inputVideoAVI->lSampleLast; //帧的数目
  56. if (nframes < 100)
  57. {
  58. return 2; //不允许小于100个视频帧
  59. }
  60. //一切正常
  61. avipath = filepath; //设置文件路径
  62. delete inputAVI;
  63. isAnalysed = false; //文件还没有被分析
  64. isOpened = true; //文件已经打开
  65. return 0;
  66. }
  67. //------------------------------------------------------------------------------
  68. //分析Xvid文件
  69. int CXvid::Analyze(CProgressCtrl &progress, CEdit &edit, bool log, int start, int stop)
  70. {
  71. //如果没有打开Xvid文件
  72. if (!isOpened)
  73. {
  74. AfxMessageBox("No Xvid AVI file opened!");
  75. return 1;
  76. }
  77. COleDateTime objOle;
  78. CString strTime;
  79. char buflog[50];
  80. LONG lActualBytes;
  81. UCHAR* b=NULL;
  82. int pbjump = (stop-start)/100;
  83. int pbcount = 0;
  84. int pbpos = 0;
  85. icount=0; pcount=0;
  86. nsum=0; isum=0; psum=0;
  87. nmax=0; nmin=32;
  88. nfsmax = 0; nfsmin = 999999999;
  89. ifsmax = 0; ifsmin = 999999999;
  90. pfsmax = 0; pfsmin = 999999999;
  91. InputFileAVI *inputAVI = new InputFileAVI(false);
  92. inputAVI->Init((char*)(LPCTSTR)avipath);
  93. VideoSourceAVI *inputVideoAVI;
  94. inputVideoAVI = (VideoSourceAVI*) inputAVI->videoSrc;
  95. progress.SetRange(0, 100);
  96. progress.SetPos(0);
  97. //如果打开了分析日志
  98. if (log)
  99. {
  100. logfile.Open("analysis.log");
  101. logfile.Print("--------------------------------------------------------------------------------------n");
  102. logfile.Print("Generated by Xvid Quants Parser v1.0n");
  103. logfile.Print("--------------------------------------------------------------------------------------n");
  104. logfile.Print("File: t");
  105. logfile.Print((char*)(LPCTSTR)avipath);
  106. logfile.Print("n");
  107. logfile.Print("Frames:t");
  108. _itoa(nframes, buflog, 10);
  109. logfile.Print(buflog);
  110. logfile.Print("n");
  111. logfile.Print("Start:t");
  112. _itoa(start, buflog, 10);
  113. logfile.Print(buflog);
  114. logfile.Print("n");
  115. logfile.Print("End:t");
  116. _itoa(stop, buflog, 10);
  117. logfile.Print(buflog);
  118. logfile.Print("n");
  119. logfile.Print("Length:t");
  120. _itoa(stop-start, buflog, 10);
  121. logfile.Print(buflog);
  122. logfile.Print("n");
  123. logfile.Print("--------------------------------------------------------------------------------------n");
  124. logfile.Print("Quantizer log:n");
  125. logfile.Print("--------------------------------------------------------------------------------------n");
  126. }
  127. //---------------------------------------------------------------------------
  128. //删除以前的quants数组
  129. if (quants != NULL)
  130. {
  131. delete[] quants;
  132. quants = NULL;
  133. }
  134. //创建新的quants数组
  135. quants = new QUANTS[stop-start];
  136. //记录分析的开始时间
  137. clock_t debut = clock();
  138. // 开始分析
  139. for (int i=start; i<stop; i++)
  140. {
  141. //得到帧的大小等数据
  142. inputVideoAVI->read(i, 1, NULL, 0, &lActualBytes, NULL);
  143. b = new UCHAR[lActualBytes];
  144. //把帧的数据读入到b中
  145. inputVideoAVI->read(i, 1, b, lActualBytes, &lActualBytes, NULL);
  146. //检查帧大小的最小/最大值
  147. quants[i-start].framesize = lActualBytes;
  148. if (lActualBytes>nfsmax) nfsmax = lActualBytes;
  149. if (lActualBytes<nfsmin) nfsmin = lActualBytes;
  150. // 如果是关键帧-I帧
  151. if (inputVideoAVI->isKey(i))
  152. {
  153. quants[i-start].isIFrame = true;
  154. icount++;
  155. //检查I帧大小的最小/最大值
  156. if (lActualBytes>ifsmax) ifsmax = lActualBytes;
  157. if (lActualBytes<ifsmin) ifsmin = lActualBytes;
  158. if (b[24] == 0x28)
  159. {
  160. isum += b[27]>>1;
  161. nsum += b[27]>>1;
  162. quants[i-start].qvalue = b[27]>>1;
  163. if (b[27]>>1 > nmax) nmax = b[27]>>1;
  164. if (b[27]>>1 < nmin) nmin = b[27]>>1;
  165. }
  166. else
  167. {
  168. isum += (b[27] & 0x3E)>>2;
  169. nsum += (b[27] & 0x3E)>>2;
  170. quants[i-start].qvalue = (b[27] & 0x3E)>>2;
  171. if ((b[27] & 0x3E)>>2 > nmax) nmax = (b[27] & 0x3E)>>2;
  172. if ((b[27] & 0x3E)>>2 < nmin) nmin = (b[27] & 0x3E)>>2;
  173. }
  174. //如果打开了分析日志
  175. if (log)
  176. {
  177. objOle = COleDateTime::GetCurrentTime();
  178. strTime = objOle.Format("%H:%M:%S");
  179. sprintf(buflog, "%s - %dtIF:Q%dt%dn", strTime, i+1, quants[i-start].qvalue, lActualBytes);
  180. }
  181. }
  182. else //如果不是关键帧(I帧)
  183. {
  184. quants[i-start].isIFrame = false;
  185. pcount++;
  186. if (lActualBytes>pfsmax) pfsmax = lActualBytes;
  187. if (lActualBytes<pfsmin) pfsmin = lActualBytes;
  188. if (b[4] == 0x68)
  189. {
  190. psum += b[7];
  191. nsum += b[7];
  192. quants[i-start].qvalue = b[7];
  193. if (b[7] > nmax) nmax = b[7];
  194. if (b[7] < nmin) nmin = b[7];
  195. }
  196. else
  197. {
  198. psum += (b[7] & 0x3E)>>1;
  199. nsum += (b[7] & 0x3E)>>1;
  200. quants[i-start].qvalue = (b[7] & 0x3E)>>1;
  201. if ((b[7] & 0x3E)>>1 > nmax) nmax = (b[7] & 0x3E)>>1;
  202. if ((b[7] & 0x3E)>>1 < nmin) nmin = (b[7] & 0x3E)>>1;
  203. }
  204. //如果打开了分析日志
  205. if (log)
  206. {
  207. objOle = COleDateTime::GetCurrentTime();
  208. strTime = objOle.Format("%H:%M:%S");
  209. sprintf(buflog, "%s - %dtPF:Q%dt%dn", strTime, i+1, quants[i-start].qvalue, lActualBytes);
  210. }
  211. }
  212. //如果打开了分析日志
  213. if (log) logfile.Print(buflog);
  214. if (b!=NULL)
  215. {
  216. delete[] b;
  217. b=NULL;
  218. }
  219. if (pbcount == pbjump)
  220. {
  221. pbcount = 0;
  222. pbpos++;
  223. progress.SetPos(pbpos);
  224. char buf[50];
  225. sprintf(buf, "Analyzing: %d %% Completed", i*100/(stop-start-1));
  226. edit.SetSel(0, edit.LineLength());
  227. edit.ReplaceSel(buf);
  228. }
  229. pbcount++;
  230. }
  231. //记录分析的结束时间
  232. clock_t fin = clock();
  233. //得到分析的时间
  234. long temps = fin - debut;
  235. char buf[50];
  236. if (temps > 1000)
  237. sprintf(buf, "Analyzed %d frames in %d seconds", nframes, temps/1000);
  238. else
  239. sprintf(buf, "Analyzed %d frames in %d milliseconds", (stop-start), temps);
  240. edit.SetSel(0, edit.LineLength());
  241. edit.ReplaceSel(buf);
  242. navg = (float)nsum/(stop-start);
  243. pavg = (float)psum/pcount;
  244. iavg = (float)isum/icount;
  245. //如果打开了分析日志
  246. if (log)
  247. {
  248. logfile.Print("--------------------------------------------------------------------------------------n");
  249. logfile.Print("End of logn");
  250. logfile.Print("--------------------------------------------------------------------------------------n");
  251. logfile.Close();
  252. }
  253. delete inputAVI;
  254. isAnalysed = true;
  255. return 0;
  256. }
  257. //------------------------------------------------------------------------------
  258. void CXvid::Close(void)
  259. {
  260. if (quants != NULL)
  261. {
  262. delete[] quants;
  263. quants = NULL;
  264. }
  265. isOpened = false;
  266. isAnalysed = false;
  267. }
  268. //------------------------------------------------------------------------------
  269. void CXvid::SetQuantsArray(CXvid::QUANTS* qvalues, int nelem)
  270. {
  271. if (quants != NULL)
  272. {
  273. delete[] quants;
  274. quants = NULL;
  275. }
  276. quants = qvalues;
  277. nframes = nelem;
  278. }