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
35 #include "wine/debug.h"
36 #include "quartz_private.h"
42 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
48 HWND hWnd; /* Target window */
49 long msg; /* User window message */
50 long instance; /* User data */
51 int disabled; /* Disabled messages posting */
55 long lEventCode; /* Event code */
56 LONG_PTR lParam1; /* Param1 */
57 LONG_PTR lParam2; /* Param2 */
60 /* messages ring implementation for queuing events (taken from winmm) */
61 #define EVENTS_RING_BUFFER_INCREMENT 64
67 CRITICAL_SECTION msg_crst;
68 HANDLE msg_event; /* Signaled for no empty queue */
71 static int EventsQueue_Init(EventsQueue* omr)
75 omr->msg_event = CreateEventW(NULL, TRUE, FALSE, NULL);
76 omr->ring_buffer_size = EVENTS_RING_BUFFER_INCREMENT;
77 omr->messages = CoTaskMemAlloc(omr->ring_buffer_size * sizeof(Event));
78 ZeroMemory(omr->messages, omr->ring_buffer_size * sizeof(Event));
80 InitializeCriticalSection(&omr->msg_crst);
81 omr->msg_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": EventsQueue.msg_crst");
85 static int EventsQueue_Destroy(EventsQueue* omr)
87 CloseHandle(omr->msg_event);
88 CoTaskMemFree(omr->messages);
89 omr->msg_crst.DebugInfo->Spare[0] = 0;
90 DeleteCriticalSection(&omr->msg_crst);
94 static int EventsQueue_PutEvent(EventsQueue* omr, const Event* evt)
96 EnterCriticalSection(&omr->msg_crst);
97 if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size)))
99 int old_ring_buffer_size = omr->ring_buffer_size;
100 omr->ring_buffer_size += EVENTS_RING_BUFFER_INCREMENT;
101 TRACE("omr->ring_buffer_size=%d\n",omr->ring_buffer_size);
102 omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(Event));
103 /* Now we need to rearrange the ring buffer so that the new
104 buffers just allocated are in between omr->msg_tosave and
107 if (omr->msg_tosave < omr->msg_toget)
109 memmove(&(omr->messages[omr->msg_toget + EVENTS_RING_BUFFER_INCREMENT]),
110 &(omr->messages[omr->msg_toget]),
111 sizeof(Event)*(old_ring_buffer_size - omr->msg_toget)
113 omr->msg_toget += EVENTS_RING_BUFFER_INCREMENT;
116 omr->messages[omr->msg_tosave] = *evt;
117 SetEvent(omr->msg_event);
118 omr->msg_tosave = (omr->msg_tosave + 1) % omr->ring_buffer_size;
119 LeaveCriticalSection(&omr->msg_crst);
123 static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut)
125 if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0)
128 EnterCriticalSection(&omr->msg_crst);
130 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
132 LeaveCriticalSection(&omr->msg_crst);
136 *evt = omr->messages[omr->msg_toget];
137 omr->msg_toget = (omr->msg_toget + 1) % omr->ring_buffer_size;
139 /* Mark the buffer as empty if needed */
140 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
141 ResetEvent(omr->msg_event);
143 LeaveCriticalSection(&omr->msg_crst);
147 #define MAX_ITF_CACHE_ENTRIES 3
148 typedef struct _ITF_CACHE_ENTRY {
154 typedef struct _IFilterGraphImpl {
155 const IFilterGraph2Vtbl *IFilterGraph2_vtbl;
156 const IMediaControlVtbl *IMediaControl_vtbl;
157 const IMediaSeekingVtbl *IMediaSeeking_vtbl;
158 const IBasicAudioVtbl *IBasicAudio_vtbl;
159 const IBasicVideo2Vtbl *IBasicVideo_vtbl;
160 const IVideoWindowVtbl *IVideoWindow_vtbl;
161 const IMediaEventExVtbl *IMediaEventEx_vtbl;
162 const IMediaFilterVtbl *IMediaFilter_vtbl;
163 const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
164 const IGraphConfigVtbl *IGraphConfig_vtbl;
165 const IMediaPositionVtbl *IMediaPosition_vtbl;
166 const IUnknownVtbl * IInner_vtbl;
167 /* IAMGraphStreams */
173 /* IRegisterServiceProvider */
174 /* IResourceMananger */
175 /* IServiceProvider */
176 /* IVideoFrameStep */
179 IFilterMapper2 * pFilterMapper2;
180 IBaseFilter ** ppFiltersInGraph;
181 LPWSTR * pFilterNames;
185 IReferenceClock *refClock;
187 HANDLE hEventCompletion;
188 int CompletionStatus;
192 int HandleEcComplete;
194 int HandleEcClockChanged;
197 ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
198 int nItfCacheEntries;
199 IUnknown * pUnkOuter;
205 LONGLONG stop_position;
208 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
209 REFIID riid, LPVOID * ppv);
210 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This);
211 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This);
213 static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface,
216 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
217 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
219 if (This->bAggregatable)
220 This->bUnkOuterValid = TRUE;
222 if (IsEqualGUID(&IID_IUnknown, riid)) {
223 *ppvObj = &(This->IInner_vtbl);
224 TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
225 } else if (IsEqualGUID(&IID_IFilterGraph, riid) ||
226 IsEqualGUID(&IID_IFilterGraph2, riid) ||
227 IsEqualGUID(&IID_IGraphBuilder, riid)) {
228 *ppvObj = &(This->IFilterGraph2_vtbl);
229 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj);
230 } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
231 *ppvObj = &(This->IMediaControl_vtbl);
232 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj);
233 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
234 *ppvObj = &(This->IMediaSeeking_vtbl);
235 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
236 } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
237 *ppvObj = &(This->IBasicAudio_vtbl);
238 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj);
239 } else if (IsEqualGUID(&IID_IBasicVideo, riid) ||
240 IsEqualGUID(&IID_IBasicVideo2, riid)) {
241 *ppvObj = &(This->IBasicVideo_vtbl);
242 TRACE(" returning IBasicVideo2 interface (%p)\n", *ppvObj);
243 } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
244 *ppvObj = &(This->IVideoWindow_vtbl);
245 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj);
246 } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
247 IsEqualGUID(&IID_IMediaEventEx, riid)) {
248 *ppvObj = &(This->IMediaEventEx_vtbl);
249 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
250 } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
251 IsEqualGUID(&IID_IPersist, riid)) {
252 *ppvObj = &(This->IMediaFilter_vtbl);
253 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj);
254 } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
255 *ppvObj = &(This->IMediaEventSink_vtbl);
256 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj);
257 } else if (IsEqualGUID(&IID_IGraphConfig, riid)) {
258 *ppvObj = &(This->IGraphConfig_vtbl);
259 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj);
260 } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
261 *ppvObj = &(This->IMediaPosition_vtbl);
262 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj);
265 FIXME("unknown interface %s\n", debugstr_guid(riid));
266 return E_NOINTERFACE;
269 IUnknown_AddRef((IUnknown *)(*ppvObj));
273 static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) {
274 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
275 ULONG ref = InterlockedIncrement(&This->ref);
277 TRACE("(%p)->(): new ref = %d\n", This, ref);
282 static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface)
284 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
285 ULONG ref = InterlockedDecrement(&This->ref);
287 TRACE("(%p)->(): new ref = %d\n", This, ref);
292 IMediaControl_Stop((IMediaControl*)&(This->IMediaControl_vtbl));
294 while (This->nFilters)
295 IFilterGraph2_RemoveFilter((IFilterGraph2*)This, This->ppFiltersInGraph[0]);
298 IReferenceClock_Release(This->refClock);
300 for (i = 0; i < This->nItfCacheEntries; i++)
302 if (This->ItfCacheEntries[i].iface)
303 IUnknown_Release(This->ItfCacheEntries[i].iface);
305 IFilterMapper2_Release(This->pFilterMapper2);
306 CloseHandle(This->hEventCompletion);
307 EventsQueue_Destroy(&This->evqueue);
308 This->cs.DebugInfo->Spare[0] = 0;
309 DeleteCriticalSection(&This->cs);
310 CoTaskMemFree(This->ppFiltersInGraph);
311 CoTaskMemFree(This->pFilterNames);
318 /*** IUnknown methods ***/
319 static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface,
322 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
324 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
325 return Filtergraph_QueryInterface(This, riid, ppvObj);
328 static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) {
329 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
331 TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
333 return Filtergraph_AddRef(This);
336 static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) {
337 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
339 TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
341 return Filtergraph_Release(This);
344 /*** IFilterGraph methods ***/
345 static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
346 IBaseFilter *pFilter,
348 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
351 WCHAR* wszFilterName = NULL;
352 int duplicate_name = FALSE;
354 TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
359 wszFilterName = CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
363 /* Check if name already exists */
364 for(i = 0; i < This->nFilters; i++)
365 if (!strcmpW(This->pFilterNames[i], pName))
367 duplicate_name = TRUE;
372 /* If no name given or name already existing, generate one */
373 if (!pName || duplicate_name)
375 static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
376 static const WCHAR wszFmt2[] = {'%','0','4','d',0};
378 for (j = 0; j < 10000 ; j++)
382 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
384 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
385 TRACE("Generated name %s\n", debugstr_w(wszFilterName));
387 /* Check if the generated name already exists */
388 for(i = 0; i < This->nFilters; i++)
389 if (!strcmpW(This->pFilterNames[i], wszFilterName))
392 /* Compute next index and exit if generated name is suitable */
393 if (This->nameIndex++ == 10000)
395 if (i == This->nFilters)
398 /* Unable to find a suitable name */
401 CoTaskMemFree(wszFilterName);
402 return VFW_E_DUPLICATE_NAME;
406 memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
408 if (This->nFilters + 1 > This->filterCapacity)
410 int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
411 IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
412 LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
413 memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
414 memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
415 if (This->filterCapacity)
417 CoTaskMemFree(This->ppFiltersInGraph);
418 CoTaskMemFree(This->pFilterNames);
420 This->ppFiltersInGraph = ppNewFilters;
421 This->pFilterNames = pNewNames;
422 This->filterCapacity = newCapacity;
425 hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
429 IBaseFilter_AddRef(pFilter);
430 This->ppFiltersInGraph[This->nFilters] = pFilter;
431 This->pFilterNames[This->nFilters] = wszFilterName;
433 IBaseFilter_SetSyncSource(pFilter, This->refClock);
436 CoTaskMemFree(wszFilterName);
438 if (SUCCEEDED(hr) && duplicate_name)
439 return VFW_S_DUPLICATE_NAME;
444 static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *pFilter)
446 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
450 TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
452 /* FIXME: check graph is stopped */
454 for (i = 0; i < This->nFilters; i++)
456 if (This->ppFiltersInGraph[i] == pFilter)
458 IEnumPins *penumpins = NULL;
461 TRACE("Removing filter %s\n", debugstr_w(This->pFilterNames[i]));
462 IBaseFilter_GetState(pFilter, 0, &state);
463 if (state == State_Running)
464 IBaseFilter_Pause(pFilter);
465 if (state != State_Stopped)
466 IBaseFilter_Stop(pFilter);
468 hr = IBaseFilter_EnumPins(pFilter, &penumpins);
471 while(IEnumPins_Next(penumpins, 1, &ppin, NULL) == S_OK)
475 IPin_ConnectedTo(ppin, &victim);
478 h = IPin_Disconnect(victim);
479 TRACE("Disconnect other side: %08x\n", h);
480 if (h == VFW_E_NOT_STOPPED)
483 IPin_QueryPinInfo(victim, &pinfo);
485 IBaseFilter_GetState(pinfo.pFilter, 0, &state);
486 if (state == State_Running)
487 IBaseFilter_Pause(pinfo.pFilter);
488 IBaseFilter_Stop(pinfo.pFilter);
489 IBaseFilter_Release(pinfo.pFilter);
490 h = IPin_Disconnect(victim);
491 TRACE("Disconnect retry: %08x\n", h);
493 IPin_Release(victim);
495 h = IPin_Disconnect(ppin);
496 TRACE("Disconnect 2: %08x\n", h);
498 IEnumPins_Release(penumpins);
501 hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
504 IBaseFilter_SetSyncSource(pFilter, NULL);
505 IBaseFilter_Release(pFilter);
506 CoTaskMemFree(This->pFilterNames[i]);
507 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
508 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
510 /* Invalidate interfaces in the cache */
511 for (i = 0; i < This->nItfCacheEntries; i++)
512 if (pFilter == This->ItfCacheEntries[i].filter)
514 IUnknown_Release(This->ItfCacheEntries[i].iface);
515 This->ItfCacheEntries[i].iface = NULL;
516 This->ItfCacheEntries[i].filter = NULL;
524 return hr; /* FIXME: check this error code */
527 static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface,
528 IEnumFilters **ppEnum) {
529 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
531 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
533 return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
536 static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface,
538 IBaseFilter **ppFilter) {
539 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
542 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
547 for (i = 0; i < This->nFilters; i++)
549 if (!strcmpW(pName, This->pFilterNames[i]))
551 *ppFilter = This->ppFiltersInGraph[i];
552 IBaseFilter_AddRef(*ppFilter);
558 return VFW_E_NOT_FOUND;
561 /* Don't allow a circular connection to form, return VFW_E_CIRCULAR_GRAPH if this would be the case.
562 * A circular connection will be formed if from the filter of the output pin, the input pin can be reached
564 static HRESULT WINAPI CheckCircularConnection(IFilterGraphImpl *This, IPin *out, IPin *in)
568 PIN_INFO info_out, info_in;
570 hr = IPin_QueryPinInfo(out, &info_out);
573 if (info_out.dir != PINDIR_OUTPUT)
575 IBaseFilter_Release(info_out.pFilter);
579 hr = IPin_QueryPinInfo(in, &info_in);
581 IBaseFilter_Release(info_in.pFilter);
584 if (info_in.dir != PINDIR_INPUT)
590 if (info_out.pFilter == info_in.pFilter)
591 hr = VFW_E_CIRCULAR_GRAPH;
597 hr = IBaseFilter_EnumPins(info_out.pFilter, &enumpins);
601 IEnumPins_Reset(enumpins);
602 while ((hr = IEnumPins_Next(enumpins, 1, &test, NULL)) == S_OK)
604 PIN_DIRECTION dir = PINDIR_OUTPUT;
605 IPin_QueryDirection(test, &dir);
606 if (dir == PINDIR_INPUT)
609 IPin_ConnectedTo(test, &victim);
612 hr = CheckCircularConnection(This, victim, in);
613 IPin_Release(victim);
623 IEnumPins_Release(enumpins);
627 IBaseFilter_Release(info_out.pFilter);
629 ERR("Checking filtergraph returned %08x, something's not right!\n", hr);
632 /* Debugging filtergraphs not enabled */
638 /* NOTE: despite the implication, it doesn't matter which
639 * way round you put in the input and output pins */
640 static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface,
643 const AM_MEDIA_TYPE *pmt) {
647 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
649 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
651 /* FIXME: check pins are in graph */
653 if (TRACE_ON(quartz))
657 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
661 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
662 IBaseFilter_Release(PinInfo.pFilter);
664 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
668 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
669 IBaseFilter_Release(PinInfo.pFilter);
672 hr = IPin_QueryDirection(ppinIn, &dir);
675 if (dir == PINDIR_INPUT)
677 hr = CheckCircularConnection(This, ppinOut, ppinIn);
679 hr = IPin_Connect(ppinOut, ppinIn, pmt);
683 hr = CheckCircularConnection(This, ppinIn, ppinOut);
685 hr = IPin_Connect(ppinIn, ppinOut, pmt);
692 static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface,
694 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
695 IPin *pConnectedTo = NULL;
697 PIN_DIRECTION pindir;
699 IPin_QueryDirection(ppin, &pindir);
700 hr = IPin_ConnectedTo(ppin, &pConnectedTo);
702 TRACE("Querying connected to failed: %x\n", hr);
705 IPin_Disconnect(ppin);
706 IPin_Disconnect(pConnectedTo);
707 if (pindir == PINDIR_INPUT)
708 hr = IPin_Connect(pConnectedTo, ppin, NULL);
710 hr = IPin_Connect(ppin, pConnectedTo, NULL);
711 IPin_Release(pConnectedTo);
713 ERR("Reconnecting pins failed, pins are not connected now..\n");
714 TRACE("(%p->%p) -- %p %p -> %x\n", iface, This, ppin, pConnectedTo, hr);
718 static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface, IPin *ppin)
720 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
722 TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
724 return IPin_Disconnect(ppin);
727 static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) {
728 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
729 IReferenceClock *pClock = NULL;
732 TRACE("(%p/%p)->() semi-stub\n", iface, This);
734 hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&pClock);
738 hr = IMediaFilter_SetSyncSource((IMediaFilter*)&(This->IMediaFilter_vtbl), pClock);
739 IReferenceClock_Release(pClock);
745 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
747 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
748 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
749 IPropertyBag * pPropBagCat = NULL;
753 V_VT(pvar) = VT_BSTR;
755 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
758 hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
761 hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
764 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
767 TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
770 IPropertyBag_Release(pPropBagCat);
775 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPin*** pppins, ULONG* pnb)
780 TRACE("(%p, %p, %p, %p)\n", pfilter, pinputpin, pppins, pnb);
781 hr = IPin_QueryInternalConnections(pinputpin, NULL, &nb);
784 } else if (hr == S_FALSE) {
785 *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
786 hr = IPin_QueryInternalConnections(pinputpin, *pppins, &nb);
788 ERR("Error (%x)\n", hr);
790 } else if (hr == E_NOTIMPL) {
791 /* Input connected to all outputs */
792 IEnumPins* penumpins;
795 TRACE("E_NOTIMPL\n");
796 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
798 ERR("filter Enumpins failed (%x)\n", hr);
802 /* Count output pins */
803 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
804 PIN_DIRECTION pindir;
805 IPin_QueryDirection(ppin, &pindir);
806 if (pindir == PINDIR_OUTPUT)
810 *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
811 /* Retrieve output pins */
812 IEnumPins_Reset(penumpins);
814 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
815 PIN_DIRECTION pindir;
816 IPin_QueryDirection(ppin, &pindir);
817 if (pindir == PINDIR_OUTPUT)
818 (*pppins)[i++] = ppin;
822 IEnumPins_Release(penumpins);
825 ERR("Next failed (%x)\n", hr);
828 } else if (FAILED(hr)) {
829 ERR("Cannot get internal connection (%x)\n", hr);
837 /*** IGraphBuilder methods ***/
838 static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, IPin *ppinIn)
840 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
843 IEnumMediaTypes* penummt;
845 IEnumPins* penumpins;
846 IEnumMoniker* pEnumMoniker;
855 TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
857 if (TRACE_ON(quartz))
859 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
863 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
864 IBaseFilter_Release(PinInfo.pFilter);
866 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
870 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
871 IBaseFilter_Release(PinInfo.pFilter);
874 hr = IPin_QueryDirection(ppinOut, &dir);
878 if (dir == PINDIR_INPUT)
887 hr = CheckCircularConnection(This, ppinOut, ppinIn);
891 /* Try direct connection first */
892 hr = IPin_Connect(ppinOut, ppinIn, NULL);
896 TRACE("Direct connection failed, trying to render using extra filters\n");
898 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
902 hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
903 IBaseFilter_Release(PinInfo.pFilter);
907 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
908 * filter to the minor mediatype of input pin of the renderer */
909 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
911 WARN("EnumMediaTypes (%x)\n", hr);
915 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
917 WARN("IEnumMediaTypes_Next (%x)\n", hr);
923 WARN("No media type found!\n");
926 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
927 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
929 /* Try to find a suitable filter that can connect to the pin to render */
930 tab[0] = mt->majortype;
931 tab[1] = mt->subtype;
932 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
934 WARN("Unable to enum filters (%x)\n", hr);
938 hr = VFW_E_CANNOT_RENDER;
939 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
944 IPin* ppinfilter = NULL;
945 IBaseFilter* pfilter = NULL;
947 hr = GetFilterInfo(pMoniker, &clsid, &var);
948 IMoniker_Release(pMoniker);
950 WARN("Unable to retrieve filter info (%x)\n", hr);
954 if (IsEqualGUID(&clsid, &FilterCLSID)) {
955 /* Skip filter (same as the one the output pin belongs to) */
959 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
961 WARN("Unable to create filter (%x), trying next one\n", hr);
965 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
967 WARN("Unable to add filter (%x)\n", hr);
968 IBaseFilter_Release(pfilter);
973 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
975 WARN("Enumpins (%x)\n", hr);
979 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
980 IEnumPins_Release(penumpins);
983 WARN("Obtaining next pin: (%x)\n", hr);
987 WARN("Cannot use this filter: no pins\n");
991 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
993 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
996 TRACE("Successfully connected to filter, follow chain...\n");
998 /* Render all output pins of the filter by calling IFilterGraph2_Connect on each of them */
999 hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
1001 if (SUCCEEDED(hr)) {
1004 IPin_Disconnect(ppinfilter);
1005 IPin_Disconnect(ppinOut);
1008 TRACE("pins to consider: %d\n", nb);
1009 for(i = 0; i < nb; i++)
1011 LPWSTR pinname = NULL;
1013 TRACE("Processing pin %d\n", i);
1015 hr = IPin_QueryId(ppins[i], &pinname);
1018 if (pinname[0] == '~')
1020 TRACE("Pinname=%s, skipping\n", debugstr_w(pinname));
1024 hr = IFilterGraph2_Connect(iface, ppins[i], ppinIn);
1025 CoTaskMemFree(pinname);
1029 TRACE("Cannot connect pin %p (%x)\n", ppinfilter, hr);
1031 IPin_Release(ppins[i]);
1032 if (SUCCEEDED(hr)) break;
1034 while (++i < nb) IPin_Release(ppins[i]);
1035 CoTaskMemFree(ppins);
1036 IPin_Release(ppinfilter);
1037 IBaseFilter_Release(pfilter);
1040 IPin_Disconnect(ppinfilter);
1041 IPin_Disconnect(ppinOut);
1042 IFilterGraph2_RemoveFilter(iface, pfilter);
1049 if (ppinfilter) IPin_Release(ppinfilter);
1051 IFilterGraph2_RemoveFilter(iface, pfilter);
1052 IBaseFilter_Release(pfilter);
1056 IEnumMediaTypes_Release(penummt);
1057 DeleteMediaType(mt);
1059 TRACE("--> %08x\n", hr);
1060 return SUCCEEDED(hr) ? S_OK : hr;
1063 static HRESULT WINAPI FilterGraph2_RenderRecurse(IFilterGraphImpl *This, IPin *ppinOut)
1065 /* This pin has been connected now, try to call render on all pins that aren't connected */
1068 IEnumPins *enumpins = NULL;
1069 BOOL renderany = FALSE;
1070 BOOL renderall = TRUE;
1072 IPin_QueryPinInfo(ppinOut, &info);
1074 IBaseFilter_EnumPins(info.pFilter, &enumpins);
1075 /* Don't need to hold a reference, IEnumPins does */
1076 IBaseFilter_Release(info.pFilter);
1078 IEnumPins_Reset(enumpins);
1079 while (IEnumPins_Next(enumpins, 1, &to, NULL) == S_OK)
1081 PIN_DIRECTION dir = PINDIR_INPUT;
1083 IPin_QueryDirection(to, &dir);
1085 if (dir == PINDIR_OUTPUT)
1089 IPin_ConnectedTo(to, &out);
1093 hr = IFilterGraph2_Render((IFilterGraph2 *)&This->IFilterGraph2_vtbl, to);
1106 IEnumPins_Release(enumpins);
1112 return VFW_S_PARTIAL_RENDER;
1114 return VFW_E_CANNOT_RENDER;
1117 /* Ogg hates me if I create a direct rendering method
1119 * It can only connect to a pin properly once, so use a recursive method that does
1121 * +----+ --- (PIN 1) (Render is called on this pin)
1123 * +----+ --- (PIN 2)
1125 * Enumerate possible renderers that EXACTLY match the requested type
1127 * If none is available, try to add intermediate filters that can connect to the input pin
1128 * then call Render on that intermediate pin's output pins
1129 * if it succeeds: Render returns success, if it doesn't, the intermediate filter is removed,
1130 * and another filter that can connect to the input pin is tried
1131 * if we run out of filters that can, give up and return VFW_E_CANNOT_RENDER
1132 * It's recursive, but fun!
1135 static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
1137 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1138 IEnumMediaTypes* penummt;
1143 IEnumMoniker* pEnumMoniker;
1151 TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
1153 if (TRACE_ON(quartz))
1157 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
1161 TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
1162 IBaseFilter_Release(PinInfo.pFilter);
1165 /* Try to find out if there is a renderer for the specified subtype already, and use that
1167 EnterCriticalSection(&This->cs);
1168 for (x = 0; x < This->nFilters; ++x)
1170 IEnumPins *enumpins = NULL;
1173 hr = IBaseFilter_EnumPins(This->ppFiltersInGraph[x], &enumpins);
1175 if (FAILED(hr) || !enumpins)
1178 IEnumPins_Reset(enumpins);
1179 while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK)
1182 PIN_DIRECTION dir = PINDIR_OUTPUT;
1184 IPin_QueryDirection(pin, &dir);
1185 if (dir != PINDIR_INPUT)
1190 IPin_ConnectedTo(pin, &to);
1194 hr = IPin_Connect(ppinOut, pin, NULL);
1197 TRACE("Connected succesfully %p/%p, %08x look if we should render more!\n", ppinOut, pin, hr);
1200 hr = FilterGraph2_RenderRecurse(This, pin);
1203 IPin_Disconnect(ppinOut);
1204 IPin_Disconnect(pin);
1207 IEnumPins_Release(enumpins);
1208 LeaveCriticalSection(&This->cs);
1211 WARN("Could not connect!\n");
1218 IEnumPins_Release(enumpins);
1221 LeaveCriticalSection(&This->cs);
1223 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
1225 WARN("EnumMediaTypes (%x)\n", hr);
1229 IEnumMediaTypes_Reset(penummt);
1231 /* Looks like no existing renderer of the kind exists
1232 * Try adding new ones
1234 tab[0] = tab[1] = GUID_NULL;
1235 while (SUCCEEDED(hr))
1237 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
1239 WARN("IEnumMediaTypes_Next (%x)\n", hr);
1242 if (!nbmt && !final)
1245 tab[0] = tab[1] = GUID_NULL;
1246 IEnumMediaTypes_Reset(penummt);
1251 hr = VFW_E_CANNOT_RENDER;
1256 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
1257 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
1259 /* Only enumerate once, this doesn't account for all previous ones, but this should be enough nonetheless */
1260 if (IsEqualIID(&tab[0], &mt->majortype) && IsEqualIID(&tab[0], &mt->majortype))
1262 DeleteMediaType(mt);
1266 /* Try to find a suitable renderer with the same media type */
1267 tab[0] = mt->majortype;
1268 tab[1] = mt->subtype;
1269 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, !final, FALSE, 0, NULL, NULL, NULL);
1272 WARN("Unable to enum filters (%x)\n", hr);
1278 while (IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1283 IBaseFilter* pfilter = NULL;
1284 IEnumPins* penumpins;
1287 hr = GetFilterInfo(pMoniker, &clsid, &var);
1288 IMoniker_Release(pMoniker);
1290 WARN("Unable to retrieve filter info (%x)\n", hr);
1294 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
1297 WARN("Unable to create filter (%x), trying next one\n", hr);
1301 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
1303 WARN("Unable to add filter (%x)\n", hr);
1304 IBaseFilter_Release(pfilter);
1309 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
1311 WARN("Splitter Enumpins (%x)\n", hr);
1314 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
1315 IEnumPins_Release(penumpins);
1317 WARN("Next (%x)\n", hr);
1326 /* Connect the pin to the "Renderer" */
1327 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
1328 IPin_Release(ppinfilter);
1331 WARN("Unable to connect %s to renderer (%x)\n", debugstr_w(V_UNION(&var, bstrVal)), hr);
1334 TRACE("Connected, recursing %s\n", debugstr_w(V_UNION(&var, bstrVal)));
1335 hr = FilterGraph2_RenderRecurse(This, ppinfilter);
1337 WARN("Unable to connect recursively (%x)\n", hr);
1340 IBaseFilter_Release(pfilter);
1345 IFilterGraph2_RemoveFilter(iface, pfilter);
1346 IBaseFilter_Release(pfilter);
1348 if (!FAILED(hr)) DebugBreak();
1352 DeleteMediaType(mt);
1358 IEnumMediaTypes_Release(penummt);
1362 static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface,
1363 LPCWSTR lpcwstrFile,
1364 LPCWSTR lpcwstrPlayList)
1366 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1367 static const WCHAR string[] = {'R','e','a','d','e','r',0};
1368 IBaseFilter* preader = NULL;
1369 IPin* ppinreader = NULL;
1370 IEnumPins* penumpins = NULL;
1372 BOOL partial = FALSE;
1373 HRESULT any = FALSE;
1375 TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
1377 if (lpcwstrPlayList != NULL)
1378 return E_INVALIDARG;
1380 hr = IFilterGraph2_AddSourceFilter(iface, lpcwstrFile, string, &preader);
1385 hr = IBaseFilter_EnumPins(preader, &penumpins);
1388 while (IEnumPins_Next(penumpins, 1, &ppinreader, NULL) == S_OK)
1392 IPin_QueryDirection(ppinreader, &dir);
1393 if (dir == PINDIR_OUTPUT)
1397 hr = IFilterGraph2_Render(iface, ppinreader);
1398 ERR("Render %08x\n", hr);
1400 for (i = 0; i < This->nFilters; ++i)
1401 FIXME("Filters in chain: %s\n", debugstr_w(This->pFilterNames[i]));
1408 IPin_Release(ppinreader);
1410 IEnumPins_Release(penumpins);
1413 hr = VFW_E_CANNOT_RENDER;
1415 hr = VFW_S_PARTIAL_RENDER;
1419 IBaseFilter_Release(preader);
1421 TRACE("--> %08x\n", hr);
1425 /* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */
1426 static HRESULT GetFileSourceFilter(LPCOLESTR pszFileName, IBaseFilter **filter)
1428 static const WCHAR wszReg[] = {'M','e','d','i','a',' ','T','y','p','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1433 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszReg, 0, KEY_READ, &extkey);
1434 hr = HRESULT_FROM_WIN32(lRet);
1438 static const WCHAR filtersource[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};
1439 WCHAR *ext = PathFindExtensionW(pszFileName);
1440 WCHAR clsid_key[39];
1442 DWORD size = sizeof(clsid_key);
1447 CloseHandle(extkey);
1451 lRet = RegOpenKeyExW(extkey, ext, 0, KEY_READ, &pathkey);
1452 hr = HRESULT_FROM_WIN32(lRet);
1453 CloseHandle(extkey);
1457 lRet = RegQueryValueExW(pathkey, filtersource, NULL, NULL, (LPBYTE)clsid_key, &size);
1458 hr = HRESULT_FROM_WIN32(lRet);
1459 CloseHandle(pathkey);
1463 CLSIDFromString(clsid_key, &clsid);
1465 TRACE("CLSID: %s\n", debugstr_guid(&clsid));
1466 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter);
1469 IFileSourceFilter *source = NULL;
1470 hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source);
1472 IFileSourceFilter_Release(source);
1474 IBaseFilter_Release(*filter);
1482 static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface,
1483 LPCWSTR lpcwstrFileName,
1484 LPCWSTR lpcwstrFilterName,
1485 IBaseFilter **ppFilter) {
1486 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1488 IBaseFilter* preader;
1489 IFileSourceFilter* pfile = NULL;
1493 TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
1495 /* Try from file name first, then fall back to default asynchronous reader */
1496 hr = GetFileSourceFilter(lpcwstrFileName, &preader);
1499 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
1501 ERR("Unable to create file source filter (%x)\n", hr);
1505 hr = IFilterGraph2_AddFilter(iface, preader, lpcwstrFilterName);
1507 ERR("Unable add filter (%x)\n", hr);
1508 IBaseFilter_Release(preader);
1512 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1514 ERR("Unable to get IFileSourceInterface (%x)\n", hr);
1518 /* Load the file in the file source filter */
1519 hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1521 ERR("Load (%x)\n", hr);
1525 IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1527 ERR("GetCurFile (%x)\n", hr);
1531 TRACE("File %s\n", debugstr_w(filename));
1532 TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1533 TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1536 *ppFilter = preader;
1537 IFileSourceFilter_Release(pfile);
1543 IFileSourceFilter_Release(pfile);
1544 IFilterGraph2_RemoveFilter(iface, preader);
1545 IBaseFilter_Release(preader);
1550 static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface,
1552 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1554 TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile);
1559 static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) {
1560 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1562 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1567 static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) {
1568 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1570 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1575 /*** IFilterGraph2 methods ***/
1576 static HRESULT WINAPI FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2 *iface,
1579 LPCWSTR lpcwstrFilterName,
1580 IBaseFilter **ppFilter) {
1581 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1583 TRACE("(%p/%p)->(%p %p %s %p): stub !!!\n", This, iface, pMoniker, pCtx, debugstr_w(lpcwstrFilterName), ppFilter);
1588 static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface,
1590 const AM_MEDIA_TYPE *pmt) {
1591 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1593 TRACE("(%p/%p)->(%p %p): stub !!!\n", This, iface, ppin, pmt);
1598 static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface,
1602 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1604 TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This, iface, pPinOut, dwFlags, pvContext);
1610 static const IFilterGraph2Vtbl IFilterGraph2_VTable =
1612 FilterGraph2_QueryInterface,
1613 FilterGraph2_AddRef,
1614 FilterGraph2_Release,
1615 FilterGraph2_AddFilter,
1616 FilterGraph2_RemoveFilter,
1617 FilterGraph2_EnumFilters,
1618 FilterGraph2_FindFilterByName,
1619 FilterGraph2_ConnectDirect,
1620 FilterGraph2_Reconnect,
1621 FilterGraph2_Disconnect,
1622 FilterGraph2_SetDefaultSyncSource,
1623 FilterGraph2_Connect,
1624 FilterGraph2_Render,
1625 FilterGraph2_RenderFile,
1626 FilterGraph2_AddSourceFilter,
1627 FilterGraph2_SetLogFile,
1629 FilterGraph2_ShouldOperationContinue,
1630 FilterGraph2_AddSourceFilterForMoniker,
1631 FilterGraph2_ReconnectEx,
1632 FilterGraph2_RenderEx
1635 /*** IUnknown methods ***/
1636 static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface,
1639 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1641 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1643 return Filtergraph_QueryInterface(This, riid, ppvObj);
1646 static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) {
1647 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1649 TRACE("(%p/%p)->()\n", This, iface);
1651 return Filtergraph_AddRef(This);
1654 static ULONG WINAPI MediaControl_Release(IMediaControl *iface) {
1655 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1657 TRACE("(%p/%p)->()\n", This, iface);
1659 return Filtergraph_Release(This);
1663 /*** IDispatch methods ***/
1664 static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface,
1666 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1668 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1673 static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface,
1676 ITypeInfo**ppTInfo) {
1677 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1679 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1684 static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface,
1690 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1692 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1697 static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
1698 DISPID dispIdMember,
1702 DISPPARAMS*pDispParams,
1704 EXCEPINFO*pExepInfo,
1706 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1708 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);
1713 typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *, DWORD_PTR data);
1715 static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter, DWORD_PTR data)
1724 TRACE("%p %p\n", pGraph, pOutputPin);
1725 PinInfo.pFilter = NULL;
1727 hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
1731 hr = IPin_QueryPinInfo(pInputPin, &PinInfo);
1733 hr = GetInternalConnections(PinInfo.pFilter, pInputPin, &ppPins, &nb);
1734 IPin_Release(pInputPin);
1741 TRACE("Reached a renderer\n");
1742 /* Count renderers for end of stream notification */
1743 pGraph->nRenderers++;
1747 for(i = 0; i < nb; i++)
1749 /* Explore the graph downstream from this pin
1750 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1751 * several input pins are connected to the same output (a MUX for instance). */
1752 ExploreGraph(pGraph, ppPins[i], FoundFilter, data);
1753 IPin_Release(ppPins[i]);
1756 CoTaskMemFree(ppPins);
1758 TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
1760 FoundFilter(PinInfo.pFilter, data);
1763 if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
1767 static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data)
1770 IReferenceClock *clock = NULL;
1772 IBaseFilter_GetSyncSource(pFilter, &clock);
1775 IReferenceClock_GetTime(clock, &time);
1781 IReferenceClock_Release(clock);
1784 return IBaseFilter_Run(pFilter, time);
1787 static HRESULT WINAPI SendPause(IBaseFilter *pFilter, DWORD_PTR data)
1789 return IBaseFilter_Pause(pFilter);
1792 static HRESULT WINAPI SendStop(IBaseFilter *pFilter, DWORD_PTR data)
1794 return IBaseFilter_Stop(pFilter);
1797 static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data)
1800 DWORD time_end = data;
1801 DWORD time_now = GetTickCount();
1804 if (time_end == INFINITE)
1808 else if (time_end > time_now)
1810 wait = time_end - time_now;
1815 return IBaseFilter_GetState(pFilter, wait, &state);
1819 static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter, DWORD_PTR data)
1821 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1823 IBaseFilter* pfilter;
1829 TRACE("(%p/%p)->()\n", This, iface);
1831 /* Explorer the graph from source filters to renderers, determine renderers
1832 * number and run filters from renderers to source filters */
1833 This->nRenderers = 0;
1834 ResetEvent(This->hEventCompletion);
1836 for(i = 0; i < This->nFilters; i++)
1839 pfilter = This->ppFiltersInGraph[i];
1840 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1843 ERR("Enum pins failed %x\n", hr);
1846 /* Check if it is a source filter */
1847 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1849 IPin_QueryDirection(pPin, &dir);
1851 if (dir == PINDIR_INPUT)
1859 TRACE("Found a source filter %p\n", pfilter);
1860 IEnumPins_Reset(pEnum);
1861 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1863 /* Explore the graph downstream from this pin */
1864 ExploreGraph(This, pPin, FoundFilter, data);
1867 FoundFilter(pfilter, data);
1869 IEnumPins_Release(pEnum);
1875 /*** IMediaControl methods ***/
1876 static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
1877 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1878 TRACE("(%p/%p)->()\n", This, iface);
1880 if (This->state == State_Running) return S_OK;
1882 EnterCriticalSection(&This->cs);
1883 if (This->state == State_Stopped)
1884 This->EcCompleteCount = 0;
1888 IReferenceClock_GetTime(This->refClock, &This->start_time);
1889 This->start_time += 500000;
1891 else This->position = This->start_time = 0;
1893 SendFilterMessage(iface, SendRun, 0);
1894 This->state = State_Running;
1895 LeaveCriticalSection(&This->cs);
1899 static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
1900 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1901 TRACE("(%p/%p)->()\n", This, iface);
1903 if (This->state == State_Paused) return S_OK;
1905 EnterCriticalSection(&This->cs);
1906 if (This->state == State_Stopped)
1907 This->EcCompleteCount = 0;
1909 if (This->state == State_Running && This->refClock)
1911 LONGLONG time = This->start_time;
1912 IReferenceClock_GetTime(This->refClock, &time);
1913 This->position += time - This->start_time;
1916 SendFilterMessage(iface, SendPause, 0);
1917 This->state = State_Paused;
1918 LeaveCriticalSection(&This->cs);
1922 static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
1923 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1924 TRACE("(%p/%p)->()\n", This, iface);
1926 if (This->state == State_Stopped) return S_OK;
1928 EnterCriticalSection(&This->cs);
1929 if (This->state == State_Running && This->refClock)
1931 LONGLONG time = This->start_time;
1932 IReferenceClock_GetTime(This->refClock, &time);
1933 This->position += time - This->start_time;
1936 if (This->state == State_Running) SendFilterMessage(iface, SendPause, 0);
1937 SendFilterMessage(iface, SendStop, 0);
1938 This->state = State_Stopped;
1939 LeaveCriticalSection(&This->cs);
1943 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
1945 OAFilterState *pfs) {
1946 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1949 TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pfs);
1954 EnterCriticalSection(&This->cs);
1959 end = GetTickCount() + msTimeout;
1961 else if (msTimeout < 0)
1970 SendFilterMessage(iface, SendGetState, end);
1972 LeaveCriticalSection(&This->cs);
1977 static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface,
1979 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1981 FIXME("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
1986 static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface,
1988 IDispatch **ppUnk) {
1989 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1991 FIXME("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
1996 static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface,
1997 IDispatch **ppUnk) {
1998 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2000 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
2005 static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
2006 IDispatch **ppUnk) {
2007 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2009 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
2014 static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) {
2015 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2017 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
2023 static const IMediaControlVtbl IMediaControl_VTable =
2025 MediaControl_QueryInterface,
2026 MediaControl_AddRef,
2027 MediaControl_Release,
2028 MediaControl_GetTypeInfoCount,
2029 MediaControl_GetTypeInfo,
2030 MediaControl_GetIDsOfNames,
2031 MediaControl_Invoke,
2035 MediaControl_GetState,
2036 MediaControl_RenderFile,
2037 MediaControl_AddSourceFilter,
2038 MediaControl_get_FilterCollection,
2039 MediaControl_get_RegFilterCollection,
2040 MediaControl_StopWhenReady
2044 /*** IUnknown methods ***/
2045 static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface,
2048 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2050 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2052 return Filtergraph_QueryInterface(This, riid, ppvObj);
2055 static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) {
2056 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2058 TRACE("(%p/%p)->()\n", This, iface);
2060 return Filtergraph_AddRef(This);
2063 static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
2064 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2066 TRACE("(%p/%p)->()\n", This, iface);
2068 return Filtergraph_Release(This);
2071 typedef HRESULT WINAPI (*fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DWORD_PTR arg);
2073 static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) {
2074 BOOL allnotimpl = TRUE;
2076 IBaseFilter* pfilter;
2078 HRESULT hr, hr_return = S_OK;
2083 TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg);
2084 /* Send a message to all renderers, they are responsible for broadcasting it further */
2086 for(i = 0; i < This->nFilters; i++)
2088 BOOL renderer = TRUE;
2089 pfilter = This->ppFiltersInGraph[i];
2090 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
2093 ERR("Enum pins failed %x\n", hr);
2096 /* Check if it is a source filter */
2097 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
2099 IPin_QueryDirection(pPin, &dir);
2101 if (dir != PINDIR_INPUT)
2107 IEnumPins_Release(pEnum);
2110 IMediaSeeking *seek = NULL;
2111 IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek);
2115 hr = FoundSeek(This, seek, arg);
2117 IMediaSeeking_Release(seek);
2118 if (hr_return != E_NOTIMPL)
2120 if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && !FAILED(hr_return)))
2130 static HRESULT WINAPI FoundCapabilities(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pcaps)
2135 hr = IMediaSeeking_GetCapabilities(seek, &caps);
2139 /* Only add common capabilities everything supports */
2140 *(DWORD*)pcaps &= caps;
2145 /*** IMediaSeeking methods ***/
2146 static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
2147 DWORD *pCapabilities) {
2148 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2150 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
2155 EnterCriticalSection(&This->cs);
2156 *pCapabilities = 0xffffffff;
2158 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
2159 LeaveCriticalSection(&This->cs);
2164 static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
2165 DWORD *pCapabilities) {
2166 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2169 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
2174 EnterCriticalSection(&This->cs);
2175 originalcaps = *pCapabilities;
2176 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
2177 LeaveCriticalSection(&This->cs);
2182 if (!*pCapabilities)
2184 if (*pCapabilities != originalcaps)
2189 static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface,
2190 const GUID *pFormat) {
2191 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2196 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
2198 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
2200 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
2207 static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface,
2209 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2214 FIXME("(%p/%p)->(%p): semi-stub !!!\n", This, iface, pFormat);
2215 memcpy(pFormat, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
2220 static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface,
2222 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2227 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
2228 memcpy(pFormat, &This->timeformatseek, sizeof(GUID));
2233 static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface,
2234 const GUID *pFormat) {
2235 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2237 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
2241 if (memcmp(pFormat, &This->timeformatseek, sizeof(GUID)))
2247 static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
2248 const GUID *pFormat) {
2249 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2254 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
2256 if (This->state != State_Stopped)
2257 return VFW_E_WRONG_STATE;
2259 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
2261 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
2262 return E_INVALIDARG;
2268 static HRESULT WINAPI FoundDuration(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pduration)
2271 LONGLONG duration = 0, *pdur = (LONGLONG*)pduration;
2273 hr = IMediaSeeking_GetDuration(seek, &duration);
2277 /* FIXME: Minimum or maximum duration? Assuming minimum */
2278 if (duration > 0 && *pdur < duration)
2284 static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
2285 LONGLONG *pDuration) {
2286 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2289 TRACE("(%p/%p)->(%p)\n", This, iface, pDuration);
2294 EnterCriticalSection(&This->cs);
2296 hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration);
2297 LeaveCriticalSection(&This->cs);
2299 TRACE("--->%08x\n", hr);
2303 static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
2305 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2308 TRACE("(%p/%p)->(%p)\n", This, iface, pStop);
2313 EnterCriticalSection(&This->cs);
2314 if (This->stop_position < 0)
2315 /* Stop position not set, use duration instead */
2316 hr = IMediaSeeking_GetDuration(iface, pStop);
2318 *pStop = This->stop_position;
2320 LeaveCriticalSection(&This->cs);
2325 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
2326 LONGLONG *pCurrent) {
2327 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2333 EnterCriticalSection(&This->cs);
2334 if (This->state == State_Running && This->refClock)
2336 IReferenceClock_GetTime(This->refClock, &time);
2338 time += This->position - This->start_time;
2339 if (time < This->position)
2340 time = This->position;
2344 *pCurrent = This->position;
2345 LeaveCriticalSection(&This->cs);
2347 TRACE("Time: %u.%03u\n", (DWORD)(*pCurrent / 10000000), (DWORD)((*pCurrent / 10000)%1000));
2352 static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface,
2354 const GUID *pTargetFormat,
2356 const GUID *pSourceFormat) {
2357 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2359 FIXME("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget,
2360 pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat);
2366 LONGLONG* current, *stop;
2367 DWORD curflags, stopflags;
2370 static HRESULT WINAPI found_setposition(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pargs)
2372 struct pos_args *args = (void*)pargs;
2374 return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags);
2377 static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface,
2379 DWORD dwCurrentFlags,
2381 DWORD dwStopFlags) {
2382 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2385 struct pos_args args;
2387 TRACE("(%p/%p)->(%p, %08x, %p, %08x)\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
2389 EnterCriticalSection(&This->cs);
2390 state = This->state;
2391 TRACE("State: %s\n", state == State_Running ? "Running" : (state == State_Paused ? "Paused" : (state == State_Stopped ? "Stopped" : "UNKNOWN")));
2393 if ((dwCurrentFlags & 0x7) == AM_SEEKING_AbsolutePositioning)
2395 This->position = *pCurrent;
2397 else if ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning)
2398 FIXME("Adjust method %x not handled yet!\n", dwCurrentFlags & 0x7);
2400 if ((dwStopFlags & 0x7) == AM_SEEKING_AbsolutePositioning)
2401 This->stop_position = *pStop;
2402 else if ((dwStopFlags & 0x7) != AM_SEEKING_NoPositioning)
2403 FIXME("Stop position not handled yet!\n");
2405 args.current = pCurrent;
2407 args.curflags = dwCurrentFlags;
2408 args.stopflags = dwStopFlags;
2409 hr = all_renderers_seek(This, found_setposition, (DWORD_PTR)&args);
2411 if (This->refClock && ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning))
2413 /* Update start time, prevents weird jumps */
2414 IReferenceClock_GetTime(This->refClock, &This->start_time);
2416 LeaveCriticalSection(&This->cs);
2421 static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
2424 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2427 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pCurrent, pStop);
2428 hr = IMediaSeeking_GetCurrentPosition(iface, pCurrent);
2430 hr = IMediaSeeking_GetStopPosition(iface, pStop);
2435 static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
2436 LONGLONG *pEarliest,
2437 LONGLONG *pLatest) {
2438 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2440 FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
2445 static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface,
2447 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2449 FIXME("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
2454 static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface,
2456 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2458 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
2463 static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface,
2464 LONGLONG *pllPreroll) {
2465 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2467 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
2473 static const IMediaSeekingVtbl IMediaSeeking_VTable =
2475 MediaSeeking_QueryInterface,
2476 MediaSeeking_AddRef,
2477 MediaSeeking_Release,
2478 MediaSeeking_GetCapabilities,
2479 MediaSeeking_CheckCapabilities,
2480 MediaSeeking_IsFormatSupported,
2481 MediaSeeking_QueryPreferredFormat,
2482 MediaSeeking_GetTimeFormat,
2483 MediaSeeking_IsUsingTimeFormat,
2484 MediaSeeking_SetTimeFormat,
2485 MediaSeeking_GetDuration,
2486 MediaSeeking_GetStopPosition,
2487 MediaSeeking_GetCurrentPosition,
2488 MediaSeeking_ConvertTimeFormat,
2489 MediaSeeking_SetPositions,
2490 MediaSeeking_GetPositions,
2491 MediaSeeking_GetAvailable,
2492 MediaSeeking_SetRate,
2493 MediaSeeking_GetRate,
2494 MediaSeeking_GetPreroll
2497 /*** IUnknown methods ***/
2498 static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID riid, void** ppvObj){
2499 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2501 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2503 return Filtergraph_QueryInterface(This, riid, ppvObj);
2506 static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface){
2507 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2509 TRACE("(%p/%p)->()\n", This, iface);
2511 return Filtergraph_AddRef(This);
2514 static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface){
2515 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
2517 TRACE("(%p/%p)->()\n", This, iface);
2519 return Filtergraph_Release(This);
2522 /*** IDispatch methods ***/
2523 static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){
2524 FIXME("(%p) stub!\n", iface);
2528 static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){
2529 FIXME("(%p) stub!\n", iface);
2533 static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){
2534 FIXME("(%p) stub!\n", iface);
2538 static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){
2539 FIXME("(%p) stub!\n", iface);
2543 /*** IMediaPosition methods ***/
2544 static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength){
2545 FIXME("(%p)->(%p) stub!\n", iface, plength);
2549 static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime){
2550 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2554 static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime){
2555 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2559 static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime){
2560 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2564 static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime){
2565 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2569 static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){
2570 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2574 static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){
2575 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2579 static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate){
2580 FIXME("(%p)->(%f) stub!\n", iface, dRate);
2584 static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate){
2585 FIXME("(%p)->(%p) stub!\n", iface, pdRate);
2589 static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){
2590 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward);
2594 static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){
2595 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward);
2600 static const IMediaPositionVtbl IMediaPosition_VTable =
2602 MediaPosition_QueryInterface,
2603 MediaPosition_AddRef,
2604 MediaPosition_Release,
2605 MediaPosition_GetTypeInfoCount,
2606 MediaPosition_GetTypeInfo,
2607 MediaPosition_GetIDsOfNames,
2608 MediaPosition_Invoke,
2609 MediaPosition_get_Duration,
2610 MediaPosition_put_CurrentPosition,
2611 MediaPosition_get_CurrentPosition,
2612 MediaPosition_get_StopTime,
2613 MediaPosition_put_StopTime,
2614 MediaPosition_get_PrerollTime,
2615 MediaPosition_put_PrerollTime,
2616 MediaPosition_put_Rate,
2617 MediaPosition_get_Rate,
2618 MediaPosition_CanSeekForward,
2619 MediaPosition_CanSeekBackward
2622 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
2624 HRESULT hr = E_NOINTERFACE;
2628 /* Check if the interface type is already registered */
2629 for (entry = 0; entry < pGraph->nItfCacheEntries; entry++)
2630 if (riid == pGraph->ItfCacheEntries[entry].riid)
2632 if (pGraph->ItfCacheEntries[entry].iface)
2634 /* Return the interface if available */
2635 *ppvObj = pGraph->ItfCacheEntries[entry].iface;
2641 if (entry >= MAX_ITF_CACHE_ENTRIES)
2643 FIXME("Not enough space to store interface in the cache\n");
2644 return E_OUTOFMEMORY;
2647 /* Find a filter supporting the requested interface */
2648 for (i = 0; i < pGraph->nFilters; i++)
2650 hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
2653 pGraph->ItfCacheEntries[entry].riid = riid;
2654 pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
2655 pGraph->ItfCacheEntries[entry].iface = (IUnknown*)*ppvObj;
2656 if (entry >= pGraph->nItfCacheEntries)
2657 pGraph->nItfCacheEntries++;
2660 if (hr != E_NOINTERFACE)
2667 /*** IUnknown methods ***/
2668 static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface,
2671 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2673 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2675 return Filtergraph_QueryInterface(This, riid, ppvObj);
2678 static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) {
2679 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2681 TRACE("(%p/%p)->()\n", This, iface);
2683 return Filtergraph_AddRef(This);
2686 static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) {
2687 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2689 TRACE("(%p/%p)->()\n", This, iface);
2691 return Filtergraph_Release(This);
2694 /*** IDispatch methods ***/
2695 static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface,
2697 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2698 IBasicAudio* pBasicAudio;
2701 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2703 EnterCriticalSection(&This->cs);
2705 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2708 hr = IBasicAudio_GetTypeInfoCount(pBasicAudio, pctinfo);
2710 LeaveCriticalSection(&This->cs);
2715 static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface,
2718 ITypeInfo**ppTInfo) {
2719 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2720 IBasicAudio* pBasicAudio;
2723 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2725 EnterCriticalSection(&This->cs);
2727 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2730 hr = IBasicAudio_GetTypeInfo(pBasicAudio, iTInfo, lcid, ppTInfo);
2732 LeaveCriticalSection(&This->cs);
2737 static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface,
2743 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2744 IBasicAudio* pBasicAudio;
2747 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2749 EnterCriticalSection(&This->cs);
2751 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2754 hr = IBasicAudio_GetIDsOfNames(pBasicAudio, riid, rgszNames, cNames, lcid, rgDispId);
2756 LeaveCriticalSection(&This->cs);
2761 static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface,
2762 DISPID dispIdMember,
2766 DISPPARAMS*pDispParams,
2768 EXCEPINFO*pExepInfo,
2770 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2771 IBasicAudio* pBasicAudio;
2774 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);
2776 EnterCriticalSection(&This->cs);
2778 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2781 hr = IBasicAudio_Invoke(pBasicAudio, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2783 LeaveCriticalSection(&This->cs);
2788 /*** IBasicAudio methods ***/
2789 static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface,
2791 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2792 IBasicAudio* pBasicAudio;
2795 TRACE("(%p/%p)->(%ld)\n", This, iface, lVolume);
2797 EnterCriticalSection(&This->cs);
2799 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2802 hr = IBasicAudio_put_Volume(pBasicAudio, lVolume);
2804 LeaveCriticalSection(&This->cs);
2809 static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface,
2811 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2812 IBasicAudio* pBasicAudio;
2815 TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
2817 EnterCriticalSection(&This->cs);
2819 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2822 hr = IBasicAudio_get_Volume(pBasicAudio, plVolume);
2824 LeaveCriticalSection(&This->cs);
2829 static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface,
2831 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2832 IBasicAudio* pBasicAudio;
2835 TRACE("(%p/%p)->(%ld)\n", This, iface, lBalance);
2837 EnterCriticalSection(&This->cs);
2839 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2842 hr = IBasicAudio_put_Balance(pBasicAudio, lBalance);
2844 LeaveCriticalSection(&This->cs);
2849 static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface,
2851 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2852 IBasicAudio* pBasicAudio;
2855 TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
2857 EnterCriticalSection(&This->cs);
2859 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2862 hr = IBasicAudio_get_Balance(pBasicAudio, plBalance);
2864 LeaveCriticalSection(&This->cs);
2869 static const IBasicAudioVtbl IBasicAudio_VTable =
2871 BasicAudio_QueryInterface,
2874 BasicAudio_GetTypeInfoCount,
2875 BasicAudio_GetTypeInfo,
2876 BasicAudio_GetIDsOfNames,
2878 BasicAudio_put_Volume,
2879 BasicAudio_get_Volume,
2880 BasicAudio_put_Balance,
2881 BasicAudio_get_Balance
2884 /*** IUnknown methods ***/
2885 static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo2 *iface,
2888 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2890 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2892 return Filtergraph_QueryInterface(This, riid, ppvObj);
2895 static ULONG WINAPI BasicVideo_AddRef(IBasicVideo2 *iface) {
2896 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2898 TRACE("(%p/%p)->()\n", This, iface);
2900 return Filtergraph_AddRef(This);
2903 static ULONG WINAPI BasicVideo_Release(IBasicVideo2 *iface) {
2904 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2906 TRACE("(%p/%p)->()\n", This, iface);
2908 return Filtergraph_Release(This);
2911 /*** IDispatch methods ***/
2912 static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo2 *iface,
2914 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2915 IBasicVideo* pBasicVideo;
2918 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2920 EnterCriticalSection(&This->cs);
2922 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2925 hr = IBasicVideo_GetTypeInfoCount(pBasicVideo, pctinfo);
2927 LeaveCriticalSection(&This->cs);
2932 static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo2 *iface,
2935 ITypeInfo**ppTInfo) {
2936 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2937 IBasicVideo* pBasicVideo;
2940 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2942 EnterCriticalSection(&This->cs);
2944 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2947 hr = IBasicVideo_GetTypeInfo(pBasicVideo, iTInfo, lcid, ppTInfo);
2949 LeaveCriticalSection(&This->cs);
2954 static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo2 *iface,
2960 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2961 IBasicVideo* pBasicVideo;
2964 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2966 EnterCriticalSection(&This->cs);
2968 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2971 hr = IBasicVideo_GetIDsOfNames(pBasicVideo, riid, rgszNames, cNames, lcid, rgDispId);
2973 LeaveCriticalSection(&This->cs);
2978 static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo2 *iface,
2979 DISPID dispIdMember,
2983 DISPPARAMS*pDispParams,
2985 EXCEPINFO*pExepInfo,
2987 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2988 IBasicVideo* pBasicVideo;
2991 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);
2993 EnterCriticalSection(&This->cs);
2995 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2998 hr = IBasicVideo_Invoke(pBasicVideo, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3000 LeaveCriticalSection(&This->cs);
3005 /*** IBasicVideo methods ***/
3006 static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo2 *iface,
3007 REFTIME *pAvgTimePerFrame) {
3008 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3009 IBasicVideo* pBasicVideo;
3012 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
3014 EnterCriticalSection(&This->cs);
3016 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3019 hr = IBasicVideo_get_AvgTimePerFrame(pBasicVideo, pAvgTimePerFrame);
3021 LeaveCriticalSection(&This->cs);
3026 static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo2 *iface,
3028 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3029 IBasicVideo* pBasicVideo;
3032 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
3034 EnterCriticalSection(&This->cs);
3036 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3039 hr = IBasicVideo_get_BitRate(pBasicVideo, pBitRate);
3041 LeaveCriticalSection(&This->cs);
3046 static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo2 *iface,
3047 long *pBitErrorRate) {
3048 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3049 IBasicVideo* pBasicVideo;
3052 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
3054 EnterCriticalSection(&This->cs);
3056 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3059 hr = IBasicVideo_get_BitErrorRate(pBasicVideo, pBitErrorRate);
3061 LeaveCriticalSection(&This->cs);
3066 static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo2 *iface,
3067 long *pVideoWidth) {
3068 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3069 IBasicVideo* pBasicVideo;
3072 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
3074 EnterCriticalSection(&This->cs);
3076 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3079 hr = IBasicVideo_get_VideoWidth(pBasicVideo, pVideoWidth);
3081 LeaveCriticalSection(&This->cs);
3086 static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo2 *iface,
3087 long *pVideoHeight) {
3088 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3089 IBasicVideo* pBasicVideo;
3092 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
3094 EnterCriticalSection(&This->cs);
3096 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3099 hr = IBasicVideo_get_VideoHeight(pBasicVideo, pVideoHeight);
3101 LeaveCriticalSection(&This->cs);
3106 static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo2 *iface,
3108 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3109 IBasicVideo* pBasicVideo;
3112 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft);
3114 EnterCriticalSection(&This->cs);
3116 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3119 hr = IBasicVideo_put_SourceLeft(pBasicVideo, SourceLeft);
3121 LeaveCriticalSection(&This->cs);
3126 static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo2 *iface,
3127 long *pSourceLeft) {
3128 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3129 IBasicVideo* pBasicVideo;
3132 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
3134 EnterCriticalSection(&This->cs);
3136 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3139 hr = IBasicVideo_get_SourceLeft(pBasicVideo, pSourceLeft);
3141 LeaveCriticalSection(&This->cs);
3146 static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo2 *iface,
3148 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3149 IBasicVideo* pBasicVideo;
3152 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth);
3154 EnterCriticalSection(&This->cs);
3156 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3159 hr = IBasicVideo_put_SourceWidth(pBasicVideo, SourceWidth);
3161 LeaveCriticalSection(&This->cs);
3166 static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo2 *iface,
3167 long *pSourceWidth) {
3168 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3169 IBasicVideo* pBasicVideo;
3172 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
3174 EnterCriticalSection(&This->cs);
3176 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3179 hr = IBasicVideo_get_SourceWidth(pBasicVideo, pSourceWidth);
3181 LeaveCriticalSection(&This->cs);
3186 static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo2 *iface,
3188 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3189 IBasicVideo* pBasicVideo;
3192 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop);
3194 EnterCriticalSection(&This->cs);
3196 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3199 hr = IBasicVideo_put_SourceTop(pBasicVideo, SourceTop);
3201 LeaveCriticalSection(&This->cs);
3206 static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo2 *iface,
3208 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3209 IBasicVideo* pBasicVideo;
3212 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
3214 EnterCriticalSection(&This->cs);
3216 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3219 hr = IBasicVideo_get_SourceTop(pBasicVideo, pSourceTop);
3221 LeaveCriticalSection(&This->cs);
3226 static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo2 *iface,
3227 long SourceHeight) {
3228 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3229 IBasicVideo* pBasicVideo;
3232 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight);
3234 EnterCriticalSection(&This->cs);
3236 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3239 hr = IBasicVideo_put_SourceHeight(pBasicVideo, SourceHeight);
3241 LeaveCriticalSection(&This->cs);
3246 static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo2 *iface,
3247 long *pSourceHeight) {
3248 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3249 IBasicVideo* pBasicVideo;
3252 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
3254 EnterCriticalSection(&This->cs);
3256 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3259 hr = IBasicVideo_get_SourceHeight(pBasicVideo, pSourceHeight);
3261 LeaveCriticalSection(&This->cs);
3266 static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo2 *iface,
3267 long DestinationLeft) {
3268 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3269 IBasicVideo* pBasicVideo;
3272 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft);
3274 EnterCriticalSection(&This->cs);
3276 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3279 hr = IBasicVideo_put_DestinationLeft(pBasicVideo, DestinationLeft);
3281 LeaveCriticalSection(&This->cs);
3286 static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo2 *iface,
3287 long *pDestinationLeft) {
3288 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3289 IBasicVideo* pBasicVideo;
3292 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
3294 EnterCriticalSection(&This->cs);
3296 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3299 hr = IBasicVideo_get_DestinationLeft(pBasicVideo, pDestinationLeft);
3301 LeaveCriticalSection(&This->cs);
3306 static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo2 *iface,
3307 long DestinationWidth) {
3308 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3309 IBasicVideo* pBasicVideo;
3312 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth);
3314 EnterCriticalSection(&This->cs);
3316 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3319 hr = IBasicVideo_put_DestinationWidth(pBasicVideo, DestinationWidth);
3321 LeaveCriticalSection(&This->cs);
3326 static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo2 *iface,
3327 long *pDestinationWidth) {
3328 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3329 IBasicVideo* pBasicVideo;
3332 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
3334 EnterCriticalSection(&This->cs);
3336 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3339 hr = IBasicVideo_get_DestinationWidth(pBasicVideo, pDestinationWidth);
3341 LeaveCriticalSection(&This->cs);
3346 static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo2 *iface,
3347 long DestinationTop) {
3348 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3349 IBasicVideo* pBasicVideo;
3352 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop);
3354 EnterCriticalSection(&This->cs);
3356 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3359 hr = IBasicVideo_put_DestinationTop(pBasicVideo, DestinationTop);
3361 LeaveCriticalSection(&This->cs);
3366 static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo2 *iface,
3367 long *pDestinationTop) {
3368 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3369 IBasicVideo* pBasicVideo;
3372 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
3374 EnterCriticalSection(&This->cs);
3376 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3379 hr = IBasicVideo_get_DestinationTop(pBasicVideo, pDestinationTop);
3381 LeaveCriticalSection(&This->cs);
3386 static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo2 *iface,
3387 long DestinationHeight) {
3388 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3389 IBasicVideo* pBasicVideo;
3392 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight);
3394 EnterCriticalSection(&This->cs);
3396 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3399 hr = IBasicVideo_put_DestinationHeight(pBasicVideo, DestinationHeight);
3401 LeaveCriticalSection(&This->cs);
3406 static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo2 *iface,
3407 long *pDestinationHeight) {
3408 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3409 IBasicVideo* pBasicVideo;
3412 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
3414 EnterCriticalSection(&This->cs);
3416 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3419 hr = IBasicVideo_get_DestinationHeight(pBasicVideo, pDestinationHeight);
3421 LeaveCriticalSection(&This->cs);
3426 static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo2 *iface,
3431 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3432 IBasicVideo* pBasicVideo;
3435 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3437 EnterCriticalSection(&This->cs);
3439 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3442 hr = IBasicVideo_SetSourcePosition(pBasicVideo, Left, Top, Width, Height);
3444 LeaveCriticalSection(&This->cs);
3449 static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo2 *iface,
3454 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3455 IBasicVideo* pBasicVideo;
3458 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3460 EnterCriticalSection(&This->cs);
3462 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3465 hr = IBasicVideo_GetSourcePosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3467 LeaveCriticalSection(&This->cs);
3472 static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo2 *iface) {
3473 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3474 IBasicVideo* pBasicVideo;
3477 TRACE("(%p/%p)->()\n", This, iface);
3479 EnterCriticalSection(&This->cs);
3481 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3484 hr = IBasicVideo_SetDefaultSourcePosition(pBasicVideo);
3486 LeaveCriticalSection(&This->cs);
3491 static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo2 *iface,
3496 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3497 IBasicVideo* pBasicVideo;
3500 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3502 EnterCriticalSection(&This->cs);
3504 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3507 hr = IBasicVideo_SetDestinationPosition(pBasicVideo, Left, Top, Width, Height);
3509 LeaveCriticalSection(&This->cs);
3514 static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo2 *iface,
3519 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3520 IBasicVideo* pBasicVideo;
3523 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3525 EnterCriticalSection(&This->cs);
3527 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3530 hr = IBasicVideo_GetDestinationPosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3532 LeaveCriticalSection(&This->cs);
3537 static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo2 *iface) {
3538 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3539 IBasicVideo* pBasicVideo;
3542 TRACE("(%p/%p)->()\n", This, iface);
3544 EnterCriticalSection(&This->cs);
3546 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3549 hr = IBasicVideo_SetDefaultDestinationPosition(pBasicVideo);
3551 LeaveCriticalSection(&This->cs);
3556 static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo2 *iface,
3559 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3560 IBasicVideo* pBasicVideo;
3563 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3565 EnterCriticalSection(&This->cs);
3567 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3570 hr = IBasicVideo_GetVideoSize(pBasicVideo, pWidth, pHeight);
3572 LeaveCriticalSection(&This->cs);
3577 static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo2 *iface,
3582 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3583 IBasicVideo* pBasicVideo;
3586 TRACE("(%p/%p)->(%ld, %ld, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
3588 EnterCriticalSection(&This->cs);
3590 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3593 hr = IBasicVideo_GetVideoPaletteEntries(pBasicVideo, StartIndex, Entries, pRetrieved, pPalette);
3595 LeaveCriticalSection(&This->cs);
3600 static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo2 *iface,
3603 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3604 IBasicVideo* pBasicVideo;
3607 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage);
3609 EnterCriticalSection(&This->cs);
3611 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3614 hr = IBasicVideo_GetCurrentImage(pBasicVideo, pBufferSize, pDIBImage);
3616 LeaveCriticalSection(&This->cs);
3621 static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo2 *iface) {
3622 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3623 IBasicVideo* pBasicVideo;
3626 TRACE("(%p/%p)->()\n", This, iface);
3628 EnterCriticalSection(&This->cs);
3630 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3633 hr = IBasicVideo_IsUsingDefaultSource(pBasicVideo);
3635 LeaveCriticalSection(&This->cs);
3640 static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo2 *iface) {
3641 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3642 IBasicVideo* pBasicVideo;
3645 TRACE("(%p/%p)->()\n", This, iface);
3647 EnterCriticalSection(&This->cs);
3649 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3652 hr = IBasicVideo_IsUsingDefaultDestination(pBasicVideo);
3654 LeaveCriticalSection(&This->cs);
3659 static HRESULT WINAPI BasicVideo2_GetPreferredAspectRatio(IBasicVideo2 *iface, LONG *plAspectX, LONG *plAspectY) {
3660 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3661 IBasicVideo2 *pBasicVideo2;
3664 TRACE("(%p/%p)->()\n", This, iface);
3666 EnterCriticalSection(&This->cs);
3668 hr = GetTargetInterface(This, &IID_IBasicVideo2, (LPVOID*)&pBasicVideo2);
3671 hr = BasicVideo2_GetPreferredAspectRatio(iface, plAspectX, plAspectY);
3673 LeaveCriticalSection(&This->cs);
3678 static const IBasicVideo2Vtbl IBasicVideo_VTable =
3680 BasicVideo_QueryInterface,
3683 BasicVideo_GetTypeInfoCount,
3684 BasicVideo_GetTypeInfo,
3685 BasicVideo_GetIDsOfNames,
3687 BasicVideo_get_AvgTimePerFrame,
3688 BasicVideo_get_BitRate,
3689 BasicVideo_get_BitErrorRate,
3690 BasicVideo_get_VideoWidth,
3691 BasicVideo_get_VideoHeight,
3692 BasicVideo_put_SourceLeft,
3693 BasicVideo_get_SourceLeft,
3694 BasicVideo_put_SourceWidth,
3695 BasicVideo_get_SourceWidth,
3696 BasicVideo_put_SourceTop,
3697 BasicVideo_get_SourceTop,
3698 BasicVideo_put_SourceHeight,
3699 BasicVideo_get_SourceHeight,
3700 BasicVideo_put_DestinationLeft,
3701 BasicVideo_get_DestinationLeft,
3702 BasicVideo_put_DestinationWidth,
3703 BasicVideo_get_DestinationWidth,
3704 BasicVideo_put_DestinationTop,
3705 BasicVideo_get_DestinationTop,
3706 BasicVideo_put_DestinationHeight,
3707 BasicVideo_get_DestinationHeight,
3708 BasicVideo_SetSourcePosition,
3709 BasicVideo_GetSourcePosition,
3710 BasicVideo_SetDefaultSourcePosition,
3711 BasicVideo_SetDestinationPosition,
3712 BasicVideo_GetDestinationPosition,
3713 BasicVideo_SetDefaultDestinationPosition,
3714 BasicVideo_GetVideoSize,
3715 BasicVideo_GetVideoPaletteEntries,
3716 BasicVideo_GetCurrentImage,
3717 BasicVideo_IsUsingDefaultSource,
3718 BasicVideo_IsUsingDefaultDestination,
3719 BasicVideo2_GetPreferredAspectRatio
3723 /*** IUnknown methods ***/
3724 static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface,
3727 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3729 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3731 return Filtergraph_QueryInterface(This, riid, ppvObj);
3734 static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) {
3735 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3737 TRACE("(%p/%p)->()\n", This, iface);
3739 return Filtergraph_AddRef(This);
3742 static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) {
3743 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3745 TRACE("(%p/%p)->()\n", This, iface);
3747 return Filtergraph_Release(This);
3750 /*** IDispatch methods ***/
3751 static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface,
3753 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3754 IVideoWindow* pVideoWindow;
3757 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3759 EnterCriticalSection(&This->cs);
3761 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3764 hr = IVideoWindow_GetTypeInfoCount(pVideoWindow, pctinfo);
3766 LeaveCriticalSection(&This->cs);
3771 static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface,
3774 ITypeInfo**ppTInfo) {
3775 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3776 IVideoWindow* pVideoWindow;
3779 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3781 EnterCriticalSection(&This->cs);
3783 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3786 hr = IVideoWindow_GetTypeInfo(pVideoWindow, iTInfo, lcid, ppTInfo);
3788 LeaveCriticalSection(&This->cs);
3793 static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface,
3799 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3800 IVideoWindow* pVideoWindow;
3803 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3805 EnterCriticalSection(&This->cs);
3807 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3810 hr = IVideoWindow_GetIDsOfNames(pVideoWindow, riid, rgszNames, cNames, lcid, rgDispId);
3812 LeaveCriticalSection(&This->cs);
3817 static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface,
3818 DISPID dispIdMember,
3822 DISPPARAMS*pDispParams,
3824 EXCEPINFO*pExepInfo,
3826 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3827 IVideoWindow* pVideoWindow;
3830 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);
3832 EnterCriticalSection(&This->cs);
3834 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3837 hr = IVideoWindow_Invoke(pVideoWindow, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3839 LeaveCriticalSection(&This->cs);
3845 /*** IVideoWindow methods ***/
3846 static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface,
3848 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3849 IVideoWindow* pVideoWindow;
3852 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
3854 EnterCriticalSection(&This->cs);
3856 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3859 hr = IVideoWindow_put_Caption(pVideoWindow, strCaption);
3861 LeaveCriticalSection(&This->cs);
3866 static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface,
3868 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3869 IVideoWindow* pVideoWindow;
3872 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
3874 EnterCriticalSection(&This->cs);
3876 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3879 hr = IVideoWindow_get_Caption(pVideoWindow, strCaption);
3881 LeaveCriticalSection(&This->cs);
3886 static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface,
3888 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3889 IVideoWindow* pVideoWindow;
3892 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyle);
3894 EnterCriticalSection(&This->cs);
3896 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3899 hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle);
3901 LeaveCriticalSection(&This->cs);
3906 static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface,
3907 long *WindowStyle) {
3908 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3909 IVideoWindow* pVideoWindow;
3912 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
3914 EnterCriticalSection(&This->cs);
3916 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3919 hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle);
3921 LeaveCriticalSection(&This->cs);
3926 static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface,
3927 long WindowStyleEx) {
3928 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3929 IVideoWindow* pVideoWindow;
3932 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx);
3934 EnterCriticalSection(&This->cs);
3936 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3939 hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx);
3941 LeaveCriticalSection(&This->cs);
3946 static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface,
3947 long *WindowStyleEx) {
3948 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3949 IVideoWindow* pVideoWindow;
3952 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
3954 EnterCriticalSection(&This->cs);
3956 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3959 hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx);
3961 LeaveCriticalSection(&This->cs);
3966 static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface,
3968 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3969 IVideoWindow* pVideoWindow;
3972 TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow);
3974 EnterCriticalSection(&This->cs);
3976 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3979 hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow);
3981 LeaveCriticalSection(&This->cs);
3986 static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface,
3988 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3989 IVideoWindow* pVideoWindow;
3992 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
3994 EnterCriticalSection(&This->cs);
3996 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3999 hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow);
4001 LeaveCriticalSection(&This->cs);
4006 static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface,
4008 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4009 IVideoWindow* pVideoWindow;
4012 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowState);
4014 EnterCriticalSection(&This->cs);
4016 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4019 hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState);
4021 LeaveCriticalSection(&This->cs);
4026 static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface,
4027 long *WindowState) {
4028 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4029 IVideoWindow* pVideoWindow;
4032 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
4034 EnterCriticalSection(&This->cs);
4036 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4039 hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState);
4041 LeaveCriticalSection(&This->cs);
4046 static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface,
4047 long BackgroundPalette) {
4048 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4049 IVideoWindow* pVideoWindow;
4052 TRACE("(%p/%p)->(%ld)\n", This, iface, BackgroundPalette);
4054 EnterCriticalSection(&This->cs);
4056 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4059 hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette);
4061 LeaveCriticalSection(&This->cs);
4066 static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface,
4067 long *pBackgroundPalette) {
4068 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4069 IVideoWindow* pVideoWindow;
4072 TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette);
4074 EnterCriticalSection(&This->cs);
4076 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4079 hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette);
4081 LeaveCriticalSection(&This->cs);
4086 static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface,
4088 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4089 IVideoWindow* pVideoWindow;
4092 TRACE("(%p/%p)->(%ld)\n", This, iface, Visible);
4094 EnterCriticalSection(&This->cs);
4096 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4099 hr = IVideoWindow_put_Visible(pVideoWindow, Visible);
4101 LeaveCriticalSection(&This->cs);
4106 static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface,
4108 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4109 IVideoWindow* pVideoWindow;
4112 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
4114 EnterCriticalSection(&This->cs);
4116 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4119 hr = IVideoWindow_get_Visible(pVideoWindow, pVisible);
4121 LeaveCriticalSection(&This->cs);
4126 static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface,
4128 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4129 IVideoWindow* pVideoWindow;
4132 TRACE("(%p/%p)->(%ld)\n", This, iface, Left);
4134 EnterCriticalSection(&This->cs);
4136 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4139 hr = IVideoWindow_put_Left(pVideoWindow, Left);
4141 LeaveCriticalSection(&This->cs);
4146 static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface,
4148 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4149 IVideoWindow* pVideoWindow;
4152 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
4154 EnterCriticalSection(&This->cs);
4156 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4159 hr = IVideoWindow_get_Left(pVideoWindow, pLeft);
4161 LeaveCriticalSection(&This->cs);
4166 static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface,
4168 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4169 IVideoWindow* pVideoWindow;
4172 TRACE("(%p/%p)->(%ld)\n", This, iface, Width);
4174 EnterCriticalSection(&This->cs);
4176 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4179 hr = IVideoWindow_put_Width(pVideoWindow, Width);
4181 LeaveCriticalSection(&This->cs);
4186 static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface,
4188 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4189 IVideoWindow* pVideoWindow;
4192 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
4194 EnterCriticalSection(&This->cs);
4196 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4199 hr = IVideoWindow_get_Width(pVideoWindow, pWidth);
4201 LeaveCriticalSection(&This->cs);
4206 static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface,
4208 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4209 IVideoWindow* pVideoWindow;
4212 TRACE("(%p/%p)->(%ld)\n", This, iface, Top);
4214 EnterCriticalSection(&This->cs);
4216 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4219 hr = IVideoWindow_put_Top(pVideoWindow, Top);
4221 LeaveCriticalSection(&This->cs);
4226 static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface,
4228 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4229 IVideoWindow* pVideoWindow;
4232 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
4234 EnterCriticalSection(&This->cs);
4236 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4239 hr = IVideoWindow_get_Top(pVideoWindow, pTop);
4241 LeaveCriticalSection(&This->cs);
4246 static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface,
4248 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4249 IVideoWindow* pVideoWindow;
4252 TRACE("(%p/%p)->(%ld)\n", This, iface, Height);
4254 EnterCriticalSection(&This->cs);
4256 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4259 hr = IVideoWindow_put_Height(pVideoWindow, Height);
4261 LeaveCriticalSection(&This->cs);
4266 static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface,
4268 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4269 IVideoWindow* pVideoWindow;
4272 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
4274 EnterCriticalSection(&This->cs);
4276 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4279 hr = IVideoWindow_get_Height(pVideoWindow, pHeight);
4281 LeaveCriticalSection(&This->cs);
4286 static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface,
4288 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4289 IVideoWindow* pVideoWindow;
4292 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
4294 EnterCriticalSection(&This->cs);
4296 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4299 hr = IVideoWindow_put_Owner(pVideoWindow, Owner);
4301 LeaveCriticalSection(&This->cs);
4306 static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface,
4308 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4309 IVideoWindow* pVideoWindow;
4312 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
4314 EnterCriticalSection(&This->cs);
4316 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4319 hr = IVideoWindow_get_Owner(pVideoWindow, Owner);
4321 LeaveCriticalSection(&This->cs);
4326 static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface,
4328 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4329 IVideoWindow* pVideoWindow;
4332 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
4334 EnterCriticalSection(&This->cs);
4336 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4339 hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain);
4341 LeaveCriticalSection(&This->cs);
4346 static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface,
4348 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4349 IVideoWindow* pVideoWindow;
4352 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
4354 EnterCriticalSection(&This->cs);
4356 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4359 hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain);
4361 LeaveCriticalSection(&This->cs);
4366 static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface,
4368 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4369 IVideoWindow* pVideoWindow;
4372 TRACE("(%p/%p)->(%p)\n", This, iface, Color);
4374 EnterCriticalSection(&This->cs);
4376 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4379 hr = IVideoWindow_get_BorderColor(pVideoWindow, Color);
4381 LeaveCriticalSection(&This->cs);
4386 static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface,
4388 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4389 IVideoWindow* pVideoWindow;
4392 TRACE("(%p/%p)->(%ld)\n", This, iface, Color);
4394 EnterCriticalSection(&This->cs);
4396 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4399 hr = IVideoWindow_put_BorderColor(pVideoWindow, Color);
4401 LeaveCriticalSection(&This->cs);
4406 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
4407 long *FullScreenMode) {
4408 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4409 IVideoWindow* pVideoWindow;
4412 TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode);
4414 EnterCriticalSection(&This->cs);
4416 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4419 hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode);
4421 LeaveCriticalSection(&This->cs);
4426 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
4427 long FullScreenMode) {
4428 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4429 IVideoWindow* pVideoWindow;
4432 TRACE("(%p/%p)->(%ld)\n", This, iface, FullScreenMode);
4434 EnterCriticalSection(&This->cs);
4436 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4439 hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode);
4441 LeaveCriticalSection(&This->cs);
4446 static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface,
4448 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4449 IVideoWindow* pVideoWindow;
4452 TRACE("(%p/%p)->(%ld)\n", This, iface, Focus);
4454 EnterCriticalSection(&This->cs);
4456 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4459 hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus);
4461 LeaveCriticalSection(&This->cs);
4466 static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface,
4471 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4472 IVideoWindow* pVideoWindow;
4475 TRACE("(%p/%p)->(%08x, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
4477 EnterCriticalSection(&This->cs);
4479 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4482 hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam);
4484 LeaveCriticalSection(&This->cs);
4489 static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface,
4494 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4495 IVideoWindow* pVideoWindow;
4498 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
4500 EnterCriticalSection(&This->cs);
4502 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4505 hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height);
4507 LeaveCriticalSection(&This->cs);
4512 static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface,
4517 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4518 IVideoWindow* pVideoWindow;
4521 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4523 EnterCriticalSection(&This->cs);
4525 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4528 hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4530 LeaveCriticalSection(&This->cs);
4535 static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface,
4538 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4539 IVideoWindow* pVideoWindow;
4542 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4544 EnterCriticalSection(&This->cs);
4546 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4549 hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight);
4551 LeaveCriticalSection(&This->cs);
4556 static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface,
4559 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4560 IVideoWindow* pVideoWindow;
4563 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4565 EnterCriticalSection(&This->cs);
4567 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4570 hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight);
4572 LeaveCriticalSection(&This->cs);
4577 static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface,
4582 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4583 IVideoWindow* pVideoWindow;
4586 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4588 EnterCriticalSection(&This->cs);
4590 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4593 hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4595 LeaveCriticalSection(&This->cs);
4600 static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface,
4602 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4603 IVideoWindow* pVideoWindow;
4606 TRACE("(%p/%p)->(%ld)\n", This, iface, HideCursor);
4608 EnterCriticalSection(&This->cs);
4610 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4613 hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor);
4615 LeaveCriticalSection(&This->cs);
4620 static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface,
4621 long *CursorHidden) {
4622 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4623 IVideoWindow* pVideoWindow;
4626 TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden);
4628 EnterCriticalSection(&This->cs);
4630 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4633 hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden);
4635 LeaveCriticalSection(&This->cs);
4641 static const IVideoWindowVtbl IVideoWindow_VTable =
4643 VideoWindow_QueryInterface,
4645 VideoWindow_Release,
4646 VideoWindow_GetTypeInfoCount,
4647 VideoWindow_GetTypeInfo,
4648 VideoWindow_GetIDsOfNames,
4650 VideoWindow_put_Caption,
4651 VideoWindow_get_Caption,
4652 VideoWindow_put_WindowStyle,
4653 VideoWindow_get_WindowStyle,
4654 VideoWindow_put_WindowStyleEx,
4655 VideoWindow_get_WindowStyleEx,
4656 VideoWindow_put_AutoShow,
4657 VideoWindow_get_AutoShow,
4658 VideoWindow_put_WindowState,
4659 VideoWindow_get_WindowState,
4660 VideoWindow_put_BackgroundPalette,
4661 VideoWindow_get_BackgroundPalette,
4662 VideoWindow_put_Visible,
4663 VideoWindow_get_Visible,
4664 VideoWindow_put_Left,
4665 VideoWindow_get_Left,
4666 VideoWindow_put_Width,
4667 VideoWindow_get_Width,
4668 VideoWindow_put_Top,
4669 VideoWindow_get_Top,
4670 VideoWindow_put_Height,
4671 VideoWindow_get_Height,
4672 VideoWindow_put_Owner,
4673 VideoWindow_get_Owner,
4674 VideoWindow_put_MessageDrain,
4675 VideoWindow_get_MessageDrain,
4676 VideoWindow_get_BorderColor,
4677 VideoWindow_put_BorderColor,
4678 VideoWindow_get_FullScreenMode,
4679 VideoWindow_put_FullScreenMode,
4680 VideoWindow_SetWindowForeground,
4681 VideoWindow_NotifyOwnerMessage,
4682 VideoWindow_SetWindowPosition,
4683 VideoWindow_GetWindowPosition,
4684 VideoWindow_GetMinIdealImageSize,
4685 VideoWindow_GetMaxIdealImageSize,
4686 VideoWindow_GetRestorePosition,
4687 VideoWindow_HideCursor,
4688 VideoWindow_IsCursorHidden
4692 /*** IUnknown methods ***/
4693 static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface,
4696 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4698 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
4700 return Filtergraph_QueryInterface(This, riid, ppvObj);
4703 static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) {
4704 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4706 TRACE("(%p/%p)->()\n", This, iface);
4708 return Filtergraph_AddRef(This);
4711 static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) {
4712 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4714 TRACE("(%p/%p)->()\n", This, iface);
4716 return Filtergraph_Release(This);
4719 /*** IDispatch methods ***/
4720 static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface,
4722 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4724 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
4729 static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface,
4732 ITypeInfo**ppTInfo) {
4733 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4735 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
4740 static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface,
4746 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4748 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
4753 static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface,
4754 DISPID dispIdMember,
4758 DISPPARAMS*pDispParams,
4760 EXCEPINFO*pExepInfo,
4762 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4764 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);
4769 /*** IMediaEvent methods ***/
4770 static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface,
4772 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4774 TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
4776 *hEvent = (OAEVENT)This->evqueue.msg_event;
4781 static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface,
4786 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4789 TRACE("(%p/%p)->(%p, %p, %p, %ld)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
4791 if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
4793 *lEventCode = evt.lEventCode;
4794 *lParam1 = evt.lParam1;
4795 *lParam2 = evt.lParam2;
4803 static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface,
4806 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4808 TRACE("(%p/%p)->(%ld, %p)\n", This, iface, msTimeout, pEvCode);
4810 if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
4812 *pEvCode = This->CompletionStatus;
4820 static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface,
4822 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4824 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4826 if (lEvCode == EC_COMPLETE)
4827 This->HandleEcComplete = FALSE;
4828 else if (lEvCode == EC_REPAINT)
4829 This->HandleEcRepaint = FALSE;
4830 else if (lEvCode == EC_CLOCK_CHANGED)
4831 This->HandleEcClockChanged = FALSE;
4838 static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface,
4840 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4842 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4844 if (lEvCode == EC_COMPLETE)
4845 This->HandleEcComplete = TRUE;
4846 else if (lEvCode == EC_REPAINT)
4847 This->HandleEcRepaint = TRUE;
4848 else if (lEvCode == EC_CLOCK_CHANGED)
4849 This->HandleEcClockChanged = TRUE;
4856 static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface,
4860 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4862 TRACE("(%p/%p)->(%ld, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
4867 /*** IMediaEventEx methods ***/
4868 static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface,
4871 LONG_PTR lInstanceData) {
4872 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4874 TRACE("(%p/%p)->(%08x, %ld, %08lx)\n", This, iface, (DWORD) hwnd, lMsg, lInstanceData);
4876 This->notif.hWnd = (HWND)hwnd;
4877 This->notif.msg = lMsg;
4878 This->notif.instance = (long) lInstanceData;
4883 static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface,
4884 long lNoNotifyFlags) {
4885 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4887 TRACE("(%p/%p)->(%ld)\n", This, iface, lNoNotifyFlags);
4889 if ((lNoNotifyFlags != 0) && (lNoNotifyFlags != 1))
4890 return E_INVALIDARG;
4892 This->notif.disabled = lNoNotifyFlags;
4897 static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface,
4898 long *lplNoNotifyFlags) {
4899 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4901 TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
4903 if (!lplNoNotifyFlags)
4906 *lplNoNotifyFlags = This->notif.disabled;
4912 static const IMediaEventExVtbl IMediaEventEx_VTable =
4914 MediaEvent_QueryInterface,
4917 MediaEvent_GetTypeInfoCount,
4918 MediaEvent_GetTypeInfo,
4919 MediaEvent_GetIDsOfNames,
4921 MediaEvent_GetEventHandle,
4922 MediaEvent_GetEvent,
4923 MediaEvent_WaitForCompletion,
4924 MediaEvent_CancelDefaultHandling,
4925 MediaEvent_RestoreDefaultHandling,
4926 MediaEvent_FreeEventParams,
4927 MediaEvent_SetNotifyWindow,
4928 MediaEvent_SetNotifyFlags,
4929 MediaEvent_GetNotifyFlags
4933 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
4935 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4937 return Filtergraph_QueryInterface(This, riid, ppv);
4940 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
4942 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4944 return Filtergraph_AddRef(This);
4947 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
4949 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4951 return Filtergraph_Release(This);
4954 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
4956 FIXME("(%p): stub\n", pClassID);
4961 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
4963 FIXME("(): stub\n");
4968 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
4970 FIXME("(): stub\n");
4975 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
4977 FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart));
4982 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
4984 FIXME("(%d, %p): stub\n", dwMsTimeout, pState);
4989 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
4991 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4995 TRACE("(%p/%p)->(%p)\n", iface, This, pClock);
4997 EnterCriticalSection(&This->cs);
4999 for (i = 0;i < This->nFilters;i++)
5001 hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
5009 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
5014 IReferenceClock_Release(This->refClock);
5015 This->refClock = pClock;
5017 IReferenceClock_AddRef(This->refClock);
5019 if (This->HandleEcClockChanged)
5021 IMediaEventSink *pEventSink;
5024 eshr = IMediaFilter_QueryInterface(iface, &IID_IMediaEventSink, (LPVOID)&pEventSink);
5025 if (SUCCEEDED(eshr))
5027 IMediaEventSink_Notify(pEventSink, EC_CLOCK_CHANGED, 0, 0);
5028 IMediaEventSink_Release(pEventSink);
5033 LeaveCriticalSection(&This->cs);
5038 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
5040 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5042 TRACE("(%p/%p)->(%p)\n", iface, This, ppClock);
5047 EnterCriticalSection(&This->cs);
5049 *ppClock = This->refClock;
5051 IReferenceClock_AddRef(*ppClock);
5053 LeaveCriticalSection(&This->cs);
5058 static const IMediaFilterVtbl IMediaFilter_VTable =
5060 MediaFilter_QueryInterface,
5062 MediaFilter_Release,
5063 MediaFilter_GetClassID,
5067 MediaFilter_GetState,
5068 MediaFilter_SetSyncSource,
5069 MediaFilter_GetSyncSource
5072 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
5074 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5076 return Filtergraph_QueryInterface(This, riid, ppv);
5079 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
5081 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5083 return Filtergraph_AddRef(This);
5086 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
5088 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5090 return Filtergraph_Release(This);
5093 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
5095 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5098 TRACE("(%p/%p)->(%ld, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
5100 /* We need thread safety here, let's use the events queue's one */
5101 EnterCriticalSection(&This->evqueue.msg_crst);
5103 if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
5105 TRACE("Process EC_COMPLETE notification\n");
5106 if (++This->EcCompleteCount == This->nRenderers)
5108 evt.lEventCode = EC_COMPLETE;
5111 TRACE("Send EC_COMPLETE to app\n");
5112 EventsQueue_PutEvent(&This->evqueue, &evt);
5113 if (!This->notif.disabled && This->notif.hWnd)
5115 TRACE("Send Window message\n");
5116 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
5118 This->CompletionStatus = EC_COMPLETE;
5119 SetEvent(This->hEventCompletion);
5122 else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
5124 /* FIXME: Not handled yet */
5128 evt.lEventCode = EventCode;
5129 evt.lParam1 = EventParam1;
5130 evt.lParam2 = EventParam2;
5131 EventsQueue_PutEvent(&This->evqueue, &evt);
5132 if (!This->notif.disabled && This->notif.hWnd)
5133 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
5136 LeaveCriticalSection(&This->evqueue.msg_crst);
5140 static const IMediaEventSinkVtbl IMediaEventSink_VTable =
5142 MediaEventSink_QueryInterface,
5143 MediaEventSink_AddRef,
5144 MediaEventSink_Release,
5145 MediaEventSink_Notify
5148 static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv)
5150 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5152 return Filtergraph_QueryInterface(This, riid, ppv);
5155 static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface)
5157 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5159 return Filtergraph_AddRef(This);
5162 static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface)
5164 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5166 return Filtergraph_Release(This);
5169 static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface,
5172 const AM_MEDIA_TYPE* pmtFirstConnection,
5173 IBaseFilter* pUsingFilter,
5177 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5179 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags);
5184 static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface,
5185 IGraphConfigCallback* pCallback,
5190 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5193 WARN("(%p)->(%p, %p, %x, %p): partial stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent);
5196 FIXME("The parameter hAbortEvent is not handled!\n");
5198 EnterCriticalSection(&This->cs);
5200 hr = IGraphConfigCallback_Reconfigure(pCallback, pvContext, dwFlags);
5202 LeaveCriticalSection(&This->cs);
5207 static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface,
5208 IBaseFilter* pFilter)
5210 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5212 FIXME("(%p)->(%p): stub!\n", This, pFilter);
5217 static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface,
5218 IEnumFilters** pEnum)
5220 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5222 FIXME("(%p)->(%p): stub!\n", This, pEnum);
5227 static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface,
5228 IBaseFilter* pFilter)
5230 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5232 FIXME("(%p)->(%p): stub!\n", This, pFilter);
5237 static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface,
5238 REFERENCE_TIME* prtStart)
5240 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5242 FIXME("(%p)->(%p): stub!\n", This, prtStart);
5247 static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface,
5249 IPinConnection* pConnection,
5252 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5254 FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort);
5259 static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface,
5260 IBaseFilter* pFilter,
5263 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5265 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
5270 static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface,
5271 IBaseFilter* pFilter,
5274 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5276 FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags);
5281 static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface,
5282 IBaseFilter* pFilter,
5285 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5287 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
5292 static const IGraphConfigVtbl IGraphConfig_VTable =
5294 GraphConfig_QueryInterface,
5296 GraphConfig_Release,
5297 GraphConfig_Reconnect,
5298 GraphConfig_Reconfigure,
5299 GraphConfig_AddFilterToCache,
5300 GraphConfig_EnumCacheFilter,
5301 GraphConfig_RemoveFilterFromCache,
5302 GraphConfig_GetStartTime,
5303 GraphConfig_PushThroughData,
5304 GraphConfig_SetFilterFlags,
5305 GraphConfig_GetFilterFlags,
5306 GraphConfig_RemoveFilterEx
5309 static const IUnknownVtbl IInner_VTable =
5311 FilterGraphInner_QueryInterface,
5312 FilterGraphInner_AddRef,
5313 FilterGraphInner_Release
5316 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
5319 if (This->bAggregatable)
5320 This->bUnkOuterValid = TRUE;
5322 if (This->pUnkOuter)
5324 if (This->bAggregatable)
5325 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
5327 if (IsEqualIID(riid, &IID_IUnknown))
5331 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
5332 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
5333 IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
5334 This->bAggregatable = TRUE;
5339 return E_NOINTERFACE;
5342 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
5345 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This) {
5346 if (This->pUnkOuter && This->bUnkOuterValid)
5347 return IUnknown_AddRef(This->pUnkOuter);
5348 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
5351 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This) {
5352 if (This->pUnkOuter && This->bUnkOuterValid)
5353 return IUnknown_Release(This->pUnkOuter);
5354 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
5357 /* This is the only function that actually creates a FilterGraph class... */
5358 HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
5360 IFilterGraphImpl *fimpl;
5363 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
5367 fimpl = CoTaskMemAlloc(sizeof(*fimpl));
5368 fimpl->pUnkOuter = pUnkOuter;
5369 fimpl->bUnkOuterValid = FALSE;
5370 fimpl->bAggregatable = FALSE;
5371 fimpl->IInner_vtbl = &IInner_VTable;
5372 fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
5373 fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
5374 fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
5375 fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
5376 fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
5377 fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
5378 fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
5379 fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
5380 fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
5381 fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable;
5382 fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable;
5384 fimpl->ppFiltersInGraph = NULL;
5385 fimpl->pFilterNames = NULL;
5386 fimpl->nFilters = 0;
5387 fimpl->filterCapacity = 0;
5388 fimpl->nameIndex = 1;
5389 fimpl->refClock = NULL;
5390 fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
5391 fimpl->HandleEcComplete = TRUE;
5392 fimpl->HandleEcRepaint = TRUE;
5393 fimpl->HandleEcClockChanged = TRUE;
5394 fimpl->notif.hWnd = 0;
5395 fimpl->notif.disabled = FALSE;
5396 fimpl->nRenderers = 0;
5397 fimpl->EcCompleteCount = 0;
5398 fimpl->state = State_Stopped;
5399 EventsQueue_Init(&fimpl->evqueue);
5400 InitializeCriticalSection(&fimpl->cs);
5401 fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
5402 fimpl->nItfCacheEntries = 0;
5403 memcpy(&fimpl->timeformatseek, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
5404 fimpl->start_time = fimpl->position = 0;
5405 fimpl->stop_position = -1;
5407 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
5409 ERR("Unable to create filter mapper (%x)\n", hr);
5412 IFilterGraph2_SetDefaultSyncSource((IFilterGraph2*)fimpl);
5418 HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj)
5420 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
5421 return FilterGraph_create(pUnkOuter, ppObj);