1 #include "stdafx.h"
2
3 #include "AVIWrite.h"
4 #pragma comment( lib, "Vfw32" )
5
6
AVIWrite()7 AVIWrite::AVIWrite()
8 {
9 m_failed = false;
10 m_file = NULL;
11 m_videoStream = NULL;
12 m_audioStream = NULL;
13 ZeroMemory( &m_videoCompSettings, sizeof( m_videoCompSettings ) );
14 ZeroMemory( &m_audioCompSettings, sizeof( m_audioCompSettings ) );
15 m_videoCompressed = NULL;
16 m_audioCompressed = NULL;
17 m_frameRate = 0;
18 m_frameCounter = 0;
19 m_sampleCounter = 0;
20 m_videoFrameSize = 0;
21 m_audioFrameSize = 0;
22 m_audioBlockAlign = 0;
23
24 AVIFileInit();
25 }
26
27
~AVIWrite()28 AVIWrite::~AVIWrite()
29 {
30 if( m_audioCompressed ) {
31 AVIStreamRelease( m_audioCompressed );
32 }
33
34 if( m_audioStream ) {
35 AVIStreamRelease( m_audioStream );
36 }
37
38 if( m_videoCompressed ) {
39 AVIStreamRelease( m_videoCompressed );
40 }
41
42 if( m_videoStream ) {
43 AVIStreamRelease( m_videoStream );
44 }
45
46 if( m_file ) {
47 AVIFileRelease( m_file );
48 }
49
50 AVIFileExit();
51 }
52
53
CreateAVIFile(LPCTSTR filename)54 bool AVIWrite::CreateAVIFile( LPCTSTR filename )
55 {
56 if( m_file || m_failed ) return false;
57
58 HRESULT err = 0;
59
60 // -- create the AVI file --
61 err = AVIFileOpen(
62 &m_file,
63 filename,
64 OF_CREATE | OF_WRITE | OF_SHARE_EXCLUSIVE,
65 NULL
66 );
67
68 if( FAILED( err ) ) {
69 m_failed = true;
70 return false;
71 }
72
73 return true;
74 }
75
76
77 // colorBits: 16, 24 or 32
CreateVideoStream(LONG imageWidth,LONG imageHeight,WORD colorBits,DWORD framesPerSecond,HWND parentWnd)78 bool AVIWrite::CreateVideoStream( LONG imageWidth, LONG imageHeight, WORD colorBits, DWORD framesPerSecond, HWND parentWnd )
79 {
80 if( m_videoStream || m_failed ) return false;
81
82 HRESULT err = 0;
83 AVISTREAMINFO videoInfo;
84 BITMAPINFOHEADER bitmapInfo;
85 AVICOMPRESSOPTIONS *settings[1];
86 ZeroMemory( &videoInfo, sizeof( videoInfo ) );
87 ZeroMemory( &bitmapInfo, sizeof( bitmapInfo ) );
88 settings[0] = &m_videoCompSettings;
89
90 // -- initialize the video stream information --
91 videoInfo.fccType = streamtypeVIDEO;
92 videoInfo.fccHandler = 0;
93 videoInfo.dwScale = 1;
94 videoInfo.dwRate = framesPerSecond;
95 videoInfo.dwSuggestedBufferSize = imageWidth * imageHeight * ( colorBits >> 3 );
96
97 // -- create the video stream --
98 err = AVIFileCreateStream(
99 m_file,
100 &m_videoStream,
101 &videoInfo
102 );
103
104 if( FAILED( err ) ) {
105 m_failed = true;
106 return false;
107 }
108
109
110 // -- ask for compression settings --
111 if( AVISaveOptions(
112 parentWnd,
113 0,
114 1,
115 &m_videoStream,
116 settings ) )
117 {
118 err = AVIMakeCompressedStream(
119 &m_videoCompressed,
120 m_videoStream,
121 settings[0],
122 NULL
123 );
124
125 AVISaveOptionsFree( 1, settings );
126 if( FAILED( err ) ) {
127 m_failed = true;
128 return false;
129 }
130 } else {
131 AVISaveOptionsFree( 1, settings );
132 m_failed = true;
133 return false;
134 }
135
136
137 // -- initialize the video stream format --
138 bitmapInfo.biSize = sizeof( bitmapInfo );
139 bitmapInfo.biWidth = imageWidth;
140 bitmapInfo.biHeight = imageHeight;
141 bitmapInfo.biBitCount = colorBits;
142 bitmapInfo.biPlanes = 1;
143 bitmapInfo.biCompression = BI_RGB;
144 bitmapInfo.biSizeImage = imageWidth * imageHeight * ( colorBits >> 3 );
145
146 // -- set the video stream format --
147 err = AVIStreamSetFormat(
148 m_videoCompressed,
149 0,
150 &bitmapInfo,
151 bitmapInfo.biSize + ( bitmapInfo.biClrUsed * sizeof( RGBQUAD ) )
152 );
153
154 if( FAILED( err ) ) {
155 m_failed = true;
156 return false;
157 }
158
159
160 m_frameRate = framesPerSecond;
161 m_videoFrameSize = imageWidth * imageHeight * ( colorBits >> 3 );
162
163 return true;
164 }
165
166
167 // call AddVideoStream() first
168 // channelCount: max. 2
169 // sampleBits: max. 16
CreateAudioStream(WORD channelCount,DWORD sampleRate,WORD sampleBits,HWND parentWnd)170 bool AVIWrite::CreateAudioStream( WORD channelCount, DWORD sampleRate, WORD sampleBits, HWND parentWnd )
171 {
172 if( m_audioStream || m_failed ) return false;
173
174 HRESULT err = 0;
175 AVISTREAMINFO audioInfo;
176 WAVEFORMATEX waveInfo;
177 ZeroMemory( &audioInfo, sizeof( audioInfo ) );
178 ZeroMemory( &waveInfo, sizeof( waveInfo ) );
179
180 // -- initialize the audio stream information --
181 audioInfo.fccType = streamtypeAUDIO;
182 audioInfo.dwQuality = (DWORD)-1;
183 audioInfo.dwScale = channelCount * ( sampleBits >> 3 );
184 audioInfo.dwRate = channelCount * ( sampleBits >> 3 ) * sampleRate;
185 audioInfo.dwInitialFrames = 1;
186 audioInfo.dwSampleSize = channelCount * ( sampleBits >> 3 );
187 audioInfo.dwSuggestedBufferSize = 0;
188
189 // -- create the audio stream --
190 err = AVIFileCreateStream(
191 m_file,
192 &m_audioStream,
193 &audioInfo
194 );
195
196 if( FAILED( err ) ) {
197 m_failed = true;
198 return false;
199 }
200
201
202 // -- initialize the audio stream format --
203 waveInfo.wFormatTag = WAVE_FORMAT_PCM;
204 waveInfo.nChannels = channelCount;
205 waveInfo.nSamplesPerSec = sampleRate;
206 waveInfo.nAvgBytesPerSec = channelCount * ( sampleBits >> 3 ) * sampleRate;
207 waveInfo.nBlockAlign = channelCount * ( sampleBits >> 3 );
208 waveInfo.wBitsPerSample = sampleBits;
209 waveInfo.cbSize = 0;
210
211 // -- set the audio stream format --
212 err = AVIStreamSetFormat(
213 m_audioStream,
214 0,
215 &waveInfo,
216 sizeof( waveInfo )
217 );
218
219 if( FAILED( err ) ) {
220 m_failed = true;
221 return false;
222 }
223
224 m_audioBlockAlign = channelCount * ( sampleBits >> 3 );
225 m_audioFrameSize = channelCount * ( sampleBits >> 3 ) * ( sampleRate / m_frameRate );
226
227 return true;
228 }
229
230
AddVideoFrame(LPVOID imageData)231 bool AVIWrite::AddVideoFrame( LPVOID imageData )
232 {
233 if( !m_videoStream || m_failed ) return false;
234
235 HRESULT err = 0;
236
237 err = AVIStreamWrite(
238 m_videoCompressed,
239 m_frameCounter,
240 1,
241 imageData,
242 m_videoFrameSize,
243 AVIIF_KEYFRAME,
244 NULL,
245 NULL
246 );
247
248 if( FAILED( err ) ) {
249 m_failed = true;
250 return false;
251 }
252
253 m_frameCounter++;
254
255 return true;
256 }
257
258
AddAudioFrame(LPVOID soundData)259 bool AVIWrite::AddAudioFrame( LPVOID soundData )
260 {
261 if( !m_audioStream || m_failed ) return false;
262
263 HRESULT err = 0;
264
265 err = AVIStreamWrite(
266 m_audioStream,
267 m_sampleCounter,
268 m_audioFrameSize / m_audioBlockAlign,
269 soundData,
270 m_audioFrameSize,
271 0,
272 NULL,
273 NULL
274 );
275
276 if( FAILED( err ) ) {
277 m_failed = true;
278 return false;
279 }
280
281 m_sampleCounter += m_audioFrameSize / m_audioBlockAlign;
282
283 return true;
284 }
285