1 // File: OpenGl_AVIWriter.cxx
2 // Created: 15.04.07 13:44
3 // Author: Alexey MORENOV & Alexander GRIGORIEV
4 // Copyright: Open CASCADE 2007
6 #include <OpenGl_AVIWriter.hxx>
9 OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
11 OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
13 return MyAVIWriterInstance;
16 //=======================================================================
17 //function : OpenGl_AVIWriter
19 //=======================================================================
21 Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
22 (const char * theFileName,
23 DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
24 Standard_Integer theFrameRate /* = 25 */)
32 mypAviCompressedStream(0L),
34 myIsAllowRecord (Standard_False),
35 myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual
38 if (theFileName != 0L && theFileName[0] != '\0') {
40 const size_t aLen = strlen(theFileName) + 1;
41 myFileName = new char [aLen];
42 memcpy(myFileName, theFileName, aLen);
43 myErrMsg = (Standard_CString)"Method Succeeded";
45 pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
46 pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
47 pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
49 pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
50 pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
51 pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
53 MyAVIWriterInstance = this;
55 ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFO));
56 myAviStreamInfo.fccType = streamtypeVIDEO;
57 myAviStreamInfo.fccHandler = dwCodec;
58 myAviStreamInfo.dwScale = 1;
59 myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second;
60 myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/
62 ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
63 myAviCompressOptions.fccType = streamtypeVIDEO;
64 myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler;
65 myAviCompressOptions.dwFlags =
66 AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE;
67 myAviCompressOptions.dwKeyFrameEvery = 1;
68 myAviCompressOptions.dwBytesPerSecond = 125000;
69 myAviCompressOptions.dwQuality = 100;
73 //=======================================================================
74 //function : ~OpenGl_AVIWriter
76 //=======================================================================
78 Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
84 MyAVIWriterInstance = 0L;
87 //=======================================================================
88 //function : StartRecording
90 //=======================================================================
92 void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
96 myIsAllowRecord = Standard_True;
99 //=======================================================================
100 //function : StopRecording
102 //=======================================================================
104 void OpenGl_AVIWriter::StopRecording()
106 myIsAllowRecord = Standard_False;
109 //=======================================================================
110 //function : ReleaseMemory
112 //=======================================================================
114 void OpenGl_AVIWriter::ReleaseMemory()
116 myAppendFuncSelector=0; //Point to DummyFunction
123 if(mypAviCompressedStream)
125 AVIStreamRelease(mypAviCompressedStream);
126 mypAviCompressedStream=NULL;
130 AVIStreamRelease(mypAviStream);
135 AVIFileRelease(mypAviFile);
140 HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
145 HeapDestroy(myhHeap);
150 //=======================================================================
151 //function : SetErrorMessage
153 //=======================================================================
155 void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
157 myErrMsg = (Standard_CString)theErrorMessage;
160 //=======================================================================
161 //function : InitMovieCreation
163 //=======================================================================
165 HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
169 int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
170 nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
172 myhAviDC = CreateCompatibleDC(NULL);
175 SetErrorMessage("Unable to Create Compatible DC");
179 if (nFrameWidth > nMaxWidth)
180 nMaxWidth= nFrameWidth;
181 if (nFrameHeight > nMaxHeight)
182 nMaxHeight = nFrameHeight;
184 myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
187 SetErrorMessage("Unable to Create Heap");
191 mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
192 nMaxWidth*nMaxHeight*4);
195 SetErrorMessage("Unable to Allocate Memory on Heap");
200 hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
201 if (!hr == AVIERR_OK)
203 SetErrorMessage("Unable to Create the Movie File");
207 if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL)))
209 SetErrorMessage("Unable to Create the Movie File");
214 myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
215 SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
216 strncpy(myAviStreamInfo.szName, "Video Stream", 64);
218 if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo)))
220 SetErrorMessage("Unable to Create Video Stream in the Movie File");
224 if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
226 &myAviCompressOptions,
229 // One reason this error might occur is if you are using a Codec that is not
230 // available on your system. Check the mmioFOURCC() code you are using and
231 // make sure you have that codec installed properly on your machine.
232 SetErrorMessage("Unable to Create Compressed Stream: "
233 "Check your CODEC options");
238 ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
239 bmpInfo.bmiHeader.biPlanes = 1;
240 bmpInfo.bmiHeader.biWidth = nFrameWidth;
241 bmpInfo.bmiHeader.biHeight = nFrameHeight;
242 bmpInfo.bmiHeader.biCompression = BI_RGB;
243 bmpInfo.bmiHeader.biBitCount = nBitsPerPixel;
244 bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
245 bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth *
246 bmpInfo.bmiHeader.biHeight*
247 bmpInfo.bmiHeader.biBitCount)/8;
249 if(FAILED(AVIStreamSetFormat(mypAviCompressedStream,
252 bmpInfo.bmiHeader.biSize)))
254 // One reason this error might occur is if your bitmap does not meet
255 // the Codec requirements.
257 // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
258 // your bitmap is 274 * 258 size, while the Codec supports only sizes
259 // that are powers of 2; etc...
260 // Possible solution to avoid this is: make your bitmap suit the codec
261 // requirements, or Choose a codec that is suitable for your bitmap.
262 SetErrorMessage("Unable to Set Video Stream Format");
266 return S_OK; // Everything went Fine
269 //=======================================================================
270 //function : AppendFrameFirstTime
272 //=======================================================================
274 HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap)
277 GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
279 if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
281 Bitmap.bmBitsPixel)))
283 myAppendFuncSelector = 2; //Point to the UsualAppend Function
284 return AppendFrameUsual(hBitmap);
291 //=======================================================================
292 //function : AppendFrameUsual
294 //=======================================================================
296 HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
300 bmpInfo.bmiHeader.biBitCount=0;
301 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
303 GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
305 bmpInfo.bmiHeader.biCompression=BI_RGB;
310 bmpInfo.bmiHeader.biHeight,
315 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
319 bmpInfo.bmiHeader.biSizeImage,
324 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
332 //=======================================================================
333 //function : AppendDummy
335 //=======================================================================
337 HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
342 //=======================================================================
343 //function : AppendNewFrame
345 //=======================================================================
347 HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
349 return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
352 //=======================================================================
353 //function : AppendNewFrame
355 //=======================================================================
357 HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
362 return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
368 //=======================================================================
369 //function : AppendFrameFirstTime
371 //=======================================================================
373 HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
378 if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
380 myAppendFuncSelector=2; //Point to the UsualAppend Function
381 return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
388 //=======================================================================
389 //function : AppendFrameUsual
391 //=======================================================================
393 HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
398 DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
400 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
409 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
417 //=======================================================================
418 //function : AppendDummy
420 //=======================================================================
422 HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth,
430 //=======================================================================
431 //function : AviWriter
433 //=======================================================================
435 void OpenGl_AVIWriter_AVIWriter(void * pp,
440 if (OpenGl_AVIWriter::GetInstance() != 0L)
441 if (OpenGl_AVIWriter::GetInstance()->IsRecording())
444 OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth,
451 //=======================================================================
452 //function : AllowWriting
454 //=======================================================================
456 Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
458 Standard_Boolean aResult(Standard_False);
459 const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
461 if (hWin == NULL || anInst->HWindow() == hWin)
462 aResult = static_cast<Standard_Boolean> (anInst->IsRecording());