1 // Created on: 2007-04-15
2 // Created by: Alexey MORENOV & Alexander GRIGORIEV
3 // Copyright (c) 2007-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_AVIWriter.hxx>
18 #if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
20 #pragma comment (lib, "vfw32.lib")
23 OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
25 OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
27 return MyAVIWriterInstance;
30 //=======================================================================
31 //function : OpenGl_AVIWriter
33 //=======================================================================
35 Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
36 (const char * theFileName,
37 DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
38 Standard_Integer theFrameRate /* = 25 */)
46 mypAviCompressedStream(0L),
48 myIsAllowRecord (Standard_False),
49 myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual
52 if (theFileName != 0L && theFileName[0] != '\0') {
54 const size_t aLen = strlen(theFileName) + 1;
55 myFileName = new char [aLen];
56 memcpy(myFileName, theFileName, aLen);
57 myErrMsg = (Standard_CString)"Method Succeeded";
59 pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
60 pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
61 pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
63 pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
64 pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
65 pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
67 MyAVIWriterInstance = this;
69 ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFO));
70 myAviStreamInfo.fccType = streamtypeVIDEO;
71 myAviStreamInfo.fccHandler = dwCodec;
72 myAviStreamInfo.dwScale = 1;
73 myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second;
74 myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/
76 ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
77 myAviCompressOptions.fccType = streamtypeVIDEO;
78 myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler;
79 myAviCompressOptions.dwFlags =
80 AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE;
81 myAviCompressOptions.dwKeyFrameEvery = 1;
82 myAviCompressOptions.dwBytesPerSecond = 125000;
83 myAviCompressOptions.dwQuality = 100;
87 //=======================================================================
88 //function : ~OpenGl_AVIWriter
90 //=======================================================================
92 Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
98 MyAVIWriterInstance = 0L;
101 //=======================================================================
102 //function : StartRecording
104 //=======================================================================
106 void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
110 myIsAllowRecord = Standard_True;
113 //=======================================================================
114 //function : StopRecording
116 //=======================================================================
118 void OpenGl_AVIWriter::StopRecording()
120 myIsAllowRecord = Standard_False;
123 //=======================================================================
124 //function : ReleaseMemory
126 //=======================================================================
128 void OpenGl_AVIWriter::ReleaseMemory()
130 myAppendFuncSelector=0; //Point to DummyFunction
137 if(mypAviCompressedStream)
139 AVIStreamRelease(mypAviCompressedStream);
140 mypAviCompressedStream=NULL;
144 AVIStreamRelease(mypAviStream);
149 AVIFileRelease(mypAviFile);
154 HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
159 HeapDestroy(myhHeap);
164 //=======================================================================
165 //function : SetErrorMessage
167 //=======================================================================
169 void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
171 myErrMsg = (Standard_CString)theErrorMessage;
174 //=======================================================================
175 //function : InitMovieCreation
177 //=======================================================================
179 HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
183 int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
184 nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
186 myhAviDC = CreateCompatibleDC(NULL);
189 SetErrorMessage("Unable to Create Compatible DC");
193 if (nFrameWidth > nMaxWidth)
194 nMaxWidth= nFrameWidth;
195 if (nFrameHeight > nMaxHeight)
196 nMaxHeight = nFrameHeight;
198 myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
201 SetErrorMessage("Unable to Create Heap");
205 mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
206 nMaxWidth*nMaxHeight*4);
209 SetErrorMessage("Unable to Allocate Memory on Heap");
214 hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
215 if (!hr == AVIERR_OK)
217 SetErrorMessage("Unable to Create the Movie File");
221 if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL)))
223 SetErrorMessage("Unable to Create the Movie File");
228 myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
229 SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
230 strncpy(myAviStreamInfo.szName, "Video Stream", 64);
232 if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo)))
234 SetErrorMessage("Unable to Create Video Stream in the Movie File");
238 if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
240 &myAviCompressOptions,
243 // One reason this error might occur is if you are using a Codec that is not
244 // available on your system. Check the mmioFOURCC() code you are using and
245 // make sure you have that codec installed properly on your machine.
246 SetErrorMessage("Unable to Create Compressed Stream: "
247 "Check your CODEC options");
252 ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
253 bmpInfo.bmiHeader.biPlanes = 1;
254 bmpInfo.bmiHeader.biWidth = nFrameWidth;
255 bmpInfo.bmiHeader.biHeight = nFrameHeight;
256 bmpInfo.bmiHeader.biCompression = BI_RGB;
257 bmpInfo.bmiHeader.biBitCount = nBitsPerPixel;
258 bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
259 bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth *
260 bmpInfo.bmiHeader.biHeight*
261 bmpInfo.bmiHeader.biBitCount)/8;
263 if(FAILED(AVIStreamSetFormat(mypAviCompressedStream,
266 bmpInfo.bmiHeader.biSize)))
268 // One reason this error might occur is if your bitmap does not meet
269 // the Codec requirements.
271 // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
272 // your bitmap is 274 * 258 size, while the Codec supports only sizes
273 // that are powers of 2; etc...
274 // Possible solution to avoid this is: make your bitmap suit the codec
275 // requirements, or Choose a codec that is suitable for your bitmap.
276 SetErrorMessage("Unable to Set Video Stream Format");
280 return S_OK; // Everything went Fine
283 //=======================================================================
284 //function : AppendFrameFirstTime
286 //=======================================================================
288 HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap)
291 GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
293 if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
295 Bitmap.bmBitsPixel)))
297 myAppendFuncSelector = 2; //Point to the UsualAppend Function
298 return AppendFrameUsual(hBitmap);
305 //=======================================================================
306 //function : AppendFrameUsual
308 //=======================================================================
310 HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
314 bmpInfo.bmiHeader.biBitCount=0;
315 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
317 GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
319 bmpInfo.bmiHeader.biCompression=BI_RGB;
324 bmpInfo.bmiHeader.biHeight,
329 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
333 bmpInfo.bmiHeader.biSizeImage,
338 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
346 //=======================================================================
347 //function : AppendDummy
349 //=======================================================================
351 HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
356 //=======================================================================
357 //function : AppendNewFrame
359 //=======================================================================
361 HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
363 return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
366 //=======================================================================
367 //function : AppendNewFrame
369 //=======================================================================
371 HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
376 return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
382 //=======================================================================
383 //function : AppendFrameFirstTime
385 //=======================================================================
387 HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
392 if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
394 myAppendFuncSelector=2; //Point to the UsualAppend Function
395 return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
402 //=======================================================================
403 //function : AppendFrameUsual
405 //=======================================================================
407 HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
412 DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
414 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
423 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
431 //=======================================================================
432 //function : AppendDummy
434 //=======================================================================
436 HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth,
444 //=======================================================================
445 //function : AviWriter
447 //=======================================================================
449 void OpenGl_AVIWriter_AVIWriter(void * pp,
454 if (OpenGl_AVIWriter::GetInstance() != 0L)
455 if (OpenGl_AVIWriter::GetInstance()->IsRecording())
458 OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth,
465 //=======================================================================
466 //function : AllowWriting
468 //=======================================================================
470 Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
472 Standard_Boolean aResult(Standard_False);
473 const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
475 if (hWin == NULL || anInst->HWindow() == hWin)
476 aResult = static_cast<Standard_Boolean> (anInst->IsRecording());