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