CFugue
AviFile.cpp
1 #include "StdAfx.h"
2 #include "avifile.h"
3 
4 #pragma comment (lib, "vfw32.lib")
5 
6 #ifndef __countof
7 #define __countof(x) ((sizeof(x)/sizeof(x[0])))
8 #endif
9 
10 CAviFile:: CAviFile(LPCTSTR lpszFileName /* =_T("Output.avi") */,
11  DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */,
12  DWORD dwFrameRate /* = 1 */)
13 {
14 
15  AVIFileInit();
16 
17  m_hHeap=NULL;
18  m_hAviDC=NULL;
19  m_lpBits=NULL;
20  m_lSample=NULL;
21  m_pAviFile=NULL;
22  m_pAviStream=NULL;
23  m_pAviCompressedStream=NULL;
24 
25  m_dwFCCHandler = dwCodec;
26  m_dwFrameRate = dwFrameRate;
27 
28  _tcscpy(m_szFileName, lpszFileName);
29  _tcscpy(m_szErrMsg, _T("Method Succeeded"));
30  m_szErrMsg[__countof(m_szErrMsg)-1] = _T('\0');
31 
32  pAppendFrame[0]= &CAviFile::AppendDummy; // VC8 requires & for Function Pointer; Remove it if your compiler complains;
33  pAppendFrame[1]= &CAviFile::AppendFrameFirstTime;
34  pAppendFrame[2]= &CAviFile::AppendFrameUsual;
35 
36  pAppendFrameBits[0]=&CAviFile::AppendDummy;
37  pAppendFrameBits[1]=&CAviFile::AppendFrameFirstTime;
38  pAppendFrameBits[2]=&CAviFile::AppendFrameUsual;
39 
40  m_nAppendFuncSelector=1; //0=Dummy 1=FirstTime 2=Usual
41 }
42 
44 {
45  ReleaseMemory();
46 
47  AVIFileExit();
48 }
49 
50 void CAviFile::ReleaseMemory()
51 {
52  m_nAppendFuncSelector=0; //Point to DummyFunction
53 
54  if(m_hAviDC)
55  {
56  DeleteDC(m_hAviDC);
57  m_hAviDC=NULL;
58  }
59  if(m_pAviCompressedStream)
60  {
61  AVIStreamRelease(m_pAviCompressedStream);
62  m_pAviCompressedStream=NULL;
63  }
64  if(m_pAviStream)
65  {
66  AVIStreamRelease(m_pAviStream);
67  m_pAviStream=NULL;
68  }
69  if(m_pAviFile)
70  {
71  AVIFileRelease(m_pAviFile);
72  m_pAviFile=NULL;
73  }
74  if(m_lpBits)
75  {
76  HeapFree(m_hHeap,HEAP_NO_SERIALIZE,m_lpBits);
77  m_lpBits=NULL;
78  }
79  if(m_hHeap)
80  {
81  HeapDestroy(m_hHeap);
82  m_hHeap=NULL;
83  }
84 }
85 
86 void CAviFile::SetErrorMessage(LPCTSTR lpszErrorMessage)
87 {
88  _tcsncpy(m_szErrMsg, lpszErrorMessage, __countof(m_szErrMsg)-1);
89 }
90 
91 HRESULT CAviFile::InitMovieCreation(int nFrameWidth, int nFrameHeight, int nBitsPerPixel)
92 {
93  int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
94 
95  m_hAviDC = CreateCompatibleDC(NULL);
96  if(m_hAviDC==NULL)
97  {
98  SetErrorMessage(_T("Unable to Create Compatible DC"));
99  return E_FAIL;
100  }
101 
102  if(nFrameWidth > nMaxWidth) nMaxWidth= nFrameWidth;
103  if(nFrameHeight > nMaxHeight) nMaxHeight = nFrameHeight;
104 
105  m_hHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
106  if(m_hHeap==NULL)
107  {
108  SetErrorMessage(_T("Unable to Create Heap"));
109  return E_FAIL;
110  }
111 
112  m_lpBits=HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4);
113  if(m_lpBits==NULL)
114  {
115  SetErrorMessage(_T("Unable to Allocate Memory on Heap"));
116  return E_FAIL;
117  }
118 
119  if(FAILED(AVIFileOpen(&m_pAviFile, m_szFileName, OF_CREATE|OF_WRITE, NULL)))
120  {
121  SetErrorMessage(_T("Unable to Create the Movie File"));
122  return E_FAIL;
123  }
124 
125  ZeroMemory(&m_AviStreamInfo,sizeof(AVISTREAMINFO));
126  m_AviStreamInfo.fccType = streamtypeVIDEO;
127  m_AviStreamInfo.fccHandler = m_dwFCCHandler;
128  m_AviStreamInfo.dwScale = 1;
129  m_AviStreamInfo.dwRate = m_dwFrameRate; // Frames Per Second;
130  m_AviStreamInfo.dwQuality = -1; // Default Quality
131  m_AviStreamInfo.dwSuggestedBufferSize = nMaxWidth*nMaxHeight*4;
132  SetRect(&m_AviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
133  _tcscpy(m_AviStreamInfo.szName, _T("Video Stream"));
134 
135  if(FAILED(AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo)))
136  {
137  SetErrorMessage(_T("Unable to Create Video Stream in the Movie File"));
138  return E_FAIL;
139  }
140 
141  ZeroMemory(&m_AviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
142  m_AviCompressOptions.fccType=streamtypeVIDEO;
143  m_AviCompressOptions.fccHandler=m_AviStreamInfo.fccHandler;
144  m_AviCompressOptions.dwFlags=AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE;
145  m_AviCompressOptions.dwKeyFrameEvery=1;
146  //m_AviCompressOptions.dwBytesPerSecond=1000/8;
147  //m_AviCompressOptions.dwQuality=100;
148 
149  if(FAILED(AVIMakeCompressedStream(&m_pAviCompressedStream,m_pAviStream,&m_AviCompressOptions,NULL)))
150  {
151  // One reason this error might occur is if you are using a Codec that is not
152  // available on your system. Check the mmioFOURCC() code you are using and make
153  // sure you have that codec installed properly on your machine.
154  SetErrorMessage(_T("Unable to Create Compressed Stream: Check your CODEC options"));
155  return E_FAIL;
156  }
157 
158  BITMAPINFO bmpInfo;
159  ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
160  bmpInfo.bmiHeader.biPlanes = 1;
161  bmpInfo.bmiHeader.biWidth = nFrameWidth;
162  bmpInfo.bmiHeader.biHeight = nFrameHeight;
163  bmpInfo.bmiHeader.biCompression = BI_RGB;
164  bmpInfo.bmiHeader.biBitCount = nBitsPerPixel;
165  bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
166  bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth*bmpInfo.bmiHeader.biHeight*bmpInfo.bmiHeader.biBitCount/8;
167 
168  if(FAILED(AVIStreamSetFormat(m_pAviCompressedStream,0,(LPVOID)&bmpInfo, bmpInfo.bmiHeader.biSize)))
169  {
170  // One reason this error might occur is if your bitmap does not meet the Codec requirements.
171  // For example,
172  // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
173  // your bitmap is 274 * 258 size, while the Codec supports only sizes that are powers of 2; etc...
174  // Possible solution to avoid this is: make your bitmap suit the codec requirements,
175  // or Choose a codec that is suitable for your bitmap.
176  SetErrorMessage(_T("Unable to Set Video Stream Format"));
177  return E_FAIL;
178  }
179 
180  return S_OK; // Everything went Fine
181 }
182 
183 
184 HRESULT CAviFile::AppendFrameFirstTime(HBITMAP hBitmap)
185 {
186  BITMAP Bitmap;
187 
188  GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
189 
190  if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth,
191  Bitmap.bmHeight,
192  Bitmap.bmBitsPixel)))
193  {
194  m_nAppendFuncSelector=2; //Point to the UsualAppend Function
195 
196  return AppendFrameUsual(hBitmap);
197  }
198 
199  ReleaseMemory();
200 
201  return E_FAIL;
202 }
203 
204 HRESULT CAviFile::AppendFrameUsual(HBITMAP hBitmap)
205 {
206  BITMAPINFO bmpInfo;
207 
208  bmpInfo.bmiHeader.biBitCount=0;
209  bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
210 
211  GetDIBits(m_hAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
212 
213  bmpInfo.bmiHeader.biCompression=BI_RGB;
214 
215  GetDIBits(m_hAviDC,hBitmap,0,bmpInfo.bmiHeader.biHeight,m_lpBits,&bmpInfo,DIB_RGB_COLORS);
216 
217  if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,m_lpBits,bmpInfo.bmiHeader.biSizeImage,0,NULL,NULL)))
218  {
219  SetErrorMessage(_T("Unable to Write Video Stream to the output Movie File"));
220 
221  ReleaseMemory();
222 
223  return E_FAIL;
224  }
225 
226  return S_OK;
227 }
228 
229 HRESULT CAviFile::AppendDummy(HBITMAP)
230 {
231  return E_FAIL;
232 }
233 
234 HRESULT CAviFile::AppendNewFrame(HBITMAP hBitmap)
235 {
236  return (this->*pAppendFrame[m_nAppendFuncSelector])((HBITMAP)hBitmap);
237 }
238 
239 HRESULT CAviFile::AppendNewFrame(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
240 {
241  return (this->*pAppendFrameBits[m_nAppendFuncSelector])(nWidth,nHeight,pBits,nBitsPerPixel);
242 }
243 
244 HRESULT CAviFile::AppendFrameFirstTime(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
245 {
246  if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
247  {
248  m_nAppendFuncSelector=2; //Point to the UsualAppend Function
249 
250  return AppendFrameUsual(nWidth, nHeight, pBits, nBitsPerPixel);
251  }
252 
253  ReleaseMemory();
254 
255  return E_FAIL;
256 }
257 
258 HRESULT CAviFile::AppendFrameUsual(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
259 {
260  DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
261 
262  if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,pBits,dwSize,0,NULL,NULL)))
263  {
264  SetErrorMessage(_T("Unable to Write Video Stream to the output Movie File"));
265 
266  ReleaseMemory();
267 
268  return E_FAIL;
269  }
270 
271  return S_OK;
272 }
273 
274 HRESULT CAviFile::AppendDummy(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel)
275 {
276  return E_FAIL;
277 }
HRESULT AppendNewFrame(HBITMAP hBitmap)
Definition: AviFile.cpp:234
CAviFile(LPCTSTR lpszFileName=_T("Output.avi"), DWORD dwCodec=mmioFOURCC('M','P','G','4'), DWORD dwFrameRate=1)
Definition: AviFile.cpp:10
~CAviFile(void)
Definition: AviFile.cpp:43

CFugue, the C++ Music Programming Library © Copyright 2009 Cenacle Research India Private Limited Gopalakrishna Palem