wined3d: Remove fake nvidia card in GetAdapterIdentifier.
[wine/dibdrv.git] / dlls / quartz / filtergraph.c
blobe6c19f5112f4e7137e4c0f7e66f3c79c0c5ac912
1 /* DirectShow FilterGraph object (QUARTZ.DLL)
3 * Copyright 2002 Lionel Ulmer
4 * Copyright 2004 Christian Costa
6 * This file contains the (internal) driver registration functions,
7 * driver enumeration APIs and DirectDraw creation functions.
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "config.h"
25 #include <stdarg.h>
27 #define COBJMACROS
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 #include "ole2.h"
36 #include "olectl.h"
37 #include "strmif.h"
38 #include "vfwmsgs.h"
39 #include "evcode.h"
40 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
45 typedef struct {
46 HWND hWnd; /* Target window */
47 long msg; /* User window message */
48 long instance; /* User data */
49 int disabled; /* Disabled messages posting */
50 } WndNotify;
52 typedef struct {
53 long lEventCode; /* Event code */
54 LONG_PTR lParam1; /* Param1 */
55 LONG_PTR lParam2; /* Param2 */
56 } Event;
58 /* messages ring implementation for queuing events (taken from winmm) */
59 #define EVENTS_RING_BUFFER_INCREMENT 64
60 typedef struct {
61 Event* messages;
62 int ring_buffer_size;
63 int msg_tosave;
64 int msg_toget;
65 CRITICAL_SECTION msg_crst;
66 HANDLE msg_event; /* Signaled for no empty queue */
67 } EventsQueue;
69 static int EventsQueue_Init(EventsQueue* omr)
71 omr->msg_toget = 0;
72 omr->msg_tosave = 0;
73 omr->msg_event = CreateEventW(NULL, TRUE, FALSE, NULL);
74 omr->ring_buffer_size = EVENTS_RING_BUFFER_INCREMENT;
75 omr->messages = CoTaskMemAlloc(omr->ring_buffer_size * sizeof(Event));
76 ZeroMemory(omr->messages, omr->ring_buffer_size * sizeof(Event));
78 InitializeCriticalSection(&omr->msg_crst);
79 omr->msg_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": EventsQueue.msg_crst");
80 return TRUE;
83 static int EventsQueue_Destroy(EventsQueue* omr)
85 CloseHandle(omr->msg_event);
86 CoTaskMemFree(omr->messages);
87 omr->msg_crst.DebugInfo->Spare[0] = 0;
88 DeleteCriticalSection(&omr->msg_crst);
89 return TRUE;
92 static int EventsQueue_PutEvent(EventsQueue* omr, Event* evt)
94 EnterCriticalSection(&omr->msg_crst);
95 if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size)))
97 int old_ring_buffer_size = omr->ring_buffer_size;
98 omr->ring_buffer_size += EVENTS_RING_BUFFER_INCREMENT;
99 TRACE("omr->ring_buffer_size=%d\n",omr->ring_buffer_size);
100 omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(Event));
101 /* Now we need to rearrange the ring buffer so that the new
102 buffers just allocated are in between omr->msg_tosave and
103 omr->msg_toget.
105 if (omr->msg_tosave < omr->msg_toget)
107 memmove(&(omr->messages[omr->msg_toget + EVENTS_RING_BUFFER_INCREMENT]),
108 &(omr->messages[omr->msg_toget]),
109 sizeof(Event)*(old_ring_buffer_size - omr->msg_toget)
111 omr->msg_toget += EVENTS_RING_BUFFER_INCREMENT;
114 omr->messages[omr->msg_tosave] = *evt;
115 SetEvent(omr->msg_event);
116 omr->msg_tosave = (omr->msg_tosave + 1) % omr->ring_buffer_size;
117 LeaveCriticalSection(&omr->msg_crst);
118 return TRUE;
121 static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut)
123 if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0)
124 return FALSE;
126 EnterCriticalSection(&omr->msg_crst);
128 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
130 LeaveCriticalSection(&omr->msg_crst);
131 return FALSE;
134 *evt = omr->messages[omr->msg_toget];
135 omr->msg_toget = (omr->msg_toget + 1) % omr->ring_buffer_size;
137 /* Mark the buffer as empty if needed */
138 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
139 ResetEvent(omr->msg_event);
141 LeaveCriticalSection(&omr->msg_crst);
142 return TRUE;
145 #define MAX_ITF_CACHE_ENTRIES 3
146 typedef struct _ITF_CACHE_ENTRY {
147 const IID* riid;
148 IBaseFilter* filter;
149 IUnknown* iface;
150 } ITF_CACHE_ENTRY;
152 typedef struct _IFilterGraphImpl {
153 const IGraphBuilderVtbl *IGraphBuilder_vtbl;
154 const IMediaControlVtbl *IMediaControl_vtbl;
155 const IMediaSeekingVtbl *IMediaSeeking_vtbl;
156 const IBasicAudioVtbl *IBasicAudio_vtbl;
157 const IBasicVideoVtbl *IBasicVideo_vtbl;
158 const IVideoWindowVtbl *IVideoWindow_vtbl;
159 const IMediaEventExVtbl *IMediaEventEx_vtbl;
160 const IMediaFilterVtbl *IMediaFilter_vtbl;
161 const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
162 const IGraphConfigVtbl *IGraphConfig_vtbl;
163 const IMediaPositionVtbl *IMediaPosition_vtbl;
164 /* IAMGraphStreams */
165 /* IAMStats */
166 /* IBasicVideo2 */
167 /* IFilterChain */
168 /* IFilterGraph2 */
169 /* IFilterMapper2 */
170 /* IGraphVersion */
171 /* IQueueCommand */
172 /* IRegisterServiceProvider */
173 /* IResourceMananger */
174 /* IServiceProvider */
175 /* IVideoFrameStep */
177 LONG ref;
178 IFilterMapper2 * pFilterMapper2;
179 IBaseFilter ** ppFiltersInGraph;
180 LPWSTR * pFilterNames;
181 int nFilters;
182 int filterCapacity;
183 long nameIndex;
184 IReferenceClock *refClock;
185 EventsQueue evqueue;
186 HANDLE hEventCompletion;
187 int CompletionStatus;
188 WndNotify notif;
189 int nRenderers;
190 int EcCompleteCount;
191 int HandleEcComplete;
192 int HandleEcRepaint;
193 int HandleEcClockChanged;
194 OAFilterState state;
195 CRITICAL_SECTION cs;
196 ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
197 int nItfCacheEntries;
198 } IFilterGraphImpl;
201 static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
202 REFIID riid,
203 LPVOID *ppvObj) {
204 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
206 if (IsEqualGUID(&IID_IUnknown, riid) ||
207 IsEqualGUID(&IID_IFilterGraph, riid) ||
208 IsEqualGUID(&IID_IGraphBuilder, riid)) {
209 *ppvObj = &(This->IGraphBuilder_vtbl);
210 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj);
211 } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
212 *ppvObj = &(This->IMediaControl_vtbl);
213 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj);
214 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
215 *ppvObj = &(This->IMediaSeeking_vtbl);
216 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
217 } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
218 *ppvObj = &(This->IBasicAudio_vtbl);
219 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj);
220 } else if (IsEqualGUID(&IID_IBasicVideo, riid)) {
221 *ppvObj = &(This->IBasicVideo_vtbl);
222 TRACE(" returning IBasicVideo interface (%p)\n", *ppvObj);
223 } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
224 *ppvObj = &(This->IVideoWindow_vtbl);
225 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj);
226 } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
227 IsEqualGUID(&IID_IMediaEventEx, riid)) {
228 *ppvObj = &(This->IMediaEventEx_vtbl);
229 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
230 } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
231 IsEqualGUID(&IID_IPersist, riid)) {
232 *ppvObj = &(This->IMediaFilter_vtbl);
233 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj);
234 } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
235 *ppvObj = &(This->IMediaEventSink_vtbl);
236 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj);
237 } else if (IsEqualGUID(&IID_IGraphConfig, riid)) {
238 *ppvObj = &(This->IGraphConfig_vtbl);
239 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj);
240 } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
241 *ppvObj = &(This->IMediaPosition_vtbl);
242 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj);
243 } else {
244 *ppvObj = NULL;
245 FIXME("unknown interface %s\n", debugstr_guid(riid));
246 return E_NOINTERFACE;
249 InterlockedIncrement(&This->ref);
250 return S_OK;
253 static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
254 ULONG ref = InterlockedIncrement(&This->ref);
256 TRACE("(%p)->(): new ref = %d\n", This, ref);
258 return ref;
261 static ULONG Filtergraph_Release(IFilterGraphImpl *This) {
262 ULONG ref = InterlockedDecrement(&This->ref);
264 TRACE("(%p)->(): new ref = %d\n", This, ref);
266 if (ref == 0) {
267 int i;
269 if (This->refClock)
270 IReferenceClock_Release(This->refClock);
272 for (i = 0; i < This->nFilters; i++)
274 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], NULL);
275 IBaseFilter_Release(This->ppFiltersInGraph[i]);
277 for (i = 0; i < This->nItfCacheEntries; i++)
279 if (This->ItfCacheEntries[i].iface)
280 IUnknown_Release(This->ItfCacheEntries[i].iface);
282 IFilterMapper2_Release(This->pFilterMapper2);
283 CloseHandle(This->hEventCompletion);
284 EventsQueue_Destroy(&This->evqueue);
285 This->cs.DebugInfo->Spare[0] = 0;
286 DeleteCriticalSection(&This->cs);
287 CoTaskMemFree(This->ppFiltersInGraph);
288 CoTaskMemFree(This->pFilterNames);
289 CoTaskMemFree(This);
291 return ref;
295 /*** IUnknown methods ***/
296 static HRESULT WINAPI GraphBuilder_QueryInterface(IGraphBuilder *iface,
297 REFIID riid,
298 LPVOID*ppvObj) {
299 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
301 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
302 return Filtergraph_QueryInterface(This, riid, ppvObj);
305 static ULONG WINAPI GraphBuilder_AddRef(IGraphBuilder *iface) {
306 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
308 TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
310 return Filtergraph_AddRef(This);
313 static ULONG WINAPI GraphBuilder_Release(IGraphBuilder *iface) {
314 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
316 TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
318 return Filtergraph_Release(This);
321 /*** IFilterGraph methods ***/
322 static HRESULT WINAPI GraphBuilder_AddFilter(IGraphBuilder *iface,
323 IBaseFilter *pFilter,
324 LPCWSTR pName) {
325 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
326 HRESULT hr;
327 int i,j;
328 WCHAR* wszFilterName = NULL;
329 int duplicate_name = FALSE;
331 TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
333 wszFilterName = (WCHAR*) CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
335 if (pName)
337 /* Check if name already exists */
338 for(i = 0; i < This->nFilters; i++)
339 if (!strcmpW(This->pFilterNames[i], pName))
341 duplicate_name = TRUE;
342 break;
346 /* If no name given or name already existing, generate one */
347 if (!pName || duplicate_name)
349 static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
350 static const WCHAR wszFmt2[] = {'%','0','4','d',0};
352 for (j = 0; j < 10000 ; j++)
354 /* Create name */
355 if (pName)
356 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
357 else
358 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
359 TRACE("Generated name %s\n", debugstr_w(wszFilterName));
361 /* Check if the generated name already exists */
362 for(i = 0; i < This->nFilters; i++)
363 if (!strcmpW(This->pFilterNames[i], wszFilterName))
364 break;
366 /* Compute next index and exit if generated name is suitable */
367 if (This->nameIndex++ == 10000)
368 This->nameIndex = 1;
369 if (i == This->nFilters)
370 break;
372 /* Unable to find a suitable name */
373 if (j == 10000)
375 CoTaskMemFree(wszFilterName);
376 return VFW_E_DUPLICATE_NAME;
379 else
380 memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
382 if (This->nFilters + 1 > This->filterCapacity)
384 int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
385 IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
386 LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
387 memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
388 memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
389 if (!This->filterCapacity)
391 CoTaskMemFree(This->ppFiltersInGraph);
392 CoTaskMemFree(This->pFilterNames);
394 This->ppFiltersInGraph = ppNewFilters;
395 This->pFilterNames = pNewNames;
396 This->filterCapacity = newCapacity;
399 hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
401 if (SUCCEEDED(hr))
403 IBaseFilter_AddRef(pFilter);
404 This->ppFiltersInGraph[This->nFilters] = pFilter;
405 This->pFilterNames[This->nFilters] = wszFilterName;
406 This->nFilters++;
407 IBaseFilter_SetSyncSource(pFilter, This->refClock);
409 else
410 CoTaskMemFree(wszFilterName);
412 if (SUCCEEDED(hr) && duplicate_name)
413 return VFW_S_DUPLICATE_NAME;
415 return hr;
418 static HRESULT WINAPI GraphBuilder_RemoveFilter(IGraphBuilder *iface,
419 IBaseFilter *pFilter) {
420 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
421 int i;
422 HRESULT hr = E_FAIL;
424 TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
426 /* FIXME: check graph is stopped */
428 for (i = 0; i < This->nFilters; i++)
430 if (This->ppFiltersInGraph[i] == pFilter)
432 IEnumPins *penumpins;
433 hr = IBaseFilter_EnumPins(pFilter, &penumpins);
434 if (SUCCEEDED(hr)) {
435 IPin *ppin;
436 while(IEnumPins_Next(penumpins, 1, &ppin, NULL) == S_OK) {
437 IPin_Disconnect(ppin);
438 IPin_Release(ppin);
440 IEnumPins_Release(penumpins);
443 hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
444 if (SUCCEEDED(hr))
446 IBaseFilter_SetSyncSource(pFilter, NULL);
447 IBaseFilter_Release(pFilter);
448 CoTaskMemFree(This->pFilterNames[i]);
449 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
450 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
451 This->nFilters--;
452 /* Invalidate interfaces in the cache */
453 for (i = 0; i < This->nItfCacheEntries; i++)
454 if (pFilter == This->ItfCacheEntries[i].filter)
456 IUnknown_Release(This->ItfCacheEntries[i].iface);
457 This->ItfCacheEntries[i].iface = NULL;
458 This->ItfCacheEntries[i].filter = NULL;
460 return S_OK;
462 break;
466 return hr; /* FIXME: check this error code */
469 static HRESULT WINAPI GraphBuilder_EnumFilters(IGraphBuilder *iface,
470 IEnumFilters **ppEnum) {
471 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
473 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
475 return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
478 static HRESULT WINAPI GraphBuilder_FindFilterByName(IGraphBuilder *iface,
479 LPCWSTR pName,
480 IBaseFilter **ppFilter) {
481 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
482 int i;
484 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
486 *ppFilter = NULL;
488 for (i = 0; i < This->nFilters; i++)
490 if (!strcmpW(pName, This->pFilterNames[i]))
492 *ppFilter = This->ppFiltersInGraph[i];
493 IBaseFilter_AddRef(*ppFilter);
494 return S_OK;
498 return E_FAIL; /* FIXME: check this error code */
501 /* NOTE: despite the implication, it doesn't matter which
502 * way round you put in the input and output pins */
503 static HRESULT WINAPI GraphBuilder_ConnectDirect(IGraphBuilder *iface,
504 IPin *ppinIn,
505 IPin *ppinOut,
506 const AM_MEDIA_TYPE *pmt) {
507 PIN_DIRECTION dir;
508 HRESULT hr;
510 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
512 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
514 /* FIXME: check pins are in graph */
516 if (TRACE_ON(quartz))
518 PIN_INFO PinInfo;
520 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
521 if (FAILED(hr))
522 return hr;
524 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
525 IBaseFilter_Release(PinInfo.pFilter);
527 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
528 if (FAILED(hr))
529 return hr;
531 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
532 IBaseFilter_Release(PinInfo.pFilter);
535 hr = IPin_QueryDirection(ppinIn, &dir);
536 if (SUCCEEDED(hr))
538 if (dir == PINDIR_INPUT)
539 hr = IPin_Connect(ppinOut, ppinIn, pmt);
540 else
541 hr = IPin_Connect(ppinIn, ppinOut, pmt);
544 return hr;
547 static HRESULT WINAPI GraphBuilder_Reconnect(IGraphBuilder *iface,
548 IPin *ppin) {
549 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
550 IPin *pConnectedTo = NULL;
551 HRESULT hr;
552 PIN_DIRECTION pindir;
554 IPin_QueryDirection(ppin, &pindir);
555 hr = IPin_ConnectedTo(ppin, &pConnectedTo);
556 if (FAILED(hr)) {
557 TRACE("Querying connected to failed: %x\n", hr);
558 return hr;
560 IPin_Disconnect(ppin);
561 IPin_Disconnect(pConnectedTo);
562 if (pindir == PINDIR_INPUT)
563 hr = IPin_Connect(pConnectedTo, ppin, NULL);
564 else
565 hr = IPin_Connect(ppin, pConnectedTo, NULL);
566 IPin_Release(pConnectedTo);
567 if (FAILED(hr))
568 ERR("Reconnecting pins failed, pins are not connected now..\n");
569 TRACE("(%p->%p) -- %p %p -> %x\n", iface, This, ppin, pConnectedTo, hr);
570 return hr;
573 static HRESULT WINAPI GraphBuilder_Disconnect(IGraphBuilder *iface,
574 IPin *ppin) {
575 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
577 TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
579 return IPin_Disconnect(ppin);
582 static HRESULT WINAPI GraphBuilder_SetDefaultSyncSource(IGraphBuilder *iface) {
583 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
585 TRACE("(%p/%p)->(): stub !!!\n", iface, This);
587 return S_OK;
590 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
592 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
593 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
594 IPropertyBag * pPropBagCat = NULL;
595 HRESULT hr;
597 VariantInit(pvar);
598 V_VT(pvar) = VT_BSTR;
600 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
602 if (SUCCEEDED(hr))
603 hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
605 if (SUCCEEDED(hr))
606 hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
608 if (SUCCEEDED(hr))
609 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
611 if (SUCCEEDED(hr))
612 TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
614 if (pPropBagCat)
615 IPropertyBag_Release(pPropBagCat);
617 return hr;
620 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPin*** pppins, ULONG* pnb)
622 HRESULT hr;
623 ULONG nb = 0;
625 TRACE("(%p, %p, %p, %p)\n", pfilter, pinputpin, pppins, pnb);
626 hr = IPin_QueryInternalConnections(pinputpin, NULL, &nb);
627 if (hr == S_OK) {
628 /* Rendered input */
629 } else if (hr == S_FALSE) {
630 *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
631 hr = IPin_QueryInternalConnections(pinputpin, *pppins, &nb);
632 if (hr != S_OK) {
633 ERR("Error (%x)\n", hr);
635 } else if (hr == E_NOTIMPL) {
636 /* Input connected to all outputs */
637 IEnumPins* penumpins;
638 IPin* ppin;
639 int i = 0;
640 TRACE("E_NOTIMPL\n");
641 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
642 if (FAILED(hr)) {
643 ERR("filter Enumpins failed (%x)\n", hr);
644 return hr;
646 i = 0;
647 /* Count output pins */
648 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
649 PIN_DIRECTION pindir;
650 IPin_QueryDirection(ppin, &pindir);
651 if (pindir == PINDIR_OUTPUT)
652 i++;
653 IPin_Release(ppin);
655 *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
656 /* Retrieve output pins */
657 IEnumPins_Reset(penumpins);
658 i = 0;
659 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
660 PIN_DIRECTION pindir;
661 IPin_QueryDirection(ppin, &pindir);
662 if (pindir == PINDIR_OUTPUT)
663 (*pppins)[i++] = ppin;
664 else
665 IPin_Release(ppin);
667 IEnumPins_Release(penumpins);
668 nb = i;
669 if (FAILED(hr)) {
670 ERR("Next failed (%x)\n", hr);
671 return hr;
673 } else if (FAILED(hr)) {
674 ERR("Cannot get internal connection (%x)\n", hr);
675 return hr;
678 *pnb = nb;
679 return S_OK;
682 /*** IGraphBuilder methods ***/
683 static HRESULT WINAPI GraphBuilder_Connect(IGraphBuilder *iface,
684 IPin *ppinOut,
685 IPin *ppinIn) {
686 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
687 HRESULT hr;
688 AM_MEDIA_TYPE* mt;
689 IEnumMediaTypes* penummt;
690 ULONG nbmt;
691 IEnumPins* penumpins;
692 IEnumMoniker* pEnumMoniker;
693 GUID tab[2];
694 ULONG nb;
695 IMoniker* pMoniker;
696 ULONG pin;
697 PIN_INFO PinInfo;
698 CLSID FilterCLSID;
700 TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
702 if (TRACE_ON(quartz))
704 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
705 if (FAILED(hr))
706 return hr;
708 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
709 IBaseFilter_Release(PinInfo.pFilter);
711 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
712 if (FAILED(hr))
713 return hr;
715 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
716 IBaseFilter_Release(PinInfo.pFilter);
719 /* Try direct connection first */
720 hr = IPin_Connect(ppinOut, ppinIn, NULL);
721 if (SUCCEEDED(hr)) {
722 return S_OK;
724 TRACE("Direct connection failed, trying to insert other filters\n");
726 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
727 if (FAILED(hr))
728 return hr;
730 hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
731 IBaseFilter_Release(PinInfo.pFilter);
732 if (FAILED(hr))
733 return hr;
735 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
736 * filter to the minor mediatype of input pin of the renderer */
737 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
738 if (FAILED(hr)) {
739 ERR("EnumMediaTypes (%x)\n", hr);
740 return hr;
743 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
744 if (FAILED(hr)) {
745 ERR("IEnumMediaTypes_Next (%x)\n", hr);
746 return hr;
749 if (!nbmt) {
750 ERR("No media type found!\n");
751 return S_OK;
753 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
754 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
756 /* Try to find a suitable filter that can connect to the pin to render */
757 tab[0] = mt->majortype;
758 tab[1] = mt->subtype;
759 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
760 if (FAILED(hr)) {
761 ERR("Unable to enum filters (%x)\n", hr);
762 return hr;
765 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
767 VARIANT var;
768 GUID clsid;
769 IPin** ppins;
770 IPin* ppinfilter = NULL;
771 IBaseFilter* pfilter = NULL;
773 hr = GetFilterInfo(pMoniker, &clsid, &var);
774 IMoniker_Release(pMoniker);
775 if (FAILED(hr)) {
776 ERR("Unable to retrieve filter info (%x)\n", hr);
777 goto error;
780 if (IsEqualGUID(&clsid, &FilterCLSID)) {
781 /* Skip filter (same as the one the output pin belongs to) */
782 goto error;
785 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
786 if (FAILED(hr)) {
787 ERR("Unable to create filter (%x), trying next one\n", hr);
788 goto error;
791 hr = IGraphBuilder_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
792 if (FAILED(hr)) {
793 ERR("Unable to add filter (%x)\n", hr);
794 IBaseFilter_Release(pfilter);
795 pfilter = NULL;
796 goto error;
799 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
800 if (FAILED(hr)) {
801 ERR("Enumpins (%x)\n", hr);
802 goto error;
805 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
806 IEnumPins_Release(penumpins);
808 if (FAILED(hr)) {
809 ERR("Next (%x)\n", hr);
810 goto error;
812 if (pin == 0) {
813 ERR("No Pin\n");
814 goto error;
817 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
818 if (FAILED(hr)) {
819 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
820 goto error;
822 TRACE("Successfully connected to filter, follow chain...\n");
824 /* Render all output pins of the filter by calling IGraphBuilder_Render on each of them */
825 hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
827 if (SUCCEEDED(hr)) {
828 int i;
829 if (nb == 0) {
830 IPin_Disconnect(ppinOut);
831 goto error;
833 TRACE("pins to consider: %d\n", nb);
834 for(i = 0; i < nb; i++) {
835 TRACE("Processing pin %d\n", i);
836 hr = IGraphBuilder_Connect(iface, ppins[i], ppinIn);
837 if (FAILED(hr)) {
838 TRACE("Cannot render pin %p (%x)\n", ppinfilter, hr);
840 IPin_Release(ppins[i]);
841 if (SUCCEEDED(hr)) break;
843 while (++i < nb) IPin_Release(ppins[i]);
844 CoTaskMemFree(ppins);
845 IPin_Release(ppinfilter);
846 IBaseFilter_Release(pfilter);
847 break;
850 error:
851 if (ppinfilter) IPin_Release(ppinfilter);
852 if (pfilter) {
853 IGraphBuilder_RemoveFilter(iface, pfilter);
854 IBaseFilter_Release(pfilter);
858 IEnumMediaTypes_Release(penummt);
859 DeleteMediaType(mt);
861 return S_OK;
864 static HRESULT WINAPI GraphBuilder_Render(IGraphBuilder *iface,
865 IPin *ppinOut) {
866 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
867 IEnumMediaTypes* penummt;
868 AM_MEDIA_TYPE* mt;
869 ULONG nbmt;
870 HRESULT hr;
872 IEnumMoniker* pEnumMoniker;
873 GUID tab[2];
874 ULONG nb;
875 IMoniker* pMoniker;
877 TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
879 if (TRACE_ON(quartz))
881 PIN_INFO PinInfo;
883 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
884 if (FAILED(hr))
885 return hr;
887 TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
888 IBaseFilter_Release(PinInfo.pFilter);
891 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
892 if (FAILED(hr)) {
893 ERR("EnumMediaTypes (%x)\n", hr);
894 return hr;
897 while(1)
899 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
900 if (FAILED(hr)) {
901 ERR("IEnumMediaTypes_Next (%x)\n", hr);
902 return hr;
904 if (!nbmt)
905 break;
906 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
907 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
909 /* Try to find a suitable renderer with the same media type */
910 tab[0] = mt->majortype;
911 tab[1] = GUID_NULL;
912 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL);
913 if (FAILED(hr)) {
914 ERR("Unable to enum filters (%x)\n", hr);
915 return hr;
918 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
920 VARIANT var;
921 GUID clsid;
922 IPin* ppinfilter;
923 IBaseFilter* pfilter = NULL;
924 IEnumPins* penumpins;
925 ULONG pin;
927 hr = GetFilterInfo(pMoniker, &clsid, &var);
928 IMoniker_Release(pMoniker);
929 if (FAILED(hr)) {
930 ERR("Unable to retrieve filter info (%x)\n", hr);
931 goto error;
934 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
935 if (FAILED(hr)) {
936 ERR("Unable to create filter (%x), trying next one\n", hr);
937 goto error;
940 hr = IGraphBuilder_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
941 if (FAILED(hr)) {
942 ERR("Unable to add filter (%x)\n", hr);
943 IBaseFilter_Release(pfilter);
944 pfilter = NULL;
945 goto error;
948 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
949 if (FAILED(hr)) {
950 ERR("Splitter Enumpins (%x)\n", hr);
951 goto error;
953 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
954 IEnumPins_Release(penumpins);
955 if (FAILED(hr)) {
956 ERR("Next (%x)\n", hr);
957 goto error;
959 if (pin == 0) {
960 ERR("No Pin\n");
961 goto error;
964 /* Connect the pin to render to the renderer */
965 hr = IGraphBuilder_Connect(iface, ppinOut, ppinfilter);
966 if (FAILED(hr)) {
967 TRACE("Unable to connect to renderer (%x)\n", hr);
968 IPin_Release(ppinfilter);
969 goto error;
971 IPin_Release(ppinfilter);
972 IBaseFilter_Release(pfilter);
973 pfilter = NULL;
974 break;
976 error:
977 if (pfilter) {
978 IGraphBuilder_RemoveFilter(iface, pfilter);
979 IBaseFilter_Release(pfilter);
983 DeleteMediaType(mt);
984 break;
987 IEnumMediaTypes_Release(penummt);
989 return S_OK;
992 static HRESULT WINAPI GraphBuilder_RenderFile(IGraphBuilder *iface,
993 LPCWSTR lpcwstrFile,
994 LPCWSTR lpcwstrPlayList) {
995 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
996 static const WCHAR string[] = {'R','e','a','d','e','r',0};
997 IBaseFilter* preader = NULL;
998 IBaseFilter* psplitter = NULL;
999 IPin* ppinreader = NULL;
1000 IPin* ppinsplitter;
1001 IEnumPins* penumpins;
1002 ULONG pin;
1003 HRESULT hr;
1004 IEnumMoniker* pEnumMoniker = NULL;
1005 GUID tab[2];
1006 IPin** ppins = NULL;
1007 ULONG nb;
1008 IMoniker* pMoniker;
1009 IFileSourceFilter* pfile = NULL;
1010 AM_MEDIA_TYPE mt;
1011 WCHAR* filename;
1013 TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
1015 if (lpcwstrPlayList != NULL)
1016 return E_INVALIDARG;
1018 hr = IGraphBuilder_AddSourceFilter(iface, lpcwstrFile, string, &preader);
1020 /* Retrieve file media type */
1021 if (SUCCEEDED(hr))
1022 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1023 if (SUCCEEDED(hr)) {
1024 hr = IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1025 IFileSourceFilter_Release(pfile);
1028 if (SUCCEEDED(hr))
1029 hr = IBaseFilter_EnumPins(preader, &penumpins);
1030 if (SUCCEEDED(hr)) {
1031 hr = IEnumPins_Next(penumpins, 1, &ppinreader, &pin);
1032 IEnumPins_Release(penumpins);
1035 if (SUCCEEDED(hr)) {
1036 tab[0] = mt.majortype;
1037 tab[1] = mt.subtype;
1038 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, 0, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
1041 if (FAILED(hr))
1043 if (ppinreader)
1044 IPin_Release(ppinreader);
1045 if (pEnumMoniker)
1046 IEnumMoniker_Release(pEnumMoniker);
1047 if (preader) {
1048 IGraphBuilder_RemoveFilter(iface, preader);
1049 IBaseFilter_Release(preader);
1051 return hr;
1054 hr = VFW_E_CANNOT_RENDER;
1055 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1057 VARIANT var;
1058 GUID clsid;
1060 hr = GetFilterInfo(pMoniker, &clsid, &var);
1061 IMoniker_Release(pMoniker);
1062 if (FAILED(hr)) {
1063 ERR("Unable to retrieve filter info (%x)\n", hr);
1064 continue;
1067 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&psplitter);
1068 if (FAILED(hr)) {
1069 ERR("Unable to create filter (%x), trying next one\n", hr);
1070 continue;
1073 hr = IGraphBuilder_AddFilter(iface, psplitter, V_UNION(&var, bstrVal));
1074 if (FAILED(hr)) {
1075 ERR("Unable add filter (%x)\n", hr);
1076 IBaseFilter_Release(psplitter);
1077 continue;
1080 /* Connect file source and splitter filters together */
1081 /* Make the splitter analyze incoming data */
1083 hr = IBaseFilter_EnumPins(psplitter, &penumpins);
1084 if (SUCCEEDED(hr)) {
1085 hr = IEnumPins_Next(penumpins, 1, &ppinsplitter, &pin);
1086 IEnumPins_Release(penumpins);
1089 if (SUCCEEDED(hr))
1090 hr = IPin_Connect(ppinreader, ppinsplitter, NULL);
1092 /* Make sure there's some output pins in the filter */
1093 if (SUCCEEDED(hr))
1094 hr = GetInternalConnections(psplitter, ppinsplitter, &ppins, &nb);
1095 if (SUCCEEDED(hr)) {
1096 if(nb == 0) {
1097 IPin_Disconnect(ppinreader);
1098 TRACE("No output pins found in filter\n");
1099 hr = VFW_E_CANNOT_RENDER;
1103 if (ppinsplitter)
1104 IPin_Release(ppinsplitter);
1105 ppinsplitter = NULL;
1107 if (SUCCEEDED(hr)) {
1108 TRACE("Successfully connected to filter\n");
1109 break;
1112 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
1114 if (ppins) {
1115 CoTaskMemFree(ppins);
1116 ppins = NULL;
1118 IGraphBuilder_RemoveFilter(iface, psplitter);
1119 IBaseFilter_Release(psplitter);
1120 psplitter = NULL;
1123 /* Render all output pin of the splitter by calling IGraphBuilder_Render on each of them */
1124 if (SUCCEEDED(hr)) {
1125 int partial = 0;
1126 int i;
1127 TRACE("pins to consider: %d\n", nb);
1128 for(i = 0; i < nb; i++) {
1129 TRACE("Processing pin %d\n", i);
1130 hr = IGraphBuilder_Render(iface, ppins[i]);
1131 if (FAILED(hr)) {
1132 ERR("Cannot render pin %p (%x)\n", ppins[i], hr);
1133 partial = 1;
1135 IPin_Release(ppins[i]);
1137 CoTaskMemFree(ppins);
1139 hr = (partial ? VFW_S_PARTIAL_RENDER : S_OK);
1142 IPin_Release(ppinreader);
1143 IBaseFilter_Release(preader);
1144 if (psplitter)
1145 IBaseFilter_Release(psplitter);
1147 return hr;
1150 static HRESULT WINAPI GraphBuilder_AddSourceFilter(IGraphBuilder *iface,
1151 LPCWSTR lpcwstrFileName,
1152 LPCWSTR lpcwstrFilterName,
1153 IBaseFilter **ppFilter) {
1154 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1155 HRESULT hr;
1156 IBaseFilter* preader;
1157 IFileSourceFilter* pfile = NULL;
1158 AM_MEDIA_TYPE mt;
1159 WCHAR* filename;
1161 TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
1163 /* Instantiate a file source filter */
1164 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
1165 if (FAILED(hr)) {
1166 ERR("Unable to create file source filter (%x)\n", hr);
1167 return hr;
1170 hr = IGraphBuilder_AddFilter(iface, preader, lpcwstrFilterName);
1171 if (FAILED(hr)) {
1172 ERR("Unable add filter (%x)\n", hr);
1173 IBaseFilter_Release(preader);
1174 return hr;
1177 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1178 if (FAILED(hr)) {
1179 ERR("Unable to get IFileSourceInterface (%x)\n", hr);
1180 goto error;
1183 /* Load the file in the file source filter */
1184 hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1185 if (FAILED(hr)) {
1186 ERR("Load (%x)\n", hr);
1187 goto error;
1190 IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1191 if (FAILED(hr)) {
1192 ERR("GetCurFile (%x)\n", hr);
1193 goto error;
1195 TRACE("File %s\n", debugstr_w(filename));
1196 TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1197 TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1199 if (ppFilter)
1200 *ppFilter = preader;
1201 IFileSourceFilter_Release(pfile);
1203 return S_OK;
1205 error:
1206 if (pfile)
1207 IFileSourceFilter_Release(pfile);
1208 IGraphBuilder_RemoveFilter(iface, preader);
1209 IBaseFilter_Release(preader);
1211 return hr;
1214 static HRESULT WINAPI GraphBuilder_SetLogFile(IGraphBuilder *iface,
1215 DWORD_PTR hFile) {
1216 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1218 TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile);
1220 return S_OK;
1223 static HRESULT WINAPI GraphBuilder_Abort(IGraphBuilder *iface) {
1224 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1226 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1228 return S_OK;
1231 static HRESULT WINAPI GraphBuilder_ShouldOperationContinue(IGraphBuilder *iface) {
1232 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphBuilder_vtbl, iface);
1234 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1236 return S_OK;
1240 static const IGraphBuilderVtbl IGraphBuilder_VTable =
1242 GraphBuilder_QueryInterface,
1243 GraphBuilder_AddRef,
1244 GraphBuilder_Release,
1245 GraphBuilder_AddFilter,
1246 GraphBuilder_RemoveFilter,
1247 GraphBuilder_EnumFilters,
1248 GraphBuilder_FindFilterByName,
1249 GraphBuilder_ConnectDirect,
1250 GraphBuilder_Reconnect,
1251 GraphBuilder_Disconnect,
1252 GraphBuilder_SetDefaultSyncSource,
1253 GraphBuilder_Connect,
1254 GraphBuilder_Render,
1255 GraphBuilder_RenderFile,
1256 GraphBuilder_AddSourceFilter,
1257 GraphBuilder_SetLogFile,
1258 GraphBuilder_Abort,
1259 GraphBuilder_ShouldOperationContinue
1262 /*** IUnknown methods ***/
1263 static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface,
1264 REFIID riid,
1265 LPVOID*ppvObj) {
1266 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1268 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1270 return Filtergraph_QueryInterface(This, riid, ppvObj);
1273 static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) {
1274 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1276 TRACE("(%p/%p)->()\n", This, iface);
1278 return Filtergraph_AddRef(This);
1281 static ULONG WINAPI MediaControl_Release(IMediaControl *iface) {
1282 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1284 TRACE("(%p/%p)->()\n", This, iface);
1286 return Filtergraph_Release(This);
1290 /*** IDispatch methods ***/
1291 static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface,
1292 UINT*pctinfo) {
1293 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1295 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1297 return S_OK;
1300 static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface,
1301 UINT iTInfo,
1302 LCID lcid,
1303 ITypeInfo**ppTInfo) {
1304 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1306 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1308 return S_OK;
1311 static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface,
1312 REFIID riid,
1313 LPOLESTR*rgszNames,
1314 UINT cNames,
1315 LCID lcid,
1316 DISPID*rgDispId) {
1317 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1319 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1321 return S_OK;
1324 static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
1325 DISPID dispIdMember,
1326 REFIID riid,
1327 LCID lcid,
1328 WORD wFlags,
1329 DISPPARAMS*pDispParams,
1330 VARIANT*pVarResult,
1331 EXCEPINFO*pExepInfo,
1332 UINT*puArgErr) {
1333 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1335 TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
1337 return S_OK;
1340 typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
1342 static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
1344 HRESULT hr;
1345 IPin* pInputPin;
1346 IPin** ppPins;
1347 ULONG nb;
1348 ULONG i;
1349 PIN_INFO PinInfo;
1351 TRACE("%p %p\n", pGraph, pOutputPin);
1352 PinInfo.pFilter = NULL;
1354 hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
1356 if (SUCCEEDED(hr))
1358 hr = IPin_QueryPinInfo(pInputPin, &PinInfo);
1359 if (SUCCEEDED(hr))
1360 hr = GetInternalConnections(PinInfo.pFilter, pInputPin, &ppPins, &nb);
1361 IPin_Release(pInputPin);
1364 if (SUCCEEDED(hr))
1366 if (nb == 0)
1368 TRACE("Reached a renderer\n");
1369 /* Count renderers for end of stream notification */
1370 pGraph->nRenderers++;
1372 else
1374 for(i = 0; i < nb; i++)
1376 /* Explore the graph downstream from this pin
1377 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1378 * several input pins are connected to the same output (a MUX for instance). */
1379 ExploreGraph(pGraph, ppPins[i], FoundFilter);
1380 IPin_Release(ppPins[i]);
1383 CoTaskMemFree(ppPins);
1385 TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
1386 FoundFilter(PinInfo.pFilter);
1389 if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
1390 return hr;
1393 static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
1394 return IBaseFilter_Run(pFilter, 0);
1397 static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
1398 return IBaseFilter_Pause(pFilter);
1401 static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
1402 return IBaseFilter_Stop(pFilter);
1405 static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
1406 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1407 int i;
1408 IBaseFilter* pfilter;
1409 IEnumPins* pEnum;
1410 HRESULT hr;
1411 IPin* pPin;
1412 DWORD dummy;
1413 PIN_DIRECTION dir;
1414 TRACE("(%p/%p)->()\n", This, iface);
1416 /* Explorer the graph from source filters to renderers, determine renderers
1417 * number and run filters from renderers to source filters */
1418 This->nRenderers = 0;
1419 ResetEvent(This->hEventCompletion);
1421 for(i = 0; i < This->nFilters; i++)
1423 BOOL source = TRUE;
1424 pfilter = This->ppFiltersInGraph[i];
1425 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1426 if (hr != S_OK)
1428 ERR("Enum pins failed %x\n", hr);
1429 continue;
1431 /* Check if it is a source filter */
1432 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1434 IPin_QueryDirection(pPin, &dir);
1435 IPin_Release(pPin);
1436 if (dir == PINDIR_INPUT)
1438 source = FALSE;
1439 break;
1442 if (source)
1444 TRACE("Found a source filter %p\n", pfilter);
1445 IEnumPins_Reset(pEnum);
1446 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1448 /* Explore the graph downstream from this pin */
1449 ExploreGraph(This, pPin, FoundFilter);
1450 IPin_Release(pPin);
1452 FoundFilter(pfilter);
1454 IEnumPins_Release(pEnum);
1457 return S_FALSE;
1460 /*** IMediaControl methods ***/
1461 static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
1462 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1463 TRACE("(%p/%p)->()\n", This, iface);
1465 if (This->state == State_Running) return S_OK;
1467 EnterCriticalSection(&This->cs);
1468 SendFilterMessage(iface, SendRun);
1469 This->state = State_Running;
1470 LeaveCriticalSection(&This->cs);
1471 return S_FALSE;
1474 static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
1475 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1476 TRACE("(%p/%p)->()\n", This, iface);
1478 if (This->state == State_Paused) return S_OK;
1480 EnterCriticalSection(&This->cs);
1481 SendFilterMessage(iface, SendPause);
1482 This->state = State_Paused;
1483 LeaveCriticalSection(&This->cs);
1484 return S_FALSE;
1487 static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
1488 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1489 TRACE("(%p/%p)->()\n", This, iface);
1491 if (This->state == State_Stopped) return S_OK;
1493 EnterCriticalSection(&This->cs);
1494 if (This->state == State_Running) SendFilterMessage(iface, SendPause);
1495 SendFilterMessage(iface, SendStop);
1496 This->state = State_Stopped;
1497 LeaveCriticalSection(&This->cs);
1498 return S_FALSE;
1501 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
1502 LONG msTimeout,
1503 OAFilterState *pfs) {
1504 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1506 TRACE("(%p/%p)->(%d, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
1508 EnterCriticalSection(&This->cs);
1510 *pfs = This->state;
1512 LeaveCriticalSection(&This->cs);
1514 return S_OK;
1517 static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface,
1518 BSTR strFilename) {
1519 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1521 TRACE("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
1523 return S_OK;
1526 static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface,
1527 BSTR strFilename,
1528 IDispatch **ppUnk) {
1529 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1531 TRACE("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
1533 return S_OK;
1536 static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface,
1537 IDispatch **ppUnk) {
1538 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1540 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1542 return S_OK;
1545 static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
1546 IDispatch **ppUnk) {
1547 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1549 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1551 return S_OK;
1554 static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) {
1555 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1557 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1559 return S_OK;
1563 static const IMediaControlVtbl IMediaControl_VTable =
1565 MediaControl_QueryInterface,
1566 MediaControl_AddRef,
1567 MediaControl_Release,
1568 MediaControl_GetTypeInfoCount,
1569 MediaControl_GetTypeInfo,
1570 MediaControl_GetIDsOfNames,
1571 MediaControl_Invoke,
1572 MediaControl_Run,
1573 MediaControl_Pause,
1574 MediaControl_Stop,
1575 MediaControl_GetState,
1576 MediaControl_RenderFile,
1577 MediaControl_AddSourceFilter,
1578 MediaControl_get_FilterCollection,
1579 MediaControl_get_RegFilterCollection,
1580 MediaControl_StopWhenReady
1584 /*** IUnknown methods ***/
1585 static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface,
1586 REFIID riid,
1587 LPVOID*ppvObj) {
1588 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1590 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1592 return Filtergraph_QueryInterface(This, riid, ppvObj);
1595 static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) {
1596 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1598 TRACE("(%p/%p)->()\n", This, iface);
1600 return Filtergraph_AddRef(This);
1603 static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
1604 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1606 TRACE("(%p/%p)->()\n", This, iface);
1608 return Filtergraph_Release(This);
1611 /*** IMediaSeeking methods ***/
1612 static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
1613 DWORD *pCapabilities) {
1614 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1616 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1618 return S_OK;
1621 static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
1622 DWORD *pCapabilities) {
1623 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1625 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1627 return S_OK;
1630 static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface,
1631 const GUID *pFormat) {
1632 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1634 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1636 return S_OK;
1639 static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface,
1640 GUID *pFormat) {
1641 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1643 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1645 return S_OK;
1648 static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface,
1649 GUID *pFormat) {
1650 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1652 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1654 return S_OK;
1657 static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface,
1658 const GUID *pFormat) {
1659 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1661 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1663 return S_OK;
1666 static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
1667 const GUID *pFormat) {
1668 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1670 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1672 return S_OK;
1675 static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
1676 LONGLONG *pDuration) {
1677 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1679 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDuration);
1681 return S_OK;
1684 static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
1685 LONGLONG *pStop) {
1686 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1688 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pStop);
1690 return S_OK;
1693 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
1694 LONGLONG *pCurrent) {
1695 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1697 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCurrent);
1699 return S_OK;
1702 static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface,
1703 LONGLONG *pTarget,
1704 const GUID *pTargetFormat,
1705 LONGLONG Source,
1706 const GUID *pSourceFormat) {
1707 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1709 TRACE("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget,
1710 pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat);
1712 return S_OK;
1715 static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface,
1716 LONGLONG *pCurrent,
1717 DWORD dwCurrentFlags,
1718 LONGLONG *pStop,
1719 DWORD dwStopFlags) {
1720 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1722 TRACE("(%p/%p)->(%p, %08x, %p, %08x): stub !!!\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
1724 return S_OK;
1727 static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
1728 LONGLONG *pCurrent,
1729 LONGLONG *pStop) {
1730 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1732 TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pCurrent, pStop);
1734 return S_OK;
1737 static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
1738 LONGLONG *pEarliest,
1739 LONGLONG *pLatest) {
1740 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1742 TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
1744 return S_OK;
1747 static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface,
1748 double dRate) {
1749 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1751 TRACE("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
1753 return S_OK;
1756 static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface,
1757 double *pdRate) {
1758 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1760 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
1762 return S_OK;
1765 static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface,
1766 LONGLONG *pllPreroll) {
1767 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1769 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
1771 return S_OK;
1775 static const IMediaSeekingVtbl IMediaSeeking_VTable =
1777 MediaSeeking_QueryInterface,
1778 MediaSeeking_AddRef,
1779 MediaSeeking_Release,
1780 MediaSeeking_GetCapabilities,
1781 MediaSeeking_CheckCapabilities,
1782 MediaSeeking_IsFormatSupported,
1783 MediaSeeking_QueryPreferredFormat,
1784 MediaSeeking_GetTimeFormat,
1785 MediaSeeking_IsUsingTimeFormat,
1786 MediaSeeking_SetTimeFormat,
1787 MediaSeeking_GetDuration,
1788 MediaSeeking_GetStopPosition,
1789 MediaSeeking_GetCurrentPosition,
1790 MediaSeeking_ConvertTimeFormat,
1791 MediaSeeking_SetPositions,
1792 MediaSeeking_GetPositions,
1793 MediaSeeking_GetAvailable,
1794 MediaSeeking_SetRate,
1795 MediaSeeking_GetRate,
1796 MediaSeeking_GetPreroll
1799 /*** IUnknown methods ***/
1800 static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID riid, void** ppvObj){
1801 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1803 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1805 return Filtergraph_QueryInterface(This, riid, ppvObj);
1808 static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface){
1809 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1811 TRACE("(%p/%p)->()\n", This, iface);
1813 return Filtergraph_AddRef(This);
1816 static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface){
1817 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1819 TRACE("(%p/%p)->()\n", This, iface);
1821 return Filtergraph_Release(This);
1824 /*** IDispatch methods ***/
1825 static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){
1826 FIXME("(%p) stub!\n", iface);
1827 return E_NOTIMPL;
1830 static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){
1831 FIXME("(%p) stub!\n", iface);
1832 return E_NOTIMPL;
1835 static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){
1836 FIXME("(%p) stub!\n", iface);
1837 return E_NOTIMPL;
1840 static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){
1841 FIXME("(%p) stub!\n", iface);
1842 return E_NOTIMPL;
1845 /*** IMediaPosition methods ***/
1846 static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength){
1847 FIXME("(%p)->(%p) stub!\n", iface, plength);
1848 return E_NOTIMPL;
1851 static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime){
1852 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1853 return E_NOTIMPL;
1856 static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime){
1857 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1858 return E_NOTIMPL;
1861 static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime){
1862 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1863 return E_NOTIMPL;
1866 static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime){
1867 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1868 return E_NOTIMPL;
1871 static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){
1872 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1873 return E_NOTIMPL;
1876 static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){
1877 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1878 return E_NOTIMPL;
1881 static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate){
1882 FIXME("(%p)->(%f) stub!\n", iface, dRate);
1883 return E_NOTIMPL;
1886 static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate){
1887 FIXME("(%p)->(%p) stub!\n", iface, pdRate);
1888 return E_NOTIMPL;
1891 static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){
1892 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward);
1893 return E_NOTIMPL;
1896 static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){
1897 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward);
1898 return E_NOTIMPL;
1902 static const IMediaPositionVtbl IMediaPosition_VTable =
1904 MediaPosition_QueryInterface,
1905 MediaPosition_AddRef,
1906 MediaPosition_Release,
1907 MediaPosition_GetTypeInfoCount,
1908 MediaPosition_GetTypeInfo,
1909 MediaPosition_GetIDsOfNames,
1910 MediaPosition_Invoke,
1911 MediaPosition_get_Duration,
1912 MediaPosition_put_CurrentPosition,
1913 MediaPosition_get_CurrentPosition,
1914 MediaPosition_get_StopTime,
1915 MediaPosition_put_StopTime,
1916 MediaPosition_get_PrerollTime,
1917 MediaPosition_put_PrerollTime,
1918 MediaPosition_put_Rate,
1919 MediaPosition_get_Rate,
1920 MediaPosition_CanSeekForward,
1921 MediaPosition_CanSeekBackward
1924 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
1926 HRESULT hr = E_NOINTERFACE;
1927 int i;
1928 int entry;
1930 /* Check if the interface type is already registered */
1931 for (entry = 0; entry < pGraph->nItfCacheEntries; entry++)
1932 if (riid == pGraph->ItfCacheEntries[entry].riid)
1934 if (pGraph->ItfCacheEntries[entry].iface)
1936 /* Return the interface if available */
1937 *ppvObj = pGraph->ItfCacheEntries[entry].iface;
1938 return S_OK;
1940 break;
1943 if (entry >= MAX_ITF_CACHE_ENTRIES)
1945 FIXME("Not enough space to store interface in the cache\n");
1946 return E_OUTOFMEMORY;
1949 /* Find a filter supporting the requested interface */
1950 for (i = 0; i < pGraph->nFilters; i++)
1952 hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
1953 if (hr == S_OK)
1955 pGraph->ItfCacheEntries[entry].riid = riid;
1956 pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
1957 pGraph->ItfCacheEntries[entry].iface = (IUnknown*)*ppvObj;
1958 if (entry >= pGraph->nItfCacheEntries)
1959 pGraph->nItfCacheEntries++;
1960 return S_OK;
1962 if (hr != E_NOINTERFACE)
1963 return hr;
1966 return hr;
1969 /*** IUnknown methods ***/
1970 static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface,
1971 REFIID riid,
1972 LPVOID*ppvObj) {
1973 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1975 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1977 return Filtergraph_QueryInterface(This, riid, ppvObj);
1980 static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) {
1981 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1983 TRACE("(%p/%p)->()\n", This, iface);
1985 return Filtergraph_AddRef(This);
1988 static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) {
1989 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
1991 TRACE("(%p/%p)->()\n", This, iface);
1993 return Filtergraph_Release(This);
1996 /*** IDispatch methods ***/
1997 static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface,
1998 UINT*pctinfo) {
1999 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2000 IBasicAudio* pBasicAudio;
2001 HRESULT hr;
2003 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2005 EnterCriticalSection(&This->cs);
2007 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2009 if (hr == S_OK)
2010 hr = IBasicAudio_GetTypeInfoCount(pBasicAudio, pctinfo);
2012 LeaveCriticalSection(&This->cs);
2014 return hr;
2017 static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface,
2018 UINT iTInfo,
2019 LCID lcid,
2020 ITypeInfo**ppTInfo) {
2021 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2022 IBasicAudio* pBasicAudio;
2023 HRESULT hr;
2025 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2027 EnterCriticalSection(&This->cs);
2029 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2031 if (hr == S_OK)
2032 hr = IBasicAudio_GetTypeInfo(pBasicAudio, iTInfo, lcid, ppTInfo);
2034 LeaveCriticalSection(&This->cs);
2036 return hr;
2039 static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface,
2040 REFIID riid,
2041 LPOLESTR*rgszNames,
2042 UINT cNames,
2043 LCID lcid,
2044 DISPID*rgDispId) {
2045 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2046 IBasicAudio* pBasicAudio;
2047 HRESULT hr;
2049 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2051 EnterCriticalSection(&This->cs);
2053 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2055 if (hr == S_OK)
2056 hr = IBasicAudio_GetIDsOfNames(pBasicAudio, riid, rgszNames, cNames, lcid, rgDispId);
2058 LeaveCriticalSection(&This->cs);
2060 return hr;
2063 static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface,
2064 DISPID dispIdMember,
2065 REFIID riid,
2066 LCID lcid,
2067 WORD wFlags,
2068 DISPPARAMS*pDispParams,
2069 VARIANT*pVarResult,
2070 EXCEPINFO*pExepInfo,
2071 UINT*puArgErr) {
2072 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2073 IBasicAudio* pBasicAudio;
2074 HRESULT hr;
2076 TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p)\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2078 EnterCriticalSection(&This->cs);
2080 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2082 if (hr == S_OK)
2083 hr = IBasicAudio_Invoke(pBasicAudio, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2085 LeaveCriticalSection(&This->cs);
2087 return hr;
2090 /*** IBasicAudio methods ***/
2091 static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface,
2092 long lVolume) {
2093 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2094 IBasicAudio* pBasicAudio;
2095 HRESULT hr;
2097 TRACE("(%p/%p)->(%ld)\n", This, iface, lVolume);
2099 EnterCriticalSection(&This->cs);
2101 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2103 if (hr == S_OK)
2104 hr = IBasicAudio_put_Volume(pBasicAudio, lVolume);
2106 LeaveCriticalSection(&This->cs);
2108 return hr;
2111 static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface,
2112 long *plVolume) {
2113 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2114 IBasicAudio* pBasicAudio;
2115 HRESULT hr;
2117 TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
2119 EnterCriticalSection(&This->cs);
2121 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2123 if (hr == S_OK)
2124 hr = IBasicAudio_get_Volume(pBasicAudio, plVolume);
2126 LeaveCriticalSection(&This->cs);
2128 return hr;
2131 static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface,
2132 long lBalance) {
2133 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2134 IBasicAudio* pBasicAudio;
2135 HRESULT hr;
2137 TRACE("(%p/%p)->(%ld)\n", This, iface, lBalance);
2139 EnterCriticalSection(&This->cs);
2141 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2143 if (hr == S_OK)
2144 hr = IBasicAudio_put_Balance(pBasicAudio, lBalance);
2146 LeaveCriticalSection(&This->cs);
2148 return hr;
2151 static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface,
2152 long *plBalance) {
2153 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2154 IBasicAudio* pBasicAudio;
2155 HRESULT hr;
2157 TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
2159 EnterCriticalSection(&This->cs);
2161 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2163 if (hr == S_OK)
2164 hr = IBasicAudio_get_Balance(pBasicAudio, plBalance);
2166 LeaveCriticalSection(&This->cs);
2168 return hr;
2171 static const IBasicAudioVtbl IBasicAudio_VTable =
2173 BasicAudio_QueryInterface,
2174 BasicAudio_AddRef,
2175 BasicAudio_Release,
2176 BasicAudio_GetTypeInfoCount,
2177 BasicAudio_GetTypeInfo,
2178 BasicAudio_GetIDsOfNames,
2179 BasicAudio_Invoke,
2180 BasicAudio_put_Volume,
2181 BasicAudio_get_Volume,
2182 BasicAudio_put_Balance,
2183 BasicAudio_get_Balance
2186 /*** IUnknown methods ***/
2187 static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo *iface,
2188 REFIID riid,
2189 LPVOID*ppvObj) {
2190 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2192 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2194 return Filtergraph_QueryInterface(This, riid, ppvObj);
2197 static ULONG WINAPI BasicVideo_AddRef(IBasicVideo *iface) {
2198 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2200 TRACE("(%p/%p)->()\n", This, iface);
2202 return Filtergraph_AddRef(This);
2205 static ULONG WINAPI BasicVideo_Release(IBasicVideo *iface) {
2206 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2208 TRACE("(%p/%p)->()\n", This, iface);
2210 return Filtergraph_Release(This);
2213 /*** IDispatch methods ***/
2214 static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo *iface,
2215 UINT*pctinfo) {
2216 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2217 IBasicVideo* pBasicVideo;
2218 HRESULT hr;
2220 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2222 EnterCriticalSection(&This->cs);
2224 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2226 if (hr == S_OK)
2227 hr = IBasicVideo_GetTypeInfoCount(pBasicVideo, pctinfo);
2229 LeaveCriticalSection(&This->cs);
2231 return hr;
2234 static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo *iface,
2235 UINT iTInfo,
2236 LCID lcid,
2237 ITypeInfo**ppTInfo) {
2238 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2239 IBasicVideo* pBasicVideo;
2240 HRESULT hr;
2242 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2244 EnterCriticalSection(&This->cs);
2246 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2248 if (hr == S_OK)
2249 hr = IBasicVideo_GetTypeInfo(pBasicVideo, iTInfo, lcid, ppTInfo);
2251 LeaveCriticalSection(&This->cs);
2253 return hr;
2256 static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo *iface,
2257 REFIID riid,
2258 LPOLESTR*rgszNames,
2259 UINT cNames,
2260 LCID lcid,
2261 DISPID*rgDispId) {
2262 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2263 IBasicVideo* pBasicVideo;
2264 HRESULT hr;
2266 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2268 EnterCriticalSection(&This->cs);
2270 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2272 if (hr == S_OK)
2273 hr = IBasicVideo_GetIDsOfNames(pBasicVideo, riid, rgszNames, cNames, lcid, rgDispId);
2275 LeaveCriticalSection(&This->cs);
2277 return hr;
2280 static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo *iface,
2281 DISPID dispIdMember,
2282 REFIID riid,
2283 LCID lcid,
2284 WORD wFlags,
2285 DISPPARAMS*pDispParams,
2286 VARIANT*pVarResult,
2287 EXCEPINFO*pExepInfo,
2288 UINT*puArgErr) {
2289 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2290 IBasicVideo* pBasicVideo;
2291 HRESULT hr;
2293 TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p)\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2295 EnterCriticalSection(&This->cs);
2297 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2299 if (hr == S_OK)
2300 hr = IBasicVideo_Invoke(pBasicVideo, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2302 LeaveCriticalSection(&This->cs);
2304 return hr;
2307 /*** IBasicVideo methods ***/
2308 static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo *iface,
2309 REFTIME *pAvgTimePerFrame) {
2310 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2311 IBasicVideo* pBasicVideo;
2312 HRESULT hr;
2314 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
2316 EnterCriticalSection(&This->cs);
2318 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2320 if (hr == S_OK)
2321 hr = IBasicVideo_get_AvgTimePerFrame(pBasicVideo, pAvgTimePerFrame);
2323 LeaveCriticalSection(&This->cs);
2325 return hr;
2328 static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo *iface,
2329 long *pBitRate) {
2330 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2331 IBasicVideo* pBasicVideo;
2332 HRESULT hr;
2334 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
2336 EnterCriticalSection(&This->cs);
2338 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2340 if (hr == S_OK)
2341 hr = IBasicVideo_get_BitRate(pBasicVideo, pBitRate);
2343 LeaveCriticalSection(&This->cs);
2345 return hr;
2348 static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo *iface,
2349 long *pBitErrorRate) {
2350 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2351 IBasicVideo* pBasicVideo;
2352 HRESULT hr;
2354 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
2356 EnterCriticalSection(&This->cs);
2358 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2360 if (hr == S_OK)
2361 hr = IBasicVideo_get_BitErrorRate(pBasicVideo, pBitErrorRate);
2363 LeaveCriticalSection(&This->cs);
2365 return hr;
2368 static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo *iface,
2369 long *pVideoWidth) {
2370 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2371 IBasicVideo* pBasicVideo;
2372 HRESULT hr;
2374 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
2376 EnterCriticalSection(&This->cs);
2378 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2380 if (hr == S_OK)
2381 hr = IBasicVideo_get_VideoWidth(pBasicVideo, pVideoWidth);
2383 LeaveCriticalSection(&This->cs);
2385 return hr;
2388 static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo *iface,
2389 long *pVideoHeight) {
2390 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2391 IBasicVideo* pBasicVideo;
2392 HRESULT hr;
2394 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
2396 EnterCriticalSection(&This->cs);
2398 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2400 if (hr == S_OK)
2401 hr = IBasicVideo_get_VideoHeight(pBasicVideo, pVideoHeight);
2403 LeaveCriticalSection(&This->cs);
2405 return hr;
2408 static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo *iface,
2409 long SourceLeft) {
2410 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2411 IBasicVideo* pBasicVideo;
2412 HRESULT hr;
2414 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft);
2416 EnterCriticalSection(&This->cs);
2418 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2420 if (hr == S_OK)
2421 hr = IBasicVideo_put_SourceLeft(pBasicVideo, SourceLeft);
2423 LeaveCriticalSection(&This->cs);
2425 return hr;
2428 static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo *iface,
2429 long *pSourceLeft) {
2430 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2431 IBasicVideo* pBasicVideo;
2432 HRESULT hr;
2434 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
2436 EnterCriticalSection(&This->cs);
2438 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2440 if (hr == S_OK)
2441 hr = IBasicVideo_get_SourceLeft(pBasicVideo, pSourceLeft);
2443 LeaveCriticalSection(&This->cs);
2445 return hr;
2448 static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo *iface,
2449 long SourceWidth) {
2450 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2451 IBasicVideo* pBasicVideo;
2452 HRESULT hr;
2454 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth);
2456 EnterCriticalSection(&This->cs);
2458 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2460 if (hr == S_OK)
2461 hr = IBasicVideo_put_SourceWidth(pBasicVideo, SourceWidth);
2463 LeaveCriticalSection(&This->cs);
2465 return hr;
2468 static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo *iface,
2469 long *pSourceWidth) {
2470 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2471 IBasicVideo* pBasicVideo;
2472 HRESULT hr;
2474 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
2476 EnterCriticalSection(&This->cs);
2478 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2480 if (hr == S_OK)
2481 hr = IBasicVideo_get_SourceWidth(pBasicVideo, pSourceWidth);
2483 LeaveCriticalSection(&This->cs);
2485 return hr;
2488 static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo *iface,
2489 long SourceTop) {
2490 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2491 IBasicVideo* pBasicVideo;
2492 HRESULT hr;
2494 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop);
2496 EnterCriticalSection(&This->cs);
2498 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2500 if (hr == S_OK)
2501 hr = IBasicVideo_put_SourceTop(pBasicVideo, SourceTop);
2503 LeaveCriticalSection(&This->cs);
2505 return hr;
2508 static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo *iface,
2509 long *pSourceTop) {
2510 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2511 IBasicVideo* pBasicVideo;
2512 HRESULT hr;
2514 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
2516 EnterCriticalSection(&This->cs);
2518 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2520 if (hr == S_OK)
2521 hr = IBasicVideo_get_SourceTop(pBasicVideo, pSourceTop);
2523 LeaveCriticalSection(&This->cs);
2525 return hr;
2528 static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo *iface,
2529 long SourceHeight) {
2530 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2531 IBasicVideo* pBasicVideo;
2532 HRESULT hr;
2534 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight);
2536 EnterCriticalSection(&This->cs);
2538 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2540 if (hr == S_OK)
2541 hr = IBasicVideo_put_SourceHeight(pBasicVideo, SourceHeight);
2543 LeaveCriticalSection(&This->cs);
2545 return hr;
2548 static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo *iface,
2549 long *pSourceHeight) {
2550 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2551 IBasicVideo* pBasicVideo;
2552 HRESULT hr;
2554 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
2556 EnterCriticalSection(&This->cs);
2558 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2560 if (hr == S_OK)
2561 hr = IBasicVideo_get_SourceHeight(pBasicVideo, pSourceHeight);
2563 LeaveCriticalSection(&This->cs);
2565 return hr;
2568 static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo *iface,
2569 long DestinationLeft) {
2570 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2571 IBasicVideo* pBasicVideo;
2572 HRESULT hr;
2574 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft);
2576 EnterCriticalSection(&This->cs);
2578 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2580 if (hr == S_OK)
2581 hr = IBasicVideo_put_DestinationLeft(pBasicVideo, DestinationLeft);
2583 LeaveCriticalSection(&This->cs);
2585 return hr;
2588 static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo *iface,
2589 long *pDestinationLeft) {
2590 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2591 IBasicVideo* pBasicVideo;
2592 HRESULT hr;
2594 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
2596 EnterCriticalSection(&This->cs);
2598 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2600 if (hr == S_OK)
2601 hr = IBasicVideo_get_DestinationLeft(pBasicVideo, pDestinationLeft);
2603 LeaveCriticalSection(&This->cs);
2605 return hr;
2608 static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo *iface,
2609 long DestinationWidth) {
2610 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2611 IBasicVideo* pBasicVideo;
2612 HRESULT hr;
2614 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth);
2616 EnterCriticalSection(&This->cs);
2618 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2620 if (hr == S_OK)
2621 hr = IBasicVideo_put_DestinationWidth(pBasicVideo, DestinationWidth);
2623 LeaveCriticalSection(&This->cs);
2625 return hr;
2628 static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo *iface,
2629 long *pDestinationWidth) {
2630 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2631 IBasicVideo* pBasicVideo;
2632 HRESULT hr;
2634 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
2636 EnterCriticalSection(&This->cs);
2638 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2640 if (hr == S_OK)
2641 hr = IBasicVideo_get_DestinationWidth(pBasicVideo, pDestinationWidth);
2643 LeaveCriticalSection(&This->cs);
2645 return hr;
2648 static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo *iface,
2649 long DestinationTop) {
2650 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2651 IBasicVideo* pBasicVideo;
2652 HRESULT hr;
2654 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop);
2656 EnterCriticalSection(&This->cs);
2658 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2660 if (hr == S_OK)
2661 hr = IBasicVideo_put_DestinationTop(pBasicVideo, DestinationTop);
2663 LeaveCriticalSection(&This->cs);
2665 return hr;
2668 static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo *iface,
2669 long *pDestinationTop) {
2670 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2671 IBasicVideo* pBasicVideo;
2672 HRESULT hr;
2674 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
2676 EnterCriticalSection(&This->cs);
2678 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2680 if (hr == S_OK)
2681 hr = IBasicVideo_get_DestinationTop(pBasicVideo, pDestinationTop);
2683 LeaveCriticalSection(&This->cs);
2685 return hr;
2688 static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo *iface,
2689 long DestinationHeight) {
2690 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2691 IBasicVideo* pBasicVideo;
2692 HRESULT hr;
2694 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight);
2696 EnterCriticalSection(&This->cs);
2698 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2700 if (hr == S_OK)
2701 hr = IBasicVideo_put_DestinationHeight(pBasicVideo, DestinationHeight);
2703 LeaveCriticalSection(&This->cs);
2705 return hr;
2708 static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo *iface,
2709 long *pDestinationHeight) {
2710 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2711 IBasicVideo* pBasicVideo;
2712 HRESULT hr;
2714 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
2716 EnterCriticalSection(&This->cs);
2718 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2720 if (hr == S_OK)
2721 hr = IBasicVideo_get_DestinationHeight(pBasicVideo, pDestinationHeight);
2723 LeaveCriticalSection(&This->cs);
2725 return hr;
2728 static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo *iface,
2729 long Left,
2730 long Top,
2731 long Width,
2732 long Height) {
2733 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2734 IBasicVideo* pBasicVideo;
2735 HRESULT hr;
2737 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
2739 EnterCriticalSection(&This->cs);
2741 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2743 if (hr == S_OK)
2744 hr = IBasicVideo_SetSourcePosition(pBasicVideo, Left, Top, Width, Height);
2746 LeaveCriticalSection(&This->cs);
2748 return hr;
2751 static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo *iface,
2752 long *pLeft,
2753 long *pTop,
2754 long *pWidth,
2755 long *pHeight) {
2756 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2757 IBasicVideo* pBasicVideo;
2758 HRESULT hr;
2760 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
2762 EnterCriticalSection(&This->cs);
2764 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2766 if (hr == S_OK)
2767 hr = IBasicVideo_GetSourcePosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
2769 LeaveCriticalSection(&This->cs);
2771 return hr;
2774 static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo *iface) {
2775 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2776 IBasicVideo* pBasicVideo;
2777 HRESULT hr;
2779 TRACE("(%p/%p)->()\n", This, iface);
2781 EnterCriticalSection(&This->cs);
2783 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2785 if (hr == S_OK)
2786 hr = IBasicVideo_SetDefaultSourcePosition(pBasicVideo);
2788 LeaveCriticalSection(&This->cs);
2790 return hr;
2793 static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo *iface,
2794 long Left,
2795 long Top,
2796 long Width,
2797 long Height) {
2798 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2799 IBasicVideo* pBasicVideo;
2800 HRESULT hr;
2802 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
2804 EnterCriticalSection(&This->cs);
2806 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2808 if (hr == S_OK)
2809 hr = IBasicVideo_SetDestinationPosition(pBasicVideo, Left, Top, Width, Height);
2811 LeaveCriticalSection(&This->cs);
2813 return hr;
2816 static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo *iface,
2817 long *pLeft,
2818 long *pTop,
2819 long *pWidth,
2820 long *pHeight) {
2821 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2822 IBasicVideo* pBasicVideo;
2823 HRESULT hr;
2825 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
2827 EnterCriticalSection(&This->cs);
2829 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2831 if (hr == S_OK)
2832 hr = IBasicVideo_GetDestinationPosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
2834 LeaveCriticalSection(&This->cs);
2836 return hr;
2839 static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
2840 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2841 IBasicVideo* pBasicVideo;
2842 HRESULT hr;
2844 TRACE("(%p/%p)->()\n", This, iface);
2846 EnterCriticalSection(&This->cs);
2848 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2850 if (hr == S_OK)
2851 hr = IBasicVideo_SetDefaultDestinationPosition(pBasicVideo);
2853 LeaveCriticalSection(&This->cs);
2855 return hr;
2858 static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo *iface,
2859 long *pWidth,
2860 long *pHeight) {
2861 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2862 IBasicVideo* pBasicVideo;
2863 HRESULT hr;
2865 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
2867 EnterCriticalSection(&This->cs);
2869 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2871 if (hr == S_OK)
2872 hr = IBasicVideo_GetVideoSize(pBasicVideo, pWidth, pHeight);
2874 LeaveCriticalSection(&This->cs);
2876 return hr;
2879 static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo *iface,
2880 long StartIndex,
2881 long Entries,
2882 long *pRetrieved,
2883 long *pPalette) {
2884 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2885 IBasicVideo* pBasicVideo;
2886 HRESULT hr;
2888 TRACE("(%p/%p)->(%ld, %ld, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
2890 EnterCriticalSection(&This->cs);
2892 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2894 if (hr == S_OK)
2895 hr = IBasicVideo_GetVideoPaletteEntries(pBasicVideo, StartIndex, Entries, pRetrieved, pPalette);
2897 LeaveCriticalSection(&This->cs);
2899 return hr;
2902 static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo *iface,
2903 long *pBufferSize,
2904 long *pDIBImage) {
2905 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2906 IBasicVideo* pBasicVideo;
2907 HRESULT hr;
2909 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage);
2911 EnterCriticalSection(&This->cs);
2913 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2915 if (hr == S_OK)
2916 hr = IBasicVideo_GetCurrentImage(pBasicVideo, pBufferSize, pDIBImage);
2918 LeaveCriticalSection(&This->cs);
2920 return hr;
2923 static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo *iface) {
2924 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2925 IBasicVideo* pBasicVideo;
2926 HRESULT hr;
2928 TRACE("(%p/%p)->()\n", This, iface);
2930 EnterCriticalSection(&This->cs);
2932 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2934 if (hr == S_OK)
2935 hr = IBasicVideo_IsUsingDefaultSource(pBasicVideo);
2937 LeaveCriticalSection(&This->cs);
2939 return hr;
2942 static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo *iface) {
2943 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2944 IBasicVideo* pBasicVideo;
2945 HRESULT hr;
2947 TRACE("(%p/%p)->()\n", This, iface);
2949 EnterCriticalSection(&This->cs);
2951 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2953 if (hr == S_OK)
2954 hr = IBasicVideo_IsUsingDefaultDestination(pBasicVideo);
2956 LeaveCriticalSection(&This->cs);
2958 return hr;
2962 static const IBasicVideoVtbl IBasicVideo_VTable =
2964 BasicVideo_QueryInterface,
2965 BasicVideo_AddRef,
2966 BasicVideo_Release,
2967 BasicVideo_GetTypeInfoCount,
2968 BasicVideo_GetTypeInfo,
2969 BasicVideo_GetIDsOfNames,
2970 BasicVideo_Invoke,
2971 BasicVideo_get_AvgTimePerFrame,
2972 BasicVideo_get_BitRate,
2973 BasicVideo_get_BitErrorRate,
2974 BasicVideo_get_VideoWidth,
2975 BasicVideo_get_VideoHeight,
2976 BasicVideo_put_SourceLeft,
2977 BasicVideo_get_SourceLeft,
2978 BasicVideo_put_SourceWidth,
2979 BasicVideo_get_SourceWidth,
2980 BasicVideo_put_SourceTop,
2981 BasicVideo_get_SourceTop,
2982 BasicVideo_put_SourceHeight,
2983 BasicVideo_get_SourceHeight,
2984 BasicVideo_put_DestinationLeft,
2985 BasicVideo_get_DestinationLeft,
2986 BasicVideo_put_DestinationWidth,
2987 BasicVideo_get_DestinationWidth,
2988 BasicVideo_put_DestinationTop,
2989 BasicVideo_get_DestinationTop,
2990 BasicVideo_put_DestinationHeight,
2991 BasicVideo_get_DestinationHeight,
2992 BasicVideo_SetSourcePosition,
2993 BasicVideo_GetSourcePosition,
2994 BasicVideo_SetDefaultSourcePosition,
2995 BasicVideo_SetDestinationPosition,
2996 BasicVideo_GetDestinationPosition,
2997 BasicVideo_SetDefaultDestinationPosition,
2998 BasicVideo_GetVideoSize,
2999 BasicVideo_GetVideoPaletteEntries,
3000 BasicVideo_GetCurrentImage,
3001 BasicVideo_IsUsingDefaultSource,
3002 BasicVideo_IsUsingDefaultDestination
3006 /*** IUnknown methods ***/
3007 static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface,
3008 REFIID riid,
3009 LPVOID*ppvObj) {
3010 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3012 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3014 return Filtergraph_QueryInterface(This, riid, ppvObj);
3017 static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) {
3018 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3020 TRACE("(%p/%p)->()\n", This, iface);
3022 return Filtergraph_AddRef(This);
3025 static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) {
3026 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3028 TRACE("(%p/%p)->()\n", This, iface);
3030 return Filtergraph_Release(This);
3033 /*** IDispatch methods ***/
3034 static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface,
3035 UINT*pctinfo) {
3036 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3037 IVideoWindow* pVideoWindow;
3038 HRESULT hr;
3040 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3042 EnterCriticalSection(&This->cs);
3044 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3046 if (hr == S_OK)
3047 hr = IVideoWindow_GetTypeInfoCount(pVideoWindow, pctinfo);
3049 LeaveCriticalSection(&This->cs);
3051 return hr;
3054 static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface,
3055 UINT iTInfo,
3056 LCID lcid,
3057 ITypeInfo**ppTInfo) {
3058 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3059 IVideoWindow* pVideoWindow;
3060 HRESULT hr;
3062 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3064 EnterCriticalSection(&This->cs);
3066 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3068 if (hr == S_OK)
3069 hr = IVideoWindow_GetTypeInfo(pVideoWindow, iTInfo, lcid, ppTInfo);
3071 LeaveCriticalSection(&This->cs);
3073 return hr;
3076 static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface,
3077 REFIID riid,
3078 LPOLESTR*rgszNames,
3079 UINT cNames,
3080 LCID lcid,
3081 DISPID*rgDispId) {
3082 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3083 IVideoWindow* pVideoWindow;
3084 HRESULT hr;
3086 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3088 EnterCriticalSection(&This->cs);
3090 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3092 if (hr == S_OK)
3093 hr = IVideoWindow_GetIDsOfNames(pVideoWindow, riid, rgszNames, cNames, lcid, rgDispId);
3095 LeaveCriticalSection(&This->cs);
3097 return hr;
3100 static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface,
3101 DISPID dispIdMember,
3102 REFIID riid,
3103 LCID lcid,
3104 WORD wFlags,
3105 DISPPARAMS*pDispParams,
3106 VARIANT*pVarResult,
3107 EXCEPINFO*pExepInfo,
3108 UINT*puArgErr) {
3109 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3110 IVideoWindow* pVideoWindow;
3111 HRESULT hr;
3113 TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p)\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3115 EnterCriticalSection(&This->cs);
3117 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3119 if (hr == S_OK)
3120 hr = IVideoWindow_Invoke(pVideoWindow, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3122 LeaveCriticalSection(&This->cs);
3124 return hr;
3128 /*** IVideoWindow methods ***/
3129 static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface,
3130 BSTR strCaption) {
3131 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3132 IVideoWindow* pVideoWindow;
3133 HRESULT hr;
3135 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
3137 EnterCriticalSection(&This->cs);
3139 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3141 if (hr == S_OK)
3142 hr = IVideoWindow_put_Caption(pVideoWindow, strCaption);
3144 LeaveCriticalSection(&This->cs);
3146 return hr;
3149 static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface,
3150 BSTR *strCaption) {
3151 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3152 IVideoWindow* pVideoWindow;
3153 HRESULT hr;
3155 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
3157 EnterCriticalSection(&This->cs);
3159 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3161 if (hr == S_OK)
3162 hr = IVideoWindow_get_Caption(pVideoWindow, strCaption);
3164 LeaveCriticalSection(&This->cs);
3166 return hr;
3169 static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface,
3170 long WindowStyle) {
3171 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3172 IVideoWindow* pVideoWindow;
3173 HRESULT hr;
3175 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyle);
3177 EnterCriticalSection(&This->cs);
3179 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3181 if (hr == S_OK)
3182 hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle);
3184 LeaveCriticalSection(&This->cs);
3186 return hr;
3189 static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface,
3190 long *WindowStyle) {
3191 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3192 IVideoWindow* pVideoWindow;
3193 HRESULT hr;
3195 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
3197 EnterCriticalSection(&This->cs);
3199 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3201 if (hr == S_OK)
3202 hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle);
3204 LeaveCriticalSection(&This->cs);
3206 return hr;
3209 static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface,
3210 long WindowStyleEx) {
3211 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3212 IVideoWindow* pVideoWindow;
3213 HRESULT hr;
3215 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx);
3217 EnterCriticalSection(&This->cs);
3219 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3221 if (hr == S_OK)
3222 hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx);
3224 LeaveCriticalSection(&This->cs);
3226 return hr;
3229 static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface,
3230 long *WindowStyleEx) {
3231 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3232 IVideoWindow* pVideoWindow;
3233 HRESULT hr;
3235 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
3237 EnterCriticalSection(&This->cs);
3239 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3241 if (hr == S_OK)
3242 hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx);
3244 LeaveCriticalSection(&This->cs);
3246 return hr;
3249 static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface,
3250 long AutoShow) {
3251 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3252 IVideoWindow* pVideoWindow;
3253 HRESULT hr;
3255 TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow);
3257 EnterCriticalSection(&This->cs);
3259 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3261 if (hr == S_OK)
3262 hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow);
3264 LeaveCriticalSection(&This->cs);
3266 return hr;
3269 static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface,
3270 long *AutoShow) {
3271 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3272 IVideoWindow* pVideoWindow;
3273 HRESULT hr;
3275 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
3277 EnterCriticalSection(&This->cs);
3279 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3281 if (hr == S_OK)
3282 hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow);
3284 LeaveCriticalSection(&This->cs);
3286 return hr;
3289 static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface,
3290 long WindowState) {
3291 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3292 IVideoWindow* pVideoWindow;
3293 HRESULT hr;
3295 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowState);
3297 EnterCriticalSection(&This->cs);
3299 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3301 if (hr == S_OK)
3302 hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState);
3304 LeaveCriticalSection(&This->cs);
3306 return hr;
3309 static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface,
3310 long *WindowState) {
3311 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3312 IVideoWindow* pVideoWindow;
3313 HRESULT hr;
3315 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
3317 EnterCriticalSection(&This->cs);
3319 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3321 if (hr == S_OK)
3322 hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState);
3324 LeaveCriticalSection(&This->cs);
3326 return hr;
3329 static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface,
3330 long BackgroundPalette) {
3331 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3332 IVideoWindow* pVideoWindow;
3333 HRESULT hr;
3335 TRACE("(%p/%p)->(%ld)\n", This, iface, BackgroundPalette);
3337 EnterCriticalSection(&This->cs);
3339 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3341 if (hr == S_OK)
3342 hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette);
3344 LeaveCriticalSection(&This->cs);
3346 return hr;
3349 static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface,
3350 long *pBackgroundPalette) {
3351 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3352 IVideoWindow* pVideoWindow;
3353 HRESULT hr;
3355 TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette);
3357 EnterCriticalSection(&This->cs);
3359 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3361 if (hr == S_OK)
3362 hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette);
3364 LeaveCriticalSection(&This->cs);
3366 return hr;
3369 static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface,
3370 long Visible) {
3371 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3372 IVideoWindow* pVideoWindow;
3373 HRESULT hr;
3375 TRACE("(%p/%p)->(%ld)\n", This, iface, Visible);
3377 EnterCriticalSection(&This->cs);
3379 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3381 if (hr == S_OK)
3382 hr = IVideoWindow_put_Visible(pVideoWindow, Visible);
3384 LeaveCriticalSection(&This->cs);
3386 return hr;
3389 static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface,
3390 long *pVisible) {
3391 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3392 IVideoWindow* pVideoWindow;
3393 HRESULT hr;
3395 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
3397 EnterCriticalSection(&This->cs);
3399 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3401 if (hr == S_OK)
3402 hr = IVideoWindow_get_Visible(pVideoWindow, pVisible);
3404 LeaveCriticalSection(&This->cs);
3406 return hr;
3409 static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface,
3410 long Left) {
3411 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3412 IVideoWindow* pVideoWindow;
3413 HRESULT hr;
3415 TRACE("(%p/%p)->(%ld)\n", This, iface, Left);
3417 EnterCriticalSection(&This->cs);
3419 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3421 if (hr == S_OK)
3422 hr = IVideoWindow_put_Left(pVideoWindow, Left);
3424 LeaveCriticalSection(&This->cs);
3426 return hr;
3429 static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface,
3430 long *pLeft) {
3431 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3432 IVideoWindow* pVideoWindow;
3433 HRESULT hr;
3435 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
3437 EnterCriticalSection(&This->cs);
3439 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3441 if (hr == S_OK)
3442 hr = IVideoWindow_get_Left(pVideoWindow, pLeft);
3444 LeaveCriticalSection(&This->cs);
3446 return hr;
3449 static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface,
3450 long Width) {
3451 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3452 IVideoWindow* pVideoWindow;
3453 HRESULT hr;
3455 TRACE("(%p/%p)->(%ld)\n", This, iface, Width);
3457 EnterCriticalSection(&This->cs);
3459 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3461 if (hr == S_OK)
3462 hr = IVideoWindow_put_Width(pVideoWindow, Width);
3464 LeaveCriticalSection(&This->cs);
3466 return hr;
3469 static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface,
3470 long *pWidth) {
3471 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3472 IVideoWindow* pVideoWindow;
3473 HRESULT hr;
3475 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
3477 EnterCriticalSection(&This->cs);
3479 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3481 if (hr == S_OK)
3482 hr = IVideoWindow_get_Width(pVideoWindow, pWidth);
3484 LeaveCriticalSection(&This->cs);
3486 return hr;
3489 static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface,
3490 long Top) {
3491 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3492 IVideoWindow* pVideoWindow;
3493 HRESULT hr;
3495 TRACE("(%p/%p)->(%ld)\n", This, iface, Top);
3497 EnterCriticalSection(&This->cs);
3499 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3501 if (hr == S_OK)
3502 hr = IVideoWindow_put_Top(pVideoWindow, Top);
3504 LeaveCriticalSection(&This->cs);
3506 return hr;
3509 static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface,
3510 long *pTop) {
3511 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3512 IVideoWindow* pVideoWindow;
3513 HRESULT hr;
3515 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
3517 EnterCriticalSection(&This->cs);
3519 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3521 if (hr == S_OK)
3522 hr = IVideoWindow_get_Top(pVideoWindow, pTop);
3524 LeaveCriticalSection(&This->cs);
3526 return hr;
3529 static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface,
3530 long Height) {
3531 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3532 IVideoWindow* pVideoWindow;
3533 HRESULT hr;
3535 TRACE("(%p/%p)->(%ld)\n", This, iface, Height);
3537 EnterCriticalSection(&This->cs);
3539 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3541 if (hr == S_OK)
3542 hr = IVideoWindow_put_Height(pVideoWindow, Height);
3544 LeaveCriticalSection(&This->cs);
3546 return hr;
3549 static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface,
3550 long *pHeight) {
3551 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3552 IVideoWindow* pVideoWindow;
3553 HRESULT hr;
3555 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
3557 EnterCriticalSection(&This->cs);
3559 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3561 if (hr == S_OK)
3562 hr = IVideoWindow_get_Height(pVideoWindow, pHeight);
3564 LeaveCriticalSection(&This->cs);
3566 return hr;
3569 static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface,
3570 OAHWND Owner) {
3571 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3572 IVideoWindow* pVideoWindow;
3573 HRESULT hr;
3575 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
3577 EnterCriticalSection(&This->cs);
3579 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3581 if (hr == S_OK)
3582 hr = IVideoWindow_put_Owner(pVideoWindow, Owner);
3584 LeaveCriticalSection(&This->cs);
3586 return hr;
3589 static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface,
3590 OAHWND *Owner) {
3591 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3592 IVideoWindow* pVideoWindow;
3593 HRESULT hr;
3595 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
3597 EnterCriticalSection(&This->cs);
3599 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3601 if (hr == S_OK)
3602 hr = IVideoWindow_get_Owner(pVideoWindow, Owner);
3604 LeaveCriticalSection(&This->cs);
3606 return hr;
3609 static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface,
3610 OAHWND Drain) {
3611 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3612 IVideoWindow* pVideoWindow;
3613 HRESULT hr;
3615 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
3617 EnterCriticalSection(&This->cs);
3619 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3621 if (hr == S_OK)
3622 hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain);
3624 LeaveCriticalSection(&This->cs);
3626 return hr;
3629 static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface,
3630 OAHWND *Drain) {
3631 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3632 IVideoWindow* pVideoWindow;
3633 HRESULT hr;
3635 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
3637 EnterCriticalSection(&This->cs);
3639 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3641 if (hr == S_OK)
3642 hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain);
3644 LeaveCriticalSection(&This->cs);
3646 return hr;
3649 static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface,
3650 long *Color) {
3651 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3652 IVideoWindow* pVideoWindow;
3653 HRESULT hr;
3655 TRACE("(%p/%p)->(%p)\n", This, iface, Color);
3657 EnterCriticalSection(&This->cs);
3659 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3661 if (hr == S_OK)
3662 hr = IVideoWindow_get_BorderColor(pVideoWindow, Color);
3664 LeaveCriticalSection(&This->cs);
3666 return hr;
3669 static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface,
3670 long Color) {
3671 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3672 IVideoWindow* pVideoWindow;
3673 HRESULT hr;
3675 TRACE("(%p/%p)->(%ld)\n", This, iface, Color);
3677 EnterCriticalSection(&This->cs);
3679 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3681 if (hr == S_OK)
3682 hr = IVideoWindow_put_BorderColor(pVideoWindow, Color);
3684 LeaveCriticalSection(&This->cs);
3686 return hr;
3689 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
3690 long *FullScreenMode) {
3691 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3692 IVideoWindow* pVideoWindow;
3693 HRESULT hr;
3695 TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode);
3697 EnterCriticalSection(&This->cs);
3699 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3701 if (hr == S_OK)
3702 hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode);
3704 LeaveCriticalSection(&This->cs);
3706 return hr;
3709 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
3710 long FullScreenMode) {
3711 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3712 IVideoWindow* pVideoWindow;
3713 HRESULT hr;
3715 TRACE("(%p/%p)->(%ld)\n", This, iface, FullScreenMode);
3717 EnterCriticalSection(&This->cs);
3719 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3721 if (hr == S_OK)
3722 hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode);
3724 LeaveCriticalSection(&This->cs);
3726 return hr;
3729 static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface,
3730 long Focus) {
3731 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3732 IVideoWindow* pVideoWindow;
3733 HRESULT hr;
3735 TRACE("(%p/%p)->(%ld)\n", This, iface, Focus);
3737 EnterCriticalSection(&This->cs);
3739 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3741 if (hr == S_OK)
3742 hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus);
3744 LeaveCriticalSection(&This->cs);
3746 return hr;
3749 static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface,
3750 OAHWND hwnd,
3751 long uMsg,
3752 LONG_PTR wParam,
3753 LONG_PTR lParam) {
3754 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3755 IVideoWindow* pVideoWindow;
3756 HRESULT hr;
3758 TRACE("(%p/%p)->(%08x, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
3760 EnterCriticalSection(&This->cs);
3762 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3764 if (hr == S_OK)
3765 hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam);
3767 LeaveCriticalSection(&This->cs);
3769 return hr;
3772 static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface,
3773 long Left,
3774 long Top,
3775 long Width,
3776 long Height) {
3777 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3778 IVideoWindow* pVideoWindow;
3779 HRESULT hr;
3781 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3783 EnterCriticalSection(&This->cs);
3785 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3787 if (hr == S_OK)
3788 hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height);
3790 LeaveCriticalSection(&This->cs);
3792 return hr;
3795 static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface,
3796 long *pLeft,
3797 long *pTop,
3798 long *pWidth,
3799 long *pHeight) {
3800 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3801 IVideoWindow* pVideoWindow;
3802 HRESULT hr;
3804 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3806 EnterCriticalSection(&This->cs);
3808 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3810 if (hr == S_OK)
3811 hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
3813 LeaveCriticalSection(&This->cs);
3815 return hr;
3818 static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface,
3819 long *pWidth,
3820 long *pHeight) {
3821 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3822 IVideoWindow* pVideoWindow;
3823 HRESULT hr;
3825 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3827 EnterCriticalSection(&This->cs);
3829 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3831 if (hr == S_OK)
3832 hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight);
3834 LeaveCriticalSection(&This->cs);
3836 return hr;
3839 static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface,
3840 long *pWidth,
3841 long *pHeight) {
3842 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3843 IVideoWindow* pVideoWindow;
3844 HRESULT hr;
3846 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3848 EnterCriticalSection(&This->cs);
3850 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3852 if (hr == S_OK)
3853 hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight);
3855 LeaveCriticalSection(&This->cs);
3857 return hr;
3860 static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface,
3861 long *pLeft,
3862 long *pTop,
3863 long *pWidth,
3864 long *pHeight) {
3865 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3866 IVideoWindow* pVideoWindow;
3867 HRESULT hr;
3869 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3871 EnterCriticalSection(&This->cs);
3873 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3875 if (hr == S_OK)
3876 hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
3878 LeaveCriticalSection(&This->cs);
3880 return hr;
3883 static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface,
3884 long HideCursor) {
3885 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3886 IVideoWindow* pVideoWindow;
3887 HRESULT hr;
3889 TRACE("(%p/%p)->(%ld)\n", This, iface, HideCursor);
3891 EnterCriticalSection(&This->cs);
3893 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3895 if (hr == S_OK)
3896 hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor);
3898 LeaveCriticalSection(&This->cs);
3900 return hr;
3903 static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface,
3904 long *CursorHidden) {
3905 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3906 IVideoWindow* pVideoWindow;
3907 HRESULT hr;
3909 TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden);
3911 EnterCriticalSection(&This->cs);
3913 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3915 if (hr == S_OK)
3916 hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden);
3918 LeaveCriticalSection(&This->cs);
3920 return hr;
3924 static const IVideoWindowVtbl IVideoWindow_VTable =
3926 VideoWindow_QueryInterface,
3927 VideoWindow_AddRef,
3928 VideoWindow_Release,
3929 VideoWindow_GetTypeInfoCount,
3930 VideoWindow_GetTypeInfo,
3931 VideoWindow_GetIDsOfNames,
3932 VideoWindow_Invoke,
3933 VideoWindow_put_Caption,
3934 VideoWindow_get_Caption,
3935 VideoWindow_put_WindowStyle,
3936 VideoWindow_get_WindowStyle,
3937 VideoWindow_put_WindowStyleEx,
3938 VideoWindow_get_WindowStyleEx,
3939 VideoWindow_put_AutoShow,
3940 VideoWindow_get_AutoShow,
3941 VideoWindow_put_WindowState,
3942 VideoWindow_get_WindowState,
3943 VideoWindow_put_BackgroundPalette,
3944 VideoWindow_get_BackgroundPalette,
3945 VideoWindow_put_Visible,
3946 VideoWindow_get_Visible,
3947 VideoWindow_put_Left,
3948 VideoWindow_get_Left,
3949 VideoWindow_put_Width,
3950 VideoWindow_get_Width,
3951 VideoWindow_put_Top,
3952 VideoWindow_get_Top,
3953 VideoWindow_put_Height,
3954 VideoWindow_get_Height,
3955 VideoWindow_put_Owner,
3956 VideoWindow_get_Owner,
3957 VideoWindow_put_MessageDrain,
3958 VideoWindow_get_MessageDrain,
3959 VideoWindow_get_BorderColor,
3960 VideoWindow_put_BorderColor,
3961 VideoWindow_get_FullScreenMode,
3962 VideoWindow_put_FullScreenMode,
3963 VideoWindow_SetWindowForeground,
3964 VideoWindow_NotifyOwnerMessage,
3965 VideoWindow_SetWindowPosition,
3966 VideoWindow_GetWindowPosition,
3967 VideoWindow_GetMinIdealImageSize,
3968 VideoWindow_GetMaxIdealImageSize,
3969 VideoWindow_GetRestorePosition,
3970 VideoWindow_HideCursor,
3971 VideoWindow_IsCursorHidden
3975 /*** IUnknown methods ***/
3976 static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface,
3977 REFIID riid,
3978 LPVOID*ppvObj) {
3979 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
3981 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3983 return Filtergraph_QueryInterface(This, riid, ppvObj);
3986 static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) {
3987 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
3989 TRACE("(%p/%p)->()\n", This, iface);
3991 return Filtergraph_AddRef(This);
3994 static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) {
3995 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
3997 TRACE("(%p/%p)->()\n", This, iface);
3999 return Filtergraph_Release(This);
4002 /*** IDispatch methods ***/
4003 static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface,
4004 UINT*pctinfo) {
4005 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4007 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
4009 return S_OK;
4012 static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface,
4013 UINT iTInfo,
4014 LCID lcid,
4015 ITypeInfo**ppTInfo) {
4016 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4018 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
4020 return S_OK;
4023 static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface,
4024 REFIID riid,
4025 LPOLESTR*rgszNames,
4026 UINT cNames,
4027 LCID lcid,
4028 DISPID*rgDispId) {
4029 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4031 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
4033 return S_OK;
4036 static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface,
4037 DISPID dispIdMember,
4038 REFIID riid,
4039 LCID lcid,
4040 WORD wFlags,
4041 DISPPARAMS*pDispParams,
4042 VARIANT*pVarResult,
4043 EXCEPINFO*pExepInfo,
4044 UINT*puArgErr) {
4045 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4047 TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
4049 return S_OK;
4052 /*** IMediaEvent methods ***/
4053 static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface,
4054 OAEVENT *hEvent) {
4055 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4057 TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
4059 *hEvent = (OAEVENT)This->evqueue.msg_event;
4061 return S_OK;
4064 static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface,
4065 long *lEventCode,
4066 LONG_PTR *lParam1,
4067 LONG_PTR *lParam2,
4068 long msTimeout) {
4069 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4070 Event evt;
4072 TRACE("(%p/%p)->(%p, %p, %p, %ld)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
4074 if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
4076 *lEventCode = evt.lEventCode;
4077 *lParam1 = evt.lParam1;
4078 *lParam2 = evt.lParam2;
4079 return S_OK;
4082 *lEventCode = 0;
4083 return E_ABORT;
4086 static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface,
4087 long msTimeout,
4088 long *pEvCode) {
4089 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4091 TRACE("(%p/%p)->(%ld, %p)\n", This, iface, msTimeout, pEvCode);
4093 if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
4095 *pEvCode = This->CompletionStatus;
4096 return S_OK;
4099 *pEvCode = 0;
4100 return E_ABORT;
4103 static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface,
4104 long lEvCode) {
4105 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4107 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4109 if (lEvCode == EC_COMPLETE)
4110 This->HandleEcComplete = FALSE;
4111 else if (lEvCode == EC_REPAINT)
4112 This->HandleEcRepaint = FALSE;
4113 else if (lEvCode == EC_CLOCK_CHANGED)
4114 This->HandleEcClockChanged = FALSE;
4115 else
4116 return S_FALSE;
4118 return S_OK;
4121 static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface,
4122 long lEvCode) {
4123 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4125 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4127 if (lEvCode == EC_COMPLETE)
4128 This->HandleEcComplete = TRUE;
4129 else if (lEvCode == EC_REPAINT)
4130 This->HandleEcRepaint = TRUE;
4131 else if (lEvCode == EC_CLOCK_CHANGED)
4132 This->HandleEcClockChanged = TRUE;
4133 else
4134 return S_FALSE;
4136 return S_OK;
4139 static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface,
4140 long lEvCode,
4141 LONG_PTR lParam1,
4142 LONG_PTR lParam2) {
4143 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4145 TRACE("(%p/%p)->(%ld, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
4147 return S_OK;
4150 /*** IMediaEventEx methods ***/
4151 static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface,
4152 OAHWND hwnd,
4153 long lMsg,
4154 LONG_PTR lInstanceData) {
4155 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4157 TRACE("(%p/%p)->(%08x, %ld, %08lx)\n", This, iface, (DWORD) hwnd, lMsg, lInstanceData);
4159 This->notif.hWnd = (HWND)hwnd;
4160 This->notif.msg = lMsg;
4161 This->notif.instance = (long) lInstanceData;
4163 return S_OK;
4166 static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface,
4167 long lNoNotifyFlags) {
4168 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4170 TRACE("(%p/%p)->(%ld)\n", This, iface, lNoNotifyFlags);
4172 if ((lNoNotifyFlags != 0) && (lNoNotifyFlags != 1))
4173 return E_INVALIDARG;
4175 This->notif.disabled = lNoNotifyFlags;
4177 return S_OK;
4180 static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface,
4181 long *lplNoNotifyFlags) {
4182 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4184 TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
4186 if (!lplNoNotifyFlags)
4187 return E_POINTER;
4189 *lplNoNotifyFlags = This->notif.disabled;
4191 return S_OK;
4195 static const IMediaEventExVtbl IMediaEventEx_VTable =
4197 MediaEvent_QueryInterface,
4198 MediaEvent_AddRef,
4199 MediaEvent_Release,
4200 MediaEvent_GetTypeInfoCount,
4201 MediaEvent_GetTypeInfo,
4202 MediaEvent_GetIDsOfNames,
4203 MediaEvent_Invoke,
4204 MediaEvent_GetEventHandle,
4205 MediaEvent_GetEvent,
4206 MediaEvent_WaitForCompletion,
4207 MediaEvent_CancelDefaultHandling,
4208 MediaEvent_RestoreDefaultHandling,
4209 MediaEvent_FreeEventParams,
4210 MediaEvent_SetNotifyWindow,
4211 MediaEvent_SetNotifyFlags,
4212 MediaEvent_GetNotifyFlags
4216 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
4218 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4220 return Filtergraph_QueryInterface(This, riid, ppv);
4223 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
4225 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4227 return Filtergraph_AddRef(This);
4230 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
4232 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4234 return Filtergraph_Release(This);
4237 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
4239 FIXME("(%p): stub\n", pClassID);
4241 return E_NOTIMPL;
4244 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
4246 FIXME("(): stub\n");
4248 return E_NOTIMPL;
4251 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
4253 FIXME("(): stub\n");
4255 return E_NOTIMPL;
4258 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
4260 FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart));
4262 return E_NOTIMPL;
4265 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
4267 FIXME("(%d, %p): stub\n", dwMsTimeout, pState);
4269 return E_NOTIMPL;
4272 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
4274 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4275 HRESULT hr = S_OK;
4276 int i;
4278 TRACE("(%p/%p)->(%p)\n", iface, This, pClock);
4280 EnterCriticalSection(&This->cs);
4282 for (i = 0;i < This->nFilters;i++)
4284 hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
4285 if (FAILED(hr))
4286 break;
4289 if (FAILED(hr))
4291 for(;i >= 0;i--)
4292 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
4294 else
4296 if (This->refClock)
4297 IReferenceClock_Release(This->refClock);
4298 This->refClock = pClock;
4299 if (This->refClock)
4300 IReferenceClock_AddRef(This->refClock);
4302 if (This->HandleEcClockChanged)
4304 IMediaEventSink *pEventSink;
4305 HRESULT eshr;
4307 eshr = IMediaFilter_QueryInterface(iface, &IID_IMediaEventSink, (LPVOID)&pEventSink);
4308 if (SUCCEEDED(eshr))
4310 IMediaEventSink_Notify(pEventSink, EC_CLOCK_CHANGED, 0, 0);
4311 IMediaEventSink_Release(pEventSink);
4316 LeaveCriticalSection(&This->cs);
4318 return hr;
4321 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
4323 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4325 TRACE("(%p/%p)->(%p)\n", iface, This, ppClock);
4327 if (!ppClock)
4328 return E_POINTER;
4330 EnterCriticalSection(&This->cs);
4332 *ppClock = This->refClock;
4333 if (*ppClock)
4334 IReferenceClock_AddRef(*ppClock);
4336 LeaveCriticalSection(&This->cs);
4338 return S_OK;
4341 static const IMediaFilterVtbl IMediaFilter_VTable =
4343 MediaFilter_QueryInterface,
4344 MediaFilter_AddRef,
4345 MediaFilter_Release,
4346 MediaFilter_GetClassID,
4347 MediaFilter_Stop,
4348 MediaFilter_Pause,
4349 MediaFilter_Run,
4350 MediaFilter_GetState,
4351 MediaFilter_SetSyncSource,
4352 MediaFilter_GetSyncSource
4355 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
4357 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4359 return Filtergraph_QueryInterface(This, riid, ppv);
4362 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
4364 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4366 return Filtergraph_AddRef(This);
4369 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
4371 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4373 return Filtergraph_Release(This);
4376 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
4378 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4379 Event evt;
4381 TRACE("(%p/%p)->(%ld, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
4383 /* We need thread safety here, let's use the events queue's one */
4384 EnterCriticalSection(&This->evqueue.msg_crst);
4386 if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
4388 TRACE("Process EC_COMPLETE notification\n");
4389 if (++This->EcCompleteCount == This->nRenderers)
4391 evt.lEventCode = EC_COMPLETE;
4392 evt.lParam1 = S_OK;
4393 evt.lParam2 = 0;
4394 TRACE("Send EC_COMPLETE to app\n");
4395 EventsQueue_PutEvent(&This->evqueue, &evt);
4396 if (!This->notif.disabled && This->notif.hWnd)
4398 TRACE("Send Window message\n");
4399 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4401 This->CompletionStatus = EC_COMPLETE;
4402 SetEvent(This->hEventCompletion);
4405 else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
4407 /* FIXME: Not handled yet */
4409 else
4411 evt.lEventCode = EventCode;
4412 evt.lParam1 = EventParam1;
4413 evt.lParam2 = EventParam2;
4414 EventsQueue_PutEvent(&This->evqueue, &evt);
4415 if (!This->notif.disabled && This->notif.hWnd)
4416 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4419 LeaveCriticalSection(&This->evqueue.msg_crst);
4420 return S_OK;
4423 static const IMediaEventSinkVtbl IMediaEventSink_VTable =
4425 MediaEventSink_QueryInterface,
4426 MediaEventSink_AddRef,
4427 MediaEventSink_Release,
4428 MediaEventSink_Notify
4431 static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv)
4433 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4435 return Filtergraph_QueryInterface(This, riid, ppv);
4438 static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface)
4440 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4442 return Filtergraph_AddRef(This);
4445 static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface)
4447 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4449 return Filtergraph_Release(This);
4452 static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface,
4453 IPin* pOutputPin,
4454 IPin* pInputPin,
4455 const AM_MEDIA_TYPE* pmtFirstConnection,
4456 IBaseFilter* pUsingFilter,
4457 HANDLE hAbortEvent,
4458 DWORD dwFlags)
4460 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4462 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags);
4464 return E_NOTIMPL;
4467 static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface,
4468 IGraphConfigCallback* pCallback,
4469 PVOID pvContext,
4470 DWORD dwFlags,
4471 HANDLE hAbortEvent)
4473 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4475 FIXME("(%p)->(%p, %p, %x, %p): stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent);
4477 return E_NOTIMPL;
4480 static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface,
4481 IBaseFilter* pFilter)
4483 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4485 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4487 return E_NOTIMPL;
4490 static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface,
4491 IEnumFilters** pEnum)
4493 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4495 FIXME("(%p)->(%p): stub!\n", This, pEnum);
4497 return E_NOTIMPL;
4500 static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface,
4501 IBaseFilter* pFilter)
4503 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4505 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4507 return E_NOTIMPL;
4510 static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface,
4511 REFERENCE_TIME* prtStart)
4513 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4515 FIXME("(%p)->(%p): stub!\n", This, prtStart);
4517 return E_NOTIMPL;
4520 static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface,
4521 IPin* pOutputPin,
4522 IPinConnection* pConnection,
4523 HANDLE hEventAbort)
4525 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4527 FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort);
4529 return E_NOTIMPL;
4532 static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface,
4533 IBaseFilter* pFilter,
4534 DWORD dwFlags)
4536 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4538 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4540 return E_NOTIMPL;
4543 static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface,
4544 IBaseFilter* pFilter,
4545 DWORD* dwFlags)
4547 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4549 FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags);
4551 return E_NOTIMPL;
4554 static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface,
4555 IBaseFilter* pFilter,
4556 DWORD dwFlags)
4558 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4560 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4562 return E_NOTIMPL;
4565 static const IGraphConfigVtbl IGraphConfig_VTable =
4567 GraphConfig_QueryInterface,
4568 GraphConfig_AddRef,
4569 GraphConfig_Release,
4570 GraphConfig_Reconnect,
4571 GraphConfig_Reconfigure,
4572 GraphConfig_AddFilterToCache,
4573 GraphConfig_EnumCacheFilter,
4574 GraphConfig_RemoveFilterFromCache,
4575 GraphConfig_GetStartTime,
4576 GraphConfig_PushThroughData,
4577 GraphConfig_SetFilterFlags,
4578 GraphConfig_GetFilterFlags,
4579 GraphConfig_RemoveFilterEx
4582 /* This is the only function that actually creates a FilterGraph class... */
4583 HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
4585 IFilterGraphImpl *fimpl;
4586 HRESULT hr;
4588 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
4590 if( pUnkOuter )
4591 return CLASS_E_NOAGGREGATION;
4593 fimpl = CoTaskMemAlloc(sizeof(*fimpl));
4594 fimpl->IGraphBuilder_vtbl = &IGraphBuilder_VTable;
4595 fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
4596 fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
4597 fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
4598 fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
4599 fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
4600 fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
4601 fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
4602 fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
4603 fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable;
4604 fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable;
4605 fimpl->ref = 1;
4606 fimpl->ppFiltersInGraph = NULL;
4607 fimpl->pFilterNames = NULL;
4608 fimpl->nFilters = 0;
4609 fimpl->filterCapacity = 0;
4610 fimpl->nameIndex = 1;
4611 fimpl->refClock = NULL;
4612 fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
4613 fimpl->HandleEcComplete = TRUE;
4614 fimpl->HandleEcRepaint = TRUE;
4615 fimpl->HandleEcClockChanged = TRUE;
4616 fimpl->notif.hWnd = 0;
4617 fimpl->notif.disabled = FALSE;
4618 fimpl->nRenderers = 0;
4619 fimpl->EcCompleteCount = 0;
4620 fimpl->state = State_Stopped;
4621 EventsQueue_Init(&fimpl->evqueue);
4622 InitializeCriticalSection(&fimpl->cs);
4623 fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
4624 fimpl->nItfCacheEntries = 0;
4626 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
4627 if (FAILED(hr)) {
4628 ERR("Unable to create filter mapper (%x)\n", hr);
4629 return hr;
4632 *ppObj = fimpl;
4633 return S_OK;
4636 HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj)
4638 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
4639 return FilterGraph_create(pUnkOuter, ppObj);