2019-12-08 12:43 CET

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000364Spring engineGeneralpublic2007-01-06 13:18
ReporterM2 
Assigned Totvo 
PrioritynormalSeverityfeatureReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000364: [patch] A somewhat improved MINGW compatible avi generator.
DescriptionA somewhat improved MINGW compatible avi generator.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon 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 */
    
    patch file icon avi.patch (25,942 bytes) 2007-01-05 09:30 +

-Relationships
+Relationships

-Notes

~0000528

tvo (reporter)

Committed, seems to work ok. Thanks for fixing this!
+Notes

-Issue History
Date Modified Username Field Change
2007-01-05 09:30 M2 New Issue
2007-01-05 09:30 M2 File Added: avi.patch
2007-01-06 12:40 tvo Summary A somewhat improved MINGW compatible avi generator. => [patch] A somewhat improved MINGW compatible avi generator.
2007-01-06 13:18 tvo Status new => resolved
2007-01-06 13:18 tvo Resolution open => fixed
2007-01-06 13:18 tvo Assigned To => tvo
2007-01-06 13:18 tvo Note Added: 0000528
+Issue History