// Created on: 2007-04-15 // Created by: Alexey MORENOV & Alexander GRIGORIEV // Copyright (c) 2007-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #include #ifdef WNT OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L; OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance() { return MyAVIWriterInstance; } //======================================================================= //function : OpenGl_AVIWriter //purpose : //======================================================================= Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter (const char * theFileName, DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */, Standard_Integer theFrameRate /* = 25 */) : myhHeap (0L), myhWindow (0L), myhAviDC (0L), mylpBits (0L), mylSample (0L), mypAviFile (0L), mypAviStream (0L), mypAviCompressedStream(0L), myFileName (0L), myIsAllowRecord (Standard_False), myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual { ::AVIFileInit(); if (theFileName != 0L && theFileName[0] != '\0') { const size_t aLen = strlen(theFileName) + 1; myFileName = new char [aLen]; memcpy(myFileName, theFileName, aLen); myErrMsg = (Standard_CString)"Method Succeeded"; pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy; pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime; pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual; pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits; pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime; pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual; MyAVIWriterInstance = this; ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFO)); myAviStreamInfo.fccType = streamtypeVIDEO; myAviStreamInfo.fccHandler = dwCodec; myAviStreamInfo.dwScale = 1; myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second; myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/ ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS)); myAviCompressOptions.fccType = streamtypeVIDEO; myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler; myAviCompressOptions.dwFlags = AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE; myAviCompressOptions.dwKeyFrameEvery = 1; myAviCompressOptions.dwBytesPerSecond = 125000; myAviCompressOptions.dwQuality = 100; } } //======================================================================= //function : ~OpenGl_AVIWriter //purpose : //======================================================================= Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void) { ReleaseMemory(); AVIFileExit(); if (myFileName) delete [] myFileName; MyAVIWriterInstance = 0L; } //======================================================================= //function : StartRecording //purpose : //======================================================================= void OpenGl_AVIWriter::StartRecording(const HANDLE hWin) { if (hWin != NULL) myhWindow = hWin; myIsAllowRecord = Standard_True; } //======================================================================= //function : StopRecording //purpose : //======================================================================= void OpenGl_AVIWriter::StopRecording() { myIsAllowRecord = Standard_False; } //======================================================================= //function : ReleaseMemory //purpose : //======================================================================= void OpenGl_AVIWriter::ReleaseMemory() { myAppendFuncSelector=0; //Point to DummyFunction if(myhAviDC) { DeleteDC(myhAviDC); myhAviDC=NULL; } if(mypAviCompressedStream) { AVIStreamRelease(mypAviCompressedStream); mypAviCompressedStream=NULL; } if(mypAviStream) { AVIStreamRelease(mypAviStream); mypAviStream=NULL; } if(mypAviFile) { AVIFileRelease(mypAviFile); mypAviFile=NULL; } if(mylpBits) { HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits); mylpBits=NULL; } if(myhHeap) { HeapDestroy(myhHeap); myhHeap=NULL; } } //======================================================================= //function : SetErrorMessage //purpose : //======================================================================= void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage) { myErrMsg = (Standard_CString)theErrorMessage; } //======================================================================= //function : InitMovieCreation //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth, int nFrameHeight, int nBitsPerPixel) { int nMaxWidth=GetSystemMetrics(SM_CXSCREEN), nMaxHeight=GetSystemMetrics(SM_CYSCREEN); myhAviDC = CreateCompatibleDC(NULL); if(myhAviDC==NULL) { SetErrorMessage("Unable to Create Compatible DC"); return E_FAIL; } if (nFrameWidth > nMaxWidth) nMaxWidth= nFrameWidth; if (nFrameHeight > nMaxHeight) nMaxHeight = nFrameHeight; myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0); if(myhHeap==NULL) { SetErrorMessage("Unable to Create Heap"); return E_FAIL; } mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4); if(mylpBits==NULL) { SetErrorMessage("Unable to Allocate Memory on Heap"); return E_FAIL; } HRESULT hr; hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL); if (!hr == AVIERR_OK) { SetErrorMessage("Unable to Create the Movie File"); return E_FAIL; } /* if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL))) { SetErrorMessage("Unable to Create the Movie File"); return E_FAIL; } */ myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4; SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight); strncpy(myAviStreamInfo.szName, "Video Stream", 64); if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo))) { SetErrorMessage("Unable to Create Video Stream in the Movie File"); return E_FAIL; } if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream, mypAviStream, &myAviCompressOptions, NULL))) { // One reason this error might occur is if you are using a Codec that is not // available on your system. Check the mmioFOURCC() code you are using and // make sure you have that codec installed properly on your machine. SetErrorMessage("Unable to Create Compressed Stream: " "Check your CODEC options"); return E_FAIL; } BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biWidth = nFrameWidth; bmpInfo.bmiHeader.biHeight = nFrameHeight; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biBitCount = nBitsPerPixel; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biHeight* bmpInfo.bmiHeader.biBitCount)/8; if(FAILED(AVIStreamSetFormat(mypAviCompressedStream, 0, (LPVOID)&bmpInfo, bmpInfo.bmiHeader.biSize))) { // One reason this error might occur is if your bitmap does not meet // the Codec requirements. // For example, // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or // your bitmap is 274 * 258 size, while the Codec supports only sizes // that are powers of 2; etc... // Possible solution to avoid this is: make your bitmap suit the codec // requirements, or Choose a codec that is suitable for your bitmap. SetErrorMessage("Unable to Set Video Stream Format"); return E_FAIL; } return S_OK; // Everything went Fine } //======================================================================= //function : AppendFrameFirstTime //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap) { BITMAP Bitmap; GetObject(hBitmap, sizeof(BITMAP), &Bitmap); if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth, Bitmap.bmHeight, Bitmap.bmBitsPixel))) { myAppendFuncSelector = 2; //Point to the UsualAppend Function return AppendFrameUsual(hBitmap); } ReleaseMemory(); return E_FAIL; } //======================================================================= //function : AppendFrameUsual //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap) { BITMAPINFO bmpInfo; bmpInfo.bmiHeader.biBitCount=0; bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(myhAviDC, hBitmap, 0, bmpInfo.bmiHeader.biHeight, mylpBits, &bmpInfo, DIB_RGB_COLORS); if(FAILED(AVIStreamWrite(mypAviCompressedStream, mylSample++, 1, mylpBits, bmpInfo.bmiHeader.biSizeImage, 0, NULL, NULL))) { SetErrorMessage("Unable to Write Video Stream to the output Movie File"); ReleaseMemory(); return E_FAIL; } return S_OK; } //======================================================================= //function : AppendDummy //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP) { return E_FAIL; } //======================================================================= //function : AppendNewFrame //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap) { return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap); } //======================================================================= //function : AppendNewFrame //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth, int nHeight, LPVOID pBits, int nBitsPerPixel) { return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth, nHeight, pBits, nBitsPerPixel); } //======================================================================= //function : AppendFrameFirstTime //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth, int nHeight, LPVOID pBits, int nBitsPerPixel) { if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel))) { myAppendFuncSelector=2; //Point to the UsualAppend Function return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel); } ReleaseMemory(); return E_FAIL; } //======================================================================= //function : AppendFrameUsual //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth, int nHeight, LPVOID pBits, int nBitsPerPixel) { DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8; if(FAILED(AVIStreamWrite(mypAviCompressedStream, mylSample++, 1, pBits, dwSize, 0, NULL, NULL))) { SetErrorMessage("Unable to Write Video Stream to the output Movie File"); ReleaseMemory(); return E_FAIL; } return S_OK; } //======================================================================= //function : AppendDummy //purpose : //======================================================================= HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth, int nHeight, LPVOID pBits, int nBitsPerPixel) { return E_FAIL; } //======================================================================= //function : AviWriter //purpose : //======================================================================= void OpenGl_AVIWriter_AVIWriter(void * pp, int nWidth, int nHeight, int nBitsPerPixel) { if (OpenGl_AVIWriter::GetInstance() != 0L) if (OpenGl_AVIWriter::GetInstance()->IsRecording()) { OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth, nHeight, pp, nBitsPerPixel); } } //======================================================================= //function : AllowWriting //purpose : //======================================================================= Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin) { Standard_Boolean aResult(Standard_False); const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance(); if (anInst != 0L) { if (hWin == NULL || anInst->HWindow() == hWin) aResult = static_cast (anInst->IsRecording()); } return aResult; } #endif //WNT