avi.patch (25,942 bytes)
2007-01-05 09:30
Index: rts/Game/Game.cpp
===================================================================
--- rts/Game/Game.cpp (revision 3066)
+++ rts/Game/Game.cpp (working copy)
@@ -18,6 +18,7 @@
#include <SDL_mouse.h>
#include <SDL_timer.h>
#include <SDL_types.h>
+#include <SDL_events.h>
#include "Game.h"
#include "float.h"
@@ -902,7 +903,7 @@
} else {
creatingVideo=true;
string name;
- for(int a=0;a<99;++a){
+ for(int a=0;a<999;++a){
char t[50];
itoa(a,t,10);
name=string("video")+t+".avi";
@@ -910,34 +911,36 @@
if(!ifs.FileExists())
break;
}
- int x=gu->viewSizeX;
- x-=gu->viewSizeX%4;
- int y=gu->viewSizeY;
- y-=gu->viewSizeY%4;
+ BITMAPINFOHEADER bih;
+ memset(&bih,0, sizeof(BITMAPINFOHEADER));
- BITMAPINFOHEADER bih;
+ // filling bitmap info structure.
bih.biSize=sizeof(BITMAPINFOHEADER);
- bih.biWidth=x;
- bih.biHeight=y;
+ bih.biWidth=(gu->viewSizeX/4)*4;
+ bih.biHeight=(gu->viewSizeY/4)*4;
bih.biPlanes=1;
bih.biBitCount=24;
+ bih.biSizeImage=bih.biWidth*bih.biHeight*3;
bih.biCompression=BI_RGB;
- bih.biSizeImage=0;
- bih.biXPelsPerMeter=1000;
- bih.biYPelsPerMeter=1000;
- bih.biClrUsed=0;
- bih.biClrImportant=0;
- aviGenerator=SAFE_NEW CAVIGenerator();
- aviGenerator->SetFileName(name.c_str());
- aviGenerator->SetRate(30);
- aviGenerator->SetBitmapHeader(&bih);
- Sint32 hr=aviGenerator->InitEngine();
+
+ aviGenerator = SAFE_NEW CAVIGenerator(name, &bih, 30);
+ int savedCursorMode = SDL_ShowCursor(SDL_QUERY);
+ SDL_ShowCursor(SDL_ENABLE);
+ HRESULT hr=aviGenerator->InitEngine();
+ SDL_ShowCursor(savedCursorMode);
+ //aviGenerator->InitEngine() (avicap32.dll)? modifies the FPU control word.
+ //Setting it back to 'normal'.
+ streflop_init<streflop::Simple>();
+
if(hr!=AVIERR_OK){
creatingVideo=false;
+ logOutput.Print(aviGenerator->GetLastErrorMessage());
+ delete aviGenerator;
+ aviGenerator=0;
} else {
- logOutput.Print("Recording avi to %s size %i %i",name.c_str(),x,y);
+ logOutput.Print("Recording avi to %s size %i %i",name.c_str(), bih.biWidth, bih.biHeight);
}
}
}
@@ -1422,7 +1425,8 @@
gameServer->gameClientUpdated=true;
#ifdef SYNCIFY //syncify doesnt support multithreading ...
- gameServer->Update();
+ if (gameServer)
+ gameServer->Update();
#endif
if(creatingVideo && playing && gameServer){
@@ -1763,13 +1767,12 @@
if(creatingVideo){
gu->lastFrameTime=1.0f/GAME_SPEED;
LPBITMAPINFOHEADER ih;
- ih=aviGenerator->GetBitmapHeader();
- unsigned char* buf=SAFE_NEW unsigned char[ih->biWidth*ih->biHeight*3];
- glReadPixels(0,0,ih->biWidth,ih->biHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,buf);
+ ih = aviGenerator->GetBitmapHeader();
+ unsigned char* buf = aviGenerator->GetPixelBuf();
+ glReadPixels(0,0,ih->biWidth, ih->biHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, buf);
aviGenerator->AddFrame(buf);
- delete buf;
// logOutput.Print("Saved avi frame size %i %i",ih->biWidth,ih->biHeight);
}
#endif
Index: rts/System/Platform/Win/AVIGenerator.cpp
===================================================================
--- rts/System/Platform/Win/AVIGenerator.cpp (revision 3066)
+++ rts/System/Platform/Win/AVIGenerator.cpp (working copy)
@@ -3,268 +3,317 @@
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
-#include <SDL_types.h>
#include "AVIGenerator.h"
-#include "Rendering/GL/myGL.h"
+#include <cassert>
#include "mmgr.h"
-#include <windows.h>
-
-#ifdef _DEBUG
-#undef THIS_FILE
-static char THIS_FILE[]=__FILE__;
-#define new DEBUG_NEW
+#if defined(_WIN32) && !defined(__MINGW32__)
+#pragma message(" _Adding library: vfw32.lib" )
+#pragma comment(lib, "vfw32.lib")
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-#define ASSERT(x)
-CAVIGenerator::CAVIGenerator()
-: m_sFile(_T("Untitled.avi")), m_dwRate(30),
-m_pAVIFile(NULL), m_pStream(NULL), m_pStreamCompressed(NULL)
-{
- memset(&m_bih,0,sizeof(BITMAPINFOHEADER));
-}
-#ifdef _AVIGENERATOR_USE_MFC
-CAVIGenerator::CAVIGenerator(LPCTSTR sFileName, CView* pView, DWORD dwRate)
-: m_sFile(sFileName), m_dwRate(dwRate),
-m_pAVIFile(NULL), m_pStream(NULL), m_pStreamCompressed(NULL)
-{
- MakeExtAvi();
- SetBitmapHeader(pView);
+bool CAVIGenerator::initVFW(){
+#if defined(_WIN32) && defined(__MINGW32__)
+
+ HMODULE hMod = LoadLibrary("msvfw32.dll");
+ if (NULL == hMod){
+ m_sError="LoadLibrary failed.";
+ return false;
+ }
+
+
+ VideoForWindowsVersion_ptr=(VideoForWindowsVersion_type)GetProcAddress(hMod, "VideoForWindowsVersion");
+ ICCompressorChoose_ptr=(ICCompressorChoose_type)GetProcAddress(hMod, "ICCompressorChoose");
+ ICCompressorFree_ptr=(ICCompressorFree_type)GetProcAddress(hMod, "ICCompressorFree");
+
+
+
+ if(!VideoForWindowsVersion_ptr || !ICCompressorChoose_ptr || !ICCompressorFree_ptr){
+ m_sError="initVFW Error.";
+ return false;
+ }
+
+
+
+ hMod = LoadLibrary("avifil32.dll");
+ if (NULL == hMod){
+ m_sError="LoadLibrary failed.";
+ return false;
+ }
+
+
+ AVIFileInit_ptr=(AVIFileInit_type)GetProcAddress(hMod, "AVIFileInit");
+ AVIFileOpenA_ptr=(AVIFileOpenA_type)GetProcAddress(hMod, "AVIFileOpenA");
+ AVIFileCreateStreamA_ptr=(AVIFileCreateStreamA_type)GetProcAddress(hMod, "AVIFileCreateStreamA");
+ AVIMakeCompressedStream_ptr=(AVIMakeCompressedStream_type)GetProcAddress(hMod, "AVIMakeCompressedStream");
+ AVIStreamSetFormat_ptr=(AVIStreamSetFormat_type)GetProcAddress(hMod, "AVIStreamSetFormat");
+ AVIStreamRelease_ptr=(AVIStreamRelease_type)GetProcAddress(hMod, "AVIStreamRelease");
+ AVIFileRelease_ptr=(AVIFileRelease_type)GetProcAddress(hMod, "AVIFileRelease");
+ AVIFileExit_ptr=(AVIFileExit_type)GetProcAddress(hMod, "AVIFileExit");
+ AVIStreamWrite_ptr=(AVIStreamWrite_type)GetProcAddress(hMod, "AVIStreamWrite");
+
+
+ if(!AVIFileInit_ptr || !AVIFileOpenA_ptr || !AVIFileCreateStreamA_ptr ||
+ !AVIMakeCompressedStream_ptr || !AVIStreamSetFormat_ptr || !AVIStreamRelease_ptr ||
+ !AVIFileRelease_ptr || !AVIFileExit_ptr || !AVIStreamWrite_ptr){
+ m_sError="initVFW Error.";
+ return false;
+ }
+ return true;
+#else
+
+ VideoForWindowsVersion_ptr =&VideoForWindowsVersion;
+ AVIFileInit_ptr = &AVIFileInit;
+ AVIFileOpenA_ptr = &AVIFileOpenA;
+ AVIFileCreateStreamA_ptr = &AVIFileCreateStreamA;
+ AVIMakeCompressedStream_ptr = &AVIMakeCompressedStream;
+ AVIStreamSetFormat_ptr = &AVIStreamSetFormat;
+ AVIStreamRelease_ptr = &AVIStreamRelease;
+ AVIFileRelease_ptr = &AVIFileRelease;
+ AVIFileExit_ptr = &AVIFileExit;
+ AVIStreamWrite_ptr = &AVIStreamWrite;
+ ICCompressorChoose_ptr = &ICCompressorChoose;
+ ICCompressorFree_ptr = &ICCompressorFree;
+
+ return true;
+#endif
}
-#endif
-CAVIGenerator::CAVIGenerator(LPCTSTR sFileName, LPBITMAPINFOHEADER lpbih, DWORD dwRate)
-: m_sFile(sFileName), m_dwRate(dwRate),
+
+
+CAVIGenerator::CAVIGenerator(const std::string & sFileName, LPBITMAPINFOHEADER lpbih, DWORD dwRate)
+: m_sFile(sFileName), m_dwRate(dwRate), pixelDataBuf(0),
m_pAVIFile(NULL), m_pStream(NULL), m_pStreamCompressed(NULL)
{
- MakeExtAvi();
- SetBitmapHeader(lpbih);
+ MakeExtAvi();
+ SetBitmapHeader(lpbih);
}
CAVIGenerator::~CAVIGenerator()
{
// Just checking that all allocated ressources have been released
- ASSERT(m_pStream==NULL);
- ASSERT(m_pStreamCompressed==NULL);
- ASSERT(m_pAVIFile==NULL);
+ assert(m_pStream==NULL);
+ assert(m_pStreamCompressed==NULL);
+ assert(m_pAVIFile==NULL);
+ assert(pixelDataBuf==NULL);
}
void CAVIGenerator::SetBitmapHeader(LPBITMAPINFOHEADER lpbih)
{
// checking that bitmap size are multiple of 4
- ASSERT(lpbih->biWidth%4==0);
- ASSERT(lpbih->biHeight%4==0);
+ assert(lpbih->biWidth%4==0);
+ assert(lpbih->biHeight%4==0);
+ assert(lpbih->biBitCount==24);
+ assert(lpbih->biCompression==BI_RGB);
+ assert(lpbih->biSizeImage==lpbih->biWidth*lpbih->biHeight*3);
// copying bitmap info structure.
// corrected thanks to Lori Gardi
memcpy(&m_bih,lpbih, sizeof(BITMAPINFOHEADER));
}
-#ifdef _AVIGENERATOR_USE_MFC
-void CAVIGenerator::SetBitmapHeader(CView *pView)
-{
- ASSERT_VALID(pView);
- ////////////////////////////////////////////////
- // Getting screen dimensions
- // Get client geometry
- CRect rect;
- pView->GetClientRect(&rect);
- CSize size(rect.Width(),rect.Height());
-
- /////////////////////////////////////////////////
- // changing size of image so dimension are multiple of 4
- size.cx=(size.cx/4)*4;
- size.cy=(size.cy/4)*4;
-
- // initialize m_bih
- memset(&m_bih,0, sizeof(BITMAPINFOHEADER));
- // filling bitmap info structure.
- m_bih.biSize=sizeof(BITMAPINFOHEADER);
- m_bih.biWidth=size.cx;
- m_bih.biHeight=size.cy;
- m_bih.biPlanes=1;
- m_bih.biBitCount=24;
- m_bih.biSizeImage=((m_bih.biWidth*m_bih.biBitCount+31)/32 * 4)*m_bih.biHeight;
- m_bih.biCompression=BI_RGB; //BI_RGB means BRG in reality
-}
-#endif
-
HRESULT CAVIGenerator::InitEngine()
{
AVISTREAMINFO strHdr; // information for a single stream
AVICOMPRESSOPTIONS opts;
- AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
- TCHAR szBuffer[1024];
HRESULT hr;
- m_sError=_T("Ok");
+ m_sError= "Ok";
+
+ if(!initVFW()){
+ return S_FALSE;
+ }
+
+ triggerCleanup cleaner(this);
+
// Step 0 : Let's make sure we are running on 1.1
- DWORD wVer = HIWORD(VideoForWindowsVersion());
+ DWORD wVer = HIWORD(VideoForWindowsVersion_ptr());
if (wVer < 0x010a)
{
- // oops, we are too old, blow out of here
- m_sError=_T("Version of Video for Windows too old. Come on, join the 21th century!");
+ // oops, we are too old, blow out of here
+ m_sError="Version of Video for Windows too old. Come on, join the 21th century!";
return S_FALSE;
}
// Step 1 : initialize AVI engine
- AVIFileInit();
+ AVIFileInit_ptr();
+
+ memset(&cv,0,sizeof(COMPVARS));
+
+ cv.cbSize=sizeof(COMPVARS);
+ cv.dwFlags=ICMF_COMPVARS_VALID;
+ cv.fccHandler=mmioFOURCC('W','M','V','3');
+ cv.lQ=ICQUALITY_DEFAULT;
+
+
+ HWND hWnd = FindWindow(NULL, "RtsSpring");
+
+ if (!ICCompressorChoose_ptr(hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME, &m_bih, NULL, &cv, NULL)){
+ return S_FALSE;
+ }
+
+
+ // Fill in the header for the video stream....
+ memset(&strHdr, 0, sizeof(AVISTREAMINFO));
+ strHdr.fccType = streamtypeVIDEO; // video stream type
+ strHdr.fccHandler = cv.fccHandler;
+ strHdr.dwScale = 1; // should be one for video
+ strHdr.dwRate = m_dwRate; // fps
+ strHdr.dwSuggestedBufferSize = m_bih.biSizeImage; // Recommended buffer size, in bytes, for the stream.
+ SetRect(&strHdr.rcFrame, 0, 0, (int)m_bih.biWidth, (int)m_bih.biHeight); // rectangle for stream
+
+
+
+ memset(&opts, 0, sizeof(AVICOMPRESSOPTIONS));
+ opts.fccType=streamtypeVIDEO;
+ opts.fccHandler=cv.fccHandler;
+ opts.dwKeyFrameEvery=cv.lKey;
+ opts.dwQuality=cv.lQ;
+ opts.dwBytesPerSecond=cv.lDataRate;
+ opts.dwFlags=(cv.lDataRate>0?AVICOMPRESSF_DATARATE:0)|(cv.lKey>0?AVICOMPRESSF_KEYFRAMES:0);
+ opts.lpFormat=NULL;
+ opts.cbFormat=0;
+ opts.lpParms=cv.lpState;
+ opts.cbParms=cv.cbState;
+ opts.dwInterleaveEvery=0;
+
// Step 2 : Open the movie file for writing....
- hr = AVIFileOpen(&m_pAVIFile, // Address to contain the new file interface pointer
- (LPCSTR)m_sFile, // Null-terminated string containing the name of the file to open
- OF_WRITE | OF_CREATE, // Access mode to use when opening the file.
- NULL); // use handler determined from file extension.
- // Name your file .avi -> very important
+ hr = AVIFileOpenA_ptr(&m_pAVIFile, // Address to contain the new file interface pointer
+ m_sFile.c_str(), // Null-terminated string containing the name of the file to open
+ OF_WRITE | OF_CREATE | OF_SHARE_EXCLUSIVE, // Access mode to use when opening the file.
+ NULL); // use handler determined from file extension.
+ // Name your file .avi -> very important
if (hr != AVIERR_OK)
{
- _tprintf(szBuffer,_T("AVI Engine failed to initialize. Check filename %s."),m_sFile);
- m_sError=szBuffer;
+ //_tprintf(szBuffer,"AVI Engine failed to initialize. Check filename %s.",m_sFile);
+ m_sError="AVI Engine failed to initialize. Check filename ";
+ m_sError+=m_sFile;
// Check it succeded.
switch(hr)
{
case AVIERR_BADFORMAT:
- m_sError+=_T("The file couldn't be read, indicating a corrupt file or an unrecognized format.");
+ m_sError+="The file couldn't be read, indicating a corrupt file or an unrecognized format.";
break;
case AVIERR_MEMORY:
- m_sError+=_T("The file could not be opened because of insufficient memory.");
+ m_sError+="The file could not be opened because of insufficient memory.";
break;
case AVIERR_FILEREAD:
- m_sError+=_T("A disk error occurred while reading the file.");
+ m_sError+="A disk error occurred while reading the file.";
break;
case AVIERR_FILEOPEN:
- m_sError+=_T("A disk error occurred while opening the file.");
+ m_sError+="A disk error occurred while opening the file.";
break;
case REGDB_E_CLASSNOTREG:
- m_sError+=_T("According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it");
+ m_sError+="According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it";
break;
}
-
return hr;
}
- // Fill in the header for the video stream....
- memset(&strHdr, 0, sizeof(strHdr));
- strHdr.fccType = streamtypeVIDEO; // video stream type
- strHdr.fccHandler = 0;
- strHdr.dwScale = 1; // should be one for video
- strHdr.dwRate = m_dwRate; // fps
- strHdr.dwSuggestedBufferSize = m_bih.biSizeImage; // Recommended buffer size, in bytes, for the stream.
- SetRect(&strHdr.rcFrame, 0, 0, // rectangle for stream
- (int) m_bih.biWidth,
- (int) m_bih.biHeight);
// Step 3 : Create the stream;
- hr = AVIFileCreateStream(m_pAVIFile, // file pointer
- &m_pStream, // returned stream pointer
- &strHdr); // stream header
+ hr = AVIFileCreateStreamA_ptr(m_pAVIFile, // file pointer
+ &m_pStream, // returned stream pointer
+ &strHdr); // stream header
// Check it succeded.
if (hr != AVIERR_OK)
{
- m_sError=_T("AVI Stream creation failed. Check Bitmap info.");
+ m_sError="AVI Stream creation failed. Check Bitmap info.";
if (hr==AVIERR_READONLY)
{
- m_sError+=_T(" Read only file.");
+ m_sError+=" Read only file.";
}
return hr;
}
- // Step 4: Get codec and infos about codec
- memset(&opts, 0, sizeof(opts));
- // Poping codec dialog
- if (!AVISaveOptions(NULL, 0, 1, &m_pStream, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
- {
- AVISaveOptionsFree(1,(LPAVICOMPRESSOPTIONS FAR *) &aopts);
- return S_FALSE;
- }
-
// Step 5: Create a compressed stream using codec options.
- hr = AVIMakeCompressedStream(&m_pStreamCompressed,
- m_pStream,
- &opts,
- NULL);
+ hr = AVIMakeCompressedStream_ptr(&m_pStreamCompressed,
+ m_pStream,
+ &opts,
+ NULL);
if (hr != AVIERR_OK)
{
- m_sError=_T("AVI Compressed Stream creation failed.");
-
+ m_sError="AVI Compressed Stream creation failed.";
+
switch(hr)
{
case AVIERR_NOCOMPRESSOR:
- m_sError+=_T(" A suitable compressor cannot be found.");
- break;
+ m_sError+=" A suitable compressor cannot be found.";
+ break;
case AVIERR_MEMORY:
- m_sError+=_T(" There is not enough memory to complete the operation.");
- break;
+ m_sError+=" There is not enough memory to complete the operation.";
+ break;
case AVIERR_UNSUPPORTED:
- m_sError+=_T("Compression is not supported for this type of data. This error might be returned if you try to compress data that is not audio or video.");
+ m_sError+="Compression is not supported for this type of data. This error might be returned if you try to compress data that is not audio or video.";
break;
}
-
return hr;
}
- // releasing memory allocated by AVISaveOptionFree
- hr=AVISaveOptionsFree(1,(LPAVICOMPRESSOPTIONS FAR *) &aopts);
- if (hr!=AVIERR_OK)
- {
- m_sError=_T("Error releasing memory");
- return hr;
- }
// Step 6 : sets the format of a stream at the specified position
- hr = AVIStreamSetFormat(m_pStreamCompressed,
- 0, // position
- &m_bih, // stream format
- m_bih.biSize + // format size
- m_bih.biClrUsed * sizeof(RGBQUAD));
+ hr = AVIStreamSetFormat_ptr(m_pStreamCompressed,
+ 0, // position
+ &m_bih, // stream format
+ m_bih.biSize + // format size
+ m_bih.biClrUsed * sizeof(RGBQUAD));
if (hr != AVIERR_OK)
{
- m_sError=_T("AVI Compressed Stream format setting failed.");
+ m_sError="AVI Compressed Stream format setting failed.";
return hr;
}
// Step 6 : Initialize step counter
m_lFrame=0;
+ pixelDataBuf = SAFE_NEW unsigned char[m_bih.biSizeImage];
+ cleaner.disarm();
return hr;
}
+
void CAVIGenerator::ReleaseEngine()
{
if (m_pStream)
{
- AVIStreamRelease(m_pStream);
+ AVIStreamRelease_ptr(m_pStream);
m_pStream=NULL;
}
if (m_pStreamCompressed)
{
- AVIStreamRelease(m_pStreamCompressed);
+ AVIStreamRelease_ptr(m_pStreamCompressed);
m_pStreamCompressed=NULL;
}
if (m_pAVIFile)
{
- AVIFileRelease(m_pAVIFile);
+ AVIFileRelease_ptr(m_pAVIFile);
m_pAVIFile=NULL;
}
+ ICCompressorFree_ptr(&cv);
+
+ delete [] pixelDataBuf;
+ pixelDataBuf=0;
+
// Close engine
- AVIFileExit();
+ AVIFileExit_ptr();
}
HRESULT CAVIGenerator::AddFrame(BYTE *bmBits)
@@ -272,7 +321,7 @@
HRESULT hr;
// compress bitmap
- hr = AVIStreamWrite(m_pStreamCompressed, // stream pointer
+ hr = AVIStreamWrite_ptr(m_pStreamCompressed, // stream pointer
m_lFrame, // time of this frame
1, // number to write
bmBits, // image buffer
@@ -287,11 +336,10 @@
return hr;
}
-void CAVIGenerator::MakeExtAvi()
-{
- // finding avi
- if( _tcsstr((const char *)m_sFile,(const char *)_T("avi"))==NULL )
- {
- m_sFile+=_T(".avi");
+void CAVIGenerator::MakeExtAvi(){
+
+ std::size_t pos = m_sFile.find_last_of(".avi");
+ if(pos == std::string::npos || pos + 1 != m_sFile.size()){
+ m_sFile += ".avi";
}
}
Index: rts/System/Platform/Win/AVIGenerator.h
===================================================================
--- rts/System/Platform/Win/AVIGenerator.h (revision 3066)
+++ rts/System/Platform/Win/AVIGenerator.h (working copy)
@@ -1,5 +1,3 @@
-#ifndef AVIGENERATOR_H
-#define AVIGENERATOR_H
// AVIGenerator.h: interface for the CAVIGenerator class.
//
// A class to easily create AVI
@@ -9,52 +7,54 @@
// Author : Jonathan de Halleux. dehalleux@auto.ucl.ac.be
//////////////////////////////////////////////////////////////////////
-// needed headers
-#include <comdef.h>
-#include <memory.h>
-#include <tchar.h>
-#include <string.h>
+#ifndef AVIGENERATOR_H
+#define AVIGENERATOR_H
+
+
+#include <windows.h>
#include <vfw.h>
-#pragma message(" _Adding library: vfw32.lib" )
-#pragma comment ( lib, "vfw32.lib")
+#include <gl/gl.h>
+#if defined(_WIN32) && defined(__MINGW32__)
+#include <gl/glext.h>
+#endif
-// undefine this if you don't use MFC
-//#define _AVIGENERATOR_USE_MFC
+#include <string>
+
/*! \brief A simple class to create AVI video stream.
\par Usage
- Step 1 : Declare an CAVIGenerator object
- Step 2 : Set Bitmap by calling SetBitmapHeader functions + other parameters
- Step 3 : Initialize engine by calling InitEngine
- Step 4 : Send each frames to engine with function AddFrame
- Step 5 : Close engine by calling ReleaseEngine
+Step 1 : Declare an CAVIGenerator object
+Step 2 : Set Bitmap by calling SetBitmapHeader functions + other parameters
+Step 3 : Initialize engine by calling InitEngine
+Step 4 : Send each frames to engine with function AddFrame
+Step 5 : Close engine by calling ReleaseEngine
\par Demo Code:
\code
- CAVIGenerator AviGen;
- BYTE* bmBits;
+CAVIGenerator AviGen;
+BYTE* bmBits;
- // set characteristics
- AviGen.SetRate(20); // set 20fps
- AviGen.SetBitmapHeader(GetActiveView()); // give info about bitmap
+// set characteristics
+AviGen.SetRate(20); // set 20fps
+AviGen.SetBitmapHeader(GetActiveView()); // give info about bitmap
- AviGen.InitEngine();
+AviGen.InitEngine();
- ..... // Draw code, bmBits is the buffer containing the frame
- AviGen.AddFrame(bmBits);
- .....
+..... // Draw code, bmBits is the buffer containing the frame
+AviGen.AddFrame(bmBits);
+.....
- AviGen.ReleaseEngine();
+AviGen.ReleaseEngine();
\endcode
\par Update history:
- - {\bf 22-10-2002} Minor changes in constructors.
+- {\bf 22-10-2002} Minor changes in constructors.
\author : Jonathan de Halleux, dehalleux@auto.ucl.ac.be (2001)
*/
@@ -63,27 +63,20 @@
public:
//! \name Constructors and destructors
//@{
- //! Default constructor
- CAVIGenerator();
-#ifdef _AVIGENERATOR_USE_MFC
- //! Inplace constructor with CView
- CAVIGenerator(LPCTSTR sFileName, CView* pView, DWORD dwRate);
-#endif
//! Inplace constructor with BITMAPINFOHEADER
- CAVIGenerator(LPCTSTR sFileName, LPBITMAPINFOHEADER lpbih, DWORD dwRate);
+ CAVIGenerator(const std::string & sFileName, LPBITMAPINFOHEADER lpbih, DWORD dwRate);
~CAVIGenerator();
//@}
//! \name AVI engine function
//@{
/*! \brief Initialize engine and choose codex
-
- Some asserts are made to check that bitmap has been properly initialized
+ Some asserts are made to check that bitmap has been properly initialized
*/
HRESULT InitEngine();
/*! \brief Adds a frame to the movie.
-
+
The data pointed by bmBits has to be compatible with the bitmap description of the movie.
*/
HRESULT AddFrame(BYTE* bmBits);
@@ -93,37 +86,33 @@
//! \name Setters and getters
//@{
-#ifdef _AVIGENERATOR_USE_MFC
- //! Sets bitmap info to match pView dimension.
- void SetBitmapHeader(CView* pView);
-#endif
- //! Sets bitmap info as in lpbih
- void SetBitmapHeader(LPBITMAPINFOHEADER lpbih);
//! returns a pointer to bitmap info
- LPBITMAPINFOHEADER GetBitmapHeader() { return &m_bih;};
- //! sets the name of the ouput file (should be .avi)
- void SetFileName(LPCTSTR _sFileName) { m_sFile=_sFileName; MakeExtAvi();};
- //! Sets FrameRate (should equal or greater than one)
- void SetRate(DWORD dwRate) { m_dwRate=dwRate;};
- //@}
-
+ LPBITMAPINFOHEADER GetBitmapHeader() {return &m_bih;}
+
//! \name Error handling
//@{
//! returns last error message
- LPCTSTR GetLastErrorMessage() const { return m_sError;};
+ std::string GetLastErrorMessage() const {return m_sError;}
//@}
+ unsigned char* GetPixelBuf(){return pixelDataBuf;}
-protected:
+
+private:
//! name of output file
- _bstr_t m_sFile;
+ std::string m_sFile;
//! Frame rate
DWORD m_dwRate;
//! structure contains information for a single stream
BITMAPINFOHEADER m_bih;
//! last error string
- _bstr_t m_sError;
+ std::string m_sError;
-private:
+ unsigned char* pixelDataBuf;
+
+
+ //! Sets bitmap info as in lpbih
+ void SetBitmapHeader(LPBITMAPINFOHEADER lpbih);
+
void MakeExtAvi();
//! frame counter
long m_lFrame;
@@ -133,6 +122,56 @@
PAVISTREAM m_pStream;
//! Address of the compressed video stream
PAVISTREAM m_pStreamCompressed;
+ //Holds compression settings
+ COMPVARS cv;
+
+ typedef DWORD (__stdcall *VideoForWindowsVersion_type)(void);
+ typedef void (__stdcall *AVIFileInit_type)(void);
+ typedef HRESULT (__stdcall *AVIFileOpenA_type)(PAVIFILE FAR *, LPCSTR, UINT, LPCLSID);
+ typedef HRESULT (__stdcall *AVIFileCreateStreamA_type)(PAVIFILE, PAVISTREAM FAR *, AVISTREAMINFOA FAR *);
+ typedef HRESULT (__stdcall *AVIMakeCompressedStream_type)(PAVISTREAM FAR *, PAVISTREAM, AVICOMPRESSOPTIONS FAR *, CLSID FAR *);
+ typedef HRESULT (__stdcall *AVIStreamSetFormat_type)(PAVISTREAM, LONG, LPVOID, LONG);
+ typedef ULONG (__stdcall *AVIStreamRelease_type)(PAVISTREAM);
+ typedef ULONG (__stdcall *AVIFileRelease_type)(PAVIFILE);
+ typedef void (__stdcall *AVIFileExit_type)(void);
+ typedef HRESULT (__stdcall *AVIStreamWrite_type)(PAVISTREAM, LONG, LONG, LPVOID, LONG, DWORD, LONG FAR *, LONG FAR *);
+ typedef BOOL (__stdcall *ICCompressorChoose_type)(HWND, UINT, LPVOID, LPVOID, PCOMPVARS, LPSTR);
+ typedef void (__stdcall *ICCompressorFree_type)(PCOMPVARS);
+
+
+
+ VideoForWindowsVersion_type VideoForWindowsVersion_ptr;
+ AVIFileInit_type AVIFileInit_ptr;
+ AVIFileOpenA_type AVIFileOpenA_ptr;
+ AVIFileCreateStreamA_type AVIFileCreateStreamA_ptr;
+ AVIMakeCompressedStream_type AVIMakeCompressedStream_ptr;
+ AVIStreamSetFormat_type AVIStreamSetFormat_ptr;
+ AVIStreamRelease_type AVIStreamRelease_ptr;
+ AVIFileRelease_type AVIFileRelease_ptr;
+ AVIFileExit_type AVIFileExit_ptr;
+ AVIStreamWrite_type AVIStreamWrite_ptr;
+ ICCompressorChoose_type ICCompressorChoose_ptr;
+ ICCompressorFree_type ICCompressorFree_ptr;
+
+
+ bool initVFW();
+
+
+ struct triggerCleanup{
+ triggerCleanup(CAVIGenerator* ptr) : clean(true), ptr(ptr){};
+ ~triggerCleanup(){
+ if(clean){
+ ptr->ReleaseEngine();
+ }
+ }
+ void disarm(){
+ clean = false;
+ }
+ private:
+ bool clean;
+ CAVIGenerator* ptr;
+ };
+
};
#endif /* AVIGENERATOR_H */