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
33 #include "wine/debug.h"
34 #include "quartz_private.h"
40 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
46 HWND hWnd; /* Target window */
47 long msg; /* User window message */
48 long instance; /* User data */
49 int disabled; /* Disabled messages posting */
53 long lEventCode; /* Event code */
54 LONG_PTR lParam1; /* Param1 */
55 LONG_PTR lParam2; /* Param2 */
58 /* messages ring implementation for queuing events (taken from winmm) */
59 #define EVENTS_RING_BUFFER_INCREMENT 64
65 CRITICAL_SECTION msg_crst;
66 HANDLE msg_event; /* Signaled for no empty queue */
69 static int EventsQueue_Init(EventsQueue* omr)
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");
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);
92 static int EventsQueue_PutEvent(EventsQueue* omr, const 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
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);
121 static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut)
123 if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0)
126 EnterCriticalSection(&omr->msg_crst);
128 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
130 LeaveCriticalSection(&omr->msg_crst);
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);
145 #define MAX_ITF_CACHE_ENTRIES 3
146 typedef struct _ITF_CACHE_ENTRY {
152 typedef struct _IFilterGraphImpl {
153 const IFilterGraph2Vtbl *IFilterGraph2_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 const IUnknownVtbl * IInner_vtbl;
165 /* IAMGraphStreams */
172 /* IRegisterServiceProvider */
173 /* IResourceMananger */
174 /* IServiceProvider */
175 /* IVideoFrameStep */
178 IFilterMapper2 * pFilterMapper2;
179 IBaseFilter ** ppFiltersInGraph;
180 LPWSTR * pFilterNames;
184 IReferenceClock *refClock;
186 HANDLE hEventCompletion;
187 int CompletionStatus;
191 int HandleEcComplete;
193 int HandleEcClockChanged;
196 ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
197 int nItfCacheEntries;
198 IUnknown * pUnkOuter;
206 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
207 REFIID riid, LPVOID * ppv);
208 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This);
209 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This);
211 static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface,
214 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
215 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
217 if (This->bAggregatable)
218 This->bUnkOuterValid = TRUE;
220 if (IsEqualGUID(&IID_IUnknown, riid)) {
221 *ppvObj = &(This->IInner_vtbl);
222 TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
223 } else if (IsEqualGUID(&IID_IFilterGraph, riid) ||
224 IsEqualGUID(&IID_IFilterGraph2, riid) ||
225 IsEqualGUID(&IID_IGraphBuilder, riid)) {
226 *ppvObj = &(This->IFilterGraph2_vtbl);
227 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj);
228 } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
229 *ppvObj = &(This->IMediaControl_vtbl);
230 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj);
231 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
232 *ppvObj = &(This->IMediaSeeking_vtbl);
233 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
234 } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
235 *ppvObj = &(This->IBasicAudio_vtbl);
236 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj);
237 } else if (IsEqualGUID(&IID_IBasicVideo, riid)) {
238 *ppvObj = &(This->IBasicVideo_vtbl);
239 TRACE(" returning IBasicVideo interface (%p)\n", *ppvObj);
240 } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
241 *ppvObj = &(This->IVideoWindow_vtbl);
242 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj);
243 } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
244 IsEqualGUID(&IID_IMediaEventEx, riid)) {
245 *ppvObj = &(This->IMediaEventEx_vtbl);
246 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
247 } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
248 IsEqualGUID(&IID_IPersist, riid)) {
249 *ppvObj = &(This->IMediaFilter_vtbl);
250 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj);
251 } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
252 *ppvObj = &(This->IMediaEventSink_vtbl);
253 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj);
254 } else if (IsEqualGUID(&IID_IGraphConfig, riid)) {
255 *ppvObj = &(This->IGraphConfig_vtbl);
256 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj);
257 } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
258 *ppvObj = &(This->IMediaPosition_vtbl);
259 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj);
262 FIXME("unknown interface %s\n", debugstr_guid(riid));
263 return E_NOINTERFACE;
266 IUnknown_AddRef((IUnknown *)(*ppvObj));
270 static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) {
271 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
272 ULONG ref = InterlockedIncrement(&This->ref);
274 TRACE("(%p)->(): new ref = %d\n", This, ref);
279 static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) {
280 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
281 ULONG ref = InterlockedDecrement(&This->ref);
283 TRACE("(%p)->(): new ref = %d\n", This, ref);
288 IMediaControl_Stop((IMediaControl*)&(This->IMediaControl_vtbl));
290 IReferenceClock_Release(This->refClock);
292 while (This->nFilters)
293 IFilterGraph2_RemoveFilter((IFilterGraph2*)This, This->ppFiltersInGraph[0]);
295 for (i = 0; i < This->nItfCacheEntries; i++)
297 if (This->ItfCacheEntries[i].iface)
298 IUnknown_Release(This->ItfCacheEntries[i].iface);
300 IFilterMapper2_Release(This->pFilterMapper2);
301 CloseHandle(This->hEventCompletion);
302 EventsQueue_Destroy(&This->evqueue);
303 This->cs.DebugInfo->Spare[0] = 0;
304 DeleteCriticalSection(&This->cs);
305 CoTaskMemFree(This->ppFiltersInGraph);
306 CoTaskMemFree(This->pFilterNames);
313 /*** IUnknown methods ***/
314 static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface,
317 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
319 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
320 return Filtergraph_QueryInterface(This, riid, ppvObj);
323 static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) {
324 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
326 TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
328 return Filtergraph_AddRef(This);
331 static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) {
332 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
334 TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
336 return Filtergraph_Release(This);
339 /*** IFilterGraph methods ***/
340 static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
341 IBaseFilter *pFilter,
343 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
346 WCHAR* wszFilterName = NULL;
347 int duplicate_name = FALSE;
349 TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
354 wszFilterName = CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
358 /* Check if name already exists */
359 for(i = 0; i < This->nFilters; i++)
360 if (!strcmpW(This->pFilterNames[i], pName))
362 duplicate_name = TRUE;
367 /* If no name given or name already existing, generate one */
368 if (!pName || duplicate_name)
370 static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
371 static const WCHAR wszFmt2[] = {'%','0','4','d',0};
373 for (j = 0; j < 10000 ; j++)
377 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
379 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
380 TRACE("Generated name %s\n", debugstr_w(wszFilterName));
382 /* Check if the generated name already exists */
383 for(i = 0; i < This->nFilters; i++)
384 if (!strcmpW(This->pFilterNames[i], wszFilterName))
387 /* Compute next index and exit if generated name is suitable */
388 if (This->nameIndex++ == 10000)
390 if (i == This->nFilters)
393 /* Unable to find a suitable name */
396 CoTaskMemFree(wszFilterName);
397 return VFW_E_DUPLICATE_NAME;
401 memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
403 if (This->nFilters + 1 > This->filterCapacity)
405 int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
406 IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
407 LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
408 memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
409 memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
410 if (This->filterCapacity)
412 CoTaskMemFree(This->ppFiltersInGraph);
413 CoTaskMemFree(This->pFilterNames);
415 This->ppFiltersInGraph = ppNewFilters;
416 This->pFilterNames = pNewNames;
417 This->filterCapacity = newCapacity;
420 hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
424 IBaseFilter_AddRef(pFilter);
425 This->ppFiltersInGraph[This->nFilters] = pFilter;
426 This->pFilterNames[This->nFilters] = wszFilterName;
428 IBaseFilter_SetSyncSource(pFilter, This->refClock);
431 CoTaskMemFree(wszFilterName);
433 if (SUCCEEDED(hr) && duplicate_name)
434 return VFW_S_DUPLICATE_NAME;
439 static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface,
440 IBaseFilter *pFilter) {
441 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
445 TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
447 /* FIXME: check graph is stopped */
449 for (i = 0; i < This->nFilters; i++)
451 if (This->ppFiltersInGraph[i] == pFilter)
453 IEnumPins *penumpins;
454 IBaseFilter_Stop(pFilter);
455 hr = IBaseFilter_EnumPins(pFilter, &penumpins);
458 while(IEnumPins_Next(penumpins, 1, &ppin, NULL) == S_OK) {
461 IPin_ConnectedTo(ppin, &victim);
464 h = IPin_Disconnect(victim);
465 TRACE("Disconnect other side: %08x\n", h);
466 if (h == VFW_E_NOT_STOPPED)
469 IPin_QueryPinInfo(victim, &pinfo);
470 IBaseFilter_Stop(pinfo.pFilter);
471 IBaseFilter_Release(pinfo.pFilter);
472 h = IPin_Disconnect(victim);
473 TRACE("Disconnect retry: %08x\n", h);
475 IPin_Release(victim);
477 h = IPin_Disconnect(ppin);
478 TRACE("Disconnect 2: %08x\n", h);
480 IEnumPins_Release(penumpins);
483 hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
486 IBaseFilter_SetSyncSource(pFilter, NULL);
487 IBaseFilter_Release(pFilter);
488 CoTaskMemFree(This->pFilterNames[i]);
489 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
490 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
492 /* Invalidate interfaces in the cache */
493 for (i = 0; i < This->nItfCacheEntries; i++)
494 if (pFilter == This->ItfCacheEntries[i].filter)
496 IUnknown_Release(This->ItfCacheEntries[i].iface);
497 This->ItfCacheEntries[i].iface = NULL;
498 This->ItfCacheEntries[i].filter = NULL;
506 return hr; /* FIXME: check this error code */
509 static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface,
510 IEnumFilters **ppEnum) {
511 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
513 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
515 return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
518 static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface,
520 IBaseFilter **ppFilter) {
521 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
524 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
529 for (i = 0; i < This->nFilters; i++)
531 if (!strcmpW(pName, This->pFilterNames[i]))
533 *ppFilter = This->ppFiltersInGraph[i];
534 IBaseFilter_AddRef(*ppFilter);
540 return VFW_E_NOT_FOUND;
543 /* NOTE: despite the implication, it doesn't matter which
544 * way round you put in the input and output pins */
545 static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface,
548 const AM_MEDIA_TYPE *pmt) {
552 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
554 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
556 /* FIXME: check pins are in graph */
558 if (TRACE_ON(quartz))
562 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
566 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
567 IBaseFilter_Release(PinInfo.pFilter);
569 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
573 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
574 IBaseFilter_Release(PinInfo.pFilter);
577 hr = IPin_QueryDirection(ppinIn, &dir);
580 if (dir == PINDIR_INPUT)
581 hr = IPin_Connect(ppinOut, ppinIn, pmt);
583 hr = IPin_Connect(ppinIn, ppinOut, pmt);
589 static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface,
591 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
592 IPin *pConnectedTo = NULL;
594 PIN_DIRECTION pindir;
596 IPin_QueryDirection(ppin, &pindir);
597 hr = IPin_ConnectedTo(ppin, &pConnectedTo);
599 TRACE("Querying connected to failed: %x\n", hr);
602 IPin_Disconnect(ppin);
603 IPin_Disconnect(pConnectedTo);
604 if (pindir == PINDIR_INPUT)
605 hr = IPin_Connect(pConnectedTo, ppin, NULL);
607 hr = IPin_Connect(ppin, pConnectedTo, NULL);
608 IPin_Release(pConnectedTo);
610 ERR("Reconnecting pins failed, pins are not connected now..\n");
611 TRACE("(%p->%p) -- %p %p -> %x\n", iface, This, ppin, pConnectedTo, hr);
615 static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface,
617 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
619 TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
621 return IPin_Disconnect(ppin);
624 static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) {
625 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
626 IReferenceClock *pClock = NULL;
629 TRACE("(%p/%p)->() semi-stub\n", iface, This);
631 hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&pClock);
635 hr = IMediaFilter_SetSyncSource((IMediaFilter*)&(This->IMediaFilter_vtbl), pClock);
636 IReferenceClock_Release(pClock);
642 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
644 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
645 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
646 IPropertyBag * pPropBagCat = NULL;
650 V_VT(pvar) = VT_BSTR;
652 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
655 hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
658 hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
661 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
664 TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
667 IPropertyBag_Release(pPropBagCat);
672 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPin*** pppins, ULONG* pnb)
677 TRACE("(%p, %p, %p, %p)\n", pfilter, pinputpin, pppins, pnb);
678 hr = IPin_QueryInternalConnections(pinputpin, NULL, &nb);
681 } else if (hr == S_FALSE) {
682 *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
683 hr = IPin_QueryInternalConnections(pinputpin, *pppins, &nb);
685 ERR("Error (%x)\n", hr);
687 } else if (hr == E_NOTIMPL) {
688 /* Input connected to all outputs */
689 IEnumPins* penumpins;
692 TRACE("E_NOTIMPL\n");
693 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
695 ERR("filter Enumpins failed (%x)\n", hr);
699 /* Count output pins */
700 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
701 PIN_DIRECTION pindir;
702 IPin_QueryDirection(ppin, &pindir);
703 if (pindir == PINDIR_OUTPUT)
707 *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
708 /* Retrieve output pins */
709 IEnumPins_Reset(penumpins);
711 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
712 PIN_DIRECTION pindir;
713 IPin_QueryDirection(ppin, &pindir);
714 if (pindir == PINDIR_OUTPUT)
715 (*pppins)[i++] = ppin;
719 IEnumPins_Release(penumpins);
722 ERR("Next failed (%x)\n", hr);
725 } else if (FAILED(hr)) {
726 ERR("Cannot get internal connection (%x)\n", hr);
734 /*** IGraphBuilder methods ***/
735 static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface,
738 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
741 IEnumMediaTypes* penummt;
743 IEnumPins* penumpins;
744 IEnumMoniker* pEnumMoniker;
752 TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
754 if (TRACE_ON(quartz))
756 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
760 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
761 IBaseFilter_Release(PinInfo.pFilter);
763 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
767 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
768 IBaseFilter_Release(PinInfo.pFilter);
771 /* Try direct connection first */
772 hr = IPin_Connect(ppinOut, ppinIn, NULL);
776 TRACE("Direct connection failed, trying to insert other filters\n");
778 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
782 hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
783 IBaseFilter_Release(PinInfo.pFilter);
787 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
788 * filter to the minor mediatype of input pin of the renderer */
789 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
791 ERR("EnumMediaTypes (%x)\n", hr);
795 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
797 ERR("IEnumMediaTypes_Next (%x)\n", hr);
802 ERR("No media type found!\n");
805 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
806 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
808 /* Try to find a suitable filter that can connect to the pin to render */
809 tab[0] = mt->majortype;
810 tab[1] = mt->subtype;
811 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
813 ERR("Unable to enum filters (%x)\n", hr);
817 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
822 IPin* ppinfilter = NULL;
823 IBaseFilter* pfilter = NULL;
825 hr = GetFilterInfo(pMoniker, &clsid, &var);
826 IMoniker_Release(pMoniker);
828 ERR("Unable to retrieve filter info (%x)\n", hr);
832 if (IsEqualGUID(&clsid, &FilterCLSID)) {
833 /* Skip filter (same as the one the output pin belongs to) */
837 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
839 ERR("Unable to create filter (%x), trying next one\n", hr);
843 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
845 ERR("Unable to add filter (%x)\n", hr);
846 IBaseFilter_Release(pfilter);
851 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
853 ERR("Enumpins (%x)\n", hr);
857 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
858 IEnumPins_Release(penumpins);
861 ERR("Next (%x)\n", hr);
869 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
871 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
874 TRACE("Successfully connected to filter, follow chain...\n");
876 /* Render all output pins of the filter by calling IFilterGraph2_Render on each of them */
877 hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
882 IPin_Disconnect(ppinOut);
885 TRACE("pins to consider: %d\n", nb);
886 for(i = 0; i < nb; i++) {
887 TRACE("Processing pin %d\n", i);
888 hr = IFilterGraph2_Connect(iface, ppins[i], ppinIn);
890 TRACE("Cannot render pin %p (%x)\n", ppinfilter, hr);
892 IPin_Release(ppins[i]);
893 if (SUCCEEDED(hr)) break;
895 while (++i < nb) IPin_Release(ppins[i]);
896 CoTaskMemFree(ppins);
897 IPin_Release(ppinfilter);
898 IBaseFilter_Release(pfilter);
903 if (ppinfilter) IPin_Release(ppinfilter);
905 IFilterGraph2_RemoveFilter(iface, pfilter);
906 IBaseFilter_Release(pfilter);
910 IEnumMediaTypes_Release(penummt);
916 static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface,
918 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
919 IEnumMediaTypes* penummt;
924 IEnumMoniker* pEnumMoniker;
929 TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
931 if (TRACE_ON(quartz))
935 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
939 TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
940 IBaseFilter_Release(PinInfo.pFilter);
943 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
945 ERR("EnumMediaTypes (%x)\n", hr);
951 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
953 ERR("IEnumMediaTypes_Next (%x)\n", hr);
958 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
959 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
961 /* Try to find a suitable renderer with the same media type */
962 tab[0] = mt->majortype;
964 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL);
966 ERR("Unable to enum filters (%x)\n", hr);
970 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
975 IBaseFilter* pfilter = NULL;
976 IEnumPins* penumpins;
979 hr = GetFilterInfo(pMoniker, &clsid, &var);
980 IMoniker_Release(pMoniker);
982 ERR("Unable to retrieve filter info (%x)\n", hr);
986 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
988 ERR("Unable to create filter (%x), trying next one\n", hr);
992 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
994 ERR("Unable to add filter (%x)\n", hr);
995 IBaseFilter_Release(pfilter);
1000 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
1002 ERR("Splitter Enumpins (%x)\n", hr);
1005 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
1006 IEnumPins_Release(penumpins);
1008 ERR("Next (%x)\n", hr);
1016 /* Connect the pin to render to the renderer */
1017 hr = IFilterGraph2_Connect(iface, ppinOut, ppinfilter);
1019 TRACE("Unable to connect to renderer (%x)\n", hr);
1020 IPin_Release(ppinfilter);
1023 IPin_Release(ppinfilter);
1024 IBaseFilter_Release(pfilter);
1030 IFilterGraph2_RemoveFilter(iface, pfilter);
1031 IBaseFilter_Release(pfilter);
1035 DeleteMediaType(mt);
1039 IEnumMediaTypes_Release(penummt);
1044 static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface,
1045 LPCWSTR lpcwstrFile,
1046 LPCWSTR lpcwstrPlayList) {
1047 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1048 static const WCHAR string[] = {'R','e','a','d','e','r',0};
1049 IBaseFilter* preader = NULL;
1050 IBaseFilter* psplitter = NULL;
1051 IPin* ppinreader = NULL;
1052 IPin* ppinsplitter = NULL;
1053 IEnumPins* penumpins;
1056 IEnumMoniker* pEnumMoniker = NULL;
1058 IPin** ppins = NULL;
1061 IFileSourceFilter* pfile = NULL;
1065 TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
1067 if (lpcwstrPlayList != NULL)
1068 return E_INVALIDARG;
1070 hr = IFilterGraph2_AddSourceFilter(iface, lpcwstrFile, string, &preader);
1072 /* Retrieve file media type */
1074 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1075 if (SUCCEEDED(hr)) {
1076 hr = IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1077 IFileSourceFilter_Release(pfile);
1081 hr = IBaseFilter_EnumPins(preader, &penumpins);
1082 if (SUCCEEDED(hr)) {
1083 hr = IEnumPins_Next(penumpins, 1, &ppinreader, &pin);
1084 IEnumPins_Release(penumpins);
1087 if (SUCCEEDED(hr)) {
1088 tab[0] = mt.majortype;
1089 tab[1] = mt.subtype;
1090 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
1096 IPin_Release(ppinreader);
1098 IEnumMoniker_Release(pEnumMoniker);
1100 IFilterGraph2_RemoveFilter(iface, preader);
1101 IBaseFilter_Release(preader);
1106 hr = VFW_E_CANNOT_RENDER;
1107 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1112 hr = GetFilterInfo(pMoniker, &clsid, &var);
1113 IMoniker_Release(pMoniker);
1115 ERR("Unable to retrieve filter info (%x)\n", hr);
1119 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&psplitter);
1121 ERR("Unable to create filter (%x), trying next one\n", hr);
1125 hr = IFilterGraph2_AddFilter(iface, psplitter, V_UNION(&var, bstrVal));
1127 ERR("Unable add filter (%x)\n", hr);
1128 IBaseFilter_Release(psplitter);
1132 /* Connect file source and splitter filters together */
1133 /* Make the splitter analyze incoming data */
1135 hr = IBaseFilter_EnumPins(psplitter, &penumpins);
1136 if (SUCCEEDED(hr)) {
1137 hr = IEnumPins_Next(penumpins, 1, &ppinsplitter, &pin);
1138 IEnumPins_Release(penumpins);
1142 hr = IPin_Connect(ppinreader, ppinsplitter, NULL);
1144 /* Make sure there's some output pins in the filter */
1146 hr = GetInternalConnections(psplitter, ppinsplitter, &ppins, &nb);
1147 if (SUCCEEDED(hr)) {
1149 IPin_Disconnect(ppinreader);
1150 TRACE("No output pins found in filter\n");
1151 hr = VFW_E_CANNOT_RENDER;
1156 IPin_Release(ppinsplitter);
1157 ppinsplitter = NULL;
1159 if (SUCCEEDED(hr)) {
1160 TRACE("Successfully connected to filter\n");
1164 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
1167 CoTaskMemFree(ppins);
1170 IFilterGraph2_RemoveFilter(iface, psplitter);
1171 IBaseFilter_Release(psplitter);
1175 /* Render all output pin of the splitter by calling IFilterGraph2_Render on each of them */
1176 if (SUCCEEDED(hr)) {
1179 TRACE("pins to consider: %d\n", nb);
1180 for(i = 0; i < nb; i++) {
1181 TRACE("Processing pin %d\n", i);
1182 hr = IFilterGraph2_Render(iface, ppins[i]);
1184 ERR("Cannot render pin %p (%x)\n", ppins[i], hr);
1187 IPin_Release(ppins[i]);
1189 CoTaskMemFree(ppins);
1191 hr = (partial ? VFW_S_PARTIAL_RENDER : S_OK);
1194 IPin_Release(ppinreader);
1195 IBaseFilter_Release(preader);
1197 IBaseFilter_Release(psplitter);
1202 static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface,
1203 LPCWSTR lpcwstrFileName,
1204 LPCWSTR lpcwstrFilterName,
1205 IBaseFilter **ppFilter) {
1206 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1208 IBaseFilter* preader;
1209 IFileSourceFilter* pfile = NULL;
1213 TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
1215 /* Instantiate a file source filter */
1216 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
1218 ERR("Unable to create file source filter (%x)\n", hr);
1222 hr = IFilterGraph2_AddFilter(iface, preader, lpcwstrFilterName);
1224 ERR("Unable add filter (%x)\n", hr);
1225 IBaseFilter_Release(preader);
1229 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1231 ERR("Unable to get IFileSourceInterface (%x)\n", hr);
1235 /* Load the file in the file source filter */
1236 hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1238 ERR("Load (%x)\n", hr);
1242 IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1244 ERR("GetCurFile (%x)\n", hr);
1247 TRACE("File %s\n", debugstr_w(filename));
1248 TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1249 TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1252 *ppFilter = preader;
1253 IFileSourceFilter_Release(pfile);
1259 IFileSourceFilter_Release(pfile);
1260 IFilterGraph2_RemoveFilter(iface, preader);
1261 IBaseFilter_Release(preader);
1266 static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface,
1268 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1270 TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile);
1275 static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) {
1276 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1278 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1283 static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) {
1284 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1286 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1291 /*** IFilterGraph2 methods ***/
1292 static HRESULT WINAPI FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2 *iface,
1295 LPCWSTR lpcwstrFilterName,
1296 IBaseFilter **ppFilter) {
1297 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1299 TRACE("(%p/%p)->(%p %p %s %p): stub !!!\n", This, iface, pMoniker, pCtx, debugstr_w(lpcwstrFilterName), ppFilter);
1304 static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface,
1306 const AM_MEDIA_TYPE *pmt) {
1307 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1309 TRACE("(%p/%p)->(%p %p): stub !!!\n", This, iface, ppin, pmt);
1314 static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface,
1318 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1320 TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This, iface, pPinOut, dwFlags, pvContext);
1326 static const IFilterGraph2Vtbl IFilterGraph2_VTable =
1328 FilterGraph2_QueryInterface,
1329 FilterGraph2_AddRef,
1330 FilterGraph2_Release,
1331 FilterGraph2_AddFilter,
1332 FilterGraph2_RemoveFilter,
1333 FilterGraph2_EnumFilters,
1334 FilterGraph2_FindFilterByName,
1335 FilterGraph2_ConnectDirect,
1336 FilterGraph2_Reconnect,
1337 FilterGraph2_Disconnect,
1338 FilterGraph2_SetDefaultSyncSource,
1339 FilterGraph2_Connect,
1340 FilterGraph2_Render,
1341 FilterGraph2_RenderFile,
1342 FilterGraph2_AddSourceFilter,
1343 FilterGraph2_SetLogFile,
1345 FilterGraph2_ShouldOperationContinue,
1346 FilterGraph2_AddSourceFilterForMoniker,
1347 FilterGraph2_ReconnectEx,
1348 FilterGraph2_RenderEx
1351 /*** IUnknown methods ***/
1352 static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface,
1355 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1357 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1359 return Filtergraph_QueryInterface(This, riid, ppvObj);
1362 static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) {
1363 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1365 TRACE("(%p/%p)->()\n", This, iface);
1367 return Filtergraph_AddRef(This);
1370 static ULONG WINAPI MediaControl_Release(IMediaControl *iface) {
1371 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1373 TRACE("(%p/%p)->()\n", This, iface);
1375 return Filtergraph_Release(This);
1379 /*** IDispatch methods ***/
1380 static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface,
1382 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1384 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1389 static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface,
1392 ITypeInfo**ppTInfo) {
1393 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1395 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1400 static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface,
1406 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1408 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1413 static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
1414 DISPID dispIdMember,
1418 DISPPARAMS*pDispParams,
1420 EXCEPINFO*pExepInfo,
1422 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1424 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);
1429 typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
1431 static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
1440 TRACE("%p %p\n", pGraph, pOutputPin);
1441 PinInfo.pFilter = NULL;
1443 hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
1447 hr = IPin_QueryPinInfo(pInputPin, &PinInfo);
1449 hr = GetInternalConnections(PinInfo.pFilter, pInputPin, &ppPins, &nb);
1450 IPin_Release(pInputPin);
1457 TRACE("Reached a renderer\n");
1458 /* Count renderers for end of stream notification */
1459 pGraph->nRenderers++;
1463 for(i = 0; i < nb; i++)
1465 /* Explore the graph downstream from this pin
1466 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1467 * several input pins are connected to the same output (a MUX for instance). */
1468 ExploreGraph(pGraph, ppPins[i], FoundFilter);
1469 IPin_Release(ppPins[i]);
1472 CoTaskMemFree(ppPins);
1474 TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
1475 LeaveCriticalSection(&pGraph->cs);
1476 FoundFilter(PinInfo.pFilter);
1477 EnterCriticalSection(&pGraph->cs);
1480 if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
1484 static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
1486 IReferenceClock *clock = NULL;
1488 IBaseFilter_GetSyncSource(pFilter, &clock);
1491 IReferenceClock_GetTime(clock, &time);
1497 IReferenceClock_Release(clock);
1500 return IBaseFilter_Run(pFilter, time);
1503 static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
1504 return IBaseFilter_Pause(pFilter);
1507 static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
1508 return IBaseFilter_Stop(pFilter);
1511 static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
1512 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1514 IBaseFilter* pfilter;
1520 TRACE("(%p/%p)->()\n", This, iface);
1522 /* Explorer the graph from source filters to renderers, determine renderers
1523 * number and run filters from renderers to source filters */
1524 This->nRenderers = 0;
1525 ResetEvent(This->hEventCompletion);
1527 for(i = 0; i < This->nFilters; i++)
1530 pfilter = This->ppFiltersInGraph[i];
1531 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1534 ERR("Enum pins failed %x\n", hr);
1537 /* Check if it is a source filter */
1538 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1540 IPin_QueryDirection(pPin, &dir);
1542 if (dir == PINDIR_INPUT)
1550 TRACE("Found a source filter %p\n", pfilter);
1551 IEnumPins_Reset(pEnum);
1552 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1554 /* Explore the graph downstream from this pin */
1555 ExploreGraph(This, pPin, FoundFilter);
1558 FoundFilter(pfilter);
1560 IEnumPins_Release(pEnum);
1566 /*** IMediaControl methods ***/
1567 static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
1568 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1569 TRACE("(%p/%p)->()\n", This, iface);
1571 if (This->state == State_Running) return S_OK;
1573 EnterCriticalSection(&This->cs);
1576 IReferenceClock_GetTime(This->refClock, &This->start_time);
1577 This->start_time += 500000;
1579 else This->position = This->start_time = 0;
1581 SendFilterMessage(iface, SendRun);
1582 This->state = State_Running;
1583 LeaveCriticalSection(&This->cs);
1587 static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
1588 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1589 TRACE("(%p/%p)->()\n", This, iface);
1591 if (This->state == State_Paused) return S_OK;
1593 EnterCriticalSection(&This->cs);
1594 if (This->state == State_Running && This->refClock)
1596 LONGLONG time = This->start_time;
1597 IReferenceClock_GetTime(This->refClock, &time);
1598 This->position += time - This->start_time;
1601 SendFilterMessage(iface, SendPause);
1602 This->state = State_Paused;
1603 LeaveCriticalSection(&This->cs);
1607 static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
1608 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1609 TRACE("(%p/%p)->()\n", This, iface);
1611 if (This->state == State_Stopped) return S_OK;
1613 EnterCriticalSection(&This->cs);
1614 if (This->state == State_Running && This->refClock)
1616 LONGLONG time = This->start_time;
1617 IReferenceClock_GetTime(This->refClock, &time);
1618 This->position += time - This->start_time;
1621 if (This->state == State_Running) SendFilterMessage(iface, SendPause);
1622 SendFilterMessage(iface, SendStop);
1623 This->state = State_Stopped;
1624 LeaveCriticalSection(&This->cs);
1628 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
1630 OAFilterState *pfs) {
1631 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1633 TRACE("(%p/%p)->(%d, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
1635 EnterCriticalSection(&This->cs);
1639 LeaveCriticalSection(&This->cs);
1644 static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface,
1646 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1648 FIXME("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
1653 static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface,
1655 IDispatch **ppUnk) {
1656 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1658 FIXME("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
1663 static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface,
1664 IDispatch **ppUnk) {
1665 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1667 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1672 static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
1673 IDispatch **ppUnk) {
1674 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1676 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1681 static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) {
1682 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1684 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
1690 static const IMediaControlVtbl IMediaControl_VTable =
1692 MediaControl_QueryInterface,
1693 MediaControl_AddRef,
1694 MediaControl_Release,
1695 MediaControl_GetTypeInfoCount,
1696 MediaControl_GetTypeInfo,
1697 MediaControl_GetIDsOfNames,
1698 MediaControl_Invoke,
1702 MediaControl_GetState,
1703 MediaControl_RenderFile,
1704 MediaControl_AddSourceFilter,
1705 MediaControl_get_FilterCollection,
1706 MediaControl_get_RegFilterCollection,
1707 MediaControl_StopWhenReady
1711 /*** IUnknown methods ***/
1712 static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface,
1715 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1717 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1719 return Filtergraph_QueryInterface(This, riid, ppvObj);
1722 static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) {
1723 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1725 TRACE("(%p/%p)->()\n", This, iface);
1727 return Filtergraph_AddRef(This);
1730 static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
1731 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1733 TRACE("(%p/%p)->()\n", This, iface);
1735 return Filtergraph_Release(This);
1738 typedef HRESULT WINAPI (*fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DWORD_PTR arg);
1740 static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) {
1741 BOOL allnotimpl = TRUE;
1743 IBaseFilter* pfilter;
1745 HRESULT hr, hr_return = S_OK;
1750 TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg);
1751 /* Send a message to all renderers, they are responsible for broadcasting it further */
1753 for(i = 0; i < This->nFilters; i++)
1755 BOOL renderer = TRUE;
1756 pfilter = This->ppFiltersInGraph[i];
1757 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1760 ERR("Enum pins failed %x\n", hr);
1763 /* Check if it is a source filter */
1764 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1766 IPin_QueryDirection(pPin, &dir);
1768 if (dir != PINDIR_INPUT)
1774 IEnumPins_Release(pEnum);
1777 IMediaSeeking *seek = NULL;
1778 IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek);
1781 LeaveCriticalSection(&This->cs);
1782 hr = FoundSeek(This, seek, arg);
1783 EnterCriticalSection(&This->cs);
1784 IMediaSeeking_Release(seek);
1785 if (hr_return != E_NOTIMPL)
1787 if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && !FAILED(hr_return)))
1797 static HRESULT WINAPI FoundCapabilities(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pcaps)
1802 hr = IMediaSeeking_GetCapabilities(seek, &caps);
1806 /* Only add common capabilities everything supports */
1807 *(DWORD*)pcaps &= caps;
1812 /*** IMediaSeeking methods ***/
1813 static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
1814 DWORD *pCapabilities) {
1815 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1817 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
1822 EnterCriticalSection(&This->cs);
1823 *pCapabilities = 0xffffffff;
1825 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
1826 LeaveCriticalSection(&This->cs);
1831 static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
1832 DWORD *pCapabilities) {
1833 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1836 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
1841 EnterCriticalSection(&This->cs);
1842 originalcaps = *pCapabilities;
1843 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
1844 LeaveCriticalSection(&This->cs);
1849 if (!*pCapabilities)
1851 if (*pCapabilities != originalcaps)
1856 static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface,
1857 const GUID *pFormat) {
1858 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1863 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
1865 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
1867 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
1874 static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface,
1876 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1881 FIXME("(%p/%p)->(%p): semi-stub !!!\n", This, iface, pFormat);
1882 memcpy(pFormat, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
1887 static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface,
1889 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1894 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
1895 memcpy(pFormat, &This->timeformatseek, sizeof(GUID));
1900 static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface,
1901 const GUID *pFormat) {
1902 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1904 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
1908 if (memcmp(pFormat, &This->timeformatseek, sizeof(GUID)))
1914 static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
1915 const GUID *pFormat) {
1916 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1921 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
1923 if (This->state != State_Stopped)
1924 return VFW_E_WRONG_STATE;
1926 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
1928 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
1929 return E_INVALIDARG;
1935 static HRESULT WINAPI FoundDuration(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pduration)
1938 LONGLONG duration = 0, *pdur = (LONGLONG*)pduration;
1940 hr = IMediaSeeking_GetDuration(seek, &duration);
1944 /* FIXME: Minimum or maximum duration? Assuming minimum */
1945 if (duration > 0 && *pdur < duration)
1951 static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
1952 LONGLONG *pDuration) {
1953 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1956 TRACE("(%p/%p)->(%p)\n", This, iface, pDuration);
1961 EnterCriticalSection(&This->cs);
1963 hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration);
1964 LeaveCriticalSection(&This->cs);
1966 TRACE("--->%08x\n", hr);
1970 static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
1972 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1974 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pStop);
1979 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
1980 LONGLONG *pCurrent) {
1981 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1987 EnterCriticalSection(&This->cs);
1988 if (This->state == State_Running && This->refClock)
1990 IReferenceClock_GetTime(This->refClock, &time);
1992 time += This->position - This->start_time;
1993 if (time < This->position)
1994 time = This->position;
1998 *pCurrent = This->position;
1999 LeaveCriticalSection(&This->cs);
2000 TRACE("Time: %lld.%03lld\n", *pCurrent / 10000000, (*pCurrent / 10000)%1000);
2005 static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface,
2007 const GUID *pTargetFormat,
2009 const GUID *pSourceFormat) {
2010 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2012 FIXME("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget,
2013 pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat);
2019 LONGLONG* current, *stop;
2020 DWORD curflags, stopflags;
2023 static HRESULT WINAPI found_setposition(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pargs)
2025 struct pos_args *args = (void*)pargs;
2027 return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags);
2030 static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface,
2032 DWORD dwCurrentFlags,
2034 DWORD dwStopFlags) {
2035 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2038 struct pos_args args;
2040 TRACE("(%p/%p)->(%p, %08x, %p, %08x)\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
2042 EnterCriticalSection(&This->cs);
2043 state = This->state;
2044 TRACE("State: %s\n", state == State_Running ? "Running" : (state == State_Paused ? "Paused" : (state == State_Stopped ? "Stopped" : "UNKNOWN")));
2046 if ((dwCurrentFlags & 0x7) == AM_SEEKING_AbsolutePositioning)
2047 This->position = *pCurrent;
2048 else if ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning)
2049 FIXME("Adjust method %x not handled yet!\n", dwCurrentFlags & 0x7);
2051 if ((dwStopFlags & 0x7) != AM_SEEKING_NoPositioning)
2052 FIXME("Stop position not handled yet!\n");
2054 args.current = pCurrent;
2056 args.curflags = dwCurrentFlags;
2057 args.stopflags = dwStopFlags;
2058 hr = all_renderers_seek(This, found_setposition, (DWORD_PTR)&args);
2059 LeaveCriticalSection(&This->cs);
2064 static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
2067 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2070 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pCurrent, pStop);
2071 hr = IMediaSeeking_GetCurrentPosition(iface, pCurrent);
2073 hr = IMediaSeeking_GetStopPosition(iface, pStop);
2078 static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
2079 LONGLONG *pEarliest,
2080 LONGLONG *pLatest) {
2081 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2083 FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
2088 static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface,
2090 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2092 FIXME("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
2097 static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface,
2099 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2101 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
2106 static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface,
2107 LONGLONG *pllPreroll) {
2108 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2110 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
2116 static const IMediaSeekingVtbl IMediaSeeking_VTable =
2118 MediaSeeking_QueryInterface,
2119 MediaSeeking_AddRef,
2120 MediaSeeking_Release,
2121 MediaSeeking_GetCapabilities,
2122 MediaSeeking_CheckCapabilities,
2123 MediaSeeking_IsFormatSupported,
2124 MediaSeeking_QueryPreferredFormat,
2125 MediaSeeking_GetTimeFormat,
2126 MediaSeeking_IsUsingTimeFormat,
2127 MediaSeeking_SetTimeFormat,
2128 MediaSeeking_GetDuration,
2129 MediaSeeking_GetStopPosition,
2130 MediaSeeking_GetCurrentPosition,
2131 MediaSeeking_ConvertTimeFormat,
2132 MediaSeeking_SetPositions,
2133 MediaSeeking_GetPositions,
2134 MediaSeeking_GetAvailable,
2135 MediaSeeking_SetRate,
2136 MediaSeeking_GetRate,
2137 MediaSeeking_GetPreroll
2140 /*** IUnknown methods ***/
2141 static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID riid, void** ppvObj){
2142 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2144 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2146 return Filtergraph_QueryInterface(This, riid, ppvObj);
2149 static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface){
2150 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2152 TRACE("(%p/%p)->()\n", This, iface);
2154 return Filtergraph_AddRef(This);
2157 static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface){
2158 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2160 TRACE("(%p/%p)->()\n", This, iface);
2162 return Filtergraph_Release(This);
2165 /*** IDispatch methods ***/
2166 static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){
2167 FIXME("(%p) stub!\n", iface);
2171 static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){
2172 FIXME("(%p) stub!\n", iface);
2176 static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){
2177 FIXME("(%p) stub!\n", iface);
2181 static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){
2182 FIXME("(%p) stub!\n", iface);
2186 /*** IMediaPosition methods ***/
2187 static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength){
2188 FIXME("(%p)->(%p) stub!\n", iface, plength);
2192 static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime){
2193 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2197 static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime){
2198 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2202 static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime){
2203 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2207 static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime){
2208 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2212 static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){
2213 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2217 static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){
2218 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2222 static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate){
2223 FIXME("(%p)->(%f) stub!\n", iface, dRate);
2227 static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate){
2228 FIXME("(%p)->(%p) stub!\n", iface, pdRate);
2232 static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){
2233 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward);
2237 static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){
2238 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward);
2243 static const IMediaPositionVtbl IMediaPosition_VTable =
2245 MediaPosition_QueryInterface,
2246 MediaPosition_AddRef,
2247 MediaPosition_Release,
2248 MediaPosition_GetTypeInfoCount,
2249 MediaPosition_GetTypeInfo,
2250 MediaPosition_GetIDsOfNames,
2251 MediaPosition_Invoke,
2252 MediaPosition_get_Duration,
2253 MediaPosition_put_CurrentPosition,
2254 MediaPosition_get_CurrentPosition,
2255 MediaPosition_get_StopTime,
2256 MediaPosition_put_StopTime,
2257 MediaPosition_get_PrerollTime,
2258 MediaPosition_put_PrerollTime,
2259 MediaPosition_put_Rate,
2260 MediaPosition_get_Rate,
2261 MediaPosition_CanSeekForward,
2262 MediaPosition_CanSeekBackward
2265 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
2267 HRESULT hr = E_NOINTERFACE;
2271 /* Check if the interface type is already registered */
2272 for (entry = 0; entry < pGraph->nItfCacheEntries; entry++)
2273 if (riid == pGraph->ItfCacheEntries[entry].riid)
2275 if (pGraph->ItfCacheEntries[entry].iface)
2277 /* Return the interface if available */
2278 *ppvObj = pGraph->ItfCacheEntries[entry].iface;
2284 if (entry >= MAX_ITF_CACHE_ENTRIES)
2286 FIXME("Not enough space to store interface in the cache\n");
2287 return E_OUTOFMEMORY;
2290 /* Find a filter supporting the requested interface */
2291 for (i = 0; i < pGraph->nFilters; i++)
2293 hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
2296 pGraph->ItfCacheEntries[entry].riid = riid;
2297 pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
2298 pGraph->ItfCacheEntries[entry].iface = (IUnknown*)*ppvObj;
2299 if (entry >= pGraph->nItfCacheEntries)
2300 pGraph->nItfCacheEntries++;
2303 if (hr != E_NOINTERFACE)
2310 /*** IUnknown methods ***/
2311 static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface,
2314 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2316 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2318 return Filtergraph_QueryInterface(This, riid, ppvObj);
2321 static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) {
2322 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2324 TRACE("(%p/%p)->()\n", This, iface);
2326 return Filtergraph_AddRef(This);
2329 static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) {
2330 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2332 TRACE("(%p/%p)->()\n", This, iface);
2334 return Filtergraph_Release(This);
2337 /*** IDispatch methods ***/
2338 static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface,
2340 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2341 IBasicAudio* pBasicAudio;
2344 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2346 EnterCriticalSection(&This->cs);
2348 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2351 hr = IBasicAudio_GetTypeInfoCount(pBasicAudio, pctinfo);
2353 LeaveCriticalSection(&This->cs);
2358 static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface,
2361 ITypeInfo**ppTInfo) {
2362 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2363 IBasicAudio* pBasicAudio;
2366 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2368 EnterCriticalSection(&This->cs);
2370 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2373 hr = IBasicAudio_GetTypeInfo(pBasicAudio, iTInfo, lcid, ppTInfo);
2375 LeaveCriticalSection(&This->cs);
2380 static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface,
2386 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2387 IBasicAudio* pBasicAudio;
2390 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2392 EnterCriticalSection(&This->cs);
2394 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2397 hr = IBasicAudio_GetIDsOfNames(pBasicAudio, riid, rgszNames, cNames, lcid, rgDispId);
2399 LeaveCriticalSection(&This->cs);
2404 static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface,
2405 DISPID dispIdMember,
2409 DISPPARAMS*pDispParams,
2411 EXCEPINFO*pExepInfo,
2413 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2414 IBasicAudio* pBasicAudio;
2417 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);
2419 EnterCriticalSection(&This->cs);
2421 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2424 hr = IBasicAudio_Invoke(pBasicAudio, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2426 LeaveCriticalSection(&This->cs);
2431 /*** IBasicAudio methods ***/
2432 static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface,
2434 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2435 IBasicAudio* pBasicAudio;
2438 TRACE("(%p/%p)->(%ld)\n", This, iface, lVolume);
2440 EnterCriticalSection(&This->cs);
2442 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2445 hr = IBasicAudio_put_Volume(pBasicAudio, lVolume);
2447 LeaveCriticalSection(&This->cs);
2452 static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface,
2454 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2455 IBasicAudio* pBasicAudio;
2458 TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
2460 EnterCriticalSection(&This->cs);
2462 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2465 hr = IBasicAudio_get_Volume(pBasicAudio, plVolume);
2467 LeaveCriticalSection(&This->cs);
2472 static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface,
2474 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2475 IBasicAudio* pBasicAudio;
2478 TRACE("(%p/%p)->(%ld)\n", This, iface, lBalance);
2480 EnterCriticalSection(&This->cs);
2482 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2485 hr = IBasicAudio_put_Balance(pBasicAudio, lBalance);
2487 LeaveCriticalSection(&This->cs);
2492 static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface,
2494 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2495 IBasicAudio* pBasicAudio;
2498 TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
2500 EnterCriticalSection(&This->cs);
2502 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2505 hr = IBasicAudio_get_Balance(pBasicAudio, plBalance);
2507 LeaveCriticalSection(&This->cs);
2512 static const IBasicAudioVtbl IBasicAudio_VTable =
2514 BasicAudio_QueryInterface,
2517 BasicAudio_GetTypeInfoCount,
2518 BasicAudio_GetTypeInfo,
2519 BasicAudio_GetIDsOfNames,
2521 BasicAudio_put_Volume,
2522 BasicAudio_get_Volume,
2523 BasicAudio_put_Balance,
2524 BasicAudio_get_Balance
2527 /*** IUnknown methods ***/
2528 static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo *iface,
2531 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2533 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2535 return Filtergraph_QueryInterface(This, riid, ppvObj);
2538 static ULONG WINAPI BasicVideo_AddRef(IBasicVideo *iface) {
2539 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2541 TRACE("(%p/%p)->()\n", This, iface);
2543 return Filtergraph_AddRef(This);
2546 static ULONG WINAPI BasicVideo_Release(IBasicVideo *iface) {
2547 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2549 TRACE("(%p/%p)->()\n", This, iface);
2551 return Filtergraph_Release(This);
2554 /*** IDispatch methods ***/
2555 static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo *iface,
2557 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2558 IBasicVideo* pBasicVideo;
2561 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2563 EnterCriticalSection(&This->cs);
2565 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2568 hr = IBasicVideo_GetTypeInfoCount(pBasicVideo, pctinfo);
2570 LeaveCriticalSection(&This->cs);
2575 static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo *iface,
2578 ITypeInfo**ppTInfo) {
2579 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2580 IBasicVideo* pBasicVideo;
2583 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2585 EnterCriticalSection(&This->cs);
2587 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2590 hr = IBasicVideo_GetTypeInfo(pBasicVideo, iTInfo, lcid, ppTInfo);
2592 LeaveCriticalSection(&This->cs);
2597 static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo *iface,
2603 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2604 IBasicVideo* pBasicVideo;
2607 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2609 EnterCriticalSection(&This->cs);
2611 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2614 hr = IBasicVideo_GetIDsOfNames(pBasicVideo, riid, rgszNames, cNames, lcid, rgDispId);
2616 LeaveCriticalSection(&This->cs);
2621 static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo *iface,
2622 DISPID dispIdMember,
2626 DISPPARAMS*pDispParams,
2628 EXCEPINFO*pExepInfo,
2630 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2631 IBasicVideo* pBasicVideo;
2634 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);
2636 EnterCriticalSection(&This->cs);
2638 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2641 hr = IBasicVideo_Invoke(pBasicVideo, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2643 LeaveCriticalSection(&This->cs);
2648 /*** IBasicVideo methods ***/
2649 static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo *iface,
2650 REFTIME *pAvgTimePerFrame) {
2651 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2652 IBasicVideo* pBasicVideo;
2655 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
2657 EnterCriticalSection(&This->cs);
2659 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2662 hr = IBasicVideo_get_AvgTimePerFrame(pBasicVideo, pAvgTimePerFrame);
2664 LeaveCriticalSection(&This->cs);
2669 static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo *iface,
2671 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2672 IBasicVideo* pBasicVideo;
2675 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
2677 EnterCriticalSection(&This->cs);
2679 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2682 hr = IBasicVideo_get_BitRate(pBasicVideo, pBitRate);
2684 LeaveCriticalSection(&This->cs);
2689 static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo *iface,
2690 long *pBitErrorRate) {
2691 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2692 IBasicVideo* pBasicVideo;
2695 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
2697 EnterCriticalSection(&This->cs);
2699 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2702 hr = IBasicVideo_get_BitErrorRate(pBasicVideo, pBitErrorRate);
2704 LeaveCriticalSection(&This->cs);
2709 static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo *iface,
2710 long *pVideoWidth) {
2711 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2712 IBasicVideo* pBasicVideo;
2715 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
2717 EnterCriticalSection(&This->cs);
2719 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2722 hr = IBasicVideo_get_VideoWidth(pBasicVideo, pVideoWidth);
2724 LeaveCriticalSection(&This->cs);
2729 static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo *iface,
2730 long *pVideoHeight) {
2731 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2732 IBasicVideo* pBasicVideo;
2735 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
2737 EnterCriticalSection(&This->cs);
2739 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2742 hr = IBasicVideo_get_VideoHeight(pBasicVideo, pVideoHeight);
2744 LeaveCriticalSection(&This->cs);
2749 static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo *iface,
2751 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2752 IBasicVideo* pBasicVideo;
2755 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft);
2757 EnterCriticalSection(&This->cs);
2759 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2762 hr = IBasicVideo_put_SourceLeft(pBasicVideo, SourceLeft);
2764 LeaveCriticalSection(&This->cs);
2769 static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo *iface,
2770 long *pSourceLeft) {
2771 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2772 IBasicVideo* pBasicVideo;
2775 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
2777 EnterCriticalSection(&This->cs);
2779 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2782 hr = IBasicVideo_get_SourceLeft(pBasicVideo, pSourceLeft);
2784 LeaveCriticalSection(&This->cs);
2789 static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo *iface,
2791 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2792 IBasicVideo* pBasicVideo;
2795 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth);
2797 EnterCriticalSection(&This->cs);
2799 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2802 hr = IBasicVideo_put_SourceWidth(pBasicVideo, SourceWidth);
2804 LeaveCriticalSection(&This->cs);
2809 static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo *iface,
2810 long *pSourceWidth) {
2811 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2812 IBasicVideo* pBasicVideo;
2815 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
2817 EnterCriticalSection(&This->cs);
2819 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2822 hr = IBasicVideo_get_SourceWidth(pBasicVideo, pSourceWidth);
2824 LeaveCriticalSection(&This->cs);
2829 static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo *iface,
2831 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2832 IBasicVideo* pBasicVideo;
2835 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop);
2837 EnterCriticalSection(&This->cs);
2839 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2842 hr = IBasicVideo_put_SourceTop(pBasicVideo, SourceTop);
2844 LeaveCriticalSection(&This->cs);
2849 static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo *iface,
2851 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2852 IBasicVideo* pBasicVideo;
2855 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
2857 EnterCriticalSection(&This->cs);
2859 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2862 hr = IBasicVideo_get_SourceTop(pBasicVideo, pSourceTop);
2864 LeaveCriticalSection(&This->cs);
2869 static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo *iface,
2870 long SourceHeight) {
2871 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2872 IBasicVideo* pBasicVideo;
2875 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight);
2877 EnterCriticalSection(&This->cs);
2879 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2882 hr = IBasicVideo_put_SourceHeight(pBasicVideo, SourceHeight);
2884 LeaveCriticalSection(&This->cs);
2889 static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo *iface,
2890 long *pSourceHeight) {
2891 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2892 IBasicVideo* pBasicVideo;
2895 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
2897 EnterCriticalSection(&This->cs);
2899 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2902 hr = IBasicVideo_get_SourceHeight(pBasicVideo, pSourceHeight);
2904 LeaveCriticalSection(&This->cs);
2909 static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo *iface,
2910 long DestinationLeft) {
2911 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2912 IBasicVideo* pBasicVideo;
2915 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft);
2917 EnterCriticalSection(&This->cs);
2919 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2922 hr = IBasicVideo_put_DestinationLeft(pBasicVideo, DestinationLeft);
2924 LeaveCriticalSection(&This->cs);
2929 static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo *iface,
2930 long *pDestinationLeft) {
2931 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2932 IBasicVideo* pBasicVideo;
2935 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
2937 EnterCriticalSection(&This->cs);
2939 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2942 hr = IBasicVideo_get_DestinationLeft(pBasicVideo, pDestinationLeft);
2944 LeaveCriticalSection(&This->cs);
2949 static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo *iface,
2950 long DestinationWidth) {
2951 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2952 IBasicVideo* pBasicVideo;
2955 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth);
2957 EnterCriticalSection(&This->cs);
2959 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2962 hr = IBasicVideo_put_DestinationWidth(pBasicVideo, DestinationWidth);
2964 LeaveCriticalSection(&This->cs);
2969 static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo *iface,
2970 long *pDestinationWidth) {
2971 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2972 IBasicVideo* pBasicVideo;
2975 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
2977 EnterCriticalSection(&This->cs);
2979 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2982 hr = IBasicVideo_get_DestinationWidth(pBasicVideo, pDestinationWidth);
2984 LeaveCriticalSection(&This->cs);
2989 static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo *iface,
2990 long DestinationTop) {
2991 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2992 IBasicVideo* pBasicVideo;
2995 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop);
2997 EnterCriticalSection(&This->cs);
2999 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3002 hr = IBasicVideo_put_DestinationTop(pBasicVideo, DestinationTop);
3004 LeaveCriticalSection(&This->cs);
3009 static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo *iface,
3010 long *pDestinationTop) {
3011 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3012 IBasicVideo* pBasicVideo;
3015 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
3017 EnterCriticalSection(&This->cs);
3019 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3022 hr = IBasicVideo_get_DestinationTop(pBasicVideo, pDestinationTop);
3024 LeaveCriticalSection(&This->cs);
3029 static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo *iface,
3030 long DestinationHeight) {
3031 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3032 IBasicVideo* pBasicVideo;
3035 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight);
3037 EnterCriticalSection(&This->cs);
3039 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3042 hr = IBasicVideo_put_DestinationHeight(pBasicVideo, DestinationHeight);
3044 LeaveCriticalSection(&This->cs);
3049 static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo *iface,
3050 long *pDestinationHeight) {
3051 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3052 IBasicVideo* pBasicVideo;
3055 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
3057 EnterCriticalSection(&This->cs);
3059 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3062 hr = IBasicVideo_get_DestinationHeight(pBasicVideo, pDestinationHeight);
3064 LeaveCriticalSection(&This->cs);
3069 static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo *iface,
3074 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3075 IBasicVideo* pBasicVideo;
3078 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3080 EnterCriticalSection(&This->cs);
3082 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3085 hr = IBasicVideo_SetSourcePosition(pBasicVideo, Left, Top, Width, Height);
3087 LeaveCriticalSection(&This->cs);
3092 static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo *iface,
3097 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3098 IBasicVideo* pBasicVideo;
3101 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3103 EnterCriticalSection(&This->cs);
3105 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3108 hr = IBasicVideo_GetSourcePosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3110 LeaveCriticalSection(&This->cs);
3115 static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo *iface) {
3116 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3117 IBasicVideo* pBasicVideo;
3120 TRACE("(%p/%p)->()\n", This, iface);
3122 EnterCriticalSection(&This->cs);
3124 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3127 hr = IBasicVideo_SetDefaultSourcePosition(pBasicVideo);
3129 LeaveCriticalSection(&This->cs);
3134 static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo *iface,
3139 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3140 IBasicVideo* pBasicVideo;
3143 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3145 EnterCriticalSection(&This->cs);
3147 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3150 hr = IBasicVideo_SetDestinationPosition(pBasicVideo, Left, Top, Width, Height);
3152 LeaveCriticalSection(&This->cs);
3157 static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo *iface,
3162 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3163 IBasicVideo* pBasicVideo;
3166 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3168 EnterCriticalSection(&This->cs);
3170 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3173 hr = IBasicVideo_GetDestinationPosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3175 LeaveCriticalSection(&This->cs);
3180 static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
3181 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3182 IBasicVideo* pBasicVideo;
3185 TRACE("(%p/%p)->()\n", This, iface);
3187 EnterCriticalSection(&This->cs);
3189 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3192 hr = IBasicVideo_SetDefaultDestinationPosition(pBasicVideo);
3194 LeaveCriticalSection(&This->cs);
3199 static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo *iface,
3202 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3203 IBasicVideo* pBasicVideo;
3206 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3208 EnterCriticalSection(&This->cs);
3210 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3213 hr = IBasicVideo_GetVideoSize(pBasicVideo, pWidth, pHeight);
3215 LeaveCriticalSection(&This->cs);
3220 static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo *iface,
3225 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3226 IBasicVideo* pBasicVideo;
3229 TRACE("(%p/%p)->(%ld, %ld, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
3231 EnterCriticalSection(&This->cs);
3233 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3236 hr = IBasicVideo_GetVideoPaletteEntries(pBasicVideo, StartIndex, Entries, pRetrieved, pPalette);
3238 LeaveCriticalSection(&This->cs);
3243 static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo *iface,
3246 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3247 IBasicVideo* pBasicVideo;
3250 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage);
3252 EnterCriticalSection(&This->cs);
3254 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3257 hr = IBasicVideo_GetCurrentImage(pBasicVideo, pBufferSize, pDIBImage);
3259 LeaveCriticalSection(&This->cs);
3264 static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo *iface) {
3265 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3266 IBasicVideo* pBasicVideo;
3269 TRACE("(%p/%p)->()\n", This, iface);
3271 EnterCriticalSection(&This->cs);
3273 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3276 hr = IBasicVideo_IsUsingDefaultSource(pBasicVideo);
3278 LeaveCriticalSection(&This->cs);
3283 static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo *iface) {
3284 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3285 IBasicVideo* pBasicVideo;
3288 TRACE("(%p/%p)->()\n", This, iface);
3290 EnterCriticalSection(&This->cs);
3292 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3295 hr = IBasicVideo_IsUsingDefaultDestination(pBasicVideo);
3297 LeaveCriticalSection(&This->cs);
3303 static const IBasicVideoVtbl IBasicVideo_VTable =
3305 BasicVideo_QueryInterface,
3308 BasicVideo_GetTypeInfoCount,
3309 BasicVideo_GetTypeInfo,
3310 BasicVideo_GetIDsOfNames,
3312 BasicVideo_get_AvgTimePerFrame,
3313 BasicVideo_get_BitRate,
3314 BasicVideo_get_BitErrorRate,
3315 BasicVideo_get_VideoWidth,
3316 BasicVideo_get_VideoHeight,
3317 BasicVideo_put_SourceLeft,
3318 BasicVideo_get_SourceLeft,
3319 BasicVideo_put_SourceWidth,
3320 BasicVideo_get_SourceWidth,
3321 BasicVideo_put_SourceTop,
3322 BasicVideo_get_SourceTop,
3323 BasicVideo_put_SourceHeight,
3324 BasicVideo_get_SourceHeight,
3325 BasicVideo_put_DestinationLeft,
3326 BasicVideo_get_DestinationLeft,
3327 BasicVideo_put_DestinationWidth,
3328 BasicVideo_get_DestinationWidth,
3329 BasicVideo_put_DestinationTop,
3330 BasicVideo_get_DestinationTop,
3331 BasicVideo_put_DestinationHeight,
3332 BasicVideo_get_DestinationHeight,
3333 BasicVideo_SetSourcePosition,
3334 BasicVideo_GetSourcePosition,
3335 BasicVideo_SetDefaultSourcePosition,
3336 BasicVideo_SetDestinationPosition,
3337 BasicVideo_GetDestinationPosition,
3338 BasicVideo_SetDefaultDestinationPosition,
3339 BasicVideo_GetVideoSize,
3340 BasicVideo_GetVideoPaletteEntries,
3341 BasicVideo_GetCurrentImage,
3342 BasicVideo_IsUsingDefaultSource,
3343 BasicVideo_IsUsingDefaultDestination
3347 /*** IUnknown methods ***/
3348 static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface,
3351 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3353 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3355 return Filtergraph_QueryInterface(This, riid, ppvObj);
3358 static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) {
3359 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3361 TRACE("(%p/%p)->()\n", This, iface);
3363 return Filtergraph_AddRef(This);
3366 static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) {
3367 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3369 TRACE("(%p/%p)->()\n", This, iface);
3371 return Filtergraph_Release(This);
3374 /*** IDispatch methods ***/
3375 static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface,
3377 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3378 IVideoWindow* pVideoWindow;
3381 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3383 EnterCriticalSection(&This->cs);
3385 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3388 hr = IVideoWindow_GetTypeInfoCount(pVideoWindow, pctinfo);
3390 LeaveCriticalSection(&This->cs);
3395 static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface,
3398 ITypeInfo**ppTInfo) {
3399 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3400 IVideoWindow* pVideoWindow;
3403 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3405 EnterCriticalSection(&This->cs);
3407 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3410 hr = IVideoWindow_GetTypeInfo(pVideoWindow, iTInfo, lcid, ppTInfo);
3412 LeaveCriticalSection(&This->cs);
3417 static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface,
3423 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3424 IVideoWindow* pVideoWindow;
3427 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3429 EnterCriticalSection(&This->cs);
3431 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3434 hr = IVideoWindow_GetIDsOfNames(pVideoWindow, riid, rgszNames, cNames, lcid, rgDispId);
3436 LeaveCriticalSection(&This->cs);
3441 static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface,
3442 DISPID dispIdMember,
3446 DISPPARAMS*pDispParams,
3448 EXCEPINFO*pExepInfo,
3450 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3451 IVideoWindow* pVideoWindow;
3454 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);
3456 EnterCriticalSection(&This->cs);
3458 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3461 hr = IVideoWindow_Invoke(pVideoWindow, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3463 LeaveCriticalSection(&This->cs);
3469 /*** IVideoWindow methods ***/
3470 static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface,
3472 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3473 IVideoWindow* pVideoWindow;
3476 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
3478 EnterCriticalSection(&This->cs);
3480 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3483 hr = IVideoWindow_put_Caption(pVideoWindow, strCaption);
3485 LeaveCriticalSection(&This->cs);
3490 static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface,
3492 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3493 IVideoWindow* pVideoWindow;
3496 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
3498 EnterCriticalSection(&This->cs);
3500 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3503 hr = IVideoWindow_get_Caption(pVideoWindow, strCaption);
3505 LeaveCriticalSection(&This->cs);
3510 static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface,
3512 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3513 IVideoWindow* pVideoWindow;
3516 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyle);
3518 EnterCriticalSection(&This->cs);
3520 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3523 hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle);
3525 LeaveCriticalSection(&This->cs);
3530 static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface,
3531 long *WindowStyle) {
3532 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3533 IVideoWindow* pVideoWindow;
3536 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
3538 EnterCriticalSection(&This->cs);
3540 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3543 hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle);
3545 LeaveCriticalSection(&This->cs);
3550 static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface,
3551 long WindowStyleEx) {
3552 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3553 IVideoWindow* pVideoWindow;
3556 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx);
3558 EnterCriticalSection(&This->cs);
3560 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3563 hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx);
3565 LeaveCriticalSection(&This->cs);
3570 static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface,
3571 long *WindowStyleEx) {
3572 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3573 IVideoWindow* pVideoWindow;
3576 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
3578 EnterCriticalSection(&This->cs);
3580 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3583 hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx);
3585 LeaveCriticalSection(&This->cs);
3590 static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface,
3592 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3593 IVideoWindow* pVideoWindow;
3596 TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow);
3598 EnterCriticalSection(&This->cs);
3600 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3603 hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow);
3605 LeaveCriticalSection(&This->cs);
3610 static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface,
3612 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3613 IVideoWindow* pVideoWindow;
3616 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
3618 EnterCriticalSection(&This->cs);
3620 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3623 hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow);
3625 LeaveCriticalSection(&This->cs);
3630 static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface,
3632 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3633 IVideoWindow* pVideoWindow;
3636 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowState);
3638 EnterCriticalSection(&This->cs);
3640 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3643 hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState);
3645 LeaveCriticalSection(&This->cs);
3650 static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface,
3651 long *WindowState) {
3652 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3653 IVideoWindow* pVideoWindow;
3656 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
3658 EnterCriticalSection(&This->cs);
3660 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3663 hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState);
3665 LeaveCriticalSection(&This->cs);
3670 static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface,
3671 long BackgroundPalette) {
3672 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3673 IVideoWindow* pVideoWindow;
3676 TRACE("(%p/%p)->(%ld)\n", This, iface, BackgroundPalette);
3678 EnterCriticalSection(&This->cs);
3680 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3683 hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette);
3685 LeaveCriticalSection(&This->cs);
3690 static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface,
3691 long *pBackgroundPalette) {
3692 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3693 IVideoWindow* pVideoWindow;
3696 TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette);
3698 EnterCriticalSection(&This->cs);
3700 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3703 hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette);
3705 LeaveCriticalSection(&This->cs);
3710 static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface,
3712 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3713 IVideoWindow* pVideoWindow;
3716 TRACE("(%p/%p)->(%ld)\n", This, iface, Visible);
3718 EnterCriticalSection(&This->cs);
3720 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3723 hr = IVideoWindow_put_Visible(pVideoWindow, Visible);
3725 LeaveCriticalSection(&This->cs);
3730 static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface,
3732 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3733 IVideoWindow* pVideoWindow;
3736 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
3738 EnterCriticalSection(&This->cs);
3740 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3743 hr = IVideoWindow_get_Visible(pVideoWindow, pVisible);
3745 LeaveCriticalSection(&This->cs);
3750 static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface,
3752 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3753 IVideoWindow* pVideoWindow;
3756 TRACE("(%p/%p)->(%ld)\n", This, iface, Left);
3758 EnterCriticalSection(&This->cs);
3760 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3763 hr = IVideoWindow_put_Left(pVideoWindow, Left);
3765 LeaveCriticalSection(&This->cs);
3770 static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface,
3772 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3773 IVideoWindow* pVideoWindow;
3776 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
3778 EnterCriticalSection(&This->cs);
3780 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3783 hr = IVideoWindow_get_Left(pVideoWindow, pLeft);
3785 LeaveCriticalSection(&This->cs);
3790 static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface,
3792 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3793 IVideoWindow* pVideoWindow;
3796 TRACE("(%p/%p)->(%ld)\n", This, iface, Width);
3798 EnterCriticalSection(&This->cs);
3800 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3803 hr = IVideoWindow_put_Width(pVideoWindow, Width);
3805 LeaveCriticalSection(&This->cs);
3810 static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface,
3812 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3813 IVideoWindow* pVideoWindow;
3816 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
3818 EnterCriticalSection(&This->cs);
3820 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3823 hr = IVideoWindow_get_Width(pVideoWindow, pWidth);
3825 LeaveCriticalSection(&This->cs);
3830 static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface,
3832 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3833 IVideoWindow* pVideoWindow;
3836 TRACE("(%p/%p)->(%ld)\n", This, iface, Top);
3838 EnterCriticalSection(&This->cs);
3840 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3843 hr = IVideoWindow_put_Top(pVideoWindow, Top);
3845 LeaveCriticalSection(&This->cs);
3850 static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface,
3852 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3853 IVideoWindow* pVideoWindow;
3856 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
3858 EnterCriticalSection(&This->cs);
3860 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3863 hr = IVideoWindow_get_Top(pVideoWindow, pTop);
3865 LeaveCriticalSection(&This->cs);
3870 static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface,
3872 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3873 IVideoWindow* pVideoWindow;
3876 TRACE("(%p/%p)->(%ld)\n", This, iface, Height);
3878 EnterCriticalSection(&This->cs);
3880 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3883 hr = IVideoWindow_put_Height(pVideoWindow, Height);
3885 LeaveCriticalSection(&This->cs);
3890 static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface,
3892 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3893 IVideoWindow* pVideoWindow;
3896 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
3898 EnterCriticalSection(&This->cs);
3900 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3903 hr = IVideoWindow_get_Height(pVideoWindow, pHeight);
3905 LeaveCriticalSection(&This->cs);
3910 static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface,
3912 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3913 IVideoWindow* pVideoWindow;
3916 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
3918 EnterCriticalSection(&This->cs);
3920 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3923 hr = IVideoWindow_put_Owner(pVideoWindow, Owner);
3925 LeaveCriticalSection(&This->cs);
3930 static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface,
3932 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3933 IVideoWindow* pVideoWindow;
3936 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
3938 EnterCriticalSection(&This->cs);
3940 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3943 hr = IVideoWindow_get_Owner(pVideoWindow, Owner);
3945 LeaveCriticalSection(&This->cs);
3950 static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface,
3952 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3953 IVideoWindow* pVideoWindow;
3956 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
3958 EnterCriticalSection(&This->cs);
3960 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3963 hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain);
3965 LeaveCriticalSection(&This->cs);
3970 static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface,
3972 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3973 IVideoWindow* pVideoWindow;
3976 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
3978 EnterCriticalSection(&This->cs);
3980 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3983 hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain);
3985 LeaveCriticalSection(&This->cs);
3990 static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface,
3992 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3993 IVideoWindow* pVideoWindow;
3996 TRACE("(%p/%p)->(%p)\n", This, iface, Color);
3998 EnterCriticalSection(&This->cs);
4000 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4003 hr = IVideoWindow_get_BorderColor(pVideoWindow, Color);
4005 LeaveCriticalSection(&This->cs);
4010 static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface,
4012 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4013 IVideoWindow* pVideoWindow;
4016 TRACE("(%p/%p)->(%ld)\n", This, iface, Color);
4018 EnterCriticalSection(&This->cs);
4020 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4023 hr = IVideoWindow_put_BorderColor(pVideoWindow, Color);
4025 LeaveCriticalSection(&This->cs);
4030 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
4031 long *FullScreenMode) {
4032 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4033 IVideoWindow* pVideoWindow;
4036 TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode);
4038 EnterCriticalSection(&This->cs);
4040 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4043 hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode);
4045 LeaveCriticalSection(&This->cs);
4050 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
4051 long FullScreenMode) {
4052 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4053 IVideoWindow* pVideoWindow;
4056 TRACE("(%p/%p)->(%ld)\n", This, iface, FullScreenMode);
4058 EnterCriticalSection(&This->cs);
4060 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4063 hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode);
4065 LeaveCriticalSection(&This->cs);
4070 static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface,
4072 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4073 IVideoWindow* pVideoWindow;
4076 TRACE("(%p/%p)->(%ld)\n", This, iface, Focus);
4078 EnterCriticalSection(&This->cs);
4080 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4083 hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus);
4085 LeaveCriticalSection(&This->cs);
4090 static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface,
4095 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4096 IVideoWindow* pVideoWindow;
4099 TRACE("(%p/%p)->(%08x, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
4101 EnterCriticalSection(&This->cs);
4103 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4106 hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam);
4108 LeaveCriticalSection(&This->cs);
4113 static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface,
4118 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4119 IVideoWindow* pVideoWindow;
4122 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
4124 EnterCriticalSection(&This->cs);
4126 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4129 hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height);
4131 LeaveCriticalSection(&This->cs);
4136 static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface,
4141 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4142 IVideoWindow* pVideoWindow;
4145 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4147 EnterCriticalSection(&This->cs);
4149 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4152 hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4154 LeaveCriticalSection(&This->cs);
4159 static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface,
4162 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4163 IVideoWindow* pVideoWindow;
4166 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4168 EnterCriticalSection(&This->cs);
4170 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4173 hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight);
4175 LeaveCriticalSection(&This->cs);
4180 static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface,
4183 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4184 IVideoWindow* pVideoWindow;
4187 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4189 EnterCriticalSection(&This->cs);
4191 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4194 hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight);
4196 LeaveCriticalSection(&This->cs);
4201 static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface,
4206 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4207 IVideoWindow* pVideoWindow;
4210 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4212 EnterCriticalSection(&This->cs);
4214 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4217 hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4219 LeaveCriticalSection(&This->cs);
4224 static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface,
4226 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4227 IVideoWindow* pVideoWindow;
4230 TRACE("(%p/%p)->(%ld)\n", This, iface, HideCursor);
4232 EnterCriticalSection(&This->cs);
4234 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4237 hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor);
4239 LeaveCriticalSection(&This->cs);
4244 static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface,
4245 long *CursorHidden) {
4246 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4247 IVideoWindow* pVideoWindow;
4250 TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden);
4252 EnterCriticalSection(&This->cs);
4254 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4257 hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden);
4259 LeaveCriticalSection(&This->cs);
4265 static const IVideoWindowVtbl IVideoWindow_VTable =
4267 VideoWindow_QueryInterface,
4269 VideoWindow_Release,
4270 VideoWindow_GetTypeInfoCount,
4271 VideoWindow_GetTypeInfo,
4272 VideoWindow_GetIDsOfNames,
4274 VideoWindow_put_Caption,
4275 VideoWindow_get_Caption,
4276 VideoWindow_put_WindowStyle,
4277 VideoWindow_get_WindowStyle,
4278 VideoWindow_put_WindowStyleEx,
4279 VideoWindow_get_WindowStyleEx,
4280 VideoWindow_put_AutoShow,
4281 VideoWindow_get_AutoShow,
4282 VideoWindow_put_WindowState,
4283 VideoWindow_get_WindowState,
4284 VideoWindow_put_BackgroundPalette,
4285 VideoWindow_get_BackgroundPalette,
4286 VideoWindow_put_Visible,
4287 VideoWindow_get_Visible,
4288 VideoWindow_put_Left,
4289 VideoWindow_get_Left,
4290 VideoWindow_put_Width,
4291 VideoWindow_get_Width,
4292 VideoWindow_put_Top,
4293 VideoWindow_get_Top,
4294 VideoWindow_put_Height,
4295 VideoWindow_get_Height,
4296 VideoWindow_put_Owner,
4297 VideoWindow_get_Owner,
4298 VideoWindow_put_MessageDrain,
4299 VideoWindow_get_MessageDrain,
4300 VideoWindow_get_BorderColor,
4301 VideoWindow_put_BorderColor,
4302 VideoWindow_get_FullScreenMode,
4303 VideoWindow_put_FullScreenMode,
4304 VideoWindow_SetWindowForeground,
4305 VideoWindow_NotifyOwnerMessage,
4306 VideoWindow_SetWindowPosition,
4307 VideoWindow_GetWindowPosition,
4308 VideoWindow_GetMinIdealImageSize,
4309 VideoWindow_GetMaxIdealImageSize,
4310 VideoWindow_GetRestorePosition,
4311 VideoWindow_HideCursor,
4312 VideoWindow_IsCursorHidden
4316 /*** IUnknown methods ***/
4317 static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface,
4320 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4322 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
4324 return Filtergraph_QueryInterface(This, riid, ppvObj);
4327 static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) {
4328 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4330 TRACE("(%p/%p)->()\n", This, iface);
4332 return Filtergraph_AddRef(This);
4335 static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) {
4336 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4338 TRACE("(%p/%p)->()\n", This, iface);
4340 return Filtergraph_Release(This);
4343 /*** IDispatch methods ***/
4344 static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface,
4346 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4348 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
4353 static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface,
4356 ITypeInfo**ppTInfo) {
4357 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4359 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
4364 static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface,
4370 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4372 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
4377 static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface,
4378 DISPID dispIdMember,
4382 DISPPARAMS*pDispParams,
4384 EXCEPINFO*pExepInfo,
4386 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4388 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);
4393 /*** IMediaEvent methods ***/
4394 static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface,
4396 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4398 TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
4400 *hEvent = (OAEVENT)This->evqueue.msg_event;
4405 static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface,
4410 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4413 TRACE("(%p/%p)->(%p, %p, %p, %ld)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
4415 if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
4417 *lEventCode = evt.lEventCode;
4418 *lParam1 = evt.lParam1;
4419 *lParam2 = evt.lParam2;
4427 static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface,
4430 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4432 TRACE("(%p/%p)->(%ld, %p)\n", This, iface, msTimeout, pEvCode);
4434 if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
4436 *pEvCode = This->CompletionStatus;
4444 static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface,
4446 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4448 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4450 if (lEvCode == EC_COMPLETE)
4451 This->HandleEcComplete = FALSE;
4452 else if (lEvCode == EC_REPAINT)
4453 This->HandleEcRepaint = FALSE;
4454 else if (lEvCode == EC_CLOCK_CHANGED)
4455 This->HandleEcClockChanged = FALSE;
4462 static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface,
4464 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4466 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4468 if (lEvCode == EC_COMPLETE)
4469 This->HandleEcComplete = TRUE;
4470 else if (lEvCode == EC_REPAINT)
4471 This->HandleEcRepaint = TRUE;
4472 else if (lEvCode == EC_CLOCK_CHANGED)
4473 This->HandleEcClockChanged = TRUE;
4480 static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface,
4484 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4486 TRACE("(%p/%p)->(%ld, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
4491 /*** IMediaEventEx methods ***/
4492 static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface,
4495 LONG_PTR lInstanceData) {
4496 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4498 TRACE("(%p/%p)->(%08x, %ld, %08lx)\n", This, iface, (DWORD) hwnd, lMsg, lInstanceData);
4500 This->notif.hWnd = (HWND)hwnd;
4501 This->notif.msg = lMsg;
4502 This->notif.instance = (long) lInstanceData;
4507 static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface,
4508 long lNoNotifyFlags) {
4509 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4511 TRACE("(%p/%p)->(%ld)\n", This, iface, lNoNotifyFlags);
4513 if ((lNoNotifyFlags != 0) && (lNoNotifyFlags != 1))
4514 return E_INVALIDARG;
4516 This->notif.disabled = lNoNotifyFlags;
4521 static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface,
4522 long *lplNoNotifyFlags) {
4523 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4525 TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
4527 if (!lplNoNotifyFlags)
4530 *lplNoNotifyFlags = This->notif.disabled;
4536 static const IMediaEventExVtbl IMediaEventEx_VTable =
4538 MediaEvent_QueryInterface,
4541 MediaEvent_GetTypeInfoCount,
4542 MediaEvent_GetTypeInfo,
4543 MediaEvent_GetIDsOfNames,
4545 MediaEvent_GetEventHandle,
4546 MediaEvent_GetEvent,
4547 MediaEvent_WaitForCompletion,
4548 MediaEvent_CancelDefaultHandling,
4549 MediaEvent_RestoreDefaultHandling,
4550 MediaEvent_FreeEventParams,
4551 MediaEvent_SetNotifyWindow,
4552 MediaEvent_SetNotifyFlags,
4553 MediaEvent_GetNotifyFlags
4557 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
4559 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4561 return Filtergraph_QueryInterface(This, riid, ppv);
4564 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
4566 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4568 return Filtergraph_AddRef(This);
4571 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
4573 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4575 return Filtergraph_Release(This);
4578 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
4580 FIXME("(%p): stub\n", pClassID);
4585 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
4587 FIXME("(): stub\n");
4592 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
4594 FIXME("(): stub\n");
4599 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
4601 FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart));
4606 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
4608 FIXME("(%d, %p): stub\n", dwMsTimeout, pState);
4613 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
4615 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4619 TRACE("(%p/%p)->(%p)\n", iface, This, pClock);
4621 EnterCriticalSection(&This->cs);
4623 for (i = 0;i < This->nFilters;i++)
4625 hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
4633 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
4638 IReferenceClock_Release(This->refClock);
4639 This->refClock = pClock;
4641 IReferenceClock_AddRef(This->refClock);
4643 if (This->HandleEcClockChanged)
4645 IMediaEventSink *pEventSink;
4648 eshr = IMediaFilter_QueryInterface(iface, &IID_IMediaEventSink, (LPVOID)&pEventSink);
4649 if (SUCCEEDED(eshr))
4651 IMediaEventSink_Notify(pEventSink, EC_CLOCK_CHANGED, 0, 0);
4652 IMediaEventSink_Release(pEventSink);
4657 LeaveCriticalSection(&This->cs);
4662 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
4664 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4666 TRACE("(%p/%p)->(%p)\n", iface, This, ppClock);
4671 EnterCriticalSection(&This->cs);
4673 *ppClock = This->refClock;
4675 IReferenceClock_AddRef(*ppClock);
4677 LeaveCriticalSection(&This->cs);
4682 static const IMediaFilterVtbl IMediaFilter_VTable =
4684 MediaFilter_QueryInterface,
4686 MediaFilter_Release,
4687 MediaFilter_GetClassID,
4691 MediaFilter_GetState,
4692 MediaFilter_SetSyncSource,
4693 MediaFilter_GetSyncSource
4696 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
4698 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4700 return Filtergraph_QueryInterface(This, riid, ppv);
4703 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
4705 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4707 return Filtergraph_AddRef(This);
4710 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
4712 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4714 return Filtergraph_Release(This);
4717 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
4719 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4722 TRACE("(%p/%p)->(%ld, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
4724 /* We need thread safety here, let's use the events queue's one */
4725 EnterCriticalSection(&This->evqueue.msg_crst);
4727 if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
4729 TRACE("Process EC_COMPLETE notification\n");
4730 if (++This->EcCompleteCount == This->nRenderers)
4732 evt.lEventCode = EC_COMPLETE;
4735 TRACE("Send EC_COMPLETE to app\n");
4736 EventsQueue_PutEvent(&This->evqueue, &evt);
4737 if (!This->notif.disabled && This->notif.hWnd)
4739 TRACE("Send Window message\n");
4740 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4742 This->CompletionStatus = EC_COMPLETE;
4743 SetEvent(This->hEventCompletion);
4746 else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
4748 /* FIXME: Not handled yet */
4752 evt.lEventCode = EventCode;
4753 evt.lParam1 = EventParam1;
4754 evt.lParam2 = EventParam2;
4755 EventsQueue_PutEvent(&This->evqueue, &evt);
4756 if (!This->notif.disabled && This->notif.hWnd)
4757 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4760 LeaveCriticalSection(&This->evqueue.msg_crst);
4764 static const IMediaEventSinkVtbl IMediaEventSink_VTable =
4766 MediaEventSink_QueryInterface,
4767 MediaEventSink_AddRef,
4768 MediaEventSink_Release,
4769 MediaEventSink_Notify
4772 static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv)
4774 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4776 return Filtergraph_QueryInterface(This, riid, ppv);
4779 static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface)
4781 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4783 return Filtergraph_AddRef(This);
4786 static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface)
4788 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4790 return Filtergraph_Release(This);
4793 static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface,
4796 const AM_MEDIA_TYPE* pmtFirstConnection,
4797 IBaseFilter* pUsingFilter,
4801 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4803 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags);
4808 static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface,
4809 IGraphConfigCallback* pCallback,
4814 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4816 FIXME("(%p)->(%p, %p, %x, %p): stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent);
4821 static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface,
4822 IBaseFilter* pFilter)
4824 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4826 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4831 static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface,
4832 IEnumFilters** pEnum)
4834 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4836 FIXME("(%p)->(%p): stub!\n", This, pEnum);
4841 static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface,
4842 IBaseFilter* pFilter)
4844 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4846 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4851 static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface,
4852 REFERENCE_TIME* prtStart)
4854 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4856 FIXME("(%p)->(%p): stub!\n", This, prtStart);
4861 static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface,
4863 IPinConnection* pConnection,
4866 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4868 FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort);
4873 static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface,
4874 IBaseFilter* pFilter,
4877 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4879 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4884 static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface,
4885 IBaseFilter* pFilter,
4888 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4890 FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags);
4895 static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface,
4896 IBaseFilter* pFilter,
4899 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4901 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4906 static const IGraphConfigVtbl IGraphConfig_VTable =
4908 GraphConfig_QueryInterface,
4910 GraphConfig_Release,
4911 GraphConfig_Reconnect,
4912 GraphConfig_Reconfigure,
4913 GraphConfig_AddFilterToCache,
4914 GraphConfig_EnumCacheFilter,
4915 GraphConfig_RemoveFilterFromCache,
4916 GraphConfig_GetStartTime,
4917 GraphConfig_PushThroughData,
4918 GraphConfig_SetFilterFlags,
4919 GraphConfig_GetFilterFlags,
4920 GraphConfig_RemoveFilterEx
4923 static const IUnknownVtbl IInner_VTable =
4925 FilterGraphInner_QueryInterface,
4926 FilterGraphInner_AddRef,
4927 FilterGraphInner_Release
4930 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
4933 if (This->bAggregatable)
4934 This->bUnkOuterValid = TRUE;
4936 if (This->pUnkOuter)
4938 if (This->bAggregatable)
4939 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
4941 if (IsEqualIID(riid, &IID_IUnknown))
4945 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
4946 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
4947 IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
4948 This->bAggregatable = TRUE;
4953 return E_NOINTERFACE;
4956 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
4959 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This) {
4960 if (This->pUnkOuter && This->bUnkOuterValid)
4961 return IUnknown_AddRef(This->pUnkOuter);
4962 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
4965 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This) {
4966 if (This->pUnkOuter && This->bUnkOuterValid)
4967 return IUnknown_Release(This->pUnkOuter);
4968 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
4971 /* This is the only function that actually creates a FilterGraph class... */
4972 HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
4974 IFilterGraphImpl *fimpl;
4977 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
4981 fimpl = CoTaskMemAlloc(sizeof(*fimpl));
4982 fimpl->pUnkOuter = pUnkOuter;
4983 fimpl->bUnkOuterValid = FALSE;
4984 fimpl->bAggregatable = FALSE;
4985 fimpl->IInner_vtbl = &IInner_VTable;
4986 fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
4987 fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
4988 fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
4989 fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
4990 fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
4991 fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
4992 fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
4993 fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
4994 fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
4995 fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable;
4996 fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable;
4998 fimpl->ppFiltersInGraph = NULL;
4999 fimpl->pFilterNames = NULL;
5000 fimpl->nFilters = 0;
5001 fimpl->filterCapacity = 0;
5002 fimpl->nameIndex = 1;
5003 fimpl->refClock = NULL;
5004 fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
5005 fimpl->HandleEcComplete = TRUE;
5006 fimpl->HandleEcRepaint = TRUE;
5007 fimpl->HandleEcClockChanged = TRUE;
5008 fimpl->notif.hWnd = 0;
5009 fimpl->notif.disabled = FALSE;
5010 fimpl->nRenderers = 0;
5011 fimpl->EcCompleteCount = 0;
5012 fimpl->state = State_Stopped;
5013 EventsQueue_Init(&fimpl->evqueue);
5014 InitializeCriticalSection(&fimpl->cs);
5015 fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
5016 fimpl->nItfCacheEntries = 0;
5017 memcpy(&fimpl->timeformatseek, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
5018 fimpl->start_time = fimpl->position = 0;
5020 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
5022 ERR("Unable to create filter mapper (%x)\n", hr);
5025 IFilterGraph2_SetDefaultSyncSource((IFilterGraph2*)fimpl);
5031 HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj)
5033 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
5034 return FilterGraph_create(pUnkOuter, ppObj);