quartz: Fix IFilterGraph RemoveFilter to stop the filter before removing it.
[wine/hacks.git] / dlls / quartz / filtergraph.c
blob762e3e2ccaaea63c244cd44ddefbe129b559982b
1 /* DirectShow FilterGraph object (QUARTZ.DLL)
3 * Copyright 2002 Lionel Ulmer
4 * Copyright 2004 Christian Costa
6 * This file contains the (internal) driver registration functions,
7 * driver enumeration APIs and DirectDraw creation functions.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "config.h"
25 #include <stdarg.h>
27 #define COBJMACROS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "dshow.h"
33 #include "wine/debug.h"
34 #include "quartz_private.h"
35 #include "ole2.h"
36 #include "olectl.h"
37 #include "strmif.h"
38 #include "vfwmsgs.h"
39 #include "evcode.h"
40 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
45 typedef struct {
46 HWND hWnd; /* Target window */
47 long msg; /* User window message */
48 long instance; /* User data */
49 int disabled; /* Disabled messages posting */
50 } WndNotify;
52 typedef struct {
53 long lEventCode; /* Event code */
54 LONG_PTR lParam1; /* Param1 */
55 LONG_PTR lParam2; /* Param2 */
56 } Event;
58 /* messages ring implementation for queuing events (taken from winmm) */
59 #define EVENTS_RING_BUFFER_INCREMENT 64
60 typedef struct {
61 Event* messages;
62 int ring_buffer_size;
63 int msg_tosave;
64 int msg_toget;
65 CRITICAL_SECTION msg_crst;
66 HANDLE msg_event; /* Signaled for no empty queue */
67 } EventsQueue;
69 static int EventsQueue_Init(EventsQueue* omr)
71 omr->msg_toget = 0;
72 omr->msg_tosave = 0;
73 omr->msg_event = CreateEventW(NULL, TRUE, FALSE, NULL);
74 omr->ring_buffer_size = EVENTS_RING_BUFFER_INCREMENT;
75 omr->messages = CoTaskMemAlloc(omr->ring_buffer_size * sizeof(Event));
76 ZeroMemory(omr->messages, omr->ring_buffer_size * sizeof(Event));
78 InitializeCriticalSection(&omr->msg_crst);
79 omr->msg_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": EventsQueue.msg_crst");
80 return TRUE;
83 static int EventsQueue_Destroy(EventsQueue* omr)
85 CloseHandle(omr->msg_event);
86 CoTaskMemFree(omr->messages);
87 omr->msg_crst.DebugInfo->Spare[0] = 0;
88 DeleteCriticalSection(&omr->msg_crst);
89 return TRUE;
92 static int EventsQueue_PutEvent(EventsQueue* omr, const Event* evt)
94 EnterCriticalSection(&omr->msg_crst);
95 if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size)))
97 int old_ring_buffer_size = omr->ring_buffer_size;
98 omr->ring_buffer_size += EVENTS_RING_BUFFER_INCREMENT;
99 TRACE("omr->ring_buffer_size=%d\n",omr->ring_buffer_size);
100 omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(Event));
101 /* Now we need to rearrange the ring buffer so that the new
102 buffers just allocated are in between omr->msg_tosave and
103 omr->msg_toget.
105 if (omr->msg_tosave < omr->msg_toget)
107 memmove(&(omr->messages[omr->msg_toget + EVENTS_RING_BUFFER_INCREMENT]),
108 &(omr->messages[omr->msg_toget]),
109 sizeof(Event)*(old_ring_buffer_size - omr->msg_toget)
111 omr->msg_toget += EVENTS_RING_BUFFER_INCREMENT;
114 omr->messages[omr->msg_tosave] = *evt;
115 SetEvent(omr->msg_event);
116 omr->msg_tosave = (omr->msg_tosave + 1) % omr->ring_buffer_size;
117 LeaveCriticalSection(&omr->msg_crst);
118 return TRUE;
121 static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut)
123 if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0)
124 return FALSE;
126 EnterCriticalSection(&omr->msg_crst);
128 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
130 LeaveCriticalSection(&omr->msg_crst);
131 return FALSE;
134 *evt = omr->messages[omr->msg_toget];
135 omr->msg_toget = (omr->msg_toget + 1) % omr->ring_buffer_size;
137 /* Mark the buffer as empty if needed */
138 if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */
139 ResetEvent(omr->msg_event);
141 LeaveCriticalSection(&omr->msg_crst);
142 return TRUE;
145 #define MAX_ITF_CACHE_ENTRIES 3
146 typedef struct _ITF_CACHE_ENTRY {
147 const IID* riid;
148 IBaseFilter* filter;
149 IUnknown* iface;
150 } ITF_CACHE_ENTRY;
152 typedef struct _IFilterGraphImpl {
153 const IFilterGraph2Vtbl *IFilterGraph2_vtbl;
154 const IMediaControlVtbl *IMediaControl_vtbl;
155 const IMediaSeekingVtbl *IMediaSeeking_vtbl;
156 const IBasicAudioVtbl *IBasicAudio_vtbl;
157 const IBasicVideoVtbl *IBasicVideo_vtbl;
158 const IVideoWindowVtbl *IVideoWindow_vtbl;
159 const IMediaEventExVtbl *IMediaEventEx_vtbl;
160 const IMediaFilterVtbl *IMediaFilter_vtbl;
161 const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
162 const IGraphConfigVtbl *IGraphConfig_vtbl;
163 const IMediaPositionVtbl *IMediaPosition_vtbl;
164 const IUnknownVtbl * IInner_vtbl;
165 /* IAMGraphStreams */
166 /* IAMStats */
167 /* IBasicVideo2 */
168 /* IFilterChain */
169 /* IFilterMapper2 */
170 /* IGraphVersion */
171 /* IQueueCommand */
172 /* IRegisterServiceProvider */
173 /* IResourceMananger */
174 /* IServiceProvider */
175 /* IVideoFrameStep */
177 LONG ref;
178 IFilterMapper2 * pFilterMapper2;
179 IBaseFilter ** ppFiltersInGraph;
180 LPWSTR * pFilterNames;
181 int nFilters;
182 int filterCapacity;
183 long nameIndex;
184 IReferenceClock *refClock;
185 EventsQueue evqueue;
186 HANDLE hEventCompletion;
187 int CompletionStatus;
188 WndNotify notif;
189 int nRenderers;
190 int EcCompleteCount;
191 int HandleEcComplete;
192 int HandleEcRepaint;
193 int HandleEcClockChanged;
194 OAFilterState state;
195 CRITICAL_SECTION cs;
196 ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
197 int nItfCacheEntries;
198 IUnknown * pUnkOuter;
199 BOOL bUnkOuterValid;
200 BOOL bAggregatable;
201 } IFilterGraphImpl;
203 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
204 REFIID riid, LPVOID * ppv);
205 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This);
206 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This);
208 static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface,
209 REFIID riid,
210 LPVOID *ppvObj) {
211 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
212 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
214 if (This->bAggregatable)
215 This->bUnkOuterValid = TRUE;
217 if (IsEqualGUID(&IID_IUnknown, riid)) {
218 *ppvObj = &(This->IInner_vtbl);
219 TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
220 } else if (IsEqualGUID(&IID_IFilterGraph, riid) ||
221 IsEqualGUID(&IID_IFilterGraph2, riid) ||
222 IsEqualGUID(&IID_IGraphBuilder, riid)) {
223 *ppvObj = &(This->IFilterGraph2_vtbl);
224 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj);
225 } else if (IsEqualGUID(&IID_IMediaControl, riid)) {
226 *ppvObj = &(This->IMediaControl_vtbl);
227 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj);
228 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
229 *ppvObj = &(This->IMediaSeeking_vtbl);
230 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
231 } else if (IsEqualGUID(&IID_IBasicAudio, riid)) {
232 *ppvObj = &(This->IBasicAudio_vtbl);
233 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj);
234 } else if (IsEqualGUID(&IID_IBasicVideo, riid)) {
235 *ppvObj = &(This->IBasicVideo_vtbl);
236 TRACE(" returning IBasicVideo interface (%p)\n", *ppvObj);
237 } else if (IsEqualGUID(&IID_IVideoWindow, riid)) {
238 *ppvObj = &(This->IVideoWindow_vtbl);
239 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj);
240 } else if (IsEqualGUID(&IID_IMediaEvent, riid) ||
241 IsEqualGUID(&IID_IMediaEventEx, riid)) {
242 *ppvObj = &(This->IMediaEventEx_vtbl);
243 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj);
244 } else if (IsEqualGUID(&IID_IMediaFilter, riid) ||
245 IsEqualGUID(&IID_IPersist, riid)) {
246 *ppvObj = &(This->IMediaFilter_vtbl);
247 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj);
248 } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) {
249 *ppvObj = &(This->IMediaEventSink_vtbl);
250 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj);
251 } else if (IsEqualGUID(&IID_IGraphConfig, riid)) {
252 *ppvObj = &(This->IGraphConfig_vtbl);
253 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj);
254 } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
255 *ppvObj = &(This->IMediaPosition_vtbl);
256 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj);
257 } else {
258 *ppvObj = NULL;
259 FIXME("unknown interface %s\n", debugstr_guid(riid));
260 return E_NOINTERFACE;
263 IUnknown_AddRef((IUnknown *)(*ppvObj));
264 return S_OK;
267 static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) {
268 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
269 ULONG ref = InterlockedIncrement(&This->ref);
271 TRACE("(%p)->(): new ref = %d\n", This, ref);
273 return ref;
276 static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) {
277 ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
278 ULONG ref = InterlockedDecrement(&This->ref);
280 TRACE("(%p)->(): new ref = %d\n", This, ref);
282 if (ref == 0) {
283 int i;
285 IMediaControl_Stop((IMediaControl*)&(This->IMediaControl_vtbl));
286 if (This->refClock)
287 IReferenceClock_Release(This->refClock);
289 while (This->nFilters)
290 IFilterGraph2_RemoveFilter((IFilterGraph2*)This, This->ppFiltersInGraph[0]);
292 for (i = 0; i < This->nItfCacheEntries; i++)
294 if (This->ItfCacheEntries[i].iface)
295 IUnknown_Release(This->ItfCacheEntries[i].iface);
297 IFilterMapper2_Release(This->pFilterMapper2);
298 CloseHandle(This->hEventCompletion);
299 EventsQueue_Destroy(&This->evqueue);
300 This->cs.DebugInfo->Spare[0] = 0;
301 DeleteCriticalSection(&This->cs);
302 CoTaskMemFree(This->ppFiltersInGraph);
303 CoTaskMemFree(This->pFilterNames);
304 CoTaskMemFree(This);
306 return ref;
310 /*** IUnknown methods ***/
311 static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface,
312 REFIID riid,
313 LPVOID*ppvObj) {
314 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
316 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
317 return Filtergraph_QueryInterface(This, riid, ppvObj);
320 static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) {
321 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
323 TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface);
325 return Filtergraph_AddRef(This);
328 static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) {
329 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
331 TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface);
333 return Filtergraph_Release(This);
336 /*** IFilterGraph methods ***/
337 static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
338 IBaseFilter *pFilter,
339 LPCWSTR pName) {
340 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
341 HRESULT hr;
342 int i,j;
343 WCHAR* wszFilterName = NULL;
344 int duplicate_name = FALSE;
346 TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName);
348 if (!pFilter)
349 return E_POINTER;
351 wszFilterName = CoTaskMemAlloc( (pName ? strlenW(pName) + 6 : 5) * sizeof(WCHAR) );
353 if (pName)
355 /* Check if name already exists */
356 for(i = 0; i < This->nFilters; i++)
357 if (!strcmpW(This->pFilterNames[i], pName))
359 duplicate_name = TRUE;
360 break;
364 /* If no name given or name already existing, generate one */
365 if (!pName || duplicate_name)
367 static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0};
368 static const WCHAR wszFmt2[] = {'%','0','4','d',0};
370 for (j = 0; j < 10000 ; j++)
372 /* Create name */
373 if (pName)
374 sprintfW(wszFilterName, wszFmt1, pName, This->nameIndex);
375 else
376 sprintfW(wszFilterName, wszFmt2, This->nameIndex);
377 TRACE("Generated name %s\n", debugstr_w(wszFilterName));
379 /* Check if the generated name already exists */
380 for(i = 0; i < This->nFilters; i++)
381 if (!strcmpW(This->pFilterNames[i], wszFilterName))
382 break;
384 /* Compute next index and exit if generated name is suitable */
385 if (This->nameIndex++ == 10000)
386 This->nameIndex = 1;
387 if (i == This->nFilters)
388 break;
390 /* Unable to find a suitable name */
391 if (j == 10000)
393 CoTaskMemFree(wszFilterName);
394 return VFW_E_DUPLICATE_NAME;
397 else
398 memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
400 if (This->nFilters + 1 > This->filterCapacity)
402 int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
403 IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
404 LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
405 memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
406 memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
407 if (!This->filterCapacity)
409 CoTaskMemFree(This->ppFiltersInGraph);
410 CoTaskMemFree(This->pFilterNames);
412 This->ppFiltersInGraph = ppNewFilters;
413 This->pFilterNames = pNewNames;
414 This->filterCapacity = newCapacity;
417 hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)This, wszFilterName);
419 if (SUCCEEDED(hr))
421 IBaseFilter_AddRef(pFilter);
422 This->ppFiltersInGraph[This->nFilters] = pFilter;
423 This->pFilterNames[This->nFilters] = wszFilterName;
424 This->nFilters++;
425 IBaseFilter_SetSyncSource(pFilter, This->refClock);
427 else
428 CoTaskMemFree(wszFilterName);
430 if (SUCCEEDED(hr) && duplicate_name)
431 return VFW_S_DUPLICATE_NAME;
433 return hr;
436 static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface,
437 IBaseFilter *pFilter) {
438 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
439 int i;
440 HRESULT hr = E_FAIL;
442 TRACE("(%p/%p)->(%p)\n", This, iface, pFilter);
444 /* FIXME: check graph is stopped */
446 for (i = 0; i < This->nFilters; i++)
448 if (This->ppFiltersInGraph[i] == pFilter)
450 IEnumPins *penumpins;
451 IBaseFilter_Stop(pFilter);
452 hr = IBaseFilter_EnumPins(pFilter, &penumpins);
453 if (SUCCEEDED(hr)) {
454 IPin *ppin;
455 while(IEnumPins_Next(penumpins, 1, &ppin, NULL) == S_OK) {
456 IPin *victim = NULL;
457 HRESULT h;
458 IPin_ConnectedTo(ppin, &victim);
459 if (victim)
461 h = IPin_Disconnect(victim);
462 TRACE("Disconnect other side: %08x\n", h);
463 if (h == VFW_E_NOT_STOPPED)
465 PIN_INFO pinfo;
466 IPin_QueryPinInfo(victim, &pinfo);
467 IBaseFilter_Stop(pinfo.pFilter);
468 IBaseFilter_Release(pinfo.pFilter);
469 h = IPin_Disconnect(victim);
470 TRACE("Disconnect retry: %08x\n", h);
472 IPin_Release(victim);
474 h = IPin_Disconnect(ppin);
475 TRACE("Disconnect 2: %08x\n", h);
477 IEnumPins_Release(penumpins);
480 hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
481 if (SUCCEEDED(hr))
483 IBaseFilter_SetSyncSource(pFilter, NULL);
484 IBaseFilter_Release(pFilter);
485 CoTaskMemFree(This->pFilterNames[i]);
486 memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
487 memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
488 This->nFilters--;
489 /* Invalidate interfaces in the cache */
490 for (i = 0; i < This->nItfCacheEntries; i++)
491 if (pFilter == This->ItfCacheEntries[i].filter)
493 IUnknown_Release(This->ItfCacheEntries[i].iface);
494 This->ItfCacheEntries[i].iface = NULL;
495 This->ItfCacheEntries[i].filter = NULL;
497 return S_OK;
499 break;
503 return hr; /* FIXME: check this error code */
506 static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface,
507 IEnumFilters **ppEnum) {
508 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
510 TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
512 return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum);
515 static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface,
516 LPCWSTR pName,
517 IBaseFilter **ppFilter) {
518 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
519 int i;
521 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter);
523 if (!ppFilter)
524 return E_POINTER;
526 for (i = 0; i < This->nFilters; i++)
528 if (!strcmpW(pName, This->pFilterNames[i]))
530 *ppFilter = This->ppFiltersInGraph[i];
531 IBaseFilter_AddRef(*ppFilter);
532 return S_OK;
536 *ppFilter = NULL;
537 return VFW_E_NOT_FOUND;
540 /* NOTE: despite the implication, it doesn't matter which
541 * way round you put in the input and output pins */
542 static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface,
543 IPin *ppinIn,
544 IPin *ppinOut,
545 const AM_MEDIA_TYPE *pmt) {
546 PIN_DIRECTION dir;
547 HRESULT hr;
549 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
551 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt);
553 /* FIXME: check pins are in graph */
555 if (TRACE_ON(quartz))
557 PIN_INFO PinInfo;
559 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
560 if (FAILED(hr))
561 return hr;
563 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
564 IBaseFilter_Release(PinInfo.pFilter);
566 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
567 if (FAILED(hr))
568 return hr;
570 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
571 IBaseFilter_Release(PinInfo.pFilter);
574 hr = IPin_QueryDirection(ppinIn, &dir);
575 if (SUCCEEDED(hr))
577 if (dir == PINDIR_INPUT)
578 hr = IPin_Connect(ppinOut, ppinIn, pmt);
579 else
580 hr = IPin_Connect(ppinIn, ppinOut, pmt);
583 return hr;
586 static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface,
587 IPin *ppin) {
588 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
589 IPin *pConnectedTo = NULL;
590 HRESULT hr;
591 PIN_DIRECTION pindir;
593 IPin_QueryDirection(ppin, &pindir);
594 hr = IPin_ConnectedTo(ppin, &pConnectedTo);
595 if (FAILED(hr)) {
596 TRACE("Querying connected to failed: %x\n", hr);
597 return hr;
599 IPin_Disconnect(ppin);
600 IPin_Disconnect(pConnectedTo);
601 if (pindir == PINDIR_INPUT)
602 hr = IPin_Connect(pConnectedTo, ppin, NULL);
603 else
604 hr = IPin_Connect(ppin, pConnectedTo, NULL);
605 IPin_Release(pConnectedTo);
606 if (FAILED(hr))
607 ERR("Reconnecting pins failed, pins are not connected now..\n");
608 TRACE("(%p->%p) -- %p %p -> %x\n", iface, This, ppin, pConnectedTo, hr);
609 return hr;
612 static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface,
613 IPin *ppin) {
614 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
616 TRACE("(%p/%p)->(%p)\n", This, iface, ppin);
618 return IPin_Disconnect(ppin);
621 static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) {
622 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
624 TRACE("(%p/%p)->(): stub !!!\n", iface, This);
626 return S_OK;
629 static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar)
631 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
632 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
633 IPropertyBag * pPropBagCat = NULL;
634 HRESULT hr;
636 VariantInit(pvar);
637 V_VT(pvar) = VT_BSTR;
639 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
641 if (SUCCEEDED(hr))
642 hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);
644 if (SUCCEEDED(hr))
645 hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
647 if (SUCCEEDED(hr))
648 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);
650 if (SUCCEEDED(hr))
651 TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal)));
653 if (pPropBagCat)
654 IPropertyBag_Release(pPropBagCat);
656 return hr;
659 static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPin*** pppins, ULONG* pnb)
661 HRESULT hr;
662 ULONG nb = 0;
664 TRACE("(%p, %p, %p, %p)\n", pfilter, pinputpin, pppins, pnb);
665 hr = IPin_QueryInternalConnections(pinputpin, NULL, &nb);
666 if (hr == S_OK) {
667 /* Rendered input */
668 } else if (hr == S_FALSE) {
669 *pppins = CoTaskMemAlloc(sizeof(IPin*)*nb);
670 hr = IPin_QueryInternalConnections(pinputpin, *pppins, &nb);
671 if (hr != S_OK) {
672 ERR("Error (%x)\n", hr);
674 } else if (hr == E_NOTIMPL) {
675 /* Input connected to all outputs */
676 IEnumPins* penumpins;
677 IPin* ppin;
678 int i = 0;
679 TRACE("E_NOTIMPL\n");
680 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
681 if (FAILED(hr)) {
682 ERR("filter Enumpins failed (%x)\n", hr);
683 return hr;
685 i = 0;
686 /* Count output pins */
687 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
688 PIN_DIRECTION pindir;
689 IPin_QueryDirection(ppin, &pindir);
690 if (pindir == PINDIR_OUTPUT)
691 i++;
692 IPin_Release(ppin);
694 *pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
695 /* Retrieve output pins */
696 IEnumPins_Reset(penumpins);
697 i = 0;
698 while(IEnumPins_Next(penumpins, 1, &ppin, &nb) == S_OK) {
699 PIN_DIRECTION pindir;
700 IPin_QueryDirection(ppin, &pindir);
701 if (pindir == PINDIR_OUTPUT)
702 (*pppins)[i++] = ppin;
703 else
704 IPin_Release(ppin);
706 IEnumPins_Release(penumpins);
707 nb = i;
708 if (FAILED(hr)) {
709 ERR("Next failed (%x)\n", hr);
710 return hr;
712 } else if (FAILED(hr)) {
713 ERR("Cannot get internal connection (%x)\n", hr);
714 return hr;
717 *pnb = nb;
718 return S_OK;
721 /*** IGraphBuilder methods ***/
722 static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface,
723 IPin *ppinOut,
724 IPin *ppinIn) {
725 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
726 HRESULT hr;
727 AM_MEDIA_TYPE* mt;
728 IEnumMediaTypes* penummt;
729 ULONG nbmt;
730 IEnumPins* penumpins;
731 IEnumMoniker* pEnumMoniker;
732 GUID tab[2];
733 ULONG nb;
734 IMoniker* pMoniker;
735 ULONG pin;
736 PIN_INFO PinInfo;
737 CLSID FilterCLSID;
739 TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
741 if (TRACE_ON(quartz))
743 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
744 if (FAILED(hr))
745 return hr;
747 TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
748 IBaseFilter_Release(PinInfo.pFilter);
750 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
751 if (FAILED(hr))
752 return hr;
754 TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
755 IBaseFilter_Release(PinInfo.pFilter);
758 /* Try direct connection first */
759 hr = IPin_Connect(ppinOut, ppinIn, NULL);
760 if (SUCCEEDED(hr)) {
761 return S_OK;
763 TRACE("Direct connection failed, trying to insert other filters\n");
765 hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
766 if (FAILED(hr))
767 return hr;
769 hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
770 IBaseFilter_Release(PinInfo.pFilter);
771 if (FAILED(hr))
772 return hr;
774 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
775 * filter to the minor mediatype of input pin of the renderer */
776 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
777 if (FAILED(hr)) {
778 ERR("EnumMediaTypes (%x)\n", hr);
779 return hr;
782 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
783 if (FAILED(hr)) {
784 ERR("IEnumMediaTypes_Next (%x)\n", hr);
785 return hr;
788 if (!nbmt) {
789 ERR("No media type found!\n");
790 return S_OK;
792 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
793 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
795 /* Try to find a suitable filter that can connect to the pin to render */
796 tab[0] = mt->majortype;
797 tab[1] = mt->subtype;
798 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
799 if (FAILED(hr)) {
800 ERR("Unable to enum filters (%x)\n", hr);
801 return hr;
804 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
806 VARIANT var;
807 GUID clsid;
808 IPin** ppins;
809 IPin* ppinfilter = NULL;
810 IBaseFilter* pfilter = NULL;
812 hr = GetFilterInfo(pMoniker, &clsid, &var);
813 IMoniker_Release(pMoniker);
814 if (FAILED(hr)) {
815 ERR("Unable to retrieve filter info (%x)\n", hr);
816 goto error;
819 if (IsEqualGUID(&clsid, &FilterCLSID)) {
820 /* Skip filter (same as the one the output pin belongs to) */
821 goto error;
824 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
825 if (FAILED(hr)) {
826 ERR("Unable to create filter (%x), trying next one\n", hr);
827 goto error;
830 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
831 if (FAILED(hr)) {
832 ERR("Unable to add filter (%x)\n", hr);
833 IBaseFilter_Release(pfilter);
834 pfilter = NULL;
835 goto error;
838 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
839 if (FAILED(hr)) {
840 ERR("Enumpins (%x)\n", hr);
841 goto error;
844 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
845 IEnumPins_Release(penumpins);
847 if (FAILED(hr)) {
848 ERR("Next (%x)\n", hr);
849 goto error;
851 if (pin == 0) {
852 ERR("No Pin\n");
853 goto error;
856 hr = IPin_Connect(ppinOut, ppinfilter, NULL);
857 if (FAILED(hr)) {
858 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
859 goto error;
861 TRACE("Successfully connected to filter, follow chain...\n");
863 /* Render all output pins of the filter by calling IFilterGraph2_Render on each of them */
864 hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb);
866 if (SUCCEEDED(hr)) {
867 int i;
868 if (nb == 0) {
869 IPin_Disconnect(ppinOut);
870 goto error;
872 TRACE("pins to consider: %d\n", nb);
873 for(i = 0; i < nb; i++) {
874 TRACE("Processing pin %d\n", i);
875 hr = IFilterGraph2_Connect(iface, ppins[i], ppinIn);
876 if (FAILED(hr)) {
877 TRACE("Cannot render pin %p (%x)\n", ppinfilter, hr);
879 IPin_Release(ppins[i]);
880 if (SUCCEEDED(hr)) break;
882 while (++i < nb) IPin_Release(ppins[i]);
883 CoTaskMemFree(ppins);
884 IPin_Release(ppinfilter);
885 IBaseFilter_Release(pfilter);
886 break;
889 error:
890 if (ppinfilter) IPin_Release(ppinfilter);
891 if (pfilter) {
892 IFilterGraph2_RemoveFilter(iface, pfilter);
893 IBaseFilter_Release(pfilter);
897 IEnumMediaTypes_Release(penummt);
898 DeleteMediaType(mt);
900 return S_OK;
903 static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface,
904 IPin *ppinOut) {
905 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
906 IEnumMediaTypes* penummt;
907 AM_MEDIA_TYPE* mt;
908 ULONG nbmt;
909 HRESULT hr;
911 IEnumMoniker* pEnumMoniker;
912 GUID tab[2];
913 ULONG nb;
914 IMoniker* pMoniker;
916 TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
918 if (TRACE_ON(quartz))
920 PIN_INFO PinInfo;
922 hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
923 if (FAILED(hr))
924 return hr;
926 TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
927 IBaseFilter_Release(PinInfo.pFilter);
930 hr = IPin_EnumMediaTypes(ppinOut, &penummt);
931 if (FAILED(hr)) {
932 ERR("EnumMediaTypes (%x)\n", hr);
933 return hr;
936 while(1)
938 hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
939 if (FAILED(hr)) {
940 ERR("IEnumMediaTypes_Next (%x)\n", hr);
941 return hr;
943 if (!nbmt)
944 break;
945 TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
946 TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
948 /* Try to find a suitable renderer with the same media type */
949 tab[0] = mt->majortype;
950 tab[1] = GUID_NULL;
951 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, TRUE, FALSE, 0, NULL, NULL, NULL);
952 if (FAILED(hr)) {
953 ERR("Unable to enum filters (%x)\n", hr);
954 return hr;
957 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
959 VARIANT var;
960 GUID clsid;
961 IPin* ppinfilter;
962 IBaseFilter* pfilter = NULL;
963 IEnumPins* penumpins;
964 ULONG pin;
966 hr = GetFilterInfo(pMoniker, &clsid, &var);
967 IMoniker_Release(pMoniker);
968 if (FAILED(hr)) {
969 ERR("Unable to retrieve filter info (%x)\n", hr);
970 goto error;
973 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
974 if (FAILED(hr)) {
975 ERR("Unable to create filter (%x), trying next one\n", hr);
976 goto error;
979 hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal));
980 if (FAILED(hr)) {
981 ERR("Unable to add filter (%x)\n", hr);
982 IBaseFilter_Release(pfilter);
983 pfilter = NULL;
984 goto error;
987 hr = IBaseFilter_EnumPins(pfilter, &penumpins);
988 if (FAILED(hr)) {
989 ERR("Splitter Enumpins (%x)\n", hr);
990 goto error;
992 hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
993 IEnumPins_Release(penumpins);
994 if (FAILED(hr)) {
995 ERR("Next (%x)\n", hr);
996 goto error;
998 if (pin == 0) {
999 ERR("No Pin\n");
1000 goto error;
1003 /* Connect the pin to render to the renderer */
1004 hr = IFilterGraph2_Connect(iface, ppinOut, ppinfilter);
1005 if (FAILED(hr)) {
1006 TRACE("Unable to connect to renderer (%x)\n", hr);
1007 IPin_Release(ppinfilter);
1008 goto error;
1010 IPin_Release(ppinfilter);
1011 IBaseFilter_Release(pfilter);
1012 pfilter = NULL;
1013 break;
1015 error:
1016 if (pfilter) {
1017 IFilterGraph2_RemoveFilter(iface, pfilter);
1018 IBaseFilter_Release(pfilter);
1022 DeleteMediaType(mt);
1023 break;
1026 IEnumMediaTypes_Release(penummt);
1028 return S_OK;
1031 static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface,
1032 LPCWSTR lpcwstrFile,
1033 LPCWSTR lpcwstrPlayList) {
1034 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1035 static const WCHAR string[] = {'R','e','a','d','e','r',0};
1036 IBaseFilter* preader = NULL;
1037 IBaseFilter* psplitter = NULL;
1038 IPin* ppinreader = NULL;
1039 IPin* ppinsplitter = NULL;
1040 IEnumPins* penumpins;
1041 ULONG pin;
1042 HRESULT hr;
1043 IEnumMoniker* pEnumMoniker = NULL;
1044 GUID tab[2];
1045 IPin** ppins = NULL;
1046 ULONG nb;
1047 IMoniker* pMoniker;
1048 IFileSourceFilter* pfile = NULL;
1049 AM_MEDIA_TYPE mt;
1050 WCHAR* filename;
1052 TRACE("(%p/%p)->(%s, %s)\n", This, iface, debugstr_w(lpcwstrFile), debugstr_w(lpcwstrPlayList));
1054 if (lpcwstrPlayList != NULL)
1055 return E_INVALIDARG;
1057 hr = IFilterGraph2_AddSourceFilter(iface, lpcwstrFile, string, &preader);
1059 /* Retrieve file media type */
1060 if (SUCCEEDED(hr))
1061 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1062 if (SUCCEEDED(hr)) {
1063 hr = IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1064 IFileSourceFilter_Release(pfile);
1067 if (SUCCEEDED(hr))
1068 hr = IBaseFilter_EnumPins(preader, &penumpins);
1069 if (SUCCEEDED(hr)) {
1070 hr = IEnumPins_Next(penumpins, 1, &ppinreader, &pin);
1071 IEnumPins_Release(penumpins);
1074 if (SUCCEEDED(hr)) {
1075 tab[0] = mt.majortype;
1076 tab[1] = mt.subtype;
1077 hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
1080 if (FAILED(hr))
1082 if (ppinreader)
1083 IPin_Release(ppinreader);
1084 if (pEnumMoniker)
1085 IEnumMoniker_Release(pEnumMoniker);
1086 if (preader) {
1087 IFilterGraph2_RemoveFilter(iface, preader);
1088 IBaseFilter_Release(preader);
1090 return hr;
1093 hr = VFW_E_CANNOT_RENDER;
1094 while(IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK)
1096 VARIANT var;
1097 GUID clsid;
1099 hr = GetFilterInfo(pMoniker, &clsid, &var);
1100 IMoniker_Release(pMoniker);
1101 if (FAILED(hr)) {
1102 ERR("Unable to retrieve filter info (%x)\n", hr);
1103 continue;
1106 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&psplitter);
1107 if (FAILED(hr)) {
1108 ERR("Unable to create filter (%x), trying next one\n", hr);
1109 continue;
1112 hr = IFilterGraph2_AddFilter(iface, psplitter, V_UNION(&var, bstrVal));
1113 if (FAILED(hr)) {
1114 ERR("Unable add filter (%x)\n", hr);
1115 IBaseFilter_Release(psplitter);
1116 continue;
1119 /* Connect file source and splitter filters together */
1120 /* Make the splitter analyze incoming data */
1122 hr = IBaseFilter_EnumPins(psplitter, &penumpins);
1123 if (SUCCEEDED(hr)) {
1124 hr = IEnumPins_Next(penumpins, 1, &ppinsplitter, &pin);
1125 IEnumPins_Release(penumpins);
1128 if (SUCCEEDED(hr))
1129 hr = IPin_Connect(ppinreader, ppinsplitter, NULL);
1131 /* Make sure there's some output pins in the filter */
1132 if (SUCCEEDED(hr))
1133 hr = GetInternalConnections(psplitter, ppinsplitter, &ppins, &nb);
1134 if (SUCCEEDED(hr)) {
1135 if(nb == 0) {
1136 IPin_Disconnect(ppinreader);
1137 TRACE("No output pins found in filter\n");
1138 hr = VFW_E_CANNOT_RENDER;
1142 if (ppinsplitter)
1143 IPin_Release(ppinsplitter);
1144 ppinsplitter = NULL;
1146 if (SUCCEEDED(hr)) {
1147 TRACE("Successfully connected to filter\n");
1148 break;
1151 TRACE("Cannot connect to filter (%x), trying next one\n", hr);
1153 if (ppins) {
1154 CoTaskMemFree(ppins);
1155 ppins = NULL;
1157 IFilterGraph2_RemoveFilter(iface, psplitter);
1158 IBaseFilter_Release(psplitter);
1159 psplitter = NULL;
1162 /* Render all output pin of the splitter by calling IFilterGraph2_Render on each of them */
1163 if (SUCCEEDED(hr)) {
1164 int partial = 0;
1165 int i;
1166 TRACE("pins to consider: %d\n", nb);
1167 for(i = 0; i < nb; i++) {
1168 TRACE("Processing pin %d\n", i);
1169 hr = IFilterGraph2_Render(iface, ppins[i]);
1170 if (FAILED(hr)) {
1171 ERR("Cannot render pin %p (%x)\n", ppins[i], hr);
1172 partial = 1;
1174 IPin_Release(ppins[i]);
1176 CoTaskMemFree(ppins);
1178 hr = (partial ? VFW_S_PARTIAL_RENDER : S_OK);
1181 IPin_Release(ppinreader);
1182 IBaseFilter_Release(preader);
1183 if (psplitter)
1184 IBaseFilter_Release(psplitter);
1186 return hr;
1189 static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface,
1190 LPCWSTR lpcwstrFileName,
1191 LPCWSTR lpcwstrFilterName,
1192 IBaseFilter **ppFilter) {
1193 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1194 HRESULT hr;
1195 IBaseFilter* preader;
1196 IFileSourceFilter* pfile = NULL;
1197 AM_MEDIA_TYPE mt;
1198 WCHAR* filename;
1200 TRACE("(%p/%p)->(%s, %s, %p)\n", This, iface, debugstr_w(lpcwstrFileName), debugstr_w(lpcwstrFilterName), ppFilter);
1202 /* Instantiate a file source filter */
1203 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
1204 if (FAILED(hr)) {
1205 ERR("Unable to create file source filter (%x)\n", hr);
1206 return hr;
1209 hr = IFilterGraph2_AddFilter(iface, preader, lpcwstrFilterName);
1210 if (FAILED(hr)) {
1211 ERR("Unable add filter (%x)\n", hr);
1212 IBaseFilter_Release(preader);
1213 return hr;
1216 hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter, (LPVOID*)&pfile);
1217 if (FAILED(hr)) {
1218 ERR("Unable to get IFileSourceInterface (%x)\n", hr);
1219 goto error;
1222 /* Load the file in the file source filter */
1223 hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
1224 if (FAILED(hr)) {
1225 ERR("Load (%x)\n", hr);
1226 goto error;
1229 IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
1230 if (FAILED(hr)) {
1231 ERR("GetCurFile (%x)\n", hr);
1232 goto error;
1234 TRACE("File %s\n", debugstr_w(filename));
1235 TRACE("MajorType %s\n", debugstr_guid(&mt.majortype));
1236 TRACE("SubType %s\n", debugstr_guid(&mt.subtype));
1238 if (ppFilter)
1239 *ppFilter = preader;
1240 IFileSourceFilter_Release(pfile);
1242 return S_OK;
1244 error:
1245 if (pfile)
1246 IFileSourceFilter_Release(pfile);
1247 IFilterGraph2_RemoveFilter(iface, preader);
1248 IBaseFilter_Release(preader);
1250 return hr;
1253 static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface,
1254 DWORD_PTR hFile) {
1255 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1257 TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile);
1259 return S_OK;
1262 static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) {
1263 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1265 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1267 return S_OK;
1270 static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) {
1271 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1273 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1275 return S_OK;
1278 /*** IFilterGraph2 methods ***/
1279 static HRESULT WINAPI FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2 *iface,
1280 IMoniker *pMoniker,
1281 IBindCtx *pCtx,
1282 LPCWSTR lpcwstrFilterName,
1283 IBaseFilter **ppFilter) {
1284 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1286 TRACE("(%p/%p)->(%p %p %s %p): stub !!!\n", This, iface, pMoniker, pCtx, debugstr_w(lpcwstrFilterName), ppFilter);
1288 return S_OK;
1291 static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface,
1292 IPin *ppin,
1293 const AM_MEDIA_TYPE *pmt) {
1294 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1296 TRACE("(%p/%p)->(%p %p): stub !!!\n", This, iface, ppin, pmt);
1298 return S_OK;
1301 static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface,
1302 IPin *pPinOut,
1303 DWORD dwFlags,
1304 DWORD *pvContext) {
1305 ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface);
1307 TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This, iface, pPinOut, dwFlags, pvContext);
1309 return S_OK;
1313 static const IFilterGraph2Vtbl IFilterGraph2_VTable =
1315 FilterGraph2_QueryInterface,
1316 FilterGraph2_AddRef,
1317 FilterGraph2_Release,
1318 FilterGraph2_AddFilter,
1319 FilterGraph2_RemoveFilter,
1320 FilterGraph2_EnumFilters,
1321 FilterGraph2_FindFilterByName,
1322 FilterGraph2_ConnectDirect,
1323 FilterGraph2_Reconnect,
1324 FilterGraph2_Disconnect,
1325 FilterGraph2_SetDefaultSyncSource,
1326 FilterGraph2_Connect,
1327 FilterGraph2_Render,
1328 FilterGraph2_RenderFile,
1329 FilterGraph2_AddSourceFilter,
1330 FilterGraph2_SetLogFile,
1331 FilterGraph2_Abort,
1332 FilterGraph2_ShouldOperationContinue,
1333 FilterGraph2_AddSourceFilterForMoniker,
1334 FilterGraph2_ReconnectEx,
1335 FilterGraph2_RenderEx
1338 /*** IUnknown methods ***/
1339 static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface,
1340 REFIID riid,
1341 LPVOID*ppvObj) {
1342 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1344 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1346 return Filtergraph_QueryInterface(This, riid, ppvObj);
1349 static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) {
1350 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1352 TRACE("(%p/%p)->()\n", This, iface);
1354 return Filtergraph_AddRef(This);
1357 static ULONG WINAPI MediaControl_Release(IMediaControl *iface) {
1358 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1360 TRACE("(%p/%p)->()\n", This, iface);
1362 return Filtergraph_Release(This);
1366 /*** IDispatch methods ***/
1367 static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface,
1368 UINT*pctinfo) {
1369 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1371 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1373 return S_OK;
1376 static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface,
1377 UINT iTInfo,
1378 LCID lcid,
1379 ITypeInfo**ppTInfo) {
1380 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1382 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1384 return S_OK;
1387 static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface,
1388 REFIID riid,
1389 LPOLESTR*rgszNames,
1390 UINT cNames,
1391 LCID lcid,
1392 DISPID*rgDispId) {
1393 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1395 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1397 return S_OK;
1400 static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
1401 DISPID dispIdMember,
1402 REFIID riid,
1403 LCID lcid,
1404 WORD wFlags,
1405 DISPPARAMS*pDispParams,
1406 VARIANT*pVarResult,
1407 EXCEPINFO*pExepInfo,
1408 UINT*puArgErr) {
1409 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1411 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);
1413 return S_OK;
1416 typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
1418 static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
1420 HRESULT hr;
1421 IPin* pInputPin;
1422 IPin** ppPins;
1423 ULONG nb;
1424 ULONG i;
1425 PIN_INFO PinInfo;
1427 TRACE("%p %p\n", pGraph, pOutputPin);
1428 PinInfo.pFilter = NULL;
1430 hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
1432 if (SUCCEEDED(hr))
1434 hr = IPin_QueryPinInfo(pInputPin, &PinInfo);
1435 if (SUCCEEDED(hr))
1436 hr = GetInternalConnections(PinInfo.pFilter, pInputPin, &ppPins, &nb);
1437 IPin_Release(pInputPin);
1440 if (SUCCEEDED(hr))
1442 if (nb == 0)
1444 TRACE("Reached a renderer\n");
1445 /* Count renderers for end of stream notification */
1446 pGraph->nRenderers++;
1448 else
1450 for(i = 0; i < nb; i++)
1452 /* Explore the graph downstream from this pin
1453 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1454 * several input pins are connected to the same output (a MUX for instance). */
1455 ExploreGraph(pGraph, ppPins[i], FoundFilter);
1456 IPin_Release(ppPins[i]);
1459 CoTaskMemFree(ppPins);
1461 TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
1462 FoundFilter(PinInfo.pFilter);
1465 if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
1466 return hr;
1469 static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
1470 return IBaseFilter_Run(pFilter, 0);
1473 static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
1474 return IBaseFilter_Pause(pFilter);
1477 static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
1478 return IBaseFilter_Stop(pFilter);
1481 static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
1482 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1483 int i;
1484 IBaseFilter* pfilter;
1485 IEnumPins* pEnum;
1486 HRESULT hr;
1487 IPin* pPin;
1488 DWORD dummy;
1489 PIN_DIRECTION dir;
1490 TRACE("(%p/%p)->()\n", This, iface);
1492 /* Explorer the graph from source filters to renderers, determine renderers
1493 * number and run filters from renderers to source filters */
1494 This->nRenderers = 0;
1495 ResetEvent(This->hEventCompletion);
1497 for(i = 0; i < This->nFilters; i++)
1499 BOOL source = TRUE;
1500 pfilter = This->ppFiltersInGraph[i];
1501 hr = IBaseFilter_EnumPins(pfilter, &pEnum);
1502 if (hr != S_OK)
1504 ERR("Enum pins failed %x\n", hr);
1505 continue;
1507 /* Check if it is a source filter */
1508 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1510 IPin_QueryDirection(pPin, &dir);
1511 IPin_Release(pPin);
1512 if (dir == PINDIR_INPUT)
1514 source = FALSE;
1515 break;
1518 if (source)
1520 TRACE("Found a source filter %p\n", pfilter);
1521 IEnumPins_Reset(pEnum);
1522 while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
1524 /* Explore the graph downstream from this pin */
1525 ExploreGraph(This, pPin, FoundFilter);
1526 IPin_Release(pPin);
1528 FoundFilter(pfilter);
1530 IEnumPins_Release(pEnum);
1533 return S_FALSE;
1536 /*** IMediaControl methods ***/
1537 static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
1538 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1539 TRACE("(%p/%p)->()\n", This, iface);
1541 if (This->state == State_Running) return S_OK;
1543 EnterCriticalSection(&This->cs);
1544 SendFilterMessage(iface, SendRun);
1545 This->state = State_Running;
1546 LeaveCriticalSection(&This->cs);
1547 return S_FALSE;
1550 static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
1551 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1552 TRACE("(%p/%p)->()\n", This, iface);
1554 if (This->state == State_Paused) return S_OK;
1556 EnterCriticalSection(&This->cs);
1557 SendFilterMessage(iface, SendPause);
1558 This->state = State_Paused;
1559 LeaveCriticalSection(&This->cs);
1560 return S_FALSE;
1563 static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
1564 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1565 TRACE("(%p/%p)->()\n", This, iface);
1567 if (This->state == State_Stopped) return S_OK;
1569 EnterCriticalSection(&This->cs);
1570 if (This->state == State_Running) SendFilterMessage(iface, SendPause);
1571 SendFilterMessage(iface, SendStop);
1572 This->state = State_Stopped;
1573 LeaveCriticalSection(&This->cs);
1574 return S_FALSE;
1577 static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
1578 LONG msTimeout,
1579 OAFilterState *pfs) {
1580 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1582 TRACE("(%p/%p)->(%d, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
1584 EnterCriticalSection(&This->cs);
1586 *pfs = This->state;
1588 LeaveCriticalSection(&This->cs);
1590 return S_OK;
1593 static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface,
1594 BSTR strFilename) {
1595 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1597 TRACE("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename);
1599 return S_OK;
1602 static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface,
1603 BSTR strFilename,
1604 IDispatch **ppUnk) {
1605 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1607 TRACE("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk);
1609 return S_OK;
1612 static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface,
1613 IDispatch **ppUnk) {
1614 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1616 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1618 return S_OK;
1621 static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
1622 IDispatch **ppUnk) {
1623 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1625 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk);
1627 return S_OK;
1630 static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) {
1631 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
1633 TRACE("(%p/%p)->(): stub !!!\n", This, iface);
1635 return S_OK;
1639 static const IMediaControlVtbl IMediaControl_VTable =
1641 MediaControl_QueryInterface,
1642 MediaControl_AddRef,
1643 MediaControl_Release,
1644 MediaControl_GetTypeInfoCount,
1645 MediaControl_GetTypeInfo,
1646 MediaControl_GetIDsOfNames,
1647 MediaControl_Invoke,
1648 MediaControl_Run,
1649 MediaControl_Pause,
1650 MediaControl_Stop,
1651 MediaControl_GetState,
1652 MediaControl_RenderFile,
1653 MediaControl_AddSourceFilter,
1654 MediaControl_get_FilterCollection,
1655 MediaControl_get_RegFilterCollection,
1656 MediaControl_StopWhenReady
1660 /*** IUnknown methods ***/
1661 static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface,
1662 REFIID riid,
1663 LPVOID*ppvObj) {
1664 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1666 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1668 return Filtergraph_QueryInterface(This, riid, ppvObj);
1671 static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) {
1672 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1674 TRACE("(%p/%p)->()\n", This, iface);
1676 return Filtergraph_AddRef(This);
1679 static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
1680 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1682 TRACE("(%p/%p)->()\n", This, iface);
1684 return Filtergraph_Release(This);
1687 /*** IMediaSeeking methods ***/
1688 static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
1689 DWORD *pCapabilities) {
1690 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1692 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1694 return S_OK;
1697 static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
1698 DWORD *pCapabilities) {
1699 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1701 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
1703 return S_OK;
1706 static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface,
1707 const GUID *pFormat) {
1708 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1710 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1712 return S_OK;
1715 static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface,
1716 GUID *pFormat) {
1717 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1719 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1721 return S_OK;
1724 static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface,
1725 GUID *pFormat) {
1726 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1728 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1730 return S_OK;
1733 static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface,
1734 const GUID *pFormat) {
1735 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1737 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1739 return S_OK;
1742 static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
1743 const GUID *pFormat) {
1744 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1746 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pFormat);
1748 return S_OK;
1751 static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
1752 LONGLONG *pDuration) {
1753 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1755 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDuration);
1757 return S_OK;
1760 static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
1761 LONGLONG *pStop) {
1762 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1764 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pStop);
1766 return S_OK;
1769 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
1770 LONGLONG *pCurrent) {
1771 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1773 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pCurrent);
1775 return S_OK;
1778 static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface,
1779 LONGLONG *pTarget,
1780 const GUID *pTargetFormat,
1781 LONGLONG Source,
1782 const GUID *pSourceFormat) {
1783 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1785 TRACE("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget,
1786 pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat);
1788 return S_OK;
1791 static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface,
1792 LONGLONG *pCurrent,
1793 DWORD dwCurrentFlags,
1794 LONGLONG *pStop,
1795 DWORD dwStopFlags) {
1796 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1798 TRACE("(%p/%p)->(%p, %08x, %p, %08x): stub !!!\n", This, iface, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
1800 return S_OK;
1803 static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
1804 LONGLONG *pCurrent,
1805 LONGLONG *pStop) {
1806 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1808 TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pCurrent, pStop);
1810 return S_OK;
1813 static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
1814 LONGLONG *pEarliest,
1815 LONGLONG *pLatest) {
1816 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1818 TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest);
1820 return S_OK;
1823 static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface,
1824 double dRate) {
1825 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1827 TRACE("(%p/%p)->(%f): stub !!!\n", This, iface, dRate);
1829 return S_OK;
1832 static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface,
1833 double *pdRate) {
1834 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1836 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate);
1838 return S_OK;
1841 static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface,
1842 LONGLONG *pllPreroll) {
1843 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
1845 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll);
1847 return S_OK;
1851 static const IMediaSeekingVtbl IMediaSeeking_VTable =
1853 MediaSeeking_QueryInterface,
1854 MediaSeeking_AddRef,
1855 MediaSeeking_Release,
1856 MediaSeeking_GetCapabilities,
1857 MediaSeeking_CheckCapabilities,
1858 MediaSeeking_IsFormatSupported,
1859 MediaSeeking_QueryPreferredFormat,
1860 MediaSeeking_GetTimeFormat,
1861 MediaSeeking_IsUsingTimeFormat,
1862 MediaSeeking_SetTimeFormat,
1863 MediaSeeking_GetDuration,
1864 MediaSeeking_GetStopPosition,
1865 MediaSeeking_GetCurrentPosition,
1866 MediaSeeking_ConvertTimeFormat,
1867 MediaSeeking_SetPositions,
1868 MediaSeeking_GetPositions,
1869 MediaSeeking_GetAvailable,
1870 MediaSeeking_SetRate,
1871 MediaSeeking_GetRate,
1872 MediaSeeking_GetPreroll
1875 /*** IUnknown methods ***/
1876 static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID riid, void** ppvObj){
1877 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1879 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1881 return Filtergraph_QueryInterface(This, riid, ppvObj);
1884 static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface){
1885 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1887 TRACE("(%p/%p)->()\n", This, iface);
1889 return Filtergraph_AddRef(This);
1892 static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface){
1893 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface);
1895 TRACE("(%p/%p)->()\n", This, iface);
1897 return Filtergraph_Release(This);
1900 /*** IDispatch methods ***/
1901 static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){
1902 FIXME("(%p) stub!\n", iface);
1903 return E_NOTIMPL;
1906 static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){
1907 FIXME("(%p) stub!\n", iface);
1908 return E_NOTIMPL;
1911 static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){
1912 FIXME("(%p) stub!\n", iface);
1913 return E_NOTIMPL;
1916 static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){
1917 FIXME("(%p) stub!\n", iface);
1918 return E_NOTIMPL;
1921 /*** IMediaPosition methods ***/
1922 static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength){
1923 FIXME("(%p)->(%p) stub!\n", iface, plength);
1924 return E_NOTIMPL;
1927 static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime){
1928 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1929 return E_NOTIMPL;
1932 static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime){
1933 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1934 return E_NOTIMPL;
1937 static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime){
1938 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1939 return E_NOTIMPL;
1942 static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime){
1943 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1944 return E_NOTIMPL;
1947 static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){
1948 FIXME("(%p)->(%p) stub!\n", iface, pllTime);
1949 return E_NOTIMPL;
1952 static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){
1953 FIXME("(%p)->(%f) stub!\n", iface, llTime);
1954 return E_NOTIMPL;
1957 static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate){
1958 FIXME("(%p)->(%f) stub!\n", iface, dRate);
1959 return E_NOTIMPL;
1962 static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate){
1963 FIXME("(%p)->(%p) stub!\n", iface, pdRate);
1964 return E_NOTIMPL;
1967 static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){
1968 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward);
1969 return E_NOTIMPL;
1972 static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){
1973 FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward);
1974 return E_NOTIMPL;
1978 static const IMediaPositionVtbl IMediaPosition_VTable =
1980 MediaPosition_QueryInterface,
1981 MediaPosition_AddRef,
1982 MediaPosition_Release,
1983 MediaPosition_GetTypeInfoCount,
1984 MediaPosition_GetTypeInfo,
1985 MediaPosition_GetIDsOfNames,
1986 MediaPosition_Invoke,
1987 MediaPosition_get_Duration,
1988 MediaPosition_put_CurrentPosition,
1989 MediaPosition_get_CurrentPosition,
1990 MediaPosition_get_StopTime,
1991 MediaPosition_put_StopTime,
1992 MediaPosition_get_PrerollTime,
1993 MediaPosition_put_PrerollTime,
1994 MediaPosition_put_Rate,
1995 MediaPosition_get_Rate,
1996 MediaPosition_CanSeekForward,
1997 MediaPosition_CanSeekBackward
2000 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
2002 HRESULT hr = E_NOINTERFACE;
2003 int i;
2004 int entry;
2006 /* Check if the interface type is already registered */
2007 for (entry = 0; entry < pGraph->nItfCacheEntries; entry++)
2008 if (riid == pGraph->ItfCacheEntries[entry].riid)
2010 if (pGraph->ItfCacheEntries[entry].iface)
2012 /* Return the interface if available */
2013 *ppvObj = pGraph->ItfCacheEntries[entry].iface;
2014 return S_OK;
2016 break;
2019 if (entry >= MAX_ITF_CACHE_ENTRIES)
2021 FIXME("Not enough space to store interface in the cache\n");
2022 return E_OUTOFMEMORY;
2025 /* Find a filter supporting the requested interface */
2026 for (i = 0; i < pGraph->nFilters; i++)
2028 hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
2029 if (hr == S_OK)
2031 pGraph->ItfCacheEntries[entry].riid = riid;
2032 pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
2033 pGraph->ItfCacheEntries[entry].iface = (IUnknown*)*ppvObj;
2034 if (entry >= pGraph->nItfCacheEntries)
2035 pGraph->nItfCacheEntries++;
2036 return S_OK;
2038 if (hr != E_NOINTERFACE)
2039 return hr;
2042 return hr;
2045 /*** IUnknown methods ***/
2046 static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface,
2047 REFIID riid,
2048 LPVOID*ppvObj) {
2049 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2051 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2053 return Filtergraph_QueryInterface(This, riid, ppvObj);
2056 static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) {
2057 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2059 TRACE("(%p/%p)->()\n", This, iface);
2061 return Filtergraph_AddRef(This);
2064 static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) {
2065 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2067 TRACE("(%p/%p)->()\n", This, iface);
2069 return Filtergraph_Release(This);
2072 /*** IDispatch methods ***/
2073 static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface,
2074 UINT*pctinfo) {
2075 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2076 IBasicAudio* pBasicAudio;
2077 HRESULT hr;
2079 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2081 EnterCriticalSection(&This->cs);
2083 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2085 if (hr == S_OK)
2086 hr = IBasicAudio_GetTypeInfoCount(pBasicAudio, pctinfo);
2088 LeaveCriticalSection(&This->cs);
2090 return hr;
2093 static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface,
2094 UINT iTInfo,
2095 LCID lcid,
2096 ITypeInfo**ppTInfo) {
2097 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2098 IBasicAudio* pBasicAudio;
2099 HRESULT hr;
2101 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2103 EnterCriticalSection(&This->cs);
2105 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2107 if (hr == S_OK)
2108 hr = IBasicAudio_GetTypeInfo(pBasicAudio, iTInfo, lcid, ppTInfo);
2110 LeaveCriticalSection(&This->cs);
2112 return hr;
2115 static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface,
2116 REFIID riid,
2117 LPOLESTR*rgszNames,
2118 UINT cNames,
2119 LCID lcid,
2120 DISPID*rgDispId) {
2121 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2122 IBasicAudio* pBasicAudio;
2123 HRESULT hr;
2125 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2127 EnterCriticalSection(&This->cs);
2129 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2131 if (hr == S_OK)
2132 hr = IBasicAudio_GetIDsOfNames(pBasicAudio, riid, rgszNames, cNames, lcid, rgDispId);
2134 LeaveCriticalSection(&This->cs);
2136 return hr;
2139 static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface,
2140 DISPID dispIdMember,
2141 REFIID riid,
2142 LCID lcid,
2143 WORD wFlags,
2144 DISPPARAMS*pDispParams,
2145 VARIANT*pVarResult,
2146 EXCEPINFO*pExepInfo,
2147 UINT*puArgErr) {
2148 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2149 IBasicAudio* pBasicAudio;
2150 HRESULT hr;
2152 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);
2154 EnterCriticalSection(&This->cs);
2156 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2158 if (hr == S_OK)
2159 hr = IBasicAudio_Invoke(pBasicAudio, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2161 LeaveCriticalSection(&This->cs);
2163 return hr;
2166 /*** IBasicAudio methods ***/
2167 static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface,
2168 long lVolume) {
2169 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2170 IBasicAudio* pBasicAudio;
2171 HRESULT hr;
2173 TRACE("(%p/%p)->(%ld)\n", This, iface, lVolume);
2175 EnterCriticalSection(&This->cs);
2177 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2179 if (hr == S_OK)
2180 hr = IBasicAudio_put_Volume(pBasicAudio, lVolume);
2182 LeaveCriticalSection(&This->cs);
2184 return hr;
2187 static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface,
2188 long *plVolume) {
2189 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2190 IBasicAudio* pBasicAudio;
2191 HRESULT hr;
2193 TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
2195 EnterCriticalSection(&This->cs);
2197 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2199 if (hr == S_OK)
2200 hr = IBasicAudio_get_Volume(pBasicAudio, plVolume);
2202 LeaveCriticalSection(&This->cs);
2204 return hr;
2207 static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface,
2208 long lBalance) {
2209 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2210 IBasicAudio* pBasicAudio;
2211 HRESULT hr;
2213 TRACE("(%p/%p)->(%ld)\n", This, iface, lBalance);
2215 EnterCriticalSection(&This->cs);
2217 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2219 if (hr == S_OK)
2220 hr = IBasicAudio_put_Balance(pBasicAudio, lBalance);
2222 LeaveCriticalSection(&This->cs);
2224 return hr;
2227 static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface,
2228 long *plBalance) {
2229 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface);
2230 IBasicAudio* pBasicAudio;
2231 HRESULT hr;
2233 TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
2235 EnterCriticalSection(&This->cs);
2237 hr = GetTargetInterface(This, &IID_IBasicAudio, (LPVOID*)&pBasicAudio);
2239 if (hr == S_OK)
2240 hr = IBasicAudio_get_Balance(pBasicAudio, plBalance);
2242 LeaveCriticalSection(&This->cs);
2244 return hr;
2247 static const IBasicAudioVtbl IBasicAudio_VTable =
2249 BasicAudio_QueryInterface,
2250 BasicAudio_AddRef,
2251 BasicAudio_Release,
2252 BasicAudio_GetTypeInfoCount,
2253 BasicAudio_GetTypeInfo,
2254 BasicAudio_GetIDsOfNames,
2255 BasicAudio_Invoke,
2256 BasicAudio_put_Volume,
2257 BasicAudio_get_Volume,
2258 BasicAudio_put_Balance,
2259 BasicAudio_get_Balance
2262 /*** IUnknown methods ***/
2263 static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo *iface,
2264 REFIID riid,
2265 LPVOID*ppvObj) {
2266 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2268 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
2270 return Filtergraph_QueryInterface(This, riid, ppvObj);
2273 static ULONG WINAPI BasicVideo_AddRef(IBasicVideo *iface) {
2274 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2276 TRACE("(%p/%p)->()\n", This, iface);
2278 return Filtergraph_AddRef(This);
2281 static ULONG WINAPI BasicVideo_Release(IBasicVideo *iface) {
2282 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2284 TRACE("(%p/%p)->()\n", This, iface);
2286 return Filtergraph_Release(This);
2289 /*** IDispatch methods ***/
2290 static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo *iface,
2291 UINT*pctinfo) {
2292 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2293 IBasicVideo* pBasicVideo;
2294 HRESULT hr;
2296 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
2298 EnterCriticalSection(&This->cs);
2300 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2302 if (hr == S_OK)
2303 hr = IBasicVideo_GetTypeInfoCount(pBasicVideo, pctinfo);
2305 LeaveCriticalSection(&This->cs);
2307 return hr;
2310 static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo *iface,
2311 UINT iTInfo,
2312 LCID lcid,
2313 ITypeInfo**ppTInfo) {
2314 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2315 IBasicVideo* pBasicVideo;
2316 HRESULT hr;
2318 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
2320 EnterCriticalSection(&This->cs);
2322 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2324 if (hr == S_OK)
2325 hr = IBasicVideo_GetTypeInfo(pBasicVideo, iTInfo, lcid, ppTInfo);
2327 LeaveCriticalSection(&This->cs);
2329 return hr;
2332 static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo *iface,
2333 REFIID riid,
2334 LPOLESTR*rgszNames,
2335 UINT cNames,
2336 LCID lcid,
2337 DISPID*rgDispId) {
2338 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2339 IBasicVideo* pBasicVideo;
2340 HRESULT hr;
2342 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
2344 EnterCriticalSection(&This->cs);
2346 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2348 if (hr == S_OK)
2349 hr = IBasicVideo_GetIDsOfNames(pBasicVideo, riid, rgszNames, cNames, lcid, rgDispId);
2351 LeaveCriticalSection(&This->cs);
2353 return hr;
2356 static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo *iface,
2357 DISPID dispIdMember,
2358 REFIID riid,
2359 LCID lcid,
2360 WORD wFlags,
2361 DISPPARAMS*pDispParams,
2362 VARIANT*pVarResult,
2363 EXCEPINFO*pExepInfo,
2364 UINT*puArgErr) {
2365 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2366 IBasicVideo* pBasicVideo;
2367 HRESULT hr;
2369 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);
2371 EnterCriticalSection(&This->cs);
2373 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2375 if (hr == S_OK)
2376 hr = IBasicVideo_Invoke(pBasicVideo, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
2378 LeaveCriticalSection(&This->cs);
2380 return hr;
2383 /*** IBasicVideo methods ***/
2384 static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo *iface,
2385 REFTIME *pAvgTimePerFrame) {
2386 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2387 IBasicVideo* pBasicVideo;
2388 HRESULT hr;
2390 TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);
2392 EnterCriticalSection(&This->cs);
2394 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2396 if (hr == S_OK)
2397 hr = IBasicVideo_get_AvgTimePerFrame(pBasicVideo, pAvgTimePerFrame);
2399 LeaveCriticalSection(&This->cs);
2401 return hr;
2404 static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo *iface,
2405 long *pBitRate) {
2406 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2407 IBasicVideo* pBasicVideo;
2408 HRESULT hr;
2410 TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);
2412 EnterCriticalSection(&This->cs);
2414 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2416 if (hr == S_OK)
2417 hr = IBasicVideo_get_BitRate(pBasicVideo, pBitRate);
2419 LeaveCriticalSection(&This->cs);
2421 return hr;
2424 static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo *iface,
2425 long *pBitErrorRate) {
2426 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2427 IBasicVideo* pBasicVideo;
2428 HRESULT hr;
2430 TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);
2432 EnterCriticalSection(&This->cs);
2434 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2436 if (hr == S_OK)
2437 hr = IBasicVideo_get_BitErrorRate(pBasicVideo, pBitErrorRate);
2439 LeaveCriticalSection(&This->cs);
2441 return hr;
2444 static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo *iface,
2445 long *pVideoWidth) {
2446 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2447 IBasicVideo* pBasicVideo;
2448 HRESULT hr;
2450 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
2452 EnterCriticalSection(&This->cs);
2454 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2456 if (hr == S_OK)
2457 hr = IBasicVideo_get_VideoWidth(pBasicVideo, pVideoWidth);
2459 LeaveCriticalSection(&This->cs);
2461 return hr;
2464 static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo *iface,
2465 long *pVideoHeight) {
2466 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2467 IBasicVideo* pBasicVideo;
2468 HRESULT hr;
2470 TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
2472 EnterCriticalSection(&This->cs);
2474 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2476 if (hr == S_OK)
2477 hr = IBasicVideo_get_VideoHeight(pBasicVideo, pVideoHeight);
2479 LeaveCriticalSection(&This->cs);
2481 return hr;
2484 static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo *iface,
2485 long SourceLeft) {
2486 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2487 IBasicVideo* pBasicVideo;
2488 HRESULT hr;
2490 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft);
2492 EnterCriticalSection(&This->cs);
2494 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2496 if (hr == S_OK)
2497 hr = IBasicVideo_put_SourceLeft(pBasicVideo, SourceLeft);
2499 LeaveCriticalSection(&This->cs);
2501 return hr;
2504 static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo *iface,
2505 long *pSourceLeft) {
2506 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2507 IBasicVideo* pBasicVideo;
2508 HRESULT hr;
2510 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
2512 EnterCriticalSection(&This->cs);
2514 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2516 if (hr == S_OK)
2517 hr = IBasicVideo_get_SourceLeft(pBasicVideo, pSourceLeft);
2519 LeaveCriticalSection(&This->cs);
2521 return hr;
2524 static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo *iface,
2525 long SourceWidth) {
2526 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2527 IBasicVideo* pBasicVideo;
2528 HRESULT hr;
2530 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth);
2532 EnterCriticalSection(&This->cs);
2534 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2536 if (hr == S_OK)
2537 hr = IBasicVideo_put_SourceWidth(pBasicVideo, SourceWidth);
2539 LeaveCriticalSection(&This->cs);
2541 return hr;
2544 static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo *iface,
2545 long *pSourceWidth) {
2546 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2547 IBasicVideo* pBasicVideo;
2548 HRESULT hr;
2550 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
2552 EnterCriticalSection(&This->cs);
2554 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2556 if (hr == S_OK)
2557 hr = IBasicVideo_get_SourceWidth(pBasicVideo, pSourceWidth);
2559 LeaveCriticalSection(&This->cs);
2561 return hr;
2564 static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo *iface,
2565 long SourceTop) {
2566 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2567 IBasicVideo* pBasicVideo;
2568 HRESULT hr;
2570 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop);
2572 EnterCriticalSection(&This->cs);
2574 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2576 if (hr == S_OK)
2577 hr = IBasicVideo_put_SourceTop(pBasicVideo, SourceTop);
2579 LeaveCriticalSection(&This->cs);
2581 return hr;
2584 static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo *iface,
2585 long *pSourceTop) {
2586 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2587 IBasicVideo* pBasicVideo;
2588 HRESULT hr;
2590 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
2592 EnterCriticalSection(&This->cs);
2594 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2596 if (hr == S_OK)
2597 hr = IBasicVideo_get_SourceTop(pBasicVideo, pSourceTop);
2599 LeaveCriticalSection(&This->cs);
2601 return hr;
2604 static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo *iface,
2605 long SourceHeight) {
2606 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2607 IBasicVideo* pBasicVideo;
2608 HRESULT hr;
2610 TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight);
2612 EnterCriticalSection(&This->cs);
2614 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2616 if (hr == S_OK)
2617 hr = IBasicVideo_put_SourceHeight(pBasicVideo, SourceHeight);
2619 LeaveCriticalSection(&This->cs);
2621 return hr;
2624 static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo *iface,
2625 long *pSourceHeight) {
2626 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2627 IBasicVideo* pBasicVideo;
2628 HRESULT hr;
2630 TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
2632 EnterCriticalSection(&This->cs);
2634 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2636 if (hr == S_OK)
2637 hr = IBasicVideo_get_SourceHeight(pBasicVideo, pSourceHeight);
2639 LeaveCriticalSection(&This->cs);
2641 return hr;
2644 static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo *iface,
2645 long DestinationLeft) {
2646 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2647 IBasicVideo* pBasicVideo;
2648 HRESULT hr;
2650 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft);
2652 EnterCriticalSection(&This->cs);
2654 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2656 if (hr == S_OK)
2657 hr = IBasicVideo_put_DestinationLeft(pBasicVideo, DestinationLeft);
2659 LeaveCriticalSection(&This->cs);
2661 return hr;
2664 static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo *iface,
2665 long *pDestinationLeft) {
2666 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2667 IBasicVideo* pBasicVideo;
2668 HRESULT hr;
2670 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
2672 EnterCriticalSection(&This->cs);
2674 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2676 if (hr == S_OK)
2677 hr = IBasicVideo_get_DestinationLeft(pBasicVideo, pDestinationLeft);
2679 LeaveCriticalSection(&This->cs);
2681 return hr;
2684 static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo *iface,
2685 long DestinationWidth) {
2686 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2687 IBasicVideo* pBasicVideo;
2688 HRESULT hr;
2690 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth);
2692 EnterCriticalSection(&This->cs);
2694 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2696 if (hr == S_OK)
2697 hr = IBasicVideo_put_DestinationWidth(pBasicVideo, DestinationWidth);
2699 LeaveCriticalSection(&This->cs);
2701 return hr;
2704 static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo *iface,
2705 long *pDestinationWidth) {
2706 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2707 IBasicVideo* pBasicVideo;
2708 HRESULT hr;
2710 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
2712 EnterCriticalSection(&This->cs);
2714 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2716 if (hr == S_OK)
2717 hr = IBasicVideo_get_DestinationWidth(pBasicVideo, pDestinationWidth);
2719 LeaveCriticalSection(&This->cs);
2721 return hr;
2724 static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo *iface,
2725 long DestinationTop) {
2726 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2727 IBasicVideo* pBasicVideo;
2728 HRESULT hr;
2730 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop);
2732 EnterCriticalSection(&This->cs);
2734 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2736 if (hr == S_OK)
2737 hr = IBasicVideo_put_DestinationTop(pBasicVideo, DestinationTop);
2739 LeaveCriticalSection(&This->cs);
2741 return hr;
2744 static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo *iface,
2745 long *pDestinationTop) {
2746 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2747 IBasicVideo* pBasicVideo;
2748 HRESULT hr;
2750 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
2752 EnterCriticalSection(&This->cs);
2754 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2756 if (hr == S_OK)
2757 hr = IBasicVideo_get_DestinationTop(pBasicVideo, pDestinationTop);
2759 LeaveCriticalSection(&This->cs);
2761 return hr;
2764 static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo *iface,
2765 long DestinationHeight) {
2766 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2767 IBasicVideo* pBasicVideo;
2768 HRESULT hr;
2770 TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight);
2772 EnterCriticalSection(&This->cs);
2774 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2776 if (hr == S_OK)
2777 hr = IBasicVideo_put_DestinationHeight(pBasicVideo, DestinationHeight);
2779 LeaveCriticalSection(&This->cs);
2781 return hr;
2784 static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo *iface,
2785 long *pDestinationHeight) {
2786 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2787 IBasicVideo* pBasicVideo;
2788 HRESULT hr;
2790 TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
2792 EnterCriticalSection(&This->cs);
2794 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2796 if (hr == S_OK)
2797 hr = IBasicVideo_get_DestinationHeight(pBasicVideo, pDestinationHeight);
2799 LeaveCriticalSection(&This->cs);
2801 return hr;
2804 static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo *iface,
2805 long Left,
2806 long Top,
2807 long Width,
2808 long Height) {
2809 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2810 IBasicVideo* pBasicVideo;
2811 HRESULT hr;
2813 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
2815 EnterCriticalSection(&This->cs);
2817 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2819 if (hr == S_OK)
2820 hr = IBasicVideo_SetSourcePosition(pBasicVideo, Left, Top, Width, Height);
2822 LeaveCriticalSection(&This->cs);
2824 return hr;
2827 static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo *iface,
2828 long *pLeft,
2829 long *pTop,
2830 long *pWidth,
2831 long *pHeight) {
2832 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2833 IBasicVideo* pBasicVideo;
2834 HRESULT hr;
2836 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
2838 EnterCriticalSection(&This->cs);
2840 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2842 if (hr == S_OK)
2843 hr = IBasicVideo_GetSourcePosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
2845 LeaveCriticalSection(&This->cs);
2847 return hr;
2850 static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo *iface) {
2851 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2852 IBasicVideo* pBasicVideo;
2853 HRESULT hr;
2855 TRACE("(%p/%p)->()\n", This, iface);
2857 EnterCriticalSection(&This->cs);
2859 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2861 if (hr == S_OK)
2862 hr = IBasicVideo_SetDefaultSourcePosition(pBasicVideo);
2864 LeaveCriticalSection(&This->cs);
2866 return hr;
2869 static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo *iface,
2870 long Left,
2871 long Top,
2872 long Width,
2873 long Height) {
2874 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2875 IBasicVideo* pBasicVideo;
2876 HRESULT hr;
2878 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
2880 EnterCriticalSection(&This->cs);
2882 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2884 if (hr == S_OK)
2885 hr = IBasicVideo_SetDestinationPosition(pBasicVideo, Left, Top, Width, Height);
2887 LeaveCriticalSection(&This->cs);
2889 return hr;
2892 static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo *iface,
2893 long *pLeft,
2894 long *pTop,
2895 long *pWidth,
2896 long *pHeight) {
2897 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2898 IBasicVideo* pBasicVideo;
2899 HRESULT hr;
2901 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
2903 EnterCriticalSection(&This->cs);
2905 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2907 if (hr == S_OK)
2908 hr = IBasicVideo_GetDestinationPosition(pBasicVideo, pLeft, pTop, pWidth, pHeight);
2910 LeaveCriticalSection(&This->cs);
2912 return hr;
2915 static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
2916 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2917 IBasicVideo* pBasicVideo;
2918 HRESULT hr;
2920 TRACE("(%p/%p)->()\n", This, iface);
2922 EnterCriticalSection(&This->cs);
2924 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2926 if (hr == S_OK)
2927 hr = IBasicVideo_SetDefaultDestinationPosition(pBasicVideo);
2929 LeaveCriticalSection(&This->cs);
2931 return hr;
2934 static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo *iface,
2935 long *pWidth,
2936 long *pHeight) {
2937 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2938 IBasicVideo* pBasicVideo;
2939 HRESULT hr;
2941 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
2943 EnterCriticalSection(&This->cs);
2945 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2947 if (hr == S_OK)
2948 hr = IBasicVideo_GetVideoSize(pBasicVideo, pWidth, pHeight);
2950 LeaveCriticalSection(&This->cs);
2952 return hr;
2955 static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo *iface,
2956 long StartIndex,
2957 long Entries,
2958 long *pRetrieved,
2959 long *pPalette) {
2960 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2961 IBasicVideo* pBasicVideo;
2962 HRESULT hr;
2964 TRACE("(%p/%p)->(%ld, %ld, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
2966 EnterCriticalSection(&This->cs);
2968 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2970 if (hr == S_OK)
2971 hr = IBasicVideo_GetVideoPaletteEntries(pBasicVideo, StartIndex, Entries, pRetrieved, pPalette);
2973 LeaveCriticalSection(&This->cs);
2975 return hr;
2978 static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo *iface,
2979 long *pBufferSize,
2980 long *pDIBImage) {
2981 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
2982 IBasicVideo* pBasicVideo;
2983 HRESULT hr;
2985 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage);
2987 EnterCriticalSection(&This->cs);
2989 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
2991 if (hr == S_OK)
2992 hr = IBasicVideo_GetCurrentImage(pBasicVideo, pBufferSize, pDIBImage);
2994 LeaveCriticalSection(&This->cs);
2996 return hr;
2999 static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo *iface) {
3000 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3001 IBasicVideo* pBasicVideo;
3002 HRESULT hr;
3004 TRACE("(%p/%p)->()\n", This, iface);
3006 EnterCriticalSection(&This->cs);
3008 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3010 if (hr == S_OK)
3011 hr = IBasicVideo_IsUsingDefaultSource(pBasicVideo);
3013 LeaveCriticalSection(&This->cs);
3015 return hr;
3018 static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo *iface) {
3019 ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface);
3020 IBasicVideo* pBasicVideo;
3021 HRESULT hr;
3023 TRACE("(%p/%p)->()\n", This, iface);
3025 EnterCriticalSection(&This->cs);
3027 hr = GetTargetInterface(This, &IID_IBasicVideo, (LPVOID*)&pBasicVideo);
3029 if (hr == S_OK)
3030 hr = IBasicVideo_IsUsingDefaultDestination(pBasicVideo);
3032 LeaveCriticalSection(&This->cs);
3034 return hr;
3038 static const IBasicVideoVtbl IBasicVideo_VTable =
3040 BasicVideo_QueryInterface,
3041 BasicVideo_AddRef,
3042 BasicVideo_Release,
3043 BasicVideo_GetTypeInfoCount,
3044 BasicVideo_GetTypeInfo,
3045 BasicVideo_GetIDsOfNames,
3046 BasicVideo_Invoke,
3047 BasicVideo_get_AvgTimePerFrame,
3048 BasicVideo_get_BitRate,
3049 BasicVideo_get_BitErrorRate,
3050 BasicVideo_get_VideoWidth,
3051 BasicVideo_get_VideoHeight,
3052 BasicVideo_put_SourceLeft,
3053 BasicVideo_get_SourceLeft,
3054 BasicVideo_put_SourceWidth,
3055 BasicVideo_get_SourceWidth,
3056 BasicVideo_put_SourceTop,
3057 BasicVideo_get_SourceTop,
3058 BasicVideo_put_SourceHeight,
3059 BasicVideo_get_SourceHeight,
3060 BasicVideo_put_DestinationLeft,
3061 BasicVideo_get_DestinationLeft,
3062 BasicVideo_put_DestinationWidth,
3063 BasicVideo_get_DestinationWidth,
3064 BasicVideo_put_DestinationTop,
3065 BasicVideo_get_DestinationTop,
3066 BasicVideo_put_DestinationHeight,
3067 BasicVideo_get_DestinationHeight,
3068 BasicVideo_SetSourcePosition,
3069 BasicVideo_GetSourcePosition,
3070 BasicVideo_SetDefaultSourcePosition,
3071 BasicVideo_SetDestinationPosition,
3072 BasicVideo_GetDestinationPosition,
3073 BasicVideo_SetDefaultDestinationPosition,
3074 BasicVideo_GetVideoSize,
3075 BasicVideo_GetVideoPaletteEntries,
3076 BasicVideo_GetCurrentImage,
3077 BasicVideo_IsUsingDefaultSource,
3078 BasicVideo_IsUsingDefaultDestination
3082 /*** IUnknown methods ***/
3083 static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface,
3084 REFIID riid,
3085 LPVOID*ppvObj) {
3086 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3088 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
3090 return Filtergraph_QueryInterface(This, riid, ppvObj);
3093 static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) {
3094 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3096 TRACE("(%p/%p)->()\n", This, iface);
3098 return Filtergraph_AddRef(This);
3101 static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) {
3102 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3104 TRACE("(%p/%p)->()\n", This, iface);
3106 return Filtergraph_Release(This);
3109 /*** IDispatch methods ***/
3110 static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface,
3111 UINT*pctinfo) {
3112 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3113 IVideoWindow* pVideoWindow;
3114 HRESULT hr;
3116 TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo);
3118 EnterCriticalSection(&This->cs);
3120 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3122 if (hr == S_OK)
3123 hr = IVideoWindow_GetTypeInfoCount(pVideoWindow, pctinfo);
3125 LeaveCriticalSection(&This->cs);
3127 return hr;
3130 static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface,
3131 UINT iTInfo,
3132 LCID lcid,
3133 ITypeInfo**ppTInfo) {
3134 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3135 IVideoWindow* pVideoWindow;
3136 HRESULT hr;
3138 TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo);
3140 EnterCriticalSection(&This->cs);
3142 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3144 if (hr == S_OK)
3145 hr = IVideoWindow_GetTypeInfo(pVideoWindow, iTInfo, lcid, ppTInfo);
3147 LeaveCriticalSection(&This->cs);
3149 return hr;
3152 static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface,
3153 REFIID riid,
3154 LPOLESTR*rgszNames,
3155 UINT cNames,
3156 LCID lcid,
3157 DISPID*rgDispId) {
3158 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3159 IVideoWindow* pVideoWindow;
3160 HRESULT hr;
3162 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
3164 EnterCriticalSection(&This->cs);
3166 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3168 if (hr == S_OK)
3169 hr = IVideoWindow_GetIDsOfNames(pVideoWindow, riid, rgszNames, cNames, lcid, rgDispId);
3171 LeaveCriticalSection(&This->cs);
3173 return hr;
3176 static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface,
3177 DISPID dispIdMember,
3178 REFIID riid,
3179 LCID lcid,
3180 WORD wFlags,
3181 DISPPARAMS*pDispParams,
3182 VARIANT*pVarResult,
3183 EXCEPINFO*pExepInfo,
3184 UINT*puArgErr) {
3185 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3186 IVideoWindow* pVideoWindow;
3187 HRESULT hr;
3189 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);
3191 EnterCriticalSection(&This->cs);
3193 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3195 if (hr == S_OK)
3196 hr = IVideoWindow_Invoke(pVideoWindow, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
3198 LeaveCriticalSection(&This->cs);
3200 return hr;
3204 /*** IVideoWindow methods ***/
3205 static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface,
3206 BSTR strCaption) {
3207 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3208 IVideoWindow* pVideoWindow;
3209 HRESULT hr;
3211 TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
3213 EnterCriticalSection(&This->cs);
3215 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3217 if (hr == S_OK)
3218 hr = IVideoWindow_put_Caption(pVideoWindow, strCaption);
3220 LeaveCriticalSection(&This->cs);
3222 return hr;
3225 static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface,
3226 BSTR *strCaption) {
3227 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3228 IVideoWindow* pVideoWindow;
3229 HRESULT hr;
3231 TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
3233 EnterCriticalSection(&This->cs);
3235 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3237 if (hr == S_OK)
3238 hr = IVideoWindow_get_Caption(pVideoWindow, strCaption);
3240 LeaveCriticalSection(&This->cs);
3242 return hr;
3245 static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface,
3246 long WindowStyle) {
3247 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3248 IVideoWindow* pVideoWindow;
3249 HRESULT hr;
3251 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyle);
3253 EnterCriticalSection(&This->cs);
3255 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3257 if (hr == S_OK)
3258 hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle);
3260 LeaveCriticalSection(&This->cs);
3262 return hr;
3265 static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface,
3266 long *WindowStyle) {
3267 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3268 IVideoWindow* pVideoWindow;
3269 HRESULT hr;
3271 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
3273 EnterCriticalSection(&This->cs);
3275 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3277 if (hr == S_OK)
3278 hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle);
3280 LeaveCriticalSection(&This->cs);
3282 return hr;
3285 static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface,
3286 long WindowStyleEx) {
3287 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3288 IVideoWindow* pVideoWindow;
3289 HRESULT hr;
3291 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx);
3293 EnterCriticalSection(&This->cs);
3295 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3297 if (hr == S_OK)
3298 hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx);
3300 LeaveCriticalSection(&This->cs);
3302 return hr;
3305 static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface,
3306 long *WindowStyleEx) {
3307 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3308 IVideoWindow* pVideoWindow;
3309 HRESULT hr;
3311 TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
3313 EnterCriticalSection(&This->cs);
3315 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3317 if (hr == S_OK)
3318 hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx);
3320 LeaveCriticalSection(&This->cs);
3322 return hr;
3325 static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface,
3326 long AutoShow) {
3327 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3328 IVideoWindow* pVideoWindow;
3329 HRESULT hr;
3331 TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow);
3333 EnterCriticalSection(&This->cs);
3335 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3337 if (hr == S_OK)
3338 hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow);
3340 LeaveCriticalSection(&This->cs);
3342 return hr;
3345 static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface,
3346 long *AutoShow) {
3347 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3348 IVideoWindow* pVideoWindow;
3349 HRESULT hr;
3351 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
3353 EnterCriticalSection(&This->cs);
3355 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3357 if (hr == S_OK)
3358 hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow);
3360 LeaveCriticalSection(&This->cs);
3362 return hr;
3365 static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface,
3366 long WindowState) {
3367 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3368 IVideoWindow* pVideoWindow;
3369 HRESULT hr;
3371 TRACE("(%p/%p)->(%ld)\n", This, iface, WindowState);
3373 EnterCriticalSection(&This->cs);
3375 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3377 if (hr == S_OK)
3378 hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState);
3380 LeaveCriticalSection(&This->cs);
3382 return hr;
3385 static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface,
3386 long *WindowState) {
3387 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3388 IVideoWindow* pVideoWindow;
3389 HRESULT hr;
3391 TRACE("(%p/%p)->(%p)\n", This, iface, WindowState);
3393 EnterCriticalSection(&This->cs);
3395 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3397 if (hr == S_OK)
3398 hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState);
3400 LeaveCriticalSection(&This->cs);
3402 return hr;
3405 static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface,
3406 long BackgroundPalette) {
3407 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3408 IVideoWindow* pVideoWindow;
3409 HRESULT hr;
3411 TRACE("(%p/%p)->(%ld)\n", This, iface, BackgroundPalette);
3413 EnterCriticalSection(&This->cs);
3415 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3417 if (hr == S_OK)
3418 hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette);
3420 LeaveCriticalSection(&This->cs);
3422 return hr;
3425 static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface,
3426 long *pBackgroundPalette) {
3427 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3428 IVideoWindow* pVideoWindow;
3429 HRESULT hr;
3431 TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette);
3433 EnterCriticalSection(&This->cs);
3435 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3437 if (hr == S_OK)
3438 hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette);
3440 LeaveCriticalSection(&This->cs);
3442 return hr;
3445 static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface,
3446 long Visible) {
3447 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3448 IVideoWindow* pVideoWindow;
3449 HRESULT hr;
3451 TRACE("(%p/%p)->(%ld)\n", This, iface, Visible);
3453 EnterCriticalSection(&This->cs);
3455 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3457 if (hr == S_OK)
3458 hr = IVideoWindow_put_Visible(pVideoWindow, Visible);
3460 LeaveCriticalSection(&This->cs);
3462 return hr;
3465 static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface,
3466 long *pVisible) {
3467 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3468 IVideoWindow* pVideoWindow;
3469 HRESULT hr;
3471 TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
3473 EnterCriticalSection(&This->cs);
3475 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3477 if (hr == S_OK)
3478 hr = IVideoWindow_get_Visible(pVideoWindow, pVisible);
3480 LeaveCriticalSection(&This->cs);
3482 return hr;
3485 static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface,
3486 long Left) {
3487 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3488 IVideoWindow* pVideoWindow;
3489 HRESULT hr;
3491 TRACE("(%p/%p)->(%ld)\n", This, iface, Left);
3493 EnterCriticalSection(&This->cs);
3495 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3497 if (hr == S_OK)
3498 hr = IVideoWindow_put_Left(pVideoWindow, Left);
3500 LeaveCriticalSection(&This->cs);
3502 return hr;
3505 static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface,
3506 long *pLeft) {
3507 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3508 IVideoWindow* pVideoWindow;
3509 HRESULT hr;
3511 TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
3513 EnterCriticalSection(&This->cs);
3515 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3517 if (hr == S_OK)
3518 hr = IVideoWindow_get_Left(pVideoWindow, pLeft);
3520 LeaveCriticalSection(&This->cs);
3522 return hr;
3525 static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface,
3526 long Width) {
3527 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3528 IVideoWindow* pVideoWindow;
3529 HRESULT hr;
3531 TRACE("(%p/%p)->(%ld)\n", This, iface, Width);
3533 EnterCriticalSection(&This->cs);
3535 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3537 if (hr == S_OK)
3538 hr = IVideoWindow_put_Width(pVideoWindow, Width);
3540 LeaveCriticalSection(&This->cs);
3542 return hr;
3545 static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface,
3546 long *pWidth) {
3547 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3548 IVideoWindow* pVideoWindow;
3549 HRESULT hr;
3551 TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
3553 EnterCriticalSection(&This->cs);
3555 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3557 if (hr == S_OK)
3558 hr = IVideoWindow_get_Width(pVideoWindow, pWidth);
3560 LeaveCriticalSection(&This->cs);
3562 return hr;
3565 static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface,
3566 long Top) {
3567 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3568 IVideoWindow* pVideoWindow;
3569 HRESULT hr;
3571 TRACE("(%p/%p)->(%ld)\n", This, iface, Top);
3573 EnterCriticalSection(&This->cs);
3575 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3577 if (hr == S_OK)
3578 hr = IVideoWindow_put_Top(pVideoWindow, Top);
3580 LeaveCriticalSection(&This->cs);
3582 return hr;
3585 static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface,
3586 long *pTop) {
3587 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3588 IVideoWindow* pVideoWindow;
3589 HRESULT hr;
3591 TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
3593 EnterCriticalSection(&This->cs);
3595 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3597 if (hr == S_OK)
3598 hr = IVideoWindow_get_Top(pVideoWindow, pTop);
3600 LeaveCriticalSection(&This->cs);
3602 return hr;
3605 static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface,
3606 long Height) {
3607 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3608 IVideoWindow* pVideoWindow;
3609 HRESULT hr;
3611 TRACE("(%p/%p)->(%ld)\n", This, iface, Height);
3613 EnterCriticalSection(&This->cs);
3615 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3617 if (hr == S_OK)
3618 hr = IVideoWindow_put_Height(pVideoWindow, Height);
3620 LeaveCriticalSection(&This->cs);
3622 return hr;
3625 static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface,
3626 long *pHeight) {
3627 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3628 IVideoWindow* pVideoWindow;
3629 HRESULT hr;
3631 TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
3633 EnterCriticalSection(&This->cs);
3635 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3637 if (hr == S_OK)
3638 hr = IVideoWindow_get_Height(pVideoWindow, pHeight);
3640 LeaveCriticalSection(&This->cs);
3642 return hr;
3645 static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface,
3646 OAHWND Owner) {
3647 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3648 IVideoWindow* pVideoWindow;
3649 HRESULT hr;
3651 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner);
3653 EnterCriticalSection(&This->cs);
3655 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3657 if (hr == S_OK)
3658 hr = IVideoWindow_put_Owner(pVideoWindow, Owner);
3660 LeaveCriticalSection(&This->cs);
3662 return hr;
3665 static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface,
3666 OAHWND *Owner) {
3667 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3668 IVideoWindow* pVideoWindow;
3669 HRESULT hr;
3671 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
3673 EnterCriticalSection(&This->cs);
3675 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3677 if (hr == S_OK)
3678 hr = IVideoWindow_get_Owner(pVideoWindow, Owner);
3680 LeaveCriticalSection(&This->cs);
3682 return hr;
3685 static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface,
3686 OAHWND Drain) {
3687 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3688 IVideoWindow* pVideoWindow;
3689 HRESULT hr;
3691 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
3693 EnterCriticalSection(&This->cs);
3695 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3697 if (hr == S_OK)
3698 hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain);
3700 LeaveCriticalSection(&This->cs);
3702 return hr;
3705 static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface,
3706 OAHWND *Drain) {
3707 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3708 IVideoWindow* pVideoWindow;
3709 HRESULT hr;
3711 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
3713 EnterCriticalSection(&This->cs);
3715 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3717 if (hr == S_OK)
3718 hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain);
3720 LeaveCriticalSection(&This->cs);
3722 return hr;
3725 static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface,
3726 long *Color) {
3727 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3728 IVideoWindow* pVideoWindow;
3729 HRESULT hr;
3731 TRACE("(%p/%p)->(%p)\n", This, iface, Color);
3733 EnterCriticalSection(&This->cs);
3735 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3737 if (hr == S_OK)
3738 hr = IVideoWindow_get_BorderColor(pVideoWindow, Color);
3740 LeaveCriticalSection(&This->cs);
3742 return hr;
3745 static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface,
3746 long Color) {
3747 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3748 IVideoWindow* pVideoWindow;
3749 HRESULT hr;
3751 TRACE("(%p/%p)->(%ld)\n", This, iface, Color);
3753 EnterCriticalSection(&This->cs);
3755 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3757 if (hr == S_OK)
3758 hr = IVideoWindow_put_BorderColor(pVideoWindow, Color);
3760 LeaveCriticalSection(&This->cs);
3762 return hr;
3765 static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface,
3766 long *FullScreenMode) {
3767 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3768 IVideoWindow* pVideoWindow;
3769 HRESULT hr;
3771 TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode);
3773 EnterCriticalSection(&This->cs);
3775 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3777 if (hr == S_OK)
3778 hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode);
3780 LeaveCriticalSection(&This->cs);
3782 return hr;
3785 static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface,
3786 long FullScreenMode) {
3787 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3788 IVideoWindow* pVideoWindow;
3789 HRESULT hr;
3791 TRACE("(%p/%p)->(%ld)\n", This, iface, FullScreenMode);
3793 EnterCriticalSection(&This->cs);
3795 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3797 if (hr == S_OK)
3798 hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode);
3800 LeaveCriticalSection(&This->cs);
3802 return hr;
3805 static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface,
3806 long Focus) {
3807 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3808 IVideoWindow* pVideoWindow;
3809 HRESULT hr;
3811 TRACE("(%p/%p)->(%ld)\n", This, iface, Focus);
3813 EnterCriticalSection(&This->cs);
3815 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3817 if (hr == S_OK)
3818 hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus);
3820 LeaveCriticalSection(&This->cs);
3822 return hr;
3825 static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface,
3826 OAHWND hwnd,
3827 long uMsg,
3828 LONG_PTR wParam,
3829 LONG_PTR lParam) {
3830 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3831 IVideoWindow* pVideoWindow;
3832 HRESULT hr;
3834 TRACE("(%p/%p)->(%08x, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
3836 EnterCriticalSection(&This->cs);
3838 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3840 if (hr == S_OK)
3841 hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam);
3843 LeaveCriticalSection(&This->cs);
3845 return hr;
3848 static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface,
3849 long Left,
3850 long Top,
3851 long Width,
3852 long Height) {
3853 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3854 IVideoWindow* pVideoWindow;
3855 HRESULT hr;
3857 TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
3859 EnterCriticalSection(&This->cs);
3861 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3863 if (hr == S_OK)
3864 hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height);
3866 LeaveCriticalSection(&This->cs);
3868 return hr;
3871 static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface,
3872 long *pLeft,
3873 long *pTop,
3874 long *pWidth,
3875 long *pHeight) {
3876 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3877 IVideoWindow* pVideoWindow;
3878 HRESULT hr;
3880 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3882 EnterCriticalSection(&This->cs);
3884 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3886 if (hr == S_OK)
3887 hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
3889 LeaveCriticalSection(&This->cs);
3891 return hr;
3894 static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface,
3895 long *pWidth,
3896 long *pHeight) {
3897 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3898 IVideoWindow* pVideoWindow;
3899 HRESULT hr;
3901 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3903 EnterCriticalSection(&This->cs);
3905 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3907 if (hr == S_OK)
3908 hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight);
3910 LeaveCriticalSection(&This->cs);
3912 return hr;
3915 static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface,
3916 long *pWidth,
3917 long *pHeight) {
3918 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3919 IVideoWindow* pVideoWindow;
3920 HRESULT hr;
3922 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
3924 EnterCriticalSection(&This->cs);
3926 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3928 if (hr == S_OK)
3929 hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight);
3931 LeaveCriticalSection(&This->cs);
3933 return hr;
3936 static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface,
3937 long *pLeft,
3938 long *pTop,
3939 long *pWidth,
3940 long *pHeight) {
3941 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3942 IVideoWindow* pVideoWindow;
3943 HRESULT hr;
3945 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
3947 EnterCriticalSection(&This->cs);
3949 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3951 if (hr == S_OK)
3952 hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight);
3954 LeaveCriticalSection(&This->cs);
3956 return hr;
3959 static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface,
3960 long HideCursor) {
3961 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3962 IVideoWindow* pVideoWindow;
3963 HRESULT hr;
3965 TRACE("(%p/%p)->(%ld)\n", This, iface, HideCursor);
3967 EnterCriticalSection(&This->cs);
3969 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3971 if (hr == S_OK)
3972 hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor);
3974 LeaveCriticalSection(&This->cs);
3976 return hr;
3979 static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface,
3980 long *CursorHidden) {
3981 ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface);
3982 IVideoWindow* pVideoWindow;
3983 HRESULT hr;
3985 TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden);
3987 EnterCriticalSection(&This->cs);
3989 hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
3991 if (hr == S_OK)
3992 hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden);
3994 LeaveCriticalSection(&This->cs);
3996 return hr;
4000 static const IVideoWindowVtbl IVideoWindow_VTable =
4002 VideoWindow_QueryInterface,
4003 VideoWindow_AddRef,
4004 VideoWindow_Release,
4005 VideoWindow_GetTypeInfoCount,
4006 VideoWindow_GetTypeInfo,
4007 VideoWindow_GetIDsOfNames,
4008 VideoWindow_Invoke,
4009 VideoWindow_put_Caption,
4010 VideoWindow_get_Caption,
4011 VideoWindow_put_WindowStyle,
4012 VideoWindow_get_WindowStyle,
4013 VideoWindow_put_WindowStyleEx,
4014 VideoWindow_get_WindowStyleEx,
4015 VideoWindow_put_AutoShow,
4016 VideoWindow_get_AutoShow,
4017 VideoWindow_put_WindowState,
4018 VideoWindow_get_WindowState,
4019 VideoWindow_put_BackgroundPalette,
4020 VideoWindow_get_BackgroundPalette,
4021 VideoWindow_put_Visible,
4022 VideoWindow_get_Visible,
4023 VideoWindow_put_Left,
4024 VideoWindow_get_Left,
4025 VideoWindow_put_Width,
4026 VideoWindow_get_Width,
4027 VideoWindow_put_Top,
4028 VideoWindow_get_Top,
4029 VideoWindow_put_Height,
4030 VideoWindow_get_Height,
4031 VideoWindow_put_Owner,
4032 VideoWindow_get_Owner,
4033 VideoWindow_put_MessageDrain,
4034 VideoWindow_get_MessageDrain,
4035 VideoWindow_get_BorderColor,
4036 VideoWindow_put_BorderColor,
4037 VideoWindow_get_FullScreenMode,
4038 VideoWindow_put_FullScreenMode,
4039 VideoWindow_SetWindowForeground,
4040 VideoWindow_NotifyOwnerMessage,
4041 VideoWindow_SetWindowPosition,
4042 VideoWindow_GetWindowPosition,
4043 VideoWindow_GetMinIdealImageSize,
4044 VideoWindow_GetMaxIdealImageSize,
4045 VideoWindow_GetRestorePosition,
4046 VideoWindow_HideCursor,
4047 VideoWindow_IsCursorHidden
4051 /*** IUnknown methods ***/
4052 static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface,
4053 REFIID riid,
4054 LPVOID*ppvObj) {
4055 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4057 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
4059 return Filtergraph_QueryInterface(This, riid, ppvObj);
4062 static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) {
4063 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4065 TRACE("(%p/%p)->()\n", This, iface);
4067 return Filtergraph_AddRef(This);
4070 static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) {
4071 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4073 TRACE("(%p/%p)->()\n", This, iface);
4075 return Filtergraph_Release(This);
4078 /*** IDispatch methods ***/
4079 static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface,
4080 UINT*pctinfo) {
4081 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4083 TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
4085 return S_OK;
4088 static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface,
4089 UINT iTInfo,
4090 LCID lcid,
4091 ITypeInfo**ppTInfo) {
4092 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4094 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
4096 return S_OK;
4099 static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface,
4100 REFIID riid,
4101 LPOLESTR*rgszNames,
4102 UINT cNames,
4103 LCID lcid,
4104 DISPID*rgDispId) {
4105 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4107 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
4109 return S_OK;
4112 static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface,
4113 DISPID dispIdMember,
4114 REFIID riid,
4115 LCID lcid,
4116 WORD wFlags,
4117 DISPPARAMS*pDispParams,
4118 VARIANT*pVarResult,
4119 EXCEPINFO*pExepInfo,
4120 UINT*puArgErr) {
4121 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4123 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);
4125 return S_OK;
4128 /*** IMediaEvent methods ***/
4129 static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface,
4130 OAEVENT *hEvent) {
4131 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4133 TRACE("(%p/%p)->(%p)\n", This, iface, hEvent);
4135 *hEvent = (OAEVENT)This->evqueue.msg_event;
4137 return S_OK;
4140 static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface,
4141 long *lEventCode,
4142 LONG_PTR *lParam1,
4143 LONG_PTR *lParam2,
4144 long msTimeout) {
4145 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4146 Event evt;
4148 TRACE("(%p/%p)->(%p, %p, %p, %ld)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout);
4150 if (EventsQueue_GetEvent(&This->evqueue, &evt, msTimeout))
4152 *lEventCode = evt.lEventCode;
4153 *lParam1 = evt.lParam1;
4154 *lParam2 = evt.lParam2;
4155 return S_OK;
4158 *lEventCode = 0;
4159 return E_ABORT;
4162 static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface,
4163 long msTimeout,
4164 long *pEvCode) {
4165 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4167 TRACE("(%p/%p)->(%ld, %p)\n", This, iface, msTimeout, pEvCode);
4169 if (WaitForSingleObject(This->hEventCompletion, msTimeout) == WAIT_OBJECT_0)
4171 *pEvCode = This->CompletionStatus;
4172 return S_OK;
4175 *pEvCode = 0;
4176 return E_ABORT;
4179 static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface,
4180 long lEvCode) {
4181 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4183 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4185 if (lEvCode == EC_COMPLETE)
4186 This->HandleEcComplete = FALSE;
4187 else if (lEvCode == EC_REPAINT)
4188 This->HandleEcRepaint = FALSE;
4189 else if (lEvCode == EC_CLOCK_CHANGED)
4190 This->HandleEcClockChanged = FALSE;
4191 else
4192 return S_FALSE;
4194 return S_OK;
4197 static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface,
4198 long lEvCode) {
4199 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4201 TRACE("(%p/%p)->(%ld)\n", This, iface, lEvCode);
4203 if (lEvCode == EC_COMPLETE)
4204 This->HandleEcComplete = TRUE;
4205 else if (lEvCode == EC_REPAINT)
4206 This->HandleEcRepaint = TRUE;
4207 else if (lEvCode == EC_CLOCK_CHANGED)
4208 This->HandleEcClockChanged = TRUE;
4209 else
4210 return S_FALSE;
4212 return S_OK;
4215 static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface,
4216 long lEvCode,
4217 LONG_PTR lParam1,
4218 LONG_PTR lParam2) {
4219 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4221 TRACE("(%p/%p)->(%ld, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2);
4223 return S_OK;
4226 /*** IMediaEventEx methods ***/
4227 static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface,
4228 OAHWND hwnd,
4229 long lMsg,
4230 LONG_PTR lInstanceData) {
4231 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4233 TRACE("(%p/%p)->(%08x, %ld, %08lx)\n", This, iface, (DWORD) hwnd, lMsg, lInstanceData);
4235 This->notif.hWnd = (HWND)hwnd;
4236 This->notif.msg = lMsg;
4237 This->notif.instance = (long) lInstanceData;
4239 return S_OK;
4242 static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface,
4243 long lNoNotifyFlags) {
4244 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4246 TRACE("(%p/%p)->(%ld)\n", This, iface, lNoNotifyFlags);
4248 if ((lNoNotifyFlags != 0) && (lNoNotifyFlags != 1))
4249 return E_INVALIDARG;
4251 This->notif.disabled = lNoNotifyFlags;
4253 return S_OK;
4256 static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface,
4257 long *lplNoNotifyFlags) {
4258 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface);
4260 TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags);
4262 if (!lplNoNotifyFlags)
4263 return E_POINTER;
4265 *lplNoNotifyFlags = This->notif.disabled;
4267 return S_OK;
4271 static const IMediaEventExVtbl IMediaEventEx_VTable =
4273 MediaEvent_QueryInterface,
4274 MediaEvent_AddRef,
4275 MediaEvent_Release,
4276 MediaEvent_GetTypeInfoCount,
4277 MediaEvent_GetTypeInfo,
4278 MediaEvent_GetIDsOfNames,
4279 MediaEvent_Invoke,
4280 MediaEvent_GetEventHandle,
4281 MediaEvent_GetEvent,
4282 MediaEvent_WaitForCompletion,
4283 MediaEvent_CancelDefaultHandling,
4284 MediaEvent_RestoreDefaultHandling,
4285 MediaEvent_FreeEventParams,
4286 MediaEvent_SetNotifyWindow,
4287 MediaEvent_SetNotifyFlags,
4288 MediaEvent_GetNotifyFlags
4292 static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv)
4294 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4296 return Filtergraph_QueryInterface(This, riid, ppv);
4299 static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface)
4301 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4303 return Filtergraph_AddRef(This);
4306 static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface)
4308 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4310 return Filtergraph_Release(This);
4313 static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID)
4315 FIXME("(%p): stub\n", pClassID);
4317 return E_NOTIMPL;
4320 static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface)
4322 FIXME("(): stub\n");
4324 return E_NOTIMPL;
4327 static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface)
4329 FIXME("(): stub\n");
4331 return E_NOTIMPL;
4334 static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart)
4336 FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart));
4338 return E_NOTIMPL;
4341 static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState)
4343 FIXME("(%d, %p): stub\n", dwMsTimeout, pState);
4345 return E_NOTIMPL;
4348 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
4350 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4351 HRESULT hr = S_OK;
4352 int i;
4354 TRACE("(%p/%p)->(%p)\n", iface, This, pClock);
4356 EnterCriticalSection(&This->cs);
4358 for (i = 0;i < This->nFilters;i++)
4360 hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
4361 if (FAILED(hr))
4362 break;
4365 if (FAILED(hr))
4367 for(;i >= 0;i--)
4368 IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
4370 else
4372 if (This->refClock)
4373 IReferenceClock_Release(This->refClock);
4374 This->refClock = pClock;
4375 if (This->refClock)
4376 IReferenceClock_AddRef(This->refClock);
4378 if (This->HandleEcClockChanged)
4380 IMediaEventSink *pEventSink;
4381 HRESULT eshr;
4383 eshr = IMediaFilter_QueryInterface(iface, &IID_IMediaEventSink, (LPVOID)&pEventSink);
4384 if (SUCCEEDED(eshr))
4386 IMediaEventSink_Notify(pEventSink, EC_CLOCK_CHANGED, 0, 0);
4387 IMediaEventSink_Release(pEventSink);
4392 LeaveCriticalSection(&This->cs);
4394 return hr;
4397 static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock)
4399 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface);
4401 TRACE("(%p/%p)->(%p)\n", iface, This, ppClock);
4403 if (!ppClock)
4404 return E_POINTER;
4406 EnterCriticalSection(&This->cs);
4408 *ppClock = This->refClock;
4409 if (*ppClock)
4410 IReferenceClock_AddRef(*ppClock);
4412 LeaveCriticalSection(&This->cs);
4414 return S_OK;
4417 static const IMediaFilterVtbl IMediaFilter_VTable =
4419 MediaFilter_QueryInterface,
4420 MediaFilter_AddRef,
4421 MediaFilter_Release,
4422 MediaFilter_GetClassID,
4423 MediaFilter_Stop,
4424 MediaFilter_Pause,
4425 MediaFilter_Run,
4426 MediaFilter_GetState,
4427 MediaFilter_SetSyncSource,
4428 MediaFilter_GetSyncSource
4431 static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv)
4433 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4435 return Filtergraph_QueryInterface(This, riid, ppv);
4438 static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface)
4440 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4442 return Filtergraph_AddRef(This);
4445 static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface)
4447 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4449 return Filtergraph_Release(This);
4452 static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, long EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2)
4454 ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface);
4455 Event evt;
4457 TRACE("(%p/%p)->(%ld, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2);
4459 /* We need thread safety here, let's use the events queue's one */
4460 EnterCriticalSection(&This->evqueue.msg_crst);
4462 if ((EventCode == EC_COMPLETE) && This->HandleEcComplete)
4464 TRACE("Process EC_COMPLETE notification\n");
4465 if (++This->EcCompleteCount == This->nRenderers)
4467 evt.lEventCode = EC_COMPLETE;
4468 evt.lParam1 = S_OK;
4469 evt.lParam2 = 0;
4470 TRACE("Send EC_COMPLETE to app\n");
4471 EventsQueue_PutEvent(&This->evqueue, &evt);
4472 if (!This->notif.disabled && This->notif.hWnd)
4474 TRACE("Send Window message\n");
4475 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4477 This->CompletionStatus = EC_COMPLETE;
4478 SetEvent(This->hEventCompletion);
4481 else if ((EventCode == EC_REPAINT) && This->HandleEcRepaint)
4483 /* FIXME: Not handled yet */
4485 else
4487 evt.lEventCode = EventCode;
4488 evt.lParam1 = EventParam1;
4489 evt.lParam2 = EventParam2;
4490 EventsQueue_PutEvent(&This->evqueue, &evt);
4491 if (!This->notif.disabled && This->notif.hWnd)
4492 PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance);
4495 LeaveCriticalSection(&This->evqueue.msg_crst);
4496 return S_OK;
4499 static const IMediaEventSinkVtbl IMediaEventSink_VTable =
4501 MediaEventSink_QueryInterface,
4502 MediaEventSink_AddRef,
4503 MediaEventSink_Release,
4504 MediaEventSink_Notify
4507 static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv)
4509 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4511 return Filtergraph_QueryInterface(This, riid, ppv);
4514 static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface)
4516 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4518 return Filtergraph_AddRef(This);
4521 static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface)
4523 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4525 return Filtergraph_Release(This);
4528 static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface,
4529 IPin* pOutputPin,
4530 IPin* pInputPin,
4531 const AM_MEDIA_TYPE* pmtFirstConnection,
4532 IBaseFilter* pUsingFilter,
4533 HANDLE hAbortEvent,
4534 DWORD dwFlags)
4536 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4538 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags);
4540 return E_NOTIMPL;
4543 static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface,
4544 IGraphConfigCallback* pCallback,
4545 PVOID pvContext,
4546 DWORD dwFlags,
4547 HANDLE hAbortEvent)
4549 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4551 FIXME("(%p)->(%p, %p, %x, %p): stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent);
4553 return E_NOTIMPL;
4556 static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface,
4557 IBaseFilter* pFilter)
4559 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4561 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4563 return E_NOTIMPL;
4566 static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface,
4567 IEnumFilters** pEnum)
4569 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4571 FIXME("(%p)->(%p): stub!\n", This, pEnum);
4573 return E_NOTIMPL;
4576 static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface,
4577 IBaseFilter* pFilter)
4579 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4581 FIXME("(%p)->(%p): stub!\n", This, pFilter);
4583 return E_NOTIMPL;
4586 static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface,
4587 REFERENCE_TIME* prtStart)
4589 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4591 FIXME("(%p)->(%p): stub!\n", This, prtStart);
4593 return E_NOTIMPL;
4596 static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface,
4597 IPin* pOutputPin,
4598 IPinConnection* pConnection,
4599 HANDLE hEventAbort)
4601 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4603 FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort);
4605 return E_NOTIMPL;
4608 static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface,
4609 IBaseFilter* pFilter,
4610 DWORD dwFlags)
4612 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4614 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4616 return E_NOTIMPL;
4619 static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface,
4620 IBaseFilter* pFilter,
4621 DWORD* dwFlags)
4623 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4625 FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags);
4627 return E_NOTIMPL;
4630 static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface,
4631 IBaseFilter* pFilter,
4632 DWORD dwFlags)
4634 ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface);
4636 FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags);
4638 return E_NOTIMPL;
4641 static const IGraphConfigVtbl IGraphConfig_VTable =
4643 GraphConfig_QueryInterface,
4644 GraphConfig_AddRef,
4645 GraphConfig_Release,
4646 GraphConfig_Reconnect,
4647 GraphConfig_Reconfigure,
4648 GraphConfig_AddFilterToCache,
4649 GraphConfig_EnumCacheFilter,
4650 GraphConfig_RemoveFilterFromCache,
4651 GraphConfig_GetStartTime,
4652 GraphConfig_PushThroughData,
4653 GraphConfig_SetFilterFlags,
4654 GraphConfig_GetFilterFlags,
4655 GraphConfig_RemoveFilterEx
4658 static const IUnknownVtbl IInner_VTable =
4660 FilterGraphInner_QueryInterface,
4661 FilterGraphInner_AddRef,
4662 FilterGraphInner_Release
4665 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
4666 REFIID riid,
4667 LPVOID * ppv) {
4668 if (This->bAggregatable)
4669 This->bUnkOuterValid = TRUE;
4671 if (This->pUnkOuter)
4673 if (This->bAggregatable)
4674 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
4676 if (IsEqualIID(riid, &IID_IUnknown))
4678 HRESULT hr;
4680 IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
4681 hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
4682 IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
4683 This->bAggregatable = TRUE;
4684 return hr;
4687 *ppv = NULL;
4688 return E_NOINTERFACE;
4691 return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
4694 static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This) {
4695 if (This->pUnkOuter && This->bUnkOuterValid)
4696 return IUnknown_AddRef(This->pUnkOuter);
4697 return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
4700 static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This) {
4701 if (This->pUnkOuter && This->bUnkOuterValid)
4702 return IUnknown_Release(This->pUnkOuter);
4703 return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
4706 /* This is the only function that actually creates a FilterGraph class... */
4707 HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
4709 IFilterGraphImpl *fimpl;
4710 HRESULT hr;
4712 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
4714 *ppObj = NULL;
4716 fimpl = CoTaskMemAlloc(sizeof(*fimpl));
4717 fimpl->pUnkOuter = pUnkOuter;
4718 fimpl->bUnkOuterValid = FALSE;
4719 fimpl->bAggregatable = FALSE;
4720 fimpl->IInner_vtbl = &IInner_VTable;
4721 fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
4722 fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
4723 fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
4724 fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable;
4725 fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable;
4726 fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable;
4727 fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable;
4728 fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable;
4729 fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable;
4730 fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable;
4731 fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable;
4732 fimpl->ref = 1;
4733 fimpl->ppFiltersInGraph = NULL;
4734 fimpl->pFilterNames = NULL;
4735 fimpl->nFilters = 0;
4736 fimpl->filterCapacity = 0;
4737 fimpl->nameIndex = 1;
4738 fimpl->refClock = NULL;
4739 fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
4740 fimpl->HandleEcComplete = TRUE;
4741 fimpl->HandleEcRepaint = TRUE;
4742 fimpl->HandleEcClockChanged = TRUE;
4743 fimpl->notif.hWnd = 0;
4744 fimpl->notif.disabled = FALSE;
4745 fimpl->nRenderers = 0;
4746 fimpl->EcCompleteCount = 0;
4747 fimpl->state = State_Stopped;
4748 EventsQueue_Init(&fimpl->evqueue);
4749 InitializeCriticalSection(&fimpl->cs);
4750 fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
4751 fimpl->nItfCacheEntries = 0;
4753 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
4754 if (FAILED(hr)) {
4755 ERR("Unable to create filter mapper (%x)\n", hr);
4756 return hr;
4759 *ppObj = fimpl;
4760 return S_OK;
4763 HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj)
4765 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
4766 return FilterGraph_create(pUnkOuter, ppObj);