0025703: Visualization - Decrease number of samplers used in ray-tracing mode
[occt.git] / src / OpenGl / OpenGl_AVIWriter.cxx
CommitLineData
b311480e 1// Created on: 2007-04-15
2// Created by: Alexey MORENOV & Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2007-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16#include <OpenGl_AVIWriter.hxx>
17
16fa0dfb 18#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
19 #ifdef _MSC_VER
20 #pragma comment (lib, "vfw32.lib")
21 #endif
22
7fd59977 23OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
24
25OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
26{
27 return MyAVIWriterInstance;
28}
29
30//=======================================================================
31//function : OpenGl_AVIWriter
32//purpose :
33//=======================================================================
34
35Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
36 (const char * theFileName,
37 DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
38 Standard_Integer theFrameRate /* = 25 */)
39 : myhHeap (0L),
40 myhWindow (0L),
41 myhAviDC (0L),
42 mylpBits (0L),
43 mylSample (0L),
44 mypAviFile (0L),
45 mypAviStream (0L),
46 mypAviCompressedStream(0L),
47 myFileName (0L),
48 myIsAllowRecord (Standard_False),
49 myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual
50{
51 ::AVIFileInit();
52 if (theFileName != 0L && theFileName[0] != '\0') {
53
54 const size_t aLen = strlen(theFileName) + 1;
55 myFileName = new char [aLen];
56 memcpy(myFileName, theFileName, aLen);
57 myErrMsg = (Standard_CString)"Method Succeeded";
58
59 pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
60 pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
61 pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
62
63 pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
64 pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
65 pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
66
67 MyAVIWriterInstance = this;
68
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*/
75
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;
84 }
85}
86
87//=======================================================================
88//function : ~OpenGl_AVIWriter
89//purpose :
90//=======================================================================
91
92Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
93{
94 ReleaseMemory();
95 AVIFileExit();
96 if (myFileName)
97 delete [] myFileName;
98 MyAVIWriterInstance = 0L;
99}
100
101//=======================================================================
102//function : StartRecording
103//purpose :
104//=======================================================================
105
106void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
107{
108 if (hWin != NULL)
109 myhWindow = hWin;
110 myIsAllowRecord = Standard_True;
111}
112
113//=======================================================================
114//function : StopRecording
115//purpose :
116//=======================================================================
117
118void OpenGl_AVIWriter::StopRecording()
119{
120 myIsAllowRecord = Standard_False;
121}
122
123//=======================================================================
124//function : ReleaseMemory
125//purpose :
126//=======================================================================
127
128void OpenGl_AVIWriter::ReleaseMemory()
129{
130 myAppendFuncSelector=0; //Point to DummyFunction
131
132 if(myhAviDC)
133 {
134 DeleteDC(myhAviDC);
135 myhAviDC=NULL;
136 }
137 if(mypAviCompressedStream)
138 {
139 AVIStreamRelease(mypAviCompressedStream);
140 mypAviCompressedStream=NULL;
141 }
142 if(mypAviStream)
143 {
144 AVIStreamRelease(mypAviStream);
145 mypAviStream=NULL;
146 }
147 if(mypAviFile)
148 {
149 AVIFileRelease(mypAviFile);
150 mypAviFile=NULL;
151 }
152 if(mylpBits)
153 {
154 HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
155 mylpBits=NULL;
156 }
157 if(myhHeap)
158 {
159 HeapDestroy(myhHeap);
160 myhHeap=NULL;
161 }
162}
163
164//=======================================================================
165//function : SetErrorMessage
166//purpose :
167//=======================================================================
168
169void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
170{
171 myErrMsg = (Standard_CString)theErrorMessage;
172}
173
174//=======================================================================
175//function : InitMovieCreation
176//purpose :
177//=======================================================================
178
179HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
180 int nFrameHeight,
181 int nBitsPerPixel)
182{
183 int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
184 nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
185
186 myhAviDC = CreateCompatibleDC(NULL);
187 if(myhAviDC==NULL)
188 {
189 SetErrorMessage("Unable to Create Compatible DC");
190 return E_FAIL;
191 }
192
193 if (nFrameWidth > nMaxWidth)
194 nMaxWidth= nFrameWidth;
195 if (nFrameHeight > nMaxHeight)
196 nMaxHeight = nFrameHeight;
197
198 myhHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
199 if(myhHeap==NULL)
200 {
201 SetErrorMessage("Unable to Create Heap");
202 return E_FAIL;
203 }
204
205 mylpBits=HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
206 nMaxWidth*nMaxHeight*4);
207 if(mylpBits==NULL)
208 {
209 SetErrorMessage("Unable to Allocate Memory on Heap");
210 return E_FAIL;
211 }
212
213 HRESULT hr;
214 hr = ::AVIFileOpen(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
215 if (!hr == AVIERR_OK)
216 {
217 SetErrorMessage("Unable to Create the Movie File");
218 return E_FAIL;
219 }
220 /*
221 if(FAILED(::AVIFileOpen(&mypAviFile, myszFileName, OF_CREATE|OF_WRITE, NULL)))
222 {
223 SetErrorMessage("Unable to Create the Movie File");
224 return E_FAIL;
225 }
226 */
227
228 myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
229 SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
230 strncpy(myAviStreamInfo.szName, "Video Stream", 64);
231
232 if(FAILED(AVIFileCreateStream(mypAviFile,&mypAviStream,&myAviStreamInfo)))
233 {
234 SetErrorMessage("Unable to Create Video Stream in the Movie File");
235 return E_FAIL;
236 }
237
238 if(FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
239 mypAviStream,
240 &myAviCompressOptions,
241 NULL)))
242 {
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");
248 return E_FAIL;
249 }
250
251 BITMAPINFO bmpInfo;
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;
262
263 if(FAILED(AVIStreamSetFormat(mypAviCompressedStream,
264 0,
265 (LPVOID)&bmpInfo,
266 bmpInfo.bmiHeader.biSize)))
267 {
268 // One reason this error might occur is if your bitmap does not meet
269 // the Codec requirements.
270 // For example,
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");
277 return E_FAIL;
278 }
279
280 return S_OK; // Everything went Fine
281}
282
283//=======================================================================
284//function : AppendFrameFirstTime
285//purpose :
286//=======================================================================
287
288HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap)
289{
290 BITMAP Bitmap;
291 GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
292
293 if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
294 Bitmap.bmHeight,
295 Bitmap.bmBitsPixel)))
296 {
297 myAppendFuncSelector = 2; //Point to the UsualAppend Function
298 return AppendFrameUsual(hBitmap);
299 }
300
301 ReleaseMemory();
302 return E_FAIL;
303}
304
305//=======================================================================
306//function : AppendFrameUsual
307//purpose :
308//=======================================================================
309
310HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
311{
312 BITMAPINFO bmpInfo;
313
314 bmpInfo.bmiHeader.biBitCount=0;
315 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
316
317 GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
318
319 bmpInfo.bmiHeader.biCompression=BI_RGB;
320
321 GetDIBits(myhAviDC,
322 hBitmap,
323 0,
324 bmpInfo.bmiHeader.biHeight,
325 mylpBits,
326 &bmpInfo,
327 DIB_RGB_COLORS);
328
329 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
330 mylSample++,
331 1,
332 mylpBits,
333 bmpInfo.bmiHeader.biSizeImage,
334 0,
335 NULL,
336 NULL)))
337 {
338 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
339 ReleaseMemory();
340 return E_FAIL;
341 }
342
343 return S_OK;
344}
345
346//=======================================================================
347//function : AppendDummy
348//purpose :
349//=======================================================================
350
351HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
352{
353 return E_FAIL;
354}
355
356//=======================================================================
357//function : AppendNewFrame
358//purpose :
359//=======================================================================
360
361HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
362{
363 return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
364}
365
366//=======================================================================
367//function : AppendNewFrame
368//purpose :
369//=======================================================================
370
371HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
372 int nHeight,
373 LPVOID pBits,
374 int nBitsPerPixel)
375{
376 return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
377 nHeight,
378 pBits,
379 nBitsPerPixel);
380}
381
382//=======================================================================
383//function : AppendFrameFirstTime
384//purpose :
385//=======================================================================
386
387HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
388 int nHeight,
389 LPVOID pBits,
390 int nBitsPerPixel)
391{
392 if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
393 {
394 myAppendFuncSelector=2; //Point to the UsualAppend Function
395 return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
396 }
397 ReleaseMemory();
398
399 return E_FAIL;
400}
401
402//=======================================================================
403//function : AppendFrameUsual
404//purpose :
405//=======================================================================
406
407HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
408 int nHeight,
409 LPVOID pBits,
410 int nBitsPerPixel)
411{
412 DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
413
414 if(FAILED(AVIStreamWrite(mypAviCompressedStream,
415 mylSample++,
416 1,
417 pBits,
418 dwSize,
419 0,
420 NULL,
421 NULL)))
422 {
423 SetErrorMessage("Unable to Write Video Stream to the output Movie File");
424 ReleaseMemory();
425 return E_FAIL;
426 }
427
428 return S_OK;
429}
430
431//=======================================================================
432//function : AppendDummy
433//purpose :
434//=======================================================================
435
436HRESULT OpenGl_AVIWriter::AppendDummyBits(int nWidth,
437 int nHeight,
438 LPVOID pBits,
439 int nBitsPerPixel)
440{
441 return E_FAIL;
442}
443
444//=======================================================================
445//function : AviWriter
446//purpose :
447//=======================================================================
448
449void OpenGl_AVIWriter_AVIWriter(void * pp,
450 int nWidth,
451 int nHeight,
452 int nBitsPerPixel)
453{
454 if (OpenGl_AVIWriter::GetInstance() != 0L)
455 if (OpenGl_AVIWriter::GetInstance()->IsRecording())
456 {
457
458 OpenGl_AVIWriter::GetInstance()->AppendNewFrame(nWidth,
459 nHeight,
460 pp,
461 nBitsPerPixel);
462 }
463}
464
465//=======================================================================
466//function : AllowWriting
467//purpose :
468//=======================================================================
469
470Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
471{
472 Standard_Boolean aResult(Standard_False);
473 const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
474 if (anInst != 0L) {
475 if (hWin == NULL || anInst->HWindow() == hWin)
476 aResult = static_cast<Standard_Boolean> (anInst->IsRecording());
477 }
478 return aResult;
479}
480
16fa0dfb 481#endif