source: trunk/src/testing/app/wshare/AviFile.cpp @ 4

Revision 4, 11.6 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/******************************************************************************
2 * SAGE - Scalable Adaptive Graphics Environment
3 *
4 * Copyright (C) 2004 Electronic Visualization Laboratory,
5 * University of Illinois at Chicago
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above
15 *    copyright notice, this list of conditions and the following disclaimer
16 *    in the documentation and/or other materials provided with the distribution.
17 *  * Neither the name of the University of Illinois at Chicago nor
18 *    the names of its contributors may be used to endorse or promote
19 *    products derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/
34 *
35 *****************************************************************************/
36
37#include "StdAfx.h"
38#include "avifile.h"
39
40/// FPS defines the Number of Frames per second;
41/// Here we set FPS to 1 meaning one Frame per Second.
42/// Increase it it you need more Frames Per Second.
43#define FPS                     1       // Frames Per Second
44
45/// VIDEOCODEC defines the Codec that need to be used for the Movie.
46/// Change the definition to use a different codec. For example,
47/// Change it to mmioFOURCC('D','I','V','X') to use DIVX codec; or
48/// Change it to mmioFOURCC('I','V','5','0') to use IV50 codec etc..
49/// Also, you can change it to 0 to avoid the codecs altogether. In that case, Frames would be saved as they are;
50/// However, make sure you have the codec installed on the machine before using its Fourcc here.
51#define VIDEOCODEC      mmioFOURCC('M','P','G','4')
52
53//#define VIDEOCODEC    0       /// Frames will be saved as they are - movie size would be HUGE !!
54
55CAviFile::CAviFile(LPCTSTR lpszFileName)
56{
57
58        AVIFileInit();
59
60        _tcscpy(m_szFileName,lpszFileName);
61
62        m_hHeap=NULL;
63        m_hAviDC=NULL;
64        m_lpBits=NULL;
65        m_lSample=NULL;
66        m_pAviFile=NULL;
67        m_pAviStream=NULL;
68        m_pAviCompressedStream=NULL;
69
70        pAppendFrame[0]= &CAviFile::AppendDummy;                        // VC8 requires & for Function Pointer; Remove it if your compiler complains;
71        pAppendFrame[1]= &CAviFile::AppendFrameFirstTime;
72        pAppendFrame[2]= &CAviFile::AppendFrameUsual;
73
74        pAppendFrameBits[0]=&CAviFile::AppendDummy;
75        pAppendFrameBits[1]=&CAviFile::AppendFrameFirstTime;
76        pAppendFrameBits[2]=&CAviFile::AppendFrameUsual;
77
78        nAppendFuncSelector=1;          //0=Dummy       1=FirstTime     2=Usual
79}
80
81CAviFile::~CAviFile(void)
82{
83        ReleaseMemory();
84
85        AVIFileExit();
86}
87
88void CAviFile::ReleaseMemory()
89{
90        nAppendFuncSelector=0;          //Point to DummyFunction
91
92        if(m_hAviDC)
93        {
94                DeleteDC(m_hAviDC);
95                m_hAviDC=NULL;
96        }
97        if(m_pAviCompressedStream)
98        {
99                AVIStreamRelease(m_pAviCompressedStream);
100                m_pAviCompressedStream=NULL;
101        }
102        if(m_pAviStream)
103        {
104                AVIStreamRelease(m_pAviStream);
105                m_pAviStream=NULL;
106        }
107        if(m_pAviFile)
108        {
109                AVIFileRelease(m_pAviFile);
110                m_pAviFile=NULL;
111        }
112        if(m_lpBits)
113        {
114                HeapFree(m_hHeap,HEAP_NO_SERIALIZE,m_lpBits);
115                m_lpBits=NULL;
116        }
117        if(m_hHeap)
118        {
119                HeapDestroy(m_hHeap);
120                m_hHeap=NULL;
121        }
122}
123
124HRESULT CAviFile::AppendFrameFirstTime(HBITMAP  hBitmap)
125{
126        int     nMaxWidth=GetSystemMetrics(SM_CXSCREEN),nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
127
128        BITMAPINFO      bmpInfo;
129
130        m_hAviDC=CreateCompatibleDC(NULL);
131        if(m_hAviDC==NULL)
132        {
133                //MessageBox(NULL,"Unable to Create Compatible DC","Error",MB_OK|MB_ICONERROR);
134                goto TerminateInit;
135        }
136
137        ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
138        bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
139
140        GetDIBits(m_hAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
141
142        bmpInfo.bmiHeader.biCompression=BI_RGB;
143
144        if(bmpInfo.bmiHeader.biHeight>nMaxHeight)       nMaxHeight=bmpInfo.bmiHeader.biHeight;
145        if(bmpInfo.bmiHeader.biWidth>nMaxWidth) nMaxWidth=bmpInfo.bmiHeader.biWidth;
146
147        m_hHeap=HeapCreate(HEAP_NO_SERIALIZE,nMaxWidth*nMaxHeight*4,0);
148        if(m_hHeap==NULL)
149        {
150                //MessageBox(NULL,"Unable to Allocate Memory","Error",MB_OK);
151                goto TerminateInit;
152        }
153
154        m_lpBits=HeapAlloc(m_hHeap,HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,nMaxWidth*nMaxHeight*4);
155        if(m_lpBits==NULL)
156        {
157                //MessageBox(NULL,"Unable to Allocate Memory","Error",MB_OK);
158                goto TerminateInit;
159        }
160
161        if(FAILED(AVIFileOpen(&m_pAviFile,m_szFileName,OF_CREATE|OF_WRITE,NULL)))
162        {
163                //MessageBox(NULL,"Unable to Create the Movie File","Error",MB_OK|MB_ICONERROR);
164                goto TerminateInit;
165        }
166
167        ZeroMemory(&m_AviStreamInfo,sizeof(AVISTREAMINFO));
168        m_AviStreamInfo.fccType=streamtypeVIDEO;
169        m_AviStreamInfo.fccHandler=VIDEOCODEC;
170        m_AviStreamInfo.dwScale=1;
171        m_AviStreamInfo.dwRate=FPS;             //Frames Per Second;
172        m_AviStreamInfo.dwQuality=-1;   //Default Quality
173        m_AviStreamInfo.dwSuggestedBufferSize=nMaxWidth*nMaxHeight*4;
174    SetRect(&m_AviStreamInfo.rcFrame,0,0,bmpInfo.bmiHeader.biWidth,bmpInfo.bmiHeader.biHeight);
175        strcpy(m_AviStreamInfo.szName,"Video Stream");
176
177        if(FAILED(AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo)))
178        {
179                //MessageBox(NULL,"Unable to Create Stream","Error",MB_OK|MB_ICONERROR);
180                goto TerminateInit;
181
182        }
183
184        ZeroMemory(&m_AviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
185        m_AviCompressOptions.fccType=streamtypeVIDEO;
186        m_AviCompressOptions.fccHandler=m_AviStreamInfo.fccHandler;
187        m_AviCompressOptions.dwFlags=AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE;
188        m_AviCompressOptions.dwKeyFrameEvery=15;
189        //m_AviCompressOptions.dwBytesPerSecond=1000/8;
190        //m_AviCompressOptions.dwQuality=100;
191
192        if(FAILED(AVIMakeCompressedStream(&m_pAviCompressedStream,m_pAviStream,&m_AviCompressOptions,NULL)))
193        {
194                //MessageBox(NULL,"Unable to Create Compressed Stream","Error",MB_OK);
195                goto TerminateInit;
196        }
197
198        if(FAILED(AVIStreamSetFormat(m_pAviCompressedStream,0,(LPVOID)&bmpInfo,bmpInfo.bmiHeader.biSize)))
199        {
200                //MessageBox(NULL,"Unable to Set Format","Error",MB_OK);
201                goto TerminateInit;
202        }
203
204        nAppendFuncSelector=2;          //Point to UsualAppend Function
205
206        return AppendFrameUsual(hBitmap);
207
208TerminateInit:
209
210        ReleaseMemory();        MessageBox(NULL,"Error Occured While Rendering the Movie","Error",MB_OK|MB_ICONERROR);
211
212        return E_FAIL;
213}
214
215HRESULT CAviFile::AppendFrameUsual(HBITMAP hBitmap)
216{
217        BITMAPINFO      bmpInfo;
218
219        bmpInfo.bmiHeader.biBitCount=0;
220        bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
221
222        GetDIBits(m_hAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
223
224        bmpInfo.bmiHeader.biCompression=BI_RGB;
225
226        GetDIBits(m_hAviDC,hBitmap,0,bmpInfo.bmiHeader.biHeight,m_lpBits,&bmpInfo,DIB_RGB_COLORS);
227
228        if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,m_lpBits,bmpInfo.bmiHeader.biSizeImage,0,NULL,NULL)))
229                return E_FAIL;
230
231    return S_OK;
232}
233
234HRESULT CAviFile::AppendDummy(HBITMAP)
235{
236        return E_FAIL;
237}
238
239HRESULT CAviFile::AppendNewFrame(HBITMAP hBitmap)
240{
241        return (this->*pAppendFrame[nAppendFuncSelector])((HBITMAP)hBitmap);
242}
243
244HRESULT CAviFile::AppendNewFrame(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
245{
246        return (this->*pAppendFrameBits[nAppendFuncSelector])(nWidth,nHeight,pBits,nBitsPerPixel);
247}
248
249HRESULT CAviFile::AppendFrameFirstTime(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
250{
251        int     nMaxWidth=GetSystemMetrics(SM_CXSCREEN),nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
252
253        BITMAPINFO      bmpInfo;
254
255        m_hAviDC=CreateCompatibleDC(NULL);
256        if(m_hAviDC==NULL)
257        {
258                //MessageBox(NULL,"Unable to Create Compatible DC","Error",MB_OK|MB_ICONERROR);
259                goto TerminateInitBits;
260        }
261
262        ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
263        bmpInfo.bmiHeader.biPlanes=1;
264        bmpInfo.bmiHeader.biWidth=nWidth;
265        bmpInfo.bmiHeader.biHeight=nHeight;
266        bmpInfo.bmiHeader.biCompression=BI_RGB;
267        bmpInfo.bmiHeader.biBitCount=nBitsPerPixel;
268        bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
269        bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*bmpInfo.bmiHeader.biHeight*bmpInfo.bmiHeader.biBitCount/8;
270
271        if(bmpInfo.bmiHeader.biHeight>nMaxHeight)       nMaxHeight=bmpInfo.bmiHeader.biHeight;
272        if(bmpInfo.bmiHeader.biWidth>nMaxWidth) nMaxWidth=bmpInfo.bmiHeader.biWidth;
273
274        m_hHeap=HeapCreate(HEAP_NO_SERIALIZE,nMaxWidth*nMaxHeight*4,0);
275        if(m_hHeap==NULL)
276        {
277                //MessageBox(NULL,"Unable to Allocate Memory","Error",MB_OK);
278                goto TerminateInitBits;
279        }
280
281        m_lpBits=HeapAlloc(m_hHeap,HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,nMaxWidth*nMaxHeight*4);
282        if(m_lpBits==NULL)
283        {
284                //MessageBox(NULL,"Unable to Allocate Memory","Error",MB_OK);
285                goto TerminateInitBits;
286        }
287
288        if(FAILED(AVIFileOpen(&m_pAviFile,m_szFileName,OF_CREATE|OF_WRITE,NULL)))
289        {
290                //MessageBox(NULL,"Unable to Create the Movie File","Error",MB_OK|MB_ICONERROR);
291                goto TerminateInitBits;
292        }
293
294        ZeroMemory(&m_AviStreamInfo,sizeof(AVISTREAMINFO));
295        m_AviStreamInfo.fccType=streamtypeVIDEO;
296        m_AviStreamInfo.fccHandler=VIDEOCODEC;
297        m_AviStreamInfo.dwScale=1;
298        m_AviStreamInfo.dwRate= FPS;    //Frames Per Second;
299        m_AviStreamInfo.dwQuality=-1;   //Default Quality
300        m_AviStreamInfo.dwSuggestedBufferSize=nMaxWidth*nMaxHeight*4;
301    SetRect(&m_AviStreamInfo.rcFrame,0,0,bmpInfo.bmiHeader.biWidth,bmpInfo.bmiHeader.biHeight);
302        strcpy(m_AviStreamInfo.szName,"Video Stream");
303
304        if(FAILED(AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo)))
305        {
306                //MessageBox(NULL,"Unable to Create Stream","Error",MB_OK|MB_ICONERROR);
307                goto TerminateInitBits;
308
309        }
310
311        ZeroMemory(&m_AviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
312        m_AviCompressOptions.fccType=streamtypeVIDEO;
313        m_AviCompressOptions.fccHandler=m_AviStreamInfo.fccHandler;
314        m_AviCompressOptions.dwFlags=AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE;
315        m_AviCompressOptions.dwKeyFrameEvery=15;
316        //m_AviCompressOptions.dwBytesPerSecond=1000/8;
317        //m_AviCompressOptions.dwQuality=100;
318
319        if(FAILED(AVIMakeCompressedStream(&m_pAviCompressedStream,m_pAviStream,&m_AviCompressOptions,NULL)))
320        {
321                //MessageBox(NULL,"Unable to Create Compressed Stream","Error",MB_OK);
322                goto TerminateInitBits;
323        }
324
325        if(FAILED(AVIStreamSetFormat(m_pAviCompressedStream,0,(LPVOID)&bmpInfo,bmpInfo.bmiHeader.biSize)))
326        {
327                //MessageBox(NULL,"Unable to Set Format","Error",MB_OK);
328                goto TerminateInitBits;
329        }
330
331        nAppendFuncSelector=2;          //Point to UsualAppend Function
332
333        return AppendFrameUsual(nWidth,nHeight,pBits,nBitsPerPixel);
334
335TerminateInitBits:
336
337        ReleaseMemory();        MessageBox(NULL,"Error Occured While Rendering the Movie","Error",MB_OK|MB_ICONERROR);
338
339        return E_FAIL;
340
341}
342
343HRESULT CAviFile::AppendFrameUsual(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
344{
345        DWORD   dwSize=nWidth*nHeight*nBitsPerPixel/8;
346
347        if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,pBits,dwSize,0,NULL,NULL)))
348                return E_FAIL;
349
350    return S_OK;
351}
352
353HRESULT CAviFile::AppendDummy(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
354{
355        return E_FAIL;
356}
Note: See TracBrowser for help on using the repository browser.