2 * Unit test suite for AVI Functions
4 * Copyright 2008 Detlef Riekenberg
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 /* ########################### */
33 static const CHAR winetest0
[] = "winetest0";
34 static const CHAR winetest1
[] = "winetest1";
35 static const CHAR testfilename
[] = "wine_avifil32_test.avi";
37 /* ########################### */
39 static const DWORD deffh
[] = /* file_header */
41 FOURCC_RIFF
, 0x34c6 /* length */, formtypeAVI
,
42 FOURCC_LIST
, 0x1ac /* length */,
43 listtypeAVIHEADER
, ckidAVIMAINHDR
, sizeof(MainAVIHeader
),
46 static const MainAVIHeader defmah
=
48 0x00008256, /* dwMicroSecPerFrame */
49 0x000080e8, /* dwMaxBytesPerSec */
50 0x00000000, /* dwPaddingGranularity */
51 0x00000910, /* dwFlags */
52 1, /* dwTotalFrames */
53 0, /* dwInitialFrames */
55 0x00100000, /* dwSuggestedBufferSize*/
58 { 0, 0, 0, 0 } /* dwReserved[4] */
61 static const AVIStreamHeader defash0
=
63 streamtypeVIDEO
, /* fccType */
64 0x30323449, /* fccHandler */
65 0x00000000, /* dwFlags */
68 0, /* dwInitialFrames */
69 0x000003e9, /* dwScale */
70 0x00007530, /* dwRate */
73 0x00100000, /* dwSuggestedBufferSize*/
74 0xffffffff, /* dwQuality */
76 { 0, 0, 0, 0 } /* short left right top bottom */
79 static const AVIStreamHeader defash1
=
82 streamtypeAUDIO
, /* fccType */
87 0, /* dwInitialFrames */
89 0x00002b11, /* dwRate */
91 0x00000665, /* dwLength */
92 0x00003000, /* dwSuggestedBufferSize*/
93 0xffffffff, /* dwQuality */
95 { 0, 0, 0, 0 } /* short left right top bottom */
98 static const PCMWAVEFORMAT defpcmwf
=
103 11025, /* nSamplesPerSec */
104 22050, /* nAvgBytesPerSec */
107 8, /* wBitsPerSample */
110 typedef struct common_avi_headers
{
111 DWORD fh
[sizeof(deffh
)];
113 AVIStreamHeader ash0
;
114 AVIStreamHeader ash1
;
116 } COMMON_AVI_HEADERS
;
118 /* Extra data needed to get the VFW API to load the file */
120 /* MainAVIHeader mah */
121 static const DWORD streamlist
[] =
123 FOURCC_LIST
, 0xd4 /* length */,
124 listtypeSTREAMHEADER
, ckidSTREAMHEADER
, 0x38 /* length */,
126 /* AVIStreamHeader ash0 */
127 static const DWORD videostreamformat
[] =
129 ckidSTREAMFORMAT
, 0x28 /* length */,
130 0x00000028, 0x00000008, 0x00000006, 0x00180001,
131 0x30323449, 0x00000090, 0x00000000, 0x00000000,
132 0x00000000, 0x00000000,
134 static const DWORD padding1
[] =
136 ckidAVIPADDING
, 0xc /* length */,
137 0x00000004, 0x00000000, 0x63643030
139 static const DWORD videopropheader
[] =
141 0x70727076, 0x44 /* length */,
142 0x00000000, 0x00000000,
143 0x0000001e, 0x00000008, 0x00000006, 0x00100009,
144 0x00000008, 0x00000006, 0x00000001, 0x00000006,
145 0x00000008, 0x00000006, 0x00000008, 0x00000000,
146 0x00000000, 0x00000000, 0x00000000,
147 FOURCC_LIST
, 0x70 /* length */,
148 listtypeSTREAMHEADER
, ckidSTREAMHEADER
, 0x38 /* length */,
150 /* AVIStreamHeader ash1 */
151 static const DWORD audiostreamformat_pre
[] =
153 ckidSTREAMFORMAT
, sizeof(PCMWAVEFORMAT
) /* length */,
155 /* PCMWAVEFORMAT pcmwf */
156 static DWORD data
[] =
158 ckidAVIPADDING
, 0xc /* length */,
159 0x00000004, 0x00000000, 0x62773130,
160 ckidAVIPADDING
, 0xc /* length */,
161 0x6c6d646f, 0x686c6d64, 0x000000f8,
162 FOURCC_LIST
, 0x18 /* length */,
164 0x54465349, 0xc /* length */,
165 0x6676614c, 0x332e3235, 0x00302e37,
166 ckidAVIPADDING
, 0x4 /* length */,
168 FOURCC_LIST
, 0xd1b /* length */, listtypeAVIMOVIE
,
172 /* ########################### */
174 static void test_AVISaveOptions(void)
176 AVICOMPRESSOPTIONS options
[2];
177 LPAVICOMPRESSOPTIONS poptions
[2];
178 PAVISTREAM streams
[2] = {NULL
, NULL
};
183 poptions
[0] = &options
[0];
184 poptions
[1] = &options
[1];
185 ZeroMemory(options
, sizeof(options
));
187 SetLastError(0xdeadbeef);
188 hres
= CreateEditableStream(&streams
[0], NULL
);
189 ok(hres
== AVIERR_OK
, "0: got 0x%x and %p (expected AVIERR_OK)\n", hres
, streams
[0]);
191 SetLastError(0xdeadbeef);
192 hres
= CreateEditableStream(&streams
[1], NULL
);
193 ok(hres
== AVIERR_OK
, "1: got 0x%x and %p (expected AVIERR_OK)\n", hres
, streams
[1]);
195 SetLastError(0xdeadbeef);
196 hres
= EditStreamSetNameA(streams
[0], winetest0
);
197 todo_wine
ok(hres
== AVIERR_OK
, "0: got 0x%x (expected AVIERR_OK)\n", hres
);
199 SetLastError(0xdeadbeef);
200 hres
= EditStreamSetNameA(streams
[1], winetest1
);
201 todo_wine
ok(hres
== AVIERR_OK
, "1: got 0x%x (expected AVIERR_OK)\n", hres
);
203 if (winetest_interactive
) {
204 SetLastError(0xdeadbeef);
205 res
= AVISaveOptions(0, ICMF_CHOOSE_DATARATE
|ICMF_CHOOSE_KEYFRAME
| ICMF_CHOOSE_ALLCOMPRESSORS
,
206 2, streams
, poptions
);
207 trace("got %u with 0x%x/%u\n", res
, GetLastError(), GetLastError());
210 SetLastError(0xdeadbeef);
211 lres
= AVISaveOptionsFree(2, poptions
);
212 ok(lres
== AVIERR_OK
, "got 0x%x with 0x%x/%u\n", lres
, GetLastError(), GetLastError());
214 SetLastError(0xdeadbeef);
215 res
= AVIStreamRelease(streams
[0]);
216 ok(res
== 0, "0: got refcount %u (expected 0)\n", res
);
218 SetLastError(0xdeadbeef);
219 res
= AVIStreamRelease(streams
[1]);
220 ok(res
== 0, "1: got refcount %u (expected 0)\n", res
);
224 /* ########################### */
226 static void init_test_struct(COMMON_AVI_HEADERS
*cah
)
228 memcpy(cah
->fh
, deffh
, sizeof(deffh
));
232 cah
->pcmwf
= defpcmwf
;
235 static void create_avi_file(const COMMON_AVI_HEADERS
*cah
, char *filename
)
240 hFile
= CreateFile(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
242 ok(hFile
!= INVALID_HANDLE_VALUE
, "Couldn't create file\n");
244 WriteFile(hFile
, &cah
->fh
, sizeof(deffh
), &written
, NULL
);
245 WriteFile(hFile
, &cah
->mah
, sizeof(MainAVIHeader
), &written
, NULL
);
246 WriteFile(hFile
, streamlist
, sizeof(streamlist
), &written
, NULL
);
247 WriteFile(hFile
, &cah
->ash0
, 0x38, &written
, NULL
);
248 WriteFile(hFile
, videostreamformat
, sizeof(videostreamformat
), &written
, NULL
);
249 WriteFile(hFile
, padding1
, sizeof(padding1
), &written
, NULL
);
250 WriteFile(hFile
, videopropheader
, sizeof(videopropheader
), &written
, NULL
);
251 WriteFile(hFile
, &cah
->ash1
, 0x38, &written
, NULL
);
252 WriteFile(hFile
, audiostreamformat_pre
, sizeof(audiostreamformat_pre
), &written
, NULL
);
253 WriteFile(hFile
, &cah
->pcmwf
, sizeof(PCMWAVEFORMAT
), &written
, NULL
);
254 WriteFile(hFile
, data
, sizeof(data
), &written
, NULL
);
259 static void test_default_data(void)
261 COMMON_AVI_HEADERS cah
;
262 char filename
[MAX_PATH
];
272 GetTempPath(MAX_PATH
, filename
);
273 strcpy(filename
+strlen(filename
), testfilename
);
275 init_test_struct(&cah
);
276 create_avi_file(&cah
, filename
);
278 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
279 ok(res
!= AVIERR_BADFORMAT
, "Unable to open file: error1=%u\n", AVIERR_BADFORMAT
);
280 ok(res
!= AVIERR_MEMORY
, "Unable to open file: error2=%u\n", AVIERR_MEMORY
);
281 ok(res
!= AVIERR_FILEREAD
, "Unable to open file: error3=%u\n", AVIERR_FILEREAD
);
282 ok(res
!= AVIERR_FILEOPEN
, "Unable to open file: error4=%u\n", AVIERR_FILEOPEN
);
283 ok(res
!= REGDB_E_CLASSNOTREG
, "Unable to open file: error5=%u\n", REGDB_E_CLASSNOTREG
);
284 ok(res
== 0, "Unable to open file: error=%u\n", res
);
286 res
= AVIFileGetStream(pFile
, &pStream0
, 0, 0);
287 ok(res
== 0, "Unable to open video stream: error=%u\n", res
);
289 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
290 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
292 res
= AVIStreamInfo(pStream0
, &asi0
, sizeof(AVISTREAMINFO
));
293 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
295 res
= AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
));
296 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
298 res
= AVIStreamReadFormat(pStream0
, AVIStreamStart(pStream1
), NULL
, &lSize
);
299 ok(res
== 0, "Unable to read format size: error=%u\n", res
);
301 res
= AVIStreamReadFormat(pStream1
, AVIStreamStart(pStream1
), &wfx
, &lSize
);
302 ok(res
== 0, "Unable to read format: error=%u\n", res
);
304 ok(asi0
.fccType
== streamtypeVIDEO
, "got 0x%x (expected streamtypeVIDEO)\n", asi0
.fccType
);
305 ok(asi0
.fccHandler
== 0x30323449, "got 0x%x (expected 0x30323449)\n", asi0
.fccHandler
);
306 ok(asi0
.dwFlags
== 0, "got %u (expected 0)\n", asi0
.dwFlags
);
307 ok(asi0
.wPriority
== 0, "got %u (expected 0)\n", asi0
.wPriority
);
308 ok(asi0
.wLanguage
== 0, "got %u (expected 0)\n", asi0
.wLanguage
);
309 ok(asi0
.dwScale
== 1001, "got %u (expected 1001)\n", asi0
.dwScale
);
310 ok(asi0
.dwRate
== 30000, "got %u (expected 30000)\n", asi0
.dwRate
);
311 ok(asi0
.dwStart
== 0, "got %u (expected 0)\n", asi0
.dwStart
);
312 ok(asi0
.dwLength
== 1, "got %u (expected 1)\n", asi0
.dwLength
);
313 ok(asi0
.dwInitialFrames
== 0, "got %u (expected 0)\n", asi0
.dwInitialFrames
);
314 ok(asi0
.dwSuggestedBufferSize
== 0, "got %u (expected 0)\n", asi0
.dwSuggestedBufferSize
);
315 ok(asi0
.dwQuality
== 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi0
.dwQuality
);
316 ok(asi0
.dwSampleSize
== 0, "got %u (expected 0)\n", asi0
.dwSampleSize
);
317 ok(asi0
.rcFrame
.left
== 0, "got %u (expected 0)\n", asi0
.rcFrame
.left
);
318 ok(asi0
.rcFrame
.top
== 0, "got %u (expected 0)\n", asi0
.rcFrame
.top
);
319 ok(asi0
.rcFrame
.right
== 8, "got %u (expected 8)\n", asi0
.rcFrame
.right
); /* these are based on the values in the mah and not */
320 ok(asi0
.rcFrame
.bottom
== 6, "got %u (expected 6)\n", asi0
.rcFrame
.bottom
);/* on the ones in the ash which are 0 here */
321 ok(asi0
.dwEditCount
== 0, "got %u (expected 0)\n", asi0
.dwEditCount
);
322 ok(asi0
.dwFormatChangeCount
== 0, "got %u (expected 0)\n", asi0
.dwFormatChangeCount
);
324 ok(asi1
.fccType
== streamtypeAUDIO
, "got 0x%x (expected streamtypeVIDEO)\n", asi1
.fccType
);
325 ok(asi1
.fccHandler
== 0x1, "got 0x%x (expected 0x1)\n", asi1
.fccHandler
);
326 ok(asi1
.dwFlags
== 0, "got %u (expected 0)\n", asi1
.dwFlags
);
327 ok(asi1
.wPriority
== 0, "got %u (expected 0)\n", asi1
.wPriority
);
328 ok(asi1
.wLanguage
== 0, "got %u (expected 0)\n", asi1
.wLanguage
);
329 ok(asi1
.dwScale
== 1, "got %u (expected 1)\n", asi1
.dwScale
);
330 ok(asi1
.dwRate
== 11025, "got %u (expected 11025)\n", asi1
.dwRate
);
331 ok(asi1
.dwStart
== 0, "got %u (expected 0)\n", asi1
.dwStart
);
332 ok(asi1
.dwLength
== 1637, "got %u (expected 1637)\n", asi1
.dwLength
);
333 ok(asi1
.dwInitialFrames
== 0, "got %u (expected 0)\n", asi1
.dwInitialFrames
);
334 ok(asi1
.dwSuggestedBufferSize
== 0, "got %u (expected 0)\n", asi1
.dwSuggestedBufferSize
);
335 ok(asi1
.dwQuality
== 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi1
.dwQuality
);
336 ok(asi1
.dwSampleSize
== 2, "got %u (expected 2)\n", asi1
.dwSampleSize
);
337 ok(asi1
.rcFrame
.left
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.left
);
338 ok(asi1
.rcFrame
.top
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.top
);
339 ok(asi1
.rcFrame
.right
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.right
);
340 ok(asi1
.rcFrame
.bottom
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.bottom
);
341 ok(asi1
.dwEditCount
== 0, "got %u (expected 0)\n", asi1
.dwEditCount
);
342 ok(asi1
.dwFormatChangeCount
== 0, "got %u (expected 0)\n", asi1
.dwFormatChangeCount
);
344 ok(wfx
.wFormatTag
== 1, "got %u (expected 1)\n",wfx
.wFormatTag
);
345 ok(wfx
.nChannels
== 2, "got %u (expected 2)\n",wfx
.nChannels
);
346 ok(wfx
.wFormatTag
== 1, "got %u (expected 1)\n",wfx
.wFormatTag
);
347 ok(wfx
.nSamplesPerSec
== 11025, "got %u (expected 11025)\n",wfx
.nSamplesPerSec
);
348 ok(wfx
.nAvgBytesPerSec
== 22050, "got %u (expected 22050)\n",wfx
.nAvgBytesPerSec
);
349 ok(wfx
.nBlockAlign
== 2, "got %u (expected 2)\n",wfx
.nBlockAlign
);
351 AVIStreamRelease(pStream0
);
352 AVIStreamRelease(pStream1
);
353 AVIFileRelease(pFile
);
354 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
357 static void test_amh_corruption(void)
359 COMMON_AVI_HEADERS cah
;
360 char filename
[MAX_PATH
];
364 GetTempPath(MAX_PATH
, filename
);
365 strcpy(filename
+strlen(filename
), testfilename
);
367 /* Make sure only AVI files with the proper headers will be loaded */
368 init_test_struct(&cah
);
369 cah
.fh
[3] = mmioFOURCC('A', 'V', 'i', ' ');
371 create_avi_file(&cah
, filename
);
372 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
373 ok(res
!= 0, "Able to open file: error=%u\n", res
);
375 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
378 static void test_ash1_corruption(void)
380 COMMON_AVI_HEADERS cah
;
381 char filename
[MAX_PATH
];
387 GetTempPath(MAX_PATH
, filename
);
388 strcpy(filename
+strlen(filename
), testfilename
);
390 /* Corrupt the sample size in the audio stream header */
391 init_test_struct(&cah
);
392 cah
.ash1
.dwSampleSize
= 0xdeadbeef;
394 create_avi_file(&cah
, filename
);
396 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
397 ok(res
== 0, "Unable to open file: error=%u\n", res
);
399 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
400 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
402 res
= AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
));
403 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
405 /* The result will still be 2, because the value is dynamically replaced with the nBlockAlign
406 value from the stream format header. The next test will prove this */
407 ok(asi1
.dwSampleSize
== 2, "got %u (expected 2)\n", asi1
.dwSampleSize
);
409 AVIStreamRelease(pStream1
);
410 AVIFileRelease(pFile
);
411 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
414 static void test_ash1_corruption2(void)
416 COMMON_AVI_HEADERS cah
;
417 char filename
[MAX_PATH
];
423 GetTempPath(MAX_PATH
, filename
);
424 strcpy(filename
+strlen(filename
), testfilename
);
426 /* Corrupt the block alignment in the audio format header */
427 init_test_struct(&cah
);
428 cah
.pcmwf
.wf
.nBlockAlign
= 0xdead;
430 create_avi_file(&cah
, filename
);
432 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
433 ok(res
== 0, "Unable to open file: error=%u\n", res
);
435 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
436 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
438 ok(AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
)) == 0, "Unable to read stream info\n");
440 /* The result will also be the corrupt value, as explained above. */
441 ok(asi1
.dwSampleSize
== 0xdead, "got 0x%x (expected 0xdead)\n", asi1
.dwSampleSize
);
443 AVIStreamRelease(pStream1
);
444 AVIFileRelease(pFile
);
445 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
448 /* ########################### */
454 test_AVISaveOptions();
456 test_amh_corruption();
457 test_ash1_corruption();
458 test_ash1_corruption2();