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 UINT msg; /* User window message */
50 LONG_PTR 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 = CoTaskMemRealloc(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 IUnknown *punkFilterMapper2;
180 IFilterMapper2 * pFilterMapper2;
181 IBaseFilter ** ppFiltersInGraph;
182 LPWSTR * pFilterNames;
186 IReferenceClock *refClock;
188 HANDLE hEventCompletion;
189 int CompletionStatus;
193 int HandleEcComplete;
195 int HandleEcClockChanged;
198 ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
199 int nItfCacheEntries;
200 IUnknown * pUnkOuter;
205 REFERENCE_TIME start_time;
206 REFERENCE_TIME pause_time;
207 LONGLONG stop_position;
211 static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
212 REFIID riid, LPVOID * ppv);
213 static ULONG Filtergraph_AddRef(IFilterGraphImpl *This);
214 static ULONG Filtergraph_Release(IFilterGraphImpl *This);
216 static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface,
219 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
220 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
222 if (This->bAggregatable)
223 This->bUnkOuterValid = TRUE;
225 if (IsEqualGUID(&IID_IUnknown, riid)) {
226 *ppvObj = &(This->IInner_vtbl);
227 TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
228 } else if (IsEqualGUID(&IID_IFilterGraph, riid) ||
229 IsEqualGUID(&IID_IFilterGraph2, riid) ||
230 IsEqualGUID(&IID_IGraphBuilder, riid)) {
231 *ppvObj = &(This->IFilterGraph2_vtbl);
232 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj);
233 } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
234 *ppvObj = &(This->IMediaControl_vtbl);
235 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj);
236 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
237 *ppvObj = &(This->IMediaSeeking_vtbl);
238 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
239 } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
240 *ppvObj = &(This->IBasicAudio_vtbl);
241 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj);
242 } else if (IsEqualGUID(&IID_IBasicVideo, riid) ||
243 IsEqualGUID(&IID_IBasicVideo2, riid)) {
244 *ppvObj = &(This->IBasicVideo_vtbl);
245 TRACE(" returning IBasicVideo2 interface (%p)\n", *ppvObj);
246 } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
247 *ppvObj = &(This->IVideoWindow_vtbl);
248 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj);
249 } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
250 IsEqualGUID(&IID_IMediaEventEx, riid)) {
251 *ppvObj = &(This->IMediaEventEx_vtbl);
252 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
253 } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
254 IsEqualGUID(&IID_IPersist, riid)) {
255 *ppvObj = &(This->IMediaFilter_vtbl);
256 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj);
257 } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
258 *ppvObj = &(This->IMediaEventSink_vtbl);
259 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj);
260 } else if (IsEqualGUID(&IID_IGraphConfig, riid)) {
261 *ppvObj = &(This->IGraphConfig_vtbl);
262 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj);
263 } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
264 *ppvObj = &(This->IMediaPosition_vtbl);
265 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj);
266 } else if (IsEqualGUID(&IID_IFilterMapper, riid)) {
267 TRACE(" requesting IFilterMapper interface from aggregated filtermapper (%p)\n", *ppvObj);
268 return IUnknown_QueryInterface(This->punkFilterMapper2, riid, ppvObj);
269 } else if (IsEqualGUID(&IID_IFilterMapper2, riid)) {
270 *ppvObj = This->pFilterMapper2;
271 TRACE(" returning IFilterMapper2 interface from aggregated filtermapper (%p)\n", *ppvObj);
274 FIXME("unknown interface %s\n", debugstr_guid(riid));
275 return E_NOINTERFACE;
278 IUnknown_AddRef((IUnknown *)(*ppvObj));
282 static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) {
283 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
284 ULONG ref = InterlockedIncrement(&This->ref);
286 TRACE("(%p)->(): new ref = %d\n", This, ref);
291 static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface)
293 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
294 ULONG ref = InterlockedDecrement(&This->ref);
296 TRACE("(%p)->(): new ref = %d\n", This, ref);
301 This->ref = 1; /* guard against reentrancy (aggregation). */
303 IMediaControl_Stop((IMediaControl*)&(This->IMediaControl_vtbl));
305 while (This->nFilters)
306 IFilterGraph2_RemoveFilter((IFilterGraph2*)This, This->ppFiltersInGraph[0]);
309 IReferenceClock_Release(This->refClock);
311 for (i = 0; i < This->nItfCacheEntries; i++)
313 if (This->ItfCacheEntries[i].iface)
314 IUnknown_Release(This->ItfCacheEntries[i].iface);
317 /* AddRef on controlling IUnknown, to compensate for Release of cached IFilterMapper2 interface below.
319 * NOTE: Filtergraph_AddRef isn't suitable, because bUnkOuterValid may be FALSE but punkOuter non-NULL
320 * and already passed as punkOuter to filtermapper in FilterGraph_create - this will happen in case of
321 * CoCreateInstance of filtergraph with non-null pUnkOuter and REFIID other than IID_Unknown that is
322 * cleaning up after error. */
323 if (This->pUnkOuter) IUnknown_AddRef(This->pUnkOuter);
324 else IUnknown_AddRef((IUnknown*)&This->IInner_vtbl);
326 IFilterMapper2_Release(This->pFilterMapper2);
327 IUnknown_Release(This->punkFilterMapper2);
329 CloseHandle(This->hEventCompletion);
330 EventsQueue_Destroy(&This->evqueue);
331 This->cs.DebugInfo->Spare[0] = 0;
332 DeleteCriticalSection(&This->cs);
333 CoTaskMemFree(This->ppFiltersInGraph);
334 CoTaskMemFree(This->pFilterNames);
341 /*** IUnknown methods ***/
342 static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface,
345 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
347 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
348 return Filtergraph_QueryInterface(This, riid, ppvObj);
351 static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) {
352 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
354 TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
356 return Filtergraph_AddRef(This);
359 static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) {
360 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
362 TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
364 return Filtergraph_Release(This);
367 /*** IFilterGraph methods ***/
368 static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
369 IBaseFilter *pFilter,
371 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
374 WCHAR* wszFilterName = NULL;
375 int duplicate_name = FALSE;
377 TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
382 wszFilterName = CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
386 /* Check if name already exists */
387 for(i = 0; i < This->nFilters; i++)
388 if (!strcmpW(This->pFilterNames[i], pName))
390 duplicate_name = TRUE;
395 /* If no name given or name already existing, generate one */
396 if (!pName || duplicate_name)
398 static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
399 static const WCHAR wszFmt2[] = {'%','0','4','d',0};
401 for (j = 0; j < 10000 ; j++)
405 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
407 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
408 TRACE("Generated name %s\n", debugstr_w(wszFilterName));
410 /* Check if the generated name already exists */
411 for(i = 0; i < This->nFilters; i++)
412 if (!strcmpW(This->pFilterNames[i], wszFilterName))
415 /* Compute next index and exit if generated name is suitable */
416 if (This->nameIndex++ == 10000)
418 if (i == This->nFilters)
421 /* Unable to find a suitable name */
424 CoTaskMemFree(wszFilterName);
425 return VFW_E_DUPLICATE_NAME;
429 memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
431 if (This->nFilters + 1 > This->filterCapacity)
433 int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
434 IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
435 LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
436 memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
437 memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
438 if (This->filterCapacity)
440 CoTaskMemFree(This->ppFiltersInGraph);
441 CoTaskMemFree(This->pFilterNames);
443 This->ppFiltersInGraph = ppNewFilters;
444 This->pFilterNames = pNewNames;
445 This->filterCapacity = newCapacity;
448 hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
452 IBaseFilter_AddRef(pFilter);
453 This->ppFiltersInGraph[This->nFilters] = pFilter;
454 This->pFilterNames[This->nFilters] = wszFilterName;
456 IBaseFilter_SetSyncSource(pFilter, This->refClock);
459 CoTaskMemFree(wszFilterName);
461 if (SUCCEEDED(hr) && duplicate_name)
462 return VFW_S_DUPLICATE_NAME;
467 static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *pFilter)
469 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
473 TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
475 /* FIXME: check graph is stopped */
477 for (i = 0; i < This->nFilters; i++)
479 if (This->ppFiltersInGraph[i] == pFilter)
481 IEnumPins *penumpins = NULL;
484 TRACE("Removing filter %s\n", debugstr_w(This->pFilterNames[i]));
485 IBaseFilter_GetState(pFilter, 0, &state);
486 if (state == State_Running)
487 IBaseFilter_Pause(pFilter);
488 if (state != State_Stopped)
489 IBaseFilter_Stop(pFilter);
491 hr = IBaseFilter_EnumPins(pFilter, &penumpins);
494 while(IEnumPins_Next(penumpins, 1, &ppin, NULL) == S_OK)
498 IPin_ConnectedTo(ppin, &victim);
501 h = IPin_Disconnect(victim);
502 TRACE("Disconnect other side: %08x\n", h);
503 if (h == VFW_E_NOT_STOPPED)
506 IPin_QueryPinInfo(victim, &pinfo);
508 IBaseFilter_GetState(pinfo.pFilter, 0, &state);
509 if (state == State_Running)
510 IBaseFilter_Pause(pinfo.pFilter);
511 IBaseFilter_Stop(pinfo.pFilter);
512 IBaseFilter_Release(pinfo.pFilter);
513 h = IPin_Disconnect(victim);
514 TRACE("Disconnect retry: %08x\n", h);
516 IPin_Release(victim);
518 h = IPin_Disconnect(ppin);
519 TRACE("Disconnect 2: %08x\n", h);
523 IEnumPins_Release(penumpins);
526 hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
529 IBaseFilter_SetSyncSource(pFilter, NULL);
530 IBaseFilter_Release(pFilter);
531 CoTaskMemFree(This->pFilterNames[i]);
532 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
533 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
535 /* Invalidate interfaces in the cache */
536 for (i = 0; i < This->nItfCacheEntries; i++)
537 if (pFilter == This->ItfCacheEntries[i].filter)
539 IUnknown_Release(This->ItfCacheEntries[i].iface);
540 This->ItfCacheEntries[i].iface = NULL;
541 This->ItfCacheEntries[i].filter = NULL;
549 return hr; /* FIXME: check this error code */
552 static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface,
553 IEnumFilters **ppEnum) {
554 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
556 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
558 return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
561 static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface,
563 IBaseFilter **ppFilter) {
564 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
567 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
572 for (i = 0; i < This->nFilters; i++)
574 if (!strcmpW(pName, This->pFilterNames[i]))
576 *ppFilter = This->ppFiltersInGraph[i];
577 IBaseFilter_AddRef(*ppFilter);
583 return VFW_E_NOT_FOUND;
586 /* Don't allow a circular connection to form, return VFW_E_CIRCULAR_GRAPH if this would be the case.
587 * A circular connection will be formed if from the filter of the output pin, the input pin can be reached
589 static HRESULT CheckCircularConnection(IFilterGraphImpl *This, IPin *out, IPin *in)
593 PIN_INFO info_out, info_in;
595 hr = IPin_QueryPinInfo(out, &info_out);
598 if (info_out.dir != PINDIR_OUTPUT)
600 IBaseFilter_Release(info_out.pFilter);
604 hr = IPin_QueryPinInfo(in, &info_in);
606 IBaseFilter_Release(info_in.pFilter);
609 if (info_in.dir != PINDIR_INPUT)
615 if (info_out.pFilter == info_in.pFilter)
616 hr = VFW_E_CIRCULAR_GRAPH;
622 hr = IBaseFilter_EnumPins(info_out.pFilter, &enumpins);
626 IEnumPins_Reset(enumpins);
627 while ((hr = IEnumPins_Next(enumpins, 1, &test, NULL)) == S_OK)
629 PIN_DIRECTION dir = PINDIR_OUTPUT;
630 IPin_QueryDirection(test, &dir);
631 if (dir == PINDIR_INPUT)
634 IPin_ConnectedTo(test, &victim);
637 hr = CheckCircularConnection(This, victim, in);
638 IPin_Release(victim);
648 IEnumPins_Release(enumpins);
652 IBaseFilter_Release(info_out.pFilter);
654 ERR("Checking filtergraph returned %08x, something's not right!\n", hr);
657 /* Debugging filtergraphs not enabled */
663 /* NOTE: despite the implication, it doesn't matter which
664 * way round you put in the input and output pins */
665 static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface,
668 const AM_MEDIA_TYPE *pmt) {
672 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
674 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
676 /* FIXME: check pins are in graph */
678 if (TRACE_ON(quartz))
682 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
686 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
687 IBaseFilter_Release(PinInfo.pFilter);
689 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
693 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
694 IBaseFilter_Release(PinInfo.pFilter);
697 hr = IPin_QueryDirection(ppinIn, &dir);
700 if (dir == PINDIR_INPUT)
702 hr = CheckCircularConnection(This, ppinOut, ppinIn);
704 hr = IPin_Connect(ppinOut, ppinIn, pmt);
708 hr = CheckCircularConnection(This, ppinIn, ppinOut);
710 hr = IPin_Connect(ppinIn, ppinOut, pmt);
717 static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface,
719 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
720 IPin *pConnectedTo = NULL;
722 PIN_DIRECTION pindir;
724 IPin_QueryDirection(ppin, &pindir);
725 hr = IPin_ConnectedTo(ppin, &pConnectedTo);
727 TRACE("Querying connected to failed: %x\n", hr);
730 IPin_Disconnect(ppin);
731 IPin_Disconnect(pConnectedTo);
732 if (pindir == PINDIR_INPUT)
733 hr = IPin_Connect(pConnectedTo, ppin, NULL);
735 hr = IPin_Connect(ppin, pConnectedTo, NULL);
736 IPin_Release(pConnectedTo);
738 WARN("Reconnecting pins failed, pins are not connected now..\n");
739 TRACE("(%p->%p) -- %p %p -> %x\n", iface, This, ppin, pConnectedTo, hr);
743 static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface, IPin *ppin)
745 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
747 TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
752 return IPin_Disconnect(ppin);
755 static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) {
756 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
757 IReferenceClock *pClock = NULL;
761 TRACE("(%p/%p)->() live sources not handled properly!\n", iface, This);
763 EnterCriticalSection(&This->cs);
765 for (i = 0; i < This->nFilters; ++i)
768 IAMFilterMiscFlags *flags = NULL;
769 IUnknown_QueryInterface(This->ppFiltersInGraph[i], &IID_IAMFilterMiscFlags, (void**)&flags);
772 miscflags = IAMFilterMiscFlags_GetMiscFlags(flags);
773 IUnknown_Release(flags);
774 if (miscflags == AM_FILTER_MISC_FLAGS_IS_RENDERER)
775 IUnknown_QueryInterface(This->ppFiltersInGraph[i], &IID_IReferenceClock, (void**)&pClock);
781 hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&pClock);
785 hr = IMediaFilter_SetSyncSource((IMediaFilter*)&(This->IMediaFilter_vtbl), pClock);
786 This->defaultclock = TRUE;
787 IReferenceClock_Release(pClock);
789 LeaveCriticalSection(&This->cs);
794 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
796 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
797 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
798 IPropertyBag * pPropBagCat = NULL;
803 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
806 hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
809 hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
814 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
817 TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
820 IPropertyBag_Release(pPropBagCat);
825 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPin*** pppins, ULONG* pnb)
830 TRACE("(%p, %p, %p, %p)\n", pfilter, pinputpin, pppins, pnb);
831 hr = IPin_QueryInternalConnections(pinputpin, NULL, &nb);
834 } else if (hr == S_FALSE) {
835 *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
836 hr = IPin_QueryInternalConnections(pinputpin, *pppins, &nb);
838 WARN("Error (%x)\n", hr);
840 } else if (hr == E_NOTIMPL) {
841 /* Input connected to all outputs */
842 IEnumPins* penumpins;
845 TRACE("E_NOTIMPL\n");
846 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
848 WARN("filter Enumpins failed (%x)\n", hr);
852 /* Count output pins */
853 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
854 PIN_DIRECTION pindir;
855 IPin_QueryDirection(ppin, &pindir);
856 if (pindir == PINDIR_OUTPUT)
860 *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
861 /* Retrieve output pins */
862 IEnumPins_Reset(penumpins);
864 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
865 PIN_DIRECTION pindir;
866 IPin_QueryDirection(ppin, &pindir);
867 if (pindir == PINDIR_OUTPUT)
868 (*pppins)[i++] = ppin;
872 IEnumPins_Release(penumpins);
875 WARN("Next failed (%x)\n", hr);
878 } else if (FAILED(hr)) {
879 WARN("Cannot get internal connection (%x)\n", hr);
887 /*** IGraphBuilder methods ***/
888 static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, IPin *ppinIn)
890 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
892 AM_MEDIA_TYPE* mt = NULL;
893 IEnumMediaTypes* penummt = NULL;
895 IEnumPins* penumpins;
896 IEnumMoniker* pEnumMoniker;
905 TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
907 if (TRACE_ON(quartz))
909 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
913 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
914 IBaseFilter_Release(PinInfo.pFilter);
916 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
920 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
921 IBaseFilter_Release(PinInfo.pFilter);
924 EnterCriticalSection(&This->cs);
925 ++This->recursioncount;
926 if (This->recursioncount >= 5)
928 WARN("Recursion count has reached %d\n", This->recursioncount);
929 hr = VFW_E_CANNOT_CONNECT;
933 hr = IPin_QueryDirection(ppinOut, &dir);
937 if (dir == PINDIR_INPUT)
946 hr = CheckCircularConnection(This, ppinOut, ppinIn);
950 /* Try direct connection first */
951 hr = IPin_Connect(ppinOut, ppinIn, NULL);
955 TRACE("Direct connection failed, trying to render using extra filters\n");
957 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
961 hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
962 IBaseFilter_Release(PinInfo.pFilter);
966 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
967 * filter to the minor mediatype of input pin of the renderer */
968 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
971 WARN("EnumMediaTypes (%x)\n", hr);
975 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
977 WARN("IEnumMediaTypes_Next (%x)\n", hr);
983 WARN("No media type found!\n");
984 hr = VFW_E_INVALIDMEDIATYPE;
987 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
988 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
990 /* Try to find a suitable filter that can connect to the pin to render */
991 tab[0] = mt->majortype;
992 tab[1] = mt->subtype;
993 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
995 WARN("Unable to enum filters (%x)\n", hr);
999 hr = VFW_E_CANNOT_RENDER;
1000 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1005 IPin* ppinfilter = NULL;
1006 IBaseFilter* pfilter = NULL;
1008 hr = GetFilterInfo(pMoniker, &clsid, &var);
1009 IMoniker_Release(pMoniker);
1011 WARN("Unable to retrieve filter info (%x)\n", hr);
1015 if (IsEqualGUID(&clsid, &FilterCLSID)) {
1016 /* Skip filter (same as the one the output pin belongs to) */
1020 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
1022 WARN("Unable to create filter (%x), trying next one\n", hr);
1026 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
1028 WARN("Unable to add filter (%x)\n", hr);
1029 IBaseFilter_Release(pfilter);
1036 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
1038 WARN("Enumpins (%x)\n", hr);
1042 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
1043 IEnumPins_Release(penumpins);
1046 WARN("Obtaining next pin: (%x)\n", hr);
1050 WARN("Cannot use this filter: no pins\n");
1054 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
1056 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
1059 TRACE("Successfully connected to filter, follow chain...\n");
1061 /* Render all output pins of the filter by calling IFilterGraph2_Connect on each of them */
1062 hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
1064 if (SUCCEEDED(hr)) {
1067 IPin_Disconnect(ppinfilter);
1068 IPin_Disconnect(ppinOut);
1071 TRACE("pins to consider: %d\n", nb);
1072 for(i = 0; i < nb; i++)
1074 LPWSTR pinname = NULL;
1076 TRACE("Processing pin %u\n", i);
1078 hr = IPin_QueryId(ppins[i], &pinname);
1081 if (pinname[0] == '~')
1083 TRACE("Pinname=%s, skipping\n", debugstr_w(pinname));
1087 hr = IFilterGraph2_Connect(iface, ppins[i], ppinIn);
1088 CoTaskMemFree(pinname);
1092 TRACE("Cannot connect pin %p (%x)\n", ppinfilter, hr);
1094 IPin_Release(ppins[i]);
1095 if (SUCCEEDED(hr)) break;
1097 while (++i < nb) IPin_Release(ppins[i]);
1098 CoTaskMemFree(ppins);
1099 IPin_Release(ppinfilter);
1100 IBaseFilter_Release(pfilter);
1103 IPin_Disconnect(ppinfilter);
1104 IPin_Disconnect(ppinOut);
1105 IFilterGraph2_RemoveFilter(iface, pfilter);
1113 if (ppinfilter) IPin_Release(ppinfilter);
1115 IFilterGraph2_RemoveFilter(iface, pfilter);
1116 IBaseFilter_Release(pfilter);
1122 IEnumMediaTypes_Release(penummt);
1124 DeleteMediaType(mt);
1125 --This->recursioncount;
1126 LeaveCriticalSection(&This->cs);
1127 TRACE("--> %08x\n", hr);
1128 return SUCCEEDED(hr) ? S_OK : hr;
1131 static HRESULT FilterGraph2_RenderRecurse(IFilterGraphImpl *This, IPin *ppinOut)
1133 /* This pin has been connected now, try to call render on all pins that aren't connected */
1136 IEnumPins *enumpins = NULL;
1137 BOOL renderany = FALSE;
1138 BOOL renderall = TRUE;
1140 IPin_QueryPinInfo(ppinOut, &info);
1142 IBaseFilter_EnumPins(info.pFilter, &enumpins);
1143 /* Don't need to hold a reference, IEnumPins does */
1144 IBaseFilter_Release(info.pFilter);
1146 IEnumPins_Reset(enumpins);
1147 while (IEnumPins_Next(enumpins, 1, &to, NULL) == S_OK)
1149 PIN_DIRECTION dir = PINDIR_INPUT;
1151 IPin_QueryDirection(to, &dir);
1153 if (dir == PINDIR_OUTPUT)
1157 IPin_ConnectedTo(to, &out);
1161 hr = IFilterGraph2_Render((IFilterGraph2 *)&This->IFilterGraph2_vtbl, to);
1174 IEnumPins_Release(enumpins);
1180 return VFW_S_PARTIAL_RENDER;
1182 return VFW_E_CANNOT_RENDER;
1185 /* Ogg hates me if I create a direct rendering method
1187 * It can only connect to a pin properly once, so use a recursive method that does
1189 * +----+ --- (PIN 1) (Render is called on this pin)
1191 * +----+ --- (PIN 2)
1193 * Enumerate possible renderers that EXACTLY match the requested type
1195 * If none is available, try to add intermediate filters that can connect to the input pin
1196 * then call Render on that intermediate pin's output pins
1197 * if it succeeds: Render returns success, if it doesn't, the intermediate filter is removed,
1198 * and another filter that can connect to the input pin is tried
1199 * if we run out of filters that can, give up and return VFW_E_CANNOT_RENDER
1200 * It's recursive, but fun!
1203 static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
1205 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1206 IEnumMediaTypes* penummt;
1211 IEnumMoniker* pEnumMoniker;
1217 TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
1219 if (TRACE_ON(quartz))
1223 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
1227 TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
1228 IBaseFilter_Release(PinInfo.pFilter);
1231 /* Try to find out if there is a renderer for the specified subtype already, and use that
1233 EnterCriticalSection(&This->cs);
1234 for (x = 0; x < This->nFilters; ++x)
1236 IEnumPins *enumpins = NULL;
1239 hr = IBaseFilter_EnumPins(This->ppFiltersInGraph[x], &enumpins);
1241 if (FAILED(hr) || !enumpins)
1244 IEnumPins_Reset(enumpins);
1245 while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK)
1248 PIN_DIRECTION dir = PINDIR_OUTPUT;
1250 IPin_QueryDirection(pin, &dir);
1251 if (dir != PINDIR_INPUT)
1256 IPin_ConnectedTo(pin, &to);
1260 hr = FilterGraph2_ConnectDirect(iface, ppinOut, pin, NULL);
1263 TRACE("Connected successfully %p/%p, %08x look if we should render more!\n", ppinOut, pin, hr);
1266 hr = FilterGraph2_RenderRecurse(This, pin);
1269 IPin_Disconnect(ppinOut);
1270 IPin_Disconnect(pin);
1273 IEnumPins_Release(enumpins);
1274 LeaveCriticalSection(&This->cs);
1277 WARN("Could not connect!\n");
1284 IEnumPins_Release(enumpins);
1287 LeaveCriticalSection(&This->cs);
1289 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
1291 WARN("EnumMediaTypes (%x)\n", hr);
1295 IEnumMediaTypes_Reset(penummt);
1297 /* Looks like no existing renderer of the kind exists
1298 * Try adding new ones
1300 tab[0] = tab[1] = GUID_NULL;
1301 while (SUCCEEDED(hr))
1303 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
1305 WARN("IEnumMediaTypes_Next (%x)\n", hr);
1310 hr = VFW_E_CANNOT_RENDER;
1315 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
1316 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
1318 /* Only enumerate once, this doesn't account for all previous ones, but this should be enough nonetheless */
1319 if (IsEqualIID(&tab[0], &mt->majortype) && IsEqualIID(&tab[1], &mt->subtype))
1321 DeleteMediaType(mt);
1325 /* Try to find a suitable renderer with the same media type */
1326 tab[0] = mt->majortype;
1327 tab[1] = mt->subtype;
1328 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
1331 WARN("Unable to enum filters (%x)\n", hr);
1337 while (IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1342 IBaseFilter* pfilter = NULL;
1343 IEnumPins* penumpins = NULL;
1346 hr = GetFilterInfo(pMoniker, &clsid, &var);
1347 IMoniker_Release(pMoniker);
1349 WARN("Unable to retrieve filter info (%x)\n", hr);
1353 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
1356 WARN("Unable to create filter (%x), trying next one\n", hr);
1360 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
1362 WARN("Unable to add filter (%x)\n", hr);
1363 IBaseFilter_Release(pfilter);
1368 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
1370 WARN("Splitter Enumpins (%x)\n", hr);
1374 while ((hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin)) == S_OK)
1384 hr = IPin_QueryDirection(ppinfilter, &dir);
1386 IPin_Release(ppinfilter);
1387 WARN("QueryDirection failed (%x)\n", hr);
1390 if (dir != PINDIR_INPUT) {
1391 IPin_Release(ppinfilter);
1392 continue; /* Wrong direction */
1395 /* Connect the pin to the "Renderer" */
1396 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
1397 IPin_Release(ppinfilter);
1400 WARN("Unable to connect %s to renderer (%x)\n", debugstr_w(V_UNION(&var, bstrVal)), hr);
1403 TRACE("Connected, recursing %s\n", debugstr_w(V_UNION(&var, bstrVal)));
1407 hr = FilterGraph2_RenderRecurse(This, ppinfilter);
1409 WARN("Unable to connect recursively (%x)\n", hr);
1412 IBaseFilter_Release(pfilter);
1415 if (SUCCEEDED(hr)) {
1416 IEnumPins_Release(penumpins);
1417 break; /* out of IEnumMoniker_Next loop */
1420 /* IEnumPins_Next failed, all other failure case caught by goto error */
1421 WARN("IEnumPins_Next (%x)\n", hr);
1427 IEnumPins_Release(penumpins);
1429 IFilterGraph2_RemoveFilter(iface, pfilter);
1430 IBaseFilter_Release(pfilter);
1432 if (SUCCEEDED(hr)) DebugBreak();
1435 IEnumMoniker_Release(pEnumMoniker);
1437 DeleteMediaType(mt);
1443 IEnumMediaTypes_Release(penummt);
1447 static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface,
1448 LPCWSTR lpcwstrFile,
1449 LPCWSTR lpcwstrPlayList)
1451 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1452 static const WCHAR string[] = {'R','e','a','d','e','r',0};
1453 IBaseFilter* preader = NULL;
1454 IPin* ppinreader = NULL;
1455 IEnumPins* penumpins = NULL;
1457 BOOL partial = FALSE;
1458 HRESULT any = FALSE;
1460 TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
1462 if (lpcwstrPlayList != NULL)
1463 return E_INVALIDARG;
1465 hr = IFilterGraph2_AddSourceFilter(iface, lpcwstrFile, string, &preader);
1470 hr = IBaseFilter_EnumPins(preader, &penumpins);
1473 while (IEnumPins_Next(penumpins, 1, &ppinreader, NULL) == S_OK)
1477 IPin_QueryDirection(ppinreader, &dir);
1478 if (dir == PINDIR_OUTPUT)
1482 hr = IFilterGraph2_Render(iface, ppinreader);
1483 TRACE("Render %08x\n", hr);
1485 for (i = 0; i < This->nFilters; ++i)
1486 TRACE("Filters in chain: %s\n", debugstr_w(This->pFilterNames[i]));
1493 IPin_Release(ppinreader);
1495 IEnumPins_Release(penumpins);
1498 hr = VFW_E_CANNOT_RENDER;
1500 hr = VFW_S_PARTIAL_RENDER;
1504 IBaseFilter_Release(preader);
1506 TRACE("--> %08x\n", hr);
1510 /* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */
1511 static HRESULT GetFileSourceFilter(LPCOLESTR pszFileName, IBaseFilter **filter)
1513 static const WCHAR wszReg[] = {'M','e','d','i','a',' ','T','y','p','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1518 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszReg, 0, KEY_READ, &extkey);
1519 hr = HRESULT_FROM_WIN32(lRet);
1523 static const WCHAR filtersource[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};
1524 WCHAR *ext = PathFindExtensionW(pszFileName);
1525 WCHAR clsid_key[39];
1527 DWORD size = sizeof(clsid_key);
1532 CloseHandle(extkey);
1536 lRet = RegOpenKeyExW(extkey, ext, 0, KEY_READ, &pathkey);
1537 hr = HRESULT_FROM_WIN32(lRet);
1538 CloseHandle(extkey);
1542 lRet = RegQueryValueExW(pathkey, filtersource, NULL, NULL, (LPBYTE)clsid_key, &size);
1543 hr = HRESULT_FROM_WIN32(lRet);
1544 CloseHandle(pathkey);
1548 CLSIDFromString(clsid_key, &clsid);
1550 TRACE("CLSID: %s\n", debugstr_guid(&clsid));
1551 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter);
1554 IFileSourceFilter *source = NULL;
1555 hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source);
1557 IFileSourceFilter_Release(source);
1559 IBaseFilter_Release(*filter);
1567 static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface,
1568 LPCWSTR lpcwstrFileName,
1569 LPCWSTR lpcwstrFilterName,
1570 IBaseFilter **ppFilter) {
1571 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1573 IBaseFilter* preader;
1574 IFileSourceFilter* pfile = NULL;
1578 TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
1580 /* Try from file name first, then fall back to default asynchronous reader */
1581 hr = GetFileSourceFilter(lpcwstrFileName, &preader);
1584 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
1586 WARN("Unable to create file source filter (%x)\n", hr);
1590 hr = IFilterGraph2_AddFilter(iface, preader, lpcwstrFilterName);
1592 WARN("Unable add filter (%x)\n", hr);
1593 IBaseFilter_Release(preader);
1597 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1599 WARN("Unable to get IFileSourceInterface (%x)\n", hr);
1603 /* Load the file in the file source filter */
1604 hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1606 WARN("Load (%x)\n", hr);
1610 IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1612 WARN("GetCurFile (%x)\n", hr);
1616 TRACE("File %s\n", debugstr_w(filename));
1617 TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1618 TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1621 *ppFilter = preader;
1622 IFileSourceFilter_Release(pfile);
1628 IFileSourceFilter_Release(pfile);
1629 IFilterGraph2_RemoveFilter(iface, preader);
1630 IBaseFilter_Release(preader);
1635 static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface,
1637 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1639 TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile);
1644 static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) {
1645 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1647 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1652 static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) {
1653 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1655 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1660 /*** IFilterGraph2 methods ***/
1661 static HRESULT WINAPI FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2 *iface,
1664 LPCWSTR lpcwstrFilterName,
1665 IBaseFilter **ppFilter) {
1666 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1668 TRACE("(%p/%p)->(%p %p %s %p): stub !!!\n", This, iface, pMoniker, pCtx, debugstr_w(lpcwstrFilterName), ppFilter);
1673 static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface,
1675 const AM_MEDIA_TYPE *pmt) {
1676 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1678 TRACE("(%p/%p)->(%p %p): stub !!!\n", This, iface, ppin, pmt);
1683 static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface,
1687 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1689 TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This, iface, pPinOut, dwFlags, pvContext);
1695 static const IFilterGraph2Vtbl IFilterGraph2_VTable =
1697 FilterGraph2_QueryInterface,
1698 FilterGraph2_AddRef,
1699 FilterGraph2_Release,
1700 FilterGraph2_AddFilter,
1701 FilterGraph2_RemoveFilter,
1702 FilterGraph2_EnumFilters,
1703 FilterGraph2_FindFilterByName,
1704 FilterGraph2_ConnectDirect,
1705 FilterGraph2_Reconnect,
1706 FilterGraph2_Disconnect,
1707 FilterGraph2_SetDefaultSyncSource,
1708 FilterGraph2_Connect,
1709 FilterGraph2_Render,
1710 FilterGraph2_RenderFile,
1711 FilterGraph2_AddSourceFilter,
1712 FilterGraph2_SetLogFile,
1714 FilterGraph2_ShouldOperationContinue,
1715 FilterGraph2_AddSourceFilterForMoniker,
1716 FilterGraph2_ReconnectEx,
1717 FilterGraph2_RenderEx
1720 /*** IUnknown methods ***/
1721 static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface,
1724 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1726 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1728 return Filtergraph_QueryInterface(This, riid, ppvObj);
1731 static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) {
1732 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1734 TRACE("(%p/%p)->()\n", This, iface);
1736 return Filtergraph_AddRef(This);
1739 static ULONG WINAPI MediaControl_Release(IMediaControl *iface) {
1740 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1742 TRACE("(%p/%p)->()\n", This, iface);
1744 return Filtergraph_Release(This);
1748 /*** IDispatch methods ***/
1749 static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface,
1751 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1753 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1758 static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface,
1761 ITypeInfo**ppTInfo) {
1762 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1764 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1769 static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface,
1775 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1777 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1782 static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
1783 DISPID dispIdMember,
1787 DISPPARAMS*pDispParams,
1789 EXCEPINFO*pExepInfo,
1791 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1793 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);
1798 typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *, DWORD_PTR data);
1800 static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter, DWORD_PTR data)
1809 TRACE("%p %p\n", pGraph, pOutputPin);
1810 PinInfo.pFilter = NULL;
1812 hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
1816 hr = IPin_QueryPinInfo(pInputPin, &PinInfo);
1818 hr = GetInternalConnections(PinInfo.pFilter, pInputPin, &ppPins, &nb);
1819 IPin_Release(pInputPin);
1826 TRACE("Reached a renderer\n");
1827 /* Count renderers for end of stream notification */
1828 pGraph->nRenderers++;
1832 for(i = 0; i < nb; i++)
1834 /* Explore the graph downstream from this pin
1835 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1836 * several input pins are connected to the same output (a MUX for instance). */
1837 ExploreGraph(pGraph, ppPins[i], FoundFilter, data);
1838 IPin_Release(ppPins[i]);
1841 CoTaskMemFree(ppPins);
1843 TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
1845 FoundFilter(PinInfo.pFilter, data);
1848 if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
1852 static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data)
1854 REFERENCE_TIME time = *(REFERENCE_TIME*)data;
1855 return IBaseFilter_Run(pFilter, time);
1858 static HRESULT WINAPI SendPause(IBaseFilter *pFilter, DWORD_PTR data)
1860 return IBaseFilter_Pause(pFilter);
1863 static HRESULT WINAPI SendStop(IBaseFilter *pFilter, DWORD_PTR data)
1865 return IBaseFilter_Stop(pFilter);
1868 static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data)
1871 DWORD time_end = data;
1872 DWORD time_now = GetTickCount();
1875 if (time_end == INFINITE)
1879 else if (time_end > time_now)
1881 wait = time_end - time_now;
1886 return IBaseFilter_GetState(pFilter, wait, &state);
1890 static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter, DWORD_PTR data)
1892 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1894 IBaseFilter* pfilter;
1900 TRACE("(%p/%p)->()\n", This, iface);
1902 /* Explorer the graph from source filters to renderers, determine renderers
1903 * number and run filters from renderers to source filters */
1904 This->nRenderers = 0;
1905 ResetEvent(This->hEventCompletion);
1907 for(i = 0; i < This->nFilters; i++)
1910 pfilter = This->ppFiltersInGraph[i];
1911 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1914 WARN("Enum pins failed %x\n", hr);
1917 /* Check if it is a source filter */
1918 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1920 IPin_QueryDirection(pPin, &dir);
1922 if (dir == PINDIR_INPUT)
1930 TRACE("Found a source filter %p\n", pfilter);
1931 IEnumPins_Reset(pEnum);
1932 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1934 /* Explore the graph downstream from this pin */
1935 ExploreGraph(This, pPin, FoundFilter, data);
1938 FoundFilter(pfilter, data);
1940 IEnumPins_Release(pEnum);
1946 /*** IMediaControl methods ***/
1947 static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
1948 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1949 TRACE("(%p/%p)->()\n", This, iface);
1951 EnterCriticalSection(&This->cs);
1952 if (This->state == State_Running)
1954 This->EcCompleteCount = 0;
1956 if (This->defaultclock && !This->refClock)
1957 IFilterGraph2_SetDefaultSyncSource((IFilterGraph2*)This);
1962 IReferenceClock_GetTime(This->refClock, &now);
1963 if (This->state == State_Stopped)
1964 This->start_time = now + 500000;
1965 else if (This->pause_time >= 0)
1966 This->start_time += now - This->pause_time;
1968 This->start_time = now;
1970 else This->start_time = 0;
1972 SendFilterMessage(iface, SendRun, (DWORD_PTR)&This->start_time);
1973 This->state = State_Running;
1975 LeaveCriticalSection(&This->cs);
1979 static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
1980 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1981 TRACE("(%p/%p)->()\n", This, iface);
1983 EnterCriticalSection(&This->cs);
1984 if (This->state == State_Paused)
1987 if (This->state == State_Running && This->refClock && This->start_time >= 0)
1988 IReferenceClock_GetTime(This->refClock, &This->pause_time);
1990 This->pause_time = -1;
1992 SendFilterMessage(iface, SendPause, 0);
1993 This->state = State_Paused;
1995 LeaveCriticalSection(&This->cs);
1999 static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
2000 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2001 TRACE("(%p/%p)->()\n", This, iface);
2003 if (This->state == State_Stopped) return S_OK;
2005 EnterCriticalSection(&This->cs);
2006 if (This->state == State_Running) SendFilterMessage(iface, SendPause, 0);
2007 SendFilterMessage(iface, SendStop, 0);
2008 This->state = State_Stopped;
2009 LeaveCriticalSection(&This->cs);
2013 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
2015 OAFilterState *pfs) {
2016 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2019 TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pfs);
2024 EnterCriticalSection(&This->cs);
2029 end = GetTickCount() + msTimeout;
2031 else if (msTimeout < 0)
2040 SendFilterMessage(iface, SendGetState, end);
2042 LeaveCriticalSection(&This->cs);
2047 static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface,
2049 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2051 FIXME("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
2056 static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface,
2058 IDispatch **ppUnk) {
2059 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2061 FIXME("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
2066 static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface,
2067 IDispatch **ppUnk) {
2068 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2070 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
2075 static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
2076 IDispatch **ppUnk) {
2077 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2079 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
2084 static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) {
2085 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
2087 FIXME("(%p/%p)->(): stub !!!\n", This, iface);
2093 static const IMediaControlVtbl IMediaControl_VTable =
2095 MediaControl_QueryInterface,
2096 MediaControl_AddRef,
2097 MediaControl_Release,
2098 MediaControl_GetTypeInfoCount,
2099 MediaControl_GetTypeInfo,
2100 MediaControl_GetIDsOfNames,
2101 MediaControl_Invoke,
2105 MediaControl_GetState,
2106 MediaControl_RenderFile,
2107 MediaControl_AddSourceFilter,
2108 MediaControl_get_FilterCollection,
2109 MediaControl_get_RegFilterCollection,
2110 MediaControl_StopWhenReady
2114 /*** IUnknown methods ***/
2115 static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface,
2118 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2120 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2122 return Filtergraph_QueryInterface(This, riid, ppvObj);
2125 static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) {
2126 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2128 TRACE("(%p/%p)->()\n", This, iface);
2130 return Filtergraph_AddRef(This);
2133 static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
2134 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2136 TRACE("(%p/%p)->()\n", This, iface);
2138 return Filtergraph_Release(This);
2141 typedef HRESULT (WINAPI *fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DWORD_PTR arg);
2143 static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) {
2144 BOOL allnotimpl = TRUE;
2146 HRESULT hr, hr_return = S_OK;
2148 TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg);
2149 /* Send a message to all renderers, they are responsible for broadcasting it further */
2151 for(i = 0; i < This->nFilters; i++)
2153 IMediaSeeking *seek = NULL;
2154 IBaseFilter* pfilter = This->ppFiltersInGraph[i];
2155 IAMFilterMiscFlags *flags = NULL;
2157 IUnknown_QueryInterface(pfilter, &IID_IAMFilterMiscFlags, (void**)&flags);
2160 filterflags = IAMFilterMiscFlags_GetMiscFlags(flags);
2161 IUnknown_Release(flags);
2162 if (filterflags != AM_FILTER_MISC_FLAGS_IS_RENDERER)
2165 IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek);
2168 hr = FoundSeek(This, seek, arg);
2169 IMediaSeeking_Release(seek);
2170 if (hr_return != E_NOTIMPL)
2172 if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && SUCCEEDED(hr_return)))
2181 static HRESULT WINAPI FoundCapabilities(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pcaps)
2186 hr = IMediaSeeking_GetCapabilities(seek, &caps);
2190 /* Only add common capabilities everything supports */
2191 *(DWORD*)pcaps &= caps;
2196 /*** IMediaSeeking methods ***/
2197 static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
2198 DWORD *pCapabilities) {
2199 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2201 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
2206 EnterCriticalSection(&This->cs);
2207 *pCapabilities = 0xffffffff;
2209 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
2210 LeaveCriticalSection(&This->cs);
2215 static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
2216 DWORD *pCapabilities) {
2217 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2220 TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
2225 EnterCriticalSection(&This->cs);
2226 originalcaps = *pCapabilities;
2227 hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
2228 LeaveCriticalSection(&This->cs);
2233 if (!*pCapabilities)
2235 if (*pCapabilities != originalcaps)
2240 static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface,
2241 const GUID *pFormat) {
2242 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2247 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
2249 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
2251 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
2258 static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface,
2260 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2265 FIXME("(%p/%p)->(%p): semi-stub !!!\n", This, iface, pFormat);
2266 memcpy(pFormat, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
2271 static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface,
2273 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2278 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
2279 memcpy(pFormat, &This->timeformatseek, sizeof(GUID));
2284 static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface,
2285 const GUID *pFormat) {
2286 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2288 TRACE("(%p/%p)->(%p)\n", This, iface, pFormat);
2292 if (memcmp(pFormat, &This->timeformatseek, sizeof(GUID)))
2298 static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
2299 const GUID *pFormat) {
2300 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2305 TRACE("(%p/%p)->(%s)\n", This, iface, debugstr_guid(pFormat));
2307 if (This->state != State_Stopped)
2308 return VFW_E_WRONG_STATE;
2310 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, pFormat))
2312 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat));
2313 return E_INVALIDARG;
2319 static HRESULT WINAPI FoundDuration(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pduration)
2322 LONGLONG duration = 0, *pdur = (LONGLONG*)pduration;
2324 hr = IMediaSeeking_GetDuration(seek, &duration);
2328 if (*pdur < duration)
2333 static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
2334 LONGLONG *pDuration) {
2335 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2338 TRACE("(%p/%p)->(%p)\n", This, iface, pDuration);
2343 EnterCriticalSection(&This->cs);
2345 hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration);
2346 LeaveCriticalSection(&This->cs);
2348 TRACE("--->%08x\n", hr);
2352 static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
2354 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2357 TRACE("(%p/%p)->(%p)\n", This, iface, pStop);
2362 EnterCriticalSection(&This->cs);
2363 if (This->stop_position < 0)
2364 /* Stop position not set, use duration instead */
2365 hr = IMediaSeeking_GetDuration(iface, pStop);
2367 *pStop = This->stop_position;
2368 LeaveCriticalSection(&This->cs);
2373 static HRESULT WINAPI FoundCurrentPosition(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pposition)
2376 LONGLONG pos = 0, *ppos = (LONGLONG*)pposition;
2378 hr = IMediaSeeking_GetCurrentPosition(seek, &pos);
2382 if (*ppos < 0 || pos < *ppos)
2387 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
2388 LONGLONG *pCurrent) {
2389 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2395 EnterCriticalSection(&This->cs);
2397 hr = all_renderers_seek(This, FoundCurrentPosition, (DWORD_PTR)pCurrent);
2398 if (hr == E_NOTIMPL) {
2402 LeaveCriticalSection(&This->cs);
2404 TRACE("Time: %u.%03u\n", (DWORD)(*pCurrent / 10000000), (DWORD)((*pCurrent / 10000)%1000));
2409 static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface,
2411 const GUID *pTargetFormat,
2413 const GUID *pSourceFormat) {
2414 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2416 FIXME("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget,
2417 pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat);
2423 LONGLONG* current, *stop;
2424 DWORD curflags, stopflags;
2427 static HRESULT WINAPI found_setposition(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pargs)
2429 struct pos_args *args = (void*)pargs;
2431 return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags);
2434 static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface,
2436 DWORD dwCurrentFlags,
2438 DWORD dwStopFlags) {
2439 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2442 struct pos_args args;
2444 TRACE("(%p/%p)->(%p, %08x, %p, %08x)\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
2446 EnterCriticalSection(&This->cs);
2447 state = This->state;
2448 TRACE("State: %s\n", state == State_Running ? "Running" : (state == State_Paused ? "Paused" : (state == State_Stopped ? "Stopped" : "UNKNOWN")));
2450 if ((dwCurrentFlags & 0x7) != AM_SEEKING_AbsolutePositioning &&
2451 (dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning)
2452 FIXME("Adjust method %x not handled yet!\n", dwCurrentFlags & 0x7);
2454 if ((dwStopFlags & 0x7) == AM_SEEKING_AbsolutePositioning)
2455 This->stop_position = *pStop;
2456 else if ((dwStopFlags & 0x7) != AM_SEEKING_NoPositioning)
2457 FIXME("Stop position not handled yet!\n");
2459 args.current = pCurrent;
2461 args.curflags = dwCurrentFlags;
2462 args.stopflags = dwStopFlags;
2463 hr = all_renderers_seek(This, found_setposition, (DWORD_PTR)&args);
2465 if ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning) {
2466 if (This->state == State_Running)
2467 FIXME("Seeking while graph is running is not properly supported!\n");
2468 This->pause_time = This->start_time = -1;
2470 LeaveCriticalSection(&This->cs);
2475 static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
2478 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2481 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pCurrent, pStop);
2482 hr = IMediaSeeking_GetCurrentPosition(iface, pCurrent);
2484 hr = IMediaSeeking_GetStopPosition(iface, pStop);
2489 static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
2490 LONGLONG *pEarliest,
2491 LONGLONG *pLatest) {
2492 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2494 FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
2499 static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface,
2501 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2503 FIXME("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
2508 static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface,
2510 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2512 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
2517 static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface,
2518 LONGLONG *pllPreroll) {
2519 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
2521 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
2527 static const IMediaSeekingVtbl IMediaSeeking_VTable =
2529 MediaSeeking_QueryInterface,
2530 MediaSeeking_AddRef,
2531 MediaSeeking_Release,
2532 MediaSeeking_GetCapabilities,
2533 MediaSeeking_CheckCapabilities,
2534 MediaSeeking_IsFormatSupported,
2535 MediaSeeking_QueryPreferredFormat,
2536 MediaSeeking_GetTimeFormat,
2537 MediaSeeking_IsUsingTimeFormat,
2538 MediaSeeking_SetTimeFormat,
2539 MediaSeeking_GetDuration,
2540 MediaSeeking_GetStopPosition,
2541 MediaSeeking_GetCurrentPosition,
2542 MediaSeeking_ConvertTimeFormat,
2543 MediaSeeking_SetPositions,
2544 MediaSeeking_GetPositions,
2545 MediaSeeking_GetAvailable,
2546 MediaSeeking_SetRate,
2547 MediaSeeking_GetRate,
2548 MediaSeeking_GetPreroll
2551 static inline IFilterGraphImpl *impl_from_IMediaPosition( IMediaPosition *iface )
2553 return (IFilterGraphImpl *)((char*)iface - FIELD_OFFSET(IFilterGraphImpl, IMediaPosition_vtbl));
2556 /*** IUnknown methods ***/
2557 static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID riid, void** ppvObj)
2559 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2561 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2562 return Filtergraph_QueryInterface(This, riid, ppvObj);
2565 static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface)
2567 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2569 TRACE("(%p/%p)->()\n", This, iface);
2570 return Filtergraph_AddRef(This);
2573 static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface)
2575 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2577 TRACE("(%p/%p)->()\n", This, iface);
2578 return Filtergraph_Release(This);
2581 /*** IDispatch methods ***/
2582 static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){
2583 FIXME("(%p) stub!\n", iface);
2587 static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){
2588 FIXME("(%p) stub!\n", iface);
2592 static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){
2593 FIXME("(%p) stub!\n", iface);
2597 static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){
2598 FIXME("(%p) stub!\n", iface);
2602 /*** IMediaPosition methods ***/
2603 static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength)
2606 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2607 HRESULT hr = IMediaSeeking_GetDuration( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &duration );
2608 if (SUCCEEDED(hr)) *plength = duration;
2612 static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime)
2614 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2615 LONGLONG reftime = llTime;
2617 return IMediaSeeking_SetPositions((IMediaSeeking *)&This->IMediaSeeking_vtbl,
2618 &reftime, AM_SEEKING_AbsolutePositioning,
2619 NULL, AM_SEEKING_NoPositioning);
2622 static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime)
2624 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2626 HRESULT hr = IMediaSeeking_GetCurrentPosition( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &pos );
2627 if (SUCCEEDED(hr)) *pllTime = pos;
2631 static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime)
2633 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2635 HRESULT hr = IMediaSeeking_GetStopPosition( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &pos );
2636 if (SUCCEEDED(hr)) *pllTime = pos;
2640 static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime)
2642 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2643 LONGLONG reftime = llTime;
2645 return IMediaSeeking_SetPositions((IMediaSeeking *)&This->IMediaSeeking_vtbl,
2646 NULL, AM_SEEKING_NoPositioning,
2647 &reftime, AM_SEEKING_AbsolutePositioning);
2650 static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){
2651 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
2655 static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){
2656 FIXME("(%p)->(%f) stub!\n", iface, llTime);
2660 static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate)
2662 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2663 return IMediaSeeking_SetRate((IMediaSeeking *)&This->IMediaSeeking_vtbl, dRate);
2666 static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate)
2668 IFilterGraphImpl *This = impl_from_IMediaPosition( iface );
2669 return IMediaSeeking_GetRate((IMediaSeeking *)&This->IMediaSeeking_vtbl, pdRate);
2672 static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){
2673 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward);
2677 static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){
2678 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward);
2683 static const IMediaPositionVtbl IMediaPosition_VTable =
2685 MediaPosition_QueryInterface,
2686 MediaPosition_AddRef,
2687 MediaPosition_Release,
2688 MediaPosition_GetTypeInfoCount,
2689 MediaPosition_GetTypeInfo,
2690 MediaPosition_GetIDsOfNames,
2691 MediaPosition_Invoke,
2692 MediaPosition_get_Duration,
2693 MediaPosition_put_CurrentPosition,
2694 MediaPosition_get_CurrentPosition,
2695 MediaPosition_get_StopTime,
2696 MediaPosition_put_StopTime,
2697 MediaPosition_get_PrerollTime,
2698 MediaPosition_put_PrerollTime,
2699 MediaPosition_put_Rate,
2700 MediaPosition_get_Rate,
2701 MediaPosition_CanSeekForward,
2702 MediaPosition_CanSeekBackward
2705 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
2707 HRESULT hr = E_NOINTERFACE;
2711 /* Check if the interface type is already registered */
2712 for (entry = 0; entry < pGraph->nItfCacheEntries; entry++)
2713 if (riid == pGraph->ItfCacheEntries[entry].riid)
2715 if (pGraph->ItfCacheEntries[entry].iface)
2717 /* Return the interface if available */
2718 *ppvObj = pGraph->ItfCacheEntries[entry].iface;
2724 if (entry >= MAX_ITF_CACHE_ENTRIES)
2726 FIXME("Not enough space to store interface in the cache\n");
2727 return E_OUTOFMEMORY;
2730 /* Find a filter supporting the requested interface */
2731 for (i = 0; i < pGraph->nFilters; i++)
2733 hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
2736 pGraph->ItfCacheEntries[entry].riid = riid;
2737 pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
2738 pGraph->ItfCacheEntries[entry].iface = *ppvObj;
2739 if (entry >= pGraph->nItfCacheEntries)
2740 pGraph->nItfCacheEntries++;
2743 if (hr != E_NOINTERFACE)
2750 /*** IUnknown methods ***/
2751 static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface,
2754 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2756 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2758 return Filtergraph_QueryInterface(This, riid, ppvObj);
2761 static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) {
2762 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2764 TRACE("(%p/%p)->()\n", This, iface);
2766 return Filtergraph_AddRef(This);
2769 static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) {
2770 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2772 TRACE("(%p/%p)->()\n", This, iface);
2774 return Filtergraph_Release(This);
2777 /*** IDispatch methods ***/
2778 static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface,
2780 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2781 IBasicAudio* pBasicAudio;
2784 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2786 EnterCriticalSection(&This->cs);
2788 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2791 hr = IBasicAudio_GetTypeInfoCount(pBasicAudio, pctinfo);
2793 LeaveCriticalSection(&This->cs);
2798 static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface,
2801 ITypeInfo**ppTInfo) {
2802 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2803 IBasicAudio* pBasicAudio;
2806 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2808 EnterCriticalSection(&This->cs);
2810 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2813 hr = IBasicAudio_GetTypeInfo(pBasicAudio, iTInfo, lcid, ppTInfo);
2815 LeaveCriticalSection(&This->cs);
2820 static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface,
2826 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2827 IBasicAudio* pBasicAudio;
2830 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2832 EnterCriticalSection(&This->cs);
2834 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2837 hr = IBasicAudio_GetIDsOfNames(pBasicAudio, riid, rgszNames, cNames, lcid, rgDispId);
2839 LeaveCriticalSection(&This->cs);
2844 static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface,
2845 DISPID dispIdMember,
2849 DISPPARAMS*pDispParams,
2851 EXCEPINFO*pExepInfo,
2853 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2854 IBasicAudio* pBasicAudio;
2857 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);
2859 EnterCriticalSection(&This->cs);
2861 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2864 hr = IBasicAudio_Invoke(pBasicAudio, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2866 LeaveCriticalSection(&This->cs);
2871 /*** IBasicAudio methods ***/
2872 static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface,
2874 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2875 IBasicAudio* pBasicAudio;
2878 TRACE("(%p/%p)->(%d)\n", This, iface, lVolume);
2880 EnterCriticalSection(&This->cs);
2882 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2885 hr = IBasicAudio_put_Volume(pBasicAudio, lVolume);
2887 LeaveCriticalSection(&This->cs);
2892 static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface,
2894 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2895 IBasicAudio* pBasicAudio;
2898 TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
2900 EnterCriticalSection(&This->cs);
2902 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2905 hr = IBasicAudio_get_Volume(pBasicAudio, plVolume);
2907 LeaveCriticalSection(&This->cs);
2912 static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface,
2914 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2915 IBasicAudio* pBasicAudio;
2918 TRACE("(%p/%p)->(%d)\n", This, iface, lBalance);
2920 EnterCriticalSection(&This->cs);
2922 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2925 hr = IBasicAudio_put_Balance(pBasicAudio, lBalance);
2927 LeaveCriticalSection(&This->cs);
2932 static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface,
2934 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2935 IBasicAudio* pBasicAudio;
2938 TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
2940 EnterCriticalSection(&This->cs);
2942 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2945 hr = IBasicAudio_get_Balance(pBasicAudio, plBalance);
2947 LeaveCriticalSection(&This->cs);
2952 static const IBasicAudioVtbl IBasicAudio_VTable =
2954 BasicAudio_QueryInterface,
2957 BasicAudio_GetTypeInfoCount,
2958 BasicAudio_GetTypeInfo,
2959 BasicAudio_GetIDsOfNames,
2961 BasicAudio_put_Volume,
2962 BasicAudio_get_Volume,
2963 BasicAudio_put_Balance,
2964 BasicAudio_get_Balance
2967 /*** IUnknown methods ***/
2968 static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo2 *iface,
2971 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2973 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2975 return Filtergraph_QueryInterface(This, riid, ppvObj);
2978 static ULONG WINAPI BasicVideo_AddRef(IBasicVideo2 *iface) {
2979 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2981 TRACE("(%p/%p)->()\n", This, iface);
2983 return Filtergraph_AddRef(This);
2986 static ULONG WINAPI BasicVideo_Release(IBasicVideo2 *iface) {
2987 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2989 TRACE("(%p/%p)->()\n", This, iface);
2991 return Filtergraph_Release(This);
2994 /*** IDispatch methods ***/
2995 static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo2 *iface,
2997 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2998 IBasicVideo* pBasicVideo;
3001 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3003 EnterCriticalSection(&This->cs);
3005 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3008 hr = IBasicVideo_GetTypeInfoCount(pBasicVideo, pctinfo);
3010 LeaveCriticalSection(&This->cs);
3015 static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo2 *iface,
3018 ITypeInfo**ppTInfo) {
3019 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3020 IBasicVideo* pBasicVideo;
3023 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3025 EnterCriticalSection(&This->cs);
3027 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3030 hr = IBasicVideo_GetTypeInfo(pBasicVideo, iTInfo, lcid, ppTInfo);
3032 LeaveCriticalSection(&This->cs);
3037 static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo2 *iface,
3043 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3044 IBasicVideo* pBasicVideo;
3047 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3049 EnterCriticalSection(&This->cs);
3051 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3054 hr = IBasicVideo_GetIDsOfNames(pBasicVideo, riid, rgszNames, cNames, lcid, rgDispId);
3056 LeaveCriticalSection(&This->cs);
3061 static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo2 *iface,
3062 DISPID dispIdMember,
3066 DISPPARAMS*pDispParams,
3068 EXCEPINFO*pExepInfo,
3070 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3071 IBasicVideo* pBasicVideo;
3074 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);
3076 EnterCriticalSection(&This->cs);
3078 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3081 hr = IBasicVideo_Invoke(pBasicVideo, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3083 LeaveCriticalSection(&This->cs);
3088 /*** IBasicVideo methods ***/
3089 static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo2 *iface,
3090 REFTIME *pAvgTimePerFrame) {
3091 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3092 IBasicVideo* pBasicVideo;
3095 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
3097 EnterCriticalSection(&This->cs);
3099 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3102 hr = IBasicVideo_get_AvgTimePerFrame(pBasicVideo, pAvgTimePerFrame);
3104 LeaveCriticalSection(&This->cs);
3109 static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo2 *iface,
3111 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3112 IBasicVideo* pBasicVideo;
3115 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
3117 EnterCriticalSection(&This->cs);
3119 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3122 hr = IBasicVideo_get_BitRate(pBasicVideo, pBitRate);
3124 LeaveCriticalSection(&This->cs);
3129 static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo2 *iface,
3130 LONG *pBitErrorRate) {
3131 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3132 IBasicVideo* pBasicVideo;
3135 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
3137 EnterCriticalSection(&This->cs);
3139 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3142 hr = IBasicVideo_get_BitErrorRate(pBasicVideo, pBitErrorRate);
3144 LeaveCriticalSection(&This->cs);
3149 static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo2 *iface,
3150 LONG *pVideoWidth) {
3151 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3152 IBasicVideo* pBasicVideo;
3155 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
3157 EnterCriticalSection(&This->cs);
3159 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3162 hr = IBasicVideo_get_VideoWidth(pBasicVideo, pVideoWidth);
3164 LeaveCriticalSection(&This->cs);
3169 static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo2 *iface,
3170 LONG *pVideoHeight) {
3171 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3172 IBasicVideo* pBasicVideo;
3175 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
3177 EnterCriticalSection(&This->cs);
3179 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3182 hr = IBasicVideo_get_VideoHeight(pBasicVideo, pVideoHeight);
3184 LeaveCriticalSection(&This->cs);
3189 static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo2 *iface,
3191 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3192 IBasicVideo* pBasicVideo;
3195 TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft);
3197 EnterCriticalSection(&This->cs);
3199 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3202 hr = IBasicVideo_put_SourceLeft(pBasicVideo, SourceLeft);
3204 LeaveCriticalSection(&This->cs);
3209 static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo2 *iface,
3210 LONG *pSourceLeft) {
3211 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3212 IBasicVideo* pBasicVideo;
3215 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
3217 EnterCriticalSection(&This->cs);
3219 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3222 hr = IBasicVideo_get_SourceLeft(pBasicVideo, pSourceLeft);
3224 LeaveCriticalSection(&This->cs);
3229 static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo2 *iface,
3231 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3232 IBasicVideo* pBasicVideo;
3235 TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth);
3237 EnterCriticalSection(&This->cs);
3239 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3242 hr = IBasicVideo_put_SourceWidth(pBasicVideo, SourceWidth);
3244 LeaveCriticalSection(&This->cs);
3249 static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo2 *iface,
3250 LONG *pSourceWidth) {
3251 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3252 IBasicVideo* pBasicVideo;
3255 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
3257 EnterCriticalSection(&This->cs);
3259 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3262 hr = IBasicVideo_get_SourceWidth(pBasicVideo, pSourceWidth);
3264 LeaveCriticalSection(&This->cs);
3269 static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo2 *iface,
3271 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3272 IBasicVideo* pBasicVideo;
3275 TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop);
3277 EnterCriticalSection(&This->cs);
3279 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3282 hr = IBasicVideo_put_SourceTop(pBasicVideo, SourceTop);
3284 LeaveCriticalSection(&This->cs);
3289 static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo2 *iface,
3291 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3292 IBasicVideo* pBasicVideo;
3295 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
3297 EnterCriticalSection(&This->cs);
3299 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3302 hr = IBasicVideo_get_SourceTop(pBasicVideo, pSourceTop);
3304 LeaveCriticalSection(&This->cs);
3309 static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo2 *iface,
3310 LONG SourceHeight) {
3311 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3312 IBasicVideo* pBasicVideo;
3315 TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight);
3317 EnterCriticalSection(&This->cs);
3319 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3322 hr = IBasicVideo_put_SourceHeight(pBasicVideo, SourceHeight);
3324 LeaveCriticalSection(&This->cs);
3329 static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo2 *iface,
3330 LONG *pSourceHeight) {
3331 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3332 IBasicVideo* pBasicVideo;
3335 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
3337 EnterCriticalSection(&This->cs);
3339 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3342 hr = IBasicVideo_get_SourceHeight(pBasicVideo, pSourceHeight);
3344 LeaveCriticalSection(&This->cs);
3349 static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo2 *iface,
3350 LONG DestinationLeft) {
3351 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3352 IBasicVideo* pBasicVideo;
3355 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft);
3357 EnterCriticalSection(&This->cs);
3359 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3362 hr = IBasicVideo_put_DestinationLeft(pBasicVideo, DestinationLeft);
3364 LeaveCriticalSection(&This->cs);
3369 static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo2 *iface,
3370 LONG *pDestinationLeft) {
3371 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3372 IBasicVideo* pBasicVideo;
3375 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
3377 EnterCriticalSection(&This->cs);
3379 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3382 hr = IBasicVideo_get_DestinationLeft(pBasicVideo, pDestinationLeft);
3384 LeaveCriticalSection(&This->cs);
3389 static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo2 *iface,
3390 LONG DestinationWidth) {
3391 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3392 IBasicVideo* pBasicVideo;
3395 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth);
3397 EnterCriticalSection(&This->cs);
3399 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3402 hr = IBasicVideo_put_DestinationWidth(pBasicVideo, DestinationWidth);
3404 LeaveCriticalSection(&This->cs);
3409 static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo2 *iface,
3410 LONG *pDestinationWidth) {
3411 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3412 IBasicVideo* pBasicVideo;
3415 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
3417 EnterCriticalSection(&This->cs);
3419 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3422 hr = IBasicVideo_get_DestinationWidth(pBasicVideo, pDestinationWidth);
3424 LeaveCriticalSection(&This->cs);
3429 static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo2 *iface,
3430 LONG DestinationTop) {
3431 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3432 IBasicVideo* pBasicVideo;
3435 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop);
3437 EnterCriticalSection(&This->cs);
3439 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3442 hr = IBasicVideo_put_DestinationTop(pBasicVideo, DestinationTop);
3444 LeaveCriticalSection(&This->cs);
3449 static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo2 *iface,
3450 LONG *pDestinationTop) {
3451 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3452 IBasicVideo* pBasicVideo;
3455 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
3457 EnterCriticalSection(&This->cs);
3459 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3462 hr = IBasicVideo_get_DestinationTop(pBasicVideo, pDestinationTop);
3464 LeaveCriticalSection(&This->cs);
3469 static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo2 *iface,
3470 LONG DestinationHeight) {
3471 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3472 IBasicVideo* pBasicVideo;
3475 TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight);
3477 EnterCriticalSection(&This->cs);
3479 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3482 hr = IBasicVideo_put_DestinationHeight(pBasicVideo, DestinationHeight);
3484 LeaveCriticalSection(&This->cs);
3489 static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo2 *iface,
3490 LONG *pDestinationHeight) {
3491 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3492 IBasicVideo* pBasicVideo;
3495 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
3497 EnterCriticalSection(&This->cs);
3499 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3502 hr = IBasicVideo_get_DestinationHeight(pBasicVideo, pDestinationHeight);
3504 LeaveCriticalSection(&This->cs);
3509 static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo2 *iface,
3514 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3515 IBasicVideo* pBasicVideo;
3518 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
3520 EnterCriticalSection(&This->cs);
3522 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3525 hr = IBasicVideo_SetSourcePosition(pBasicVideo, Left, Top, Width, Height);
3527 LeaveCriticalSection(&This->cs);
3532 static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo2 *iface,
3537 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3538 IBasicVideo* pBasicVideo;
3541 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3543 EnterCriticalSection(&This->cs);
3545 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3548 hr = IBasicVideo_GetSourcePosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3550 LeaveCriticalSection(&This->cs);
3555 static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo2 *iface) {
3556 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3557 IBasicVideo* pBasicVideo;
3560 TRACE("(%p/%p)->()\n", This, iface);
3562 EnterCriticalSection(&This->cs);
3564 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3567 hr = IBasicVideo_SetDefaultSourcePosition(pBasicVideo);
3569 LeaveCriticalSection(&This->cs);
3574 static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo2 *iface,
3579 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3580 IBasicVideo* pBasicVideo;
3583 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
3585 EnterCriticalSection(&This->cs);
3587 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3590 hr = IBasicVideo_SetDestinationPosition(pBasicVideo, Left, Top, Width, Height);
3592 LeaveCriticalSection(&This->cs);
3597 static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo2 *iface,
3602 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3603 IBasicVideo* pBasicVideo;
3606 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3608 EnterCriticalSection(&This->cs);
3610 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3613 hr = IBasicVideo_GetDestinationPosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
3615 LeaveCriticalSection(&This->cs);
3620 static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo2 *iface) {
3621 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3622 IBasicVideo* pBasicVideo;
3625 TRACE("(%p/%p)->()\n", This, iface);
3627 EnterCriticalSection(&This->cs);
3629 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3632 hr = IBasicVideo_SetDefaultDestinationPosition(pBasicVideo);
3634 LeaveCriticalSection(&This->cs);
3639 static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo2 *iface,
3642 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3643 IBasicVideo* pBasicVideo;
3646 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3648 EnterCriticalSection(&This->cs);
3650 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3653 hr = IBasicVideo_GetVideoSize(pBasicVideo, pWidth, pHeight);
3655 LeaveCriticalSection(&This->cs);
3660 static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo2 *iface,
3665 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3666 IBasicVideo* pBasicVideo;
3669 TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
3671 EnterCriticalSection(&This->cs);
3673 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3676 hr = IBasicVideo_GetVideoPaletteEntries(pBasicVideo, StartIndex, Entries, pRetrieved, pPalette);
3678 LeaveCriticalSection(&This->cs);
3683 static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo2 *iface,
3686 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3687 IBasicVideo* pBasicVideo;
3690 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage);
3692 EnterCriticalSection(&This->cs);
3694 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3697 hr = IBasicVideo_GetCurrentImage(pBasicVideo, pBufferSize, pDIBImage);
3699 LeaveCriticalSection(&This->cs);
3704 static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo2 *iface) {
3705 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3706 IBasicVideo* pBasicVideo;
3709 TRACE("(%p/%p)->()\n", This, iface);
3711 EnterCriticalSection(&This->cs);
3713 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3716 hr = IBasicVideo_IsUsingDefaultSource(pBasicVideo);
3718 LeaveCriticalSection(&This->cs);
3723 static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo2 *iface) {
3724 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3725 IBasicVideo* pBasicVideo;
3728 TRACE("(%p/%p)->()\n", This, iface);
3730 EnterCriticalSection(&This->cs);
3732 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3735 hr = IBasicVideo_IsUsingDefaultDestination(pBasicVideo);
3737 LeaveCriticalSection(&This->cs);
3742 static HRESULT WINAPI BasicVideo2_GetPreferredAspectRatio(IBasicVideo2 *iface, LONG *plAspectX, LONG *plAspectY) {
3743 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3744 IBasicVideo2 *pBasicVideo2;
3747 TRACE("(%p/%p)->()\n", This, iface);
3749 EnterCriticalSection(&This->cs);
3751 hr = GetTargetInterface(This, &IID_IBasicVideo2, (LPVOID*)&pBasicVideo2);
3754 hr = BasicVideo2_GetPreferredAspectRatio(iface, plAspectX, plAspectY);
3756 LeaveCriticalSection(&This->cs);
3761 static const IBasicVideo2Vtbl IBasicVideo_VTable =
3763 BasicVideo_QueryInterface,
3766 BasicVideo_GetTypeInfoCount,
3767 BasicVideo_GetTypeInfo,
3768 BasicVideo_GetIDsOfNames,
3770 BasicVideo_get_AvgTimePerFrame,
3771 BasicVideo_get_BitRate,
3772 BasicVideo_get_BitErrorRate,
3773 BasicVideo_get_VideoWidth,
3774 BasicVideo_get_VideoHeight,
3775 BasicVideo_put_SourceLeft,
3776 BasicVideo_get_SourceLeft,
3777 BasicVideo_put_SourceWidth,
3778 BasicVideo_get_SourceWidth,
3779 BasicVideo_put_SourceTop,
3780 BasicVideo_get_SourceTop,
3781 BasicVideo_put_SourceHeight,
3782 BasicVideo_get_SourceHeight,
3783 BasicVideo_put_DestinationLeft,
3784 BasicVideo_get_DestinationLeft,
3785 BasicVideo_put_DestinationWidth,
3786 BasicVideo_get_DestinationWidth,
3787 BasicVideo_put_DestinationTop,
3788 BasicVideo_get_DestinationTop,
3789 BasicVideo_put_DestinationHeight,
3790 BasicVideo_get_DestinationHeight,
3791 BasicVideo_SetSourcePosition,
3792 BasicVideo_GetSourcePosition,
3793 BasicVideo_SetDefaultSourcePosition,
3794 BasicVideo_SetDestinationPosition,
3795 BasicVideo_GetDestinationPosition,
3796 BasicVideo_SetDefaultDestinationPosition,
3797 BasicVideo_GetVideoSize,
3798 BasicVideo_GetVideoPaletteEntries,
3799 BasicVideo_GetCurrentImage,
3800 BasicVideo_IsUsingDefaultSource,
3801 BasicVideo_IsUsingDefaultDestination,
3802 BasicVideo2_GetPreferredAspectRatio
3806 /*** IUnknown methods ***/
3807 static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface,
3810 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3812 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3814 return Filtergraph_QueryInterface(This, riid, ppvObj);
3817 static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) {
3818 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3820 TRACE("(%p/%p)->()\n", This, iface);
3822 return Filtergraph_AddRef(This);
3825 static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) {
3826 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3828 TRACE("(%p/%p)->()\n", This, iface);
3830 return Filtergraph_Release(This);
3833 /*** IDispatch methods ***/
3834 static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface,
3836 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3837 IVideoWindow* pVideoWindow;
3840 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3842 EnterCriticalSection(&This->cs);
3844 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3847 hr = IVideoWindow_GetTypeInfoCount(pVideoWindow, pctinfo);
3849 LeaveCriticalSection(&This->cs);
3854 static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface,
3857 ITypeInfo**ppTInfo) {
3858 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3859 IVideoWindow* pVideoWindow;
3862 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3864 EnterCriticalSection(&This->cs);
3866 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3869 hr = IVideoWindow_GetTypeInfo(pVideoWindow, iTInfo, lcid, ppTInfo);
3871 LeaveCriticalSection(&This->cs);
3876 static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface,
3882 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3883 IVideoWindow* pVideoWindow;
3886 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3888 EnterCriticalSection(&This->cs);
3890 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3893 hr = IVideoWindow_GetIDsOfNames(pVideoWindow, riid, rgszNames, cNames, lcid, rgDispId);
3895 LeaveCriticalSection(&This->cs);
3900 static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface,
3901 DISPID dispIdMember,
3905 DISPPARAMS*pDispParams,
3907 EXCEPINFO*pExepInfo,
3909 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3910 IVideoWindow* pVideoWindow;
3913 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);
3915 EnterCriticalSection(&This->cs);
3917 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3920 hr = IVideoWindow_Invoke(pVideoWindow, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3922 LeaveCriticalSection(&This->cs);
3928 /*** IVideoWindow methods ***/
3929 static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface,
3931 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3932 IVideoWindow* pVideoWindow;
3935 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
3937 EnterCriticalSection(&This->cs);
3939 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3942 hr = IVideoWindow_put_Caption(pVideoWindow, strCaption);
3944 LeaveCriticalSection(&This->cs);
3949 static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface,
3951 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3952 IVideoWindow* pVideoWindow;
3955 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
3957 EnterCriticalSection(&This->cs);
3959 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3962 hr = IVideoWindow_get_Caption(pVideoWindow, strCaption);
3964 LeaveCriticalSection(&This->cs);
3969 static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface,
3971 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3972 IVideoWindow* pVideoWindow;
3975 TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyle);
3977 EnterCriticalSection(&This->cs);
3979 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3982 hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle);
3984 LeaveCriticalSection(&This->cs);
3989 static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface,
3990 LONG *WindowStyle) {
3991 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3992 IVideoWindow* pVideoWindow;
3995 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
3997 EnterCriticalSection(&This->cs);
3999 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4002 hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle);
4004 LeaveCriticalSection(&This->cs);
4009 static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface,
4010 LONG WindowStyleEx) {
4011 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4012 IVideoWindow* pVideoWindow;
4015 TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx);
4017 EnterCriticalSection(&This->cs);
4019 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4022 hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx);
4024 LeaveCriticalSection(&This->cs);
4029 static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface,
4030 LONG *WindowStyleEx) {
4031 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4032 IVideoWindow* pVideoWindow;
4035 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
4037 EnterCriticalSection(&This->cs);
4039 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4042 hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx);
4044 LeaveCriticalSection(&This->cs);
4049 static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface,
4051 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4052 IVideoWindow* pVideoWindow;
4055 TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow);
4057 EnterCriticalSection(&This->cs);
4059 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4062 hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow);
4064 LeaveCriticalSection(&This->cs);
4069 static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface,
4071 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4072 IVideoWindow* pVideoWindow;
4075 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
4077 EnterCriticalSection(&This->cs);
4079 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4082 hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow);
4084 LeaveCriticalSection(&This->cs);
4089 static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface,
4091 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4092 IVideoWindow* pVideoWindow;
4095 TRACE("(%p/%p)->(%d)\n", This, iface, WindowState);
4097 EnterCriticalSection(&This->cs);
4099 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4102 hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState);
4104 LeaveCriticalSection(&This->cs);
4109 static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface,
4110 LONG *WindowState) {
4111 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4112 IVideoWindow* pVideoWindow;
4115 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
4117 EnterCriticalSection(&This->cs);
4119 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4122 hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState);
4124 LeaveCriticalSection(&This->cs);
4129 static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface,
4130 LONG BackgroundPalette) {
4131 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4132 IVideoWindow* pVideoWindow;
4135 TRACE("(%p/%p)->(%d)\n", This, iface, BackgroundPalette);
4137 EnterCriticalSection(&This->cs);
4139 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4142 hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette);
4144 LeaveCriticalSection(&This->cs);
4149 static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface,
4150 LONG *pBackgroundPalette) {
4151 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4152 IVideoWindow* pVideoWindow;
4155 TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette);
4157 EnterCriticalSection(&This->cs);
4159 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4162 hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette);
4164 LeaveCriticalSection(&This->cs);
4169 static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface,
4171 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4172 IVideoWindow* pVideoWindow;
4175 TRACE("(%p/%p)->(%d)\n", This, iface, Visible);
4177 EnterCriticalSection(&This->cs);
4179 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4182 hr = IVideoWindow_put_Visible(pVideoWindow, Visible);
4184 LeaveCriticalSection(&This->cs);
4189 static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface,
4191 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4192 IVideoWindow* pVideoWindow;
4195 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
4197 EnterCriticalSection(&This->cs);
4199 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4202 hr = IVideoWindow_get_Visible(pVideoWindow, pVisible);
4204 LeaveCriticalSection(&This->cs);
4209 static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface,
4211 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4212 IVideoWindow* pVideoWindow;
4215 TRACE("(%p/%p)->(%d)\n", This, iface, Left);
4217 EnterCriticalSection(&This->cs);
4219 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4222 hr = IVideoWindow_put_Left(pVideoWindow, Left);
4224 LeaveCriticalSection(&This->cs);
4229 static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface,
4231 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4232 IVideoWindow* pVideoWindow;
4235 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
4237 EnterCriticalSection(&This->cs);
4239 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4242 hr = IVideoWindow_get_Left(pVideoWindow, pLeft);
4244 LeaveCriticalSection(&This->cs);
4249 static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface,
4251 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4252 IVideoWindow* pVideoWindow;
4255 TRACE("(%p/%p)->(%d)\n", This, iface, Width);
4257 EnterCriticalSection(&This->cs);
4259 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4262 hr = IVideoWindow_put_Width(pVideoWindow, Width);
4264 LeaveCriticalSection(&This->cs);
4269 static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface,
4271 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4272 IVideoWindow* pVideoWindow;
4275 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
4277 EnterCriticalSection(&This->cs);
4279 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4282 hr = IVideoWindow_get_Width(pVideoWindow, pWidth);
4284 LeaveCriticalSection(&This->cs);
4289 static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface,
4291 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4292 IVideoWindow* pVideoWindow;
4295 TRACE("(%p/%p)->(%d)\n", This, iface, Top);
4297 EnterCriticalSection(&This->cs);
4299 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4302 hr = IVideoWindow_put_Top(pVideoWindow, Top);
4304 LeaveCriticalSection(&This->cs);
4309 static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface,
4311 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4312 IVideoWindow* pVideoWindow;
4315 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
4317 EnterCriticalSection(&This->cs);
4319 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4322 hr = IVideoWindow_get_Top(pVideoWindow, pTop);
4324 LeaveCriticalSection(&This->cs);
4329 static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface,
4331 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4332 IVideoWindow* pVideoWindow;
4335 TRACE("(%p/%p)->(%d)\n", This, iface, Height);
4337 EnterCriticalSection(&This->cs);
4339 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4342 hr = IVideoWindow_put_Height(pVideoWindow, Height);
4344 LeaveCriticalSection(&This->cs);
4349 static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface,
4351 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4352 IVideoWindow* pVideoWindow;
4355 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
4357 EnterCriticalSection(&This->cs);
4359 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4362 hr = IVideoWindow_get_Height(pVideoWindow, pHeight);
4364 LeaveCriticalSection(&This->cs);
4369 static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface,
4371 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4372 IVideoWindow* pVideoWindow;
4375 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
4377 EnterCriticalSection(&This->cs);
4379 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4382 hr = IVideoWindow_put_Owner(pVideoWindow, Owner);
4384 LeaveCriticalSection(&This->cs);
4389 static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface,
4391 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4392 IVideoWindow* pVideoWindow;
4395 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
4397 EnterCriticalSection(&This->cs);
4399 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4402 hr = IVideoWindow_get_Owner(pVideoWindow, Owner);
4404 LeaveCriticalSection(&This->cs);
4409 static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface,
4411 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4412 IVideoWindow* pVideoWindow;
4415 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
4417 EnterCriticalSection(&This->cs);
4419 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4422 hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain);
4424 LeaveCriticalSection(&This->cs);
4429 static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface,
4431 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4432 IVideoWindow* pVideoWindow;
4435 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
4437 EnterCriticalSection(&This->cs);
4439 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4442 hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain);
4444 LeaveCriticalSection(&This->cs);
4449 static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface,
4451 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4452 IVideoWindow* pVideoWindow;
4455 TRACE("(%p/%p)->(%p)\n", This, iface, Color);
4457 EnterCriticalSection(&This->cs);
4459 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4462 hr = IVideoWindow_get_BorderColor(pVideoWindow, Color);
4464 LeaveCriticalSection(&This->cs);
4469 static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface,
4471 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4472 IVideoWindow* pVideoWindow;
4475 TRACE("(%p/%p)->(%d)\n", This, iface, Color);
4477 EnterCriticalSection(&This->cs);
4479 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4482 hr = IVideoWindow_put_BorderColor(pVideoWindow, Color);
4484 LeaveCriticalSection(&This->cs);
4489 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
4490 LONG *FullScreenMode) {
4491 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4492 IVideoWindow* pVideoWindow;
4495 TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode);
4497 EnterCriticalSection(&This->cs);
4499 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4502 hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode);
4504 LeaveCriticalSection(&This->cs);
4509 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
4510 LONG FullScreenMode) {
4511 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4512 IVideoWindow* pVideoWindow;
4515 TRACE("(%p/%p)->(%d)\n", This, iface, FullScreenMode);
4517 EnterCriticalSection(&This->cs);
4519 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4522 hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode);
4524 LeaveCriticalSection(&This->cs);
4529 static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface,
4531 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4532 IVideoWindow* pVideoWindow;
4535 TRACE("(%p/%p)->(%d)\n", This, iface, Focus);
4537 EnterCriticalSection(&This->cs);
4539 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4542 hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus);
4544 LeaveCriticalSection(&This->cs);
4549 static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface,
4554 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4555 IVideoWindow* pVideoWindow;
4558 TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam);
4560 EnterCriticalSection(&This->cs);
4562 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4565 hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam);
4567 LeaveCriticalSection(&This->cs);
4572 static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface,
4577 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4578 IVideoWindow* pVideoWindow;
4581 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
4583 EnterCriticalSection(&This->cs);
4585 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4588 hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height);
4590 LeaveCriticalSection(&This->cs);
4595 static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface,
4600 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4601 IVideoWindow* pVideoWindow;
4604 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4606 EnterCriticalSection(&This->cs);
4608 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4611 hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4613 LeaveCriticalSection(&This->cs);
4618 static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface,
4621 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4622 IVideoWindow* pVideoWindow;
4625 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4627 EnterCriticalSection(&This->cs);
4629 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4632 hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight);
4634 LeaveCriticalSection(&This->cs);
4639 static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface,
4642 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4643 IVideoWindow* pVideoWindow;
4646 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
4648 EnterCriticalSection(&This->cs);
4650 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4653 hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight);
4655 LeaveCriticalSection(&This->cs);
4660 static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface,
4665 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4666 IVideoWindow* pVideoWindow;
4669 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
4671 EnterCriticalSection(&This->cs);
4673 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4676 hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
4678 LeaveCriticalSection(&This->cs);
4683 static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface,
4685 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4686 IVideoWindow* pVideoWindow;
4689 TRACE("(%p/%p)->(%d)\n", This, iface, HideCursor);
4691 EnterCriticalSection(&This->cs);
4693 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4696 hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor);
4698 LeaveCriticalSection(&This->cs);
4703 static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface,
4704 LONG *CursorHidden) {
4705 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
4706 IVideoWindow* pVideoWindow;
4709 TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden);
4711 EnterCriticalSection(&This->cs);
4713 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
4716 hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden);
4718 LeaveCriticalSection(&This->cs);
4724 static const IVideoWindowVtbl IVideoWindow_VTable =
4726 VideoWindow_QueryInterface,
4728 VideoWindow_Release,
4729 VideoWindow_GetTypeInfoCount,
4730 VideoWindow_GetTypeInfo,
4731 VideoWindow_GetIDsOfNames,
4733 VideoWindow_put_Caption,
4734 VideoWindow_get_Caption,
4735 VideoWindow_put_WindowStyle,
4736 VideoWindow_get_WindowStyle,
4737 VideoWindow_put_WindowStyleEx,
4738 VideoWindow_get_WindowStyleEx,
4739 VideoWindow_put_AutoShow,
4740 VideoWindow_get_AutoShow,
4741 VideoWindow_put_WindowState,
4742 VideoWindow_get_WindowState,
4743 VideoWindow_put_BackgroundPalette,
4744 VideoWindow_get_BackgroundPalette,
4745 VideoWindow_put_Visible,
4746 VideoWindow_get_Visible,
4747 VideoWindow_put_Left,
4748 VideoWindow_get_Left,
4749 VideoWindow_put_Width,
4750 VideoWindow_get_Width,
4751 VideoWindow_put_Top,
4752 VideoWindow_get_Top,
4753 VideoWindow_put_Height,
4754 VideoWindow_get_Height,
4755 VideoWindow_put_Owner,
4756 VideoWindow_get_Owner,
4757 VideoWindow_put_MessageDrain,
4758 VideoWindow_get_MessageDrain,
4759 VideoWindow_get_BorderColor,
4760 VideoWindow_put_BorderColor,
4761 VideoWindow_get_FullScreenMode,
4762 VideoWindow_put_FullScreenMode,
4763 VideoWindow_SetWindowForeground,
4764 VideoWindow_NotifyOwnerMessage,
4765 VideoWindow_SetWindowPosition,
4766 VideoWindow_GetWindowPosition,
4767 VideoWindow_GetMinIdealImageSize,
4768 VideoWindow_GetMaxIdealImageSize,
4769 VideoWindow_GetRestorePosition,
4770 VideoWindow_HideCursor,
4771 VideoWindow_IsCursorHidden
4775 /*** IUnknown methods ***/
4776 static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface,
4779 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4781 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
4783 return Filtergraph_QueryInterface(This, riid, ppvObj);
4786 static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) {
4787 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4789 TRACE("(%p/%p)->()\n", This, iface);
4791 return Filtergraph_AddRef(This);
4794 static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) {
4795 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4797 TRACE("(%p/%p)->()\n", This, iface);
4799 return Filtergraph_Release(This);
4802 /*** IDispatch methods ***/
4803 static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface,
4805 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4807 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
4812 static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface,
4815 ITypeInfo**ppTInfo) {
4816 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4818 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
4823 static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface,
4829 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4831 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
4836 static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface,
4837 DISPID dispIdMember,
4841 DISPPARAMS*pDispParams,
4843 EXCEPINFO*pExepInfo,
4845 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4847 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);
4852 /*** IMediaEvent methods ***/
4853 static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface,
4855 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4857 TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
4859 *hEvent = (OAEVENT)This->evqueue.msg_event;
4864 static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface,
4869 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4872 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
4874 if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
4876 *lEventCode = evt.lEventCode;
4877 *lParam1 = evt.lParam1;
4878 *lParam2 = evt.lParam2;
4886 static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface,
4889 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4891 TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pEvCode);
4893 if (This->state != State_Running)
4894 return VFW_E_WRONG_STATE;
4896 if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
4898 *pEvCode = This->CompletionStatus;
4906 static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface,
4908 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4910 TRACE("(%p/%p)->(%d)\n", This, iface, lEvCode);
4912 if (lEvCode == EC_COMPLETE)
4913 This->HandleEcComplete = FALSE;
4914 else if (lEvCode == EC_REPAINT)
4915 This->HandleEcRepaint = FALSE;
4916 else if (lEvCode == EC_CLOCK_CHANGED)
4917 This->HandleEcClockChanged = FALSE;
4924 static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface,
4926 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4928 TRACE("(%p/%p)->(%d)\n", This, iface, lEvCode);
4930 if (lEvCode == EC_COMPLETE)
4931 This->HandleEcComplete = TRUE;
4932 else if (lEvCode == EC_REPAINT)
4933 This->HandleEcRepaint = TRUE;
4934 else if (lEvCode == EC_CLOCK_CHANGED)
4935 This->HandleEcClockChanged = TRUE;
4942 static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface,
4946 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4948 TRACE("(%p/%p)->(%d, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
4953 /*** IMediaEventEx methods ***/
4954 static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface,
4957 LONG_PTR lInstanceData) {
4958 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4960 TRACE("(%p/%p)->(%08lx, %d, %08lx)\n", This, iface, hwnd, lMsg, lInstanceData);
4962 This->notif.hWnd = (HWND)hwnd;
4963 This->notif.msg = lMsg;
4964 This->notif.instance = lInstanceData;
4969 static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface,
4970 LONG lNoNotifyFlags) {
4971 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4973 TRACE("(%p/%p)->(%d)\n", This, iface, lNoNotifyFlags);
4975 if ((lNoNotifyFlags != 0) && (lNoNotifyFlags != 1))
4976 return E_INVALIDARG;
4978 This->notif.disabled = lNoNotifyFlags;
4983 static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface,
4984 LONG *lplNoNotifyFlags) {
4985 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4987 TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
4989 if (!lplNoNotifyFlags)
4992 *lplNoNotifyFlags = This->notif.disabled;
4998 static const IMediaEventExVtbl IMediaEventEx_VTable =
5000 MediaEvent_QueryInterface,
5003 MediaEvent_GetTypeInfoCount,
5004 MediaEvent_GetTypeInfo,
5005 MediaEvent_GetIDsOfNames,
5007 MediaEvent_GetEventHandle,
5008 MediaEvent_GetEvent,
5009 MediaEvent_WaitForCompletion,
5010 MediaEvent_CancelDefaultHandling,
5011 MediaEvent_RestoreDefaultHandling,
5012 MediaEvent_FreeEventParams,
5013 MediaEvent_SetNotifyWindow,
5014 MediaEvent_SetNotifyFlags,
5015 MediaEvent_GetNotifyFlags
5019 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
5021 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5023 return Filtergraph_QueryInterface(This, riid, ppv);
5026 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
5028 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5030 return Filtergraph_AddRef(This);
5033 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
5035 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5037 return Filtergraph_Release(This);
5040 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
5042 FIXME("(%p): stub\n", pClassID);
5047 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
5049 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5050 return MediaControl_Stop((IMediaControl*)&This->IMediaControl_vtbl);
5053 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
5055 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5056 return MediaControl_Pause((IMediaControl*)&This->IMediaControl_vtbl);
5059 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
5061 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5063 FIXME("Run called with non-null tStart: %x%08x\n",
5064 (int)(tStart>>32), (int)tStart);
5065 return MediaControl_Run((IMediaControl*)&This->IMediaControl_vtbl);
5068 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
5070 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5071 return MediaControl_GetState((IMediaControl*)&This->IMediaControl_vtbl, dwMsTimeout, (OAFilterState*)pState);
5074 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
5076 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5080 TRACE("(%p/%p)->(%p)\n", iface, This, pClock);
5082 EnterCriticalSection(&This->cs);
5084 for (i = 0;i < This->nFilters;i++)
5086 hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
5094 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
5099 IReferenceClock_Release(This->refClock);
5100 This->refClock = pClock;
5102 IReferenceClock_AddRef(This->refClock);
5103 This->defaultclock = FALSE;
5105 if (This->HandleEcClockChanged)
5107 IMediaEventSink *pEventSink;
5110 eshr = IMediaFilter_QueryInterface(iface, &IID_IMediaEventSink, (LPVOID)&pEventSink);
5111 if (SUCCEEDED(eshr))
5113 IMediaEventSink_Notify(pEventSink, EC_CLOCK_CHANGED, 0, 0);
5114 IMediaEventSink_Release(pEventSink);
5119 LeaveCriticalSection(&This->cs);
5124 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
5126 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
5128 TRACE("(%p/%p)->(%p)\n", iface, This, ppClock);
5133 EnterCriticalSection(&This->cs);
5135 *ppClock = This->refClock;
5137 IReferenceClock_AddRef(*ppClock);
5139 LeaveCriticalSection(&This->cs);
5144 static const IMediaFilterVtbl IMediaFilter_VTable =
5146 MediaFilter_QueryInterface,
5148 MediaFilter_Release,
5149 MediaFilter_GetClassID,
5153 MediaFilter_GetState,
5154 MediaFilter_SetSyncSource,
5155 MediaFilter_GetSyncSource
5158 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
5160 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5162 return Filtergraph_QueryInterface(This, riid, ppv);
5165 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
5167 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5169 return Filtergraph_AddRef(This);
5172 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
5174 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5176 return Filtergraph_Release(This);
5179 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
5181 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
5184 TRACE("(%p/%p)->(%d, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
5186 /* We need thread safety here, let's use the events queue's one */
5187 EnterCriticalSection(&This->evqueue.msg_crst);
5189 if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
5191 TRACE("Process EC_COMPLETE notification\n");
5192 if (++This->EcCompleteCount == This->nRenderers)
5194 evt.lEventCode = EC_COMPLETE;
5197 TRACE("Send EC_COMPLETE to app\n");
5198 EventsQueue_PutEvent(&This->evqueue, &evt);
5199 if (!This->notif.disabled && This->notif.hWnd)
5201 TRACE("Send Window message\n");
5202 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
5204 This->CompletionStatus = EC_COMPLETE;
5205 SetEvent(This->hEventCompletion);
5208 else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
5210 /* FIXME: Not handled yet */
5214 evt.lEventCode = EventCode;
5215 evt.lParam1 = EventParam1;
5216 evt.lParam2 = EventParam2;
5217 EventsQueue_PutEvent(&This->evqueue, &evt);
5218 if (!This->notif.disabled && This->notif.hWnd)
5219 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
5222 LeaveCriticalSection(&This->evqueue.msg_crst);
5226 static const IMediaEventSinkVtbl IMediaEventSink_VTable =
5228 MediaEventSink_QueryInterface,
5229 MediaEventSink_AddRef,
5230 MediaEventSink_Release,
5231 MediaEventSink_Notify
5234 static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv)
5236 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5238 return Filtergraph_QueryInterface(This, riid, ppv);
5241 static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface)
5243 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5245 return Filtergraph_AddRef(This);
5248 static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface)
5250 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5252 return Filtergraph_Release(This);
5255 static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface,
5258 const AM_MEDIA_TYPE* pmtFirstConnection,
5259 IBaseFilter* pUsingFilter,
5263 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5265 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags);
5270 static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface,
5271 IGraphConfigCallback* pCallback,
5276 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5279 WARN("(%p)->(%p, %p, %x, %p): partial stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent);
5282 FIXME("The parameter hAbortEvent is not handled!\n");
5284 EnterCriticalSection(&This->cs);
5286 hr = IGraphConfigCallback_Reconfigure(pCallback, pvContext, dwFlags);
5288 LeaveCriticalSection(&This->cs);
5293 static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface,
5294 IBaseFilter* pFilter)
5296 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5298 FIXME("(%p)->(%p): stub!\n", This, pFilter);
5303 static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface,
5304 IEnumFilters** pEnum)
5306 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5308 FIXME("(%p)->(%p): stub!\n", This, pEnum);
5313 static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface,
5314 IBaseFilter* pFilter)
5316 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5318 FIXME("(%p)->(%p): stub!\n", This, pFilter);
5323 static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface,
5324 REFERENCE_TIME* prtStart)
5326 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5328 FIXME("(%p)->(%p): stub!\n", This, prtStart);
5333 static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface,
5335 IPinConnection* pConnection,
5338 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5340 FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort);
5345 static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface,
5346 IBaseFilter* pFilter,
5349 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5351 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
5356 static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface,
5357 IBaseFilter* pFilter,
5360 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5362 FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags);
5367 static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface,
5368 IBaseFilter* pFilter,
5371 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
5373 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
5378 static const IGraphConfigVtbl IGraphConfig_VTable =
5380 GraphConfig_QueryInterface,
5382 GraphConfig_Release,
5383 GraphConfig_Reconnect,
5384 GraphConfig_Reconfigure,
5385 GraphConfig_AddFilterToCache,
5386 GraphConfig_EnumCacheFilter,
5387 GraphConfig_RemoveFilterFromCache,
5388 GraphConfig_GetStartTime,
5389 GraphConfig_PushThroughData,
5390 GraphConfig_SetFilterFlags,
5391 GraphConfig_GetFilterFlags,
5392 GraphConfig_RemoveFilterEx
5395 static const IUnknownVtbl IInner_VTable =
5397 FilterGraphInner_QueryInterface,
5398 FilterGraphInner_AddRef,
5399 FilterGraphInner_Release
5402 static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
5405 if (This->bAggregatable)
5406 This->bUnkOuterValid = TRUE;
5408 if (This->pUnkOuter)
5410 if (This->bAggregatable)
5411 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
5413 if (IsEqualIID(riid, &IID_IUnknown))
5417 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
5418 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
5419 IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
5420 This->bAggregatable = TRUE;
5425 return E_NOINTERFACE;
5428 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
5431 static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
5432 if (This->pUnkOuter && This->bUnkOuterValid)
5433 return IUnknown_AddRef(This->pUnkOuter);
5434 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
5437 static ULONG Filtergraph_Release(IFilterGraphImpl *This) {
5438 if (This->pUnkOuter && This->bUnkOuterValid)
5439 return IUnknown_Release(This->pUnkOuter);
5440 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
5443 /* This is the only function that actually creates a FilterGraph class... */
5444 HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
5446 IFilterGraphImpl *fimpl;
5449 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
5453 fimpl = CoTaskMemAlloc(sizeof(*fimpl));
5454 fimpl->pUnkOuter = pUnkOuter;
5455 fimpl->bUnkOuterValid = FALSE;
5456 fimpl->bAggregatable = FALSE;
5457 fimpl->defaultclock = TRUE;
5458 fimpl->IInner_vtbl = &IInner_VTable;
5459 fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
5460 fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
5461 fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
5462 fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
5463 fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
5464 fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
5465 fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
5466 fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
5467 fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
5468 fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable;
5469 fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable;
5471 fimpl->ppFiltersInGraph = NULL;
5472 fimpl->pFilterNames = NULL;
5473 fimpl->nFilters = 0;
5474 fimpl->filterCapacity = 0;
5475 fimpl->nameIndex = 1;
5476 fimpl->refClock = NULL;
5477 fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
5478 fimpl->HandleEcComplete = TRUE;
5479 fimpl->HandleEcRepaint = TRUE;
5480 fimpl->HandleEcClockChanged = TRUE;
5481 fimpl->notif.hWnd = 0;
5482 fimpl->notif.disabled = FALSE;
5483 fimpl->nRenderers = 0;
5484 fimpl->EcCompleteCount = 0;
5485 fimpl->state = State_Stopped;
5486 EventsQueue_Init(&fimpl->evqueue);
5487 InitializeCriticalSection(&fimpl->cs);
5488 fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
5489 fimpl->nItfCacheEntries = 0;
5490 memcpy(&fimpl->timeformatseek, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
5491 fimpl->start_time = fimpl->pause_time = 0;
5492 fimpl->stop_position = -1;
5493 fimpl->punkFilterMapper2 = NULL;
5494 fimpl->recursioncount = 0;
5496 /* create Filtermapper aggregated. */
5497 hr = CoCreateInstance(&CLSID_FilterMapper2, pUnkOuter ? pUnkOuter : (IUnknown*)&fimpl->IInner_vtbl, CLSCTX_INPROC_SERVER,
5498 &IID_IUnknown, (LPVOID*)&fimpl->punkFilterMapper2);
5500 if (SUCCEEDED(hr)) {
5501 hr = IUnknown_QueryInterface(fimpl->punkFilterMapper2, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
5504 if (SUCCEEDED(hr)) {
5505 /* Release controlling IUnknown - compensate refcount increase from caching IFilterMapper2 interface. */
5506 if (pUnkOuter) IUnknown_Release(pUnkOuter);
5507 else IUnknown_Release((IUnknown*)&fimpl->IInner_vtbl);
5511 ERR("Unable to create filter mapper (%x)\n", hr);
5512 if (fimpl->punkFilterMapper2) IUnknown_Release(fimpl->punkFilterMapper2);
5513 CloseHandle(fimpl->hEventCompletion);
5514 EventsQueue_Destroy(&fimpl->evqueue);
5515 fimpl->cs.DebugInfo->Spare[0] = 0;
5516 DeleteCriticalSection(&fimpl->cs);
5517 CoTaskMemFree(fimpl);
5525 HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj)
5527 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
5528 return FilterGraph_create(pUnkOuter, ppObj);