?? cxvid.cpp
字號:
// 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 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文件的信息
//得到每秒鐘的幀數(shù)
fps = (float)inputVideoAVI->streamInfo.dwRate / (float)inputVideoAVI->streamInfo.dwScale;
height = inputVideoAVI->getImageFormat()->biHeight; //視頻的高度
width = inputVideoAVI->getImageFormat()->biWidth; //視頻的寬度
nframes = inputVideoAVI->lSampleLast; //幀的數(shù)目
if (nframes < 100)
{
return 2; //不允許小于100個視頻幀
}
//一切正常
avipath = filepath; //設(shè)置文件路徑
delete inputAVI;
isAnalysed = false; //文件還沒有被分析
isOpened = true; //文件已經(jīng)打開
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數(shù)組
if (quants != NULL)
{
delete[] quants;
quants = NULL;
}
//創(chuàng)建新的quants數(shù)組
quants = new QUANTS[stop-start];
//記錄分析的開始時間
clock_t debut = clock();
// 開始分析
for (int i=start; i<stop; i++)
{
//得到幀的大小等數(shù)據(jù)
inputVideoAVI->read(i, 1, NULL, 0, &lActualBytes, NULL);
b = new UCHAR[lActualBytes];
//把幀的數(shù)據(jù)讀入到b中
inputVideoAVI->read(i, 1, b, lActualBytes, &lActualBytes, NULL);
//檢查幀大小的最小/最大值
quants[i-start].framesize = lActualBytes;
if (lActualBytes>nfsmax) nfsmax = lActualBytes;
if (lActualBytes<nfsmin) nfsmin = lActualBytes;
// 如果是關(guān)鍵幀-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 - %d\tIF:Q%d\t%d\n", strTime, i+1, quants[i-start].qvalue, lActualBytes);
}
}
else //如果不是關(guān)鍵幀(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 - %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++;
}
//記錄分析的結(jié)束時間
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;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -