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.
21 #include <OpenGl_AVIWriter.hxx>
24 OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
26 OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
28 return MyAVIWriterInstance;
31 //=======================================================================
32 //function : OpenGl_AVIWriter
34 //=======================================================================
36 Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
37 (const char * theFileName,
38 DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
39 Standard_Integer theFrameRate /* = 25 */)
47 mypAviCompressedStream(0L),
49 myIsAllowRecord (Standard_False),
50 myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual
53 if (theFileName != 0L && theFileName[0] != '\0') {
55 const size_t aLen = strlen(theFileName) + 1;
56 myFileName = new char [aLen];
57 memcpy(myFileName, theFileName, aLen);
58 myErrMsg = (Standard_CString)"Method Succeeded";
60 pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
61 pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
62 pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
64 pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
65 pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
66 pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
68 MyAVIWriterInstance = this;
70 ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFO));
71 myAviStreamInfo.fccType = streamtypeVIDEO;
72 myAviStreamInfo.fccHandler = dwCodec;
73 myAviStreamInfo.dwScale = 1;
74 myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second;
75 myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/
77 ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
78 myAviCompressOptions.fccType = streamtypeVIDEO;
79 myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler;
80 myAviCompressOptions.dwFlags =
81 AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE;
82 myAviCompressOptions.dwKeyFrameEvery = 1;
83 myAviCompressOptions.dwBytesPerSecond = 125000;
84 myAviCompressOptions.dwQuality = 100;
88 //=======================================================================
89 //function : ~OpenGl_AVIWriter
91 //=======================================================================
93 Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
99 MyAVIWriterInstance = 0L;
102 //=======================================================================
103 //function : StartRecording
105 //=======================================================================
107 void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
111 myIsAllowRecord = Standard_True;
114 //=======================================================================
115 //function : StopRecording
117 //=======================================================================
119 void OpenGl_AVIWriter::StopRecording()
121 myIsAllowRecord = Standard_False;
124 //=======================================================================
125 //function : ReleaseMemory
127 //=======================================================================
129 void OpenGl_AVIWriter::ReleaseMemory()
131 myAppendFuncSelector=0; //Point to DummyFunction
138 if(mypAviCompressedStream)
140 AVIStreamRelease(mypAviCompressedStream);
141 mypAviCompressedStream=NULL;
145 AVIStreamRelease(mypAviStream);
150 AVIFileRelease(mypAviFile);
155 HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
160 HeapDestroy(myhHeap);
165 //=======================================================================
166 //function : SetErrorMessage
168 //=======================================================================
170 void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
172 myErrMsg = (Standard_CString)theErrorMessage;
175 //=======================================================================
176 //function : InitMovieCreation
178 //=======================================================================
180 HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
184 int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
185 nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
187 myhAviDC = CreateCompatibleDC(NULL);
190 SetErrorMessage("Unable to Create Compatible DC");
194 if (nFrameWidth > nMaxWidth)
195 nMaxWidth= nFrameWidth;
196 if (nFrameHeight > nMaxHeight)
197 nMaxHeight = nFrameHeight;
199 myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
202 SetErrorMessage("Unable to Create Heap");
206 mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
207 nMaxWidth*nMaxHeight*4);
210 SetErrorMessage("Unable to Allocate Memory on Heap");
215 hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
216 if (!hr == AVIERR_OK)
218 SetErrorMessage("Unable to Create the Movie File");
222 if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL)))
224 SetErrorMessage("Unable to Create the Movie File");
229 myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
230 SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
231 strncpy(myAviStreamInfo.szName, "Video Stream", 64);
233 if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo)))
235 SetErrorMessage("Unable to Create Video Stream in the Movie File");
239 if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
241 &myAviCompressOptions,
244 // One reason this error might occur is if you are using a Codec that is not
245 // available on your system. Check the mmioFOURCC() code you are using and
246 // make sure you have that codec installed properly on your machine.
247 SetErrorMessage("Unable to Create Compressed Stream: "
248 "Check your CODEC options");
253 ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
254 bmpInfo.bmiHeader.biPlanes = 1;
255 bmpInfo.bmiHeader.biWidth = nFrameWidth;
256 bmpInfo.bmiHeader.biHeight = nFrameHeight;
257 bmpInfo.bmiHeader.biCompression = BI_RGB;
258 bmpInfo.bmiHeader.biBitCount = nBitsPerPixel;
259 bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
260 bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth *
261 bmpInfo.bmiHeader.biHeight*
262 bmpInfo.bmiHeader.biBitCount)/8;
264 if(FAILED(AVIStreamSetFormat(mypAviCompressedStream,
267 bmpInfo.bmiHeader.biSize)))
269 // One reason this error might occur is if your bitmap does not meet
270 // the Codec requirements.
272 // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
273 // your bitmap is 274 * 258 size, while the Codec supports only sizes
274 // that are powers of 2; etc...
275 // Possible solution to avoid this is: make your bitmap suit the codec
276 // requirements, or Choose a codec that is suitable for your bitmap.
277 SetErrorMessage("Unable to Set Video Stream Format");
281 return S_OK; // Everything went Fine
284 //=======================================================================
285 //function : AppendFrameFirstTime
287 //=======================================================================
289 HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap)
292 GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
294 if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
296 Bitmap.bmBitsPixel)))
298 myAppendFuncSelector = 2; //Point to the UsualAppend Function
299 return AppendFrameUsual(hBitmap);
306 //=======================================================================
307 //function : AppendFrameUsual
309 //=======================================================================
311 HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
315 bmpInfo.bmiHeader.biBitCount=0;
316 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
318 GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
320 bmpInfo.bmiHeader.biCompression=BI_RGB;
325 bmpInfo.bmiHeader.biHeight,
330 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
334 bmpInfo.bmiHeader.biSizeImage,
339 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
347 //=======================================================================
348 //function : AppendDummy
350 //=======================================================================
352 HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
357 //=======================================================================
358 //function : AppendNewFrame
360 //=======================================================================
362 HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
364 return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
367 //=======================================================================
368 //function : AppendNewFrame
370 //=======================================================================
372 HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
377 return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
383 //=======================================================================
384 //function : AppendFrameFirstTime
386 //=======================================================================
388 HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
393 if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
395 myAppendFuncSelector=2; //Point to the UsualAppend Function
396 return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
403 //=======================================================================
404 //function : AppendFrameUsual
406 //=======================================================================
408 HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
413 DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
415 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
424 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
432 //=======================================================================
433 //function : AppendDummy
435 //=======================================================================
437 HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth,
445 //=======================================================================
446 //function : AviWriter
448 //=======================================================================
450 void OpenGl_AVIWriter_AVIWriter(void * pp,
455 if (OpenGl_AVIWriter::GetInstance() != 0L)
456 if (OpenGl_AVIWriter::GetInstance()->IsRecording())
459 OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth,
466 //=======================================================================
467 //function : AllowWriting
469 //=======================================================================
471 Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
473 Standard_Boolean aResult(Standard_False);
474 const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
476 if (hWin == NULL || anInst->HWindow() == hWin)
477 aResult = static_cast<Standard_Boolean> (anInst->IsRecording());