www.pudn.com > Gesture[20040824].rar > AviFile.cpp
// AviFile.cpp: implementation of the CAviFile class.
// darrennix@msn.com
// http://homepages.msn.com/RedmondAve/darrennix
// See also: www.egerter.com www.gamedev.net
//////////////////////////////////////////////////////////////////////
// The usual disclaimers apply to all source code you receive
// from me. You can read my copyright/disclaimer at my website.
#include "stdafx.h"
#include "CAviFile.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAviFile::CAviFile()
{/* m_frame = NULL ; //liu
fm = -1; //liu
*/ AVIFileInit();
Init();
}
CAviFile::~CAviFile()
{
AVIFileExit();
Release();
}
void CAviFile::Init()
{
m_pAviFile = NULL;
m_nNumAudioStreams = 0;
m_nNumVideoStreams = 0;
int n;
for(n = 0; n < MAX_AUDIO_STREAMS; n++)
{
m_pAudioStreams[n] = NULL;
m_pAudioFormats[n] = NULL;
m_pAudioData[n] = NULL;
}
for(n = 0; n < MAX_VIDEO_STREAMS; n++)
{
m_pVideoStreams[n] = NULL;
m_pVideoFormats[n] = NULL;
m_pVideoPGF[n] = NULL;
m_lVideoEndTime[n] = 0;
}
}
//
// The Release function must return the object's state to
// the way it was when it was initially allocated. The
// object must be ready to be reused.
//
void CAviFile::Release()
{ /*delete m_frame ; // liu
m_frame = NULL ; // liu
fm = -1; // liu
m_length = -1; // liu
*/if(m_pAviFile)
AVIFileRelease(m_pAviFile);
int n;
for(n = 0; n < m_nNumAudioStreams; n++)
{
if(m_pAudioStreams[n])
AVIStreamRelease(m_pAudioStreams[n]);
if(m_pAudioFormats[n])
delete [] ((LPBYTE)m_pAudioFormats[n]);
if(m_pAudioData[n])
delete [] m_pAudioData[n];
}
for(n = 0; n < m_nNumVideoStreams; n++)
{
if(m_pVideoStreams[n])
AVIStreamRelease(m_pVideoStreams[n]);
if(m_pVideoFormats[n])
delete [] ((LPBYTE)m_pVideoFormats[n]);
}
Init();
}
bool CAviFile::Open(LPCSTR lpszFileName)
{
if(AVIFileOpen(&m_pAviFile, lpszFileName, OF_READ, NULL))
return false;
FindStreams();
if(!DetermineAudioFormats() ||
!DetermineVideoFormats())
{
Release();
return false;
}
/*ASSERT(m_frame == NULL);//liu
m_frame = new CImage; // liu
m_frame->Create(m_pVideoFormats[0]->bmiHeader.biWidth,m_pVideoFormats[0]->bmiHeader.biHeight,m_pVideoFormats[0]->bmiHeader.biBitCount);//liu
m_length = AVIStreamEnd(m_pVideoStreams[0]); */
// Okay, we know what's in the file.
// Video and audio will be loaded as it's needed,
// so there isn't a huge delay or impact on memory
// when loading a large video file.
// Yippee!
return true;
}
void CAviFile::FindStreams()
{
do
{
if(AVIFileGetStream(m_pAviFile, &m_pAudioStreams[m_nNumAudioStreams],
streamtypeAUDIO, m_nNumAudioStreams))
break;
}
while(++m_nNumAudioStreams < MAX_AUDIO_STREAMS);
do
{
if(AVIFileGetStream(m_pAviFile, &m_pVideoStreams[m_nNumVideoStreams],
streamtypeVIDEO, m_nNumVideoStreams))
break;
}
while(++m_nNumVideoStreams < MAX_VIDEO_STREAMS);
}
bool CAviFile::DetermineAudioFormats()
{
for(int n = 0; n < m_nNumAudioStreams; n++)
{
PAVISTREAM pStream = m_pAudioStreams[n];
LONG lSize;
if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), NULL, &lSize))
return false;
LPBYTE pChunk = new BYTE[lSize];
if(!pChunk)
return false;
if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), pChunk, &lSize))
return false;
m_pAudioFormats[n] = (LPWAVEFORMAT)pChunk;
}
// Yay!
return true;
}
bool CAviFile::DetermineVideoFormats()
{
for(int n = 0; n < m_nNumVideoStreams; n++)
{
PAVISTREAM pStream = m_pVideoStreams[n];
LONG lSize;
if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), NULL, &lSize))
return false;
LPBYTE pChunk = new BYTE[lSize];
if(!pChunk)
return false;
if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), pChunk, &lSize))
return false;
m_pVideoFormats[n] = (LPBITMAPINFO)pChunk;
}
// Bravo!
return true;
}
int CAviFile::GetAudioStreamCount()
{
return m_nNumAudioStreams;
}
int CAviFile::GetVideoStreamCount()
{
return m_nNumVideoStreams;
}
LPBYTE CAviFile::ExtractAudioStream(UINT nStreamNum)
{
if(m_pAudioData[nStreamNum])
return m_pAudioData[nStreamNum];
if(nStreamNum >= m_nNumAudioStreams)
return NULL;
PAVISTREAM pStream = m_pAudioStreams[nStreamNum];
LONG lSize;
if(AVIStreamRead(pStream, 0, AVISTREAMREAD_CONVENIENT, NULL, 0, &lSize, NULL))
return NULL;
LPBYTE pBuffer = new BYTE[lSize];
if(!pBuffer)
return NULL;
if(AVIStreamRead(pStream, 0, AVISTREAMREAD_CONVENIENT, pBuffer, lSize, NULL, NULL))
return NULL;
m_pAudioData[nStreamNum] = pBuffer;
return pBuffer;
}
bool CAviFile::StartVideoRetrieve(UINT nStreamNum)
{
if(nStreamNum >= m_nNumVideoStreams)
return false;
PAVISTREAM pStream = m_pVideoStreams[nStreamNum];
PGETFRAME &pgf = m_pVideoPGF[nStreamNum];
//LPBITMAPINFOHEADER lpDesiredFormat = &m_pVideoFormats[nStreamNum]->bmiHeader;
pgf = AVIStreamGetFrameOpen(pStream, NULL/*lpDesiredFormat*/);
if(!pgf)
return false;
m_lVideoEndTime[nStreamNum] = AVIStreamEndTime(pStream);
// Yahoo!
return true;
}
bool CAviFile::EndVideoRetrieve(UINT nStreamNum)
{
PGETFRAME &pgf = m_pVideoPGF[nStreamNum];
if(AVIStreamGetFrameClose(pgf))
return false;
pgf = NULL;
// Hurray!
return true;
}
void CAviFile::GetVideoFrameAtTime(UINT nStreamNum, LONG lTimeInMilliSec, LPBITMAPINFOHEADER *ppbi)
{
if(nStreamNum >= m_nNumVideoStreams)
{
*ppbi = NULL;
return;
}
PAVISTREAM pStream = m_pVideoStreams[nStreamNum];
PGETFRAME &pgf = m_pVideoPGF[nStreamNum];
LONG lFrame;
if(lTimeInMilliSec <= m_lVideoEndTime[nStreamNum])
lFrame = AVIStreamTimeToSample(pStream, lTimeInMilliSec);
else
{
*ppbi = NULL; // video is done, no more frames
return;
}
*ppbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, lFrame);
}
void CAviFile::GetVideoFrame(UINT nStreamNum, LONG lFrame, LPBITMAPINFOHEADER *ppbi)
{
PGETFRAME &pgf = m_pVideoPGF[nStreamNum];
*ppbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, lFrame);
// NULL on error or no more frames
}
LPWAVEFORMAT CAviFile::GetAudioFormat(UINT nStreamNum)
{
if(nStreamNum >= m_nNumAudioStreams)
return NULL;
return m_pAudioFormats[nStreamNum];
}
LPBITMAPINFO CAviFile::GetVideoFormat(UINT nStreamNum)
{
if(nStreamNum >= m_nNumVideoStreams)
return NULL;
return m_pVideoFormats[nStreamNum];
}
// add by liu
/*CImage * CAviFile::GetFrameImg(int frame)
{
LPBITMAPINFOHEADER pBmp;
GetVideoFrame(0,frame, &pBmp);
if( pBmp == NULL ) return NULL;
fm = frame;
iplConvertFromDIB(pBmp, m_frame->GetImage());
return m_frame;
}
*/
int CAviFile::GetFrameNum()
{
return AVIStreamEnd(m_pVideoStreams[0]);
}