2 * Unit tests for the avi splitter functions
4 * Copyright (C) 2007 Google (Lei Zhang)
5 * Copyright (C) 2008 Google (Maarten Lankhorst)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
28 static IUnknown
*pAviSplitter
= NULL
;
30 static BOOL
create_avisplitter(void)
34 hr
= CoCreateInstance(&CLSID_AviSplitter
, NULL
, CLSCTX_INPROC_SERVER
,
35 &IID_IUnknown
, (LPVOID
*)&pAviSplitter
);
36 return (hr
== S_OK
&& pAviSplitter
!= NULL
);
39 static void release_avisplitter(void)
44 hr
= IUnknown_Release(pAviSplitter
);
46 /* Looks like wine has a reference leak somewhere on test_threads tests,
47 * it passes in windows
49 ok(hr
== 0, "IUnknown_Release failed with %d\n", (INT
)hr
);
52 hr
= IUnknown_Release(pAviSplitter
);
56 static void test_query_interface(void)
60 IUnknown
*iface
= NULL
;
62 #define TEST_INTERFACE(riid,expected) do { \
63 hr = IUnknown_QueryInterface(pAviSplitter, &riid, (void**)&iface); \
64 ok( hr == expected, #riid" should %s got %08X\n", expected==S_OK ? "exist" : "not be present", GetLastError() ); \
66 ref = IUnknown_Release(iface); \
67 ok(ref == 1, "Reference is %u, expected 1\n", ref); \
72 TEST_INTERFACE(IID_IBaseFilter
,S_OK
);
73 TEST_INTERFACE(IID_IMediaSeeking
,E_NOINTERFACE
);
74 TEST_INTERFACE(IID_IKsPropertySet
,E_NOINTERFACE
);
75 TEST_INTERFACE(IID_IMediaPosition
,E_NOINTERFACE
);
76 TEST_INTERFACE(IID_IQualityControl
,E_NOINTERFACE
);
77 TEST_INTERFACE(IID_IQualProp
,E_NOINTERFACE
);
81 static void test_pin(IPin
*pin
)
83 IMemInputPin
*mpin
= NULL
;
85 IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void **)&mpin
);
87 ok(mpin
== NULL
, "IMemInputPin found!\n");
89 IMemInputPin_Release(mpin
);
93 static void test_basefilter(void)
95 IEnumPins
*pin_enum
= NULL
;
96 IBaseFilter
*base
= NULL
;
101 IUnknown_QueryInterface(pAviSplitter
, &IID_IBaseFilter
, (void **)&base
);
104 /* test_query_interface handles this case */
105 skip("No IBaseFilter\n");
109 hr
= IBaseFilter_EnumPins(base
, NULL
);
110 ok(hr
== E_POINTER
, "hr = %08x and not E_POINTER\n", hr
);
112 hr
= IBaseFilter_EnumPins(base
, &pin_enum
);
113 ok(hr
== S_OK
, "hr = %08x and not S_OK\n", hr
);
115 hr
= IEnumPins_Next(pin_enum
, 1, NULL
, NULL
);
116 ok(hr
== E_POINTER
, "hr = %08x and not E_POINTER\n", hr
);
118 hr
= IEnumPins_Next(pin_enum
, 2, pins
, NULL
);
119 ok(hr
== E_INVALIDARG
, "hr = %08x and not E_INVALIDARG\n", hr
);
121 pins
[0] = (void *)0xdead;
122 pins
[1] = (void *)0xdeed;
124 hr
= IEnumPins_Next(pin_enum
, 2, pins
, &ref
);
125 ok(hr
== S_FALSE
, "hr = %08x instead of S_FALSE\n", hr
);
126 ok(pins
[0] != (void *)0xdead && pins
[0] != NULL
,
127 "pins[0] = %p\n", pins
[0]);
128 if (pins
[0] != (void *)0xdead && pins
[0] != NULL
)
131 IPin_Release(pins
[0]);
134 ok(pins
[1] == (void *)0xdeed, "pins[1] = %p\n", pins
[1]);
136 ref
= IEnumPins_Release(pin_enum
);
137 ok(ref
== 0, "ref is %u and not 0!\n", ref
);
139 IBaseFilter_Release(base
);
142 static const WCHAR avifile
[] = {'t','e','s','t','.','a','v','i',0};
144 static WCHAR
*load_resource(const WCHAR
*name
)
146 static WCHAR pathW
[MAX_PATH
];
152 GetTempPathW(ARRAY_SIZE(pathW
), pathW
);
153 lstrcatW(pathW
, name
);
155 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
156 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
),
159 res
= FindResourceW(NULL
, name
, (LPCWSTR
)RT_RCDATA
);
160 ok( res
!= 0, "couldn't find resource\n" );
161 ptr
= LockResource( LoadResource( GetModuleHandleA(NULL
), res
));
162 WriteFile( file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
163 ok( written
== SizeofResource( GetModuleHandleA(NULL
), res
), "couldn't write resource\n" );
169 static void test_filter_graph(void)
171 IFileSourceFilter
*pfile
= NULL
;
172 IBaseFilter
*preader
= NULL
, *pavi
= NULL
;
173 IEnumPins
*enumpins
= NULL
;
174 IPin
*filepin
= NULL
, *avipin
= NULL
;
177 PIN_DIRECTION dir
= PINDIR_OUTPUT
;
182 WCHAR
*filename
= load_resource(avifile
);
184 file
= CreateFileW(filename
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
185 NULL
, OPEN_EXISTING
, 0, NULL
);
186 if (file
== INVALID_HANDLE_VALUE
)
188 skip("Could not read test file \"%s\", skipping test\n", wine_dbgstr_w(filename
));
189 DeleteFileW(filename
);
193 memset(buffer
, 0, 13);
195 ReadFile(file
, buffer
, readbytes
, &readbytes
, NULL
);
197 if (strncmp(buffer
, "RIFF", 4) || strcmp(buffer
+ 8, "AVI "))
199 skip("%s is not an avi riff file, not doing the avi splitter test\n",
200 wine_dbgstr_w(filename
));
201 DeleteFileW(filename
);
205 hr
= IUnknown_QueryInterface(pAviSplitter
, &IID_IFileSourceFilter
,
207 ok(hr
== E_NOINTERFACE
,
208 "Avi splitter returns unexpected error: %08x\n", hr
);
210 IFileSourceFilter_Release(pfile
);
213 hr
= CoCreateInstance(&CLSID_AsyncReader
, NULL
, CLSCTX_INPROC_SERVER
,
214 &IID_IBaseFilter
, (LPVOID
*)&preader
);
215 ok(hr
== S_OK
, "Could not create asynchronous reader: %08x\n", hr
);
219 hr
= IBaseFilter_QueryInterface(preader
, &IID_IFileSourceFilter
,
221 ok(hr
== S_OK
, "Could not get IFileSourceFilter: %08x\n", hr
);
225 hr
= IUnknown_QueryInterface(pAviSplitter
, &IID_IBaseFilter
,
227 ok(hr
== S_OK
, "Could not get base filter: %08x\n", hr
);
231 hr
= IFileSourceFilter_Load(pfile
, filename
, NULL
);
234 trace("Could not load file: %08x\n", hr
);
238 hr
= IBaseFilter_EnumPins(preader
, &enumpins
);
239 ok(hr
== S_OK
, "No enumpins: %08x\n", hr
);
243 hr
= IEnumPins_Next(enumpins
, 1, &filepin
, NULL
);
244 ok(hr
== S_OK
, "No pin: %08x\n", hr
);
248 IEnumPins_Release(enumpins
);
251 hr
= IBaseFilter_EnumPins(pavi
, &enumpins
);
252 ok(hr
== S_OK
, "No enumpins: %08x\n", hr
);
256 hr
= IEnumPins_Next(enumpins
, 1, &avipin
, NULL
);
257 ok(hr
== S_OK
, "No pin: %08x\n", hr
);
261 hr
= IPin_Connect(filepin
, avipin
, NULL
);
262 ok(hr
== S_OK
, "Could not connect: %08x\n", hr
);
266 IPin_Release(avipin
);
269 IEnumPins_Reset(enumpins
);
271 /* Windows puts the pins in the order: Outputpins - Inputpin,
272 * wine does the reverse, just don't test it for now
273 * Hate to admit it, but windows way makes more sense
275 while (IEnumPins_Next(enumpins
, 1, &avipin
, NULL
) == S_OK
)
277 IPin_QueryDirection(avipin
, &dir
);
278 if (dir
== PINDIR_OUTPUT
)
280 /* Well, connect it to a null renderer! */
281 IBaseFilter
*pnull
= NULL
;
282 IEnumPins
*nullenum
= NULL
;
283 IPin
*nullpin
= NULL
;
285 hr
= CoCreateInstance(&CLSID_NullRenderer
, NULL
,
286 CLSCTX_INPROC_SERVER
, &IID_IBaseFilter
, (LPVOID
*)&pnull
);
287 if (hr
== REGDB_E_CLASSNOTREG
)
289 win_skip("Null renderer not registered, skipping\n");
292 ok(hr
== S_OK
, "Could not create null renderer: %08x\n", hr
);
294 hr
= IBaseFilter_EnumPins(pnull
, &nullenum
);
295 ok(hr
== S_OK
, "Failed to enum pins, hr %#x.\n", hr
);
296 hr
= IEnumPins_Next(nullenum
, 1, &nullpin
, NULL
);
297 ok(hr
== S_OK
, "Failed to get next pin, hr %#x.\n", hr
);
298 IEnumPins_Release(nullenum
);
299 IPin_QueryDirection(nullpin
, &dir
);
301 hr
= IPin_Connect(avipin
, nullpin
, NULL
);
302 ok(hr
== S_OK
, "Failed to connect output pin: %08x\n", hr
);
303 IPin_Release(nullpin
);
306 IBaseFilter_Release(pnull
);
309 IBaseFilter_Run(pnull
, 0);
312 IPin_Release(avipin
);
317 IPin_Release(avipin
);
322 /* At this point there is a minimalistic connected avi splitter that can
323 * be used for all sorts of source filter tests. However that still needs
324 * to be written at a later time.
327 * - Can you disconnect an output pin while running?
329 * - Can you disconnect the pullpin while running?
331 * - Is the reference count incremented during playback or when connected?
332 * Does this happen once for every output pin? Or is there something else
334 * Expecting: You tell me
337 IBaseFilter_Run(preader
, 0);
338 IBaseFilter_Run(pavi
, 0);
339 IBaseFilter_GetState(pavi
, INFINITE
, &state
);
341 IBaseFilter_Pause(pavi
);
342 IBaseFilter_Pause(preader
);
343 IBaseFilter_Stop(pavi
);
344 IBaseFilter_Stop(preader
);
345 IBaseFilter_GetState(pavi
, INFINITE
, &state
);
346 IBaseFilter_GetState(preader
, INFINITE
, &state
);
349 IEnumPins_Reset(enumpins
);
350 while (IEnumPins_Next(enumpins
, 1, &avipin
, NULL
) == S_OK
)
354 IPin_QueryDirection(avipin
, &dir
);
355 IPin_ConnectedTo(avipin
, &to
);
360 if (dir
== PINDIR_OUTPUT
)
364 hr
= IPin_QueryPinInfo(to
, &info
);
365 ok(hr
== S_OK
, "Failed to query pin info, hr %#x.\n", hr
);
367 /* Release twice: Once normal, second from the
368 * previous while loop
370 IBaseFilter_Stop(info
.pFilter
);
372 IPin_Disconnect(avipin
);
373 IBaseFilter_Release(info
.pFilter
);
374 IBaseFilter_Release(info
.pFilter
);
379 IPin_Disconnect(avipin
);
382 IPin_Release(avipin
);
388 skip("Prerequisites not matched, skipping remainder of test\n");
390 IEnumPins_Release(enumpins
);
393 IPin_Release(avipin
);
398 IPin_ConnectedTo(filepin
, &to
);
401 IPin_Disconnect(filepin
);
404 IPin_Release(filepin
);
408 IBaseFilter_Release(preader
);
410 IBaseFilter_Release(pavi
);
412 IFileSourceFilter_Release(pfile
);
414 DeleteFileW(filename
);
417 START_TEST(avisplitter
)
421 if (!create_avisplitter())
423 skip("Could not create avisplitter\n");
427 test_query_interface();
431 release_avisplitter();