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