CXvid.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:8k
- // CXvid.cpp: implementation of the CXvid class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "XvidQuantsParser.h"
- #include "CXvid.h"
- #include <time.h>
- #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 StudioVC98Include目录下
-
- //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.0n");
- 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<stop; i++)
- {
- //得到帧的大小等数据
- inputVideoAVI->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<nfsmin) nfsmin = lActualBytes;
- // 如果是关键帧-I帧
- if (inputVideoAVI->isKey(i))
- {
- quants[i-start].isIFrame = true;
- icount++;
-
- //检查I帧大小的最小/最大值
- if (lActualBytes>ifsmax) ifsmax = lActualBytes;
- if (lActualBytes<ifsmin) ifsmin = lActualBytes;
- if (b[24] == 0x28)
- {
- isum += b[27]>>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 - %dtIF:Q%dt%dn", strTime, i+1, quants[i-start].qvalue, lActualBytes);
- }
-
- }
- else //如果不是关键帧(I帧)
- {
- quants[i-start].isIFrame = false;
- pcount++;
- if (lActualBytes>pfsmax) pfsmax = lActualBytes;
- if (lActualBytes<pfsmin) pfsmin = lActualBytes;
- if (b[4] == 0x68)
- {
- psum += b[7];
- nsum += b[7];
- quants[i-start].qvalue = b[7];
- if (b[7] > 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 - %dtPF:Q%dt%dn", 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 logn");
- 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;
- }