// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CAviRenderer
//  - prototype : bool CAviRenderer::SaveFrame()
//
//  - Purpose   : Captures a frame and saves it into the avi file.
//
// -----------------------------------------------------------------------------
bool CAviRenderer::SaveFrame()
{
	if(!IsValid())
	{
		return false;
	}

    // Get an image and stuff it into a bitmap.

	HRESULT hr;
    HBITMAP bmp;

    if((bmp = LoadBMPFromFB(m_pWindowGL)) == NULL)
	{
		return false;
	}

	LPBITMAPINFOHEADER lpInfoHeader = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 32));
    DeleteObject(bmp);

	if(lpInfoHeader == NULL)
	{
		LOG.Write("\nERROR - CAviRenderer::SaveFrame(). GlobalLock() failed.");
		return false;
	}

	if(m_nWidth != lpInfoHeader->biWidth)
	{
		LOG.Write("\nERROR - CAviRenderer::SaveFrame(): mismatched window width / info header width.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	if(m_nHeight != lpInfoHeader->biHeight)
	{
		LOG.Write("\nERROR - CAviRenderer::SaveFrame(): mismatched window height / info header height.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	// Save frame

	hr = AVIStreamWrite(m_pAviStreamCompressed,			// stream pointer
						m_nFrameCount,					// frame
						1,								// number of frames to write
						(LPBYTE) lpInfoHeader +			// pointer to data
						lpInfoHeader->biSize +
						lpInfoHeader->biClrUsed * sizeof(RGBQUAD),
						lpInfoHeader->biSizeImage,		// size of this frame
						AVIIF_KEYFRAME,					// flags....
						NULL,
						NULL);

	if(hr != AVIERR_OK)
	{
		CLogger::ErrorWindow("CAviRenderer::SaveFrame(). AVIStreamWrite() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	GlobalFreePtr(lpInfoHeader);
	m_nFrameCount++;

	return true;
}
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CAviRenderer
//  - prototype : bool StartRender(CWindowGL *pWindowGL, std::string strAviFile, int nFramerate)
//
//  - Purpose   : Prepares the object for capturing the opengl window to an AVI.
//
// -----------------------------------------------------------------------------
bool CAviRenderer::StartRender(CWindowGL *pWindowGL, std::string strAviFile, int nFramerate)
{
	assert(pWindowGL);

	m_pWindowGL  = NULL;
	m_bIsWorking = false;

	// Check VFW version.

	WORD wVer = HIWORD(VideoForWindowsVersion());

	if(wVer < 0x010A)
	{
		CLogger::ErrorWindow("Video For Windows outdated version");
		return false;
	}

	// Init library

	AVIFileInit();

    // Get an image and stuff it into a bitmap.

	HRESULT hr;
    HBITMAP bmp;

	if((bmp = LoadBMPFromFB(pWindowGL)) == NULL)
	{
		return false;
	}

	LPBITMAPINFOHEADER lpInfoHeader = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 32));
    DeleteObject(bmp);

	if(lpInfoHeader == NULL)
	{
		LOG.Write("\nERROR - CAviRenderer::StartRender(): GlobalLock() failed.");
		return false;
	}

	m_nWidth  = (int)lpInfoHeader->biWidth;
	m_nHeight = (int)lpInfoHeader->biHeight;

	// Open an avi file for writing

	hr = AVIFileOpen(	&m_pAviFile,		    // returned file pointer
						strAviFile.data(),		// file name
						OF_WRITE | OF_CREATE,	// mode to open file with
						NULL);					// use handler determined
												// from file extension....
	if (hr != AVIERR_OK)
	{
		LOG.Write("\nERROR - CAviRenderer::StartRender(): AVIFileOpen() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	// Configure the stream

	_fmemset(&m_aviStreamInfo, 0, sizeof(m_aviStreamInfo));

	m_aviStreamInfo.fccType                = streamtypeVIDEO; // stream type
	m_aviStreamInfo.fccHandler             = 0;
	m_aviStreamInfo.dwScale                = 1;
	m_aviStreamInfo.dwRate                 = nFramerate;
	m_aviStreamInfo.dwSuggestedBufferSize  = lpInfoHeader->biSizeImage;

	SetRect(&m_aviStreamInfo.rcFrame, 0, 0,	// rectangle for stream
			(int)lpInfoHeader->biWidth,
			(int)lpInfoHeader->biHeight);

	// And create the stream

	hr = AVIFileCreateStream(m_pAviFile,		// file pointer
						     &m_pAviStream,		// returned stream pointer
							 &m_aviStreamInfo);	// stream header
	if(hr != AVIERR_OK)
	{
		LOG.Write("\nERROR - CAviRenderer::StartRender(): AVIFileCreateStream() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	// Get save options (prompt dialog)

	_fmemset(&m_aviOptions, 0, sizeof(m_aviOptions));

	if(!AVISaveOptions(NULL, 0, 1, &m_pAviStream, (LPAVICOMPRESSOPTIONS FAR *) &m_pAviOptions))
	{
        LOG.Write("\nERROR - CAviRenderer::StartRender(): AVISaveOptions() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	// Create compressed stream

	hr = AVIMakeCompressedStream(&m_pAviStreamCompressed, m_pAviStream, &m_aviOptions, NULL);

	if(hr != AVIERR_OK)
	{
        LOG.Write("\nERROR - CAviRenderer::StartRender(): AVIMakeCompressedStream() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	// Set it's format

	hr = AVIStreamSetFormat(m_pAviStreamCompressed, 0,
							lpInfoHeader,	         // stream format
							lpInfoHeader->biSize +   // format size
							lpInfoHeader->biClrUsed * sizeof(RGBQUAD));

	if(hr != AVIERR_OK)
	{
		LOG.Write("\nERROR - CAviRenderer::StartRender(): AVIStreamSetFormat() failed.");
		GlobalFreePtr(lpInfoHeader);
		return false;
	}

	m_pWindowGL  = pWindowGL;
	m_bIsWorking = true;

	UpdateWindow(pWindowGL->GetHWND());

	return true;
}
Exemple #3
0
bool MovieMaker::Snap()
{
	HRESULT hr;

	if (!bOK)
		return false;

    // Get an image and stuff it into a bitmap.
    HBITMAP bmp;
    bmp = LoadBMPFromFB( width, height );

	LPBITMAPINFOHEADER alpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 32));
    DeleteObject( bmp );

	if (alpbi == NULL)
        {
        bOK = false;
		return false;
        }
	if (width>=0 && width != alpbi->biWidth)
	{
		GlobalFreePtr(alpbi);
        bOK = false;
		return false;
	}
	if (height>=0 && height != alpbi->biHeight)
	{
		GlobalFreePtr(alpbi);
        bOK = false;
		return false;
	}
	width = alpbi->biWidth;
	height = alpbi->biHeight;
	if (nFrames == 0)
	{
		hr = AVIFileOpenA(&pfile,		    // returned file pointer
			       fname,							// file name
				   OF_WRITE | OF_CREATE,		    // mode to open file with
				   NULL);							// use handler determined
													// from file extension....
		if (hr != AVIERR_OK)
		{
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}
		_fmemset(&strhdr, 0, sizeof(strhdr));
		strhdr.fccType                = streamtypeVIDEO;// stream type
		strhdr.fccHandler             = 0;
		strhdr.dwScale                = 1;
		strhdr.dwRate                 = 15;
		strhdr.dwSuggestedBufferSize  = alpbi->biSizeImage;
		SetRect(&strhdr.rcFrame, 0, 0,		    // rectangle for stream
			(int) alpbi->biWidth,
			(int) alpbi->biHeight);

		// And create the stream;
		hr = AVIFileCreateStream(pfile,		    // file pointer
						         &ps,		    // returned stream pointer
								 &strhdr);	    // stream header
		if (hr != AVIERR_OK)
		{
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}

		_fmemset(&opts, 0, sizeof(opts));

		if (!AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
		{
            fprintf( stderr, "AVISaveOptions failed.\n" );
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}

		hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
		if (hr != AVIERR_OK)
		{
            fprintf( stderr, "AVIMakeCompressedStream failed.\n" );
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}

		hr = AVIStreamSetFormat(psCompressed, 0,
					   alpbi,	    // stream format
				       alpbi->biSize +   // format size
				       alpbi->biClrUsed * sizeof(RGBQUAD));
		if (hr != AVIERR_OK)
		{
            fprintf( stderr, "AVIStreamSetFormat failed.\n" );
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}

		// Fill in the stream header for the text stream....

		// The text stream is in 60ths of a second....
/*
		_fmemset(&strhdr, 0, sizeof(strhdr));
		strhdr.fccType                = streamtypeTEXT;
		strhdr.fccHandler             = mmioFOURCC('D', 'R', 'A', 'W');
		strhdr.dwScale                = 1;
		strhdr.dwRate                 = 60;
		strhdr.dwSuggestedBufferSize  = sizeof(szText);
		SetRect(&strhdr.rcFrame, 0, (int) alpbi->biHeight,
			(int) alpbi->biWidth, (int) alpbi->biHeight + TEXT_HEIGHT);

		// ....and create the stream.
		hr = AVIFileCreateStream(pfile, &psText, &strhdr);
		if (hr != AVIERR_OK)
		{
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}

		dwTextFormat = sizeof(dwTextFormat);
		hr = AVIStreamSetFormat(psText, 0, &dwTextFormat, sizeof(dwTextFormat));
		if (hr != AVIERR_OK)
		{
			GlobalFreePtr(alpbi);
			bOK = false;
			return false;
		}
*/
	}

	// Now actual writing
	hr = AVIStreamWrite(psCompressed,	// stream pointer
		nFrames * 1, // 10,				// time of this frame
		1,				// number to write
		(LPBYTE) alpbi +		// pointer to data
			alpbi->biSize +
			alpbi->biClrUsed * sizeof(RGBQUAD),
			alpbi->biSizeImage,	// size of this frame
		AVIIF_KEYFRAME,			 // flags....
		NULL,
		NULL);
	if (hr != AVIERR_OK)
	{
        fprintf( stderr, "AVIStreamWrite failed.\n" );
		GlobalFreePtr(alpbi);
		bOK = false;
		return false;
	}

	// Make some text to put in the file ...
	//LoadString(hInstance, IDS_TEXTFORMAT, szMessage, BUFSIZE );
	/*
	strcpy(szMessage, "This is frame #%d");
		
	int iLen = wsprintf(szText, szMessage, (int)(nFrames + 1));

	// ... and write it as well.
	hr = AVIStreamWrite(psText,
			nFrames * 40,
			1,
			szText,
			iLen + 1,
			AVIIF_KEYFRAME,
			NULL,
			NULL);
	if (hr != AVIERR_OK)
	{
		GlobalFreePtr(alpbi);
		bOK = false;
		return false;
	}
	*/
	GlobalFreePtr(alpbi);

	nFrames++;

    fprintf( stderr, "Wrote frame %d.\r", nFrames );

	return true;
}