Removed W->A from DEFWND_ImmIsUIMessageW.
[wine] / dlls / quartz / filtergraph.c
1 /*              DirectShow FilterGraph object (QUARTZ.DLL)
2  *
3  * Copyright 2002 Lionel Ulmer
4  * Copyright 2004 Christian Costa
5  *
6  * This file contains the (internal) driver registration functions,
7  * driver enumeration APIs and DirectDraw creation functions.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25 #include <stdarg.h>
26
27 #define COBJMACROS
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "dshow.h"
33 #include "wine/debug.h"
34 #include "quartz_private.h"
35 #define COM_NO_WINDOWS_H
36 #include "ole2.h"
37 #include "olectl.h"
38 #include "strmif.h"
39 #include "vfwmsgs.h"
40 #include "evcode.h"
41 #include "wine/unicode.h"
42
43
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
45
46 typedef struct {
47     HWND hWnd;      /* Target window */
48     long msg;       /* User window message */
49     long instance;  /* User data */
50     int  disabled;  /* Disabled messages posting */
51 } WndNotify;
52
53 typedef struct {
54     long lEventCode;   /* Event code */
55     LONG_PTR lParam1;  /* Param1 */
56     LONG_PTR lParam2;  /* Param2 */
57 } Event;
58
59 /* messages ring implementation for queuing events (taken from winmm) */
60 #define EVENTS_RING_BUFFER_INCREMENT      64
61 typedef struct {
62     Event* messages;
63     int ring_buffer_size;
64     int msg_tosave;
65     int msg_toget;
66     CRITICAL_SECTION msg_crst;
67     HANDLE msg_event; /* Signaled for no empty queue */
68 } EventsQueue;
69
70 static int EventsQueue_Init(EventsQueue* omr)
71 {
72     omr->msg_toget = 0;
73     omr->msg_tosave = 0;
74     omr->msg_event = CreateEventW(NULL, TRUE, FALSE, NULL);
75     omr->ring_buffer_size = EVENTS_RING_BUFFER_INCREMENT;
76     omr->messages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,omr->ring_buffer_size * sizeof(Event));
77
78     InitializeCriticalSection(&omr->msg_crst);
79     return TRUE;
80 }
81
82 static int EventsQueue_Destroy(EventsQueue* omr)
83 {
84     CloseHandle(omr->msg_event);
85     HeapFree(GetProcessHeap(),0,omr->messages);
86     DeleteCriticalSection(&omr->msg_crst);
87     return TRUE;
88 }
89
90 static int EventsQueue_PutEvent(EventsQueue* omr, Event* evt)
91 {
92     EnterCriticalSection(&omr->msg_crst);
93     if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size)))
94     {
95         int old_ring_buffer_size = omr->ring_buffer_size;
96         omr->ring_buffer_size += EVENTS_RING_BUFFER_INCREMENT;
97         TRACE("omr->ring_buffer_size=%d\n",omr->ring_buffer_size);
98         omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(Event));
99         /* Now we need to rearrange the ring buffer so that the new
100            buffers just allocated are in between omr->msg_tosave and
101            omr->msg_toget.
102         */
103         if (omr->msg_tosave < omr->msg_toget)
104         {
105             memmove(&(omr->messages[omr->msg_toget + EVENTS_RING_BUFFER_INCREMENT]),
106                     &(omr->messages[omr->msg_toget]),
107                     sizeof(Event)*(old_ring_buffer_size - omr->msg_toget)
108                     );
109             omr->msg_toget += EVENTS_RING_BUFFER_INCREMENT;
110         }
111     }
112     omr->messages[omr->msg_tosave] = *evt;
113     SetEvent(omr->msg_event);
114     omr->msg_tosave = (omr->msg_tosave + 1) % omr->ring_buffer_size;
115     LeaveCriticalSection(&omr->msg_crst);
116     return TRUE;
117 }
118
119 static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut)
120 {
121     if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0)
122         return FALSE;
123         
124     EnterCriticalSection(&omr->msg_crst);
125
126     if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
127     {
128         LeaveCriticalSection(&omr->msg_crst);
129         return FALSE;
130     }
131
132     *evt = omr->messages[omr->msg_toget];
133     omr->msg_toget = (omr->msg_toget + 1) % omr->ring_buffer_size;
134
135     /* Mark the buffer as empty if needed */
136     if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
137         ResetEvent(omr->msg_event);
138
139     LeaveCriticalSection(&omr->msg_crst);
140     return TRUE;
141 }
142
143 typedef struct _IFilterGraphImpl {
144     IGraphBuilderVtbl *IGraphBuilder_vtbl;
145     IMediaControlVtbl *IMediaControl_vtbl;
146     IMediaSeekingVtbl *IMediaSeeking_vtbl;
147     IBasicAudioVtbl *IBasicAudio_vtbl;
148     IBasicVideoVtbl *IBasicVideo_vtbl;
149     IVideoWindowVtbl *IVideoWindow_vtbl;
150     IMediaEventExVtbl *IMediaEventEx_vtbl;
151     IMediaFilterVtbl *IMediaFilter_vtbl;
152     IMediaEventSinkVtbl *IMediaEventSink_vtbl;
153     /* IAMGraphStreams */
154     /* IAMStats */
155     /* IBasicVideo2 */
156     /* IFilterChain */
157     /* IFilterGraph2 */
158     /* IFilterMapper2 */
159     /* IGraphConfig */
160     /* IGraphVersion */
161     /* IMediaPosition */
162     /* IQueueCommand */
163     /* IRegisterServiceProvider */
164     /* IResourceMananger */
165     /* IServiceProvider */
166     /* IVideoFrameStep */
167
168     ULONG ref;
169     IFilterMapper2 * pFilterMapper2;
170     IBaseFilter ** ppFiltersInGraph;
171     LPWSTR * pFilterNames;
172     int nFilters;
173     int filterCapacity;
174     long nameIndex;
175     EventsQueue evqueue;
176     HANDLE hEventCompletion;
177     int CompletionStatus;
178     WndNotify notif;
179     int nRenderers;
180     int EcCompleteCount;
181     int HandleEcComplete;
182     int HandleEcRepaint;
183 } IFilterGraphImpl;
184
185
186 static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
187                                           REFIID riid,
188                                           LPVOID *ppvObj) {
189     TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
190     
191     if (IsEqualGUID(&IID_IUnknown, riid) ||
192         IsEqualGUID(&IID_IFilterGraph, riid) ||
193         IsEqualGUID(&IID_IGraphBuilder, riid)) {
194         *ppvObj = &(This->IGraphBuilder_vtbl);
195         TRACE("   returning IGraphBuilder interface (%p)\n", *ppvObj);
196     } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
197         *ppvObj = &(This->IMediaControl_vtbl);
198         TRACE("   returning IMediaControl interface (%p)\n", *ppvObj);
199     } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
200         *ppvObj = &(This->IMediaSeeking_vtbl);
201         TRACE("   returning IMediaSeeking interface (%p)\n", *ppvObj);
202     } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
203         *ppvObj = &(This->IBasicAudio_vtbl);
204         TRACE("   returning IBasicAudio interface (%p)\n", *ppvObj);
205     } else if (IsEqualGUID(&IID_IBasicVideo, riid)) {
206         *ppvObj = &(This->IBasicVideo_vtbl);
207         TRACE("   returning IBasicVideo interface (%p)\n", *ppvObj);
208     } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
209         *ppvObj = &(This->IVideoWindow_vtbl);
210         TRACE("   returning IVideoWindow interface (%p)\n", *ppvObj);
211     } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
212            IsEqualGUID(&IID_IMediaEventEx, riid)) {
213         *ppvObj = &(This->IMediaEventEx_vtbl);
214         TRACE("   returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
215     } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
216           IsEqualGUID(&IID_IPersist, riid)) {
217         *ppvObj = &(This->IMediaFilter_vtbl);
218         TRACE("   returning IMediaFilter interface (%p)\n", *ppvObj);
219     } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
220         *ppvObj = &(This->IMediaEventSink_vtbl);
221         TRACE("   returning IMediaEventSink interface (%p)\n", *ppvObj);
222     } else {
223         *ppvObj = NULL;
224         FIXME("unknown interface %s\n", debugstr_guid(riid));
225         return E_NOINTERFACE;
226     }
227
228     This->ref++;
229     return S_OK;
230 }
231
232 static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
233     TRACE("(%p)->(): new ref = %ld\n", This, This->ref + 1);
234     
235     return ++This->ref;
236 }
237
238 static ULONG Filtergraph_Release(IFilterGraphImpl *This) {
239     static ULONG ref;
240     
241     TRACE("(%p)->(): new ref = %ld\n", This, This->ref - 1);
242     
243     ref = --This->ref;
244     if (ref == 0) {
245         IFilterMapper2_Release(This->pFilterMapper2);
246         CloseHandle(This->hEventCompletion);
247         EventsQueue_Destroy(&This->evqueue);
248         HeapFree(GetProcessHeap(), 0, This->ppFiltersInGraph);
249         HeapFree(GetProcessHeap(), 0, This->pFilterNames);
250         HeapFree(GetProcessHeap(), 0, This);
251     }
252     return ref;
253 }
254
255
256 /*** IUnknown methods ***/
257 static HRESULT WINAPI Graphbuilder_QueryInterface(IGraphBuilder *iface,
258                                                   REFIID riid,
259                                                   LPVOID*ppvObj) {
260     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
261     
262     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
263     return Filtergraph_QueryInterface(This, riid, ppvObj);
264 }
265
266 static ULONG WINAPI Graphbuilder_AddRef(IGraphBuilder *iface) {
267     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
268     
269     TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
270     
271     return Filtergraph_AddRef(This);
272 }
273
274 static ULONG WINAPI Graphbuilder_Release(IGraphBuilder *iface) {
275     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
276     
277     TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
278
279     return Filtergraph_Release(This);
280 }
281
282 /*** IFilterGraph methods ***/
283 static HRESULT WINAPI Graphbuilder_AddFilter(IGraphBuilder *iface,
284                                              IBaseFilter *pFilter,
285                                              LPCWSTR pName) {
286     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
287     HRESULT hr;
288     int i,j;
289     WCHAR* wszFilterName = NULL;
290     int duplicate_name = FALSE;
291     
292     TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
293
294     wszFilterName = (WCHAR*) CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
295     
296     if (pName)
297     {
298         /* Check if name already exists */
299         for(i = 0; i < This->nFilters; i++)
300             if (!strcmpW(This->pFilterNames[i], pName))
301             {
302                 duplicate_name = TRUE;
303                 break;
304             }
305     }
306
307     /* If no name given or name already existing, generate one */
308     if (!pName || duplicate_name)
309     {
310         static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
311         static const WCHAR wszFmt2[] = {'%','0','4','d',0};
312
313         for (j = 0; j < 10000 ; j++)
314         {
315             /* Create name */
316             if (pName)
317                 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
318             else
319                 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
320             TRACE("Generated name %s\n", debugstr_w(wszFilterName));
321
322             /* Check if the generated name already exists */
323             for(i = 0; i < This->nFilters; i++)
324                 if (!strcmpW(This->pFilterNames[i], wszFilterName))
325                     break;
326
327             /* Compute next index and exit if generated name is suitable */
328             if (This->nameIndex++ == 10000)
329                 This->nameIndex = 1;
330             if (i == This->nFilters)
331                 break;
332         }
333         /* Unable to find a suitable name */
334         if (j == 10000)
335         {
336             CoTaskMemFree(wszFilterName);
337             return VFW_E_DUPLICATE_NAME;
338         }
339     }
340     else
341         memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
342
343     if (This->nFilters + 1 > This->filterCapacity)
344     {
345         int newCapacity = 2*This->filterCapacity;
346         IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
347         LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
348         memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
349         memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
350         CoTaskMemFree(This->ppFiltersInGraph);
351         CoTaskMemFree(This->pFilterNames);
352         This->ppFiltersInGraph = ppNewFilters;
353         This->pFilterNames = pNewNames;
354         This->filterCapacity = newCapacity;
355     }
356
357     hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
358
359     if (SUCCEEDED(hr))
360     {
361         IBaseFilter_AddRef(pFilter);
362         This->ppFiltersInGraph[This->nFilters] = pFilter;
363         This->pFilterNames[This->nFilters] = wszFilterName;
364         This->nFilters++;
365     }
366     else
367         CoTaskMemFree(wszFilterName);
368
369     if (SUCCEEDED(hr) && duplicate_name)
370         return VFW_S_DUPLICATE_NAME;
371         
372     return hr;
373 }
374
375 static HRESULT WINAPI Graphbuilder_RemoveFilter(IGraphBuilder *iface,
376                                                 IBaseFilter *pFilter) {
377     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
378     int i;
379     HRESULT hr = E_FAIL;
380
381     TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
382
383     /* FIXME: check graph is stopped */
384
385     for (i = 0; i < This->nFilters; i++)
386     {
387         if (This->ppFiltersInGraph[i] == pFilter)
388         {
389             /* FIXME: disconnect pins */
390             hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
391             if (SUCCEEDED(hr))
392             {
393                 IPin_Release(pFilter);
394                 CoTaskMemFree(This->pFilterNames[i]);
395                 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
396                 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
397                 This->nFilters--;
398                 return S_OK;
399             }
400             break;
401         }
402     }
403
404     return hr; /* FIXME: check this error code */
405 }
406
407 static HRESULT WINAPI Graphbuilder_EnumFilters(IGraphBuilder *iface,
408                                               IEnumFilters **ppEnum) {
409     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
410
411     TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
412
413     return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
414 }
415
416 static HRESULT WINAPI Graphbuilder_FindFilterByName(IGraphBuilder *iface,
417                                                     LPCWSTR pName,
418                                                     IBaseFilter **ppFilter) {
419     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
420     int i;
421
422     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
423
424     *ppFilter = NULL;
425
426     for (i = 0; i < This->nFilters; i++)
427     {
428         if (!strcmpW(pName, This->pFilterNames[i]))
429         {
430             *ppFilter = This->ppFiltersInGraph[i];
431             IBaseFilter_AddRef(*ppFilter);
432             return S_OK;
433         }
434     }
435
436     return E_FAIL; /* FIXME: check this error code */
437 }
438
439 /* NOTE: despite the implication, it doesn't matter which
440  * way round you put in the input and output pins */
441 static HRESULT WINAPI Graphbuilder_ConnectDirect(IGraphBuilder *iface,
442                                                  IPin *ppinIn,
443                                                  IPin *ppinOut,
444                                                  const AM_MEDIA_TYPE *pmt) {
445     PIN_DIRECTION dir;
446     HRESULT hr;
447
448     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
449
450     TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
451
452     /* FIXME: check pins are in graph */
453
454     hr = IPin_QueryDirection(ppinIn, &dir);
455     if (SUCCEEDED(hr))
456     {
457         if (dir == PINDIR_INPUT)
458             hr = IPin_Connect(ppinOut, ppinIn, pmt);
459         else
460             hr = IPin_Connect(ppinIn, ppinOut, pmt);
461     }
462
463     return hr;
464 }
465
466 static HRESULT WINAPI Graphbuilder_Reconnect(IGraphBuilder *iface,
467                                              IPin *ppin) {
468     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
469
470     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppin);
471
472     return S_OK;
473 }
474
475 static HRESULT WINAPI Graphbuilder_Disconnect(IGraphBuilder *iface,
476                                               IPin *ppin) {
477     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
478
479     TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
480
481     return IPin_Disconnect(ppin);
482 }
483
484 static HRESULT WINAPI Graphbuilder_SetDefaultSyncSource(IGraphBuilder *iface) {
485     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
486
487     TRACE("(%p/%p)->(): stub !!!\n", iface, This);
488
489     return S_OK;
490 }
491
492 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
493 {
494     static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
495     static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
496     IPropertyBag * pPropBagCat = NULL;
497     HRESULT hr;
498     
499     VariantInit(pvar);
500     V_VT(pvar) = VT_BSTR;
501
502     hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
503
504     if (SUCCEEDED(hr))
505         hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
506
507     if (SUCCEEDED(hr))
508         hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
509
510     if (SUCCEEDED(hr))
511         hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
512
513     if (SUCCEEDED(hr))
514         TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
515
516     if (pPropBagCat)
517         IPropertyBag_Release(pPropBagCat);
518
519     return hr;
520 }
521
522 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* poutputpin, IPin*** pppins, ULONG* pnb)
523 {
524     HRESULT hr;
525     ULONG nb = 0;
526
527     TRACE("\n");
528     hr = IPin_QueryInternalConnections(poutputpin, NULL, &nb);
529     if (hr == S_OK) {
530         /* Rendered input */
531     } else if (hr == S_FALSE) {
532         *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
533         hr = IPin_QueryInternalConnections(poutputpin, *pppins, &nb);
534         if (hr != S_OK) {
535             ERR("Error (%lx)\n", hr);
536         }
537     } else if (hr == E_NOTIMPL) {
538         /* Input connected to all outputs */
539         IEnumPins* penumpins;
540         IPin* ppin;
541         int i = 0;
542         TRACE("E_NOTIMPL\n");
543         hr = IBaseFilter_EnumPins(pfilter, &penumpins);
544         if (FAILED(hr)) {
545             ERR("filter Enumpins failed (%lx)\n", hr);
546             return hr;
547         }
548         i = 0;
549         /* Count output pins */
550         while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
551             PIN_DIRECTION pindir;
552             IPin_QueryDirection(ppin, &pindir);
553             if (pindir == PINDIR_OUTPUT)
554                 i++;
555             else
556                 IPin_Release(ppin);
557         }
558         *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
559         /* Retreive output pins */
560         IEnumPins_Reset(penumpins);
561         i = 0;
562         while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
563             PIN_DIRECTION pindir;
564             IPin_QueryDirection(ppin, &pindir);
565             if (pindir == PINDIR_OUTPUT)
566                 (*pppins)[i++] = ppin;
567             else
568                 IPin_Release(ppin);
569         }
570         nb = i;
571         if (FAILED(hr)) {
572             ERR("Next failed (%lx)\n", hr);
573             return hr;
574         }
575         IEnumPins_Release(penumpins);
576     } else if (FAILED(hr)) {
577         ERR("Cannot get internal connection (%lx)\n", hr);
578         return hr;
579     }
580
581     *pnb = nb;
582     return S_OK;
583 }
584
585 /*** IGraphBuilder methods ***/
586 static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
587                                            IPin *ppinOut,
588                                            IPin *ppinIn) {
589     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
590     HRESULT hr;
591     AM_MEDIA_TYPE* mt;
592     IEnumMediaTypes* penummt;
593     ULONG nbmt;
594     IEnumPins* penumpins;
595     IEnumMoniker* pEnumMoniker;
596     GUID tab[2];
597     ULONG nb;
598     IMoniker* pMoniker;
599     ULONG pin;
600
601     TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
602
603     /* Try direct connection first */
604     TRACE("Try direct connection first\n");
605     hr = IPin_Connect(ppinOut, ppinIn, NULL);
606     if (SUCCEEDED(hr)) {
607         TRACE("Direct connection successfull\n");
608         return S_OK;
609     }
610     TRACE("Direct connection failed, trying to insert other filters\n");
611
612     /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream 
613      * filter to the minor mediatype of input pin of the renderer */
614     hr = IPin_EnumMediaTypes(ppinOut, &penummt);
615     if (FAILED(hr)) {
616         ERR("EnumMediaTypes (%lx)\n", hr);
617         return hr;
618     }
619
620     hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
621     if (FAILED(hr)) {
622         ERR("IEnumMediaTypes_Next (%lx)\n", hr);
623         return hr;
624     }
625
626     if (!nbmt) {
627         ERR("No media type found!\n");
628         return S_OK;
629     }
630     TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
631     TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
632
633     /* Try to find a suitable filter that can connect to the pin to render */
634     tab[0] = mt->majortype;
635     tab[1] = mt->subtype;
636     hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
637     if (FAILED(hr)) {
638         ERR("Unable to enum filters (%lx)\n", hr);
639         return hr;
640     }
641     
642     while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
643     {
644         VARIANT var;
645         GUID clsid;
646         IPin** ppins;
647         IPin* ppinfilter;
648         IBaseFilter* pfilter = NULL;
649
650         hr = GetFilterInfo(pMoniker, &clsid, &var);
651         IMoniker_Release(pMoniker);
652         if (FAILED(hr)) {
653            ERR("Unable to retreive filter info (%lx)\n", hr);
654            goto error;
655         }
656
657         hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
658         if (FAILED(hr)) {
659            ERR("Unable to create filter (%lx), trying next one\n", hr);
660            goto error;
661         }
662
663         hr = IGraphBuilder_AddFilter(iface, pfilter, NULL);
664         if (FAILED(hr)) {
665             ERR("Unable to add filter (%lx)\n", hr);
666             IBaseFilter_Release(pfilter);
667             pfilter = NULL;
668             goto error;
669         }
670
671         hr = IBaseFilter_EnumPins(pfilter, &penumpins);
672         if (FAILED(hr)) {
673             ERR("Enumpins (%lx)\n", hr);
674             goto error;
675         }
676         hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
677         if (FAILED(hr)) {
678             ERR("Next (%lx)\n", hr);
679             goto error;
680         }
681         if (pin == 0) {
682             ERR("No Pin\n");
683             goto error;
684         }
685         IEnumPins_Release(penumpins);
686
687         hr = IPin_Connect(ppinOut, ppinfilter, NULL);
688         if (FAILED(hr)) {
689             TRACE("Cannot connect to filter (%lx), trying next one\n", hr);
690             goto error;
691         }
692         TRACE("Successfully connected to filter, follow chain...\n");
693
694         /* Render all output pins of the filter by calling IGraphBuilder_Render on each of them */
695         hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
696
697         if (SUCCEEDED(hr)) {
698             int i;
699             TRACE("pins to consider: %ld\n", nb);
700             for(i = 0; i < nb; i++) {
701                 TRACE("Processing pin %d\n", i);
702                 hr = IGraphBuilder_Connect(iface, ppins[0], ppinIn);
703                 if (FAILED(hr)) {
704                     TRACE("Cannot render pin %p (%lx)\n", ppinfilter, hr);
705                     return hr;
706                 }
707             }
708             CoTaskMemFree(ppins);
709         }
710         break;
711
712 error:
713         if (pfilter) {
714             IGraphBuilder_RemoveFilter(iface, pfilter);
715             IBaseFilter_Release(pfilter);
716         }
717     }
718
719     IEnumMediaTypes_Release(penummt);
720     DeleteMediaType(mt);
721     
722     return S_OK;
723 }
724
725 static HRESULT WINAPI Graphbuilder_Render(IGraphBuilder *iface,
726                                           IPin *ppinOut) {
727     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
728     IEnumMediaTypes* penummt;
729     AM_MEDIA_TYPE* mt;
730     ULONG nbmt;
731     HRESULT hr;
732
733     IEnumMoniker* pEnumMoniker;
734     GUID tab[2];
735     ULONG nb;
736     IMoniker* pMoniker;
737
738     TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
739
740     hr = IPin_EnumMediaTypes(ppinOut, &penummt);
741     if (FAILED(hr)) {
742         ERR("EnumMediaTypes (%lx)\n", hr);
743         return hr;
744     }
745
746     while(1)
747     {
748         hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
749         if (FAILED(hr)) {
750             ERR("IEnumMediaTypes_Next (%lx)\n", hr);
751             return hr;
752         }
753         if (!nbmt)
754             break;
755         TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
756         TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
757
758         /* Try to find a suitable renderer with the same media type */
759         tab[0] = mt->majortype;
760         tab[1] = GUID_NULL;
761         hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL);
762         if (FAILED(hr)) {
763             ERR("Unable to enum filters (%lx)\n", hr);
764             return hr;
765         }
766
767         while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
768         {
769             VARIANT var;
770             GUID clsid;
771             IPin* ppinfilter;
772             IBaseFilter* pfilter = NULL;
773             IEnumPins* penumpins;
774             ULONG pin;
775
776             hr = GetFilterInfo(pMoniker, &clsid, &var);
777             IMoniker_Release(pMoniker);
778             if (FAILED(hr)) {
779                 ERR("Unable to retreive filter info (%lx)\n", hr);
780                 goto error;
781             }
782
783             hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
784             if (FAILED(hr)) {
785                ERR("Unable to create filter (%lx), trying next one\n", hr);
786                goto error;
787             }
788
789             hr = IGraphBuilder_AddFilter(iface, pfilter, NULL);
790             if (FAILED(hr)) {
791                 ERR("Unable to add filter (%lx)\n", hr);
792                 IBaseFilter_Release(pfilter);
793                 pfilter = NULL;
794                 goto error;
795             }
796
797             hr = IBaseFilter_EnumPins(pfilter, &penumpins);
798             if (FAILED(hr)) {
799                 ERR("Splitter Enumpins (%lx)\n", hr);
800                 goto error;
801             }
802             hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
803             if (FAILED(hr)) {
804                ERR("Next (%lx)\n", hr);
805                goto error;
806             }
807             if (pin == 0) {
808                ERR("No Pin\n");
809                goto error;
810             }
811             IEnumPins_Release(penumpins);
812
813             /* Connect the pin to render to the renderer */
814             hr = IGraphBuilder_Connect(iface, ppinOut, ppinfilter);
815             if (FAILED(hr)) {
816                 TRACE("Unable to connect to renderer (%lx)\n", hr);
817                 goto error;
818             }
819             break;
820
821 error:
822             if (pfilter) {
823                 IGraphBuilder_RemoveFilter(iface, pfilter);
824                 IBaseFilter_Release(pfilter);
825             }
826         }
827        
828         DeleteMediaType(mt);
829         break;  
830     }
831
832     IEnumMediaTypes_Release(penummt);
833     
834     return S_OK;
835 }
836
837 static HRESULT WINAPI Graphbuilder_RenderFile(IGraphBuilder *iface,
838                                               LPCWSTR lpcwstrFile,
839                                               LPCWSTR lpcwstrPlayList) {
840     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
841     static const WCHAR string[] = {'R','e','a','d','e','r',0};
842     IBaseFilter* preader = NULL;
843     IBaseFilter* psplitter;
844     IPin* ppinreader;
845     IPin* ppinsplitter;
846     IEnumPins* penumpins;
847     ULONG pin;
848     HRESULT hr;
849     IEnumMoniker* pEnumMoniker;
850     GUID tab[2];
851     IPin** ppins;
852     ULONG nb;
853     IMoniker* pMoniker;
854     IFileSourceFilter* pfile = NULL;
855     AM_MEDIA_TYPE mt;
856     WCHAR* filename;
857
858     TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
859
860     hr = IGraphBuilder_AddSourceFilter(iface, lpcwstrFile, string, &preader);
861
862     /* Retreive file media type */
863     if (SUCCEEDED(hr))
864         hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
865     if (SUCCEEDED(hr)) {
866         hr = IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
867         IFileSourceFilter_Release(pfile);
868     }
869
870     if (SUCCEEDED(hr)) {
871         tab[0] = mt.majortype;
872         tab[1] = mt.subtype;
873         hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
874     } else {
875         if (preader) {
876              IGraphBuilder_RemoveFilter(iface, preader);
877              IBaseFilter_Release(preader);
878         }
879         return hr;
880     }
881
882     while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
883     {
884         VARIANT var;
885         GUID clsid;
886
887         hr = GetFilterInfo(pMoniker, &clsid, &var);
888         IMoniker_Release(pMoniker);
889         if (FAILED(hr)) {
890             ERR("Unable to retreive filter info (%lx)\n", hr);
891             continue;
892         }
893
894         hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&psplitter);
895         if (FAILED(hr)) {
896            ERR("Unable to create filter (%lx), trying next one\n", hr);
897            continue;
898         }
899
900         hr = IGraphBuilder_AddFilter(iface, psplitter, NULL);
901         if (FAILED(hr)) {
902             ERR("Unable add filter (%lx)\n", hr);
903             return hr;
904         }
905
906         /* Connect file source and splitter filters together */
907         /* Make the splitter analyze incoming data */
908         hr = IBaseFilter_EnumPins(preader, &penumpins);
909         if (FAILED(hr)) {
910             ERR("Enumpins (%lx)\n", hr);
911             return hr;
912         }
913         hr = IEnumPins_Next(penumpins, 1, &ppinreader, &pin);
914         if (FAILED(hr)) {
915             ERR("Next (%lx)\n", hr);
916             return hr;
917         }
918         if (pin == 0) {
919             ERR("No Pin\n");
920             return E_FAIL;
921         }
922         IEnumPins_Release(penumpins);
923
924         hr = IBaseFilter_EnumPins(psplitter, &penumpins);
925         if (FAILED(hr)) {
926             ERR("Splitter Enumpins (%lx)\n", hr);
927             return hr;
928         }
929         hr = IEnumPins_Next(penumpins, 1, &ppinsplitter, &pin);
930         if (FAILED(hr)) {
931             ERR("Next (%lx)\n", hr);
932             return hr;
933         }
934         if (pin == 0) {
935             ERR("No Pin\n");
936             return E_FAIL;
937         }
938         IEnumPins_Release(penumpins);
939
940         hr = IPin_Connect(ppinreader, ppinsplitter, NULL);
941         if (FAILED(hr)) {
942             IBaseFilter_Release(ppinsplitter);
943             ppinsplitter = NULL;
944             TRACE("Cannot connect to filter (%lx), trying next one\n", hr);
945             break;
946         }
947         TRACE("Successfully connected to filter\n");
948         break;
949     }
950
951     /* Render all output pin of the splitter by calling IGraphBuilder_Render on each of them */
952     hr = GetInternalConnections(psplitter, ppinsplitter, &ppins, &nb);
953     
954     if (SUCCEEDED(hr)) {
955         int i;
956         TRACE("pins to consider: %ld\n", nb);
957         for(i = 0; i < nb; i++) {
958             TRACE("Processing pin %d\n", i);
959             hr = IGraphBuilder_Render(iface, ppins[i]);
960             if (FAILED(hr)) {
961                 ERR("Cannot render pin %p (%lx)\n", ppins[i], hr);
962                 /* FIXME: We should clean created things properly */
963                 break;
964             }
965         }
966     }
967     CoTaskMemFree(ppins);
968     
969     return S_OK;
970 }
971
972 static HRESULT WINAPI Graphbuilder_AddSourceFilter(IGraphBuilder *iface,
973                                                    LPCWSTR lpcwstrFileName,
974                                                    LPCWSTR lpcwstrFilterName,
975                                                    IBaseFilter **ppFilter) {
976     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
977     HRESULT hr;
978     IBaseFilter* preader;
979     IFileSourceFilter* pfile = NULL;
980     AM_MEDIA_TYPE mt;
981     WCHAR* filename;
982
983     TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
984
985     /* Instantiate a file source filter */ 
986     hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
987     if (FAILED(hr)) {
988         ERR("Unable to create file source filter (%lx)\n", hr);
989         return hr;
990     }
991
992     hr = IGraphBuilder_AddFilter(iface, preader, lpcwstrFilterName);
993     if (FAILED(hr)) {
994         ERR("Unable add filter (%lx)\n", hr);
995         IBaseFilter_Release(preader);
996         return hr;
997     }
998
999     hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1000     if (FAILED(hr)) {
1001         ERR("Unable to get IFileSourceInterface (%lx)\n", hr);
1002         goto error;
1003     }
1004
1005     /* Load the file in the file source filter */
1006     hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1007     if (FAILED(hr)) {
1008         ERR("Load (%lx)\n", hr);
1009         goto error;
1010     }
1011     
1012     IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1013     if (FAILED(hr)) {
1014         ERR("GetCurFile (%lx)\n", hr);
1015         goto error;
1016     }
1017     TRACE("File %s\n", debugstr_w(filename));
1018     TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1019     TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1020
1021     if (ppFilter)
1022         *ppFilter = preader;
1023
1024     return S_OK;
1025     
1026 error:
1027     if (pfile)
1028         IFileSourceFilter_Release(pfile);
1029     IGraphBuilder_RemoveFilter(iface, preader);
1030     IBaseFilter_Release(preader);
1031        
1032     return S_OK;
1033 }
1034
1035 static HRESULT WINAPI Graphbuilder_SetLogFile(IGraphBuilder *iface,
1036                                               DWORD_PTR hFile) {
1037     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1038
1039     TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) hFile);
1040
1041     return S_OK;
1042 }
1043
1044 static HRESULT WINAPI Graphbuilder_Abort(IGraphBuilder *iface) {
1045     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1046
1047     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1048
1049     return S_OK;
1050 }
1051
1052 static HRESULT WINAPI Graphbuilder_ShouldOperationContinue(IGraphBuilder *iface) {
1053     ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1054
1055     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1056
1057     return S_OK;
1058 }
1059
1060
1061 static IGraphBuilderVtbl IGraphBuilder_VTable =
1062 {
1063     Graphbuilder_QueryInterface,
1064     Graphbuilder_AddRef,
1065     Graphbuilder_Release,
1066     Graphbuilder_AddFilter,
1067     Graphbuilder_RemoveFilter,
1068     Graphbuilder_EnumFilters,
1069     Graphbuilder_FindFilterByName,
1070     Graphbuilder_ConnectDirect,
1071     Graphbuilder_Reconnect,
1072     Graphbuilder_Disconnect,
1073     Graphbuilder_SetDefaultSyncSource,
1074     Graphbuilder_Connect,
1075     Graphbuilder_Render,
1076     Graphbuilder_RenderFile,
1077     Graphbuilder_AddSourceFilter,
1078     Graphbuilder_SetLogFile,
1079     Graphbuilder_Abort,
1080     Graphbuilder_ShouldOperationContinue
1081 };
1082
1083 /*** IUnknown methods ***/
1084 static HRESULT WINAPI Mediacontrol_QueryInterface(IMediaControl *iface,
1085                                                   REFIID riid,
1086                                                   LPVOID*ppvObj) {
1087     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1088
1089     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1090
1091     return Filtergraph_QueryInterface(This, riid, ppvObj);
1092 }
1093
1094 static ULONG WINAPI Mediacontrol_AddRef(IMediaControl *iface) {
1095     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1096
1097     TRACE("(%p/%p)->()\n", This, iface);
1098
1099     return Filtergraph_AddRef(This);
1100 }
1101
1102 static ULONG WINAPI Mediacontrol_Release(IMediaControl *iface) {
1103     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1104
1105     TRACE("(%p/%p)->()\n", This, iface);
1106
1107     return Filtergraph_Release(This);
1108
1109 }
1110
1111 /*** IDispatch methods ***/
1112 static HRESULT WINAPI Mediacontrol_GetTypeInfoCount(IMediaControl *iface,
1113                                                     UINT*pctinfo) {
1114     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1115
1116     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1117
1118     return S_OK;
1119 }
1120
1121 static HRESULT WINAPI Mediacontrol_GetTypeInfo(IMediaControl *iface,
1122                                                UINT iTInfo,
1123                                                LCID lcid,
1124                                                ITypeInfo**ppTInfo) {
1125     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1126
1127     TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1128
1129     return S_OK;
1130 }
1131
1132 static HRESULT WINAPI Mediacontrol_GetIDsOfNames(IMediaControl *iface,
1133                                                  REFIID riid,
1134                                                  LPOLESTR*rgszNames,
1135                                                  UINT cNames,
1136                                                  LCID lcid,
1137                                                  DISPID*rgDispId) {
1138     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1139
1140     TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1141
1142     return S_OK;
1143 }
1144
1145 static HRESULT WINAPI Mediacontrol_Invoke(IMediaControl *iface,
1146                                           DISPID dispIdMember,
1147                                           REFIID riid,
1148                                           LCID lcid,
1149                                           WORD wFlags,
1150                                           DISPPARAMS*pDispParams,
1151                                           VARIANT*pVarResult,
1152                                           EXCEPINFO*pExepInfo,
1153                                           UINT*puArgErr) {
1154     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1155
1156     TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
1157
1158     return S_OK;
1159 }
1160
1161 /*** IMediaControl methods ***/
1162 static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) {
1163     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1164
1165     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1166
1167     ResetEvent(This->hEventCompletion);
1168
1169     return S_OK;
1170 }
1171
1172 static HRESULT WINAPI Mediacontrol_Pause(IMediaControl *iface) {
1173     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1174
1175     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1176
1177     return S_OK;
1178 }
1179
1180 static HRESULT WINAPI Mediacontrol_Stop(IMediaControl *iface) {
1181     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1182
1183     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1184
1185     return S_OK;
1186 }
1187
1188 static HRESULT WINAPI Mediacontrol_GetState(IMediaControl *iface,
1189                                             LONG msTimeout,
1190                                             OAFilterState *pfs) {
1191     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1192
1193     TRACE("(%p/%p)->(%ld, %p): stub !!!\n", This, iface, msTimeout, pfs);
1194
1195     return S_OK;
1196 }
1197
1198 static HRESULT WINAPI Mediacontrol_RenderFile(IMediaControl *iface,
1199                                               BSTR strFilename) {
1200     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1201
1202     TRACE("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
1203
1204     return S_OK;
1205 }
1206
1207 static HRESULT WINAPI Mediacontrol_AddSourceFilter(IMediaControl *iface,
1208                                                    BSTR strFilename,
1209                                                    IDispatch **ppUnk) {
1210     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1211
1212     TRACE("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
1213
1214     return S_OK;
1215 }
1216
1217 static HRESULT WINAPI Mediacontrol_get_FilterCollection(IMediaControl *iface,
1218                                                         IDispatch **ppUnk) {
1219     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1220
1221     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1222
1223     return S_OK;
1224 }
1225
1226 static HRESULT WINAPI Mediacontrol_get_RegFilterCollection(IMediaControl *iface,
1227                                                            IDispatch **ppUnk) {
1228     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1229
1230     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1231
1232     return S_OK;
1233 }
1234
1235 static HRESULT WINAPI Mediacontrol_StopWhenReady(IMediaControl *iface) {
1236     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1237
1238     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1239
1240     return S_OK;
1241 }
1242
1243
1244 static IMediaControlVtbl IMediaControl_VTable =
1245 {
1246     Mediacontrol_QueryInterface,
1247     Mediacontrol_AddRef,
1248     Mediacontrol_Release,
1249     Mediacontrol_GetTypeInfoCount,
1250     Mediacontrol_GetTypeInfo,
1251     Mediacontrol_GetIDsOfNames,
1252     Mediacontrol_Invoke,
1253     Mediacontrol_Run,
1254     Mediacontrol_Pause,
1255     Mediacontrol_Stop,
1256     Mediacontrol_GetState,
1257     Mediacontrol_RenderFile,
1258     Mediacontrol_AddSourceFilter,
1259     Mediacontrol_get_FilterCollection,
1260     Mediacontrol_get_RegFilterCollection,
1261     Mediacontrol_StopWhenReady
1262 };
1263
1264
1265 /*** IUnknown methods ***/
1266 static HRESULT WINAPI Mediaseeking_QueryInterface(IMediaSeeking *iface,
1267                                                   REFIID riid,
1268                                                   LPVOID*ppvObj) {
1269     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1270
1271     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1272
1273     return Filtergraph_QueryInterface(This, riid, ppvObj);
1274 }
1275
1276 static ULONG WINAPI Mediaseeking_AddRef(IMediaSeeking *iface) {
1277     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1278
1279     TRACE("(%p/%p)->()\n", This, iface);
1280
1281     return Filtergraph_AddRef(This);
1282 }
1283
1284 static ULONG WINAPI Mediaseeking_Release(IMediaSeeking *iface) {
1285     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1286
1287     TRACE("(%p/%p)->()\n", This, iface);
1288
1289     return Filtergraph_Release(This);
1290 }
1291
1292 /*** IMediaSeeking methods ***/
1293 static HRESULT WINAPI Mediaseeking_GetCapabilities(IMediaSeeking *iface,
1294                                                    DWORD *pCapabilities) {
1295     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1296
1297     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1298
1299     return S_OK;
1300 }
1301
1302 static HRESULT WINAPI Mediaseeking_CheckCapabilities(IMediaSeeking *iface,
1303                                                      DWORD *pCapabilities) {
1304     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1305
1306     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1307
1308     return S_OK;
1309 }
1310
1311 static HRESULT WINAPI Mediaseeking_IsFormatSupported(IMediaSeeking *iface,
1312                                                      const GUID *pFormat) {
1313     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1314
1315     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1316
1317     return S_OK;
1318 }
1319
1320 static HRESULT WINAPI Mediaseeking_QueryPreferredFormat(IMediaSeeking *iface,
1321                                                         GUID *pFormat) {
1322     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1323
1324     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1325
1326     return S_OK;
1327 }
1328
1329 static HRESULT WINAPI Mediaseeking_GetTimeFormat(IMediaSeeking *iface,
1330                                                  GUID *pFormat) {
1331     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1332
1333     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1334
1335     return S_OK;
1336 }
1337
1338 static HRESULT WINAPI Mediaseeking_IsUsingTimeFormat(IMediaSeeking *iface,
1339                                                      const GUID *pFormat) {
1340     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1341
1342     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1343
1344     return S_OK;
1345 }
1346
1347 static HRESULT WINAPI Mediaseeking_SetTimeFormat(IMediaSeeking *iface,
1348                                                  const GUID *pFormat) {
1349     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1350
1351     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1352
1353     return S_OK;
1354 }
1355
1356 static HRESULT WINAPI Mediaseeking_GetDuration(IMediaSeeking *iface,
1357                                                LONGLONG *pDuration) {
1358     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1359
1360     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDuration);
1361
1362     return S_OK;
1363 }
1364
1365 static HRESULT WINAPI Mediaseeking_GetStopPosition(IMediaSeeking *iface,
1366                                                    LONGLONG *pStop) {
1367     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1368
1369     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pStop);
1370
1371     return S_OK;
1372 }
1373
1374 static HRESULT WINAPI Mediaseeking_GetCurrentPosition(IMediaSeeking *iface,
1375                                                       LONGLONG *pCurrent) {
1376     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1377
1378     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCurrent);
1379
1380     return S_OK;
1381 }
1382
1383 static HRESULT WINAPI Mediaseeking_ConvertTimeFormat(IMediaSeeking *iface,
1384                                                      LONGLONG *pTarget,
1385                                                      const GUID *pTargetFormat,
1386                                                      LONGLONG Source,
1387                                                      const GUID *pSourceFormat) {
1388     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1389
1390     TRACE("(%p/%p)->(%p, %p, %lld, %p): stub !!!\n", This, iface, pTarget, pTargetFormat, Source, pSourceFormat);
1391
1392     return S_OK;
1393 }
1394
1395 static HRESULT WINAPI Mediaseeking_SetPositions(IMediaSeeking *iface,
1396                                                 LONGLONG *pCurrent,
1397                                                 DWORD dwCurrentFlags,
1398                                                 LONGLONG *pStop,
1399                                                 DWORD dwStopFlags) {
1400     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1401
1402     TRACE("(%p/%p)->(%p, %08lx, %p, %08lx): stub !!!\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
1403
1404     return S_OK;
1405 }
1406
1407 static HRESULT WINAPI Mediaseeking_GetPositions(IMediaSeeking *iface,
1408                                                 LONGLONG *pCurrent,
1409                                                 LONGLONG *pStop) {
1410     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1411
1412     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pCurrent, pStop);
1413
1414     return S_OK;
1415 }
1416
1417 static HRESULT WINAPI Mediaseeking_GetAvailable(IMediaSeeking *iface,
1418                                                 LONGLONG *pEarliest,
1419                                                 LONGLONG *pLatest) {
1420     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1421
1422     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
1423
1424     return S_OK;
1425 }
1426
1427 static HRESULT WINAPI Mediaseeking_SetRate(IMediaSeeking *iface,
1428                                            double dRate) {
1429     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1430
1431     TRACE("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
1432
1433     return S_OK;
1434 }
1435
1436 static HRESULT WINAPI Mediaseeking_GetRate(IMediaSeeking *iface,
1437                                            double *pdRate) {
1438     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1439
1440     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
1441
1442     return S_OK;
1443 }
1444
1445 static HRESULT WINAPI Mediaseeking_GetPreroll(IMediaSeeking *iface,
1446                                               LONGLONG *pllPreroll) {
1447     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1448
1449     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
1450
1451     return S_OK;
1452 }
1453
1454
1455 static IMediaSeekingVtbl IMediaSeeking_VTable =
1456 {
1457     Mediaseeking_QueryInterface,
1458     Mediaseeking_AddRef,
1459     Mediaseeking_Release,
1460     Mediaseeking_GetCapabilities,
1461     Mediaseeking_CheckCapabilities,
1462     Mediaseeking_IsFormatSupported,
1463     Mediaseeking_QueryPreferredFormat,
1464     Mediaseeking_GetTimeFormat,
1465     Mediaseeking_IsUsingTimeFormat,
1466     Mediaseeking_SetTimeFormat,
1467     Mediaseeking_GetDuration,
1468     Mediaseeking_GetStopPosition,
1469     Mediaseeking_GetCurrentPosition,
1470     Mediaseeking_ConvertTimeFormat,
1471     Mediaseeking_SetPositions,
1472     Mediaseeking_GetPositions,
1473     Mediaseeking_GetAvailable,
1474     Mediaseeking_SetRate,
1475     Mediaseeking_GetRate,
1476     Mediaseeking_GetPreroll
1477 };
1478
1479 /*** IUnknown methods ***/
1480 static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface,
1481                                                 REFIID riid,
1482                                                 LPVOID*ppvObj) {
1483     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1484
1485     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1486
1487     return Filtergraph_QueryInterface(This, riid, ppvObj);
1488 }
1489
1490 static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
1491     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1492
1493     TRACE("(%p/%p)->()\n", This, iface);
1494
1495     return Filtergraph_AddRef(This);
1496 }
1497
1498 static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
1499     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1500
1501     TRACE("(%p/%p)->()\n", This, iface);
1502
1503     return Filtergraph_Release(This);
1504 }
1505
1506 /*** IDispatch methods ***/
1507 static HRESULT WINAPI Basicaudio_GetTypeInfoCount(IBasicAudio *iface,
1508                                                   UINT*pctinfo) {
1509     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1510
1511     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1512
1513     return S_OK;
1514 }
1515
1516 static HRESULT WINAPI Basicaudio_GetTypeInfo(IBasicAudio *iface,
1517                                              UINT iTInfo,
1518                                              LCID lcid,
1519                                              ITypeInfo**ppTInfo) {
1520     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1521
1522     TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1523
1524     return S_OK;
1525 }
1526
1527 static HRESULT WINAPI Basicaudio_GetIDsOfNames(IBasicAudio *iface,
1528                                                REFIID riid,
1529                                                LPOLESTR*rgszNames,
1530                                                UINT cNames,
1531                                                LCID lcid,
1532                                                DISPID*rgDispId) {
1533     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1534
1535     TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1536
1537     return S_OK;
1538 }
1539
1540 static HRESULT WINAPI Basicaudio_Invoke(IBasicAudio *iface,
1541                                         DISPID dispIdMember,
1542                                         REFIID riid,
1543                                         LCID lcid,
1544                                         WORD wFlags,
1545                                         DISPPARAMS*pDispParams,
1546                                         VARIANT*pVarResult,
1547                                         EXCEPINFO*pExepInfo,
1548                                         UINT*puArgErr) {
1549     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1550
1551     TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
1552
1553     return S_OK;
1554 }
1555
1556 /*** IBasicAudio methods ***/
1557 static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface,
1558                                             long lVolume) {
1559     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1560
1561     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, lVolume);
1562
1563     return S_OK;
1564 }
1565
1566 static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface,
1567                                             long *plVolume) {
1568     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1569
1570     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, plVolume);
1571
1572     return S_OK;
1573 }
1574
1575 static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface,
1576                                              long lBalance) {
1577     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1578
1579     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, lBalance);
1580
1581     return S_OK;
1582 }
1583
1584 static HRESULT WINAPI Basicaudio_get_Balance(IBasicAudio *iface,
1585                                              long *plBalance) {
1586     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1587
1588     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, plBalance);
1589
1590     return S_OK;
1591 }
1592
1593 static IBasicAudioVtbl IBasicAudio_VTable =
1594 {
1595     Basicaudio_QueryInterface,
1596     Basicaudio_AddRef,
1597     Basicaudio_Release,
1598     Basicaudio_GetTypeInfoCount,
1599     Basicaudio_GetTypeInfo,
1600     Basicaudio_GetIDsOfNames,
1601     Basicaudio_Invoke,
1602     Basicaudio_put_Volume,
1603     Basicaudio_get_Volume,
1604     Basicaudio_put_Balance,
1605     Basicaudio_get_Balance
1606 };
1607
1608 /*** IUnknown methods ***/
1609 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface,
1610                                                 REFIID riid,
1611                                                 LPVOID*ppvObj) {
1612     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1613
1614     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1615
1616     return Filtergraph_QueryInterface(This, riid, ppvObj);
1617 }
1618
1619 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) {
1620     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1621
1622     TRACE("(%p/%p)->()\n", This, iface);
1623
1624     return Filtergraph_AddRef(This);
1625 }
1626
1627 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) {
1628     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1629
1630     TRACE("(%p/%p)->()\n", This, iface);
1631
1632     return Filtergraph_Release(This);
1633 }
1634
1635 /*** IDispatch methods ***/
1636 static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface,
1637                                                   UINT*pctinfo) {
1638     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1639
1640     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1641
1642     return S_OK;
1643 }
1644
1645 static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface,
1646                                              UINT iTInfo,
1647                                              LCID lcid,
1648                                              ITypeInfo**ppTInfo) {
1649     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1650
1651     TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1652
1653     return S_OK;
1654 }
1655
1656 static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface,
1657                                                REFIID riid,
1658                                                LPOLESTR*rgszNames,
1659                                                UINT cNames,
1660                                                LCID lcid,
1661                                                DISPID*rgDispId) {
1662     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1663
1664     TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1665
1666     return S_OK;
1667 }
1668
1669 static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface,
1670                                         DISPID dispIdMember,
1671                                         REFIID riid,
1672                                         LCID lcid,
1673                                         WORD wFlags,
1674                                         DISPPARAMS*pDispParams,
1675                                         VARIANT*pVarResult,
1676                                         EXCEPINFO*pExepInfo,
1677                                         UINT*puArgErr) {
1678     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1679
1680     TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
1681
1682     return S_OK;
1683 }
1684
1685 /*** IBasicVideo methods ***/
1686 static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface,
1687                                                      REFTIME *pAvgTimePerFrame) {
1688     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1689
1690     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame);
1691
1692     return S_OK;
1693 }
1694
1695 static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface,
1696                                              long *pBitRate) {
1697     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1698
1699     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate);
1700
1701     return S_OK;
1702 }
1703
1704 static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface,
1705                                                   long *pBitErrorRate) {
1706     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1707
1708     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate);
1709
1710     return S_OK;
1711 }
1712
1713 static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface,
1714                                                 long *pVideoWidth) {
1715     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1716
1717     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVideoWidth);
1718
1719     return S_OK;
1720 }
1721
1722 static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface,
1723                                                  long *pVideoHeight) {
1724     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1725
1726     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVideoHeight);
1727
1728     return S_OK;
1729 }
1730
1731 static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface,
1732                                                 long SourceLeft) {
1733     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1734
1735     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceLeft);
1736
1737     return S_OK;
1738 }
1739
1740 static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface,
1741                                                 long *pSourceLeft) {
1742     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1743
1744     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceLeft);
1745
1746     return S_OK;
1747 }
1748
1749 static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface,
1750                                                  long SourceWidth) {
1751     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1752
1753     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceWidth);
1754
1755     return S_OK;
1756 }
1757
1758 static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface,
1759                                                  long *pSourceWidth) {
1760     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1761
1762     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceWidth);
1763
1764     return S_OK;
1765 }
1766
1767 static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface,
1768                                                long SourceTop) {
1769     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1770
1771     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceTop);
1772
1773     return S_OK;
1774 }
1775
1776 static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface,
1777                                                long *pSourceTop) {
1778     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1779
1780     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceTop);
1781
1782     return S_OK;
1783 }
1784
1785 static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface,
1786                                                   long SourceHeight) {
1787     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1788
1789     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceHeight);
1790
1791     return S_OK;
1792 }
1793
1794 static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface,
1795                                                   long *pSourceHeight) {
1796     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1797
1798     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceHeight);
1799
1800     return S_OK;
1801 }
1802
1803 static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface,
1804                                                      long DestinationLeft) {
1805     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1806
1807     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationLeft);
1808
1809     return S_OK;
1810 }
1811
1812 static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface,
1813                                                      long *pDestinationLeft) {
1814     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1815
1816     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationLeft);
1817
1818     return S_OK;
1819 }
1820
1821 static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface,
1822                                                       long DestinationWidth) {
1823     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1824
1825     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationWidth);
1826
1827     return S_OK;
1828 }
1829
1830 static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface,
1831                                                       long *pDestinationWidth) {
1832     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1833
1834     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationWidth);
1835
1836     return S_OK;
1837 }
1838
1839 static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface,
1840                                                     long DestinationTop) {
1841     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1842
1843     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationTop);
1844
1845     return S_OK;
1846 }
1847
1848 static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface,
1849                                                     long *pDestinationTop) {
1850     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1851
1852     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationTop);
1853
1854     return S_OK;
1855 }
1856
1857 static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface,
1858                                                        long DestinationHeight) {
1859     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1860
1861     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationHeight);
1862
1863     return S_OK;
1864 }
1865
1866 static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface,
1867                                                        long *pDestinationHeight) {
1868     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1869
1870     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationHeight);
1871
1872     return S_OK;
1873 }
1874
1875 static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface,
1876                                                    long Left,
1877                                                    long Top,
1878                                                    long Width,
1879                                                    long Height) {
1880     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1881
1882     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
1883
1884     return S_OK;
1885 }
1886
1887 static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface,
1888                                                    long *pLeft,
1889                                                    long *pTop,
1890                                                    long *pWidth,
1891                                                    long *pHeight) {
1892     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1893
1894     TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
1895
1896     return S_OK;
1897 }
1898
1899 static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) {
1900     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1901
1902     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1903
1904     return S_OK;
1905 }
1906
1907 static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface,
1908                                                         long Left,
1909                                                         long Top,
1910                                                         long Width,
1911                                                         long Height) {
1912     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1913
1914     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
1915
1916     return S_OK;
1917 }
1918
1919 static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface,
1920                                                         long *pLeft,
1921                                                         long *pTop,
1922                                                         long *pWidth,
1923                                                         long *pHeight) {
1924     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1925
1926     TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
1927
1928     return S_OK;
1929 }
1930
1931 static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
1932     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1933
1934     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1935
1936     return S_OK;
1937 }
1938
1939 static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface,
1940                                               long *pWidth,
1941                                               long *pHeight) {
1942     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1943
1944     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
1945
1946     return S_OK;
1947 }
1948
1949 static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface,
1950                                                         long StartIndex,
1951                                                         long Entries,
1952                                                         long *pRetrieved,
1953                                                         long *pPalette) {
1954     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1955
1956     TRACE("(%p/%p)->(%ld, %ld, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
1957
1958     return S_OK;
1959 }
1960
1961 static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
1962                                                  long *pBufferSize,
1963                                                  long *pDIBImage) {
1964     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1965
1966     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pBufferSize, pDIBImage);
1967
1968     return S_OK;
1969 }
1970
1971 static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) {
1972     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1973
1974     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1975
1976     return S_OK;
1977 }
1978
1979 static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) {
1980     ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
1981
1982     TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1983
1984     return S_OK;
1985 }
1986
1987
1988 static IBasicVideoVtbl IBasicVideo_VTable =
1989 {
1990     Basicvideo_QueryInterface,
1991     Basicvideo_AddRef,
1992     Basicvideo_Release,
1993     Basicvideo_GetTypeInfoCount,
1994     Basicvideo_GetTypeInfo,
1995     Basicvideo_GetIDsOfNames,
1996     Basicvideo_Invoke,
1997     Basicvideo_get_AvgTimePerFrame,
1998     Basicvideo_get_BitRate,
1999     Basicvideo_get_BitErrorRate,
2000     Basicvideo_get_VideoWidth,
2001     Basicvideo_get_VideoHeight,
2002     Basicvideo_put_SourceLeft,
2003     Basicvideo_get_SourceLeft,
2004     Basicvideo_put_SourceWidth,
2005     Basicvideo_get_SourceWidth,
2006     Basicvideo_put_SourceTop,
2007     Basicvideo_get_SourceTop,
2008     Basicvideo_put_SourceHeight,
2009     Basicvideo_get_SourceHeight,
2010     Basicvideo_put_DestinationLeft,
2011     Basicvideo_get_DestinationLeft,
2012     Basicvideo_put_DestinationWidth,
2013     Basicvideo_get_DestinationWidth,
2014     Basicvideo_put_DestinationTop,
2015     Basicvideo_get_DestinationTop,
2016     Basicvideo_put_DestinationHeight,
2017     Basicvideo_get_DestinationHeight,
2018     Basicvideo_SetSourcePosition,
2019     Basicvideo_GetSourcePosition,
2020     Basicvideo_SetDefaultSourcePosition,
2021     Basicvideo_SetDestinationPosition,
2022     Basicvideo_GetDestinationPosition,
2023     Basicvideo_SetDefaultDestinationPosition,
2024     Basicvideo_GetVideoSize,
2025     Basicvideo_GetVideoPaletteEntries,
2026     Basicvideo_GetCurrentImage,
2027     Basicvideo_IsUsingDefaultSource,
2028     Basicvideo_IsUsingDefaultDestination
2029 };
2030
2031
2032 /*** IUnknown methods ***/
2033 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface,
2034                                                  REFIID riid,
2035                                                  LPVOID*ppvObj) {
2036     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2037
2038     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2039
2040     return Filtergraph_QueryInterface(This, riid, ppvObj);
2041 }
2042
2043 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) {
2044     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2045
2046     TRACE("(%p/%p)->()\n", This, iface);
2047
2048     return Filtergraph_AddRef(This);
2049 }
2050
2051 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) {
2052     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2053
2054     TRACE("(%p/%p)->()\n", This, iface);
2055
2056     return Filtergraph_Release(This);
2057 }
2058
2059 /*** IDispatch methods ***/
2060 static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface,
2061                                                    UINT*pctinfo) {
2062     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2063
2064     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
2065
2066     return S_OK;
2067 }
2068
2069 static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface,
2070                                               UINT iTInfo,
2071                                               LCID lcid,
2072                                               ITypeInfo**ppTInfo) {
2073     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2074
2075     TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
2076
2077     return S_OK;
2078 }
2079
2080 static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface,
2081                                                 REFIID riid,
2082                                                 LPOLESTR*rgszNames,
2083                                                 UINT cNames,
2084                                                 LCID lcid,
2085                                                 DISPID*rgDispId) {
2086     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2087
2088     TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2089
2090     return S_OK;
2091 }
2092
2093 static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface,
2094                                          DISPID dispIdMember,
2095                                          REFIID riid,
2096                                          LCID lcid,
2097                                          WORD wFlags,
2098                                          DISPPARAMS*pDispParams,
2099                                          VARIANT*pVarResult,
2100                                          EXCEPINFO*pExepInfo,
2101                                          UINT*puArgErr) {
2102     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2103
2104     TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2105
2106     return S_OK;
2107 }
2108
2109 /*** IVideoWindow methods ***/
2110 static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface,
2111                                               BSTR strCaption) {
2112     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2113
2114     TRACE("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strCaption), strCaption);
2115
2116     return S_OK;
2117 }
2118
2119 static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface,
2120                                               BSTR *strCaption) {
2121     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2122
2123     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, strCaption);
2124
2125     return S_OK;
2126 }
2127
2128 static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface,
2129                                                   long WindowStyle) {
2130     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2131
2132     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowStyle);
2133
2134     return S_OK;
2135 }
2136
2137 static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface,
2138                                                   long *WindowStyle) {
2139     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2140
2141     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowStyle);
2142
2143     return S_OK;
2144 }
2145
2146 static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface,
2147                                                     long WindowStyleEx) {
2148     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2149
2150     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowStyleEx);
2151
2152     return S_OK;
2153 }
2154
2155 static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface,
2156                                                     long *WindowStyleEx) {
2157     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2158
2159     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowStyleEx);
2160
2161     return S_OK;
2162 }
2163
2164 static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface,
2165                                                long AutoShow) {
2166     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2167
2168     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, AutoShow);
2169
2170     return S_OK;
2171 }
2172
2173 static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface,
2174                                                long *AutoShow) {
2175     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2176
2177     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, AutoShow);
2178
2179     return S_OK;
2180 }
2181
2182 static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface,
2183                                                   long WindowState) {
2184     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2185
2186     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowState);
2187
2188     return S_OK;
2189 }
2190
2191 static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface,
2192                                                   long *WindowState) {
2193     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2194
2195     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState);
2196
2197     return S_OK;
2198 }
2199
2200 static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface,
2201                                                         long BackgroundPalette) {
2202     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2203
2204     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, BackgroundPalette);
2205
2206     return S_OK;
2207 }
2208
2209 static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface,
2210                                                         long *pBackgroundPalette) {
2211     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2212
2213     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette);
2214
2215     return S_OK;
2216 }
2217
2218 static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface,
2219                                               long Visible) {
2220     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2221
2222     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Visible);
2223
2224     return S_OK;
2225 }
2226
2227 static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface,
2228                                               long *pVisible) {
2229     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2230
2231     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVisible);
2232
2233     return S_OK;
2234 }
2235
2236 static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface,
2237                                            long Left) {
2238     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2239
2240     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Left);
2241
2242     return S_OK;
2243 }
2244
2245 static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface,
2246                                            long *pLeft) {
2247     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2248
2249     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pLeft);
2250
2251     return S_OK;
2252 }
2253
2254 static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface,
2255                                             long Width) {
2256     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2257
2258     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Width);
2259
2260     return S_OK;
2261 }
2262
2263 static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface,
2264                                             long *pWidth) {
2265     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2266
2267     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pWidth);
2268
2269     return S_OK;
2270 }
2271
2272 static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface,
2273                                           long Top) {
2274     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2275
2276     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Top);
2277
2278     return S_OK;
2279 }
2280
2281 static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface,
2282                                           long *pTop) {
2283     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2284
2285     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pTop);
2286
2287     return S_OK;
2288 }
2289
2290 static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface,
2291                                              long Height) {
2292     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2293
2294     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Height);
2295
2296     return S_OK;
2297 }
2298
2299 static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface,
2300                                              long *pHeight) {
2301     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2302
2303     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pHeight);
2304
2305     return S_OK;
2306 }
2307
2308 static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface,
2309                                             OAHWND Owner) {
2310     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2311
2312     TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Owner);
2313
2314     return S_OK;
2315 }
2316
2317 static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface,
2318                                             OAHWND *Owner) {
2319     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2320
2321     TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Owner);
2322
2323     return S_OK;
2324 }
2325
2326 static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface,
2327                                                    OAHWND Drain) {
2328     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2329
2330     TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Drain);
2331
2332     return S_OK;
2333 }
2334
2335 static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface,
2336                                                    OAHWND *Drain) {
2337     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2338
2339     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, Drain);
2340
2341     return S_OK;
2342 }
2343
2344 static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface,
2345                                                   long *Color) {
2346     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2347
2348     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, Color);
2349
2350     return S_OK;
2351 }
2352
2353 static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface,
2354                                                   long Color) {
2355     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2356
2357     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Color);
2358
2359     return S_OK;
2360 }
2361
2362 static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface,
2363                                                      long *FullScreenMode) {
2364     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2365
2366     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode);
2367
2368     return S_OK;
2369 }
2370
2371 static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface,
2372                                                      long FullScreenMode) {
2373     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2374
2375     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, FullScreenMode);
2376
2377     return S_OK;
2378 }
2379
2380 static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface,
2381                                                       long Focus) {
2382     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2383
2384     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Focus);
2385
2386     return S_OK;
2387 }
2388
2389 static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface,
2390                                                      OAHWND hwnd,
2391                                                      long uMsg,
2392                                                      LONG_PTR wParam,
2393                                                      LONG_PTR lParam) {
2394     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2395
2396     TRACE("(%p/%p)->(%08lx, %ld, %08lx, %08lx): stub !!!\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
2397
2398     return S_OK;
2399 }
2400
2401 static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface,
2402                                                     long Left,
2403                                                     long Top,
2404                                                     long Width,
2405                                                     long Height) {
2406     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2407     
2408     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
2409
2410     return S_OK;
2411 }
2412
2413 static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface,
2414                                                     long *pLeft,
2415                                                     long *pTop,
2416                                                     long *pWidth,
2417                                                     long *pHeight) {
2418     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2419
2420     TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
2421
2422     return S_OK;
2423 }
2424
2425 static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface,
2426                                                        long *pWidth,
2427                                                        long *pHeight) {
2428     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2429
2430     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
2431
2432     return S_OK;
2433 }
2434
2435 static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface,
2436                                                        long *pWidth,
2437                                                        long *pHeight) {
2438     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2439
2440     TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
2441
2442     return S_OK;
2443 }
2444
2445 static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface,
2446                                                      long *pLeft,
2447                                                      long *pTop,
2448                                                      long *pWidth,
2449                                                      long *pHeight) {
2450     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2451
2452     TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
2453
2454     return S_OK;
2455 }
2456
2457 static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface,
2458                                              long HideCursor) {
2459     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2460
2461     TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, HideCursor);
2462
2463     return S_OK;
2464 }
2465
2466 static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface,
2467                                                  long *CursorHidden) {
2468     ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
2469
2470     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden);
2471
2472     return S_OK;
2473 }
2474
2475
2476 static IVideoWindowVtbl IVideoWindow_VTable =
2477 {
2478     Videowindow_QueryInterface,
2479     Videowindow_AddRef,
2480     Videowindow_Release,
2481     Videowindow_GetTypeInfoCount,
2482     Videowindow_GetTypeInfo,
2483     Videowindow_GetIDsOfNames,
2484     Videowindow_Invoke,
2485     Videowindow_put_Caption,
2486     Videowindow_get_Caption,
2487     Videowindow_put_WindowStyle,
2488     Videowindow_get_WindowStyle,
2489     Videowindow_put_WindowStyleEx,
2490     Videowindow_get_WindowStyleEx,
2491     Videowindow_put_AutoShow,
2492     Videowindow_get_AutoShow,
2493     Videowindow_put_WindowState,
2494     Videowindow_get_WindowState,
2495     Videowindow_put_BackgroundPalette,
2496     Videowindow_get_BackgroundPalette,
2497     Videowindow_put_Visible,
2498     Videowindow_get_Visible,
2499     Videowindow_put_Left,
2500     Videowindow_get_Left,
2501     Videowindow_put_Width,
2502     Videowindow_get_Width,
2503     Videowindow_put_Top,
2504     Videowindow_get_Top,
2505     Videowindow_put_Height,
2506     Videowindow_get_Height,
2507     Videowindow_put_Owner,
2508     Videowindow_get_Owner,
2509     Videowindow_put_MessageDrain,
2510     Videowindow_get_MessageDrain,
2511     Videowindow_get_BorderColor,
2512     Videowindow_put_BorderColor,
2513     Videowindow_get_FullScreenMode,
2514     Videowindow_put_FullScreenMode,
2515     Videowindow_SetWindowForeground,
2516     Videowindow_NotifyOwnerMessage,
2517     Videowindow_SetWindowPosition,
2518     Videowindow_GetWindowPosition,
2519     Videowindow_GetMinIdealImageSize,
2520     Videowindow_GetMaxIdealImageSize,
2521     Videowindow_GetRestorePosition,
2522     Videowindow_HideCursor,
2523     Videowindow_IsCursorHidden
2524 };
2525
2526
2527 /*** IUnknown methods ***/
2528 static HRESULT WINAPI Mediaevent_QueryInterface(IMediaEventEx *iface,
2529                                                 REFIID riid,
2530                                                 LPVOID*ppvObj) {
2531     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2532
2533     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2534
2535     return Filtergraph_QueryInterface(This, riid, ppvObj);
2536 }
2537
2538 static ULONG WINAPI Mediaevent_AddRef(IMediaEventEx *iface) {
2539     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2540
2541     TRACE("(%p/%p)->()\n", This, iface);
2542
2543     return Filtergraph_AddRef(This);
2544 }
2545
2546 static ULONG WINAPI Mediaevent_Release(IMediaEventEx *iface) {
2547     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2548
2549     TRACE("(%p/%p)->()\n", This, iface);
2550
2551     return Filtergraph_Release(This);
2552 }
2553
2554 /*** IDispatch methods ***/
2555 static HRESULT WINAPI Mediaevent_GetTypeInfoCount(IMediaEventEx *iface,
2556                                                   UINT*pctinfo) {
2557     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2558
2559     TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
2560
2561     return S_OK;
2562 }
2563
2564 static HRESULT WINAPI Mediaevent_GetTypeInfo(IMediaEventEx *iface,
2565                                              UINT iTInfo,
2566                                              LCID lcid,
2567                                              ITypeInfo**ppTInfo) {
2568     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2569
2570     TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
2571
2572     return S_OK;
2573 }
2574
2575 static HRESULT WINAPI Mediaevent_GetIDsOfNames(IMediaEventEx *iface,
2576                                                REFIID riid,
2577                                                LPOLESTR*rgszNames,
2578                                                UINT cNames,
2579                                                LCID lcid,
2580                                                DISPID*rgDispId) {
2581     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2582
2583     TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2584
2585     return S_OK;
2586 }
2587
2588 static HRESULT WINAPI Mediaevent_Invoke(IMediaEventEx *iface,
2589                                         DISPID dispIdMember,
2590                                         REFIID riid,
2591                                         LCID lcid,
2592                                         WORD wFlags,
2593                                         DISPPARAMS*pDispParams,
2594                                         VARIANT*pVarResult,
2595                                         EXCEPINFO*pExepInfo,
2596                                         UINT*puArgErr) {
2597     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2598
2599     TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2600
2601     return S_OK;
2602 }
2603
2604 /*** IMediaEvent methods ***/
2605 static HRESULT WINAPI Mediaevent_GetEventHandle(IMediaEventEx *iface,
2606                                                 OAEVENT *hEvent) {
2607     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2608
2609     TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
2610
2611     *hEvent = (OAEVENT)This->evqueue.msg_event;
2612
2613     return S_OK;
2614 }
2615
2616 static HRESULT WINAPI Mediaevent_GetEvent(IMediaEventEx *iface,
2617                                           long *lEventCode,
2618                                           LONG_PTR *lParam1,
2619                                           LONG_PTR *lParam2,
2620                                           long msTimeout) {
2621     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2622     Event evt;
2623
2624     TRACE("(%p/%p)->(%p, %p, %p, %ld)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
2625
2626     if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
2627     {
2628         *lEventCode = evt.lEventCode;
2629         *lParam1 = evt.lParam1;
2630         *lParam2 = evt.lParam2;
2631         return S_OK;
2632     }
2633
2634     *lEventCode = 0;
2635     return E_ABORT;
2636 }
2637
2638 static HRESULT WINAPI Mediaevent_WaitForCompletion(IMediaEventEx *iface,
2639                                                    long msTimeout,
2640                                                    long *pEvCode) {
2641     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2642
2643     TRACE("(%p/%p)->(%ld, %p)\n", This, iface, msTimeout, pEvCode);
2644
2645     if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
2646     {
2647         *pEvCode = This->CompletionStatus;
2648         return S_OK;
2649     }
2650
2651     *pEvCode = 0;
2652     return E_ABORT;
2653 }
2654
2655 static HRESULT WINAPI Mediaevent_CancelDefaultHandling(IMediaEventEx *iface,
2656                                                        long lEvCode) {
2657     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2658
2659     TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
2660
2661     if (lEvCode == EC_COMPLETE)
2662         This->HandleEcComplete = FALSE;
2663     else if (lEvCode == EC_REPAINT)
2664         This->HandleEcRepaint = FALSE;
2665     else
2666         return S_FALSE;
2667
2668     return S_OK;
2669 }
2670
2671 static HRESULT WINAPI Mediaevent_RestoreDefaultHandling(IMediaEventEx *iface,
2672                                                         long lEvCode) {
2673     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2674
2675     TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
2676
2677     if (lEvCode == EC_COMPLETE)
2678         This->HandleEcComplete = TRUE;
2679     else if (lEvCode == EC_REPAINT)
2680         This->HandleEcRepaint = TRUE;
2681     else
2682         return S_FALSE;
2683
2684     return S_OK;
2685 }
2686
2687 static HRESULT WINAPI Mediaevent_FreeEventParams(IMediaEventEx *iface,
2688                                                  long lEvCode,
2689                                                  LONG_PTR lParam1,
2690                                                  LONG_PTR lParam2) {
2691     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2692
2693     TRACE("(%p/%p)->(%ld, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
2694
2695     return S_OK;
2696 }
2697
2698 /*** IMediaEventEx methods ***/
2699 static HRESULT WINAPI Mediaevent_SetNotifyWindow(IMediaEventEx *iface,
2700                                                  OAHWND hwnd,
2701                                                  long lMsg,
2702                                                  LONG_PTR lInstanceData) {
2703     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2704
2705     TRACE("(%p/%p)->(%08lx, %ld, %08lx)\n", This, iface, (DWORD) hwnd, lMsg, lInstanceData);
2706
2707     This->notif.hWnd = (HWND)hwnd;
2708     This->notif.msg = lMsg;
2709     This->notif.instance = (long) lInstanceData;
2710
2711     return S_OK;
2712 }
2713
2714 static HRESULT WINAPI Mediaevent_SetNotifyFlags(IMediaEventEx *iface,
2715                                                 long lNoNotifyFlags) {
2716     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2717
2718     TRACE("(%p/%p)->(%ld)\n", This, iface, lNoNotifyFlags);
2719
2720     if ((lNoNotifyFlags != 0) || (lNoNotifyFlags != 1))
2721         return E_INVALIDARG;
2722
2723     This->notif.disabled = lNoNotifyFlags;
2724
2725     return S_OK;
2726 }
2727
2728 static HRESULT WINAPI Mediaevent_GetNotifyFlags(IMediaEventEx *iface,
2729                                                 long *lplNoNotifyFlags) {
2730     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2731
2732     TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
2733
2734     if (!lplNoNotifyFlags)
2735         return E_POINTER;
2736
2737     *lplNoNotifyFlags = This->notif.disabled;
2738
2739     return S_OK;
2740 }
2741
2742
2743 static IMediaEventExVtbl IMediaEventEx_VTable =
2744 {
2745     Mediaevent_QueryInterface,
2746     Mediaevent_AddRef,
2747     Mediaevent_Release,
2748     Mediaevent_GetTypeInfoCount,
2749     Mediaevent_GetTypeInfo,
2750     Mediaevent_GetIDsOfNames,
2751     Mediaevent_Invoke,
2752     Mediaevent_GetEventHandle,
2753     Mediaevent_GetEvent,
2754     Mediaevent_WaitForCompletion,
2755     Mediaevent_CancelDefaultHandling,
2756     Mediaevent_RestoreDefaultHandling,
2757     Mediaevent_FreeEventParams,
2758     Mediaevent_SetNotifyWindow,
2759     Mediaevent_SetNotifyFlags,
2760     Mediaevent_GetNotifyFlags
2761 };
2762
2763
2764 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
2765 {
2766     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2767
2768     return Filtergraph_QueryInterface(This, riid, ppv);
2769 }
2770
2771 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
2772 {
2773     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2774
2775     return Filtergraph_AddRef(This);
2776 }
2777
2778 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
2779 {
2780     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
2781
2782     return Filtergraph_Release(This);
2783 }
2784
2785 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
2786 {
2787     FIXME("(%p): stub\n", pClassID);
2788
2789     return E_NOTIMPL;
2790 }
2791
2792 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
2793 {
2794     FIXME("(): stub\n");
2795
2796     return E_NOTIMPL;
2797 }
2798
2799 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
2800 {
2801     FIXME("(): stub\n");
2802
2803     return E_NOTIMPL;
2804 }
2805
2806 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
2807 {
2808     FIXME("(%lld): stub\n", tStart);
2809
2810     return E_NOTIMPL;
2811 }
2812
2813 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
2814 {
2815     FIXME("(%ld, %p): stub\n", dwMsTimeout, pState);
2816
2817     return E_NOTIMPL;
2818 }
2819
2820 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
2821 {
2822     FIXME("(%p): stub\n", pClock);
2823
2824     return E_NOTIMPL;
2825 }
2826
2827 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
2828 {
2829     FIXME("(%p): stub\n", ppClock);
2830
2831     return E_NOTIMPL;
2832 }
2833
2834 static IMediaFilterVtbl IMediaFilter_VTable =
2835 {
2836     MediaFilter_QueryInterface,
2837     MediaFilter_AddRef,
2838     MediaFilter_Release,
2839     MediaFilter_GetClassID,
2840     MediaFilter_Stop,
2841     MediaFilter_Pause,
2842     MediaFilter_Run,
2843     MediaFilter_GetState,
2844     MediaFilter_SetSyncSource,
2845     MediaFilter_GetSyncSource
2846 };
2847
2848 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
2849 {
2850     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
2851
2852     return Filtergraph_QueryInterface(This, riid, ppv);
2853 }
2854
2855 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
2856 {
2857     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
2858
2859     return Filtergraph_AddRef(This);
2860 }
2861
2862 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
2863 {
2864     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
2865
2866     return Filtergraph_Release(This);
2867 }
2868
2869 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
2870 {
2871     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
2872     Event evt;
2873
2874     TRACE("(%p/%p)->(%ld, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
2875
2876     /* We need thread safety here, let's use the events queue's one */
2877     EnterCriticalSection(&This->evqueue.msg_crst);
2878     
2879     if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
2880     {
2881         if (++This->EcCompleteCount == This->nRenderers)
2882         {
2883             evt.lEventCode = EC_COMPLETE;
2884             evt.lParam1 = S_OK;
2885             evt.lParam2 = 0;
2886             EventsQueue_PutEvent(&This->evqueue, &evt);
2887             if (!This->notif.disabled && This->notif.hWnd)
2888                 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
2889             This->CompletionStatus = EC_COMPLETE;
2890             SetEvent(This->hEventCompletion);
2891         }
2892     }
2893     else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
2894     {
2895         /* FIXME: Not handled yet */
2896     }
2897     else
2898     {
2899         evt.lEventCode = EventCode;
2900         evt.lParam1 = EventParam1;
2901         evt.lParam2 = EventParam2;
2902         EventsQueue_PutEvent(&This->evqueue, &evt);
2903         if (!This->notif.disabled && This->notif.hWnd)
2904             PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
2905     }
2906
2907     LeaveCriticalSection(&This->evqueue.msg_crst);
2908     return S_OK;
2909 }
2910
2911 static IMediaEventSinkVtbl IMediaEventSink_VTable =
2912 {
2913     MediaEventSink_QueryInterface,
2914     MediaEventSink_AddRef,
2915     MediaEventSink_Release,
2916     MediaEventSink_Notify
2917 };
2918
2919 /* This is the only function that actually creates a FilterGraph class... */
2920 HRESULT FILTERGRAPH_create(IUnknown *pUnkOuter, LPVOID *ppObj) {
2921     IFilterGraphImpl *fimpl;
2922     HRESULT hr;
2923
2924     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2925
2926     if( pUnkOuter )
2927         return CLASS_E_NOAGGREGATION;
2928
2929     fimpl = (IFilterGraphImpl *) HeapAlloc(GetProcessHeap(), 0, sizeof(*fimpl));
2930     fimpl->IGraphBuilder_vtbl = &IGraphBuilder_VTable;
2931     fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
2932     fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
2933     fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
2934     fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
2935     fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
2936     fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
2937     fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
2938     fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
2939     fimpl->ref = 1;
2940     fimpl->ppFiltersInGraph = NULL;
2941     fimpl->pFilterNames = NULL;
2942     fimpl->nFilters = 0;
2943     fimpl->filterCapacity = 0;
2944     fimpl->nameIndex = 1;
2945     fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE,0);
2946     fimpl->HandleEcComplete = TRUE;
2947     fimpl->HandleEcRepaint = TRUE;
2948     fimpl->notif.hWnd = 0;
2949     fimpl->notif.disabled = TRUE;
2950     fimpl->nRenderers = 0;
2951     fimpl->EcCompleteCount = 0;
2952     EventsQueue_Init(&fimpl->evqueue);
2953
2954     hr = CoCreateInstance(&CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
2955     if (FAILED(hr)) {
2956         ERR("Unable to create filter mapper (%lx)\n", hr);
2957         return hr;
2958     }
2959
2960     *ppObj = fimpl;
2961     return S_OK;
2962 }