2 * Unit tests for Direct Show functions
4 * Copyright (C) 2004 Christian Costa
5 * Copyright (C) 2008 Alexander Dorofeyev
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
25 #include "wine/test.h"
29 typedef struct TestFilterImpl
31 IBaseFilter IBaseFilter_iface
;
34 CRITICAL_SECTION csFilter
;
36 FILTER_INFO filterInfo
;
42 static const WCHAR avifile
[] = {'t','e','s','t','.','a','v','i',0};
43 static const WCHAR mpegfile
[] = {'t','e','s','t','.','m','p','g',0};
45 static IGraphBuilder
*pgraph
;
47 static int createfiltergraph(void)
49 return S_OK
== CoCreateInstance(
50 &CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IGraphBuilder
, (LPVOID
*)&pgraph
);
53 static void test_basic_video(void)
56 LONG video_width
, video_height
;
57 LONG left
, top
, width
, height
;
60 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IBasicVideo
, (LPVOID
*)&pbv
);
61 ok(hr
==S_OK
, "Cannot get IBasicVideo interface returned: %x\n", hr
);
63 /* test get video size */
64 hr
= IBasicVideo_GetVideoSize(pbv
, NULL
, NULL
);
65 ok(hr
==E_POINTER
, "IBasicVideo_GetVideoSize returned: %x\n", hr
);
66 hr
= IBasicVideo_GetVideoSize(pbv
, &video_width
, NULL
);
67 ok(hr
==E_POINTER
, "IBasicVideo_GetVideoSize returned: %x\n", hr
);
68 hr
= IBasicVideo_GetVideoSize(pbv
, NULL
, &video_height
);
69 ok(hr
==E_POINTER
, "IBasicVideo_GetVideoSize returned: %x\n", hr
);
70 hr
= IBasicVideo_GetVideoSize(pbv
, &video_width
, &video_height
);
71 ok(hr
==S_OK
, "Cannot get video size returned: %x\n", hr
);
73 /* test source position */
74 hr
= IBasicVideo_GetSourcePosition(pbv
, NULL
, NULL
, NULL
, NULL
);
75 ok(hr
== E_POINTER
, "IBasicVideo_GetSourcePosition returned: %x\n", hr
);
76 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, NULL
, NULL
);
77 ok(hr
== E_POINTER
, "IBasicVideo_GetSourcePosition returned: %x\n", hr
);
78 hr
= IBasicVideo_GetSourcePosition(pbv
, NULL
, NULL
, &width
, &height
);
79 ok(hr
== E_POINTER
, "IBasicVideo_GetSourcePosition returned: %x\n", hr
);
80 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, &width
, &height
);
81 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
82 ok(left
== 0, "expected 0, got %d\n", left
);
83 ok(top
== 0, "expected 0, got %d\n", top
);
84 ok(width
== video_width
, "expected %d, got %d\n", video_width
, width
);
85 ok(height
== video_height
, "expected %d, got %d\n", video_height
, height
);
87 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, 0, 0, 0);
88 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
89 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, 0, video_width
*2, video_height
*2);
90 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
91 hr
= IBasicVideo_put_SourceTop(pbv
, -1);
92 ok(hr
==E_INVALIDARG
, "IBasicVideo_put_SourceTop returned: %x\n", hr
);
93 hr
= IBasicVideo_put_SourceTop(pbv
, 0);
94 ok(hr
==S_OK
, "Cannot put source top returned: %x\n", hr
);
95 hr
= IBasicVideo_put_SourceTop(pbv
, 1);
96 ok(hr
==E_INVALIDARG
, "IBasicVideo_put_SourceTop returned: %x\n", hr
);
98 hr
= IBasicVideo_SetSourcePosition(pbv
, video_width
, 0, video_width
, video_height
);
99 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
100 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, video_height
, video_width
, video_height
);
101 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
102 hr
= IBasicVideo_SetSourcePosition(pbv
, -1, 0, video_width
, video_height
);
103 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
104 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, -1, video_width
, video_height
);
105 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
106 hr
= IBasicVideo_SetSourcePosition(pbv
, video_width
/2, video_height
/2, video_width
, video_height
);
107 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
108 hr
= IBasicVideo_SetSourcePosition(pbv
, video_width
/2, video_height
/2, video_width
, video_height
);
109 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
111 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, 0, video_width
, video_height
+1);
112 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
113 hr
= IBasicVideo_SetSourcePosition(pbv
, 0, 0, video_width
+1, video_height
);
114 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetSourcePosition returned: %x\n", hr
);
116 hr
= IBasicVideo_SetSourcePosition(pbv
, video_width
/2, video_height
/2, video_width
/3+1, video_height
/3+1);
117 ok(hr
==S_OK
, "Cannot set source position returned: %x\n", hr
);
119 hr
= IBasicVideo_get_SourceLeft(pbv
, &left
);
120 ok(hr
==S_OK
, "Cannot get source left returned: %x\n", hr
);
121 ok(left
==video_width
/2, "expected %d, got %d\n", video_width
/2, left
);
122 hr
= IBasicVideo_get_SourceTop(pbv
, &top
);
123 ok(hr
==S_OK
, "Cannot get source top returned: %x\n", hr
);
124 ok(top
==video_height
/2, "expected %d, got %d\n", video_height
/2, top
);
125 hr
= IBasicVideo_get_SourceWidth(pbv
, &width
);
126 ok(hr
==S_OK
, "Cannot get source width returned: %x\n", hr
);
127 ok(width
==video_width
/3+1, "expected %d, got %d\n", video_width
/3+1, width
);
128 hr
= IBasicVideo_get_SourceHeight(pbv
, &height
);
129 ok(hr
==S_OK
, "Cannot get source height returned: %x\n", hr
);
130 ok(height
==video_height
/3+1, "expected %d, got %d\n", video_height
/3+1, height
);
132 hr
= IBasicVideo_put_SourceLeft(pbv
, video_width
/3);
133 ok(hr
==S_OK
, "Cannot put source left returned: %x\n", hr
);
134 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, &width
, &height
);
135 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
136 ok(left
== video_width
/3, "expected %d, got %d\n", video_width
/3, left
);
137 ok(width
== video_width
/3+1, "expected %d, got %d\n", video_width
/3+1, width
);
139 hr
= IBasicVideo_put_SourceTop(pbv
, video_height
/3);
140 ok(hr
==S_OK
, "Cannot put source top returned: %x\n", hr
);
141 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, &width
, &height
);
142 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
143 ok(top
== video_height
/3, "expected %d, got %d\n", video_height
/3, top
);
144 ok(height
== video_height
/3+1, "expected %d, got %d\n", video_height
/3+1, height
);
146 hr
= IBasicVideo_put_SourceWidth(pbv
, video_width
/4+1);
147 ok(hr
==S_OK
, "Cannot put source width returned: %x\n", hr
);
148 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, &width
, &height
);
149 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
150 ok(left
== video_width
/3, "expected %d, got %d\n", video_width
/3, left
);
151 ok(width
== video_width
/4+1, "expected %d, got %d\n", video_width
/4+1, width
);
153 hr
= IBasicVideo_put_SourceHeight(pbv
, video_height
/4+1);
154 ok(hr
==S_OK
, "Cannot put source height returned: %x\n", hr
);
155 hr
= IBasicVideo_GetSourcePosition(pbv
, &left
, &top
, &width
, &height
);
156 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
157 ok(top
== video_height
/3, "expected %d, got %d\n", video_height
/3, top
);
158 ok(height
== video_height
/4+1, "expected %d, got %d\n", video_height
/4+1, height
);
160 /* test destination rectangle */
161 hr
= IBasicVideo_GetDestinationPosition(pbv
, NULL
, NULL
, NULL
, NULL
);
162 ok(hr
== E_POINTER
, "IBasicVideo_GetDestinationPosition returned: %x\n", hr
);
163 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, NULL
, NULL
);
164 ok(hr
== E_POINTER
, "IBasicVideo_GetDestinationPosition returned: %x\n", hr
);
165 hr
= IBasicVideo_GetDestinationPosition(pbv
, NULL
, NULL
, &width
, &height
);
166 ok(hr
== E_POINTER
, "IBasicVideo_GetDestinationPosition returned: %x\n", hr
);
167 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, &width
, &height
);
168 ok(hr
== S_OK
, "Cannot get destination position returned: %x\n", hr
);
169 ok(left
== 0, "expected 0, got %d\n", left
);
170 ok(top
== 0, "expected 0, got %d\n", top
);
171 todo_wine
ok(width
== video_width
, "expected %d, got %d\n", video_width
, width
);
172 todo_wine
ok(height
== video_height
, "expected %d, got %d\n", video_height
, height
);
174 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, 0, 0, 0);
175 ok(hr
==E_INVALIDARG
, "IBasicVideo_SetDestinationPosition returned: %x\n", hr
);
176 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, 0, video_width
*2, video_height
*2);
177 ok(hr
==S_OK
, "Cannot put destination position returned: %x\n", hr
);
179 hr
= IBasicVideo_put_DestinationLeft(pbv
, -1);
180 ok(hr
==S_OK
, "Cannot put destination left returned: %x\n", hr
);
181 hr
= IBasicVideo_put_DestinationLeft(pbv
, 0);
182 ok(hr
==S_OK
, "Cannot put destination left returned: %x\n", hr
);
183 hr
= IBasicVideo_put_DestinationLeft(pbv
, 1);
184 ok(hr
==S_OK
, "Cannot put destination left returned: %x\n", hr
);
186 hr
= IBasicVideo_SetDestinationPosition(pbv
, video_width
, 0, video_width
, video_height
);
187 ok(hr
==S_OK
, "Cannot set destinaiton position returned: %x\n", hr
);
188 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, video_height
, video_width
, video_height
);
189 ok(hr
==S_OK
, "Cannot set destinaiton position returned: %x\n", hr
);
190 hr
= IBasicVideo_SetDestinationPosition(pbv
, -1, 0, video_width
, video_height
);
191 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
192 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, -1, video_width
, video_height
);
193 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
194 hr
= IBasicVideo_SetDestinationPosition(pbv
, video_width
/2, video_height
/2, video_width
, video_height
);
195 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
196 hr
= IBasicVideo_SetDestinationPosition(pbv
, video_width
/2, video_height
/2, video_width
, video_height
);
197 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
199 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, 0, video_width
, video_height
+1);
200 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
201 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, 0, video_width
+1, video_height
);
202 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
204 hr
= IBasicVideo_SetDestinationPosition(pbv
, video_width
/2, video_height
/2, video_width
/3+1, video_height
/3+1);
205 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
207 hr
= IBasicVideo_get_DestinationLeft(pbv
, &left
);
208 ok(hr
==S_OK
, "Cannot get destination left returned: %x\n", hr
);
209 ok(left
==video_width
/2, "expected %d, got %d\n", video_width
/2, left
);
210 hr
= IBasicVideo_get_DestinationTop(pbv
, &top
);
211 ok(hr
==S_OK
, "Cannot get destination top returned: %x\n", hr
);
212 ok(top
==video_height
/2, "expected %d, got %d\n", video_height
/2, top
);
213 hr
= IBasicVideo_get_DestinationWidth(pbv
, &width
);
214 ok(hr
==S_OK
, "Cannot get destination width returned: %x\n", hr
);
215 ok(width
==video_width
/3+1, "expected %d, got %d\n", video_width
/3+1, width
);
216 hr
= IBasicVideo_get_DestinationHeight(pbv
, &height
);
217 ok(hr
==S_OK
, "Cannot get destination height returned: %x\n", hr
);
218 ok(height
==video_height
/3+1, "expected %d, got %d\n", video_height
/3+1, height
);
220 hr
= IBasicVideo_put_DestinationLeft(pbv
, video_width
/3);
221 ok(hr
==S_OK
, "Cannot put destination left returned: %x\n", hr
);
222 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, &width
, &height
);
223 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
224 ok(left
== video_width
/3, "expected %d, got %d\n", video_width
/3, left
);
225 ok(width
== video_width
/3+1, "expected %d, got %d\n", video_width
/3+1, width
);
227 hr
= IBasicVideo_put_DestinationTop(pbv
, video_height
/3);
228 ok(hr
==S_OK
, "Cannot put destination top returned: %x\n", hr
);
229 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, &width
, &height
);
230 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
231 ok(top
== video_height
/3, "expected %d, got %d\n", video_height
/3, top
);
232 ok(height
== video_height
/3+1, "expected %d, got %d\n", video_height
/3+1, height
);
234 hr
= IBasicVideo_put_DestinationWidth(pbv
, video_width
/4+1);
235 ok(hr
==S_OK
, "Cannot put destination width returned: %x\n", hr
);
236 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, &width
, &height
);
237 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
238 ok(left
== video_width
/3, "expected %d, got %d\n", video_width
/3, left
);
239 ok(width
== video_width
/4+1, "expected %d, got %d\n", video_width
/4+1, width
);
241 hr
= IBasicVideo_put_DestinationHeight(pbv
, video_height
/4+1);
242 ok(hr
==S_OK
, "Cannot put destination height returned: %x\n", hr
);
243 hr
= IBasicVideo_GetDestinationPosition(pbv
, &left
, &top
, &width
, &height
);
244 ok(hr
== S_OK
, "Cannot get source position returned: %x\n", hr
);
245 ok(top
== video_height
/3, "expected %d, got %d\n", video_height
/3, top
);
246 ok(height
== video_height
/4+1, "expected %d, got %d\n", video_height
/4+1, height
);
248 /* reset source rectangle */
249 hr
= IBasicVideo_SetDefaultSourcePosition(pbv
);
250 ok(hr
==S_OK
, "IBasicVideo_SetDefaultSourcePosition returned: %x\n", hr
);
252 /* reset destination position */
253 hr
= IBasicVideo_SetDestinationPosition(pbv
, 0, 0, video_width
, video_height
);
254 ok(hr
==S_OK
, "Cannot set destination position returned: %x\n", hr
);
256 IBasicVideo_Release(pbv
);
259 static void rungraph(void)
267 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaControl
, (LPVOID
*)&pmc
);
268 ok(hr
==S_OK
, "Cannot get IMediaControl interface returned: %x\n", hr
);
270 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaFilter
, (LPVOID
*)&pmf
);
271 ok(hr
==S_OK
, "Cannot get IMediaFilter interface returned: %x\n", hr
);
273 IMediaControl_Stop(pmc
);
275 IMediaFilter_SetSyncSource(pmf
, NULL
);
277 IMediaFilter_Release(pmf
);
281 hr
= IMediaControl_Run(pmc
);
282 ok(hr
==S_FALSE
, "Cannot run the graph returned: %x\n", hr
);
286 trace("run -> stop\n");
287 hr
= IMediaControl_Stop(pmc
);
288 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot stop the graph returned: %x\n", hr
);
290 IGraphBuilder_SetDefaultSyncSource(pgraph
);
293 trace("stop -> pause\n");
294 hr
= IMediaControl_Pause(pmc
);
295 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot pause the graph returned: %x\n", hr
);
298 trace("pause -> run\n");
299 hr
= IMediaControl_Run(pmc
);
300 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot start the graph returned: %x\n", hr
);
303 trace("run -> pause\n");
304 hr
= IMediaControl_Pause(pmc
);
305 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot pause the graph returned: %x\n", hr
);
308 trace("pause -> stop\n");
309 hr
= IMediaControl_Stop(pmc
);
310 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot stop the graph returned: %x\n", hr
);
313 trace("pause -> run\n");
314 hr
= IMediaControl_Run(pmc
);
315 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot start the graph returned: %x\n", hr
);
317 trace("run -> stop\n");
318 hr
= IMediaControl_Stop(pmc
);
319 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot stop the graph returned: %x\n", hr
);
321 trace("stop -> run\n");
322 hr
= IMediaControl_Run(pmc
);
323 ok(hr
==S_OK
|| hr
== S_FALSE
, "Cannot start the graph returned: %x\n", hr
);
325 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaEvent
, (LPVOID
*)&pme
);
326 ok(hr
==S_OK
, "Cannot get IMediaEvent interface returned: %x\n", hr
);
328 hr
= IMediaEvent_GetEventHandle(pme
, (OAEVENT
*)&hEvent
);
329 ok(hr
==S_OK
, "Cannot get event handle returned: %x\n", hr
);
331 /* WaitForSingleObject(hEvent, INFINITE); */
334 hr
= IMediaEvent_Release(pme
);
335 ok(hr
==2, "Releasing mediaevent returned: %x\n", hr
);
337 hr
= IMediaControl_Stop(pmc
);
338 ok(hr
==S_OK
, "Cannot stop the graph returned: %x\n", hr
);
340 hr
= IMediaControl_Release(pmc
);
341 ok(hr
==1, "Releasing mediacontrol returned: %x\n", hr
);
344 static void releasefiltergraph(void)
348 hr
= IGraphBuilder_Release(pgraph
);
349 ok(hr
==0, "Releasing filtergraph returned: %x\n", hr
);
352 static void test_render_run(const WCHAR
*file
)
357 h
= CreateFileW(file
, 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
358 if (h
== INVALID_HANDLE_VALUE
) {
359 skip("Could not read test file %s, skipping test\n", wine_dbgstr_w(file
));
364 if (!createfiltergraph())
367 hr
= IGraphBuilder_RenderFile(pgraph
, file
, NULL
);
368 ok(hr
== S_OK
, "RenderFile returned: %x\n", hr
);
371 releasefiltergraph();
373 /* check reference leaks */
374 h
= CreateFileW(file
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
375 ok(h
!= INVALID_HANDLE_VALUE
, "CreateFile failed: err=%d\n", GetLastError());
379 static void test_graph_builder(void)
382 IBaseFilter
*pF
= NULL
;
383 IBaseFilter
*pF2
= NULL
;
385 IEnumPins
*pEnum
= NULL
;
387 static const WCHAR testFilterW
[] = {'t','e','s','t','F','i','l','t','e','r',0};
388 static const WCHAR fooBarW
[] = {'f','o','o','B','a','r',0};
390 if (!createfiltergraph())
393 /* create video filter */
394 hr
= CoCreateInstance(&CLSID_VideoRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
395 &IID_IBaseFilter
, (LPVOID
*)&pF
);
396 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
397 ok(pF
!= NULL
, "pF is NULL\n");
399 hr
= IGraphBuilder_AddFilter(pgraph
, NULL
, testFilterW
);
400 ok(hr
== E_POINTER
, "IGraphBuilder_AddFilter returned %x\n", hr
);
402 /* add the two filters to the graph */
403 hr
= IGraphBuilder_AddFilter(pgraph
, pF
, testFilterW
);
404 ok(hr
== S_OK
, "failed to add pF to the graph: %x\n", hr
);
407 hr
= IBaseFilter_EnumPins(pF
, &pEnum
);
408 ok(hr
== S_OK
, "IBaseFilter_EnumPins failed for pF: %x\n", hr
);
409 ok(pEnum
!= NULL
, "pEnum is NULL\n");
410 hr
= IEnumPins_Next(pEnum
, 1, &pIn
, NULL
);
411 ok(hr
== S_OK
, "IEnumPins_Next failed for pF: %x\n", hr
);
412 ok(pIn
!= NULL
, "pIn is NULL\n");
413 hr
= IPin_QueryDirection(pIn
, &dir
);
414 ok(hr
== S_OK
, "IPin_QueryDirection failed: %x\n", hr
);
415 ok(dir
== PINDIR_INPUT
, "pin has wrong direction\n");
417 hr
= IGraphBuilder_FindFilterByName(pgraph
, fooBarW
, &pF2
);
418 ok(hr
== VFW_E_NOT_FOUND
, "IGraphBuilder_FindFilterByName returned %x\n", hr
);
419 ok(pF2
== NULL
, "IGraphBuilder_FindFilterByName returned %p\n", pF2
);
420 hr
= IGraphBuilder_FindFilterByName(pgraph
, testFilterW
, &pF2
);
421 ok(hr
== S_OK
, "IGraphBuilder_FindFilterByName returned %x\n", hr
);
422 ok(pF2
!= NULL
, "IGraphBuilder_FindFilterByName returned NULL\n");
423 hr
= IGraphBuilder_FindFilterByName(pgraph
, testFilterW
, NULL
);
424 ok(hr
== E_POINTER
, "IGraphBuilder_FindFilterByName returned %x\n", hr
);
426 hr
= IGraphBuilder_Connect(pgraph
, NULL
, pIn
);
427 ok(hr
== E_POINTER
, "IGraphBuilder_Connect returned %x\n", hr
);
429 hr
= IGraphBuilder_Connect(pgraph
, pIn
, NULL
);
430 ok(hr
== E_POINTER
, "IGraphBuilder_Connect returned %x\n", hr
);
432 hr
= IGraphBuilder_Connect(pgraph
, pIn
, pIn
);
433 ok(hr
== VFW_E_CANNOT_CONNECT
, "IGraphBuilder_Connect returned %x\n", hr
);
435 if (pIn
) IPin_Release(pIn
);
436 if (pEnum
) IEnumPins_Release(pEnum
);
437 if (pF
) IBaseFilter_Release(pF
);
438 if (pF2
) IBaseFilter_Release(pF2
);
440 releasefiltergraph();
443 static void test_graph_builder_addfilter(void)
446 IBaseFilter
*pF
= NULL
;
447 static const WCHAR testFilterW
[] = {'t','e','s','t','F','i','l','t','e','r',0};
449 if (!createfiltergraph())
452 hr
= IGraphBuilder_AddFilter(pgraph
, NULL
, testFilterW
);
453 ok(hr
== E_POINTER
, "IGraphBuilder_AddFilter returned: %x\n", hr
);
455 /* create video filter */
456 hr
= CoCreateInstance(&CLSID_VideoRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
457 &IID_IBaseFilter
, (LPVOID
*)&pF
);
458 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
459 ok(pF
!= NULL
, "pF is NULL\n");
461 skip("failed to created filter, skipping\n");
465 hr
= IGraphBuilder_AddFilter(pgraph
, pF
, NULL
);
466 ok(hr
== S_OK
, "IGraphBuilder_AddFilter returned: %x\n", hr
);
467 IBaseFilter_Release(pF
);
470 static void test_mediacontrol(void)
473 LONGLONG pos
= 0xdeadbeef;
474 GUID format
= GUID_NULL
;
475 IMediaSeeking
*seeking
= NULL
;
476 IMediaFilter
*filter
= NULL
;
477 IMediaControl
*control
= NULL
;
479 IGraphBuilder_SetDefaultSyncSource(pgraph
);
480 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaSeeking
, (void**) &seeking
);
481 ok(hr
== S_OK
, "QueryInterface IMediaControl failed: %08x\n", hr
);
485 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaFilter
, (void**) &filter
);
486 ok(hr
== S_OK
, "QueryInterface IMediaFilter failed: %08x\n", hr
);
489 IMediaSeeking_Release(seeking
);
493 hr
= IGraphBuilder_QueryInterface(pgraph
, &IID_IMediaControl
, (void**) &control
);
494 ok(hr
== S_OK
, "QueryInterface IMediaControl failed: %08x\n", hr
);
497 IMediaSeeking_Release(seeking
);
498 IMediaFilter_Release(filter
);
503 hr
= IMediaSeeking_GetTimeFormat(seeking
, &format
);
504 ok(hr
== S_OK
, "GetTimeFormat failed: %08x\n", hr
);
505 ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "GetTimeFormat: unexpected format %s\n", wine_dbgstr_guid(&format
));
508 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &pos
, NULL
, 0x123456789a, NULL
);
509 ok(hr
== S_OK
, "ConvertTimeFormat failed: %08x\n", hr
);
510 ok(pos
== 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
513 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &pos
, &TIME_FORMAT_MEDIA_TIME
, 0x123456789a, NULL
);
514 ok(hr
== S_OK
, "ConvertTimeFormat failed: %08x\n", hr
);
515 ok(pos
== 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
518 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &pos
, NULL
, 0x123456789a, &TIME_FORMAT_MEDIA_TIME
);
519 ok(hr
== S_OK
, "ConvertTimeFormat failed: %08x\n", hr
);
520 ok(pos
== 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
522 hr
= IMediaSeeking_GetCurrentPosition(seeking
, &pos
);
523 ok(hr
== S_OK
, "GetCurrentPosition failed: %08x\n", hr
);
524 ok(pos
== 0, "Position != 0 (%x%08x)\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
526 hr
= IMediaSeeking_SetPositions(seeking
, NULL
, AM_SEEKING_ReturnTime
, NULL
, AM_SEEKING_NoPositioning
);
527 ok(hr
== S_OK
, "SetPositions failed: %08x\n", hr
);
528 hr
= IMediaSeeking_SetPositions(seeking
, NULL
, AM_SEEKING_NoPositioning
, NULL
, AM_SEEKING_ReturnTime
);
529 ok(hr
== S_OK
, "SetPositions failed: %08x\n", hr
);
531 IMediaFilter_SetSyncSource(filter
, NULL
);
533 hr
= IMediaSeeking_GetCurrentPosition(seeking
, &pos
);
534 ok(hr
== S_OK
, "GetCurrentPosition failed: %08x\n", hr
);
535 ok(pos
== 0, "Position != 0 (%x%08x)\n", (DWORD
)(pos
>> 32), (DWORD
)pos
);
537 hr
= IMediaControl_GetState(control
, 1000, NULL
);
538 ok(hr
== E_POINTER
, "GetState expected %08x, got %08x\n", E_POINTER
, hr
);
540 IMediaControl_Release(control
);
541 IMediaSeeking_Release(seeking
);
542 IMediaFilter_Release(filter
);
543 releasefiltergraph();
546 static void test_filter_graph2(void)
549 IFilterGraph2
*pF
= NULL
;
551 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
552 &IID_IFilterGraph2
, (LPVOID
*)&pF
);
553 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
554 ok(pF
!= NULL
, "pF is NULL\n");
556 hr
= IFilterGraph2_Release(pF
);
557 ok(hr
== 0, "IFilterGraph2_Release returned: %x\n", hr
);
560 /* IEnumMediaTypes implementation (supporting code for Render() test.) */
561 static void FreeMediaType(AM_MEDIA_TYPE
* pMediaType
)
563 if (pMediaType
->pbFormat
)
565 CoTaskMemFree(pMediaType
->pbFormat
);
566 pMediaType
->pbFormat
= NULL
;
568 if (pMediaType
->pUnk
)
570 IUnknown_Release(pMediaType
->pUnk
);
571 pMediaType
->pUnk
= NULL
;
575 static HRESULT
CopyMediaType(AM_MEDIA_TYPE
* pDest
, const AM_MEDIA_TYPE
*pSrc
)
578 if (!pSrc
->pbFormat
) return S_OK
;
579 if (!(pDest
->pbFormat
= CoTaskMemAlloc(pSrc
->cbFormat
)))
580 return E_OUTOFMEMORY
;
581 memcpy(pDest
->pbFormat
, pSrc
->pbFormat
, pSrc
->cbFormat
);
583 IUnknown_AddRef(pDest
->pUnk
);
587 static AM_MEDIA_TYPE
* CreateMediaType(AM_MEDIA_TYPE
const * pSrc
)
589 AM_MEDIA_TYPE
* pDest
;
591 pDest
= CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
595 if (FAILED(CopyMediaType(pDest
, pSrc
)))
597 CoTaskMemFree(pDest
);
604 static BOOL
CompareMediaTypes(const AM_MEDIA_TYPE
* pmt1
, const AM_MEDIA_TYPE
* pmt2
, BOOL bWildcards
)
606 return (((bWildcards
&& (IsEqualGUID(&pmt1
->majortype
, &GUID_NULL
) || IsEqualGUID(&pmt2
->majortype
, &GUID_NULL
))) || IsEqualGUID(&pmt1
->majortype
, &pmt2
->majortype
)) &&
607 ((bWildcards
&& (IsEqualGUID(&pmt1
->subtype
, &GUID_NULL
) || IsEqualGUID(&pmt2
->subtype
, &GUID_NULL
))) || IsEqualGUID(&pmt1
->subtype
, &pmt2
->subtype
)));
610 static void DeleteMediaType(AM_MEDIA_TYPE
* pMediaType
)
612 FreeMediaType(pMediaType
);
613 CoTaskMemFree(pMediaType
);
616 typedef struct IEnumMediaTypesImpl
618 IEnumMediaTypes IEnumMediaTypes_iface
;
620 AM_MEDIA_TYPE
*pMediaTypes
;
623 } IEnumMediaTypesImpl
;
625 static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl
;
627 static inline IEnumMediaTypesImpl
*impl_from_IEnumMediaTypes(IEnumMediaTypes
*iface
)
629 return CONTAINING_RECORD(iface
, IEnumMediaTypesImpl
, IEnumMediaTypes_iface
);
632 static HRESULT
IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE
* pMediaTypes
, ULONG cMediaTypes
, IEnumMediaTypes
** ppEnum
)
635 IEnumMediaTypesImpl
* pEnumMediaTypes
= CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl
));
637 if (!pEnumMediaTypes
)
640 return E_OUTOFMEMORY
;
642 pEnumMediaTypes
->IEnumMediaTypes_iface
.lpVtbl
= &IEnumMediaTypesImpl_Vtbl
;
643 pEnumMediaTypes
->refCount
= 1;
644 pEnumMediaTypes
->uIndex
= 0;
645 pEnumMediaTypes
->cMediaTypes
= cMediaTypes
;
646 pEnumMediaTypes
->pMediaTypes
= CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * cMediaTypes
);
647 for (i
= 0; i
< cMediaTypes
; i
++)
648 if (FAILED(CopyMediaType(&pEnumMediaTypes
->pMediaTypes
[i
], &pMediaTypes
[i
])))
651 FreeMediaType(&pEnumMediaTypes
->pMediaTypes
[i
]);
652 CoTaskMemFree(pEnumMediaTypes
->pMediaTypes
);
653 return E_OUTOFMEMORY
;
655 *ppEnum
= &pEnumMediaTypes
->IEnumMediaTypes_iface
;
659 static HRESULT WINAPI
IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes
* iface
, REFIID riid
, LPVOID
* ppv
)
663 if (IsEqualIID(riid
, &IID_IUnknown
))
665 else if (IsEqualIID(riid
, &IID_IEnumMediaTypes
))
670 IUnknown_AddRef((IUnknown
*)(*ppv
));
674 return E_NOINTERFACE
;
677 static ULONG WINAPI
IEnumMediaTypesImpl_AddRef(IEnumMediaTypes
* iface
)
679 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
680 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
685 static ULONG WINAPI
IEnumMediaTypesImpl_Release(IEnumMediaTypes
* iface
)
687 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
688 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
693 for (i
= 0; i
< This
->cMediaTypes
; i
++)
694 FreeMediaType(&This
->pMediaTypes
[i
]);
695 CoTaskMemFree(This
->pMediaTypes
);
701 static HRESULT WINAPI
IEnumMediaTypesImpl_Next(IEnumMediaTypes
* iface
, ULONG cMediaTypes
, AM_MEDIA_TYPE
** ppMediaTypes
, ULONG
* pcFetched
)
704 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
706 cFetched
= min(This
->cMediaTypes
, This
->uIndex
+ cMediaTypes
) - This
->uIndex
;
711 for (i
= 0; i
< cFetched
; i
++)
712 if (!(ppMediaTypes
[i
] = CreateMediaType(&This
->pMediaTypes
[This
->uIndex
+ i
])))
715 DeleteMediaType(ppMediaTypes
[i
]);
717 return E_OUTOFMEMORY
;
721 if ((cMediaTypes
!= 1) || pcFetched
)
722 *pcFetched
= cFetched
;
724 This
->uIndex
+= cFetched
;
726 if (cFetched
!= cMediaTypes
)
731 static HRESULT WINAPI
IEnumMediaTypesImpl_Skip(IEnumMediaTypes
* iface
, ULONG cMediaTypes
)
733 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
735 if (This
->uIndex
+ cMediaTypes
< This
->cMediaTypes
)
737 This
->uIndex
+= cMediaTypes
;
743 static HRESULT WINAPI
IEnumMediaTypesImpl_Reset(IEnumMediaTypes
* iface
)
745 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
751 static HRESULT WINAPI
IEnumMediaTypesImpl_Clone(IEnumMediaTypes
* iface
, IEnumMediaTypes
** ppEnum
)
754 IEnumMediaTypesImpl
*This
= impl_from_IEnumMediaTypes(iface
);
756 hr
= IEnumMediaTypesImpl_Construct(This
->pMediaTypes
, This
->cMediaTypes
, ppEnum
);
759 return IEnumMediaTypes_Skip(*ppEnum
, This
->uIndex
);
762 static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl
=
764 IEnumMediaTypesImpl_QueryInterface
,
765 IEnumMediaTypesImpl_AddRef
,
766 IEnumMediaTypesImpl_Release
,
767 IEnumMediaTypesImpl_Next
,
768 IEnumMediaTypesImpl_Skip
,
769 IEnumMediaTypesImpl_Reset
,
770 IEnumMediaTypesImpl_Clone
773 /* Implementation of a very stripped down pin for the test filter. Just enough
774 functionality for connecting and Render() to work. */
776 static void Copy_PinInfo(PIN_INFO
* pDest
, const PIN_INFO
* pSrc
)
778 lstrcpyW(pDest
->achName
, pSrc
->achName
);
779 pDest
->dir
= pSrc
->dir
;
780 pDest
->pFilter
= pSrc
->pFilter
;
783 typedef struct ITestPinImpl
787 LPCRITICAL_SECTION pCritSec
;
790 AM_MEDIA_TYPE mtCurrent
;
794 static inline ITestPinImpl
*impl_from_IPin(IPin
*iface
)
796 return CONTAINING_RECORD(iface
, ITestPinImpl
, IPin_iface
);
799 static HRESULT WINAPI
TestFilter_Pin_QueryInterface(IPin
* iface
, REFIID riid
, LPVOID
* ppv
)
803 if (IsEqualIID(riid
, &IID_IUnknown
))
805 else if (IsEqualIID(riid
, &IID_IPin
))
810 IUnknown_AddRef((IUnknown
*)(*ppv
));
814 return E_NOINTERFACE
;
817 static ULONG WINAPI
TestFilter_Pin_AddRef(IPin
* iface
)
819 ITestPinImpl
*This
= impl_from_IPin(iface
);
820 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
824 static ULONG WINAPI
TestFilter_Pin_Release(IPin
* iface
)
826 ITestPinImpl
*This
= impl_from_IPin(iface
);
827 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
831 FreeMediaType(&This
->mtCurrent
);
839 static HRESULT WINAPI
TestFilter_InputPin_Connect(IPin
* iface
, IPin
* pConnector
, const AM_MEDIA_TYPE
* pmt
)
844 static HRESULT WINAPI
TestFilter_InputPin_ReceiveConnection(IPin
* iface
, IPin
* pReceivePin
, const AM_MEDIA_TYPE
* pmt
)
846 ITestPinImpl
*This
= impl_from_IPin(iface
);
847 PIN_DIRECTION pindirReceive
;
850 EnterCriticalSection(This
->pCritSec
);
852 if (!(IsEqualIID(&pmt
->majortype
, &This
->mtCurrent
.majortype
) && (IsEqualIID(&pmt
->subtype
, &This
->mtCurrent
.subtype
) ||
853 IsEqualIID(&GUID_NULL
, &This
->mtCurrent
.subtype
))))
854 hr
= VFW_E_TYPE_NOT_ACCEPTED
;
856 if (This
->pConnectedTo
)
857 hr
= VFW_E_ALREADY_CONNECTED
;
861 IPin_QueryDirection(pReceivePin
, &pindirReceive
);
863 if (pindirReceive
!= PINDIR_OUTPUT
)
865 hr
= VFW_E_INVALID_DIRECTION
;
871 CopyMediaType(&This
->mtCurrent
, pmt
);
872 This
->pConnectedTo
= pReceivePin
;
873 IPin_AddRef(pReceivePin
);
876 LeaveCriticalSection(This
->pCritSec
);
881 static HRESULT WINAPI
TestFilter_Pin_Disconnect(IPin
* iface
)
884 ITestPinImpl
*This
= impl_from_IPin(iface
);
886 EnterCriticalSection(This
->pCritSec
);
888 if (This
->pConnectedTo
)
890 IPin_Release(This
->pConnectedTo
);
891 This
->pConnectedTo
= NULL
;
897 LeaveCriticalSection(This
->pCritSec
);
902 static HRESULT WINAPI
TestFilter_Pin_ConnectedTo(IPin
* iface
, IPin
** ppPin
)
905 ITestPinImpl
*This
= impl_from_IPin(iface
);
907 EnterCriticalSection(This
->pCritSec
);
909 if (This
->pConnectedTo
)
911 *ppPin
= This
->pConnectedTo
;
917 hr
= VFW_E_NOT_CONNECTED
;
921 LeaveCriticalSection(This
->pCritSec
);
926 static HRESULT WINAPI
TestFilter_Pin_ConnectionMediaType(IPin
* iface
, AM_MEDIA_TYPE
* pmt
)
929 ITestPinImpl
*This
= impl_from_IPin(iface
);
931 EnterCriticalSection(This
->pCritSec
);
933 if (This
->pConnectedTo
)
935 CopyMediaType(pmt
, &This
->mtCurrent
);
940 ZeroMemory(pmt
, sizeof(*pmt
));
941 hr
= VFW_E_NOT_CONNECTED
;
944 LeaveCriticalSection(This
->pCritSec
);
949 static HRESULT WINAPI
TestFilter_Pin_QueryPinInfo(IPin
* iface
, PIN_INFO
* pInfo
)
951 ITestPinImpl
*This
= impl_from_IPin(iface
);
953 Copy_PinInfo(pInfo
, &This
->pinInfo
);
954 IBaseFilter_AddRef(pInfo
->pFilter
);
959 static HRESULT WINAPI
TestFilter_Pin_QueryDirection(IPin
* iface
, PIN_DIRECTION
* pPinDir
)
961 ITestPinImpl
*This
= impl_from_IPin(iface
);
963 *pPinDir
= This
->pinInfo
.dir
;
968 static HRESULT WINAPI
TestFilter_Pin_QueryId(IPin
* iface
, LPWSTR
* Id
)
973 static HRESULT WINAPI
TestFilter_Pin_QueryAccept(IPin
* iface
, const AM_MEDIA_TYPE
* pmt
)
975 ITestPinImpl
*This
= impl_from_IPin(iface
);
977 if (IsEqualIID(&pmt
->majortype
, &This
->mtCurrent
.majortype
) && (IsEqualIID(&pmt
->subtype
, &This
->mtCurrent
.subtype
) ||
978 IsEqualIID(&GUID_NULL
, &This
->mtCurrent
.subtype
)))
981 return VFW_E_TYPE_NOT_ACCEPTED
;
984 static HRESULT WINAPI
TestFilter_Pin_EnumMediaTypes(IPin
* iface
, IEnumMediaTypes
** ppEnum
)
986 ITestPinImpl
*This
= impl_from_IPin(iface
);
988 return IEnumMediaTypesImpl_Construct(&This
->mtCurrent
, 1, ppEnum
);
991 static HRESULT WINAPI
TestFilter_Pin_QueryInternalConnections(IPin
* iface
, IPin
** apPin
, ULONG
* cPin
)
996 static HRESULT WINAPI
TestFilter_Pin_BeginFlush(IPin
* iface
)
1001 static HRESULT WINAPI
TestFilter_Pin_EndFlush(IPin
* iface
)
1006 static HRESULT WINAPI
TestFilter_Pin_NewSegment(IPin
* iface
, REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1011 static HRESULT WINAPI
TestFilter_Pin_EndOfStream(IPin
* iface
)
1016 static const IPinVtbl TestFilter_InputPin_Vtbl
=
1018 TestFilter_Pin_QueryInterface
,
1019 TestFilter_Pin_AddRef
,
1020 TestFilter_Pin_Release
,
1021 TestFilter_InputPin_Connect
,
1022 TestFilter_InputPin_ReceiveConnection
,
1023 TestFilter_Pin_Disconnect
,
1024 TestFilter_Pin_ConnectedTo
,
1025 TestFilter_Pin_ConnectionMediaType
,
1026 TestFilter_Pin_QueryPinInfo
,
1027 TestFilter_Pin_QueryDirection
,
1028 TestFilter_Pin_QueryId
,
1029 TestFilter_Pin_QueryAccept
,
1030 TestFilter_Pin_EnumMediaTypes
,
1031 TestFilter_Pin_QueryInternalConnections
,
1032 TestFilter_Pin_EndOfStream
,
1033 TestFilter_Pin_BeginFlush
,
1034 TestFilter_Pin_EndFlush
,
1035 TestFilter_Pin_NewSegment
1038 static HRESULT WINAPI
TestFilter_OutputPin_ReceiveConnection(IPin
* iface
, IPin
* pReceivePin
, const AM_MEDIA_TYPE
* pmt
)
1040 return E_UNEXPECTED
;
1043 /* Private helper function */
1044 static HRESULT
TestFilter_OutputPin_ConnectSpecific(ITestPinImpl
* This
, IPin
* pReceivePin
,
1045 const AM_MEDIA_TYPE
* pmt
)
1049 This
->pConnectedTo
= pReceivePin
;
1050 IPin_AddRef(pReceivePin
);
1052 hr
= IPin_ReceiveConnection(pReceivePin
, &This
->IPin_iface
, pmt
);
1056 IPin_Release(This
->pConnectedTo
);
1057 This
->pConnectedTo
= NULL
;
1063 static HRESULT WINAPI
TestFilter_OutputPin_Connect(IPin
* iface
, IPin
* pReceivePin
, const AM_MEDIA_TYPE
* pmt
)
1065 ITestPinImpl
*This
= impl_from_IPin(iface
);
1068 EnterCriticalSection(This
->pCritSec
);
1070 /* if we have been a specific type to connect with, then we can either connect
1071 * with that or fail. We cannot choose different AM_MEDIA_TYPE */
1072 if (pmt
&& !IsEqualGUID(&pmt
->majortype
, &GUID_NULL
) && !IsEqualGUID(&pmt
->subtype
, &GUID_NULL
))
1073 hr
= TestFilter_OutputPin_ConnectSpecific(This
, pReceivePin
, pmt
);
1076 if (( !pmt
|| CompareMediaTypes(pmt
, &This
->mtCurrent
, TRUE
) ) &&
1077 (TestFilter_OutputPin_ConnectSpecific(This
, pReceivePin
, &This
->mtCurrent
) == S_OK
))
1079 else hr
= VFW_E_NO_ACCEPTABLE_TYPES
;
1080 } /* if negotiate media type */
1081 } /* if succeeded */
1082 LeaveCriticalSection(This
->pCritSec
);
1087 static const IPinVtbl TestFilter_OutputPin_Vtbl
=
1089 TestFilter_Pin_QueryInterface
,
1090 TestFilter_Pin_AddRef
,
1091 TestFilter_Pin_Release
,
1092 TestFilter_OutputPin_Connect
,
1093 TestFilter_OutputPin_ReceiveConnection
,
1094 TestFilter_Pin_Disconnect
,
1095 TestFilter_Pin_ConnectedTo
,
1096 TestFilter_Pin_ConnectionMediaType
,
1097 TestFilter_Pin_QueryPinInfo
,
1098 TestFilter_Pin_QueryDirection
,
1099 TestFilter_Pin_QueryId
,
1100 TestFilter_Pin_QueryAccept
,
1101 TestFilter_Pin_EnumMediaTypes
,
1102 TestFilter_Pin_QueryInternalConnections
,
1103 TestFilter_Pin_EndOfStream
,
1104 TestFilter_Pin_BeginFlush
,
1105 TestFilter_Pin_EndFlush
,
1106 TestFilter_Pin_NewSegment
1109 static HRESULT
TestFilter_Pin_Construct(const IPinVtbl
*Pin_Vtbl
, const PIN_INFO
* pPinInfo
, AM_MEDIA_TYPE
*pinmt
,
1110 LPCRITICAL_SECTION pCritSec
, IPin
** ppPin
)
1112 ITestPinImpl
* pPinImpl
;
1116 pPinImpl
= CoTaskMemAlloc(sizeof(ITestPinImpl
));
1119 return E_OUTOFMEMORY
;
1121 pPinImpl
->refCount
= 1;
1122 pPinImpl
->pConnectedTo
= NULL
;
1123 pPinImpl
->pCritSec
= pCritSec
;
1124 Copy_PinInfo(&pPinImpl
->pinInfo
, pPinInfo
);
1125 pPinImpl
->mtCurrent
= *pinmt
;
1127 pPinImpl
->IPin_iface
.lpVtbl
= Pin_Vtbl
;
1129 *ppPin
= &pPinImpl
->IPin_iface
;
1133 /* IEnumPins implementation */
1135 typedef HRESULT (* FNOBTAINPIN
)(TestFilterImpl
*tf
, ULONG pos
, IPin
**pin
, DWORD
*lastsynctick
);
1137 typedef struct IEnumPinsImpl
1139 IEnumPins IEnumPins_iface
;
1142 TestFilterImpl
*base
;
1143 FNOBTAINPIN receive_pin
;
1147 static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl
;
1149 static inline IEnumPinsImpl
*impl_from_IEnumPins(IEnumPins
*iface
)
1151 return CONTAINING_RECORD(iface
, IEnumPinsImpl
, IEnumPins_iface
);
1154 static HRESULT
createenumpins(IEnumPins
** ppEnum
, FNOBTAINPIN receive_pin
, TestFilterImpl
*base
)
1156 IEnumPinsImpl
* pEnumPins
;
1161 pEnumPins
= CoTaskMemAlloc(sizeof(IEnumPinsImpl
));
1165 return E_OUTOFMEMORY
;
1167 pEnumPins
->IEnumPins_iface
.lpVtbl
= &IEnumPinsImpl_Vtbl
;
1168 pEnumPins
->refCount
= 1;
1169 pEnumPins
->uIndex
= 0;
1170 pEnumPins
->receive_pin
= receive_pin
;
1171 pEnumPins
->base
= base
;
1172 IBaseFilter_AddRef(&base
->IBaseFilter_iface
);
1173 *ppEnum
= &pEnumPins
->IEnumPins_iface
;
1175 receive_pin(base
, ~0, NULL
, &pEnumPins
->synctime
);
1180 static HRESULT WINAPI
IEnumPinsImpl_QueryInterface(IEnumPins
* iface
, REFIID riid
, LPVOID
* ppv
)
1184 if (IsEqualIID(riid
, &IID_IUnknown
))
1186 else if (IsEqualIID(riid
, &IID_IEnumPins
))
1191 IUnknown_AddRef((IUnknown
*)(*ppv
));
1195 return E_NOINTERFACE
;
1198 static ULONG WINAPI
IEnumPinsImpl_AddRef(IEnumPins
* iface
)
1200 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1201 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
1206 static ULONG WINAPI
IEnumPinsImpl_Release(IEnumPins
* iface
)
1208 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1209 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
1213 IBaseFilter_Release(&This
->base
->IBaseFilter_iface
);
1214 CoTaskMemFree(This
);
1221 static HRESULT WINAPI
IEnumPinsImpl_Next(IEnumPins
* iface
, ULONG cPins
, IPin
** ppPins
, ULONG
* pcFetched
)
1223 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1224 DWORD synctime
= This
->synctime
;
1231 if (cPins
> 1 && !pcFetched
)
1232 return E_INVALIDARG
;
1237 while (i
< cPins
&& hr
== S_OK
)
1239 hr
= This
->receive_pin(This
->base
, This
->uIndex
+ i
, &ppPins
[i
], &synctime
);
1244 if (synctime
!= This
->synctime
)
1248 if (!i
&& synctime
!= This
->synctime
)
1249 return VFW_E_ENUM_OUT_OF_SYNC
;
1260 static HRESULT WINAPI
IEnumPinsImpl_Skip(IEnumPins
* iface
, ULONG cPins
)
1262 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1263 DWORD synctime
= This
->synctime
;
1267 hr
= This
->receive_pin(This
->base
, This
->uIndex
+ cPins
, &pin
, &synctime
);
1271 if (synctime
!= This
->synctime
)
1272 return VFW_E_ENUM_OUT_OF_SYNC
;
1275 This
->uIndex
+= cPins
;
1280 static HRESULT WINAPI
IEnumPinsImpl_Reset(IEnumPins
* iface
)
1282 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1284 This
->receive_pin(This
->base
, ~0, NULL
, &This
->synctime
);
1290 static HRESULT WINAPI
IEnumPinsImpl_Clone(IEnumPins
* iface
, IEnumPins
** ppEnum
)
1293 IEnumPinsImpl
*This
= impl_from_IEnumPins(iface
);
1295 hr
= createenumpins(ppEnum
, This
->receive_pin
, This
->base
);
1298 return IEnumPins_Skip(*ppEnum
, This
->uIndex
);
1301 static const IEnumPinsVtbl IEnumPinsImpl_Vtbl
=
1303 IEnumPinsImpl_QueryInterface
,
1304 IEnumPinsImpl_AddRef
,
1305 IEnumPinsImpl_Release
,
1308 IEnumPinsImpl_Reset
,
1312 /* Test filter implementation - a filter that has few predefined pins with single media type
1313 * that accept only this single media type. Enough for Render(). */
1315 typedef struct TestFilterPinData
1317 PIN_DIRECTION pinDir
;
1318 const GUID
*mediasubtype
;
1319 } TestFilterPinData
;
1321 static const IBaseFilterVtbl TestFilter_Vtbl
;
1323 static inline TestFilterImpl
*impl_from_IBaseFilter(IBaseFilter
*iface
)
1325 return CONTAINING_RECORD(iface
, TestFilterImpl
, IBaseFilter_iface
);
1328 static HRESULT
createtestfilter(const CLSID
* pClsid
, const TestFilterPinData
*pinData
,
1329 TestFilterImpl
**tf
)
1331 static const WCHAR wcsInputPinName
[] = {'i','n','p','u','t',' ','p','i','n',0};
1332 static const WCHAR wcsOutputPinName
[] = {'o','u','t','p','u','t',' ','p','i','n',0};
1335 TestFilterImpl
* pTestFilter
= NULL
;
1339 pTestFilter
= CoTaskMemAlloc(sizeof(TestFilterImpl
));
1340 if (!pTestFilter
) return E_OUTOFMEMORY
;
1342 pTestFilter
->clsid
= *pClsid
;
1343 pTestFilter
->IBaseFilter_iface
.lpVtbl
= &TestFilter_Vtbl
;
1344 pTestFilter
->refCount
= 1;
1345 InitializeCriticalSection(&pTestFilter
->csFilter
);
1346 pTestFilter
->state
= State_Stopped
;
1348 ZeroMemory(&pTestFilter
->filterInfo
, sizeof(FILTER_INFO
));
1351 while(pinData
[nPins
].mediasubtype
) ++nPins
;
1353 pTestFilter
->ppPins
= CoTaskMemAlloc(nPins
* sizeof(IPin
*));
1354 if (!pTestFilter
->ppPins
)
1359 ZeroMemory(pTestFilter
->ppPins
, nPins
* sizeof(IPin
*));
1361 for (i
= 0; i
< nPins
; i
++)
1363 ZeroMemory(&mt
, sizeof(mt
));
1364 mt
.majortype
= MEDIATYPE_Video
;
1365 mt
.formattype
= FORMAT_None
;
1366 mt
.subtype
= *pinData
[i
].mediasubtype
;
1368 pinInfo
.dir
= pinData
[i
].pinDir
;
1369 pinInfo
.pFilter
= &pTestFilter
->IBaseFilter_iface
;
1370 if (pinInfo
.dir
== PINDIR_INPUT
)
1372 lstrcpynW(pinInfo
.achName
, wcsInputPinName
, sizeof(pinInfo
.achName
) / sizeof(pinInfo
.achName
[0]));
1373 hr
= TestFilter_Pin_Construct(&TestFilter_InputPin_Vtbl
, &pinInfo
, &mt
, &pTestFilter
->csFilter
,
1374 &pTestFilter
->ppPins
[i
]);
1379 lstrcpynW(pinInfo
.achName
, wcsOutputPinName
, sizeof(pinInfo
.achName
) / sizeof(pinInfo
.achName
[0]));
1380 hr
= TestFilter_Pin_Construct(&TestFilter_OutputPin_Vtbl
, &pinInfo
, &mt
, &pTestFilter
->csFilter
,
1381 &pTestFilter
->ppPins
[i
]);
1383 if (FAILED(hr
) || !pTestFilter
->ppPins
[i
]) goto error
;
1386 pTestFilter
->nPins
= nPins
;
1392 if (pTestFilter
->ppPins
)
1394 for (i
= 0; i
< nPins
; i
++)
1396 if (pTestFilter
->ppPins
[i
]) IPin_Release(pTestFilter
->ppPins
[i
]);
1399 CoTaskMemFree(pTestFilter
->ppPins
);
1400 DeleteCriticalSection(&pTestFilter
->csFilter
);
1401 CoTaskMemFree(pTestFilter
);
1406 static HRESULT WINAPI
TestFilter_QueryInterface(IBaseFilter
* iface
, REFIID riid
, LPVOID
* ppv
)
1408 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1412 if (IsEqualIID(riid
, &IID_IUnknown
))
1414 else if (IsEqualIID(riid
, &IID_IPersist
))
1416 else if (IsEqualIID(riid
, &IID_IMediaFilter
))
1418 else if (IsEqualIID(riid
, &IID_IBaseFilter
))
1423 IUnknown_AddRef((IUnknown
*)(*ppv
));
1427 return E_NOINTERFACE
;
1430 static ULONG WINAPI
TestFilter_AddRef(IBaseFilter
* iface
)
1432 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1433 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
1438 static ULONG WINAPI
TestFilter_Release(IBaseFilter
* iface
)
1440 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1441 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
1447 for (i
= 0; i
< This
->nPins
; i
++)
1451 if (SUCCEEDED(IPin_ConnectedTo(This
->ppPins
[i
], &pConnectedTo
)))
1453 IPin_Disconnect(pConnectedTo
);
1454 IPin_Release(pConnectedTo
);
1456 IPin_Disconnect(This
->ppPins
[i
]);
1458 IPin_Release(This
->ppPins
[i
]);
1461 CoTaskMemFree(This
->ppPins
);
1463 DeleteCriticalSection(&This
->csFilter
);
1465 CoTaskMemFree(This
);
1472 /** IPersist methods **/
1474 static HRESULT WINAPI
TestFilter_GetClassID(IBaseFilter
* iface
, CLSID
* pClsid
)
1476 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1478 *pClsid
= This
->clsid
;
1483 /** IMediaFilter methods **/
1485 static HRESULT WINAPI
TestFilter_Stop(IBaseFilter
* iface
)
1490 static HRESULT WINAPI
TestFilter_Pause(IBaseFilter
* iface
)
1495 static HRESULT WINAPI
TestFilter_Run(IBaseFilter
* iface
, REFERENCE_TIME tStart
)
1500 static HRESULT WINAPI
TestFilter_GetState(IBaseFilter
* iface
, DWORD dwMilliSecsTimeout
, FILTER_STATE
*pState
)
1502 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1504 EnterCriticalSection(&This
->csFilter
);
1506 *pState
= This
->state
;
1508 LeaveCriticalSection(&This
->csFilter
);
1513 static HRESULT WINAPI
TestFilter_SetSyncSource(IBaseFilter
* iface
, IReferenceClock
*pClock
)
1518 static HRESULT WINAPI
TestFilter_GetSyncSource(IBaseFilter
* iface
, IReferenceClock
**ppClock
)
1523 /** IBaseFilter implementation **/
1525 static HRESULT
getpin_callback(TestFilterImpl
*tf
, ULONG pos
, IPin
**pin
, DWORD
*lastsynctick
)
1527 /* Our pins are static, not changing so setting static tick count is ok */
1530 if (pos
>= tf
->nPins
)
1533 *pin
= tf
->ppPins
[pos
];
1538 static HRESULT WINAPI
TestFilter_EnumPins(IBaseFilter
* iface
, IEnumPins
**ppEnum
)
1540 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1542 return createenumpins(ppEnum
, getpin_callback
, This
);
1545 static HRESULT WINAPI
TestFilter_FindPin(IBaseFilter
* iface
, LPCWSTR Id
, IPin
**ppPin
)
1550 static HRESULT WINAPI
TestFilter_QueryFilterInfo(IBaseFilter
* iface
, FILTER_INFO
*pInfo
)
1552 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1554 lstrcpyW(pInfo
->achName
, This
->filterInfo
.achName
);
1555 pInfo
->pGraph
= This
->filterInfo
.pGraph
;
1558 IFilterGraph_AddRef(pInfo
->pGraph
);
1563 static HRESULT WINAPI
TestFilter_JoinFilterGraph(IBaseFilter
* iface
, IFilterGraph
*pGraph
, LPCWSTR pName
)
1566 TestFilterImpl
*This
= impl_from_IBaseFilter(iface
);
1568 EnterCriticalSection(&This
->csFilter
);
1571 lstrcpyW(This
->filterInfo
.achName
, pName
);
1573 *This
->filterInfo
.achName
= '\0';
1574 This
->filterInfo
.pGraph
= pGraph
; /* NOTE: do NOT increase ref. count */
1576 LeaveCriticalSection(&This
->csFilter
);
1581 static HRESULT WINAPI
TestFilter_QueryVendorInfo(IBaseFilter
* iface
, LPWSTR
*pVendorInfo
)
1586 static const IBaseFilterVtbl TestFilter_Vtbl
=
1588 TestFilter_QueryInterface
,
1591 TestFilter_GetClassID
,
1595 TestFilter_GetState
,
1596 TestFilter_SetSyncSource
,
1597 TestFilter_GetSyncSource
,
1598 TestFilter_EnumPins
,
1600 TestFilter_QueryFilterInfo
,
1601 TestFilter_JoinFilterGraph
,
1602 TestFilter_QueryVendorInfo
1605 /* IClassFactory implementation */
1607 typedef struct TestClassFactoryImpl
1609 IClassFactory IClassFactory_iface
;
1610 const TestFilterPinData
*filterPinData
;
1612 } TestClassFactoryImpl
;
1614 static inline TestClassFactoryImpl
*impl_from_IClassFactory(IClassFactory
*iface
)
1616 return CONTAINING_RECORD(iface
, TestClassFactoryImpl
, IClassFactory_iface
);
1619 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
1620 LPCLASSFACTORY iface
,
1624 if (ppvObj
== NULL
) return E_POINTER
;
1626 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
1627 IsEqualGUID(riid
, &IID_IClassFactory
))
1630 IClassFactory_AddRef(iface
);
1635 return E_NOINTERFACE
;
1638 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
1640 return 2; /* non-heap-based object */
1643 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
1645 return 1; /* non-heap-based object */
1648 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
1649 LPCLASSFACTORY iface
,
1650 LPUNKNOWN pUnkOuter
,
1654 TestClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
1656 TestFilterImpl
*testfilter
;
1660 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
1662 hr
= createtestfilter(This
->clsid
, This
->filterPinData
, &testfilter
);
1663 if (SUCCEEDED(hr
)) {
1664 hr
= IBaseFilter_QueryInterface(&testfilter
->IBaseFilter_iface
, riid
, ppvObj
);
1665 IBaseFilter_Release(&testfilter
->IBaseFilter_iface
);
1670 static HRESULT WINAPI
Test_IClassFactory_LockServer(
1671 LPCLASSFACTORY iface
,
1677 static IClassFactoryVtbl TestClassFactory_Vtbl
=
1679 Test_IClassFactory_QueryInterface
,
1680 Test_IClassFactory_AddRef
,
1681 Test_IClassFactory_Release
,
1682 Test_IClassFactory_CreateInstance
,
1683 Test_IClassFactory_LockServer
1686 static HRESULT
get_connected_filter_name(TestFilterImpl
*pFilter
, char *FilterName
)
1690 FILTER_INFO filterInfo
;
1695 hr
= IPin_ConnectedTo(pFilter
->ppPins
[0], &pin
);
1696 ok(hr
== S_OK
, "IPin_ConnectedTo failed with %x\n", hr
);
1697 if (FAILED(hr
)) return hr
;
1699 hr
= IPin_QueryPinInfo(pin
, &pinInfo
);
1700 ok(hr
== S_OK
, "IPin_QueryPinInfo failed with %x\n", hr
);
1702 if (FAILED(hr
)) return hr
;
1704 SetLastError(0xdeadbeef);
1705 hr
= IBaseFilter_QueryFilterInfo(pinInfo
.pFilter
, &filterInfo
);
1706 if (hr
== S_OK
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1708 IBaseFilter_Release(pinInfo
.pFilter
);
1711 ok(hr
== S_OK
, "IBaseFilter_QueryFilterInfo failed with %x\n", hr
);
1712 IBaseFilter_Release(pinInfo
.pFilter
);
1713 if (FAILED(hr
)) return hr
;
1715 IFilterGraph_Release(filterInfo
.pGraph
);
1717 WideCharToMultiByte(CP_ACP
, 0, filterInfo
.achName
, -1, FilterName
, MAX_FILTER_NAME
, NULL
, NULL
);
1722 static void test_render_filter_priority(void)
1724 /* Tests filter choice priorities in Render(). */
1725 DWORD cookie1
= 0, cookie2
= 0, cookie3
= 0;
1727 IFilterGraph2
* pgraph2
= NULL
;
1728 IFilterMapper2
*pMapper2
= NULL
;
1729 TestFilterImpl
*ptestfilter
= NULL
;
1730 TestFilterImpl
*ptestfilter2
= NULL
;
1731 static const CLSID CLSID_TestFilter2
= {
1735 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1737 static const CLSID CLSID_TestFilter3
= {
1741 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1743 static const CLSID CLSID_TestFilter4
= {
1747 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1749 static const GUID mediasubtype1
= {
1753 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1755 static const GUID mediasubtype2
= {
1759 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1761 static const TestFilterPinData PinData1
[] = {
1762 { PINDIR_OUTPUT
, &mediasubtype1
},
1765 static const TestFilterPinData PinData2
[] = {
1766 { PINDIR_INPUT
, &mediasubtype1
},
1769 static const TestFilterPinData PinData3
[] = {
1770 { PINDIR_INPUT
, &GUID_NULL
},
1773 static const TestFilterPinData PinData4
[] = {
1774 { PINDIR_INPUT
, &mediasubtype1
},
1775 { PINDIR_OUTPUT
, &mediasubtype2
},
1778 static const TestFilterPinData PinData5
[] = {
1779 { PINDIR_INPUT
, &mediasubtype2
},
1782 TestClassFactoryImpl Filter1ClassFactory
= {
1783 { &TestClassFactory_Vtbl
},
1784 PinData2
, &CLSID_TestFilter2
1786 TestClassFactoryImpl Filter2ClassFactory
= {
1787 { &TestClassFactory_Vtbl
},
1788 PinData4
, &CLSID_TestFilter3
1790 TestClassFactoryImpl Filter3ClassFactory
= {
1791 { &TestClassFactory_Vtbl
},
1792 PinData5
, &CLSID_TestFilter4
1794 char ConnectedFilterName1
[MAX_FILTER_NAME
];
1795 char ConnectedFilterName2
[MAX_FILTER_NAME
];
1797 REGFILTERPINS2 rgPins2
[2];
1798 REGPINTYPES rgPinType
[2];
1799 static const WCHAR wszFilterInstanceName1
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1800 'n', 's', 't', 'a', 'n', 'c', 'e', '1', 0 };
1801 static const WCHAR wszFilterInstanceName2
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1802 'n', 's', 't', 'a', 'n', 'c', 'e', '2', 0 };
1803 static const WCHAR wszFilterInstanceName3
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1804 'n', 's', 't', 'a', 'n', 'c', 'e', '3', 0 };
1805 static const WCHAR wszFilterInstanceName4
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1806 'n', 's', 't', 'a', 'n', 'c', 'e', '4', 0 };
1808 /* Test which renderer of two already added to the graph will be chosen
1809 * (one is "exact" match, other is "wildcard" match. Seems to depend
1810 * on the order in which filters are added to the graph, thus indicating
1811 * no preference given to exact match. */
1812 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
1813 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
1814 if (!pgraph2
) return;
1816 hr
= createtestfilter(&GUID_NULL
, PinData1
, &ptestfilter
);
1817 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1818 if (FAILED(hr
)) goto out
;
1820 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter
->IBaseFilter_iface
, wszFilterInstanceName1
);
1821 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1823 hr
= createtestfilter(&GUID_NULL
, PinData2
, &ptestfilter2
);
1824 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1825 if (FAILED(hr
)) goto out
;
1827 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName2
);
1828 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1830 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1831 ptestfilter2
= NULL
;
1833 hr
= createtestfilter(&GUID_NULL
, PinData3
, &ptestfilter2
);
1834 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1835 if (FAILED(hr
)) goto out
;
1837 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName3
);
1838 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1840 hr
= IFilterGraph2_Render(pgraph2
, ptestfilter
->ppPins
[0]);
1841 ok(hr
== S_OK
, "IFilterGraph2_Render failed with %08x\n", hr
);
1843 hr
= get_connected_filter_name(ptestfilter
, ConnectedFilterName1
);
1845 IFilterGraph2_Release(pgraph2
);
1847 IBaseFilter_Release(&ptestfilter
->IBaseFilter_iface
);
1849 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1850 ptestfilter2
= NULL
;
1852 if (hr
== E_NOTIMPL
)
1854 win_skip("Needed functions are not implemented\n");
1858 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
1859 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
1860 if (!pgraph2
) goto out
;
1862 hr
= createtestfilter(&GUID_NULL
, PinData1
, &ptestfilter
);
1863 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1864 if (FAILED(hr
)) goto out
;
1866 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter
->IBaseFilter_iface
, wszFilterInstanceName1
);
1867 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1869 hr
= createtestfilter(&GUID_NULL
, PinData3
, &ptestfilter2
);
1870 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1871 if (FAILED(hr
)) goto out
;
1873 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName3
);
1874 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1876 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1877 ptestfilter2
= NULL
;
1879 hr
= createtestfilter(&GUID_NULL
, PinData2
, &ptestfilter2
);
1880 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1881 if (FAILED(hr
)) goto out
;
1883 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName2
);
1884 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1886 hr
= IFilterGraph2_Render(pgraph2
, ptestfilter
->ppPins
[0]);
1887 ok(hr
== S_OK
, "IFilterGraph2_Render failed with %08x\n", hr
);
1889 hr
= IFilterGraph2_Disconnect(pgraph2
, NULL
);
1890 ok(hr
== E_POINTER
, "IFilterGraph2_Disconnect failed. Expected E_POINTER, received %08x\n", hr
);
1892 get_connected_filter_name(ptestfilter
, ConnectedFilterName2
);
1893 ok(strcmp(ConnectedFilterName1
, ConnectedFilterName2
),
1894 "expected connected filters to be different but got %s both times\n", ConnectedFilterName1
);
1896 IFilterGraph2_Release(pgraph2
);
1898 IBaseFilter_Release(&ptestfilter
->IBaseFilter_iface
);
1900 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1901 ptestfilter2
= NULL
;
1903 /* Test if any preference is given to existing renderer which renders the pin directly vs
1904 an existing renderer which renders the pin indirectly, through an additional middle filter,
1905 again trying different orders of creation. Native appears not to give a preference. */
1907 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
1908 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
1909 if (!pgraph2
) goto out
;
1911 hr
= createtestfilter(&GUID_NULL
, PinData1
, &ptestfilter
);
1912 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1913 if (FAILED(hr
)) goto out
;
1915 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter
->IBaseFilter_iface
, wszFilterInstanceName1
);
1916 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1918 hr
= createtestfilter(&GUID_NULL
, PinData2
, &ptestfilter2
);
1919 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1920 if (FAILED(hr
)) goto out
;
1922 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName2
);
1923 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1925 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1926 ptestfilter2
= NULL
;
1928 hr
= createtestfilter(&GUID_NULL
, PinData4
, &ptestfilter2
);
1929 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1930 if (FAILED(hr
)) goto out
;
1932 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName3
);
1933 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1935 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1936 ptestfilter2
= NULL
;
1938 hr
= createtestfilter(&GUID_NULL
, PinData5
, &ptestfilter2
);
1939 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1940 if (FAILED(hr
)) goto out
;
1942 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName4
);
1943 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1945 hr
= IFilterGraph2_Render(pgraph2
, ptestfilter
->ppPins
[0]);
1946 ok(hr
== S_OK
, "IFilterGraph2_Render failed with %08x\n", hr
);
1948 get_connected_filter_name(ptestfilter
, ConnectedFilterName1
);
1949 ok(!strcmp(ConnectedFilterName1
, "TestfilterInstance3") || !strcmp(ConnectedFilterName1
, "TestfilterInstance2"),
1950 "unexpected connected filter: %s\n", ConnectedFilterName1
);
1952 IFilterGraph2_Release(pgraph2
);
1954 IBaseFilter_Release(&ptestfilter
->IBaseFilter_iface
);
1956 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1957 ptestfilter2
= NULL
;
1959 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
1960 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
1961 if (!pgraph2
) goto out
;
1963 hr
= createtestfilter(&GUID_NULL
, PinData1
, &ptestfilter
);
1964 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1965 if (FAILED(hr
)) goto out
;
1967 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter
->IBaseFilter_iface
, wszFilterInstanceName1
);
1968 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1970 hr
= createtestfilter(&GUID_NULL
, PinData4
, &ptestfilter2
);
1971 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1972 if (FAILED(hr
)) goto out
;
1974 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName3
);
1975 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1977 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1978 ptestfilter2
= NULL
;
1980 hr
= createtestfilter(&GUID_NULL
, PinData5
, &ptestfilter2
);
1981 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1982 if (FAILED(hr
)) goto out
;
1984 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName4
);
1985 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1987 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
1988 ptestfilter2
= NULL
;
1990 hr
= createtestfilter(&GUID_NULL
, PinData2
, &ptestfilter2
);
1991 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
1992 if (FAILED(hr
)) goto out
;
1994 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter2
->IBaseFilter_iface
, wszFilterInstanceName2
);
1995 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
1997 hr
= IFilterGraph2_Render(pgraph2
, ptestfilter
->ppPins
[0]);
1998 ok(hr
== S_OK
, "IFilterGraph2_Render failed with %08x\n", hr
);
2000 get_connected_filter_name(ptestfilter
, ConnectedFilterName2
);
2001 ok(!strcmp(ConnectedFilterName2
, "TestfilterInstance3") || !strcmp(ConnectedFilterName2
, "TestfilterInstance2"),
2002 "unexpected connected filter: %s\n", ConnectedFilterName2
);
2003 ok(strcmp(ConnectedFilterName1
, ConnectedFilterName2
),
2004 "expected connected filters to be different but got %s both times\n", ConnectedFilterName1
);
2006 IFilterGraph2_Release(pgraph2
);
2008 IBaseFilter_Release(&ptestfilter
->IBaseFilter_iface
);
2010 IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
2011 ptestfilter2
= NULL
;
2013 /* Test if renderers are tried before non-renderers (intermediary filters). */
2014 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
2015 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
2016 if (!pgraph2
) goto out
;
2018 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
2019 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
2020 if (!pMapper2
) goto out
;
2022 hr
= createtestfilter(&GUID_NULL
, PinData1
, &ptestfilter
);
2023 ok(hr
== S_OK
, "createtestfilter failed with %08x\n", hr
);
2024 if (FAILED(hr
)) goto out
;
2026 hr
= IFilterGraph2_AddFilter(pgraph2
, &ptestfilter
->IBaseFilter_iface
, wszFilterInstanceName1
);
2027 ok(hr
== S_OK
, "IFilterGraph2_AddFilter failed with %08x\n", hr
);
2029 /* Register our filters with COM and with Filtermapper. */
2030 hr
= CoRegisterClassObject(Filter1ClassFactory
.clsid
,
2031 (IUnknown
*)&Filter1ClassFactory
.IClassFactory_iface
, CLSCTX_INPROC_SERVER
,
2032 REGCLS_MULTIPLEUSE
, &cookie1
);
2033 ok(hr
== S_OK
, "CoRegisterClassObject failed with %08x\n", hr
);
2034 if (FAILED(hr
)) goto out
;
2035 hr
= CoRegisterClassObject(Filter2ClassFactory
.clsid
,
2036 (IUnknown
*)&Filter2ClassFactory
.IClassFactory_iface
, CLSCTX_INPROC_SERVER
,
2037 REGCLS_MULTIPLEUSE
, &cookie2
);
2038 ok(hr
== S_OK
, "CoRegisterClassObject failed with %08x\n", hr
);
2039 if (FAILED(hr
)) goto out
;
2040 hr
= CoRegisterClassObject(Filter3ClassFactory
.clsid
,
2041 (IUnknown
*)&Filter3ClassFactory
.IClassFactory_iface
, CLSCTX_INPROC_SERVER
,
2042 REGCLS_MULTIPLEUSE
, &cookie3
);
2043 ok(hr
== S_OK
, "CoRegisterClassObject failed with %08x\n", hr
);
2044 if (FAILED(hr
)) goto out
;
2047 rgf2
.dwMerit
= MERIT_UNLIKELY
;
2048 S2(U(rgf2
)).cPins2
= 1;
2049 S2(U(rgf2
)).rgPins2
= rgPins2
;
2050 rgPins2
[0].dwFlags
= REG_PINFLAG_B_RENDERER
;
2051 rgPins2
[0].cInstances
= 1;
2052 rgPins2
[0].nMediaTypes
= 1;
2053 rgPins2
[0].lpMediaType
= &rgPinType
[0];
2054 rgPins2
[0].nMediums
= 0;
2055 rgPins2
[0].lpMedium
= NULL
;
2056 rgPins2
[0].clsPinCategory
= NULL
;
2057 rgPinType
[0].clsMajorType
= &MEDIATYPE_Video
;
2058 rgPinType
[0].clsMinorType
= &mediasubtype1
;
2060 hr
= IFilterMapper2_RegisterFilter(pMapper2
, &CLSID_TestFilter2
, wszFilterInstanceName2
, NULL
,
2061 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
2062 if (hr
== E_ACCESSDENIED
)
2063 skip("Not authorized to register filters\n");
2066 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
2068 rgf2
.dwMerit
= MERIT_PREFERRED
;
2069 rgPinType
[0].clsMinorType
= &mediasubtype2
;
2071 hr
= IFilterMapper2_RegisterFilter(pMapper2
, &CLSID_TestFilter4
, wszFilterInstanceName4
, NULL
,
2072 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
2073 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
2075 S2(U(rgf2
)).cPins2
= 2;
2076 rgPins2
[0].dwFlags
= 0;
2077 rgPinType
[0].clsMinorType
= &mediasubtype1
;
2079 rgPins2
[1].dwFlags
= REG_PINFLAG_B_OUTPUT
;
2080 rgPins2
[1].cInstances
= 1;
2081 rgPins2
[1].nMediaTypes
= 1;
2082 rgPins2
[1].lpMediaType
= &rgPinType
[1];
2083 rgPins2
[1].nMediums
= 0;
2084 rgPins2
[1].lpMedium
= NULL
;
2085 rgPins2
[1].clsPinCategory
= NULL
;
2086 rgPinType
[1].clsMajorType
= &MEDIATYPE_Video
;
2087 rgPinType
[1].clsMinorType
= &mediasubtype2
;
2089 hr
= IFilterMapper2_RegisterFilter(pMapper2
, &CLSID_TestFilter3
, wszFilterInstanceName3
, NULL
,
2090 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
2091 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
2093 hr
= IFilterGraph2_Render(pgraph2
, ptestfilter
->ppPins
[0]);
2094 ok(hr
== S_OK
, "IFilterGraph2_Render failed with %08x\n", hr
);
2096 get_connected_filter_name(ptestfilter
, ConnectedFilterName1
);
2097 ok(!strcmp(ConnectedFilterName1
, "TestfilterInstance3"),
2098 "unexpected connected filter: %s\n", ConnectedFilterName1
);
2100 hr
= IFilterMapper2_UnregisterFilter(pMapper2
, &CLSID_LegacyAmFilterCategory
, NULL
,
2101 &CLSID_TestFilter2
);
2102 ok(hr
== S_OK
, "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
2103 hr
= IFilterMapper2_UnregisterFilter(pMapper2
, &CLSID_LegacyAmFilterCategory
, NULL
,
2104 &CLSID_TestFilter3
);
2105 ok(hr
== S_OK
, "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
2106 hr
= IFilterMapper2_UnregisterFilter(pMapper2
, &CLSID_LegacyAmFilterCategory
, NULL
,
2107 &CLSID_TestFilter4
);
2108 ok(hr
== S_OK
, "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
2113 if (ptestfilter
) IBaseFilter_Release(&ptestfilter
->IBaseFilter_iface
);
2114 if (ptestfilter2
) IBaseFilter_Release(&ptestfilter2
->IBaseFilter_iface
);
2115 if (pgraph2
) IFilterGraph2_Release(pgraph2
);
2116 if (pMapper2
) IFilterMapper2_Release(pMapper2
);
2118 hr
= CoRevokeClassObject(cookie1
);
2119 ok(hr
== S_OK
, "CoRevokeClassObject failed with %08x\n", hr
);
2120 hr
= CoRevokeClassObject(cookie2
);
2121 ok(hr
== S_OK
, "CoRevokeClassObject failed with %08x\n", hr
);
2122 hr
= CoRevokeClassObject(cookie3
);
2123 ok(hr
== S_OK
, "CoRevokeClassObject failed with %08x\n", hr
);
2126 typedef struct IUnknownImpl
2128 IUnknown IUnknown_iface
;
2133 static IUnknownImpl
*IUnknownImpl_from_iface(IUnknown
* iface
)
2135 return CONTAINING_RECORD(iface
, IUnknownImpl
, IUnknown_iface
);
2138 static HRESULT WINAPI
IUnknownImpl_QueryInterface(IUnknown
* iface
, REFIID riid
, LPVOID
* ppv
)
2140 ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid
));
2141 return E_NOINTERFACE
;
2144 static ULONG WINAPI
IUnknownImpl_AddRef(IUnknown
* iface
)
2146 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
2147 This
->AddRef_called
++;
2151 static ULONG WINAPI
IUnknownImpl_Release(IUnknown
* iface
)
2153 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
2154 This
->Release_called
++;
2158 static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl
=
2160 IUnknownImpl_QueryInterface
,
2161 IUnknownImpl_AddRef
,
2162 IUnknownImpl_Release
2165 static void test_aggregate_filter_graph(void)
2170 IUnknownImpl unk_outer
= { { &IUnknownImpl_Vtbl
}, 0, 0 };
2172 hr
= CoCreateInstance(&CLSID_FilterGraph
, &unk_outer
.IUnknown_iface
, CLSCTX_INPROC_SERVER
,
2173 &IID_IUnknown
, (void **)&pgraph
);
2174 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
2175 ok(pgraph
!= &unk_outer
.IUnknown_iface
, "pgraph = %p, expected not %p\n", pgraph
, &unk_outer
.IUnknown_iface
);
2177 hr
= IUnknown_QueryInterface(pgraph
, &IID_IUnknown
, (void **)&punk
);
2178 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
2179 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
2180 IUnknown_Release(punk
);
2182 ok(unk_outer
.AddRef_called
== 0, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
2183 ok(unk_outer
.Release_called
== 0, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
2184 unk_outer
.AddRef_called
= 0;
2185 unk_outer
.Release_called
= 0;
2187 hr
= IUnknown_QueryInterface(pgraph
, &IID_IFilterMapper
, (void **)&punk
);
2188 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
2189 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
2190 IUnknown_Release(punk
);
2192 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
2193 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
2194 unk_outer
.AddRef_called
= 0;
2195 unk_outer
.Release_called
= 0;
2197 hr
= IUnknown_QueryInterface(pgraph
, &IID_IFilterMapper2
, (void **)&punk
);
2198 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
2199 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
2200 IUnknown_Release(punk
);
2202 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
2203 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
2204 unk_outer
.AddRef_called
= 0;
2205 unk_outer
.Release_called
= 0;
2207 hr
= IUnknown_QueryInterface(pgraph
, &IID_IFilterMapper3
, (void **)&punk
);
2208 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
2209 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
2210 IUnknown_Release(punk
);
2212 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
2213 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
2215 IUnknown_Release(pgraph
);
2218 START_TEST(filtergraph
)
2221 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
2222 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
2223 &IID_IGraphBuilder
, (LPVOID
*)&pgraph
);
2225 skip("Creating filtergraph returned %08x, skipping tests\n", hr
);
2228 IGraphBuilder_Release(pgraph
);
2229 test_render_run(avifile
);
2230 test_render_run(mpegfile
);
2231 test_graph_builder();
2232 test_graph_builder_addfilter();
2233 test_mediacontrol();
2234 test_filter_graph2();
2235 test_render_filter_priority();
2236 test_aggregate_filter_graph();