www.pudn.com > XvidQP.rar > CXvid.cpp
// CXvid.cpp: implementation of the CXvid class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "XvidQuantsParser.h" #include "CXvid.h" #include#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CXvid::CXvid() { quants = NULL; isOpened = false; isAnalysed = false; } //------------------------------------------------------------------------------ CXvid::~CXvid() { if (quants != NULL) { delete[] quants; quants = NULL; } } //------------------------------------------------------------------------------ //打开Xvid文件 int CXvid::Open(CString filepath) { HIC hic; // HIC和ICINFO定义在VfW.H - Video for Windows头文件 ICINFO icinfo; // 一般在\Microsoft Visual Studio\VC98\Include\目录下 //InputFileAVI类 InputFileAVI* inputAVI = new InputFileAVI(false); inputAVI->Init((char*)(LPCTSTR)filepath); VideoSourceAVI* inputVideoAVI; inputVideoAVI = (VideoSourceAVI*)inputAVI->videoSrc; //验证XVID中的fourCC hic = inputVideoAVI->getDecompressorHandle(); //得到当前文件的解码器句柄 ICGetInfo(hic, &icinfo, sizeof(ICINFO)); if(!icinfo.fccHandler == mmioFOURCC('X','V','I','D')) { AfxMessageBox("Not a valid Xvid AVI File!"); return 1; } //得到这个AVI文件的信息 //得到每秒钟的帧数 fps = (float)inputVideoAVI->streamInfo.dwRate / (float)inputVideoAVI->streamInfo.dwScale; height = inputVideoAVI->getImageFormat()->biHeight; //视频的高度 width = inputVideoAVI->getImageFormat()->biWidth; //视频的宽度 nframes = inputVideoAVI->lSampleLast; //帧的数目 if (nframes < 100) { return 2; //不允许小于100个视频帧 } //一切正常 avipath = filepath; //设置文件路径 delete inputAVI; isAnalysed = false; //文件还没有被分析 isOpened = true; //文件已经打开 return 0; } //------------------------------------------------------------------------------ //分析Xvid文件 int CXvid::Analyze(CProgressCtrl &progress, CEdit &edit, bool log, int start, int stop) { //如果没有打开Xvid文件 if (!isOpened) { AfxMessageBox("No Xvid AVI file opened!"); return 1; } COleDateTime objOle; CString strTime; char buflog[50]; LONG lActualBytes; UCHAR* b=NULL; int pbjump = (stop-start)/100; int pbcount = 0; int pbpos = 0; icount=0; pcount=0; nsum=0; isum=0; psum=0; nmax=0; nmin=32; nfsmax = 0; nfsmin = 999999999; ifsmax = 0; ifsmin = 999999999; pfsmax = 0; pfsmin = 999999999; InputFileAVI *inputAVI = new InputFileAVI(false); inputAVI->Init((char*)(LPCTSTR)avipath); VideoSourceAVI *inputVideoAVI; inputVideoAVI = (VideoSourceAVI*) inputAVI->videoSrc; progress.SetRange(0, 100); progress.SetPos(0); //如果打开了分析日志 if (log) { logfile.Open("analysis.log"); logfile.Print("--------------------------------------------------------------------------------------\n"); logfile.Print("Generated by Xvid Quants Parser v1.0\n"); logfile.Print("--------------------------------------------------------------------------------------\n"); logfile.Print("File: \t"); logfile.Print((char*)(LPCTSTR)avipath); logfile.Print("\n"); logfile.Print("Frames:\t"); _itoa(nframes, buflog, 10); logfile.Print(buflog); logfile.Print("\n"); logfile.Print("Start:\t"); _itoa(start, buflog, 10); logfile.Print(buflog); logfile.Print("\n"); logfile.Print("End:\t"); _itoa(stop, buflog, 10); logfile.Print(buflog); logfile.Print("\n"); logfile.Print("Length:\t"); _itoa(stop-start, buflog, 10); logfile.Print(buflog); logfile.Print("\n"); logfile.Print("--------------------------------------------------------------------------------------\n"); logfile.Print("Quantizer log:\n"); logfile.Print("--------------------------------------------------------------------------------------\n"); } //--------------------------------------------------------------------------- //删除以前的quants数组 if (quants != NULL) { delete[] quants; quants = NULL; } //创建新的quants数组 quants = new QUANTS[stop-start]; //记录分析的开始时间 clock_t debut = clock(); // 开始分析 for (int i=start; i read(i, 1, NULL, 0, &lActualBytes, NULL); b = new UCHAR[lActualBytes]; //把帧的数据读入到b中 inputVideoAVI->read(i, 1, b, lActualBytes, &lActualBytes, NULL); //检查帧大小的最小/最大值 quants[i-start].framesize = lActualBytes; if (lActualBytes>nfsmax) nfsmax = lActualBytes; if (lActualBytes isKey(i)) { quants[i-start].isIFrame = true; icount++; //检查I帧大小的最小/最大值 if (lActualBytes>ifsmax) ifsmax = lActualBytes; if (lActualBytes >1; nsum += b[27]>>1; quants[i-start].qvalue = b[27]>>1; if (b[27]>>1 > nmax) nmax = b[27]>>1; if (b[27]>>1 < nmin) nmin = b[27]>>1; } else { isum += (b[27] & 0x3E)>>2; nsum += (b[27] & 0x3E)>>2; quants[i-start].qvalue = (b[27] & 0x3E)>>2; if ((b[27] & 0x3E)>>2 > nmax) nmax = (b[27] & 0x3E)>>2; if ((b[27] & 0x3E)>>2 < nmin) nmin = (b[27] & 0x3E)>>2; } //如果打开了分析日志 if (log) { objOle = COleDateTime::GetCurrentTime(); strTime = objOle.Format("%H:%M:%S"); sprintf(buflog, "%s - %d\tIF:Q%d\t%d\n", strTime, i+1, quants[i-start].qvalue, lActualBytes); } } else //如果不是关键帧(I帧) { quants[i-start].isIFrame = false; pcount++; if (lActualBytes>pfsmax) pfsmax = lActualBytes; if (lActualBytes nmax) nmax = b[7]; if (b[7] < nmin) nmin = b[7]; } else { psum += (b[7] & 0x3E)>>1; nsum += (b[7] & 0x3E)>>1; quants[i-start].qvalue = (b[7] & 0x3E)>>1; if ((b[7] & 0x3E)>>1 > nmax) nmax = (b[7] & 0x3E)>>1; if ((b[7] & 0x3E)>>1 < nmin) nmin = (b[7] & 0x3E)>>1; } //如果打开了分析日志 if (log) { objOle = COleDateTime::GetCurrentTime(); strTime = objOle.Format("%H:%M:%S"); sprintf(buflog, "%s - %d\tPF:Q%d\t%d\n", strTime, i+1, quants[i-start].qvalue, lActualBytes); } } //如果打开了分析日志 if (log) logfile.Print(buflog); if (b!=NULL) { delete[] b; b=NULL; } if (pbcount == pbjump) { pbcount = 0; pbpos++; progress.SetPos(pbpos); char buf[50]; sprintf(buf, "Analyzing: %d %% Completed", i*100/(stop-start-1)); edit.SetSel(0, edit.LineLength()); edit.ReplaceSel(buf); } pbcount++; } //记录分析的结束时间 clock_t fin = clock(); //得到分析的时间 long temps = fin - debut; char buf[50]; if (temps > 1000) sprintf(buf, "Analyzed %d frames in %d seconds", nframes, temps/1000); else sprintf(buf, "Analyzed %d frames in %d milliseconds", (stop-start), temps); edit.SetSel(0, edit.LineLength()); edit.ReplaceSel(buf); navg = (float)nsum/(stop-start); pavg = (float)psum/pcount; iavg = (float)isum/icount; //如果打开了分析日志 if (log) { logfile.Print("--------------------------------------------------------------------------------------\n"); logfile.Print("End of log\n"); logfile.Print("--------------------------------------------------------------------------------------\n"); logfile.Close(); } delete inputAVI; isAnalysed = true; return 0; } //------------------------------------------------------------------------------ void CXvid::Close(void) { if (quants != NULL) { delete[] quants; quants = NULL; } isOpened = false; isAnalysed = false; } //------------------------------------------------------------------------------ void CXvid::SetQuantsArray(CXvid::QUANTS* qvalues, int nelem) { if (quants != NULL) { delete[] quants; quants = NULL; } quants = qvalues; nframes = nelem; }