ReactOS 0.4.15-dev-8145-ga541a46
filtergraph.c
Go to the documentation of this file.
1/*
2 * Unit tests for Direct Show functions
3 *
4 * Copyright (C) 2004 Christian Costa
5 * Copyright (C) 2008 Alexander Dorofeyev
6 *
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.
11 *
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.
16 *
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
20 */
21
22#define COBJMACROS
23#define CONST_VTABLE
24
25#include "wine/test.h"
26#include "dshow.h"
27#include "control.h"
28
29typedef struct TestFilterImpl
30{
32
35 FILTER_STATE state;
36 FILTER_INFO filterInfo;
41
42static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0};
43static const WCHAR mpegfile[] = {'t','e','s','t','.','m','p','g',0};
44
46{
47 static WCHAR pathW[MAX_PATH];
48 DWORD written;
50 HRSRC res;
51 void *ptr;
52
53 GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
54 lstrcatW(pathW, name);
55
57 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW),
58 GetLastError());
59
61 ok( res != 0, "couldn't find resource\n" );
64 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
66
67 return pathW;
68}
69
71{
73 HRESULT hr;
74 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&ret);
75 ok(hr == S_OK, "Failed to create FilterGraph: %#x\n", hr);
76 return ret;
77}
78
80{
81 IBasicVideo* pbv;
82 LONG video_width, video_height, window_width;
84 HRESULT hr;
85
86 hr = IFilterGraph2_QueryInterface(graph, &IID_IBasicVideo, (void **)&pbv);
87 ok(hr==S_OK, "Cannot get IBasicVideo interface returned: %x\n", hr);
88
89 /* test get video size */
90 hr = IBasicVideo_GetVideoSize(pbv, NULL, NULL);
91 ok(hr==E_POINTER, "IBasicVideo_GetVideoSize returned: %x\n", hr);
92 hr = IBasicVideo_GetVideoSize(pbv, &video_width, NULL);
93 ok(hr==E_POINTER, "IBasicVideo_GetVideoSize returned: %x\n", hr);
94 hr = IBasicVideo_GetVideoSize(pbv, NULL, &video_height);
95 ok(hr==E_POINTER, "IBasicVideo_GetVideoSize returned: %x\n", hr);
96 hr = IBasicVideo_GetVideoSize(pbv, &video_width, &video_height);
97 ok(hr==S_OK, "Cannot get video size returned: %x\n", hr);
98
99 /* test source position */
100 hr = IBasicVideo_GetSourcePosition(pbv, NULL, NULL, NULL, NULL);
101 ok(hr == E_POINTER, "IBasicVideo_GetSourcePosition returned: %x\n", hr);
102 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, NULL, NULL);
103 ok(hr == E_POINTER, "IBasicVideo_GetSourcePosition returned: %x\n", hr);
104 hr = IBasicVideo_GetSourcePosition(pbv, NULL, NULL, &width, &height);
105 ok(hr == E_POINTER, "IBasicVideo_GetSourcePosition returned: %x\n", hr);
106 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
107 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
108 ok(left == 0, "expected 0, got %d\n", left);
109 ok(top == 0, "expected 0, got %d\n", top);
110 ok(width == video_width, "expected %d, got %d\n", video_width, width);
111 ok(height == video_height, "expected %d, got %d\n", video_height, height);
112
113 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, 0, 0);
114 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
115 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width*2, video_height*2);
116 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
117 hr = IBasicVideo_put_SourceTop(pbv, -1);
118 ok(hr==E_INVALIDARG, "IBasicVideo_put_SourceTop returned: %x\n", hr);
119 hr = IBasicVideo_put_SourceTop(pbv, 0);
120 ok(hr==S_OK, "Cannot put source top returned: %x\n", hr);
121 hr = IBasicVideo_put_SourceTop(pbv, 1);
122 ok(hr==E_INVALIDARG, "IBasicVideo_put_SourceTop returned: %x\n", hr);
123
124 hr = IBasicVideo_SetSourcePosition(pbv, video_width, 0, video_width, video_height);
125 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
126 hr = IBasicVideo_SetSourcePosition(pbv, 0, video_height, video_width, video_height);
127 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
128 hr = IBasicVideo_SetSourcePosition(pbv, -1, 0, video_width, video_height);
129 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
130 hr = IBasicVideo_SetSourcePosition(pbv, 0, -1, video_width, video_height);
131 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
132 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width, video_height);
133 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
134 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width, video_height);
135 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
136
137 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width, video_height+1);
138 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
139 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width+1, video_height);
140 ok(hr==E_INVALIDARG, "IBasicVideo_SetSourcePosition returned: %x\n", hr);
141
142 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width/3+1, video_height/3+1);
143 ok(hr==S_OK, "Cannot set source position returned: %x\n", hr);
144
145 hr = IBasicVideo_get_SourceLeft(pbv, &left);
146 ok(hr==S_OK, "Cannot get source left returned: %x\n", hr);
147 ok(left==video_width/2, "expected %d, got %d\n", video_width/2, left);
148 hr = IBasicVideo_get_SourceTop(pbv, &top);
149 ok(hr==S_OK, "Cannot get source top returned: %x\n", hr);
150 ok(top==video_height/2, "expected %d, got %d\n", video_height/2, top);
151 hr = IBasicVideo_get_SourceWidth(pbv, &width);
152 ok(hr==S_OK, "Cannot get source width returned: %x\n", hr);
153 ok(width==video_width/3+1, "expected %d, got %d\n", video_width/3+1, width);
154 hr = IBasicVideo_get_SourceHeight(pbv, &height);
155 ok(hr==S_OK, "Cannot get source height returned: %x\n", hr);
156 ok(height==video_height/3+1, "expected %d, got %d\n", video_height/3+1, height);
157
158 hr = IBasicVideo_put_SourceLeft(pbv, video_width/3);
159 ok(hr==S_OK, "Cannot put source left returned: %x\n", hr);
160 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
161 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
162 ok(left == video_width/3, "expected %d, got %d\n", video_width/3, left);
163 ok(width == video_width/3+1, "expected %d, got %d\n", video_width/3+1, width);
164
165 hr = IBasicVideo_put_SourceTop(pbv, video_height/3);
166 ok(hr==S_OK, "Cannot put source top returned: %x\n", hr);
167 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
168 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
169 ok(top == video_height/3, "expected %d, got %d\n", video_height/3, top);
170 ok(height == video_height/3+1, "expected %d, got %d\n", video_height/3+1, height);
171
172 hr = IBasicVideo_put_SourceWidth(pbv, video_width/4+1);
173 ok(hr==S_OK, "Cannot put source width returned: %x\n", hr);
174 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
175 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
176 ok(left == video_width/3, "expected %d, got %d\n", video_width/3, left);
177 ok(width == video_width/4+1, "expected %d, got %d\n", video_width/4+1, width);
178
179 hr = IBasicVideo_put_SourceHeight(pbv, video_height/4+1);
180 ok(hr==S_OK, "Cannot put source height returned: %x\n", hr);
181 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
182 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
183 ok(top == video_height/3, "expected %d, got %d\n", video_height/3, top);
184 ok(height == video_height/4+1, "expected %d, got %d\n", video_height/4+1, height);
185
186 /* test destination rectangle */
187 window_width = max(video_width, GetSystemMetrics(SM_CXMIN) - 2 * GetSystemMetrics(SM_CXFRAME));
188
189 hr = IBasicVideo_GetDestinationPosition(pbv, NULL, NULL, NULL, NULL);
190 ok(hr == E_POINTER, "IBasicVideo_GetDestinationPosition returned: %x\n", hr);
191 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, NULL, NULL);
192 ok(hr == E_POINTER, "IBasicVideo_GetDestinationPosition returned: %x\n", hr);
193 hr = IBasicVideo_GetDestinationPosition(pbv, NULL, NULL, &width, &height);
194 ok(hr == E_POINTER, "IBasicVideo_GetDestinationPosition returned: %x\n", hr);
195 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
196 ok(hr == S_OK, "Cannot get destination position returned: %x\n", hr);
197 ok(left == 0, "expected 0, got %d\n", left);
198 ok(top == 0, "expected 0, got %d\n", top);
199 todo_wine ok(width == window_width, "expected %d, got %d\n", window_width, width);
200 todo_wine ok(height == video_height, "expected %d, got %d\n", video_height, height);
201
202 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, 0, 0);
203 ok(hr==E_INVALIDARG, "IBasicVideo_SetDestinationPosition returned: %x\n", hr);
204 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width*2, video_height*2);
205 ok(hr==S_OK, "Cannot put destination position returned: %x\n", hr);
206
207 hr = IBasicVideo_put_DestinationLeft(pbv, -1);
208 ok(hr==S_OK, "Cannot put destination left returned: %x\n", hr);
209 hr = IBasicVideo_put_DestinationLeft(pbv, 0);
210 ok(hr==S_OK, "Cannot put destination left returned: %x\n", hr);
211 hr = IBasicVideo_put_DestinationLeft(pbv, 1);
212 ok(hr==S_OK, "Cannot put destination left returned: %x\n", hr);
213
214 hr = IBasicVideo_SetDestinationPosition(pbv, video_width, 0, video_width, video_height);
215 ok(hr==S_OK, "Cannot set destinaiton position returned: %x\n", hr);
216 hr = IBasicVideo_SetDestinationPosition(pbv, 0, video_height, video_width, video_height);
217 ok(hr==S_OK, "Cannot set destinaiton position returned: %x\n", hr);
218 hr = IBasicVideo_SetDestinationPosition(pbv, -1, 0, video_width, video_height);
219 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
220 hr = IBasicVideo_SetDestinationPosition(pbv, 0, -1, video_width, video_height);
221 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
222 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width, video_height);
223 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
224 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width, video_height);
225 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
226
227 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width, video_height+1);
228 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
229 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width+1, video_height);
230 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
231
232 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width/3+1, video_height/3+1);
233 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
234
235 hr = IBasicVideo_get_DestinationLeft(pbv, &left);
236 ok(hr==S_OK, "Cannot get destination left returned: %x\n", hr);
237 ok(left==video_width/2, "expected %d, got %d\n", video_width/2, left);
238 hr = IBasicVideo_get_DestinationTop(pbv, &top);
239 ok(hr==S_OK, "Cannot get destination top returned: %x\n", hr);
240 ok(top==video_height/2, "expected %d, got %d\n", video_height/2, top);
241 hr = IBasicVideo_get_DestinationWidth(pbv, &width);
242 ok(hr==S_OK, "Cannot get destination width returned: %x\n", hr);
243 ok(width==video_width/3+1, "expected %d, got %d\n", video_width/3+1, width);
244 hr = IBasicVideo_get_DestinationHeight(pbv, &height);
245 ok(hr==S_OK, "Cannot get destination height returned: %x\n", hr);
246 ok(height==video_height/3+1, "expected %d, got %d\n", video_height/3+1, height);
247
248 hr = IBasicVideo_put_DestinationLeft(pbv, video_width/3);
249 ok(hr==S_OK, "Cannot put destination left returned: %x\n", hr);
250 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
251 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
252 ok(left == video_width/3, "expected %d, got %d\n", video_width/3, left);
253 ok(width == video_width/3+1, "expected %d, got %d\n", video_width/3+1, width);
254
255 hr = IBasicVideo_put_DestinationTop(pbv, video_height/3);
256 ok(hr==S_OK, "Cannot put destination top returned: %x\n", hr);
257 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
258 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
259 ok(top == video_height/3, "expected %d, got %d\n", video_height/3, top);
260 ok(height == video_height/3+1, "expected %d, got %d\n", video_height/3+1, height);
261
262 hr = IBasicVideo_put_DestinationWidth(pbv, video_width/4+1);
263 ok(hr==S_OK, "Cannot put destination width returned: %x\n", hr);
264 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
265 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
266 ok(left == video_width/3, "expected %d, got %d\n", video_width/3, left);
267 ok(width == video_width/4+1, "expected %d, got %d\n", video_width/4+1, width);
268
269 hr = IBasicVideo_put_DestinationHeight(pbv, video_height/4+1);
270 ok(hr==S_OK, "Cannot put destination height returned: %x\n", hr);
271 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
272 ok(hr == S_OK, "Cannot get source position returned: %x\n", hr);
273 ok(top == video_height/3, "expected %d, got %d\n", video_height/3, top);
274 ok(height == video_height/4+1, "expected %d, got %d\n", video_height/4+1, height);
275
276 /* reset source rectangle */
277 hr = IBasicVideo_SetDefaultSourcePosition(pbv);
278 ok(hr==S_OK, "IBasicVideo_SetDefaultSourcePosition returned: %x\n", hr);
279
280 /* reset destination position */
281 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width, video_height);
282 ok(hr==S_OK, "Cannot set destination position returned: %x\n", hr);
283
284 IBasicVideo_Release(pbv);
285}
286
288{
289 IMediaSeeking *seeking;
291 LONGLONG pos, stop, duration;
292 GUID format;
293 HRESULT hr;
294
295 IFilterGraph2_SetDefaultSyncSource(graph);
296 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
297 ok(hr == S_OK, "QueryInterface(IMediaControl) failed: %08x\n", hr);
298
299 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
300 ok(hr == S_OK, "QueryInterface(IMediaFilter) failed: %08x\n", hr);
301
303 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
304 ok(hr == S_OK, "GetTimeFormat failed: %#x\n", hr);
305 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "got %s\n", wine_dbgstr_guid(&format));
306
307 pos = 0xdeadbeef;
308 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, NULL);
309 ok(hr == S_OK, "ConvertTimeFormat failed: %#x\n", hr);
310 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
311
312 pos = 0xdeadbeef;
313 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, NULL);
314 ok(hr == S_OK, "ConvertTimeFormat failed: %#x\n", hr);
315 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
316
317 pos = 0xdeadbeef;
318 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
319 ok(hr == S_OK, "ConvertTimeFormat failed: %#x\n", hr);
320 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
321
322 hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
323 ok(hr == S_OK, "GetCurrentPosition failed: %#x\n", hr);
324 ok(pos == 0, "got %s\n", wine_dbgstr_longlong(pos));
325
326 hr = IMediaSeeking_GetDuration(seeking, &duration);
327 ok(hr == S_OK, "GetDuration failed: %#x\n", hr);
328 ok(duration > 0, "got %s\n", wine_dbgstr_longlong(duration));
329
330 hr = IMediaSeeking_GetStopPosition(seeking, &stop);
331 ok(hr == S_OK, "GetCurrentPosition failed: %08x\n", hr);
332 ok(stop == duration || stop == duration + 1, "expected %s, got %s\n",
334
335 hr = IMediaSeeking_SetPositions(seeking, NULL, AM_SEEKING_ReturnTime, NULL, AM_SEEKING_NoPositioning);
336 ok(hr == S_OK, "SetPositions failed: %#x\n", hr);
337 hr = IMediaSeeking_SetPositions(seeking, NULL, AM_SEEKING_NoPositioning, NULL, AM_SEEKING_ReturnTime);
338 ok(hr == S_OK, "SetPositions failed: %#x\n", hr);
339
340 pos = 0;
341 hr = IMediaSeeking_SetPositions(seeking, &pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
342 ok(hr == S_OK, "SetPositions failed: %08x\n", hr);
343
344 IMediaFilter_SetSyncSource(filter, NULL);
345 pos = 0xdeadbeef;
346 hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
347 ok(hr == S_OK, "GetCurrentPosition failed: %08x\n", hr);
348 ok(pos == 0, "Position != 0 (%s)\n", wine_dbgstr_longlong(pos));
349 IFilterGraph2_SetDefaultSyncSource(graph);
350
351 IMediaSeeking_Release(seeking);
352 IMediaFilter_Release(filter);
353}
354
356{
357 IMediaControl *control;
358 OAFilterState state;
359 HRESULT hr;
360
361 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
362 ok(hr == S_OK, "QueryInterface(IMediaControl) failed: %x\n", hr);
363
364 hr = IMediaControl_GetState(control, 1000, &state);
365 ok(hr == S_OK, "GetState() failed: %x\n", hr);
366 ok(state == State_Stopped, "wrong state %d\n", state);
367
368 hr = IMediaControl_Run(control);
369 ok(SUCCEEDED(hr), "Run() failed: %x\n", hr);
370 hr = IMediaControl_GetState(control, INFINITE, &state);
371 ok(SUCCEEDED(hr), "GetState() failed: %x\n", hr);
372 ok(state == State_Running, "wrong state %d\n", state);
373
374 hr = IMediaControl_Stop(control);
375 ok(SUCCEEDED(hr), "Stop() failed: %x\n", hr);
376 hr = IMediaControl_GetState(control, 1000, &state);
377 ok(hr == S_OK, "GetState() failed: %x\n", hr);
378 ok(state == State_Stopped, "wrong state %d\n", state);
379
380 hr = IMediaControl_Pause(control);
381 ok(SUCCEEDED(hr), "Pause() failed: %x\n", hr);
382 hr = IMediaControl_GetState(control, 1000, &state);
383 ok(hr == S_OK, "GetState() failed: %x\n", hr);
384 ok(state == State_Paused, "wrong state %d\n", state);
385
386 hr = IMediaControl_Run(control);
387 ok(SUCCEEDED(hr), "Run() failed: %x\n", hr);
388 hr = IMediaControl_GetState(control, 1000, &state);
389 ok(hr == S_OK, "GetState() failed: %x\n", hr);
390 ok(state == State_Running, "wrong state %d\n", state);
391
392 hr = IMediaControl_Pause(control);
393 ok(SUCCEEDED(hr), "Pause() failed: %x\n", hr);
394 hr = IMediaControl_GetState(control, 1000, &state);
395 ok(hr == S_OK, "GetState() failed: %x\n", hr);
396 ok(state == State_Paused, "wrong state %d\n", state);
397
398 hr = IMediaControl_Stop(control);
399 ok(SUCCEEDED(hr), "Stop() failed: %x\n", hr);
400 hr = IMediaControl_GetState(control, 1000, &state);
401 ok(hr == S_OK, "GetState() failed: %x\n", hr);
402 ok(state == State_Stopped, "wrong state %d\n", state);
403
404 IMediaControl_Release(control);
405}
406
408{
409 IMediaEvent *media_event;
410 IMediaSeeking *seeking;
411 IMediaControl *control;
413 LONG_PTR lparam1, lparam2;
414 LONGLONG current, stop;
415 OAFilterState state;
416 int got_eos = 0;
418 HRESULT hr;
419 LONG code;
420
421 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
422 ok(hr == S_OK, "QueryInterface(IMediaFilter) failed: %#x\n", hr);
423
424 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
425 ok(hr == S_OK, "QueryInterface(IMediaControl) failed: %#x\n", hr);
426
427 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&media_event);
428 ok(hr == S_OK, "QueryInterface(IMediaEvent) failed: %#x\n", hr);
429
430 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
431 ok(hr == S_OK, "QueryInterface(IMediaEvent) failed: %#x\n", hr);
432
433 hr = IMediaControl_Stop(control);
434 ok(SUCCEEDED(hr), "Stop() failed: %#x\n", hr);
435 hr = IMediaControl_GetState(control, 1000, &state);
436 ok(hr == S_OK, "GetState() timed out\n");
437
438 hr = IMediaSeeking_GetDuration(seeking, &stop);
439 ok(hr == S_OK, "GetDuration() failed: %#x\n", hr);
440 current = 0;
441 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning, &stop, AM_SEEKING_AbsolutePositioning);
442 ok(hr == S_OK, "SetPositions() failed: %#x\n", hr);
443
444 hr = IMediaFilter_SetSyncSource(filter, NULL);
445 ok(hr == S_OK, "SetSyncSource() failed: %#x\n", hr);
446
447 hr = IMediaEvent_GetEventHandle(media_event, (OAEVENT *)&event);
448 ok(hr == S_OK, "GetEventHandle() failed: %#x\n", hr);
449
450 /* flush existing events */
451 while ((hr = IMediaEvent_GetEvent(media_event, &code, &lparam1, &lparam2, 0)) == S_OK);
452
453 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "event should not be signaled\n");
454
455 hr = IMediaControl_Run(control);
456 ok(SUCCEEDED(hr), "Run() failed: %#x\n", hr);
457
458 while (!got_eos)
459 {
461 break;
462
463 while ((hr = IMediaEvent_GetEvent(media_event, &code, &lparam1, &lparam2, 0)) == S_OK)
464 {
465 if (code == EC_COMPLETE)
466 {
467 got_eos = 1;
468 break;
469 }
470 }
471 }
472 ok(got_eos, "didn't get EOS\n");
473
474 hr = IMediaSeeking_GetCurrentPosition(seeking, &current);
475 ok(hr == S_OK, "GetCurrentPosition() failed: %#x\n", hr);
477 ok(current == stop, "expected %s, got %s\n", wine_dbgstr_longlong(stop), wine_dbgstr_longlong(current));
478
479 hr = IMediaControl_Stop(control);
480 ok(SUCCEEDED(hr), "Run() failed: %#x\n", hr);
481 hr = IMediaControl_GetState(control, 1000, &state);
482 ok(hr == S_OK, "GetState() timed out\n");
483
484 hr = IFilterGraph2_SetDefaultSyncSource(graph);
485 ok(hr == S_OK, "SetDefaultSinkSource() failed: %#x\n", hr);
486
487 IMediaSeeking_Release(seeking);
488 IMediaEvent_Release(media_event);
489 IMediaControl_Release(control);
490 IMediaFilter_Release(filter);
491}
492
493static void rungraph(IFilterGraph2 *graph)
494{
495 test_basic_video(graph);
496 test_media_seeking(graph);
497 test_state_change(graph);
498 test_media_event(graph);
499}
500
502{
503 static const WCHAR outputW[] = {'O','u','t','p','u','t',0};
504 static const WCHAR inW[] = {'I','n',0};
505 IBaseFilter *source_filter, *video_filter;
506 IPin *pin_in, *pin_out;
507 IFilterGraph2 *graph;
508 IVideoWindow *window;
509 HRESULT hr;
510
511 graph = create_graph();
512
513 hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, &IID_IVideoWindow, (void **)&window);
514 ok(hr == S_OK, "Failed to create VideoRenderer: %#x\n", hr);
515
516 hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &source_filter);
517 ok(hr == S_OK, "AddSourceFilter failed: %#x\n", hr);
518
519 hr = IVideoWindow_QueryInterface(window, &IID_IBaseFilter, (void **)&video_filter);
520 ok(hr == S_OK, "QueryInterface(IBaseFilter) failed: %#x\n", hr);
521 hr = IFilterGraph2_AddFilter(graph, video_filter, NULL);
522 ok(hr == S_OK, "AddFilter failed: %#x\n", hr);
523
524 hr = IBaseFilter_FindPin(source_filter, outputW, &pin_out);
525 ok(hr == S_OK, "FindPin failed: %#x\n", hr);
526 hr = IBaseFilter_FindPin(video_filter, inW, &pin_in);
527 ok(hr == S_OK, "FindPin failed: %#x\n", hr);
528 hr = IFilterGraph2_Connect(graph, pin_out, pin_in);
529
530 if (SUCCEEDED(hr))
531 rungraph(graph);
532
533 IPin_Release(pin_in);
534 IPin_Release(pin_out);
535 IBaseFilter_Release(source_filter);
536 IBaseFilter_Release(video_filter);
537 IVideoWindow_Release(window);
538 IFilterGraph2_Release(graph);
539
540 return hr;
541}
542
543static void test_render_run(const WCHAR *file)
544{
545 IFilterGraph2 *graph;
546 HANDLE h;
547 HRESULT hr;
548 LONG refs;
550
552 if (h == INVALID_HANDLE_VALUE) {
553 skip("Could not read test file %s, skipping test\n", wine_dbgstr_w(file));
555 return;
556 }
557 CloseHandle(h);
558
559 trace("running %s\n", wine_dbgstr_w(file));
560
561 graph = create_graph();
562
563 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
564 if (FAILED(hr))
565 {
566 skip("%s: codec not supported; skipping test\n", wine_dbgstr_w(file));
567
568 refs = IFilterGraph2_Release(graph);
569 ok(!refs, "Graph has %u references\n", refs);
570
573 ok(hr == VFW_E_CANNOT_CONNECT, "got %#x\n", hr);
574 }
575 else
576 {
577 ok(hr == S_OK || hr == VFW_S_AUDIO_NOT_RENDERED, "RenderFile failed: %x\n", hr);
578 rungraph(graph);
579
580 refs = IFilterGraph2_Release(graph);
581 ok(!refs, "Graph has %u references\n", refs);
582
584 ok(hr == S_OK || hr == VFW_S_PARTIAL_RENDER, "got %#x\n", hr);
585 }
586
587 /* check reference leaks */
589 ok(h != INVALID_HANDLE_VALUE, "CreateFile failed: err=%d\n", GetLastError());
590 CloseHandle(h);
591
593}
594
596{
598 IFilterGraph2 *graph = lParam;
599 HRESULT hr;
600
601 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
603 ok(SUCCEEDED(hr), "RenderFile failed: %x\n", hr);
604
605 if (SUCCEEDED(hr))
606 rungraph(graph);
607
608 return 0;
609}
610
612{
613 IFilterGraph2 *graph;
615
617
618 graph = create_graph();
619
621
622 ok(WaitForSingleObject(thread, 1000) == WAIT_OBJECT_0, "wait failed\n");
623 IFilterGraph2_Release(graph);
626}
627
628static void test_graph_builder(void)
629{
630 HRESULT hr;
631 IGraphBuilder *pgraph;
632 IBaseFilter *pF = NULL;
633 IBaseFilter *pF2 = NULL;
634 IPin *pIn = NULL;
635 IEnumPins *pEnum = NULL;
637 static const WCHAR testFilterW[] = {'t','e','s','t','F','i','l','t','e','r',0};
638 static const WCHAR fooBarW[] = {'f','o','o','B','a','r',0};
639
640 pgraph = (IGraphBuilder *)create_graph();
641
642 /* create video filter */
643 hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
644 &IID_IBaseFilter, (LPVOID*)&pF);
645 ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr);
646 ok(pF != NULL, "pF is NULL\n");
647
648 hr = IGraphBuilder_AddFilter(pgraph, NULL, testFilterW);
649 ok(hr == E_POINTER, "IGraphBuilder_AddFilter returned %x\n", hr);
650
651 /* add the two filters to the graph */
652 hr = IGraphBuilder_AddFilter(pgraph, pF, testFilterW);
653 ok(hr == S_OK, "failed to add pF to the graph: %x\n", hr);
654
655 /* find the pins */
656 hr = IBaseFilter_EnumPins(pF, &pEnum);
657 ok(hr == S_OK, "IBaseFilter_EnumPins failed for pF: %x\n", hr);
658 ok(pEnum != NULL, "pEnum is NULL\n");
659 hr = IEnumPins_Next(pEnum, 1, &pIn, NULL);
660 ok(hr == S_OK, "IEnumPins_Next failed for pF: %x\n", hr);
661 ok(pIn != NULL, "pIn is NULL\n");
662 hr = IPin_QueryDirection(pIn, &dir);
663 ok(hr == S_OK, "IPin_QueryDirection failed: %x\n", hr);
664 ok(dir == PINDIR_INPUT, "pin has wrong direction\n");
665
666 hr = IGraphBuilder_FindFilterByName(pgraph, fooBarW, &pF2);
667 ok(hr == VFW_E_NOT_FOUND, "IGraphBuilder_FindFilterByName returned %x\n", hr);
668 ok(pF2 == NULL, "IGraphBuilder_FindFilterByName returned %p\n", pF2);
669 hr = IGraphBuilder_FindFilterByName(pgraph, testFilterW, &pF2);
670 ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned %x\n", hr);
671 ok(pF2 != NULL, "IGraphBuilder_FindFilterByName returned NULL\n");
672 hr = IGraphBuilder_FindFilterByName(pgraph, testFilterW, NULL);
673 ok(hr == E_POINTER, "IGraphBuilder_FindFilterByName returned %x\n", hr);
674
675 hr = IGraphBuilder_Connect(pgraph, NULL, pIn);
676 ok(hr == E_POINTER, "IGraphBuilder_Connect returned %x\n", hr);
677
678 hr = IGraphBuilder_Connect(pgraph, pIn, NULL);
679 ok(hr == E_POINTER, "IGraphBuilder_Connect returned %x\n", hr);
680
681 hr = IGraphBuilder_Connect(pgraph, pIn, pIn);
682 ok(hr == VFW_E_CANNOT_CONNECT, "IGraphBuilder_Connect returned %x\n", hr);
683
684 if (pIn) IPin_Release(pIn);
685 if (pEnum) IEnumPins_Release(pEnum);
686 if (pF) IBaseFilter_Release(pF);
687 if (pF2) IBaseFilter_Release(pF2);
688 IGraphBuilder_Release(pgraph);
689}
690
691/* IEnumMediaTypes implementation (supporting code for Render() test.) */
692static void FreeMediaType(AM_MEDIA_TYPE * pMediaType)
693{
694 if (pMediaType->pbFormat)
695 {
696 CoTaskMemFree(pMediaType->pbFormat);
697 pMediaType->pbFormat = NULL;
698 }
699 if (pMediaType->pUnk)
700 {
701 IUnknown_Release(pMediaType->pUnk);
702 pMediaType->pUnk = NULL;
703 }
704}
705
707{
708 *pDest = *pSrc;
709 if (!pSrc->pbFormat) return S_OK;
710 if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat)))
711 return E_OUTOFMEMORY;
712 memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat);
713 if (pDest->pUnk)
714 IUnknown_AddRef(pDest->pUnk);
715 return S_OK;
716}
717
719{
720 AM_MEDIA_TYPE * pDest;
721
722 pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
723 if (!pDest)
724 return NULL;
725
726 if (FAILED(CopyMediaType(pDest, pSrc)))
727 {
728 CoTaskMemFree(pDest);
729 return NULL;
730 }
731
732 return pDest;
733}
734
735static BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards)
736{
737 return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) &&
738 ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || IsEqualGUID(&pmt1->subtype, &pmt2->subtype)));
739}
740
741static void DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
742{
743 FreeMediaType(pMediaType);
744 CoTaskMemFree(pMediaType);
745}
746
748{
755
756static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
757
759{
760 return CONTAINING_RECORD(iface, IEnumMediaTypesImpl, IEnumMediaTypes_iface);
761}
762
763static HRESULT IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE * pMediaTypes, ULONG cMediaTypes, IEnumMediaTypes ** ppEnum)
764{
765 ULONG i;
766 IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
767
768 if (!pEnumMediaTypes)
769 {
770 *ppEnum = NULL;
771 return E_OUTOFMEMORY;
772 }
773 pEnumMediaTypes->IEnumMediaTypes_iface.lpVtbl = &IEnumMediaTypesImpl_Vtbl;
774 pEnumMediaTypes->refCount = 1;
775 pEnumMediaTypes->uIndex = 0;
776 pEnumMediaTypes->cMediaTypes = cMediaTypes;
777 pEnumMediaTypes->pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * cMediaTypes);
778 for (i = 0; i < cMediaTypes; i++)
779 if (FAILED(CopyMediaType(&pEnumMediaTypes->pMediaTypes[i], &pMediaTypes[i])))
780 {
781 while (i--)
782 FreeMediaType(&pEnumMediaTypes->pMediaTypes[i]);
783 CoTaskMemFree(pEnumMediaTypes->pMediaTypes);
784 return E_OUTOFMEMORY;
785 }
786 *ppEnum = &pEnumMediaTypes->IEnumMediaTypes_iface;
787 return S_OK;
788}
789
791{
792 *ppv = NULL;
793
795 *ppv = iface;
796 else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
797 *ppv = iface;
798
799 if (*ppv)
800 {
801 IUnknown_AddRef((IUnknown *)(*ppv));
802 return S_OK;
803 }
804
805 return E_NOINTERFACE;
806}
807
809{
811 ULONG refCount = InterlockedIncrement(&This->refCount);
812
813 return refCount;
814}
815
817{
819 ULONG refCount = InterlockedDecrement(&This->refCount);
820
821 if (!refCount)
822 {
823 int i;
824 for (i = 0; i < This->cMediaTypes; i++)
825 FreeMediaType(&This->pMediaTypes[i]);
826 CoTaskMemFree(This->pMediaTypes);
828 }
829 return refCount;
830}
831
832static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
833{
834 ULONG cFetched;
836
837 cFetched = min(This->cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
838
839 if (cFetched > 0)
840 {
841 ULONG i;
842 for (i = 0; i < cFetched; i++)
843 if (!(ppMediaTypes[i] = CreateMediaType(&This->pMediaTypes[This->uIndex + i])))
844 {
845 while (i--)
846 DeleteMediaType(ppMediaTypes[i]);
847 *pcFetched = 0;
848 return E_OUTOFMEMORY;
849 }
850 }
851
852 if ((cMediaTypes != 1) || pcFetched)
853 *pcFetched = cFetched;
854
855 This->uIndex += cFetched;
856
857 if (cFetched != cMediaTypes)
858 return S_FALSE;
859 return S_OK;
860}
861
863{
865
866 if (This->uIndex + cMediaTypes < This->cMediaTypes)
867 {
868 This->uIndex += cMediaTypes;
869 return S_OK;
870 }
871 return S_FALSE;
872}
873
875{
877
878 This->uIndex = 0;
879 return S_OK;
880}
881
883{
884 HRESULT hr;
886
887 hr = IEnumMediaTypesImpl_Construct(This->pMediaTypes, This->cMediaTypes, ppEnum);
888 if (FAILED(hr))
889 return hr;
890 return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
891}
892
893static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
894{
902};
903
904/* Implementation of a very stripped down pin for the test filter. Just enough
905 functionality for connecting and Render() to work. */
906
907static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
908{
909 lstrcpyW(pDest->achName, pSrc->achName);
910 pDest->dir = pSrc->dir;
911 pDest->pFilter = pSrc->pFilter;
912}
913
914typedef struct ITestPinImpl
915{
924
925static inline ITestPinImpl *impl_from_IPin(IPin *iface)
926{
927 return CONTAINING_RECORD(iface, ITestPinImpl, IPin_iface);
928}
929
931{
932 *ppv = NULL;
933
935 *ppv = iface;
936 else if (IsEqualIID(riid, &IID_IPin))
937 *ppv = iface;
938
939 if (*ppv)
940 {
941 IUnknown_AddRef((IUnknown *)(*ppv));
942 return S_OK;
943 }
944
945 return E_NOINTERFACE;
946}
947
949{
951 ULONG refCount = InterlockedIncrement(&This->refCount);
952 return refCount;
953}
954
956{
958 ULONG refCount = InterlockedDecrement(&This->refCount);
959
960 if (!refCount)
961 {
962 FreeMediaType(&This->mtCurrent);
964 return 0;
965 }
966 else
967 return refCount;
968}
969
970static HRESULT WINAPI TestFilter_InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt)
971{
972 return E_UNEXPECTED;
973}
974
976{
978 PIN_DIRECTION pindirReceive;
979 HRESULT hr = S_OK;
980
981 EnterCriticalSection(This->pCritSec);
982 {
983 if (!(IsEqualIID(&pmt->majortype, &This->mtCurrent.majortype) && (IsEqualIID(&pmt->subtype, &This->mtCurrent.subtype) ||
984 IsEqualIID(&GUID_NULL, &This->mtCurrent.subtype))))
986
987 if (This->pConnectedTo)
989
990 if (SUCCEEDED(hr))
991 {
992 IPin_QueryDirection(pReceivePin, &pindirReceive);
993
994 if (pindirReceive != PINDIR_OUTPUT)
995 {
997 }
998 }
999
1000 if (SUCCEEDED(hr))
1001 {
1002 CopyMediaType(&This->mtCurrent, pmt);
1003 This->pConnectedTo = pReceivePin;
1004 IPin_AddRef(pReceivePin);
1005 }
1006 }
1007 LeaveCriticalSection(This->pCritSec);
1008
1009 return hr;
1010}
1011
1013{
1014 HRESULT hr;
1016
1017 EnterCriticalSection(This->pCritSec);
1018 {
1019 if (This->pConnectedTo)
1020 {
1021 IPin_Release(This->pConnectedTo);
1022 This->pConnectedTo = NULL;
1023 hr = S_OK;
1024 }
1025 else
1026 hr = S_FALSE;
1027 }
1028 LeaveCriticalSection(This->pCritSec);
1029
1030 return hr;
1031}
1032
1034{
1035 HRESULT hr;
1037
1038 EnterCriticalSection(This->pCritSec);
1039 {
1040 if (This->pConnectedTo)
1041 {
1042 *ppPin = This->pConnectedTo;
1043 IPin_AddRef(*ppPin);
1044 hr = S_OK;
1045 }
1046 else
1047 {
1049 *ppPin = NULL;
1050 }
1051 }
1052 LeaveCriticalSection(This->pCritSec);
1053
1054 return hr;
1055}
1056
1058{
1059 HRESULT hr;
1061
1062 EnterCriticalSection(This->pCritSec);
1063 {
1064 if (This->pConnectedTo)
1065 {
1066 CopyMediaType(pmt, &This->mtCurrent);
1067 hr = S_OK;
1068 }
1069 else
1070 {
1071 ZeroMemory(pmt, sizeof(*pmt));
1073 }
1074 }
1075 LeaveCriticalSection(This->pCritSec);
1076
1077 return hr;
1078}
1079
1081{
1083
1084 Copy_PinInfo(pInfo, &This->pinInfo);
1085 IBaseFilter_AddRef(pInfo->pFilter);
1086
1087 return S_OK;
1088}
1089
1091{
1093
1094 *pPinDir = This->pinInfo.dir;
1095
1096 return S_OK;
1097}
1098
1100{
1101 return E_NOTIMPL;
1102}
1103
1105{
1107
1108 if (IsEqualIID(&pmt->majortype, &This->mtCurrent.majortype) && (IsEqualIID(&pmt->subtype, &This->mtCurrent.subtype) ||
1109 IsEqualIID(&GUID_NULL, &This->mtCurrent.subtype)))
1110 return S_OK;
1111 else
1113}
1114
1116{
1118
1119 return IEnumMediaTypesImpl_Construct(&This->mtCurrent, 1, ppEnum);
1120}
1121
1123{
1124 return E_NOTIMPL;
1125}
1126
1128{
1129 return E_NOTIMPL;
1130}
1131
1133{
1134 return E_NOTIMPL;
1135}
1136
1137static HRESULT WINAPI TestFilter_Pin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
1138{
1139 return E_NOTIMPL;
1140}
1141
1143{
1144 return E_NOTIMPL;
1145}
1146
1147static const IPinVtbl TestFilter_InputPin_Vtbl =
1148{
1167};
1168
1170{
1171 return E_UNEXPECTED;
1172}
1173
1174/* Private helper function */
1176 const AM_MEDIA_TYPE * pmt)
1177{
1178 HRESULT hr;
1179
1180 This->pConnectedTo = pReceivePin;
1181 IPin_AddRef(pReceivePin);
1182
1183 hr = IPin_ReceiveConnection(pReceivePin, &This->IPin_iface, pmt);
1184
1185 if (FAILED(hr))
1186 {
1187 IPin_Release(This->pConnectedTo);
1188 This->pConnectedTo = NULL;
1189 }
1190
1191 return hr;
1192}
1193
1194static HRESULT WINAPI TestFilter_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
1195{
1197 HRESULT hr;
1198
1199 EnterCriticalSection(This->pCritSec);
1200 {
1201 /* if we have been a specific type to connect with, then we can either connect
1202 * with that or fail. We cannot choose different AM_MEDIA_TYPE */
1203 if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL))
1204 hr = TestFilter_OutputPin_ConnectSpecific(This, pReceivePin, pmt);
1205 else
1206 {
1207 if (( !pmt || CompareMediaTypes(pmt, &This->mtCurrent, TRUE) ) &&
1208 (TestFilter_OutputPin_ConnectSpecific(This, pReceivePin, &This->mtCurrent) == S_OK))
1209 hr = S_OK;
1211 } /* if negotiate media type */
1212 } /* if succeeded */
1213 LeaveCriticalSection(This->pCritSec);
1214
1215 return hr;
1216}
1217
1218static const IPinVtbl TestFilter_OutputPin_Vtbl =
1219{
1238};
1239
1240static HRESULT TestFilter_Pin_Construct(const IPinVtbl *Pin_Vtbl, const PIN_INFO * pPinInfo, AM_MEDIA_TYPE *pinmt,
1241 LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
1242{
1243 ITestPinImpl * pPinImpl;
1244
1245 *ppPin = NULL;
1246
1247 pPinImpl = CoTaskMemAlloc(sizeof(ITestPinImpl));
1248
1249 if (!pPinImpl)
1250 return E_OUTOFMEMORY;
1251
1252 pPinImpl->refCount = 1;
1253 pPinImpl->pConnectedTo = NULL;
1254 pPinImpl->pCritSec = pCritSec;
1255 Copy_PinInfo(&pPinImpl->pinInfo, pPinInfo);
1256 pPinImpl->mtCurrent = *pinmt;
1257
1258 pPinImpl->IPin_iface.lpVtbl = Pin_Vtbl;
1259
1260 *ppPin = &pPinImpl->IPin_iface;
1261 return S_OK;
1262}
1263
1264/* IEnumPins implementation */
1265
1266typedef HRESULT (* FNOBTAINPIN)(TestFilterImpl *tf, ULONG pos, IPin **pin, DWORD *lastsynctick);
1267
1268typedef struct IEnumPinsImpl
1269{
1277
1278static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
1279
1281{
1282 return CONTAINING_RECORD(iface, IEnumPinsImpl, IEnumPins_iface);
1283}
1284
1286{
1287 IEnumPinsImpl * pEnumPins;
1288
1289 if (!ppEnum)
1290 return E_POINTER;
1291
1292 pEnumPins = CoTaskMemAlloc(sizeof(IEnumPinsImpl));
1293 if (!pEnumPins)
1294 {
1295 *ppEnum = NULL;
1296 return E_OUTOFMEMORY;
1297 }
1298 pEnumPins->IEnumPins_iface.lpVtbl = &IEnumPinsImpl_Vtbl;
1299 pEnumPins->refCount = 1;
1300 pEnumPins->uIndex = 0;
1301 pEnumPins->receive_pin = receive_pin;
1302 pEnumPins->base = base;
1303 IBaseFilter_AddRef(&base->IBaseFilter_iface);
1304 *ppEnum = &pEnumPins->IEnumPins_iface;
1305
1306 receive_pin(base, ~0, NULL, &pEnumPins->synctime);
1307
1308 return S_OK;
1309}
1310
1312{
1313 *ppv = NULL;
1314
1316 *ppv = iface;
1317 else if (IsEqualIID(riid, &IID_IEnumPins))
1318 *ppv = iface;
1319
1320 if (*ppv)
1321 {
1322 IUnknown_AddRef((IUnknown *)(*ppv));
1323 return S_OK;
1324 }
1325
1326 return E_NOINTERFACE;
1327}
1328
1330{
1332 ULONG refCount = InterlockedIncrement(&This->refCount);
1333
1334 return refCount;
1335}
1336
1338{
1340 ULONG refCount = InterlockedDecrement(&This->refCount);
1341
1342 if (!refCount)
1343 {
1344 IBaseFilter_Release(&This->base->IBaseFilter_iface);
1346 return 0;
1347 }
1348 else
1349 return refCount;
1350}
1351
1352static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched)
1353{
1355 DWORD synctime = This->synctime;
1356 HRESULT hr = S_OK;
1357 ULONG i = 0;
1358
1359 if (!ppPins)
1360 return E_POINTER;
1361
1362 if (cPins > 1 && !pcFetched)
1363 return E_INVALIDARG;
1364
1365 if (pcFetched)
1366 *pcFetched = 0;
1367
1368 while (i < cPins && hr == S_OK)
1369 {
1370 hr = This->receive_pin(This->base, This->uIndex + i, &ppPins[i], &synctime);
1371
1372 if (hr == S_OK)
1373 ++i;
1374
1375 if (synctime != This->synctime)
1376 break;
1377 }
1378
1379 if (!i && synctime != This->synctime)
1381
1382 if (pcFetched)
1383 *pcFetched = i;
1384 This->uIndex += i;
1385
1386 if (i < cPins)
1387 return S_FALSE;
1388 return S_OK;
1389}
1390
1392{
1394 DWORD synctime = This->synctime;
1395 HRESULT hr;
1396 IPin *pin = NULL;
1397
1398 hr = This->receive_pin(This->base, This->uIndex + cPins, &pin, &synctime);
1399 if (pin)
1400 IPin_Release(pin);
1401
1402 if (synctime != This->synctime)
1404
1405 if (hr == S_OK)
1406 This->uIndex += cPins;
1407
1408 return hr;
1409}
1410
1412{
1414
1415 This->receive_pin(This->base, ~0, NULL, &This->synctime);
1416
1417 This->uIndex = 0;
1418 return S_OK;
1419}
1420
1422{
1423 HRESULT hr;
1425
1426 hr = createenumpins(ppEnum, This->receive_pin, This->base);
1427 if (FAILED(hr))
1428 return hr;
1429 return IEnumPins_Skip(*ppEnum, This->uIndex);
1430}
1431
1432static const IEnumPinsVtbl IEnumPinsImpl_Vtbl =
1433{
1441};
1442
1443/* Test filter implementation - a filter that has few predefined pins with single media type
1444 * that accept only this single media type. Enough for Render(). */
1445
1446typedef struct TestFilterPinData
1447{
1451
1452static const IBaseFilterVtbl TestFilter_Vtbl;
1453
1455{
1456 return CONTAINING_RECORD(iface, TestFilterImpl, IBaseFilter_iface);
1457}
1458
1459static HRESULT createtestfilter(const CLSID* pClsid, const TestFilterPinData *pinData,
1461{
1462 static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
1463 static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
1464 HRESULT hr;
1465 PIN_INFO pinInfo;
1466 TestFilterImpl* pTestFilter = NULL;
1467 UINT nPins, i;
1468 AM_MEDIA_TYPE mt;
1469
1470 pTestFilter = CoTaskMemAlloc(sizeof(TestFilterImpl));
1471 if (!pTestFilter) return E_OUTOFMEMORY;
1472
1473 pTestFilter->clsid = *pClsid;
1474 pTestFilter->IBaseFilter_iface.lpVtbl = &TestFilter_Vtbl;
1475 pTestFilter->refCount = 1;
1476 InitializeCriticalSection(&pTestFilter->csFilter);
1477 pTestFilter->state = State_Stopped;
1478
1479 ZeroMemory(&pTestFilter->filterInfo, sizeof(FILTER_INFO));
1480
1481 nPins = 0;
1482 while(pinData[nPins].mediasubtype) ++nPins;
1483
1484 pTestFilter->ppPins = CoTaskMemAlloc(nPins * sizeof(IPin *));
1485 if (!pTestFilter->ppPins)
1486 {
1487 hr = E_OUTOFMEMORY;
1488 goto error;
1489 }
1490 ZeroMemory(pTestFilter->ppPins, nPins * sizeof(IPin *));
1491
1492 for (i = 0; i < nPins; i++)
1493 {
1494 ZeroMemory(&mt, sizeof(mt));
1495 mt.majortype = MEDIATYPE_Video;
1496 mt.formattype = FORMAT_None;
1497 mt.subtype = *pinData[i].mediasubtype;
1498
1499 pinInfo.dir = pinData[i].pinDir;
1500 pinInfo.pFilter = &pTestFilter->IBaseFilter_iface;
1501 if (pinInfo.dir == PINDIR_INPUT)
1502 {
1503 lstrcpynW(pinInfo.achName, wcsInputPinName, sizeof(pinInfo.achName) / sizeof(pinInfo.achName[0]));
1504 hr = TestFilter_Pin_Construct(&TestFilter_InputPin_Vtbl, &pinInfo, &mt, &pTestFilter->csFilter,
1505 &pTestFilter->ppPins[i]);
1506
1507 }
1508 else
1509 {
1510 lstrcpynW(pinInfo.achName, wcsOutputPinName, sizeof(pinInfo.achName) / sizeof(pinInfo.achName[0]));
1511 hr = TestFilter_Pin_Construct(&TestFilter_OutputPin_Vtbl, &pinInfo, &mt, &pTestFilter->csFilter,
1512 &pTestFilter->ppPins[i]);
1513 }
1514 if (FAILED(hr) || !pTestFilter->ppPins[i]) goto error;
1515 }
1516
1517 pTestFilter->nPins = nPins;
1518 *tf = pTestFilter;
1519 return S_OK;
1520
1521 error:
1522
1523 if (pTestFilter->ppPins)
1524 {
1525 for (i = 0; i < nPins; i++)
1526 {
1527 if (pTestFilter->ppPins[i]) IPin_Release(pTestFilter->ppPins[i]);
1528 }
1529 }
1530 CoTaskMemFree(pTestFilter->ppPins);
1531 DeleteCriticalSection(&pTestFilter->csFilter);
1532 CoTaskMemFree(pTestFilter);
1533
1534 return hr;
1535}
1536
1538{
1540
1541 *ppv = NULL;
1542
1544 *ppv = This;
1545 else if (IsEqualIID(riid, &IID_IPersist))
1546 *ppv = This;
1547 else if (IsEqualIID(riid, &IID_IMediaFilter))
1548 *ppv = This;
1549 else if (IsEqualIID(riid, &IID_IBaseFilter))
1550 *ppv = This;
1551
1552 if (*ppv)
1553 {
1554 IUnknown_AddRef((IUnknown *)(*ppv));
1555 return S_OK;
1556 }
1557
1558 return E_NOINTERFACE;
1559}
1560
1562{
1564 ULONG refCount = InterlockedIncrement(&This->refCount);
1565
1566 return refCount;
1567}
1568
1570{
1572 ULONG refCount = InterlockedDecrement(&This->refCount);
1573
1574 if (!refCount)
1575 {
1576 ULONG i;
1577
1578 for (i = 0; i < This->nPins; i++)
1579 {
1580 IPin *pConnectedTo;
1581
1582 if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[i], &pConnectedTo)))
1583 {
1584 IPin_Disconnect(pConnectedTo);
1585 IPin_Release(pConnectedTo);
1586 }
1587 IPin_Disconnect(This->ppPins[i]);
1588
1589 IPin_Release(This->ppPins[i]);
1590 }
1591
1592 CoTaskMemFree(This->ppPins);
1593
1594 DeleteCriticalSection(&This->csFilter);
1595
1597
1598 return 0;
1599 }
1600 else
1601 return refCount;
1602}
1606{
1608
1609 *pClsid = This->clsid;
1610
1611 return S_OK;
1612}
1613
1617{
1618 return E_NOTIMPL;
1619}
1620
1622{
1623 return E_NOTIMPL;
1624}
1625
1627{
1628 return E_NOTIMPL;
1629}
1630
1631static HRESULT WINAPI TestFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
1632{
1634
1635 EnterCriticalSection(&This->csFilter);
1636 {
1637 *pState = This->state;
1638 }
1639 LeaveCriticalSection(&This->csFilter);
1640
1641 return S_OK;
1642}
1643
1645{
1646 return E_NOTIMPL;
1647}
1648
1650{
1651 return E_NOTIMPL;
1652}
1653
1657{
1658 /* Our pins are static, not changing so setting static tick count is ok */
1659 *lastsynctick = 0;
1660
1661 if (pos >= tf->nPins)
1662 return S_FALSE;
1663
1664 *pin = tf->ppPins[pos];
1665 IPin_AddRef(*pin);
1666 return S_OK;
1667}
1668
1670{
1672
1673 return createenumpins(ppEnum, getpin_callback, This);
1674}
1675
1677{
1678 return E_NOTIMPL;
1679}
1680
1681static HRESULT WINAPI TestFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
1682{
1684
1685 lstrcpyW(pInfo->achName, This->filterInfo.achName);
1686 pInfo->pGraph = This->filterInfo.pGraph;
1687
1688 if (pInfo->pGraph)
1689 IFilterGraph_AddRef(pInfo->pGraph);
1690
1691 return S_OK;
1692}
1693
1695{
1696 HRESULT hr = S_OK;
1698
1699 EnterCriticalSection(&This->csFilter);
1700 {
1701 if (pName)
1702 lstrcpyW(This->filterInfo.achName, pName);
1703 else
1704 *This->filterInfo.achName = '\0';
1705 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
1706 }
1707 LeaveCriticalSection(&This->csFilter);
1708
1709 return hr;
1710}
1711
1713{
1714 return E_NOTIMPL;
1715}
1716
1717static const IBaseFilterVtbl TestFilter_Vtbl =
1718{
1734};
1735
1736/* IClassFactory implementation */
1737
1739{
1742 const CLSID *clsid;
1744
1746{
1747 return CONTAINING_RECORD(iface, TestClassFactoryImpl, IClassFactory_iface);
1748}
1749
1751 LPCLASSFACTORY iface,
1752 REFIID riid,
1753 LPVOID *ppvObj)
1754{
1755 if (ppvObj == NULL) return E_POINTER;
1756
1757 if (IsEqualGUID(riid, &IID_IUnknown) ||
1759 {
1760 *ppvObj = iface;
1761 IClassFactory_AddRef(iface);
1762 return S_OK;
1763 }
1764
1765 *ppvObj = NULL;
1766 return E_NOINTERFACE;
1767}
1768
1769static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
1770{
1771 return 2; /* non-heap-based object */
1772}
1773
1774static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
1775{
1776 return 1; /* non-heap-based object */
1777}
1778
1780 LPCLASSFACTORY iface,
1781 LPUNKNOWN pUnkOuter,
1782 REFIID riid,
1783 LPVOID *ppvObj)
1784{
1786 HRESULT hr;
1787 TestFilterImpl *testfilter;
1788
1789 *ppvObj = NULL;
1790
1791 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
1792
1793 hr = createtestfilter(This->clsid, This->filterPinData, &testfilter);
1794 if (SUCCEEDED(hr)) {
1795 hr = IBaseFilter_QueryInterface(&testfilter->IBaseFilter_iface, riid, ppvObj);
1796 IBaseFilter_Release(&testfilter->IBaseFilter_iface);
1797 }
1798 return hr;
1799}
1800
1802 LPCLASSFACTORY iface,
1803 BOOL fLock)
1804{
1805 return S_OK;
1806}
1807
1808static IClassFactoryVtbl TestClassFactory_Vtbl =
1809{
1815};
1816
1817static HRESULT get_connected_filter_name(TestFilterImpl *pFilter, char *FilterName)
1818{
1819 IPin *pin = NULL;
1820 PIN_INFO pinInfo;
1821 FILTER_INFO filterInfo;
1822 HRESULT hr;
1823
1824 FilterName[0] = 0;
1825
1826 hr = IPin_ConnectedTo(pFilter->ppPins[0], &pin);
1827 ok(hr == S_OK, "IPin_ConnectedTo failed with %x\n", hr);
1828
1829 hr = IPin_QueryPinInfo(pin, &pinInfo);
1830 ok(hr == S_OK, "IPin_QueryPinInfo failed with %x\n", hr);
1831 IPin_Release(pin);
1832
1833 SetLastError(0xdeadbeef);
1834 hr = IBaseFilter_QueryFilterInfo(pinInfo.pFilter, &filterInfo);
1836 {
1837 IBaseFilter_Release(pinInfo.pFilter);
1838 return E_NOTIMPL;
1839 }
1840 ok(hr == S_OK, "IBaseFilter_QueryFilterInfo failed with %x\n", hr);
1841 IBaseFilter_Release(pinInfo.pFilter);
1842
1843 IFilterGraph_Release(filterInfo.pGraph);
1844
1845 WideCharToMultiByte(CP_ACP, 0, filterInfo.achName, -1, FilterName, MAX_FILTER_NAME, NULL, NULL);
1846
1847 return S_OK;
1848}
1849
1851{
1852 /* Tests filter choice priorities in Render(). */
1853 DWORD cookie1 = 0, cookie2 = 0, cookie3 = 0;
1854 HRESULT hr;
1855 IFilterGraph2* pgraph2 = NULL;
1856 IFilterMapper2 *pMapper2 = NULL;
1857 TestFilterImpl *ptestfilter = NULL;
1858 TestFilterImpl *ptestfilter2 = NULL;
1859 static const CLSID CLSID_TestFilter2 = {
1860 0x37a4edb0,
1861 0x4d13,
1862 0x11dd,
1863 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1864 };
1865 static const CLSID CLSID_TestFilter3 = {
1866 0x37a4f2d8,
1867 0x4d13,
1868 0x11dd,
1869 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1870 };
1871 static const CLSID CLSID_TestFilter4 = {
1872 0x37a4f3b4,
1873 0x4d13,
1874 0x11dd,
1875 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1876 };
1877 static const GUID mediasubtype1 = {
1878 0x37a4f51c,
1879 0x4d13,
1880 0x11dd,
1881 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1882 };
1883 static const GUID mediasubtype2 = {
1884 0x37a4f5c6,
1885 0x4d13,
1886 0x11dd,
1887 {0xe8, 0x9b, 0x00, 0x19, 0x66, 0x2f, 0xf0, 0xce}
1888 };
1889 static const TestFilterPinData PinData1[] = {
1890 { PINDIR_OUTPUT, &mediasubtype1 },
1891 { 0, 0 }
1892 };
1893 static const TestFilterPinData PinData2[] = {
1894 { PINDIR_INPUT, &mediasubtype1 },
1895 { 0, 0 }
1896 };
1897 static const TestFilterPinData PinData3[] = {
1898 { PINDIR_INPUT, &GUID_NULL },
1899 { 0, 0 }
1900 };
1901 static const TestFilterPinData PinData4[] = {
1902 { PINDIR_INPUT, &mediasubtype1 },
1903 { PINDIR_OUTPUT, &mediasubtype2 },
1904 { 0, 0 }
1905 };
1906 static const TestFilterPinData PinData5[] = {
1907 { PINDIR_INPUT, &mediasubtype2 },
1908 { 0, 0 }
1909 };
1910 TestClassFactoryImpl Filter1ClassFactory = {
1912 PinData2, &CLSID_TestFilter2
1913 };
1914 TestClassFactoryImpl Filter2ClassFactory = {
1916 PinData4, &CLSID_TestFilter3
1917 };
1918 TestClassFactoryImpl Filter3ClassFactory = {
1920 PinData5, &CLSID_TestFilter4
1921 };
1922 char ConnectedFilterName1[MAX_FILTER_NAME];
1923 char ConnectedFilterName2[MAX_FILTER_NAME];
1924 REGFILTER2 rgf2;
1925 REGFILTERPINS2 rgPins2[2];
1926 REGPINTYPES rgPinType[2];
1927 static const WCHAR wszFilterInstanceName1[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1928 'n', 's', 't', 'a', 'n', 'c', 'e', '1', 0 };
1929 static const WCHAR wszFilterInstanceName2[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1930 'n', 's', 't', 'a', 'n', 'c', 'e', '2', 0 };
1931 static const WCHAR wszFilterInstanceName3[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1932 'n', 's', 't', 'a', 'n', 'c', 'e', '3', 0 };
1933 static const WCHAR wszFilterInstanceName4[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 'I',
1934 'n', 's', 't', 'a', 'n', 'c', 'e', '4', 0 };
1935
1936 /* Test which renderer of two already added to the graph will be chosen
1937 * (one is "exact" match, other is "wildcard" match. Seems to depend
1938 * on the order in which filters are added to the graph, thus indicating
1939 * no preference given to exact match. */
1940 pgraph2 = create_graph();
1941
1942 hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
1943 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1944
1945 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
1946 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1947
1948 hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
1949 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1950
1951 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
1952 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1953
1954 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
1955
1956 hr = createtestfilter(&GUID_NULL, PinData3, &ptestfilter2);
1957 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1958
1959 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
1960 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1961
1962 hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
1963 ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
1964
1965 hr = get_connected_filter_name(ptestfilter, ConnectedFilterName1);
1966
1967 IFilterGraph2_Release(pgraph2);
1968 IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
1969 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
1970
1971 pgraph2 = create_graph();
1972
1973 hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
1974 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1975
1976 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
1977 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1978
1979 hr = createtestfilter(&GUID_NULL, PinData3, &ptestfilter2);
1980 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1981
1982 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
1983 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1984
1985 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
1986
1987 hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
1988 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
1989
1990 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
1991 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
1992
1993 hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
1994 ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
1995
1996 hr = IFilterGraph2_Disconnect(pgraph2, NULL);
1997 ok(hr == E_POINTER, "IFilterGraph2_Disconnect failed. Expected E_POINTER, received %08x\n", hr);
1998
1999 get_connected_filter_name(ptestfilter, ConnectedFilterName2);
2000 ok(strcmp(ConnectedFilterName1, ConnectedFilterName2),
2001 "expected connected filters to be different but got %s both times\n", ConnectedFilterName1);
2002
2003 IFilterGraph2_Release(pgraph2);
2004 IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
2005 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2006
2007 /* Test if any preference is given to existing renderer which renders the pin directly vs
2008 an existing renderer which renders the pin indirectly, through an additional middle filter,
2009 again trying different orders of creation. Native appears not to give a preference. */
2010
2011 pgraph2 = create_graph();
2012
2013 hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
2014 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2015
2016 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
2017 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2018
2019 hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
2020 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2021
2022 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
2023 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2024
2025 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2026
2027 hr = createtestfilter(&GUID_NULL, PinData4, &ptestfilter2);
2028 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2029
2030 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
2031 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2032
2033 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2034
2035 hr = createtestfilter(&GUID_NULL, PinData5, &ptestfilter2);
2036 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2037
2038 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName4);
2039 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2040
2041 hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
2042 ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
2043
2044 get_connected_filter_name(ptestfilter, ConnectedFilterName1);
2045 ok(!strcmp(ConnectedFilterName1, "TestfilterInstance3") || !strcmp(ConnectedFilterName1, "TestfilterInstance2"),
2046 "unexpected connected filter: %s\n", ConnectedFilterName1);
2047
2048 IFilterGraph2_Release(pgraph2);
2049 IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
2050 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2051
2052 pgraph2 = create_graph();
2053
2054 hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
2055 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2056
2057 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
2058 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2059
2060 hr = createtestfilter(&GUID_NULL, PinData4, &ptestfilter2);
2061 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2062
2063 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
2064 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2065
2066 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2067
2068 hr = createtestfilter(&GUID_NULL, PinData5, &ptestfilter2);
2069 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2070
2071 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName4);
2072 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2073
2074 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2075
2076 hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
2077 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2078
2079 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
2080 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2081
2082 hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
2083 ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
2084
2085 get_connected_filter_name(ptestfilter, ConnectedFilterName2);
2086 ok(!strcmp(ConnectedFilterName2, "TestfilterInstance3") || !strcmp(ConnectedFilterName2, "TestfilterInstance2"),
2087 "unexpected connected filter: %s\n", ConnectedFilterName2);
2088 ok(strcmp(ConnectedFilterName1, ConnectedFilterName2),
2089 "expected connected filters to be different but got %s both times\n", ConnectedFilterName1);
2090
2091 IFilterGraph2_Release(pgraph2);
2092 IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
2093 IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
2094
2095 /* Test if renderers are tried before non-renderers (intermediary filters). */
2096 pgraph2 = create_graph();
2097
2098 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pMapper2);
2099 ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
2100
2101 hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
2102 ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
2103
2104 hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
2105 ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
2106
2107 /* Register our filters with COM and with Filtermapper. */
2108 hr = CoRegisterClassObject(Filter1ClassFactory.clsid,
2109 (IUnknown *)&Filter1ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
2110 REGCLS_MULTIPLEUSE, &cookie1);
2111 ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
2112 hr = CoRegisterClassObject(Filter2ClassFactory.clsid,
2113 (IUnknown *)&Filter2ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
2114 REGCLS_MULTIPLEUSE, &cookie2);
2115 ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
2116 hr = CoRegisterClassObject(Filter3ClassFactory.clsid,
2117 (IUnknown *)&Filter3ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
2118 REGCLS_MULTIPLEUSE, &cookie3);
2119 ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
2120
2121 rgf2.dwVersion = 2;
2122 rgf2.dwMerit = MERIT_UNLIKELY;
2123 S2(U(rgf2)).cPins2 = 1;
2124 S2(U(rgf2)).rgPins2 = rgPins2;
2125 rgPins2[0].dwFlags = REG_PINFLAG_B_RENDERER;
2126 rgPins2[0].cInstances = 1;
2127 rgPins2[0].nMediaTypes = 1;
2128 rgPins2[0].lpMediaType = &rgPinType[0];
2129 rgPins2[0].nMediums = 0;
2130 rgPins2[0].lpMedium = NULL;
2131 rgPins2[0].clsPinCategory = NULL;
2132 rgPinType[0].clsMajorType = &MEDIATYPE_Video;
2133 rgPinType[0].clsMinorType = &mediasubtype1;
2134
2135 hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter2, wszFilterInstanceName2, NULL,
2136 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
2137 if (hr == E_ACCESSDENIED)
2138 skip("Not authorized to register filters\n");
2139 else
2140 {
2141 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
2142
2143 rgf2.dwMerit = MERIT_PREFERRED;
2144 rgPinType[0].clsMinorType = &mediasubtype2;
2145
2146 hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter4, wszFilterInstanceName4, NULL,
2147 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
2148 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
2149
2150 S2(U(rgf2)).cPins2 = 2;
2151 rgPins2[0].dwFlags = 0;
2152 rgPinType[0].clsMinorType = &mediasubtype1;
2153
2154 rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
2155 rgPins2[1].cInstances = 1;
2156 rgPins2[1].nMediaTypes = 1;
2157 rgPins2[1].lpMediaType = &rgPinType[1];
2158 rgPins2[1].nMediums = 0;
2159 rgPins2[1].lpMedium = NULL;
2160 rgPins2[1].clsPinCategory = NULL;
2161 rgPinType[1].clsMajorType = &MEDIATYPE_Video;
2162 rgPinType[1].clsMinorType = &mediasubtype2;
2163
2164 hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter3, wszFilterInstanceName3, NULL,
2165 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
2166 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
2167
2168 hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
2169 ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
2170
2171 get_connected_filter_name(ptestfilter, ConnectedFilterName1);
2172 ok(!strcmp(ConnectedFilterName1, "TestfilterInstance3"),
2173 "unexpected connected filter: %s\n", ConnectedFilterName1);
2174
2175 hr = IFilterMapper2_UnregisterFilter(pMapper2, &CLSID_LegacyAmFilterCategory, NULL,
2176 &CLSID_TestFilter2);
2177 ok(hr == S_OK, "IFilterMapper2_UnregisterFilter failed with %x\n", hr);
2178 hr = IFilterMapper2_UnregisterFilter(pMapper2, &CLSID_LegacyAmFilterCategory, NULL,
2179 &CLSID_TestFilter3);
2180 ok(hr == S_OK, "IFilterMapper2_UnregisterFilter failed with %x\n", hr);
2181 hr = IFilterMapper2_UnregisterFilter(pMapper2, &CLSID_LegacyAmFilterCategory, NULL,
2182 &CLSID_TestFilter4);
2183 ok(hr == S_OK, "IFilterMapper2_UnregisterFilter failed with %x\n", hr);
2184 }
2185
2186 IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
2187 IFilterGraph2_Release(pgraph2);
2188 IFilterMapper2_Release(pMapper2);
2189
2190 hr = CoRevokeClassObject(cookie1);
2191 ok(hr == S_OK, "CoRevokeClassObject failed with %08x\n", hr);
2192 hr = CoRevokeClassObject(cookie2);
2193 ok(hr == S_OK, "CoRevokeClassObject failed with %08x\n", hr);
2194 hr = CoRevokeClassObject(cookie3);
2195 ok(hr == S_OK, "CoRevokeClassObject failed with %08x\n", hr);
2196}
2197
2198typedef struct IUnknownImpl
2199{
2204
2206{
2207 return CONTAINING_RECORD(iface, IUnknownImpl, IUnknown_iface);
2208}
2209
2211{
2212 ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid));
2213 return E_NOINTERFACE;
2214}
2215
2217{
2219 This->AddRef_called++;
2220 return 2;
2221}
2222
2224{
2226 This->Release_called++;
2227 return 1;
2228}
2229
2230static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl =
2231{
2235};
2236
2238{
2239 HRESULT hr;
2240 IUnknown *pgraph;
2241 IUnknown *punk;
2242 IUnknownImpl unk_outer = { { &IUnknownImpl_Vtbl }, 0, 0 };
2243
2244 hr = CoCreateInstance(&CLSID_FilterGraph, &unk_outer.IUnknown_iface, CLSCTX_INPROC_SERVER,
2245 &IID_IUnknown, (void **)&pgraph);
2246 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
2247 ok(pgraph != &unk_outer.IUnknown_iface, "pgraph = %p, expected not %p\n", pgraph, &unk_outer.IUnknown_iface);
2248
2249 hr = IUnknown_QueryInterface(pgraph, &IID_IUnknown, (void **)&punk);
2250 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
2251 ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
2252 IUnknown_Release(punk);
2253
2254 ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
2255 ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
2256 unk_outer.AddRef_called = 0;
2257 unk_outer.Release_called = 0;
2258
2259 hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper, (void **)&punk);
2260 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
2261 ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
2262 IUnknown_Release(punk);
2263
2264 ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
2265 ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
2266 unk_outer.AddRef_called = 0;
2267 unk_outer.Release_called = 0;
2268
2269 hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper2, (void **)&punk);
2270 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
2271 ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
2272 IUnknown_Release(punk);
2273
2274 ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
2275 ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
2276 unk_outer.AddRef_called = 0;
2277 unk_outer.Release_called = 0;
2278
2279 hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper3, (void **)&punk);
2280 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
2281 ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
2282 IUnknown_Release(punk);
2283
2284 ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
2285 ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
2286
2287 IUnknown_Release(pgraph);
2288}
2289
2290START_TEST(filtergraph)
2291{
2293
2301}
DWORD Id
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
@ AM_SEEKING_NoPositioning
Definition: axcore.idl:591
@ AM_SEEKING_AbsolutePositioning
Definition: axcore.idl:592
@ AM_SEEKING_ReturnTime
Definition: axcore.idl:597
enum _PinDirection PIN_DIRECTION
#define MAX_FILTER_NAME
Definition: axcore.idl:48
@ PINDIR_OUTPUT
Definition: axcore.idl:42
@ PINDIR_INPUT
Definition: axcore.idl:41
REGPINTYPES
Definition: axextend.idl:192
@ REG_PINFLAG_B_RENDERER
Definition: axextend.idl:217
@ REG_PINFLAG_B_OUTPUT
Definition: axextend.idl:219
#define U(x)
Definition: wordpad.c:45
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
const GUID IID_IClassFactory
LPARAM lParam
Definition: combotst.c:139
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static const WCHAR wcsInputPinName[]
Definition: parser.c:38
#define CloseHandle
Definition: compat.h:739
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrcpynW
Definition: compat.h:738
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister)
Definition: compobj.c:2897
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(DWORD dwRegister)
Definition: compobj.c:1086
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
#define INFINITE
Definition: serial.h:102
#define EC_COMPLETE
Definition: evcode.h:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HFONT tf
Definition: icontest.c:17
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
#define CREATE_ALWAYS
Definition: disk.h:72
static PVOID ptr
Definition: dispmode.c:27
static LPSTR pName
Definition: security.c:75
static IHTMLWindow2 * window
Definition: events.c:77
#define todo_wine
Definition: custom.c:79
static HRESULT WINAPI TestFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: filtergraph.c:1694
static const IPinVtbl TestFilter_OutputPin_Vtbl
Definition: filtergraph.c:1218
struct IEnumPinsImpl IEnumPinsImpl
static HRESULT createenumpins(IEnumPins **ppEnum, FNOBTAINPIN receive_pin, TestFilterImpl *base)
Definition: filtergraph.c:1285
static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins *iface)
Definition: filtergraph.c:1329
static HRESULT WINAPI TestFilter_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
Definition: filtergraph.c:1676
static IEnumMediaTypesImpl * impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
Definition: filtergraph.c:758
static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes *iface)
Definition: filtergraph.c:874
static HRESULT WINAPI TestFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
Definition: filtergraph.c:1626
static TestFilterImpl * impl_from_IBaseFilter(IBaseFilter *iface)
Definition: filtergraph.c:1454
static void test_render_run(const WCHAR *file)
Definition: filtergraph.c:543
static HRESULT get_connected_filter_name(TestFilterImpl *pFilter, char *FilterName)
Definition: filtergraph.c:1817
static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins *iface, IEnumPins **ppEnum)
Definition: filtergraph.c:1421
static HRESULT IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE *pMediaTypes, ULONG cMediaTypes, IEnumMediaTypes **ppEnum)
Definition: filtergraph.c:763
static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins *iface, REFIID riid, LPVOID *ppv)
Definition: filtergraph.c:1311
static HRESULT WINAPI TestFilter_InputPin_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:975
static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl
Definition: filtergraph.c:756
static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **ppEnum)
Definition: filtergraph.c:882
static WCHAR * load_resource(const WCHAR *name)
Definition: filtergraph.c:45
static void rungraph(IFilterGraph2 *graph)
Definition: filtergraph.c:493
static void test_media_event(IFilterGraph2 *graph)
Definition: filtergraph.c:407
static HRESULT WINAPI TestFilter_Pin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: filtergraph.c:1137
static AM_MEDIA_TYPE * CreateMediaType(AM_MEDIA_TYPE const *pSrc)
Definition: filtergraph.c:718
struct IEnumMediaTypesImpl IEnumMediaTypesImpl
static HRESULT getpin_callback(TestFilterImpl *tf, ULONG pos, IPin **pin, DWORD *lastsynctick)
Definition: filtergraph.c:1656
static BOOL CompareMediaTypes(const AM_MEDIA_TYPE *pmt1, const AM_MEDIA_TYPE *pmt2, BOOL bWildcards)
Definition: filtergraph.c:735
static IEnumPinsImpl * impl_from_IEnumPins(IEnumPins *iface)
Definition: filtergraph.c:1280
static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
Definition: filtergraph.c:2216
static TestClassFactoryImpl * impl_from_IClassFactory(IClassFactory *iface)
Definition: filtergraph.c:1745
static HRESULT WINAPI Test_IClassFactory_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
Definition: filtergraph.c:1750
static void DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:741
HRESULT(* FNOBTAINPIN)(TestFilterImpl *tf, ULONG pos, IPin **pin, DWORD *lastsynctick)
Definition: filtergraph.c:1266
static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins *iface)
Definition: filtergraph.c:1337
static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl
Definition: filtergraph.c:1278
static HRESULT WINAPI TestFilter_Pin_Disconnect(IPin *iface)
Definition: filtergraph.c:1012
static HRESULT WINAPI TestFilter_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: filtergraph.c:1605
static HRESULT WINAPI TestFilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: filtergraph.c:1649
static HRESULT TestFilter_OutputPin_ConnectSpecific(ITestPinImpl *This, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:1175
static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins *iface, ULONG cPins, IPin **ppPins, ULONG *pcFetched)
Definition: filtergraph.c:1352
static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins *iface, ULONG cPins)
Definition: filtergraph.c:1391
static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes *iface, ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched)
Definition: filtergraph.c:832
static HRESULT WINAPI Test_IClassFactory_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: filtergraph.c:1801
static const WCHAR avifile[]
Definition: filtergraph.c:42
static HRESULT WINAPI TestFilter_Pin_EndFlush(IPin *iface)
Definition: filtergraph.c:1132
static HRESULT WINAPI Test_IClassFactory_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
Definition: filtergraph.c:1779
static DWORD WINAPI call_RenderFile_multithread(LPVOID lParam)
Definition: filtergraph.c:595
static const IBaseFilterVtbl TestFilter_Vtbl
Definition: filtergraph.c:1452
static HRESULT WINAPI TestFilter_Pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:1104
static HRESULT WINAPI TestFilter_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
Definition: filtergraph.c:1631
static HRESULT WINAPI TestFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
Definition: filtergraph.c:1712
static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes *iface, ULONG cMediaTypes)
Definition: filtergraph.c:862
static HRESULT WINAPI TestFilter_InputPin_Connect(IPin *iface, IPin *pConnector, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:970
static const IPinVtbl TestFilter_InputPin_Vtbl
Definition: filtergraph.c:1147
static void Copy_PinInfo(PIN_INFO *pDest, const PIN_INFO *pSrc)
Definition: filtergraph.c:907
static void test_aggregate_filter_graph(void)
Definition: filtergraph.c:2237
static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes *iface)
Definition: filtergraph.c:808
static HRESULT WINAPI TestFilter_Pin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:1057
static HRESULT WINAPI TestFilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: filtergraph.c:1681
static const WCHAR mpegfile[]
Definition: filtergraph.c:43
static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes *iface)
Definition: filtergraph.c:816
static HRESULT createtestfilter(const CLSID *pClsid, const TestFilterPinData *pinData, TestFilterImpl **tf)
Definition: filtergraph.c:1459
static HRESULT WINAPI TestFilter_Pin_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *cPin)
Definition: filtergraph.c:1122
static HRESULT WINAPI TestFilter_Pin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
Definition: filtergraph.c:1090
static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppv)
Definition: filtergraph.c:2210
static HRESULT WINAPI TestFilter_Pin_EndOfStream(IPin *iface)
Definition: filtergraph.c:1142
static HRESULT WINAPI TestFilter_Pin_ConnectedTo(IPin *iface, IPin **ppPin)
Definition: filtergraph.c:1033
static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
Definition: filtergraph.c:1769
static HRESULT WINAPI TestFilter_Pin_BeginFlush(IPin *iface)
Definition: filtergraph.c:1127
static HRESULT WINAPI TestFilter_Pin_QueryId(IPin *iface, LPWSTR *Id)
Definition: filtergraph.c:1099
static void test_render_filter_priority(void)
Definition: filtergraph.c:1850
static ULONG WINAPI TestFilter_AddRef(IBaseFilter *iface)
Definition: filtergraph.c:1561
static void test_basic_video(IFilterGraph2 *graph)
Definition: filtergraph.c:79
static HRESULT TestFilter_Pin_Construct(const IPinVtbl *Pin_Vtbl, const PIN_INFO *pPinInfo, AM_MEDIA_TYPE *pinmt, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
Definition: filtergraph.c:1240
static ULONG WINAPI TestFilter_Pin_Release(IPin *iface)
Definition: filtergraph.c:955
static IFilterGraph2 * create_graph(void)
Definition: filtergraph.c:70
static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl
Definition: filtergraph.c:2230
static void test_state_change(IFilterGraph2 *graph)
Definition: filtergraph.c:355
struct IUnknownImpl IUnknownImpl
static HRESULT WINAPI TestFilter_Pin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
Definition: filtergraph.c:1080
static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
Definition: filtergraph.c:2223
static HRESULT WINAPI TestFilter_Pin_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: filtergraph.c:930
static HRESULT WINAPI TestFilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: filtergraph.c:1644
static HRESULT WINAPI TestFilter_Stop(IBaseFilter *iface)
Definition: filtergraph.c:1616
static ITestPinImpl * impl_from_IPin(IPin *iface)
Definition: filtergraph.c:925
static HRESULT WINAPI TestFilter_Pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
Definition: filtergraph.c:1115
static HRESULT WINAPI TestFilter_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv)
Definition: filtergraph.c:1537
static HRESULT WINAPI TestFilter_OutputPin_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:1194
static IUnknownImpl * IUnknownImpl_from_iface(IUnknown *iface)
Definition: filtergraph.c:2205
static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins *iface)
Definition: filtergraph.c:1411
static HRESULT test_graph_builder_connect(WCHAR *filename)
Definition: filtergraph.c:501
static void test_render_with_multithread(void)
Definition: filtergraph.c:611
static void FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:692
static void test_graph_builder(void)
Definition: filtergraph.c:628
static HRESULT WINAPI TestFilter_Pause(IBaseFilter *iface)
Definition: filtergraph.c:1621
static ULONG WINAPI TestFilter_Pin_AddRef(IPin *iface)
Definition: filtergraph.c:948
static void test_media_seeking(IFilterGraph2 *graph)
Definition: filtergraph.c:287
static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes *iface, REFIID riid, LPVOID *ppv)
Definition: filtergraph.c:790
static HRESULT WINAPI TestFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: filtergraph.c:1669
static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
Definition: filtergraph.c:1774
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
static IClassFactoryVtbl TestClassFactory_Vtbl
Definition: filtergraph.c:1808
static ULONG WINAPI TestFilter_Release(IBaseFilter *iface)
Definition: filtergraph.c:1569
static HRESULT WINAPI TestFilter_OutputPin_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: filtergraph.c:1169
#define min(a, b)
Definition: monoChain.cc:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
static LPUNKNOWN
Definition: ndr_ole.c:49
#define GENERIC_WRITE
Definition: nt_native.h:90
@ REGCLS_MULTIPLEUSE
Definition: objbase.h:393
#define CONST_VTBL
Definition: objbase.h:222
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
@ COINIT_MULTITHREADED
Definition: objbase.h:279
#define RT_RCDATA
Definition: pedump.c:372
long LONG
Definition: pedump.c:60
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define S2(x)
Definition: test.h:222
HRESULT hr
Definition: shlfolder.c:183
AM_MEDIA_TYPE * pMediaTypes
Definition: filtergraph.c:751
IEnumMediaTypes IEnumMediaTypes_iface
Definition: filtergraph.c:749
TestFilterImpl * base
Definition: filtergraph.c:1273
FNOBTAINPIN receive_pin
Definition: filtergraph.c:1274
IEnumPins IEnumPins_iface
Definition: filtergraph.c:1270
LPCRITICAL_SECTION pCritSec
Definition: filtergraph.c:918
LPVOID pUserData
Definition: filtergraph.c:922
IPin * pConnectedTo
Definition: filtergraph.c:920
AM_MEDIA_TYPE mtCurrent
Definition: filtergraph.c:921
PIN_INFO pinInfo
Definition: filtergraph.c:919
IUnknown IUnknown_iface
Definition: filtergraph.c:2200
DWORD dwVersion
Definition: axextend.idl:236
DWORD dwMerit
Definition: axextend.idl:237
const CLSID * clsPinCategory
Definition: axextend.idl:231
const REGPINMEDIUM * lpMedium
Definition: axextend.idl:230
const REGPINTYPES * lpMediaType
Definition: axextend.idl:228
const TestFilterPinData * filterPinData
Definition: filtergraph.c:1741
IClassFactory IClassFactory_iface
Definition: filtergraph.c:1740
const CLSID * clsid
Definition: filtergraph.c:1742
CRITICAL_SECTION csFilter
Definition: filtergraph.c:34
IPin ** ppPins
Definition: filtergraph.c:38
FILTER_INFO filterInfo
Definition: filtergraph.c:36
IBaseFilter IBaseFilter_iface
Definition: filtergraph.c:31
FILTER_STATE state
Definition: filtergraph.c:35
const GUID * mediasubtype
Definition: filtergraph.c:1449
PIN_DIRECTION pinDir
Definition: filtergraph.c:1448
Definition: inflate.c:139
Definition: fci.c:127
Definition: name.c:39
Definition: regsvr.c:104
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
int64_t LONGLONG
Definition: typedefs.h:68
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
static const WCHAR inW[]
Definition: lex.c:61
#define VFW_E_ALREADY_CONNECTED
Definition: vfwmsgs.h:43
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_INVALID_DIRECTION
Definition: vfwmsgs.h:47
#define VFW_E_NO_ACCEPTABLE_TYPES
Definition: vfwmsgs.h:46
#define VFW_S_PARTIAL_RENDER
Definition: vfwmsgs.h:22
#define VFW_E_ENUM_OUT_OF_SYNC
Definition: vfwmsgs.h:42
#define VFW_E_CANNOT_CONNECT
Definition: vfwmsgs.h:62
#define VFW_S_AUDIO_NOT_RENDERED
Definition: vfwmsgs.h:28
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
static const WCHAR wcsOutputPinName[]
Definition: waveparser.c:39
int ret
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_UNEXPECTED
Definition: winerror.h:2456
#define E_POINTER
Definition: winerror.h:2365
#define SM_CXFRAME
Definition: winuser.h:994
#define SM_CXMIN
Definition: winuser.h:989
int WINAPI GetSystemMetrics(_In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185