1 // Created on: 2007-04-15
2 // Created by: Alexey MORENOV & Alexander GRIGORIEV
3 // Copyright (c) 2007-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #include <OpenGl_AVIWriter.hxx>
22 #if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
24 #pragma comment (lib, "vfw32.lib")
27 OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
29 OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
31 return MyAVIWriterInstance;
34 //=======================================================================
35 //function : OpenGl_AVIWriter
37 //=======================================================================
39 Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
40 (const char * theFileName,
41 DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
42 Standard_Integer theFrameRate /* = 25 */)
50 mypAviCompressedStream(0L),
52 myIsAllowRecord (Standard_False),
53 myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual
56 if (theFileName != 0L && theFileName[0] != '\0') {
58 const size_t aLen = strlen(theFileName) + 1;
59 myFileName = new char [aLen];
60 memcpy(myFileName, theFileName, aLen);
61 myErrMsg = (Standard_CString)"Method Succeeded";
63 pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
64 pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
65 pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
67 pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
68 pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
69 pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
71 MyAVIWriterInstance = this;
73 ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFO));
74 myAviStreamInfo.fccType = streamtypeVIDEO;
75 myAviStreamInfo.fccHandler = dwCodec;
76 myAviStreamInfo.dwScale = 1;
77 myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second;
78 myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/
80 ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
81 myAviCompressOptions.fccType = streamtypeVIDEO;
82 myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler;
83 myAviCompressOptions.dwFlags =
84 AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE;
85 myAviCompressOptions.dwKeyFrameEvery = 1;
86 myAviCompressOptions.dwBytesPerSecond = 125000;
87 myAviCompressOptions.dwQuality = 100;
91 //=======================================================================
92 //function : ~OpenGl_AVIWriter
94 //=======================================================================
96 Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
101 delete [] myFileName;
102 MyAVIWriterInstance = 0L;
105 //=======================================================================
106 //function : StartRecording
108 //=======================================================================
110 void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
114 myIsAllowRecord = Standard_True;
117 //=======================================================================
118 //function : StopRecording
120 //=======================================================================
122 void OpenGl_AVIWriter::StopRecording()
124 myIsAllowRecord = Standard_False;
127 //=======================================================================
128 //function : ReleaseMemory
130 //=======================================================================
132 void OpenGl_AVIWriter::ReleaseMemory()
134 myAppendFuncSelector=0; //Point to DummyFunction
141 if(mypAviCompressedStream)
143 AVIStreamRelease(mypAviCompressedStream);
144 mypAviCompressedStream=NULL;
148 AVIStreamRelease(mypAviStream);
153 AVIFileRelease(mypAviFile);
158 HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
163 HeapDestroy(myhHeap);
168 //=======================================================================
169 //function : SetErrorMessage
171 //=======================================================================
173 void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
175 myErrMsg = (Standard_CString)theErrorMessage;
178 //=======================================================================
179 //function : InitMovieCreation
181 //=======================================================================
183 HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
187 int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
188 nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
190 myhAviDC = CreateCompatibleDC(NULL);
193 SetErrorMessage("Unable to Create Compatible DC");
197 if (nFrameWidth > nMaxWidth)
198 nMaxWidth= nFrameWidth;
199 if (nFrameHeight > nMaxHeight)
200 nMaxHeight = nFrameHeight;
202 myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
205 SetErrorMessage("Unable to Create Heap");
209 mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
210 nMaxWidth*nMaxHeight*4);
213 SetErrorMessage("Unable to Allocate Memory on Heap");
218 hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
219 if (!hr == AVIERR_OK)
221 SetErrorMessage("Unable to Create the Movie File");
225 if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL)))
227 SetErrorMessage("Unable to Create the Movie File");
232 myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
233 SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
234 strncpy(myAviStreamInfo.szName, "Video Stream", 64);
236 if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo)))
238 SetErrorMessage("Unable to Create Video Stream in the Movie File");
242 if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
244 &myAviCompressOptions,
247 // One reason this error might occur is if you are using a Codec that is not
248 // available on your system. Check the mmioFOURCC() code you are using and
249 // make sure you have that codec installed properly on your machine.
250 SetErrorMessage("Unable to Create Compressed Stream: "
251 "Check your CODEC options");
256 ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
257 bmpInfo.bmiHeader.biPlanes = 1;
258 bmpInfo.bmiHeader.biWidth = nFrameWidth;
259 bmpInfo.bmiHeader.biHeight = nFrameHeight;
260 bmpInfo.bmiHeader.biCompression = BI_RGB;
261 bmpInfo.bmiHeader.biBitCount = nBitsPerPixel;
262 bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
263 bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth *
264 bmpInfo.bmiHeader.biHeight*
265 bmpInfo.bmiHeader.biBitCount)/8;
267 if(FAILED(AVIStreamSetFormat(mypAviCompressedStream,
270 bmpInfo.bmiHeader.biSize)))
272 // One reason this error might occur is if your bitmap does not meet
273 // the Codec requirements.
275 // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
276 // your bitmap is 274 * 258 size, while the Codec supports only sizes
277 // that are powers of 2; etc...
278 // Possible solution to avoid this is: make your bitmap suit the codec
279 // requirements, or Choose a codec that is suitable for your bitmap.
280 SetErrorMessage("Unable to Set Video Stream Format");
284 return S_OK; // Everything went Fine
287 //=======================================================================
288 //function : AppendFrameFirstTime
290 //=======================================================================
292 HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap)
295 GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
297 if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
299 Bitmap.bmBitsPixel)))
301 myAppendFuncSelector = 2; //Point to the UsualAppend Function
302 return AppendFrameUsual(hBitmap);
309 //=======================================================================
310 //function : AppendFrameUsual
312 //=======================================================================
314 HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
318 bmpInfo.bmiHeader.biBitCount=0;
319 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
321 GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
323 bmpInfo.bmiHeader.biCompression=BI_RGB;
328 bmpInfo.bmiHeader.biHeight,
333 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
337 bmpInfo.bmiHeader.biSizeImage,
342 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
350 //=======================================================================
351 //function : AppendDummy
353 //=======================================================================
355 HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
360 //=======================================================================
361 //function : AppendNewFrame
363 //=======================================================================
365 HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
367 return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
370 //=======================================================================
371 //function : AppendNewFrame
373 //=======================================================================
375 HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
380 return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
386 //=======================================================================
387 //function : AppendFrameFirstTime
389 //=======================================================================
391 HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
396 if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
398 myAppendFuncSelector=2; //Point to the UsualAppend Function
399 return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
406 //=======================================================================
407 //function : AppendFrameUsual
409 //=======================================================================
411 HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
416 DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
418 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
427 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
435 //=======================================================================
436 //function : AppendDummy
438 //=======================================================================
440 HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth,
448 //=======================================================================
449 //function : AviWriter
451 //=======================================================================
453 void OpenGl_AVIWriter_AVIWriter(void * pp,
458 if (OpenGl_AVIWriter::GetInstance() != 0L)
459 if (OpenGl_AVIWriter::GetInstance()->IsRecording())
462 OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth,
469 //=======================================================================
470 //function : AllowWriting
472 //=======================================================================
474 Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
476 Standard_Boolean aResult(Standard_False);
477 const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
479 if (hWin == NULL || anInst->HWindow() == hWin)
480 aResult = static_cast<Standard_Boolean> (anInst->IsRecording());