1 /* DirectShow FilterGraph object (QUARTZ.DLL)
3 * Copyright 2002 Lionel Ulmer
4 * Copyright 2004 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/debug.h"
33 #include "quartz_private.h"
39 #include "wine/unicode.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
45 HWND hWnd
; /* Target window */
46 UINT msg
; /* User window message */
47 LONG_PTR instance
; /* User data */
48 int disabled
; /* Disabled messages posting */
52 LONG lEventCode
; /* Event code */
53 LONG_PTR lParam1
; /* Param1 */
54 LONG_PTR lParam2
; /* Param2 */
57 /* messages ring implementation for queuing events (taken from winmm) */
58 #define EVENTS_RING_BUFFER_INCREMENT 64
64 CRITICAL_SECTION msg_crst
;
65 HANDLE msg_event
; /* Signaled for no empty queue */
68 static int EventsQueue_Init(EventsQueue
* omr
)
72 omr
->msg_event
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
73 omr
->ring_buffer_size
= EVENTS_RING_BUFFER_INCREMENT
;
74 omr
->messages
= CoTaskMemAlloc(omr
->ring_buffer_size
* sizeof(Event
));
75 ZeroMemory(omr
->messages
, omr
->ring_buffer_size
* sizeof(Event
));
77 InitializeCriticalSection(&omr
->msg_crst
);
78 omr
->msg_crst
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": EventsQueue.msg_crst");
82 static int EventsQueue_Destroy(EventsQueue
* omr
)
84 CloseHandle(omr
->msg_event
);
85 CoTaskMemFree(omr
->messages
);
86 omr
->msg_crst
.DebugInfo
->Spare
[0] = 0;
87 DeleteCriticalSection(&omr
->msg_crst
);
91 static BOOL
EventsQueue_PutEvent(EventsQueue
* omr
, const Event
* evt
)
93 EnterCriticalSection(&omr
->msg_crst
);
94 if (omr
->msg_toget
== ((omr
->msg_tosave
+ 1) % omr
->ring_buffer_size
))
96 int old_ring_buffer_size
= omr
->ring_buffer_size
;
97 omr
->ring_buffer_size
+= EVENTS_RING_BUFFER_INCREMENT
;
98 TRACE("omr->ring_buffer_size=%d\n",omr
->ring_buffer_size
);
99 omr
->messages
= CoTaskMemRealloc(omr
->messages
, omr
->ring_buffer_size
* sizeof(Event
));
100 /* Now we need to rearrange the ring buffer so that the new
101 buffers just allocated are in between omr->msg_tosave and
104 if (omr
->msg_tosave
< omr
->msg_toget
)
106 memmove(&(omr
->messages
[omr
->msg_toget
+ EVENTS_RING_BUFFER_INCREMENT
]),
107 &(omr
->messages
[omr
->msg_toget
]),
108 sizeof(Event
)*(old_ring_buffer_size
- omr
->msg_toget
)
110 omr
->msg_toget
+= EVENTS_RING_BUFFER_INCREMENT
;
113 omr
->messages
[omr
->msg_tosave
] = *evt
;
114 SetEvent(omr
->msg_event
);
115 omr
->msg_tosave
= (omr
->msg_tosave
+ 1) % omr
->ring_buffer_size
;
116 LeaveCriticalSection(&omr
->msg_crst
);
120 static BOOL
EventsQueue_GetEvent(EventsQueue
* omr
, Event
* evt
, LONG msTimeOut
)
122 if (WaitForSingleObject(omr
->msg_event
, msTimeOut
) != WAIT_OBJECT_0
)
125 EnterCriticalSection(&omr
->msg_crst
);
127 if (omr
->msg_toget
== omr
->msg_tosave
) /* buffer empty ? */
129 LeaveCriticalSection(&omr
->msg_crst
);
133 *evt
= omr
->messages
[omr
->msg_toget
];
134 omr
->msg_toget
= (omr
->msg_toget
+ 1) % omr
->ring_buffer_size
;
136 /* Mark the buffer as empty if needed */
137 if (omr
->msg_toget
== omr
->msg_tosave
) /* buffer empty ? */
138 ResetEvent(omr
->msg_event
);
140 LeaveCriticalSection(&omr
->msg_crst
);
144 #define MAX_ITF_CACHE_ENTRIES 3
145 typedef struct _ITF_CACHE_ENTRY
{
151 typedef struct _IFilterGraphImpl
{
152 IUnknown IUnknown_inner
;
153 IFilterGraph2 IFilterGraph2_iface
;
154 IMediaControl IMediaControl_iface
;
155 IMediaSeeking IMediaSeeking_iface
;
156 IBasicAudio IBasicAudio_iface
;
157 IBasicVideo2 IBasicVideo2_iface
;
158 IVideoWindow IVideoWindow_iface
;
159 IMediaEventEx IMediaEventEx_iface
;
160 IMediaFilter IMediaFilter_iface
;
161 IMediaEventSink IMediaEventSink_iface
;
162 IGraphConfig IGraphConfig_iface
;
163 IMediaPosition IMediaPosition_iface
;
164 IObjectWithSite IObjectWithSite_iface
;
165 IGraphVersion IGraphVersion_iface
;
166 /* IAMGraphStreams */
171 /* IRegisterServiceProvider */
172 /* IResourceMananger */
173 /* IServiceProvider */
174 /* IVideoFrameStep */
178 IUnknown
*punkFilterMapper2
;
179 IBaseFilter
** ppFiltersInGraph
;
180 LPWSTR
* pFilterNames
;
184 IReferenceClock
*refClock
;
185 IBaseFilter
*refClockProvider
;
187 HANDLE hEventCompletion
;
188 int CompletionStatus
;
192 int HandleEcComplete
;
194 int HandleEcClockChanged
;
197 ITF_CACHE_ENTRY ItfCacheEntries
[MAX_ITF_CACHE_ENTRIES
];
198 int nItfCacheEntries
;
201 REFERENCE_TIME start_time
;
202 REFERENCE_TIME pause_time
;
203 LONGLONG stop_position
;
209 static inline IFilterGraphImpl
*impl_from_IUnknown(IUnknown
*iface
)
211 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IUnknown_inner
);
214 static HRESULT WINAPI
FilterGraphInner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppvObj
)
216 IFilterGraphImpl
*This
= impl_from_IUnknown(iface
);
217 TRACE("(%p)->(%s (%p), %p)\n", This
, debugstr_guid(riid
), riid
, ppvObj
);
219 if (IsEqualGUID(&IID_IUnknown
, riid
)) {
220 *ppvObj
= &This
->IUnknown_inner
;
221 TRACE(" returning IUnknown interface (%p)\n", *ppvObj
);
222 } else if (IsEqualGUID(&IID_IFilterGraph
, riid
) ||
223 IsEqualGUID(&IID_IFilterGraph2
, riid
) ||
224 IsEqualGUID(&IID_IGraphBuilder
, riid
)) {
225 *ppvObj
= &This
->IFilterGraph2_iface
;
226 TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj
);
227 } else if (IsEqualGUID(&IID_IMediaControl
, riid
)) {
228 *ppvObj
= &This
->IMediaControl_iface
;
229 TRACE(" returning IMediaControl interface (%p)\n", *ppvObj
);
230 } else if (IsEqualGUID(&IID_IMediaSeeking
, riid
)) {
231 *ppvObj
= &This
->IMediaSeeking_iface
;
232 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj
);
233 } else if (IsEqualGUID(&IID_IBasicAudio
, riid
)) {
234 *ppvObj
= &This
->IBasicAudio_iface
;
235 TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj
);
236 } else if (IsEqualGUID(&IID_IBasicVideo
, riid
) ||
237 IsEqualGUID(&IID_IBasicVideo2
, riid
)) {
238 *ppvObj
= &This
->IBasicVideo2_iface
;
239 TRACE(" returning IBasicVideo2 interface (%p)\n", *ppvObj
);
240 } else if (IsEqualGUID(&IID_IVideoWindow
, riid
)) {
241 *ppvObj
= &This
->IVideoWindow_iface
;
242 TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj
);
243 } else if (IsEqualGUID(&IID_IMediaEvent
, riid
) ||
244 IsEqualGUID(&IID_IMediaEventEx
, riid
)) {
245 *ppvObj
= &This
->IMediaEventEx_iface
;
246 TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj
);
247 } else if (IsEqualGUID(&IID_IMediaFilter
, riid
) ||
248 IsEqualGUID(&IID_IPersist
, riid
)) {
249 *ppvObj
= &This
->IMediaFilter_iface
;
250 TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj
);
251 } else if (IsEqualGUID(&IID_IMediaEventSink
, riid
)) {
252 *ppvObj
= &This
->IMediaEventSink_iface
;
253 TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj
);
254 } else if (IsEqualGUID(&IID_IGraphConfig
, riid
)) {
255 *ppvObj
= &This
->IGraphConfig_iface
;
256 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj
);
257 } else if (IsEqualGUID(&IID_IMediaPosition
, riid
)) {
258 *ppvObj
= &This
->IMediaPosition_iface
;
259 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj
);
260 } else if (IsEqualGUID(&IID_IObjectWithSite
, riid
)) {
261 *ppvObj
= &This
->IObjectWithSite_iface
;
262 TRACE(" returning IObjectWithSite interface (%p)\n", *ppvObj
);
263 } else if (IsEqualGUID(&IID_IFilterMapper
, riid
)) {
264 TRACE(" requesting IFilterMapper interface from aggregated filtermapper (%p)\n", *ppvObj
);
265 return IUnknown_QueryInterface(This
->punkFilterMapper2
, riid
, ppvObj
);
266 } else if (IsEqualGUID(&IID_IFilterMapper2
, riid
)) {
267 TRACE(" returning IFilterMapper2 interface from aggregated filtermapper (%p)\n", *ppvObj
);
268 return IUnknown_QueryInterface(This
->punkFilterMapper2
, riid
, ppvObj
);
269 } else if (IsEqualGUID(&IID_IFilterMapper3
, riid
)) {
270 TRACE(" returning IFilterMapper3 interface from aggregated filtermapper (%p)\n", *ppvObj
);
271 return IUnknown_QueryInterface(This
->punkFilterMapper2
, riid
, ppvObj
);
272 } else if (IsEqualGUID(&IID_IGraphVersion
, riid
)) {
273 *ppvObj
= &This
->IGraphConfig_iface
;
274 TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj
);
277 FIXME("unknown interface %s\n", debugstr_guid(riid
));
278 return E_NOINTERFACE
;
281 IUnknown_AddRef((IUnknown
*)*ppvObj
);
285 static ULONG WINAPI
FilterGraphInner_AddRef(IUnknown
*iface
)
287 IFilterGraphImpl
*This
= impl_from_IUnknown(iface
);
288 ULONG ref
= InterlockedIncrement(&This
->ref
);
290 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
295 static ULONG WINAPI
FilterGraphInner_Release(IUnknown
*iface
)
297 IFilterGraphImpl
*This
= impl_from_IUnknown(iface
);
298 ULONG ref
= InterlockedDecrement(&This
->ref
);
300 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
305 This
->ref
= 1; /* guard against reentrancy (aggregation). */
307 IMediaControl_Stop(&This
->IMediaControl_iface
);
309 while (This
->nFilters
)
310 IFilterGraph2_RemoveFilter(&This
->IFilterGraph2_iface
, This
->ppFiltersInGraph
[0]);
313 IReferenceClock_Release(This
->refClock
);
315 for (i
= 0; i
< This
->nItfCacheEntries
; i
++)
317 if (This
->ItfCacheEntries
[i
].iface
)
318 IUnknown_Release(This
->ItfCacheEntries
[i
].iface
);
321 IUnknown_Release(This
->punkFilterMapper2
);
323 if (This
->pSite
) IUnknown_Release(This
->pSite
);
325 CloseHandle(This
->hEventCompletion
);
326 EventsQueue_Destroy(&This
->evqueue
);
327 This
->cs
.DebugInfo
->Spare
[0] = 0;
328 DeleteCriticalSection(&This
->cs
);
329 CoTaskMemFree(This
->ppFiltersInGraph
);
330 CoTaskMemFree(This
->pFilterNames
);
336 static inline IFilterGraphImpl
*impl_from_IFilterGraph2(IFilterGraph2
*iface
)
338 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IFilterGraph2_iface
);
341 static HRESULT WINAPI
FilterGraph2_QueryInterface(IFilterGraph2
*iface
, REFIID riid
, void **ppvObj
)
343 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
345 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
347 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
350 static ULONG WINAPI
FilterGraph2_AddRef(IFilterGraph2
*iface
)
352 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
354 TRACE("(%p/%p)->()\n", This
, iface
);
356 return IUnknown_AddRef(This
->outer_unk
);
359 static ULONG WINAPI
FilterGraph2_Release(IFilterGraph2
*iface
)
361 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
363 TRACE("(%p/%p)->()\n", This
, iface
);
365 return IUnknown_Release(This
->outer_unk
);
368 /*** IFilterGraph methods ***/
369 static HRESULT WINAPI
FilterGraph2_AddFilter(IFilterGraph2
*iface
, IBaseFilter
*pFilter
,
372 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
375 WCHAR
* wszFilterName
= NULL
;
376 BOOL duplicate_name
= FALSE
;
378 TRACE("(%p/%p)->(%p, %s (%p))\n", This
, iface
, pFilter
, debugstr_w(pName
), pName
);
383 wszFilterName
= CoTaskMemAlloc( (pName
? strlenW(pName
) + 6 : 5) * sizeof(WCHAR
) );
387 /* Check if name already exists */
388 for(i
= 0; i
< This
->nFilters
; i
++)
389 if (!strcmpW(This
->pFilterNames
[i
], pName
))
391 duplicate_name
= TRUE
;
396 /* If no name given or name already existing, generate one */
397 if (!pName
|| duplicate_name
)
399 static const WCHAR wszFmt1
[] = {'%','s',' ','%','0','4','d',0};
400 static const WCHAR wszFmt2
[] = {'%','0','4','d',0};
402 for (j
= 0; j
< 10000 ; j
++)
406 sprintfW(wszFilterName
, wszFmt1
, pName
, This
->nameIndex
);
408 sprintfW(wszFilterName
, wszFmt2
, This
->nameIndex
);
409 TRACE("Generated name %s\n", debugstr_w(wszFilterName
));
411 /* Check if the generated name already exists */
412 for(i
= 0; i
< This
->nFilters
; i
++)
413 if (!strcmpW(This
->pFilterNames
[i
], wszFilterName
))
416 /* Compute next index and exit if generated name is suitable */
417 if (This
->nameIndex
++ == 10000)
419 if (i
== This
->nFilters
)
422 /* Unable to find a suitable name */
425 CoTaskMemFree(wszFilterName
);
426 return VFW_E_DUPLICATE_NAME
;
430 memcpy(wszFilterName
, pName
, (strlenW(pName
) + 1) * sizeof(WCHAR
));
432 if (This
->nFilters
+ 1 > This
->filterCapacity
)
434 int newCapacity
= This
->filterCapacity
? 2 * This
->filterCapacity
: 1;
435 IBaseFilter
** ppNewFilters
= CoTaskMemAlloc(newCapacity
* sizeof(IBaseFilter
*));
436 LPWSTR
* pNewNames
= CoTaskMemAlloc(newCapacity
* sizeof(LPWSTR
));
437 memcpy(ppNewFilters
, This
->ppFiltersInGraph
, This
->nFilters
* sizeof(IBaseFilter
*));
438 memcpy(pNewNames
, This
->pFilterNames
, This
->nFilters
* sizeof(LPWSTR
));
439 if (This
->filterCapacity
)
441 CoTaskMemFree(This
->ppFiltersInGraph
);
442 CoTaskMemFree(This
->pFilterNames
);
444 This
->ppFiltersInGraph
= ppNewFilters
;
445 This
->pFilterNames
= pNewNames
;
446 This
->filterCapacity
= newCapacity
;
449 hr
= IBaseFilter_JoinFilterGraph(pFilter
, (IFilterGraph
*)&This
->IFilterGraph2_iface
, wszFilterName
);
453 IBaseFilter_AddRef(pFilter
);
454 This
->ppFiltersInGraph
[This
->nFilters
] = pFilter
;
455 This
->pFilterNames
[This
->nFilters
] = wszFilterName
;
458 IBaseFilter_SetSyncSource(pFilter
, This
->refClock
);
461 CoTaskMemFree(wszFilterName
);
463 if (SUCCEEDED(hr
) && duplicate_name
)
464 return VFW_S_DUPLICATE_NAME
;
469 static HRESULT WINAPI
FilterGraph2_RemoveFilter(IFilterGraph2
*iface
, IBaseFilter
*pFilter
)
471 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
475 TRACE("(%p/%p)->(%p)\n", This
, iface
, pFilter
);
477 /* FIXME: check graph is stopped */
479 for (i
= 0; i
< This
->nFilters
; i
++)
481 if (This
->ppFiltersInGraph
[i
] == pFilter
)
483 IEnumPins
*penumpins
= NULL
;
486 if (This
->defaultclock
&& This
->refClockProvider
== pFilter
)
488 IMediaFilter_SetSyncSource(&This
->IMediaFilter_iface
, NULL
);
489 This
->defaultclock
= TRUE
;
492 TRACE("Removing filter %s\n", debugstr_w(This
->pFilterNames
[i
]));
493 IBaseFilter_GetState(pFilter
, 0, &state
);
494 if (state
== State_Running
)
495 IBaseFilter_Pause(pFilter
);
496 if (state
!= State_Stopped
)
497 IBaseFilter_Stop(pFilter
);
499 hr
= IBaseFilter_EnumPins(pFilter
, &penumpins
);
502 while(IEnumPins_Next(penumpins
, 1, &ppin
, NULL
) == S_OK
)
506 IPin_ConnectedTo(ppin
, &victim
);
509 h
= IPin_Disconnect(victim
);
510 TRACE("Disconnect other side: %08x\n", h
);
511 if (h
== VFW_E_NOT_STOPPED
)
514 IPin_QueryPinInfo(victim
, &pinfo
);
516 IBaseFilter_GetState(pinfo
.pFilter
, 0, &state
);
517 if (state
== State_Running
)
518 IBaseFilter_Pause(pinfo
.pFilter
);
519 IBaseFilter_Stop(pinfo
.pFilter
);
520 IBaseFilter_Release(pinfo
.pFilter
);
521 h
= IPin_Disconnect(victim
);
522 TRACE("Disconnect retry: %08x\n", h
);
524 IPin_Release(victim
);
526 h
= IPin_Disconnect(ppin
);
527 TRACE("Disconnect 2: %08x\n", h
);
531 IEnumPins_Release(penumpins
);
534 hr
= IBaseFilter_JoinFilterGraph(pFilter
, NULL
, This
->pFilterNames
[i
]);
537 IBaseFilter_SetSyncSource(pFilter
, NULL
);
538 IBaseFilter_Release(pFilter
);
539 CoTaskMemFree(This
->pFilterNames
[i
]);
540 memmove(This
->ppFiltersInGraph
+i
, This
->ppFiltersInGraph
+i
+1, sizeof(IBaseFilter
*)*(This
->nFilters
- 1 - i
));
541 memmove(This
->pFilterNames
+i
, This
->pFilterNames
+i
+1, sizeof(LPWSTR
)*(This
->nFilters
- 1 - i
));
544 /* Invalidate interfaces in the cache */
545 for (i
= 0; i
< This
->nItfCacheEntries
; i
++)
546 if (pFilter
== This
->ItfCacheEntries
[i
].filter
)
548 IUnknown_Release(This
->ItfCacheEntries
[i
].iface
);
549 This
->ItfCacheEntries
[i
].iface
= NULL
;
550 This
->ItfCacheEntries
[i
].filter
= NULL
;
558 return hr
; /* FIXME: check this error code */
561 static HRESULT WINAPI
FilterGraph2_EnumFilters(IFilterGraph2
*iface
, IEnumFilters
**ppEnum
)
563 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
565 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppEnum
);
567 return IEnumFiltersImpl_Construct(&This
->IGraphVersion_iface
, &This
->ppFiltersInGraph
, &This
->nFilters
, ppEnum
);
570 static HRESULT WINAPI
FilterGraph2_FindFilterByName(IFilterGraph2
*iface
, LPCWSTR pName
,
571 IBaseFilter
**ppFilter
)
573 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
576 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_w(pName
), pName
, ppFilter
);
581 for (i
= 0; i
< This
->nFilters
; i
++)
583 if (!strcmpW(pName
, This
->pFilterNames
[i
]))
585 *ppFilter
= This
->ppFiltersInGraph
[i
];
586 IBaseFilter_AddRef(*ppFilter
);
592 return VFW_E_NOT_FOUND
;
595 /* Don't allow a circular connection to form, return VFW_E_CIRCULAR_GRAPH if this would be the case.
596 * A circular connection will be formed if from the filter of the output pin, the input pin can be reached
598 static HRESULT
CheckCircularConnection(IFilterGraphImpl
*This
, IPin
*out
, IPin
*in
)
602 PIN_INFO info_out
, info_in
;
604 hr
= IPin_QueryPinInfo(out
, &info_out
);
607 if (info_out
.dir
!= PINDIR_OUTPUT
)
609 IBaseFilter_Release(info_out
.pFilter
);
610 return VFW_E_CANNOT_CONNECT
;
613 hr
= IPin_QueryPinInfo(in
, &info_in
);
615 IBaseFilter_Release(info_in
.pFilter
);
618 if (info_in
.dir
!= PINDIR_INPUT
)
620 hr
= VFW_E_CANNOT_CONNECT
;
624 if (info_out
.pFilter
== info_in
.pFilter
)
625 hr
= VFW_E_CIRCULAR_GRAPH
;
631 hr
= IBaseFilter_EnumPins(info_out
.pFilter
, &enumpins
);
635 IEnumPins_Reset(enumpins
);
636 while ((hr
= IEnumPins_Next(enumpins
, 1, &test
, NULL
)) == S_OK
)
638 PIN_DIRECTION dir
= PINDIR_OUTPUT
;
639 IPin_QueryDirection(test
, &dir
);
640 if (dir
== PINDIR_INPUT
)
643 IPin_ConnectedTo(test
, &victim
);
646 hr
= CheckCircularConnection(This
, victim
, in
);
647 IPin_Release(victim
);
657 IEnumPins_Release(enumpins
);
661 IBaseFilter_Release(info_out
.pFilter
);
663 ERR("Checking filtergraph returned %08x, something's not right!\n", hr
);
666 /* Debugging filtergraphs not enabled */
672 /* NOTE: despite the implication, it doesn't matter which
673 * way round you put in the input and output pins */
674 static HRESULT WINAPI
FilterGraph2_ConnectDirect(IFilterGraph2
*iface
, IPin
*ppinIn
, IPin
*ppinOut
,
675 const AM_MEDIA_TYPE
*pmt
)
677 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
681 TRACE("(%p/%p)->(%p, %p, %p)\n", This
, iface
, ppinIn
, ppinOut
, pmt
);
683 /* FIXME: check pins are in graph */
685 if (TRACE_ON(quartz
))
689 hr
= IPin_QueryPinInfo(ppinIn
, &PinInfo
);
693 TRACE("Filter owning first pin => %p\n", PinInfo
.pFilter
);
694 IBaseFilter_Release(PinInfo
.pFilter
);
696 hr
= IPin_QueryPinInfo(ppinOut
, &PinInfo
);
700 TRACE("Filter owning second pin => %p\n", PinInfo
.pFilter
);
701 IBaseFilter_Release(PinInfo
.pFilter
);
704 hr
= IPin_QueryDirection(ppinIn
, &dir
);
707 if (dir
== PINDIR_INPUT
)
709 hr
= CheckCircularConnection(This
, ppinOut
, ppinIn
);
711 hr
= IPin_Connect(ppinOut
, ppinIn
, pmt
);
715 hr
= CheckCircularConnection(This
, ppinIn
, ppinOut
);
717 hr
= IPin_Connect(ppinIn
, ppinOut
, pmt
);
724 static HRESULT WINAPI
FilterGraph2_Reconnect(IFilterGraph2
*iface
, IPin
*ppin
)
726 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
727 IPin
*pConnectedTo
= NULL
;
729 PIN_DIRECTION pindir
;
731 IPin_QueryDirection(ppin
, &pindir
);
732 hr
= IPin_ConnectedTo(ppin
, &pConnectedTo
);
734 TRACE("Querying connected to failed: %x\n", hr
);
737 IPin_Disconnect(ppin
);
738 IPin_Disconnect(pConnectedTo
);
739 if (pindir
== PINDIR_INPUT
)
740 hr
= IPin_Connect(pConnectedTo
, ppin
, NULL
);
742 hr
= IPin_Connect(ppin
, pConnectedTo
, NULL
);
743 IPin_Release(pConnectedTo
);
745 WARN("Reconnecting pins failed, pins are not connected now..\n");
746 TRACE("(%p->%p) -- %p %p -> %x\n", iface
, This
, ppin
, pConnectedTo
, hr
);
750 static HRESULT WINAPI
FilterGraph2_Disconnect(IFilterGraph2
*iface
, IPin
*ppin
)
752 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
754 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppin
);
759 return IPin_Disconnect(ppin
);
762 static HRESULT WINAPI
FilterGraph2_SetDefaultSyncSource(IFilterGraph2
*iface
)
764 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
765 IReferenceClock
*pClock
= NULL
;
769 TRACE("(%p/%p)->() live sources not handled properly!\n", iface
, This
);
771 EnterCriticalSection(&This
->cs
);
773 for (i
= 0; i
< This
->nFilters
; ++i
)
776 IAMFilterMiscFlags
*flags
= NULL
;
777 IBaseFilter_QueryInterface(This
->ppFiltersInGraph
[i
], &IID_IAMFilterMiscFlags
, (void**)&flags
);
780 miscflags
= IAMFilterMiscFlags_GetMiscFlags(flags
);
781 IAMFilterMiscFlags_Release(flags
);
782 if (miscflags
== AM_FILTER_MISC_FLAGS_IS_RENDERER
)
783 IBaseFilter_QueryInterface(This
->ppFiltersInGraph
[i
], &IID_IReferenceClock
, (void**)&pClock
);
790 hr
= CoCreateInstance(&CLSID_SystemClock
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IReferenceClock
, (LPVOID
*)&pClock
);
791 This
->refClockProvider
= NULL
;
794 This
->refClockProvider
= This
->ppFiltersInGraph
[i
];
798 hr
= IMediaFilter_SetSyncSource(&This
->IMediaFilter_iface
, pClock
);
799 This
->defaultclock
= TRUE
;
800 IReferenceClock_Release(pClock
);
802 LeaveCriticalSection(&This
->cs
);
807 static HRESULT
GetFilterInfo(IMoniker
* pMoniker
, VARIANT
* pvar
)
809 static const WCHAR wszFriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
810 IPropertyBag
* pPropBagCat
= NULL
;
815 hr
= IMoniker_BindToStorage(pMoniker
, NULL
, NULL
, &IID_IPropertyBag
, (LPVOID
*)&pPropBagCat
);
818 hr
= IPropertyBag_Read(pPropBagCat
, wszFriendlyName
, pvar
, NULL
);
821 TRACE("Moniker = %s\n", debugstr_w(V_BSTR(pvar
)));
824 IPropertyBag_Release(pPropBagCat
);
829 static HRESULT
GetInternalConnections(IBaseFilter
* pfilter
, IPin
* pinputpin
, IPin
*** pppins
, ULONG
* pnb
)
834 TRACE("(%p, %p, %p, %p)\n", pfilter
, pinputpin
, pppins
, pnb
);
835 hr
= IPin_QueryInternalConnections(pinputpin
, NULL
, &nb
);
838 } else if (hr
== S_FALSE
) {
839 *pppins
= CoTaskMemAlloc(sizeof(IPin
*)*nb
);
840 hr
= IPin_QueryInternalConnections(pinputpin
, *pppins
, &nb
);
842 WARN("Error (%x)\n", hr
);
844 } else if (hr
== E_NOTIMPL
) {
845 /* Input connected to all outputs */
846 IEnumPins
* penumpins
;
849 TRACE("E_NOTIMPL\n");
850 hr
= IBaseFilter_EnumPins(pfilter
, &penumpins
);
852 WARN("filter Enumpins failed (%x)\n", hr
);
856 /* Count output pins */
857 while(IEnumPins_Next(penumpins
, 1, &ppin
, &nb
) == S_OK
) {
858 PIN_DIRECTION pindir
;
859 IPin_QueryDirection(ppin
, &pindir
);
860 if (pindir
== PINDIR_OUTPUT
)
864 *pppins
= CoTaskMemAlloc(sizeof(IPin
*)*i
);
865 /* Retrieve output pins */
866 IEnumPins_Reset(penumpins
);
868 while(IEnumPins_Next(penumpins
, 1, &ppin
, &nb
) == S_OK
) {
869 PIN_DIRECTION pindir
;
870 IPin_QueryDirection(ppin
, &pindir
);
871 if (pindir
== PINDIR_OUTPUT
)
872 (*pppins
)[i
++] = ppin
;
876 IEnumPins_Release(penumpins
);
879 WARN("Next failed (%x)\n", hr
);
882 } else if (FAILED(hr
)) {
883 WARN("Cannot get internal connection (%x)\n", hr
);
891 /*** IGraphBuilder methods ***/
892 static HRESULT WINAPI
FilterGraph2_Connect(IFilterGraph2
*iface
, IPin
*ppinOut
, IPin
*ppinIn
)
894 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
896 AM_MEDIA_TYPE
* mt
= NULL
;
897 IEnumMediaTypes
* penummt
= NULL
;
899 IEnumPins
* penumpins
;
900 IEnumMoniker
* pEnumMoniker
;
909 IFilterMapper2
*pFilterMapper2
= NULL
;
911 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, ppinOut
, ppinIn
);
913 if(!ppinOut
|| !ppinIn
)
916 if (TRACE_ON(quartz
))
918 hr
= IPin_QueryPinInfo(ppinIn
, &PinInfo
);
922 TRACE("Filter owning first pin => %p\n", PinInfo
.pFilter
);
923 IBaseFilter_Release(PinInfo
.pFilter
);
925 hr
= IPin_QueryPinInfo(ppinOut
, &PinInfo
);
929 TRACE("Filter owning second pin => %p\n", PinInfo
.pFilter
);
930 IBaseFilter_Release(PinInfo
.pFilter
);
933 EnterCriticalSection(&This
->cs
);
934 ++This
->recursioncount
;
935 if (This
->recursioncount
>= 5)
937 WARN("Recursion count has reached %d\n", This
->recursioncount
);
938 hr
= VFW_E_CANNOT_CONNECT
;
942 hr
= IPin_QueryDirection(ppinOut
, &dir
);
946 if (dir
== PINDIR_INPUT
)
955 hr
= CheckCircularConnection(This
, ppinOut
, ppinIn
);
959 /* Try direct connection first */
960 hr
= IPin_Connect(ppinOut
, ppinIn
, NULL
);
964 TRACE("Direct connection failed, trying to render using extra filters\n");
966 hr
= IPin_QueryPinInfo(ppinIn
, &PinInfo
);
970 hr
= IBaseFilter_GetClassID(PinInfo
.pFilter
, &FilterCLSID
);
971 IBaseFilter_Release(PinInfo
.pFilter
);
975 /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
976 * filter to the minor mediatype of input pin of the renderer */
977 hr
= IPin_EnumMediaTypes(ppinOut
, &penummt
);
980 WARN("EnumMediaTypes (%x)\n", hr
);
984 hr
= IEnumMediaTypes_Next(penummt
, 1, &mt
, &nbmt
);
986 WARN("IEnumMediaTypes_Next (%x)\n", hr
);
992 WARN("No media type found!\n");
993 hr
= VFW_E_INVALIDMEDIATYPE
;
996 TRACE("MajorType %s\n", debugstr_guid(&mt
->majortype
));
997 TRACE("SubType %s\n", debugstr_guid(&mt
->subtype
));
999 hr
= IUnknown_QueryInterface(This
->punkFilterMapper2
, &IID_IFilterMapper2
, (void**)&pFilterMapper2
);
1001 WARN("Unable to get IFilterMapper2 (%x)\n", hr
);
1005 /* Try to find a suitable filter that can connect to the pin to render */
1006 tab
[0] = mt
->majortype
;
1007 tab
[1] = mt
->subtype
;
1008 hr
= IFilterMapper2_EnumMatchingFilters(pFilterMapper2
, &pEnumMoniker
, 0, FALSE
, MERIT_UNLIKELY
, TRUE
, 1, tab
, NULL
, NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, NULL
);
1010 WARN("Unable to enum filters (%x)\n", hr
);
1014 hr
= VFW_E_CANNOT_RENDER
;
1015 while(IEnumMoniker_Next(pEnumMoniker
, 1, &pMoniker
, &nb
) == S_OK
)
1019 IPin
** ppins
= NULL
;
1020 IPin
* ppinfilter
= NULL
;
1021 IBaseFilter
* pfilter
= NULL
;
1022 IAMGraphBuilderCallback
*callback
= NULL
;
1024 hr
= GetFilterInfo(pMoniker
, &var
);
1026 WARN("Unable to retrieve filter info (%x)\n", hr
);
1030 hr
= IMoniker_BindToObject(pMoniker
, NULL
, NULL
, &IID_IBaseFilter
, (LPVOID
*)&pfilter
);
1031 IMoniker_Release(pMoniker
);
1033 WARN("Unable to create filter (%x), trying next one\n", hr
);
1037 hr
= IBaseFilter_GetClassID(pfilter
, &clsid
);
1040 IBaseFilter_Release(pfilter
);
1044 if (IsEqualGUID(&clsid
, &FilterCLSID
)) {
1045 /* Skip filter (same as the one the output pin belongs to) */
1046 IBaseFilter_Release(pfilter
);
1052 IUnknown_QueryInterface(This
->pSite
, &IID_IAMGraphBuilderCallback
, (LPVOID
*)&callback
);
1056 rc
= IAMGraphBuilderCallback_SelectedFilter(callback
, pMoniker
);
1059 TRACE("Filter rejected by IAMGraphBuilderCallback_SelectedFilter\n");
1060 IAMGraphBuilderCallback_Release(callback
);
1069 rc
= IAMGraphBuilderCallback_CreatedFilter(callback
, pfilter
);
1070 IAMGraphBuilderCallback_Release(callback
);
1073 IBaseFilter_Release(pfilter
);
1075 TRACE("Filter rejected by IAMGraphBuilderCallback_CreatedFilter\n");
1080 hr
= IFilterGraph2_AddFilter(iface
, pfilter
, V_BSTR(&var
));
1082 WARN("Unable to add filter (%x)\n", hr
);
1083 IBaseFilter_Release(pfilter
);
1090 hr
= IBaseFilter_EnumPins(pfilter
, &penumpins
);
1092 WARN("Enumpins (%x)\n", hr
);
1096 hr
= IEnumPins_Next(penumpins
, 1, &ppinfilter
, &pin
);
1097 IEnumPins_Release(penumpins
);
1100 WARN("Obtaining next pin: (%x)\n", hr
);
1104 WARN("Cannot use this filter: no pins\n");
1108 hr
= IPin_Connect(ppinOut
, ppinfilter
, NULL
);
1110 TRACE("Cannot connect to filter (%x), trying next one\n", hr
);
1113 TRACE("Successfully connected to filter, follow chain...\n");
1115 /* Render all output pins of the filter by calling IFilterGraph2_Connect on each of them */
1116 hr
= GetInternalConnections(pfilter
, ppinfilter
, &ppins
, &nb
);
1118 if (SUCCEEDED(hr
)) {
1120 IPin_Disconnect(ppinfilter
);
1121 IPin_Disconnect(ppinOut
);
1124 TRACE("pins to consider: %d\n", nb
);
1125 for(i
= 0; i
< nb
; i
++)
1127 LPWSTR pinname
= NULL
;
1129 TRACE("Processing pin %u\n", i
);
1131 hr
= IPin_QueryId(ppins
[i
], &pinname
);
1134 if (pinname
[0] == '~')
1136 TRACE("Pinname=%s, skipping\n", debugstr_w(pinname
));
1140 hr
= IFilterGraph2_Connect(iface
, ppins
[i
], ppinIn
);
1141 CoTaskMemFree(pinname
);
1145 TRACE("Cannot connect pin %p (%x)\n", ppinfilter
, hr
);
1147 IPin_Release(ppins
[i
]);
1148 if (SUCCEEDED(hr
)) break;
1150 while (++i
< nb
) IPin_Release(ppins
[i
]);
1151 CoTaskMemFree(ppins
);
1152 IPin_Release(ppinfilter
);
1153 IBaseFilter_Release(pfilter
);
1156 IPin_Disconnect(ppinfilter
);
1157 IPin_Disconnect(ppinOut
);
1158 IFilterGraph2_RemoveFilter(iface
, pfilter
);
1166 if (ppinfilter
) IPin_Release(ppinfilter
);
1168 IFilterGraph2_RemoveFilter(iface
, pfilter
);
1169 IBaseFilter_Release(pfilter
);
1171 while (++i
< nb
) IPin_Release(ppins
[i
]);
1172 CoTaskMemFree(ppins
);
1175 IEnumMoniker_Release(pEnumMoniker
);
1179 IFilterMapper2_Release(pFilterMapper2
);
1181 IEnumMediaTypes_Release(penummt
);
1183 DeleteMediaType(mt
);
1184 --This
->recursioncount
;
1185 LeaveCriticalSection(&This
->cs
);
1186 TRACE("--> %08x\n", hr
);
1187 return SUCCEEDED(hr
) ? S_OK
: hr
;
1190 static HRESULT
FilterGraph2_RenderRecurse(IFilterGraphImpl
*This
, IPin
*ppinOut
)
1192 /* This pin has been connected now, try to call render on all pins that aren't connected */
1195 IEnumPins
*enumpins
= NULL
;
1196 BOOL renderany
= FALSE
;
1197 BOOL renderall
= TRUE
;
1199 IPin_QueryPinInfo(ppinOut
, &info
);
1201 IBaseFilter_EnumPins(info
.pFilter
, &enumpins
);
1202 /* Don't need to hold a reference, IEnumPins does */
1203 IBaseFilter_Release(info
.pFilter
);
1205 IEnumPins_Reset(enumpins
);
1206 while (IEnumPins_Next(enumpins
, 1, &to
, NULL
) == S_OK
)
1208 PIN_DIRECTION dir
= PINDIR_INPUT
;
1210 IPin_QueryDirection(to
, &dir
);
1212 if (dir
== PINDIR_OUTPUT
)
1216 IPin_ConnectedTo(to
, &out
);
1220 hr
= IFilterGraph2_Render(&This
->IFilterGraph2_iface
, to
);
1233 IEnumPins_Release(enumpins
);
1239 return VFW_S_PARTIAL_RENDER
;
1241 return VFW_E_CANNOT_RENDER
;
1244 /* Ogg hates me if I create a direct rendering method
1246 * It can only connect to a pin properly once, so use a recursive method that does
1248 * +----+ --- (PIN 1) (Render is called on this pin)
1250 * +----+ --- (PIN 2)
1252 * Enumerate possible renderers that EXACTLY match the requested type
1254 * If none is available, try to add intermediate filters that can connect to the input pin
1255 * then call Render on that intermediate pin's output pins
1256 * if it succeeds: Render returns success, if it doesn't, the intermediate filter is removed,
1257 * and another filter that can connect to the input pin is tried
1258 * if we run out of filters that can, give up and return VFW_E_CANNOT_RENDER
1259 * It's recursive, but fun!
1262 static HRESULT WINAPI
FilterGraph2_Render(IFilterGraph2
*iface
, IPin
*ppinOut
)
1264 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1265 IEnumMediaTypes
* penummt
;
1270 IEnumMoniker
* pEnumMoniker
;
1275 IFilterMapper2
*pFilterMapper2
= NULL
;
1277 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppinOut
);
1279 if (TRACE_ON(quartz
))
1283 hr
= IPin_QueryPinInfo(ppinOut
, &PinInfo
);
1287 TRACE("Filter owning pin => %p\n", PinInfo
.pFilter
);
1288 IBaseFilter_Release(PinInfo
.pFilter
);
1291 /* Try to find out if there is a renderer for the specified subtype already, and use that
1293 EnterCriticalSection(&This
->cs
);
1294 for (x
= 0; x
< This
->nFilters
; ++x
)
1296 IEnumPins
*enumpins
= NULL
;
1299 hr
= IBaseFilter_EnumPins(This
->ppFiltersInGraph
[x
], &enumpins
);
1301 if (FAILED(hr
) || !enumpins
)
1304 IEnumPins_Reset(enumpins
);
1305 while (IEnumPins_Next(enumpins
, 1, &pin
, NULL
) == S_OK
)
1308 PIN_DIRECTION dir
= PINDIR_OUTPUT
;
1310 IPin_QueryDirection(pin
, &dir
);
1311 if (dir
!= PINDIR_INPUT
)
1316 IPin_ConnectedTo(pin
, &to
);
1320 hr
= FilterGraph2_ConnectDirect(iface
, ppinOut
, pin
, NULL
);
1323 TRACE("Connected successfully %p/%p, %08x look if we should render more!\n", ppinOut
, pin
, hr
);
1326 hr
= FilterGraph2_RenderRecurse(This
, pin
);
1329 IPin_Disconnect(ppinOut
);
1330 IPin_Disconnect(pin
);
1333 IEnumPins_Release(enumpins
);
1334 LeaveCriticalSection(&This
->cs
);
1337 WARN("Could not connect!\n");
1344 IEnumPins_Release(enumpins
);
1347 LeaveCriticalSection(&This
->cs
);
1349 hr
= IPin_EnumMediaTypes(ppinOut
, &penummt
);
1351 WARN("EnumMediaTypes (%x)\n", hr
);
1355 IEnumMediaTypes_Reset(penummt
);
1357 /* Looks like no existing renderer of the kind exists
1358 * Try adding new ones
1360 tab
[0] = tab
[1] = GUID_NULL
;
1361 while (SUCCEEDED(hr
))
1363 hr
= IEnumMediaTypes_Next(penummt
, 1, &mt
, &nbmt
);
1365 WARN("IEnumMediaTypes_Next (%x)\n", hr
);
1370 hr
= VFW_E_CANNOT_RENDER
;
1375 TRACE("MajorType %s\n", debugstr_guid(&mt
->majortype
));
1376 TRACE("SubType %s\n", debugstr_guid(&mt
->subtype
));
1378 /* Only enumerate once, this doesn't account for all previous ones, but this should be enough nonetheless */
1379 if (IsEqualIID(&tab
[0], &mt
->majortype
) && IsEqualIID(&tab
[1], &mt
->subtype
))
1381 DeleteMediaType(mt
);
1385 if (pFilterMapper2
== NULL
)
1387 hr
= IUnknown_QueryInterface(This
->punkFilterMapper2
, &IID_IFilterMapper2
, (void**)&pFilterMapper2
);
1390 WARN("Unable to query IFilterMapper2 (%x)\n", hr
);
1395 /* Try to find a suitable renderer with the same media type */
1396 tab
[0] = mt
->majortype
;
1397 tab
[1] = mt
->subtype
;
1398 hr
= IFilterMapper2_EnumMatchingFilters(pFilterMapper2
, &pEnumMoniker
, 0, FALSE
, MERIT_UNLIKELY
, TRUE
, 1, tab
, NULL
, NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, NULL
);
1401 WARN("Unable to enum filters (%x)\n", hr
);
1407 while (IEnumMoniker_Next(pEnumMoniker
, 1, &pMoniker
, &nb
) == S_OK
)
1411 IBaseFilter
* pfilter
= NULL
;
1412 IEnumPins
* penumpins
= NULL
;
1415 hr
= GetFilterInfo(pMoniker
, &var
);
1417 WARN("Unable to retrieve filter info (%x)\n", hr
);
1421 hr
= IMoniker_BindToObject(pMoniker
, NULL
, NULL
, &IID_IBaseFilter
, (LPVOID
*)&pfilter
);
1422 IMoniker_Release(pMoniker
);
1425 WARN("Unable to create filter (%x), trying next one\n", hr
);
1429 hr
= IFilterGraph2_AddFilter(iface
, pfilter
, V_BSTR(&var
));
1431 WARN("Unable to add filter (%x)\n", hr
);
1432 IBaseFilter_Release(pfilter
);
1437 hr
= IBaseFilter_EnumPins(pfilter
, &penumpins
);
1439 WARN("Splitter Enumpins (%x)\n", hr
);
1443 while ((hr
= IEnumPins_Next(penumpins
, 1, &ppinfilter
, &pin
)) == S_OK
)
1453 hr
= IPin_QueryDirection(ppinfilter
, &dir
);
1455 IPin_Release(ppinfilter
);
1456 WARN("QueryDirection failed (%x)\n", hr
);
1459 if (dir
!= PINDIR_INPUT
) {
1460 IPin_Release(ppinfilter
);
1461 continue; /* Wrong direction */
1464 /* Connect the pin to the "Renderer" */
1465 hr
= IPin_Connect(ppinOut
, ppinfilter
, NULL
);
1466 IPin_Release(ppinfilter
);
1469 WARN("Unable to connect %s to renderer (%x)\n", debugstr_w(V_BSTR(&var
)), hr
);
1472 TRACE("Connected, recursing %s\n", debugstr_w(V_BSTR(&var
)));
1476 hr
= FilterGraph2_RenderRecurse(This
, ppinfilter
);
1478 WARN("Unable to connect recursively (%x)\n", hr
);
1481 IBaseFilter_Release(pfilter
);
1484 if (SUCCEEDED(hr
)) {
1485 IEnumPins_Release(penumpins
);
1486 break; /* out of IEnumMoniker_Next loop */
1489 /* IEnumPins_Next failed, all other failure case caught by goto error */
1490 WARN("IEnumPins_Next (%x)\n", hr
);
1496 IEnumPins_Release(penumpins
);
1498 IFilterGraph2_RemoveFilter(iface
, pfilter
);
1499 IBaseFilter_Release(pfilter
);
1501 if (SUCCEEDED(hr
)) DebugBreak();
1504 IEnumMoniker_Release(pEnumMoniker
);
1506 DeleteMediaType(mt
);
1513 IFilterMapper2_Release(pFilterMapper2
);
1515 IEnumMediaTypes_Release(penummt
);
1519 static HRESULT WINAPI
FilterGraph2_RenderFile(IFilterGraph2
*iface
, LPCWSTR lpcwstrFile
,
1520 LPCWSTR lpcwstrPlayList
)
1522 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1523 static const WCHAR string
[] = {'R','e','a','d','e','r',0};
1524 IBaseFilter
* preader
= NULL
;
1525 IPin
* ppinreader
= NULL
;
1526 IEnumPins
* penumpins
= NULL
;
1528 BOOL partial
= FALSE
;
1531 TRACE("(%p/%p)->(%s, %s)\n", This
, iface
, debugstr_w(lpcwstrFile
), debugstr_w(lpcwstrPlayList
));
1533 if (lpcwstrPlayList
!= NULL
)
1534 return E_INVALIDARG
;
1536 hr
= IFilterGraph2_AddSourceFilter(iface
, lpcwstrFile
, string
, &preader
);
1541 hr
= IBaseFilter_EnumPins(preader
, &penumpins
);
1544 while (IEnumPins_Next(penumpins
, 1, &ppinreader
, NULL
) == S_OK
)
1548 IPin_QueryDirection(ppinreader
, &dir
);
1549 if (dir
== PINDIR_OUTPUT
)
1553 hr
= IFilterGraph2_Render(iface
, ppinreader
);
1554 TRACE("Render %08x\n", hr
);
1556 for (i
= 0; i
< This
->nFilters
; ++i
)
1557 TRACE("Filters in chain: %s\n", debugstr_w(This
->pFilterNames
[i
]));
1564 IPin_Release(ppinreader
);
1566 IEnumPins_Release(penumpins
);
1569 hr
= VFW_E_CANNOT_RENDER
;
1571 hr
= VFW_S_PARTIAL_RENDER
;
1575 IBaseFilter_Release(preader
);
1577 TRACE("--> %08x\n", hr
);
1581 static HRESULT
CreateFilterInstanceAndLoadFile(GUID
* clsid
, LPCOLESTR pszFileName
, IBaseFilter
**filter
)
1583 IFileSourceFilter
*source
= NULL
;
1584 HRESULT hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IBaseFilter
, (LPVOID
*)filter
);
1585 TRACE("CLSID: %s\n", debugstr_guid(clsid
));
1589 hr
= IBaseFilter_QueryInterface(*filter
, &IID_IFileSourceFilter
, (LPVOID
*)&source
);
1592 IBaseFilter_Release(*filter
);
1596 /* Load the file in the file source filter */
1597 hr
= IFileSourceFilter_Load(source
, pszFileName
, NULL
);
1598 IFileSourceFilter_Release(source
);
1600 WARN("Load (%x)\n", hr
);
1601 IBaseFilter_Release(*filter
);
1608 /* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */
1609 static HRESULT
GetFileSourceFilter(LPCOLESTR pszFileName
, IBaseFilter
**filter
)
1613 IAsyncReader
* pReader
= NULL
;
1614 IFileSourceFilter
* pSource
= NULL
;
1615 IPin
* pOutputPin
= NULL
;
1616 static const WCHAR wszOutputPinName
[] = { 'O','u','t','p','u','t',0 };
1618 /* Try to find a match without reading the file first */
1619 hr
= GetClassMediaFile(NULL
, pszFileName
, NULL
, NULL
, &clsid
);
1622 return CreateFilterInstanceAndLoadFile(&clsid
, pszFileName
, filter
);
1624 /* Now create a AyncReader instance, to check for signature bytes in the file */
1625 hr
= CoCreateInstance(&CLSID_AsyncReader
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IBaseFilter
, (LPVOID
*)filter
);
1629 hr
= IBaseFilter_QueryInterface(*filter
, &IID_IFileSourceFilter
, (LPVOID
*)&pSource
);
1632 IBaseFilter_Release(*filter
);
1636 hr
= IFileSourceFilter_Load(pSource
, pszFileName
, NULL
);
1637 IFileSourceFilter_Release(pSource
);
1640 IBaseFilter_Release(*filter
);
1644 hr
= IBaseFilter_FindPin(*filter
, wszOutputPinName
, &pOutputPin
);
1647 IBaseFilter_Release(*filter
);
1651 hr
= IPin_QueryInterface(pOutputPin
, &IID_IAsyncReader
, (LPVOID
*)&pReader
);
1652 IPin_Release(pOutputPin
);
1655 IBaseFilter_Release(*filter
);
1659 /* Try again find a match */
1660 hr
= GetClassMediaFile(pReader
, pszFileName
, NULL
, NULL
, &clsid
);
1661 IAsyncReader_Release(pReader
);
1665 /* Release the AsyncReader filter and create the matching one */
1666 IBaseFilter_Release(*filter
);
1667 return CreateFilterInstanceAndLoadFile(&clsid
, pszFileName
, filter
);
1670 /* Return the AsyncReader filter */
1674 static HRESULT WINAPI
FilterGraph2_AddSourceFilter(IFilterGraph2
*iface
, LPCWSTR lpcwstrFileName
,
1675 LPCWSTR lpcwstrFilterName
, IBaseFilter
**ppFilter
)
1677 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1679 IBaseFilter
* preader
;
1680 IFileSourceFilter
* pfile
= NULL
;
1684 TRACE("(%p/%p)->(%s, %s, %p)\n", This
, iface
, debugstr_w(lpcwstrFileName
), debugstr_w(lpcwstrFilterName
), ppFilter
);
1686 /* Try from file name first, then fall back to default asynchronous reader */
1687 hr
= GetFileSourceFilter(lpcwstrFileName
, &preader
);
1689 WARN("Unable to create file source filter (%x)\n", hr
);
1693 hr
= IFilterGraph2_AddFilter(iface
, preader
, lpcwstrFilterName
);
1695 WARN("Unable add filter (%x)\n", hr
);
1696 IBaseFilter_Release(preader
);
1700 hr
= IBaseFilter_QueryInterface(preader
, &IID_IFileSourceFilter
, (LPVOID
*)&pfile
);
1702 WARN("Unable to get IFileSourceInterface (%x)\n", hr
);
1706 /* The file has been already loaded */
1707 hr
= IFileSourceFilter_GetCurFile(pfile
, &filename
, &mt
);
1709 WARN("GetCurFile (%x)\n", hr
);
1713 TRACE("File %s\n", debugstr_w(filename
));
1714 TRACE("MajorType %s\n", debugstr_guid(&mt
.majortype
));
1715 TRACE("SubType %s\n", debugstr_guid(&mt
.subtype
));
1718 *ppFilter
= preader
;
1719 IFileSourceFilter_Release(pfile
);
1725 IFileSourceFilter_Release(pfile
);
1726 IFilterGraph2_RemoveFilter(iface
, preader
);
1727 IBaseFilter_Release(preader
);
1732 static HRESULT WINAPI
FilterGraph2_SetLogFile(IFilterGraph2
*iface
, DWORD_PTR hFile
)
1734 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1736 TRACE("(%p/%p)->(%08x): stub !!!\n", This
, iface
, (DWORD
) hFile
);
1741 static HRESULT WINAPI
FilterGraph2_Abort(IFilterGraph2
*iface
)
1743 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1745 TRACE("(%p/%p)->(): stub !!!\n", This
, iface
);
1750 static HRESULT WINAPI
FilterGraph2_ShouldOperationContinue(IFilterGraph2
*iface
)
1752 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1754 TRACE("(%p/%p)->(): stub !!!\n", This
, iface
);
1759 /*** IFilterGraph2 methods ***/
1760 static HRESULT WINAPI
FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2
*iface
,
1761 IMoniker
*pMoniker
, IBindCtx
*pCtx
, LPCWSTR lpcwstrFilterName
, IBaseFilter
**ppFilter
)
1763 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1765 IBaseFilter
* pfilter
;
1767 TRACE("(%p/%p)->(%p %p %s %p)\n", This
, iface
, pMoniker
, pCtx
, debugstr_w(lpcwstrFilterName
), ppFilter
);
1769 hr
= IMoniker_BindToObject(pMoniker
, pCtx
, NULL
, &IID_IBaseFilter
, (void**)&pfilter
);
1771 WARN("Unable to bind moniker to filter object (%x)\n", hr
);
1775 hr
= IFilterGraph2_AddFilter(iface
, pfilter
, lpcwstrFilterName
);
1777 WARN("Unable to add filter (%x)\n", hr
);
1778 IBaseFilter_Release(pfilter
);
1783 *ppFilter
= pfilter
;
1784 else IBaseFilter_Release(pfilter
);
1789 static HRESULT WINAPI
FilterGraph2_ReconnectEx(IFilterGraph2
*iface
, IPin
*ppin
,
1790 const AM_MEDIA_TYPE
*pmt
)
1792 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1794 TRACE("(%p/%p)->(%p %p): stub !!!\n", This
, iface
, ppin
, pmt
);
1799 static HRESULT WINAPI
FilterGraph2_RenderEx(IFilterGraph2
*iface
, IPin
*pPinOut
, DWORD dwFlags
,
1802 IFilterGraphImpl
*This
= impl_from_IFilterGraph2(iface
);
1804 TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This
, iface
, pPinOut
, dwFlags
, pvContext
);
1810 static const IFilterGraph2Vtbl IFilterGraph2_VTable
=
1812 FilterGraph2_QueryInterface
,
1813 FilterGraph2_AddRef
,
1814 FilterGraph2_Release
,
1815 FilterGraph2_AddFilter
,
1816 FilterGraph2_RemoveFilter
,
1817 FilterGraph2_EnumFilters
,
1818 FilterGraph2_FindFilterByName
,
1819 FilterGraph2_ConnectDirect
,
1820 FilterGraph2_Reconnect
,
1821 FilterGraph2_Disconnect
,
1822 FilterGraph2_SetDefaultSyncSource
,
1823 FilterGraph2_Connect
,
1824 FilterGraph2_Render
,
1825 FilterGraph2_RenderFile
,
1826 FilterGraph2_AddSourceFilter
,
1827 FilterGraph2_SetLogFile
,
1829 FilterGraph2_ShouldOperationContinue
,
1830 FilterGraph2_AddSourceFilterForMoniker
,
1831 FilterGraph2_ReconnectEx
,
1832 FilterGraph2_RenderEx
1835 static inline IFilterGraphImpl
*impl_from_IMediaControl(IMediaControl
*iface
)
1837 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaControl_iface
);
1840 static HRESULT WINAPI
MediaControl_QueryInterface(IMediaControl
*iface
, REFIID riid
, void **ppvObj
)
1842 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1844 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
1846 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
1849 static ULONG WINAPI
MediaControl_AddRef(IMediaControl
*iface
)
1851 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1853 TRACE("(%p/%p)->()\n", This
, iface
);
1855 return IUnknown_AddRef(This
->outer_unk
);
1858 static ULONG WINAPI
MediaControl_Release(IMediaControl
*iface
)
1860 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1862 TRACE("(%p/%p)->()\n", This
, iface
);
1864 return IUnknown_Release(This
->outer_unk
);
1868 /*** IDispatch methods ***/
1869 static HRESULT WINAPI
MediaControl_GetTypeInfoCount(IMediaControl
*iface
, UINT
*pctinfo
)
1871 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1873 TRACE("(%p/%p)->(%p): stub !!!\n", This
, iface
, pctinfo
);
1878 static HRESULT WINAPI
MediaControl_GetTypeInfo(IMediaControl
*iface
, UINT iTInfo
, LCID lcid
,
1879 ITypeInfo
**ppTInfo
)
1881 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1883 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
1888 static HRESULT WINAPI
MediaControl_GetIDsOfNames(IMediaControl
*iface
, REFIID riid
,
1889 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1891 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1893 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
1898 static HRESULT WINAPI
MediaControl_Invoke(IMediaControl
*iface
, DISPID dispIdMember
, REFIID riid
,
1899 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
,
1902 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
1904 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
);
1909 typedef HRESULT(WINAPI
*fnFoundFilter
)(IBaseFilter
*, DWORD_PTR data
);
1911 static HRESULT
ExploreGraph(IFilterGraphImpl
* pGraph
, IPin
* pOutputPin
, fnFoundFilter FoundFilter
, DWORD_PTR data
)
1920 TRACE("%p %p\n", pGraph
, pOutputPin
);
1921 PinInfo
.pFilter
= NULL
;
1923 hr
= IPin_ConnectedTo(pOutputPin
, &pInputPin
);
1927 hr
= IPin_QueryPinInfo(pInputPin
, &PinInfo
);
1929 hr
= GetInternalConnections(PinInfo
.pFilter
, pInputPin
, &ppPins
, &nb
);
1930 IPin_Release(pInputPin
);
1937 TRACE("Reached a renderer\n");
1938 /* Count renderers for end of stream notification */
1939 pGraph
->nRenderers
++;
1943 for(i
= 0; i
< nb
; i
++)
1945 /* Explore the graph downstream from this pin
1946 * FIXME: We should prevent exploring from a pin more than once. This can happens when
1947 * several input pins are connected to the same output (a MUX for instance). */
1948 ExploreGraph(pGraph
, ppPins
[i
], FoundFilter
, data
);
1949 IPin_Release(ppPins
[i
]);
1952 CoTaskMemFree(ppPins
);
1954 TRACE("Doing stuff with filter %p\n", PinInfo
.pFilter
);
1956 FoundFilter(PinInfo
.pFilter
, data
);
1959 if (PinInfo
.pFilter
) IBaseFilter_Release(PinInfo
.pFilter
);
1963 static HRESULT WINAPI
SendRun(IBaseFilter
*pFilter
, DWORD_PTR data
)
1965 REFERENCE_TIME time
= *(REFERENCE_TIME
*)data
;
1966 return IBaseFilter_Run(pFilter
, time
);
1969 static HRESULT WINAPI
SendPause(IBaseFilter
*pFilter
, DWORD_PTR data
)
1971 return IBaseFilter_Pause(pFilter
);
1974 static HRESULT WINAPI
SendStop(IBaseFilter
*pFilter
, DWORD_PTR data
)
1976 return IBaseFilter_Stop(pFilter
);
1979 static HRESULT WINAPI
SendGetState(IBaseFilter
*pFilter
, DWORD_PTR data
)
1982 DWORD time_end
= data
;
1983 DWORD time_now
= GetTickCount();
1986 if (time_end
== INFINITE
)
1990 else if (time_end
> time_now
)
1992 wait
= time_end
- time_now
;
1997 return IBaseFilter_GetState(pFilter
, wait
, &state
);
2001 static HRESULT
SendFilterMessage(IFilterGraphImpl
*This
, fnFoundFilter FoundFilter
, DWORD_PTR data
)
2004 IBaseFilter
* pfilter
;
2011 TRACE("(%p)->()\n", This
);
2013 /* Explorer the graph from source filters to renderers, determine renderers
2014 * number and run filters from renderers to source filters */
2015 This
->nRenderers
= 0;
2016 ResetEvent(This
->hEventCompletion
);
2018 for(i
= 0; i
< This
->nFilters
; i
++)
2021 pfilter
= This
->ppFiltersInGraph
[i
];
2022 hr
= IBaseFilter_EnumPins(pfilter
, &pEnum
);
2025 WARN("Enum pins failed %x\n", hr
);
2028 /* Check if it is a source filter */
2029 while(IEnumPins_Next(pEnum
, 1, &pPin
, &dummy
) == S_OK
)
2031 IPin_QueryDirection(pPin
, &dir
);
2033 if (dir
== PINDIR_INPUT
)
2041 TRACE("Found a source filter %p\n", pfilter
);
2042 IEnumPins_Reset(pEnum
);
2043 while(IEnumPins_Next(pEnum
, 1, &pPin
, &dummy
) == S_OK
)
2045 /* Explore the graph downstream from this pin */
2046 ExploreGraph(This
, pPin
, FoundFilter
, data
);
2049 FoundFilter(pfilter
, data
);
2051 IEnumPins_Release(pEnum
);
2057 /*** IMediaControl methods ***/
2058 static HRESULT WINAPI
MediaControl_Run(IMediaControl
*iface
)
2060 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2062 TRACE("(%p/%p)->()\n", This
, iface
);
2064 EnterCriticalSection(&This
->cs
);
2065 if (This
->state
== State_Running
)
2067 This
->EcCompleteCount
= 0;
2069 if (This
->defaultclock
&& !This
->refClock
)
2070 IFilterGraph2_SetDefaultSyncSource(&This
->IFilterGraph2_iface
);
2075 IReferenceClock_GetTime(This
->refClock
, &now
);
2076 if (This
->state
== State_Stopped
)
2077 This
->start_time
= now
+ 500000;
2078 else if (This
->pause_time
>= 0)
2079 This
->start_time
+= now
- This
->pause_time
;
2081 This
->start_time
= now
;
2083 else This
->start_time
= 0;
2085 SendFilterMessage(This
, SendRun
, (DWORD_PTR
)&This
->start_time
);
2086 This
->state
= State_Running
;
2088 LeaveCriticalSection(&This
->cs
);
2092 static HRESULT WINAPI
MediaControl_Pause(IMediaControl
*iface
)
2094 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2096 TRACE("(%p/%p)->()\n", This
, iface
);
2098 EnterCriticalSection(&This
->cs
);
2099 if (This
->state
== State_Paused
)
2102 if (This
->state
== State_Running
&& This
->refClock
&& This
->start_time
>= 0)
2103 IReferenceClock_GetTime(This
->refClock
, &This
->pause_time
);
2105 This
->pause_time
= -1;
2107 SendFilterMessage(This
, SendPause
, 0);
2108 This
->state
= State_Paused
;
2110 LeaveCriticalSection(&This
->cs
);
2114 static HRESULT WINAPI
MediaControl_Stop(IMediaControl
*iface
)
2116 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2118 TRACE("(%p/%p)->()\n", This
, iface
);
2120 if (This
->state
== State_Stopped
) return S_OK
;
2122 EnterCriticalSection(&This
->cs
);
2123 if (This
->state
== State_Running
) SendFilterMessage(This
, SendPause
, 0);
2124 SendFilterMessage(This
, SendStop
, 0);
2125 This
->state
= State_Stopped
;
2126 LeaveCriticalSection(&This
->cs
);
2130 static HRESULT WINAPI
MediaControl_GetState(IMediaControl
*iface
, LONG msTimeout
,
2133 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2136 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, msTimeout
, pfs
);
2141 EnterCriticalSection(&This
->cs
);
2146 end
= GetTickCount() + msTimeout
;
2148 else if (msTimeout
< 0)
2157 SendFilterMessage(This
, SendGetState
, end
);
2159 LeaveCriticalSection(&This
->cs
);
2164 static HRESULT WINAPI
MediaControl_RenderFile(IMediaControl
*iface
, BSTR strFilename
)
2166 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2168 TRACE("(%p/%p)->(%s (%p))\n", This
, iface
, debugstr_w(strFilename
), strFilename
);
2170 return IFilterGraph2_RenderFile(&This
->IFilterGraph2_iface
, strFilename
, NULL
);
2173 static HRESULT WINAPI
MediaControl_AddSourceFilter(IMediaControl
*iface
, BSTR strFilename
,
2176 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2178 FIXME("(%p/%p)->(%s (%p), %p): stub !!!\n", This
, iface
, debugstr_w(strFilename
), strFilename
, ppUnk
);
2183 static HRESULT WINAPI
MediaControl_get_FilterCollection(IMediaControl
*iface
, IDispatch
**ppUnk
)
2185 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2187 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, ppUnk
);
2192 static HRESULT WINAPI
MediaControl_get_RegFilterCollection(IMediaControl
*iface
, IDispatch
**ppUnk
)
2194 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2196 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, ppUnk
);
2201 static HRESULT WINAPI
MediaControl_StopWhenReady(IMediaControl
*iface
)
2203 IFilterGraphImpl
*This
= impl_from_IMediaControl(iface
);
2205 FIXME("(%p/%p)->(): stub !!!\n", This
, iface
);
2211 static const IMediaControlVtbl IMediaControl_VTable
=
2213 MediaControl_QueryInterface
,
2214 MediaControl_AddRef
,
2215 MediaControl_Release
,
2216 MediaControl_GetTypeInfoCount
,
2217 MediaControl_GetTypeInfo
,
2218 MediaControl_GetIDsOfNames
,
2219 MediaControl_Invoke
,
2223 MediaControl_GetState
,
2224 MediaControl_RenderFile
,
2225 MediaControl_AddSourceFilter
,
2226 MediaControl_get_FilterCollection
,
2227 MediaControl_get_RegFilterCollection
,
2228 MediaControl_StopWhenReady
2231 static inline IFilterGraphImpl
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
2233 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaSeeking_iface
);
2236 static HRESULT WINAPI
MediaSeeking_QueryInterface(IMediaSeeking
*iface
, REFIID riid
, void **ppvObj
)
2238 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2240 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
2242 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
2245 static ULONG WINAPI
MediaSeeking_AddRef(IMediaSeeking
*iface
)
2247 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2249 TRACE("(%p/%p)->()\n", This
, iface
);
2251 return IUnknown_AddRef(This
->outer_unk
);
2254 static ULONG WINAPI
MediaSeeking_Release(IMediaSeeking
*iface
)
2256 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2258 TRACE("(%p/%p)->()\n", This
, iface
);
2260 return IUnknown_Release(This
->outer_unk
);
2263 typedef HRESULT (WINAPI
*fnFoundSeek
)(IFilterGraphImpl
*This
, IMediaSeeking
*, DWORD_PTR arg
);
2265 static HRESULT
all_renderers_seek(IFilterGraphImpl
*This
, fnFoundSeek FoundSeek
, DWORD_PTR arg
) {
2266 BOOL allnotimpl
= TRUE
;
2268 HRESULT hr
, hr_return
= S_OK
;
2270 TRACE("(%p)->(%p %08lx)\n", This
, FoundSeek
, arg
);
2271 /* Send a message to all renderers, they are responsible for broadcasting it further */
2273 for(i
= 0; i
< This
->nFilters
; i
++)
2275 IMediaSeeking
*seek
= NULL
;
2276 IBaseFilter
* pfilter
= This
->ppFiltersInGraph
[i
];
2277 IAMFilterMiscFlags
*flags
= NULL
;
2279 IBaseFilter_QueryInterface(pfilter
, &IID_IAMFilterMiscFlags
, (void**)&flags
);
2282 filterflags
= IAMFilterMiscFlags_GetMiscFlags(flags
);
2283 IAMFilterMiscFlags_Release(flags
);
2284 if (filterflags
!= AM_FILTER_MISC_FLAGS_IS_RENDERER
)
2287 IBaseFilter_QueryInterface(pfilter
, &IID_IMediaSeeking
, (void**)&seek
);
2290 hr
= FoundSeek(This
, seek
, arg
);
2291 IMediaSeeking_Release(seek
);
2292 if (hr_return
!= E_NOTIMPL
)
2294 if (hr_return
== S_OK
|| (FAILED(hr
) && hr
!= E_NOTIMPL
&& SUCCEEDED(hr_return
)))
2303 static HRESULT WINAPI
FoundCapabilities(IFilterGraphImpl
*This
, IMediaSeeking
*seek
, DWORD_PTR pcaps
)
2308 hr
= IMediaSeeking_GetCapabilities(seek
, &caps
);
2312 /* Only add common capabilities everything supports */
2313 *(DWORD
*)pcaps
&= caps
;
2318 /*** IMediaSeeking methods ***/
2319 static HRESULT WINAPI
MediaSeeking_GetCapabilities(IMediaSeeking
*iface
, DWORD
*pCapabilities
)
2321 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2324 TRACE("(%p/%p)->(%p)\n", This
, iface
, pCapabilities
);
2329 EnterCriticalSection(&This
->cs
);
2330 *pCapabilities
= 0xffffffff;
2332 hr
= all_renderers_seek(This
, FoundCapabilities
, (DWORD_PTR
)pCapabilities
);
2333 LeaveCriticalSection(&This
->cs
);
2338 static HRESULT WINAPI
MediaSeeking_CheckCapabilities(IMediaSeeking
*iface
, DWORD
*pCapabilities
)
2340 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2344 TRACE("(%p/%p)->(%p)\n", This
, iface
, pCapabilities
);
2349 EnterCriticalSection(&This
->cs
);
2350 originalcaps
= *pCapabilities
;
2351 hr
= all_renderers_seek(This
, FoundCapabilities
, (DWORD_PTR
)pCapabilities
);
2352 LeaveCriticalSection(&This
->cs
);
2357 if (!*pCapabilities
)
2359 if (*pCapabilities
!= originalcaps
)
2364 static HRESULT WINAPI
MediaSeeking_IsFormatSupported(IMediaSeeking
*iface
, const GUID
*pFormat
)
2366 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2371 TRACE("(%p/%p)->(%s)\n", This
, iface
, debugstr_guid(pFormat
));
2373 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME
, pFormat
))
2375 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat
));
2382 static HRESULT WINAPI
MediaSeeking_QueryPreferredFormat(IMediaSeeking
*iface
, GUID
*pFormat
)
2384 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2389 FIXME("(%p/%p)->(%p): semi-stub !!!\n", This
, iface
, pFormat
);
2390 memcpy(pFormat
, &TIME_FORMAT_MEDIA_TIME
, sizeof(GUID
));
2395 static HRESULT WINAPI
MediaSeeking_GetTimeFormat(IMediaSeeking
*iface
, GUID
*pFormat
)
2397 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2402 TRACE("(%p/%p)->(%p)\n", This
, iface
, pFormat
);
2403 memcpy(pFormat
, &This
->timeformatseek
, sizeof(GUID
));
2408 static HRESULT WINAPI
MediaSeeking_IsUsingTimeFormat(IMediaSeeking
*iface
, const GUID
*pFormat
)
2410 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2412 TRACE("(%p/%p)->(%p)\n", This
, iface
, pFormat
);
2416 if (memcmp(pFormat
, &This
->timeformatseek
, sizeof(GUID
)))
2422 static HRESULT WINAPI
MediaSeeking_SetTimeFormat(IMediaSeeking
*iface
, const GUID
*pFormat
)
2424 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2429 TRACE("(%p/%p)->(%s)\n", This
, iface
, debugstr_guid(pFormat
));
2431 if (This
->state
!= State_Stopped
)
2432 return VFW_E_WRONG_STATE
;
2434 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME
, pFormat
))
2436 FIXME("Unhandled time format %s\n", debugstr_guid(pFormat
));
2437 return E_INVALIDARG
;
2443 static HRESULT WINAPI
FoundDuration(IFilterGraphImpl
*This
, IMediaSeeking
*seek
, DWORD_PTR pduration
)
2446 LONGLONG duration
= 0, *pdur
= (LONGLONG
*)pduration
;
2448 hr
= IMediaSeeking_GetDuration(seek
, &duration
);
2452 if (*pdur
< duration
)
2457 static HRESULT WINAPI
MediaSeeking_GetDuration(IMediaSeeking
*iface
, LONGLONG
*pDuration
)
2459 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2462 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDuration
);
2467 EnterCriticalSection(&This
->cs
);
2469 hr
= all_renderers_seek(This
, FoundDuration
, (DWORD_PTR
)pDuration
);
2470 LeaveCriticalSection(&This
->cs
);
2472 TRACE("--->%08x\n", hr
);
2476 static HRESULT WINAPI
MediaSeeking_GetStopPosition(IMediaSeeking
*iface
, LONGLONG
*pStop
)
2478 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2481 TRACE("(%p/%p)->(%p)\n", This
, iface
, pStop
);
2486 EnterCriticalSection(&This
->cs
);
2487 if (This
->stop_position
< 0)
2488 /* Stop position not set, use duration instead */
2489 hr
= IMediaSeeking_GetDuration(iface
, pStop
);
2491 *pStop
= This
->stop_position
;
2492 LeaveCriticalSection(&This
->cs
);
2497 static HRESULT WINAPI
MediaSeeking_GetCurrentPosition(IMediaSeeking
*iface
, LONGLONG
*pCurrent
)
2499 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2505 EnterCriticalSection(&This
->cs
);
2506 if (This
->state
== State_Running
&& This
->refClock
&& This
->start_time
>= 0)
2508 IReferenceClock_GetTime(This
->refClock
, &time
);
2510 time
-= This
->start_time
;
2512 if (This
->pause_time
> 0)
2513 time
+= This
->pause_time
;
2515 LeaveCriticalSection(&This
->cs
);
2517 TRACE("Time: %u.%03u\n", (DWORD
)(*pCurrent
/ 10000000), (DWORD
)((*pCurrent
/ 10000)%1000));
2522 static HRESULT WINAPI
MediaSeeking_ConvertTimeFormat(IMediaSeeking
*iface
, LONGLONG
*pTarget
,
2523 const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
)
2525 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2527 TRACE("(%p/%p)->(%p, %s, 0x%s, %s)\n", This
, iface
, pTarget
,
2528 debugstr_guid(pTargetFormat
), wine_dbgstr_longlong(Source
), debugstr_guid(pSourceFormat
));
2531 pSourceFormat
= &This
->timeformatseek
;
2534 pTargetFormat
= &This
->timeformatseek
;
2536 if (IsEqualGUID(pTargetFormat
, pSourceFormat
))
2539 FIXME("conversion %s->%s not supported\n", debugstr_guid(pSourceFormat
), debugstr_guid(pTargetFormat
));
2545 LONGLONG
* current
, *stop
;
2546 DWORD curflags
, stopflags
;
2549 static HRESULT WINAPI
found_setposition(IFilterGraphImpl
*This
, IMediaSeeking
*seek
, DWORD_PTR pargs
)
2551 struct pos_args
*args
= (void*)pargs
;
2553 return IMediaSeeking_SetPositions(seek
, args
->current
, args
->curflags
, args
->stop
, args
->stopflags
);
2556 static HRESULT WINAPI
MediaSeeking_SetPositions(IMediaSeeking
*iface
, LONGLONG
*pCurrent
,
2557 DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
)
2559 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2562 struct pos_args args
;
2564 TRACE("(%p/%p)->(%p, %08x, %p, %08x)\n", This
, iface
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
2566 EnterCriticalSection(&This
->cs
);
2567 state
= This
->state
;
2568 TRACE("State: %s\n", state
== State_Running
? "Running" : (state
== State_Paused
? "Paused" : (state
== State_Stopped
? "Stopped" : "UNKNOWN")));
2570 if ((dwCurrentFlags
& 0x7) != AM_SEEKING_AbsolutePositioning
&&
2571 (dwCurrentFlags
& 0x7) != AM_SEEKING_NoPositioning
)
2572 FIXME("Adjust method %x not handled yet!\n", dwCurrentFlags
& 0x7);
2574 if ((dwStopFlags
& 0x7) == AM_SEEKING_AbsolutePositioning
)
2575 This
->stop_position
= *pStop
;
2576 else if ((dwStopFlags
& 0x7) != AM_SEEKING_NoPositioning
)
2577 FIXME("Stop position not handled yet!\n");
2579 if (state
== State_Running
&& !(dwCurrentFlags
& AM_SEEKING_NoFlush
))
2580 IMediaControl_Pause(&This
->IMediaControl_iface
);
2581 args
.current
= pCurrent
;
2583 args
.curflags
= dwCurrentFlags
;
2584 args
.stopflags
= dwStopFlags
;
2585 hr
= all_renderers_seek(This
, found_setposition
, (DWORD_PTR
)&args
);
2587 if ((dwCurrentFlags
& 0x7) != AM_SEEKING_NoPositioning
)
2588 This
->pause_time
= This
->start_time
= -1;
2589 if (state
== State_Running
&& !(dwCurrentFlags
& AM_SEEKING_NoFlush
))
2590 IMediaControl_Run(&This
->IMediaControl_iface
);
2591 LeaveCriticalSection(&This
->cs
);
2596 static HRESULT WINAPI
MediaSeeking_GetPositions(IMediaSeeking
*iface
, LONGLONG
*pCurrent
,
2599 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2602 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pCurrent
, pStop
);
2603 hr
= IMediaSeeking_GetCurrentPosition(iface
, pCurrent
);
2605 hr
= IMediaSeeking_GetStopPosition(iface
, pStop
);
2610 static HRESULT WINAPI
MediaSeeking_GetAvailable(IMediaSeeking
*iface
, LONGLONG
*pEarliest
,
2613 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2615 FIXME("(%p/%p)->(%p, %p): stub !!!\n", This
, iface
, pEarliest
, pLatest
);
2620 static HRESULT WINAPI
MediaSeeking_SetRate(IMediaSeeking
*iface
, double dRate
)
2622 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2624 FIXME("(%p/%p)->(%f): stub !!!\n", This
, iface
, dRate
);
2629 static HRESULT WINAPI
MediaSeeking_GetRate(IMediaSeeking
*iface
, double *pdRate
)
2631 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2633 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pdRate
);
2643 static HRESULT WINAPI
MediaSeeking_GetPreroll(IMediaSeeking
*iface
, LONGLONG
*pllPreroll
)
2645 IFilterGraphImpl
*This
= impl_from_IMediaSeeking(iface
);
2647 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pllPreroll
);
2653 static const IMediaSeekingVtbl IMediaSeeking_VTable
=
2655 MediaSeeking_QueryInterface
,
2656 MediaSeeking_AddRef
,
2657 MediaSeeking_Release
,
2658 MediaSeeking_GetCapabilities
,
2659 MediaSeeking_CheckCapabilities
,
2660 MediaSeeking_IsFormatSupported
,
2661 MediaSeeking_QueryPreferredFormat
,
2662 MediaSeeking_GetTimeFormat
,
2663 MediaSeeking_IsUsingTimeFormat
,
2664 MediaSeeking_SetTimeFormat
,
2665 MediaSeeking_GetDuration
,
2666 MediaSeeking_GetStopPosition
,
2667 MediaSeeking_GetCurrentPosition
,
2668 MediaSeeking_ConvertTimeFormat
,
2669 MediaSeeking_SetPositions
,
2670 MediaSeeking_GetPositions
,
2671 MediaSeeking_GetAvailable
,
2672 MediaSeeking_SetRate
,
2673 MediaSeeking_GetRate
,
2674 MediaSeeking_GetPreroll
2677 static inline IFilterGraphImpl
*impl_from_IMediaPosition(IMediaPosition
*iface
)
2679 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaPosition_iface
);
2682 /*** IUnknown methods ***/
2683 static HRESULT WINAPI
MediaPosition_QueryInterface(IMediaPosition
* iface
, REFIID riid
, void** ppvObj
)
2685 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2687 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
2689 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
2692 static ULONG WINAPI
MediaPosition_AddRef(IMediaPosition
*iface
)
2694 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2696 TRACE("(%p/%p)->()\n", This
, iface
);
2698 return IUnknown_AddRef(This
->outer_unk
);
2701 static ULONG WINAPI
MediaPosition_Release(IMediaPosition
*iface
)
2703 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2705 TRACE("(%p/%p)->()\n", This
, iface
);
2707 return IUnknown_Release(This
->outer_unk
);
2710 /*** IDispatch methods ***/
2711 static HRESULT WINAPI
MediaPosition_GetTypeInfoCount(IMediaPosition
*iface
, UINT
* pctinfo
)
2713 FIXME("(%p) stub!\n", iface
);
2717 static HRESULT WINAPI
MediaPosition_GetTypeInfo(IMediaPosition
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
2719 FIXME("(%p) stub!\n", iface
);
2723 static HRESULT WINAPI
MediaPosition_GetIDsOfNames(IMediaPosition
* iface
, REFIID riid
, LPOLESTR
* rgszNames
, UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
2725 FIXME("(%p) stub!\n", iface
);
2729 static HRESULT WINAPI
MediaPosition_Invoke(IMediaPosition
* iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
, EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
2731 FIXME("(%p) stub!\n", iface
);
2735 static HRESULT
ConvertFromREFTIME(IMediaSeeking
*seek
, REFTIME time_in
, LONGLONG
*time_out
)
2740 hr
= MediaSeeking_GetTimeFormat(seek
, &time_format
);
2743 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME
, &time_format
))
2745 FIXME("Unsupported time format.\n");
2749 *time_out
= (LONGLONG
) (time_in
* 10000000); /* convert from 1 second intervals to 100 ns intervals */
2753 static HRESULT
ConvertToREFTIME(IMediaSeeking
*seek
, LONGLONG time_in
, REFTIME
*time_out
)
2758 hr
= MediaSeeking_GetTimeFormat(seek
, &time_format
);
2761 if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME
, &time_format
))
2763 FIXME("Unsupported time format.\n");
2767 *time_out
= (REFTIME
)time_in
/ 10000000; /* convert from 100 ns intervals to 1 second intervals */
2771 /*** IMediaPosition methods ***/
2772 static HRESULT WINAPI
MediaPosition_get_Duration(IMediaPosition
* iface
, REFTIME
*plength
)
2775 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2776 HRESULT hr
= IMediaSeeking_GetDuration(&This
->IMediaSeeking_iface
, &duration
);
2779 return ConvertToREFTIME(&This
->IMediaSeeking_iface
, duration
, plength
);
2782 static HRESULT WINAPI
MediaPosition_put_CurrentPosition(IMediaPosition
* iface
, REFTIME llTime
)
2784 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2788 hr
= ConvertFromREFTIME(&This
->IMediaSeeking_iface
, llTime
, &reftime
);
2791 return IMediaSeeking_SetPositions(&This
->IMediaSeeking_iface
, &reftime
,
2792 AM_SEEKING_AbsolutePositioning
, NULL
, AM_SEEKING_NoPositioning
);
2795 static HRESULT WINAPI
MediaPosition_get_CurrentPosition(IMediaPosition
* iface
, REFTIME
*pllTime
)
2797 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2801 hr
= IMediaSeeking_GetCurrentPosition(&This
->IMediaSeeking_iface
, &pos
);
2804 return ConvertToREFTIME(&This
->IMediaSeeking_iface
, pos
, pllTime
);
2807 static HRESULT WINAPI
MediaPosition_get_StopTime(IMediaPosition
* iface
, REFTIME
*pllTime
)
2809 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2811 HRESULT hr
= IMediaSeeking_GetStopPosition(&This
->IMediaSeeking_iface
, &pos
);
2814 return ConvertToREFTIME(&This
->IMediaSeeking_iface
, pos
, pllTime
);
2817 static HRESULT WINAPI
MediaPosition_put_StopTime(IMediaPosition
* iface
, REFTIME llTime
)
2819 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2823 hr
= ConvertFromREFTIME(&This
->IMediaSeeking_iface
, llTime
, &reftime
);
2826 return IMediaSeeking_SetPositions(&This
->IMediaSeeking_iface
, NULL
, AM_SEEKING_NoPositioning
,
2827 &reftime
, AM_SEEKING_AbsolutePositioning
);
2830 static HRESULT WINAPI
MediaPosition_get_PrerollTime(IMediaPosition
* iface
, REFTIME
*pllTime
)
2832 FIXME("(%p)->(%p) stub!\n", iface
, pllTime
);
2836 static HRESULT WINAPI
MediaPosition_put_PrerollTime(IMediaPosition
* iface
, REFTIME llTime
)
2838 FIXME("(%p)->(%f) stub!\n", iface
, llTime
);
2842 static HRESULT WINAPI
MediaPosition_put_Rate(IMediaPosition
* iface
, double dRate
)
2844 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2845 return IMediaSeeking_SetRate(&This
->IMediaSeeking_iface
, dRate
);
2848 static HRESULT WINAPI
MediaPosition_get_Rate(IMediaPosition
* iface
, double *pdRate
)
2850 IFilterGraphImpl
*This
= impl_from_IMediaPosition( iface
);
2851 return IMediaSeeking_GetRate(&This
->IMediaSeeking_iface
, pdRate
);
2854 static HRESULT WINAPI
MediaPosition_CanSeekForward(IMediaPosition
* iface
, LONG
*pCanSeekForward
)
2856 FIXME("(%p)->(%p) stub!\n", iface
, pCanSeekForward
);
2860 static HRESULT WINAPI
MediaPosition_CanSeekBackward(IMediaPosition
* iface
, LONG
*pCanSeekBackward
)
2862 FIXME("(%p)->(%p) stub!\n", iface
, pCanSeekBackward
);
2867 static const IMediaPositionVtbl IMediaPosition_VTable
=
2869 MediaPosition_QueryInterface
,
2870 MediaPosition_AddRef
,
2871 MediaPosition_Release
,
2872 MediaPosition_GetTypeInfoCount
,
2873 MediaPosition_GetTypeInfo
,
2874 MediaPosition_GetIDsOfNames
,
2875 MediaPosition_Invoke
,
2876 MediaPosition_get_Duration
,
2877 MediaPosition_put_CurrentPosition
,
2878 MediaPosition_get_CurrentPosition
,
2879 MediaPosition_get_StopTime
,
2880 MediaPosition_put_StopTime
,
2881 MediaPosition_get_PrerollTime
,
2882 MediaPosition_put_PrerollTime
,
2883 MediaPosition_put_Rate
,
2884 MediaPosition_get_Rate
,
2885 MediaPosition_CanSeekForward
,
2886 MediaPosition_CanSeekBackward
2889 static inline IFilterGraphImpl
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
2891 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IObjectWithSite_iface
);
2894 /*** IUnknown methods ***/
2895 static HRESULT WINAPI
ObjectWithSite_QueryInterface(IObjectWithSite
* iface
, REFIID riid
, void** ppvObj
)
2897 IFilterGraphImpl
*This
= impl_from_IObjectWithSite( iface
);
2899 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
2901 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
2904 static ULONG WINAPI
ObjectWithSite_AddRef(IObjectWithSite
*iface
)
2906 IFilterGraphImpl
*This
= impl_from_IObjectWithSite( iface
);
2908 TRACE("(%p/%p)->()\n", This
, iface
);
2910 return IUnknown_AddRef(This
->outer_unk
);
2913 static ULONG WINAPI
ObjectWithSite_Release(IObjectWithSite
*iface
)
2915 IFilterGraphImpl
*This
= impl_from_IObjectWithSite( iface
);
2917 TRACE("(%p/%p)->()\n", This
, iface
);
2919 return IUnknown_Release(This
->outer_unk
);
2922 /*** IObjectWithSite methods ***/
2924 static HRESULT WINAPI
ObjectWithSite_SetSite(IObjectWithSite
*iface
, IUnknown
*pUnkSite
)
2926 IFilterGraphImpl
*This
= impl_from_IObjectWithSite( iface
);
2928 TRACE("(%p/%p)->()\n", This
, iface
);
2929 if (This
->pSite
) IUnknown_Release(This
->pSite
);
2930 This
->pSite
= pUnkSite
;
2931 IUnknown_AddRef(This
->pSite
);
2935 static HRESULT WINAPI
ObjectWithSite_GetSite(IObjectWithSite
*iface
, REFIID riid
, PVOID
*ppvSite
)
2937 IFilterGraphImpl
*This
= impl_from_IObjectWithSite( iface
);
2939 TRACE("(%p/%p)->(%s)\n", This
, iface
,debugstr_guid(riid
));
2945 return IUnknown_QueryInterface(This
->pSite
, riid
, ppvSite
);
2948 static const IObjectWithSiteVtbl IObjectWithSite_VTable
=
2950 ObjectWithSite_QueryInterface
,
2951 ObjectWithSite_AddRef
,
2952 ObjectWithSite_Release
,
2953 ObjectWithSite_SetSite
,
2954 ObjectWithSite_GetSite
,
2957 static HRESULT
GetTargetInterface(IFilterGraphImpl
* pGraph
, REFIID riid
, LPVOID
* ppvObj
)
2959 HRESULT hr
= E_NOINTERFACE
;
2963 /* Check if the interface type is already registered */
2964 for (entry
= 0; entry
< pGraph
->nItfCacheEntries
; entry
++)
2965 if (riid
== pGraph
->ItfCacheEntries
[entry
].riid
)
2967 if (pGraph
->ItfCacheEntries
[entry
].iface
)
2969 /* Return the interface if available */
2970 *ppvObj
= pGraph
->ItfCacheEntries
[entry
].iface
;
2976 if (entry
>= MAX_ITF_CACHE_ENTRIES
)
2978 FIXME("Not enough space to store interface in the cache\n");
2979 return E_OUTOFMEMORY
;
2982 /* Find a filter supporting the requested interface */
2983 for (i
= 0; i
< pGraph
->nFilters
; i
++)
2985 hr
= IBaseFilter_QueryInterface(pGraph
->ppFiltersInGraph
[i
], riid
, ppvObj
);
2988 pGraph
->ItfCacheEntries
[entry
].riid
= riid
;
2989 pGraph
->ItfCacheEntries
[entry
].filter
= pGraph
->ppFiltersInGraph
[i
];
2990 pGraph
->ItfCacheEntries
[entry
].iface
= *ppvObj
;
2991 if (entry
>= pGraph
->nItfCacheEntries
)
2992 pGraph
->nItfCacheEntries
++;
2995 if (hr
!= E_NOINTERFACE
)
3002 static inline IFilterGraphImpl
*impl_from_IBasicAudio(IBasicAudio
*iface
)
3004 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IBasicAudio_iface
);
3007 static HRESULT WINAPI
BasicAudio_QueryInterface(IBasicAudio
*iface
, REFIID riid
, void **ppvObj
)
3009 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3011 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
3013 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
3016 static ULONG WINAPI
BasicAudio_AddRef(IBasicAudio
*iface
)
3018 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3020 TRACE("(%p/%p)->()\n", This
, iface
);
3022 return IUnknown_AddRef(This
->outer_unk
);
3025 static ULONG WINAPI
BasicAudio_Release(IBasicAudio
*iface
)
3027 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3029 TRACE("(%p/%p)->()\n", This
, iface
);
3031 return IUnknown_Release(This
->outer_unk
);
3034 /*** IDispatch methods ***/
3035 static HRESULT WINAPI
BasicAudio_GetTypeInfoCount(IBasicAudio
*iface
, UINT
*pctinfo
)
3037 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3038 IBasicAudio
* pBasicAudio
;
3041 TRACE("(%p/%p)->(%p)\n", This
, iface
, pctinfo
);
3043 EnterCriticalSection(&This
->cs
);
3045 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3048 hr
= IBasicAudio_GetTypeInfoCount(pBasicAudio
, pctinfo
);
3050 LeaveCriticalSection(&This
->cs
);
3055 static HRESULT WINAPI
BasicAudio_GetTypeInfo(IBasicAudio
*iface
, UINT iTInfo
, LCID lcid
,
3056 ITypeInfo
**ppTInfo
)
3058 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3059 IBasicAudio
* pBasicAudio
;
3062 TRACE("(%p/%p)->(%d, %d, %p)\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
3064 EnterCriticalSection(&This
->cs
);
3066 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3069 hr
= IBasicAudio_GetTypeInfo(pBasicAudio
, iTInfo
, lcid
, ppTInfo
);
3071 LeaveCriticalSection(&This
->cs
);
3076 static HRESULT WINAPI
BasicAudio_GetIDsOfNames(IBasicAudio
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
3077 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3079 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3080 IBasicAudio
* pBasicAudio
;
3083 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3085 EnterCriticalSection(&This
->cs
);
3087 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3090 hr
= IBasicAudio_GetIDsOfNames(pBasicAudio
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3092 LeaveCriticalSection(&This
->cs
);
3097 static HRESULT WINAPI
BasicAudio_Invoke(IBasicAudio
*iface
, DISPID dispIdMember
, REFIID riid
,
3098 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
,
3101 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3102 IBasicAudio
* pBasicAudio
;
3105 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
);
3107 EnterCriticalSection(&This
->cs
);
3109 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3112 hr
= IBasicAudio_Invoke(pBasicAudio
, dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
3114 LeaveCriticalSection(&This
->cs
);
3119 /*** IBasicAudio methods ***/
3120 static HRESULT WINAPI
BasicAudio_put_Volume(IBasicAudio
*iface
, LONG lVolume
)
3122 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3123 IBasicAudio
* pBasicAudio
;
3126 TRACE("(%p/%p)->(%d)\n", This
, iface
, lVolume
);
3128 EnterCriticalSection(&This
->cs
);
3130 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3133 hr
= IBasicAudio_put_Volume(pBasicAudio
, lVolume
);
3135 LeaveCriticalSection(&This
->cs
);
3140 static HRESULT WINAPI
BasicAudio_get_Volume(IBasicAudio
*iface
, LONG
*plVolume
)
3142 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3143 IBasicAudio
* pBasicAudio
;
3146 TRACE("(%p/%p)->(%p)\n", This
, iface
, plVolume
);
3148 EnterCriticalSection(&This
->cs
);
3150 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3153 hr
= IBasicAudio_get_Volume(pBasicAudio
, plVolume
);
3155 LeaveCriticalSection(&This
->cs
);
3160 static HRESULT WINAPI
BasicAudio_put_Balance(IBasicAudio
*iface
, LONG lBalance
)
3162 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3163 IBasicAudio
* pBasicAudio
;
3166 TRACE("(%p/%p)->(%d)\n", This
, iface
, lBalance
);
3168 EnterCriticalSection(&This
->cs
);
3170 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3173 hr
= IBasicAudio_put_Balance(pBasicAudio
, lBalance
);
3175 LeaveCriticalSection(&This
->cs
);
3180 static HRESULT WINAPI
BasicAudio_get_Balance(IBasicAudio
*iface
, LONG
*plBalance
)
3182 IFilterGraphImpl
*This
= impl_from_IBasicAudio(iface
);
3183 IBasicAudio
* pBasicAudio
;
3186 TRACE("(%p/%p)->(%p)\n", This
, iface
, plBalance
);
3188 EnterCriticalSection(&This
->cs
);
3190 hr
= GetTargetInterface(This
, &IID_IBasicAudio
, (LPVOID
*)&pBasicAudio
);
3193 hr
= IBasicAudio_get_Balance(pBasicAudio
, plBalance
);
3195 LeaveCriticalSection(&This
->cs
);
3200 static const IBasicAudioVtbl IBasicAudio_VTable
=
3202 BasicAudio_QueryInterface
,
3205 BasicAudio_GetTypeInfoCount
,
3206 BasicAudio_GetTypeInfo
,
3207 BasicAudio_GetIDsOfNames
,
3209 BasicAudio_put_Volume
,
3210 BasicAudio_get_Volume
,
3211 BasicAudio_put_Balance
,
3212 BasicAudio_get_Balance
3215 static inline IFilterGraphImpl
*impl_from_IBasicVideo2(IBasicVideo2
*iface
)
3217 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IBasicVideo2_iface
);
3220 static HRESULT WINAPI
BasicVideo_QueryInterface(IBasicVideo2
*iface
, REFIID riid
, void **ppvObj
)
3222 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3224 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
3226 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
3229 static ULONG WINAPI
BasicVideo_AddRef(IBasicVideo2
*iface
)
3231 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3233 TRACE("(%p/%p)->()\n", This
, iface
);
3235 return IUnknown_AddRef(This
->outer_unk
);
3238 static ULONG WINAPI
BasicVideo_Release(IBasicVideo2
*iface
)
3240 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3242 TRACE("(%p/%p)->()\n", This
, iface
);
3244 return IUnknown_Release(This
->outer_unk
);
3247 /*** IDispatch methods ***/
3248 static HRESULT WINAPI
BasicVideo_GetTypeInfoCount(IBasicVideo2
*iface
, UINT
*pctinfo
)
3250 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3251 IBasicVideo
*pBasicVideo
;
3254 TRACE("(%p/%p)->(%p)\n", This
, iface
, pctinfo
);
3256 EnterCriticalSection(&This
->cs
);
3258 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3261 hr
= IBasicVideo_GetTypeInfoCount(pBasicVideo
, pctinfo
);
3263 LeaveCriticalSection(&This
->cs
);
3268 static HRESULT WINAPI
BasicVideo_GetTypeInfo(IBasicVideo2
*iface
, UINT iTInfo
, LCID lcid
,
3269 ITypeInfo
**ppTInfo
)
3271 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3272 IBasicVideo
*pBasicVideo
;
3275 TRACE("(%p/%p)->(%d, %d, %p)\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
3277 EnterCriticalSection(&This
->cs
);
3279 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3282 hr
= IBasicVideo_GetTypeInfo(pBasicVideo
, iTInfo
, lcid
, ppTInfo
);
3284 LeaveCriticalSection(&This
->cs
);
3289 static HRESULT WINAPI
BasicVideo_GetIDsOfNames(IBasicVideo2
*iface
, REFIID riid
,
3290 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3292 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3293 IBasicVideo
*pBasicVideo
;
3296 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3298 EnterCriticalSection(&This
->cs
);
3300 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3303 hr
= IBasicVideo_GetIDsOfNames(pBasicVideo
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
3305 LeaveCriticalSection(&This
->cs
);
3310 static HRESULT WINAPI
BasicVideo_Invoke(IBasicVideo2
*iface
, DISPID dispIdMember
, REFIID riid
,
3311 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
,
3314 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3315 IBasicVideo
*pBasicVideo
;
3318 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
);
3320 EnterCriticalSection(&This
->cs
);
3322 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3325 hr
= IBasicVideo_Invoke(pBasicVideo
, dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
3327 LeaveCriticalSection(&This
->cs
);
3332 /*** IBasicVideo methods ***/
3333 static HRESULT WINAPI
BasicVideo_get_AvgTimePerFrame(IBasicVideo2
*iface
, REFTIME
*pAvgTimePerFrame
)
3335 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3336 IBasicVideo
*pBasicVideo
;
3339 TRACE("(%p/%p)->(%p)\n", This
, iface
, pAvgTimePerFrame
);
3341 EnterCriticalSection(&This
->cs
);
3343 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3346 hr
= IBasicVideo_get_AvgTimePerFrame(pBasicVideo
, pAvgTimePerFrame
);
3348 LeaveCriticalSection(&This
->cs
);
3353 static HRESULT WINAPI
BasicVideo_get_BitRate(IBasicVideo2
*iface
, LONG
*pBitRate
)
3355 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3356 IBasicVideo
*pBasicVideo
;
3359 TRACE("(%p/%p)->(%p)\n", This
, iface
, pBitRate
);
3361 EnterCriticalSection(&This
->cs
);
3363 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3366 hr
= IBasicVideo_get_BitRate(pBasicVideo
, pBitRate
);
3368 LeaveCriticalSection(&This
->cs
);
3373 static HRESULT WINAPI
BasicVideo_get_BitErrorRate(IBasicVideo2
*iface
, LONG
*pBitErrorRate
)
3375 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3376 IBasicVideo
*pBasicVideo
;
3379 TRACE("(%p/%p)->(%p)\n", This
, iface
, pBitErrorRate
);
3381 EnterCriticalSection(&This
->cs
);
3383 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3386 hr
= IBasicVideo_get_BitErrorRate(pBasicVideo
, pBitErrorRate
);
3388 LeaveCriticalSection(&This
->cs
);
3393 static HRESULT WINAPI
BasicVideo_get_VideoWidth(IBasicVideo2
*iface
, LONG
*pVideoWidth
)
3395 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3396 IBasicVideo
*pBasicVideo
;
3399 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVideoWidth
);
3401 EnterCriticalSection(&This
->cs
);
3403 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3406 hr
= IBasicVideo_get_VideoWidth(pBasicVideo
, pVideoWidth
);
3408 LeaveCriticalSection(&This
->cs
);
3413 static HRESULT WINAPI
BasicVideo_get_VideoHeight(IBasicVideo2
*iface
, LONG
*pVideoHeight
)
3415 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3416 IBasicVideo
*pBasicVideo
;
3419 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVideoHeight
);
3421 EnterCriticalSection(&This
->cs
);
3423 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3426 hr
= IBasicVideo_get_VideoHeight(pBasicVideo
, pVideoHeight
);
3428 LeaveCriticalSection(&This
->cs
);
3433 static HRESULT WINAPI
BasicVideo_put_SourceLeft(IBasicVideo2
*iface
, LONG SourceLeft
)
3435 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3436 IBasicVideo
*pBasicVideo
;
3439 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceLeft
);
3441 EnterCriticalSection(&This
->cs
);
3443 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3446 hr
= IBasicVideo_put_SourceLeft(pBasicVideo
, SourceLeft
);
3448 LeaveCriticalSection(&This
->cs
);
3453 static HRESULT WINAPI
BasicVideo_get_SourceLeft(IBasicVideo2
*iface
, LONG
*pSourceLeft
)
3455 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3456 IBasicVideo
*pBasicVideo
;
3459 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceLeft
);
3461 EnterCriticalSection(&This
->cs
);
3463 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3466 hr
= IBasicVideo_get_SourceLeft(pBasicVideo
, pSourceLeft
);
3468 LeaveCriticalSection(&This
->cs
);
3473 static HRESULT WINAPI
BasicVideo_put_SourceWidth(IBasicVideo2
*iface
, LONG SourceWidth
)
3475 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3476 IBasicVideo
*pBasicVideo
;
3479 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceWidth
);
3481 EnterCriticalSection(&This
->cs
);
3483 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3486 hr
= IBasicVideo_put_SourceWidth(pBasicVideo
, SourceWidth
);
3488 LeaveCriticalSection(&This
->cs
);
3493 static HRESULT WINAPI
BasicVideo_get_SourceWidth(IBasicVideo2
*iface
, LONG
*pSourceWidth
)
3495 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3496 IBasicVideo
*pBasicVideo
;
3499 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceWidth
);
3501 EnterCriticalSection(&This
->cs
);
3503 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3506 hr
= IBasicVideo_get_SourceWidth(pBasicVideo
, pSourceWidth
);
3508 LeaveCriticalSection(&This
->cs
);
3513 static HRESULT WINAPI
BasicVideo_put_SourceTop(IBasicVideo2
*iface
, LONG SourceTop
)
3515 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3516 IBasicVideo
*pBasicVideo
;
3519 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceTop
);
3521 EnterCriticalSection(&This
->cs
);
3523 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3526 hr
= IBasicVideo_put_SourceTop(pBasicVideo
, SourceTop
);
3528 LeaveCriticalSection(&This
->cs
);
3533 static HRESULT WINAPI
BasicVideo_get_SourceTop(IBasicVideo2
*iface
, LONG
*pSourceTop
)
3535 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3536 IBasicVideo
*pBasicVideo
;
3539 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceTop
);
3541 EnterCriticalSection(&This
->cs
);
3543 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3546 hr
= IBasicVideo_get_SourceTop(pBasicVideo
, pSourceTop
);
3548 LeaveCriticalSection(&This
->cs
);
3553 static HRESULT WINAPI
BasicVideo_put_SourceHeight(IBasicVideo2
*iface
, LONG SourceHeight
)
3555 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3556 IBasicVideo
*pBasicVideo
;
3559 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceHeight
);
3561 EnterCriticalSection(&This
->cs
);
3563 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3566 hr
= IBasicVideo_put_SourceHeight(pBasicVideo
, SourceHeight
);
3568 LeaveCriticalSection(&This
->cs
);
3573 static HRESULT WINAPI
BasicVideo_get_SourceHeight(IBasicVideo2
*iface
, LONG
*pSourceHeight
)
3575 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3576 IBasicVideo
*pBasicVideo
;
3579 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceHeight
);
3581 EnterCriticalSection(&This
->cs
);
3583 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3586 hr
= IBasicVideo_get_SourceHeight(pBasicVideo
, pSourceHeight
);
3588 LeaveCriticalSection(&This
->cs
);
3593 static HRESULT WINAPI
BasicVideo_put_DestinationLeft(IBasicVideo2
*iface
, LONG DestinationLeft
)
3595 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3596 IBasicVideo
*pBasicVideo
;
3599 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationLeft
);
3601 EnterCriticalSection(&This
->cs
);
3603 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3606 hr
= IBasicVideo_put_DestinationLeft(pBasicVideo
, DestinationLeft
);
3608 LeaveCriticalSection(&This
->cs
);
3613 static HRESULT WINAPI
BasicVideo_get_DestinationLeft(IBasicVideo2
*iface
, LONG
*pDestinationLeft
)
3615 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3616 IBasicVideo
*pBasicVideo
;
3619 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationLeft
);
3621 EnterCriticalSection(&This
->cs
);
3623 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3626 hr
= IBasicVideo_get_DestinationLeft(pBasicVideo
, pDestinationLeft
);
3628 LeaveCriticalSection(&This
->cs
);
3633 static HRESULT WINAPI
BasicVideo_put_DestinationWidth(IBasicVideo2
*iface
, LONG DestinationWidth
)
3635 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3636 IBasicVideo
*pBasicVideo
;
3639 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationWidth
);
3641 EnterCriticalSection(&This
->cs
);
3643 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3646 hr
= IBasicVideo_put_DestinationWidth(pBasicVideo
, DestinationWidth
);
3648 LeaveCriticalSection(&This
->cs
);
3653 static HRESULT WINAPI
BasicVideo_get_DestinationWidth(IBasicVideo2
*iface
, LONG
*pDestinationWidth
)
3655 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3656 IBasicVideo
*pBasicVideo
;
3659 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationWidth
);
3661 EnterCriticalSection(&This
->cs
);
3663 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3666 hr
= IBasicVideo_get_DestinationWidth(pBasicVideo
, pDestinationWidth
);
3668 LeaveCriticalSection(&This
->cs
);
3673 static HRESULT WINAPI
BasicVideo_put_DestinationTop(IBasicVideo2
*iface
, LONG DestinationTop
)
3675 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3676 IBasicVideo
*pBasicVideo
;
3679 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationTop
);
3681 EnterCriticalSection(&This
->cs
);
3683 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3686 hr
= IBasicVideo_put_DestinationTop(pBasicVideo
, DestinationTop
);
3688 LeaveCriticalSection(&This
->cs
);
3693 static HRESULT WINAPI
BasicVideo_get_DestinationTop(IBasicVideo2
*iface
, LONG
*pDestinationTop
)
3695 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3696 IBasicVideo
*pBasicVideo
;
3699 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationTop
);
3701 EnterCriticalSection(&This
->cs
);
3703 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3706 hr
= IBasicVideo_get_DestinationTop(pBasicVideo
, pDestinationTop
);
3708 LeaveCriticalSection(&This
->cs
);
3713 static HRESULT WINAPI
BasicVideo_put_DestinationHeight(IBasicVideo2
*iface
, LONG DestinationHeight
)
3715 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3716 IBasicVideo
*pBasicVideo
;
3719 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationHeight
);
3721 EnterCriticalSection(&This
->cs
);
3723 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3726 hr
= IBasicVideo_put_DestinationHeight(pBasicVideo
, DestinationHeight
);
3728 LeaveCriticalSection(&This
->cs
);
3733 static HRESULT WINAPI
BasicVideo_get_DestinationHeight(IBasicVideo2
*iface
,
3734 LONG
*pDestinationHeight
)
3736 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3737 IBasicVideo
*pBasicVideo
;
3740 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationHeight
);
3742 EnterCriticalSection(&This
->cs
);
3744 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3747 hr
= IBasicVideo_get_DestinationHeight(pBasicVideo
, pDestinationHeight
);
3749 LeaveCriticalSection(&This
->cs
);
3754 static HRESULT WINAPI
BasicVideo_SetSourcePosition(IBasicVideo2
*iface
, LONG Left
, LONG Top
,
3755 LONG Width
, LONG Height
)
3757 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3758 IBasicVideo
*pBasicVideo
;
3761 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
3763 EnterCriticalSection(&This
->cs
);
3765 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3768 hr
= IBasicVideo_SetSourcePosition(pBasicVideo
, Left
, Top
, Width
, Height
);
3770 LeaveCriticalSection(&This
->cs
);
3775 static HRESULT WINAPI
BasicVideo_GetSourcePosition(IBasicVideo2
*iface
, LONG
*pLeft
, LONG
*pTop
,
3776 LONG
*pWidth
, LONG
*pHeight
)
3778 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3779 IBasicVideo
*pBasicVideo
;
3782 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
3784 EnterCriticalSection(&This
->cs
);
3786 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3789 hr
= IBasicVideo_GetSourcePosition(pBasicVideo
, pLeft
, pTop
, pWidth
, pHeight
);
3791 LeaveCriticalSection(&This
->cs
);
3796 static HRESULT WINAPI
BasicVideo_SetDefaultSourcePosition(IBasicVideo2
*iface
)
3798 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3799 IBasicVideo
*pBasicVideo
;
3802 TRACE("(%p/%p)->()\n", This
, iface
);
3804 EnterCriticalSection(&This
->cs
);
3806 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3809 hr
= IBasicVideo_SetDefaultSourcePosition(pBasicVideo
);
3811 LeaveCriticalSection(&This
->cs
);
3816 static HRESULT WINAPI
BasicVideo_SetDestinationPosition(IBasicVideo2
*iface
, LONG Left
, LONG Top
,
3817 LONG Width
, LONG Height
)
3819 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3820 IBasicVideo
*pBasicVideo
;
3823 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
3825 EnterCriticalSection(&This
->cs
);
3827 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3830 hr
= IBasicVideo_SetDestinationPosition(pBasicVideo
, Left
, Top
, Width
, Height
);
3832 LeaveCriticalSection(&This
->cs
);
3837 static HRESULT WINAPI
BasicVideo_GetDestinationPosition(IBasicVideo2
*iface
, LONG
*pLeft
,
3838 LONG
*pTop
, LONG
*pWidth
, LONG
*pHeight
)
3840 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3841 IBasicVideo
*pBasicVideo
;
3844 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
3846 EnterCriticalSection(&This
->cs
);
3848 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3851 hr
= IBasicVideo_GetDestinationPosition(pBasicVideo
, pLeft
, pTop
, pWidth
, pHeight
);
3853 LeaveCriticalSection(&This
->cs
);
3858 static HRESULT WINAPI
BasicVideo_SetDefaultDestinationPosition(IBasicVideo2
*iface
)
3860 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3861 IBasicVideo
*pBasicVideo
;
3864 TRACE("(%p/%p)->()\n", This
, iface
);
3866 EnterCriticalSection(&This
->cs
);
3868 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3871 hr
= IBasicVideo_SetDefaultDestinationPosition(pBasicVideo
);
3873 LeaveCriticalSection(&This
->cs
);
3878 static HRESULT WINAPI
BasicVideo_GetVideoSize(IBasicVideo2
*iface
, LONG
*pWidth
, LONG
*pHeight
)
3880 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3881 IBasicVideo
*pBasicVideo
;
3884 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pWidth
, pHeight
);
3886 EnterCriticalSection(&This
->cs
);
3888 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3891 hr
= IBasicVideo_GetVideoSize(pBasicVideo
, pWidth
, pHeight
);
3893 LeaveCriticalSection(&This
->cs
);
3898 static HRESULT WINAPI
BasicVideo_GetVideoPaletteEntries(IBasicVideo2
*iface
, LONG StartIndex
,
3899 LONG Entries
, LONG
*pRetrieved
, LONG
*pPalette
)
3901 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3902 IBasicVideo
*pBasicVideo
;
3905 TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This
, iface
, StartIndex
, Entries
, pRetrieved
, pPalette
);
3907 EnterCriticalSection(&This
->cs
);
3909 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3912 hr
= IBasicVideo_GetVideoPaletteEntries(pBasicVideo
, StartIndex
, Entries
, pRetrieved
, pPalette
);
3914 LeaveCriticalSection(&This
->cs
);
3919 static HRESULT WINAPI
BasicVideo_GetCurrentImage(IBasicVideo2
*iface
, LONG
*pBufferSize
,
3922 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3923 IBasicVideo
*pBasicVideo
;
3926 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pBufferSize
, pDIBImage
);
3928 EnterCriticalSection(&This
->cs
);
3930 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3933 hr
= IBasicVideo_GetCurrentImage(pBasicVideo
, pBufferSize
, pDIBImage
);
3935 LeaveCriticalSection(&This
->cs
);
3940 static HRESULT WINAPI
BasicVideo_IsUsingDefaultSource(IBasicVideo2
*iface
)
3942 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3943 IBasicVideo
*pBasicVideo
;
3946 TRACE("(%p/%p)->()\n", This
, iface
);
3948 EnterCriticalSection(&This
->cs
);
3950 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3953 hr
= IBasicVideo_IsUsingDefaultSource(pBasicVideo
);
3955 LeaveCriticalSection(&This
->cs
);
3960 static HRESULT WINAPI
BasicVideo_IsUsingDefaultDestination(IBasicVideo2
*iface
)
3962 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3963 IBasicVideo
*pBasicVideo
;
3966 TRACE("(%p/%p)->()\n", This
, iface
);
3968 EnterCriticalSection(&This
->cs
);
3970 hr
= GetTargetInterface(This
, &IID_IBasicVideo
, (LPVOID
*)&pBasicVideo
);
3973 hr
= IBasicVideo_IsUsingDefaultDestination(pBasicVideo
);
3975 LeaveCriticalSection(&This
->cs
);
3980 static HRESULT WINAPI
BasicVideo2_GetPreferredAspectRatio(IBasicVideo2
*iface
, LONG
*plAspectX
,
3983 IFilterGraphImpl
*This
= impl_from_IBasicVideo2(iface
);
3984 IBasicVideo2
*pBasicVideo2
;
3987 TRACE("(%p/%p)->()\n", This
, iface
);
3989 EnterCriticalSection(&This
->cs
);
3991 hr
= GetTargetInterface(This
, &IID_IBasicVideo2
, (LPVOID
*)&pBasicVideo2
);
3994 hr
= BasicVideo2_GetPreferredAspectRatio(iface
, plAspectX
, plAspectY
);
3996 LeaveCriticalSection(&This
->cs
);
4001 static const IBasicVideo2Vtbl IBasicVideo_VTable
=
4003 BasicVideo_QueryInterface
,
4006 BasicVideo_GetTypeInfoCount
,
4007 BasicVideo_GetTypeInfo
,
4008 BasicVideo_GetIDsOfNames
,
4010 BasicVideo_get_AvgTimePerFrame
,
4011 BasicVideo_get_BitRate
,
4012 BasicVideo_get_BitErrorRate
,
4013 BasicVideo_get_VideoWidth
,
4014 BasicVideo_get_VideoHeight
,
4015 BasicVideo_put_SourceLeft
,
4016 BasicVideo_get_SourceLeft
,
4017 BasicVideo_put_SourceWidth
,
4018 BasicVideo_get_SourceWidth
,
4019 BasicVideo_put_SourceTop
,
4020 BasicVideo_get_SourceTop
,
4021 BasicVideo_put_SourceHeight
,
4022 BasicVideo_get_SourceHeight
,
4023 BasicVideo_put_DestinationLeft
,
4024 BasicVideo_get_DestinationLeft
,
4025 BasicVideo_put_DestinationWidth
,
4026 BasicVideo_get_DestinationWidth
,
4027 BasicVideo_put_DestinationTop
,
4028 BasicVideo_get_DestinationTop
,
4029 BasicVideo_put_DestinationHeight
,
4030 BasicVideo_get_DestinationHeight
,
4031 BasicVideo_SetSourcePosition
,
4032 BasicVideo_GetSourcePosition
,
4033 BasicVideo_SetDefaultSourcePosition
,
4034 BasicVideo_SetDestinationPosition
,
4035 BasicVideo_GetDestinationPosition
,
4036 BasicVideo_SetDefaultDestinationPosition
,
4037 BasicVideo_GetVideoSize
,
4038 BasicVideo_GetVideoPaletteEntries
,
4039 BasicVideo_GetCurrentImage
,
4040 BasicVideo_IsUsingDefaultSource
,
4041 BasicVideo_IsUsingDefaultDestination
,
4042 BasicVideo2_GetPreferredAspectRatio
4045 static inline IFilterGraphImpl
*impl_from_IVideoWindow(IVideoWindow
*iface
)
4047 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IVideoWindow_iface
);
4050 static HRESULT WINAPI
VideoWindow_QueryInterface(IVideoWindow
*iface
, REFIID riid
, void **ppvObj
)
4052 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4054 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
4056 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
4059 static ULONG WINAPI
VideoWindow_AddRef(IVideoWindow
*iface
)
4061 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4063 TRACE("(%p/%p)->()\n", This
, iface
);
4065 return IUnknown_AddRef(This
->outer_unk
);
4068 static ULONG WINAPI
VideoWindow_Release(IVideoWindow
*iface
)
4070 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4072 TRACE("(%p/%p)->()\n", This
, iface
);
4074 return IUnknown_Release(This
->outer_unk
);
4077 /*** IDispatch methods ***/
4078 static HRESULT WINAPI
VideoWindow_GetTypeInfoCount(IVideoWindow
*iface
, UINT
*pctinfo
)
4080 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4081 IVideoWindow
*pVideoWindow
;
4084 TRACE("(%p/%p)->(%p)\n", This
, iface
, pctinfo
);
4086 EnterCriticalSection(&This
->cs
);
4088 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4091 hr
= IVideoWindow_GetTypeInfoCount(pVideoWindow
, pctinfo
);
4093 LeaveCriticalSection(&This
->cs
);
4098 static HRESULT WINAPI
VideoWindow_GetTypeInfo(IVideoWindow
*iface
, UINT iTInfo
, LCID lcid
,
4099 ITypeInfo
**ppTInfo
)
4101 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4102 IVideoWindow
*pVideoWindow
;
4105 TRACE("(%p/%p)->(%d, %d, %p)\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
4107 EnterCriticalSection(&This
->cs
);
4109 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4112 hr
= IVideoWindow_GetTypeInfo(pVideoWindow
, iTInfo
, lcid
, ppTInfo
);
4114 LeaveCriticalSection(&This
->cs
);
4119 static HRESULT WINAPI
VideoWindow_GetIDsOfNames(IVideoWindow
*iface
, REFIID riid
,
4120 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
4122 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4123 IVideoWindow
*pVideoWindow
;
4126 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
4128 EnterCriticalSection(&This
->cs
);
4130 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4133 hr
= IVideoWindow_GetIDsOfNames(pVideoWindow
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
4135 LeaveCriticalSection(&This
->cs
);
4140 static HRESULT WINAPI
VideoWindow_Invoke(IVideoWindow
*iface
, DISPID dispIdMember
, REFIID riid
,
4141 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
,
4144 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4145 IVideoWindow
*pVideoWindow
;
4148 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
);
4150 EnterCriticalSection(&This
->cs
);
4152 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4155 hr
= IVideoWindow_Invoke(pVideoWindow
, dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
4157 LeaveCriticalSection(&This
->cs
);
4163 /*** IVideoWindow methods ***/
4164 static HRESULT WINAPI
VideoWindow_put_Caption(IVideoWindow
*iface
, BSTR strCaption
)
4166 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4167 IVideoWindow
*pVideoWindow
;
4170 TRACE("(%p/%p)->(%s (%p))\n", This
, iface
, debugstr_w(strCaption
), strCaption
);
4172 EnterCriticalSection(&This
->cs
);
4174 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4177 hr
= IVideoWindow_put_Caption(pVideoWindow
, strCaption
);
4179 LeaveCriticalSection(&This
->cs
);
4184 static HRESULT WINAPI
VideoWindow_get_Caption(IVideoWindow
*iface
, BSTR
*strCaption
)
4186 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4187 IVideoWindow
*pVideoWindow
;
4190 TRACE("(%p/%p)->(%p)\n", This
, iface
, strCaption
);
4192 EnterCriticalSection(&This
->cs
);
4194 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4197 hr
= IVideoWindow_get_Caption(pVideoWindow
, strCaption
);
4199 LeaveCriticalSection(&This
->cs
);
4204 static HRESULT WINAPI
VideoWindow_put_WindowStyle(IVideoWindow
*iface
, LONG WindowStyle
)
4206 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4207 IVideoWindow
*pVideoWindow
;
4210 TRACE("(%p/%p)->(%d)\n", This
, iface
, WindowStyle
);
4212 EnterCriticalSection(&This
->cs
);
4214 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4217 hr
= IVideoWindow_put_WindowStyle(pVideoWindow
, WindowStyle
);
4219 LeaveCriticalSection(&This
->cs
);
4224 static HRESULT WINAPI
VideoWindow_get_WindowStyle(IVideoWindow
*iface
, LONG
*WindowStyle
)
4226 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4227 IVideoWindow
*pVideoWindow
;
4230 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowStyle
);
4232 EnterCriticalSection(&This
->cs
);
4234 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4237 hr
= IVideoWindow_get_WindowStyle(pVideoWindow
, WindowStyle
);
4239 LeaveCriticalSection(&This
->cs
);
4244 static HRESULT WINAPI
VideoWindow_put_WindowStyleEx(IVideoWindow
*iface
, LONG WindowStyleEx
)
4246 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4247 IVideoWindow
*pVideoWindow
;
4250 TRACE("(%p/%p)->(%d)\n", This
, iface
, WindowStyleEx
);
4252 EnterCriticalSection(&This
->cs
);
4254 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4257 hr
= IVideoWindow_put_WindowStyleEx(pVideoWindow
, WindowStyleEx
);
4259 LeaveCriticalSection(&This
->cs
);
4264 static HRESULT WINAPI
VideoWindow_get_WindowStyleEx(IVideoWindow
*iface
, LONG
*WindowStyleEx
)
4266 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4267 IVideoWindow
*pVideoWindow
;
4270 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowStyleEx
);
4272 EnterCriticalSection(&This
->cs
);
4274 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4277 hr
= IVideoWindow_get_WindowStyleEx(pVideoWindow
, WindowStyleEx
);
4279 LeaveCriticalSection(&This
->cs
);
4284 static HRESULT WINAPI
VideoWindow_put_AutoShow(IVideoWindow
*iface
, LONG AutoShow
)
4286 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4287 IVideoWindow
*pVideoWindow
;
4290 TRACE("(%p/%p)->(%d)\n", This
, iface
, AutoShow
);
4292 EnterCriticalSection(&This
->cs
);
4294 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4297 hr
= IVideoWindow_put_AutoShow(pVideoWindow
, AutoShow
);
4299 LeaveCriticalSection(&This
->cs
);
4304 static HRESULT WINAPI
VideoWindow_get_AutoShow(IVideoWindow
*iface
, LONG
*AutoShow
)
4306 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4307 IVideoWindow
*pVideoWindow
;
4310 TRACE("(%p/%p)->(%p)\n", This
, iface
, AutoShow
);
4312 EnterCriticalSection(&This
->cs
);
4314 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4317 hr
= IVideoWindow_get_AutoShow(pVideoWindow
, AutoShow
);
4319 LeaveCriticalSection(&This
->cs
);
4324 static HRESULT WINAPI
VideoWindow_put_WindowState(IVideoWindow
*iface
, LONG WindowState
)
4326 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4327 IVideoWindow
*pVideoWindow
;
4330 TRACE("(%p/%p)->(%d)\n", This
, iface
, WindowState
);
4332 EnterCriticalSection(&This
->cs
);
4334 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4337 hr
= IVideoWindow_put_WindowState(pVideoWindow
, WindowState
);
4339 LeaveCriticalSection(&This
->cs
);
4344 static HRESULT WINAPI
VideoWindow_get_WindowState(IVideoWindow
*iface
, LONG
*WindowState
)
4346 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4347 IVideoWindow
*pVideoWindow
;
4350 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowState
);
4352 EnterCriticalSection(&This
->cs
);
4354 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4357 hr
= IVideoWindow_get_WindowState(pVideoWindow
, WindowState
);
4359 LeaveCriticalSection(&This
->cs
);
4364 static HRESULT WINAPI
VideoWindow_put_BackgroundPalette(IVideoWindow
*iface
, LONG BackgroundPalette
)
4366 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4367 IVideoWindow
*pVideoWindow
;
4370 TRACE("(%p/%p)->(%d)\n", This
, iface
, BackgroundPalette
);
4372 EnterCriticalSection(&This
->cs
);
4374 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4377 hr
= IVideoWindow_put_BackgroundPalette(pVideoWindow
, BackgroundPalette
);
4379 LeaveCriticalSection(&This
->cs
);
4384 static HRESULT WINAPI
VideoWindow_get_BackgroundPalette(IVideoWindow
*iface
,
4385 LONG
*pBackgroundPalette
)
4387 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4388 IVideoWindow
*pVideoWindow
;
4391 TRACE("(%p/%p)->(%p)\n", This
, iface
, pBackgroundPalette
);
4393 EnterCriticalSection(&This
->cs
);
4395 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4398 hr
= IVideoWindow_get_BackgroundPalette(pVideoWindow
, pBackgroundPalette
);
4400 LeaveCriticalSection(&This
->cs
);
4405 static HRESULT WINAPI
VideoWindow_put_Visible(IVideoWindow
*iface
, LONG Visible
)
4407 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4408 IVideoWindow
*pVideoWindow
;
4411 TRACE("(%p/%p)->(%d)\n", This
, iface
, Visible
);
4413 EnterCriticalSection(&This
->cs
);
4415 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4418 hr
= IVideoWindow_put_Visible(pVideoWindow
, Visible
);
4420 LeaveCriticalSection(&This
->cs
);
4425 static HRESULT WINAPI
VideoWindow_get_Visible(IVideoWindow
*iface
, LONG
*pVisible
)
4427 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4428 IVideoWindow
*pVideoWindow
;
4431 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVisible
);
4433 EnterCriticalSection(&This
->cs
);
4435 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4438 hr
= IVideoWindow_get_Visible(pVideoWindow
, pVisible
);
4440 LeaveCriticalSection(&This
->cs
);
4445 static HRESULT WINAPI
VideoWindow_put_Left(IVideoWindow
*iface
, LONG Left
)
4447 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4448 IVideoWindow
*pVideoWindow
;
4451 TRACE("(%p/%p)->(%d)\n", This
, iface
, Left
);
4453 EnterCriticalSection(&This
->cs
);
4455 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4458 hr
= IVideoWindow_put_Left(pVideoWindow
, Left
);
4460 LeaveCriticalSection(&This
->cs
);
4465 static HRESULT WINAPI
VideoWindow_get_Left(IVideoWindow
*iface
, LONG
*pLeft
)
4467 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4468 IVideoWindow
*pVideoWindow
;
4471 TRACE("(%p/%p)->(%p)\n", This
, iface
, pLeft
);
4473 EnterCriticalSection(&This
->cs
);
4475 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4478 hr
= IVideoWindow_get_Left(pVideoWindow
, pLeft
);
4480 LeaveCriticalSection(&This
->cs
);
4485 static HRESULT WINAPI
VideoWindow_put_Width(IVideoWindow
*iface
, LONG Width
)
4487 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4488 IVideoWindow
*pVideoWindow
;
4491 TRACE("(%p/%p)->(%d)\n", This
, iface
, Width
);
4493 EnterCriticalSection(&This
->cs
);
4495 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4498 hr
= IVideoWindow_put_Width(pVideoWindow
, Width
);
4500 LeaveCriticalSection(&This
->cs
);
4505 static HRESULT WINAPI
VideoWindow_get_Width(IVideoWindow
*iface
, LONG
*pWidth
)
4507 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4508 IVideoWindow
*pVideoWindow
;
4511 TRACE("(%p/%p)->(%p)\n", This
, iface
, pWidth
);
4513 EnterCriticalSection(&This
->cs
);
4515 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4518 hr
= IVideoWindow_get_Width(pVideoWindow
, pWidth
);
4520 LeaveCriticalSection(&This
->cs
);
4525 static HRESULT WINAPI
VideoWindow_put_Top(IVideoWindow
*iface
, LONG Top
)
4527 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4528 IVideoWindow
*pVideoWindow
;
4531 TRACE("(%p/%p)->(%d)\n", This
, iface
, Top
);
4533 EnterCriticalSection(&This
->cs
);
4535 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4538 hr
= IVideoWindow_put_Top(pVideoWindow
, Top
);
4540 LeaveCriticalSection(&This
->cs
);
4545 static HRESULT WINAPI
VideoWindow_get_Top(IVideoWindow
*iface
, LONG
*pTop
)
4547 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4548 IVideoWindow
*pVideoWindow
;
4551 TRACE("(%p/%p)->(%p)\n", This
, iface
, pTop
);
4553 EnterCriticalSection(&This
->cs
);
4555 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4558 hr
= IVideoWindow_get_Top(pVideoWindow
, pTop
);
4560 LeaveCriticalSection(&This
->cs
);
4565 static HRESULT WINAPI
VideoWindow_put_Height(IVideoWindow
*iface
, LONG Height
)
4567 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4568 IVideoWindow
*pVideoWindow
;
4571 TRACE("(%p/%p)->(%d)\n", This
, iface
, Height
);
4573 EnterCriticalSection(&This
->cs
);
4575 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4578 hr
= IVideoWindow_put_Height(pVideoWindow
, Height
);
4580 LeaveCriticalSection(&This
->cs
);
4585 static HRESULT WINAPI
VideoWindow_get_Height(IVideoWindow
*iface
, LONG
*pHeight
)
4587 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4588 IVideoWindow
*pVideoWindow
;
4591 TRACE("(%p/%p)->(%p)\n", This
, iface
, pHeight
);
4593 EnterCriticalSection(&This
->cs
);
4595 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4598 hr
= IVideoWindow_get_Height(pVideoWindow
, pHeight
);
4600 LeaveCriticalSection(&This
->cs
);
4605 static HRESULT WINAPI
VideoWindow_put_Owner(IVideoWindow
*iface
, OAHWND Owner
)
4607 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4608 IVideoWindow
*pVideoWindow
;
4611 TRACE("(%p/%p)->(%08x)\n", This
, iface
, (DWORD
) Owner
);
4613 EnterCriticalSection(&This
->cs
);
4615 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4618 hr
= IVideoWindow_put_Owner(pVideoWindow
, Owner
);
4620 LeaveCriticalSection(&This
->cs
);
4625 static HRESULT WINAPI
VideoWindow_get_Owner(IVideoWindow
*iface
, OAHWND
*Owner
)
4627 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4628 IVideoWindow
*pVideoWindow
;
4631 TRACE("(%p/%p)->(%p)\n", This
, iface
, Owner
);
4633 EnterCriticalSection(&This
->cs
);
4635 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4638 hr
= IVideoWindow_get_Owner(pVideoWindow
, Owner
);
4640 LeaveCriticalSection(&This
->cs
);
4645 static HRESULT WINAPI
VideoWindow_put_MessageDrain(IVideoWindow
*iface
, OAHWND Drain
)
4647 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4648 IVideoWindow
*pVideoWindow
;
4651 TRACE("(%p/%p)->(%08x)\n", This
, iface
, (DWORD
) Drain
);
4653 EnterCriticalSection(&This
->cs
);
4655 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4658 hr
= IVideoWindow_put_MessageDrain(pVideoWindow
, Drain
);
4660 LeaveCriticalSection(&This
->cs
);
4665 static HRESULT WINAPI
VideoWindow_get_MessageDrain(IVideoWindow
*iface
, OAHWND
*Drain
)
4667 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4668 IVideoWindow
*pVideoWindow
;
4671 TRACE("(%p/%p)->(%p)\n", This
, iface
, Drain
);
4673 EnterCriticalSection(&This
->cs
);
4675 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4678 hr
= IVideoWindow_get_MessageDrain(pVideoWindow
, Drain
);
4680 LeaveCriticalSection(&This
->cs
);
4685 static HRESULT WINAPI
VideoWindow_get_BorderColor(IVideoWindow
*iface
, LONG
*Color
)
4687 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4688 IVideoWindow
*pVideoWindow
;
4691 TRACE("(%p/%p)->(%p)\n", This
, iface
, Color
);
4693 EnterCriticalSection(&This
->cs
);
4695 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4698 hr
= IVideoWindow_get_BorderColor(pVideoWindow
, Color
);
4700 LeaveCriticalSection(&This
->cs
);
4705 static HRESULT WINAPI
VideoWindow_put_BorderColor(IVideoWindow
*iface
, LONG Color
)
4707 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4708 IVideoWindow
*pVideoWindow
;
4711 TRACE("(%p/%p)->(%d)\n", This
, iface
, Color
);
4713 EnterCriticalSection(&This
->cs
);
4715 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4718 hr
= IVideoWindow_put_BorderColor(pVideoWindow
, Color
);
4720 LeaveCriticalSection(&This
->cs
);
4725 static HRESULT WINAPI
VideoWindow_get_FullScreenMode(IVideoWindow
*iface
, LONG
*FullScreenMode
)
4727 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4728 IVideoWindow
*pVideoWindow
;
4731 TRACE("(%p/%p)->(%p)\n", This
, iface
, FullScreenMode
);
4733 EnterCriticalSection(&This
->cs
);
4735 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4738 hr
= IVideoWindow_get_FullScreenMode(pVideoWindow
, FullScreenMode
);
4740 LeaveCriticalSection(&This
->cs
);
4745 static HRESULT WINAPI
VideoWindow_put_FullScreenMode(IVideoWindow
*iface
, LONG FullScreenMode
)
4747 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4748 IVideoWindow
*pVideoWindow
;
4751 TRACE("(%p/%p)->(%d)\n", This
, iface
, FullScreenMode
);
4753 EnterCriticalSection(&This
->cs
);
4755 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4758 hr
= IVideoWindow_put_FullScreenMode(pVideoWindow
, FullScreenMode
);
4760 LeaveCriticalSection(&This
->cs
);
4765 static HRESULT WINAPI
VideoWindow_SetWindowForeground(IVideoWindow
*iface
, LONG Focus
)
4767 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4768 IVideoWindow
*pVideoWindow
;
4771 TRACE("(%p/%p)->(%d)\n", This
, iface
, Focus
);
4773 EnterCriticalSection(&This
->cs
);
4775 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4778 hr
= IVideoWindow_SetWindowForeground(pVideoWindow
, Focus
);
4780 LeaveCriticalSection(&This
->cs
);
4785 static HRESULT WINAPI
VideoWindow_NotifyOwnerMessage(IVideoWindow
*iface
, OAHWND hwnd
, LONG uMsg
,
4786 LONG_PTR wParam
, LONG_PTR lParam
)
4788 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4789 IVideoWindow
*pVideoWindow
;
4792 TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This
, iface
, hwnd
, uMsg
, wParam
, lParam
);
4794 EnterCriticalSection(&This
->cs
);
4796 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4799 hr
= IVideoWindow_NotifyOwnerMessage(pVideoWindow
, hwnd
, uMsg
, wParam
, lParam
);
4801 LeaveCriticalSection(&This
->cs
);
4806 static HRESULT WINAPI
VideoWindow_SetWindowPosition(IVideoWindow
*iface
, LONG Left
, LONG Top
,
4807 LONG Width
, LONG Height
)
4809 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4810 IVideoWindow
*pVideoWindow
;
4813 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
4815 EnterCriticalSection(&This
->cs
);
4817 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4820 hr
= IVideoWindow_SetWindowPosition(pVideoWindow
, Left
, Top
, Width
, Height
);
4822 LeaveCriticalSection(&This
->cs
);
4827 static HRESULT WINAPI
VideoWindow_GetWindowPosition(IVideoWindow
*iface
, LONG
*pLeft
, LONG
*pTop
,
4828 LONG
*pWidth
, LONG
*pHeight
)
4830 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4831 IVideoWindow
*pVideoWindow
;
4834 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
4836 EnterCriticalSection(&This
->cs
);
4838 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4841 hr
= IVideoWindow_GetWindowPosition(pVideoWindow
, pLeft
, pTop
, pWidth
, pHeight
);
4843 LeaveCriticalSection(&This
->cs
);
4848 static HRESULT WINAPI
VideoWindow_GetMinIdealImageSize(IVideoWindow
*iface
, LONG
*pWidth
,
4851 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4852 IVideoWindow
*pVideoWindow
;
4855 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pWidth
, pHeight
);
4857 EnterCriticalSection(&This
->cs
);
4859 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4862 hr
= IVideoWindow_GetMinIdealImageSize(pVideoWindow
, pWidth
, pHeight
);
4864 LeaveCriticalSection(&This
->cs
);
4869 static HRESULT WINAPI
VideoWindow_GetMaxIdealImageSize(IVideoWindow
*iface
, LONG
*pWidth
,
4872 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4873 IVideoWindow
*pVideoWindow
;
4876 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pWidth
, pHeight
);
4878 EnterCriticalSection(&This
->cs
);
4880 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4883 hr
= IVideoWindow_GetMaxIdealImageSize(pVideoWindow
, pWidth
, pHeight
);
4885 LeaveCriticalSection(&This
->cs
);
4890 static HRESULT WINAPI
VideoWindow_GetRestorePosition(IVideoWindow
*iface
, LONG
*pLeft
, LONG
*pTop
,
4891 LONG
*pWidth
, LONG
*pHeight
)
4893 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4894 IVideoWindow
*pVideoWindow
;
4897 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
4899 EnterCriticalSection(&This
->cs
);
4901 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4904 hr
= IVideoWindow_GetRestorePosition(pVideoWindow
, pLeft
, pTop
, pWidth
, pHeight
);
4906 LeaveCriticalSection(&This
->cs
);
4911 static HRESULT WINAPI
VideoWindow_HideCursor(IVideoWindow
*iface
, LONG HideCursor
)
4913 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4914 IVideoWindow
*pVideoWindow
;
4917 TRACE("(%p/%p)->(%d)\n", This
, iface
, HideCursor
);
4919 EnterCriticalSection(&This
->cs
);
4921 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4924 hr
= IVideoWindow_HideCursor(pVideoWindow
, HideCursor
);
4926 LeaveCriticalSection(&This
->cs
);
4931 static HRESULT WINAPI
VideoWindow_IsCursorHidden(IVideoWindow
*iface
, LONG
*CursorHidden
)
4933 IFilterGraphImpl
*This
= impl_from_IVideoWindow(iface
);
4934 IVideoWindow
*pVideoWindow
;
4937 TRACE("(%p/%p)->(%p)\n", This
, iface
, CursorHidden
);
4939 EnterCriticalSection(&This
->cs
);
4941 hr
= GetTargetInterface(This
, &IID_IVideoWindow
, (LPVOID
*)&pVideoWindow
);
4944 hr
= IVideoWindow_IsCursorHidden(pVideoWindow
, CursorHidden
);
4946 LeaveCriticalSection(&This
->cs
);
4952 static const IVideoWindowVtbl IVideoWindow_VTable
=
4954 VideoWindow_QueryInterface
,
4956 VideoWindow_Release
,
4957 VideoWindow_GetTypeInfoCount
,
4958 VideoWindow_GetTypeInfo
,
4959 VideoWindow_GetIDsOfNames
,
4961 VideoWindow_put_Caption
,
4962 VideoWindow_get_Caption
,
4963 VideoWindow_put_WindowStyle
,
4964 VideoWindow_get_WindowStyle
,
4965 VideoWindow_put_WindowStyleEx
,
4966 VideoWindow_get_WindowStyleEx
,
4967 VideoWindow_put_AutoShow
,
4968 VideoWindow_get_AutoShow
,
4969 VideoWindow_put_WindowState
,
4970 VideoWindow_get_WindowState
,
4971 VideoWindow_put_BackgroundPalette
,
4972 VideoWindow_get_BackgroundPalette
,
4973 VideoWindow_put_Visible
,
4974 VideoWindow_get_Visible
,
4975 VideoWindow_put_Left
,
4976 VideoWindow_get_Left
,
4977 VideoWindow_put_Width
,
4978 VideoWindow_get_Width
,
4979 VideoWindow_put_Top
,
4980 VideoWindow_get_Top
,
4981 VideoWindow_put_Height
,
4982 VideoWindow_get_Height
,
4983 VideoWindow_put_Owner
,
4984 VideoWindow_get_Owner
,
4985 VideoWindow_put_MessageDrain
,
4986 VideoWindow_get_MessageDrain
,
4987 VideoWindow_get_BorderColor
,
4988 VideoWindow_put_BorderColor
,
4989 VideoWindow_get_FullScreenMode
,
4990 VideoWindow_put_FullScreenMode
,
4991 VideoWindow_SetWindowForeground
,
4992 VideoWindow_NotifyOwnerMessage
,
4993 VideoWindow_SetWindowPosition
,
4994 VideoWindow_GetWindowPosition
,
4995 VideoWindow_GetMinIdealImageSize
,
4996 VideoWindow_GetMaxIdealImageSize
,
4997 VideoWindow_GetRestorePosition
,
4998 VideoWindow_HideCursor
,
4999 VideoWindow_IsCursorHidden
5002 static inline IFilterGraphImpl
*impl_from_IMediaEventEx(IMediaEventEx
*iface
)
5004 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaEventEx_iface
);
5007 static HRESULT WINAPI
MediaEvent_QueryInterface(IMediaEventEx
*iface
, REFIID riid
, void **ppvObj
)
5009 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5011 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
5013 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppvObj
);
5016 static ULONG WINAPI
MediaEvent_AddRef(IMediaEventEx
*iface
)
5018 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5020 TRACE("(%p/%p)->()\n", This
, iface
);
5022 return IUnknown_AddRef(This
->outer_unk
);
5025 static ULONG WINAPI
MediaEvent_Release(IMediaEventEx
*iface
)
5027 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5029 TRACE("(%p/%p)->()\n", This
, iface
);
5031 return IUnknown_Release(This
->outer_unk
);
5034 /*** IDispatch methods ***/
5035 static HRESULT WINAPI
MediaEvent_GetTypeInfoCount(IMediaEventEx
*iface
, UINT
*pctinfo
)
5037 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5039 TRACE("(%p/%p)->(%p): stub !!!\n", This
, iface
, pctinfo
);
5044 static HRESULT WINAPI
MediaEvent_GetTypeInfo(IMediaEventEx
*iface
, UINT iTInfo
, LCID lcid
,
5045 ITypeInfo
**ppTInfo
)
5047 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5049 TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
5054 static HRESULT WINAPI
MediaEvent_GetIDsOfNames(IMediaEventEx
*iface
, REFIID riid
,
5055 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
5057 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5059 TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
5064 static HRESULT WINAPI
MediaEvent_Invoke(IMediaEventEx
*iface
, DISPID dispIdMember
, REFIID riid
,
5065 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
,
5068 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5070 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
);
5075 /*** IMediaEvent methods ***/
5076 static HRESULT WINAPI
MediaEvent_GetEventHandle(IMediaEventEx
*iface
, OAEVENT
*hEvent
)
5078 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5080 TRACE("(%p/%p)->(%p)\n", This
, iface
, hEvent
);
5082 *hEvent
= (OAEVENT
)This
->evqueue
.msg_event
;
5087 static HRESULT WINAPI
MediaEvent_GetEvent(IMediaEventEx
*iface
, LONG
*lEventCode
, LONG_PTR
*lParam1
,
5088 LONG_PTR
*lParam2
, LONG msTimeout
)
5090 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5093 TRACE("(%p/%p)->(%p, %p, %p, %d)\n", This
, iface
, lEventCode
, lParam1
, lParam2
, msTimeout
);
5095 if (EventsQueue_GetEvent(&This
->evqueue
, &evt
, msTimeout
))
5097 *lEventCode
= evt
.lEventCode
;
5098 *lParam1
= evt
.lParam1
;
5099 *lParam2
= evt
.lParam2
;
5107 static HRESULT WINAPI
MediaEvent_WaitForCompletion(IMediaEventEx
*iface
, LONG msTimeout
,
5110 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5112 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, msTimeout
, pEvCode
);
5114 if (This
->state
!= State_Running
)
5115 return VFW_E_WRONG_STATE
;
5117 if (WaitForSingleObject(This
->hEventCompletion
, msTimeout
) == WAIT_OBJECT_0
)
5119 *pEvCode
= This
->CompletionStatus
;
5127 static HRESULT WINAPI
MediaEvent_CancelDefaultHandling(IMediaEventEx
*iface
, LONG lEvCode
)
5129 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5131 TRACE("(%p/%p)->(%d)\n", This
, iface
, lEvCode
);
5133 if (lEvCode
== EC_COMPLETE
)
5134 This
->HandleEcComplete
= FALSE
;
5135 else if (lEvCode
== EC_REPAINT
)
5136 This
->HandleEcRepaint
= FALSE
;
5137 else if (lEvCode
== EC_CLOCK_CHANGED
)
5138 This
->HandleEcClockChanged
= FALSE
;
5145 static HRESULT WINAPI
MediaEvent_RestoreDefaultHandling(IMediaEventEx
*iface
, LONG lEvCode
)
5147 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5149 TRACE("(%p/%p)->(%d)\n", This
, iface
, lEvCode
);
5151 if (lEvCode
== EC_COMPLETE
)
5152 This
->HandleEcComplete
= TRUE
;
5153 else if (lEvCode
== EC_REPAINT
)
5154 This
->HandleEcRepaint
= TRUE
;
5155 else if (lEvCode
== EC_CLOCK_CHANGED
)
5156 This
->HandleEcClockChanged
= TRUE
;
5163 static HRESULT WINAPI
MediaEvent_FreeEventParams(IMediaEventEx
*iface
, LONG lEvCode
,
5164 LONG_PTR lParam1
, LONG_PTR lParam2
)
5166 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5168 TRACE("(%p/%p)->(%d, %08lx, %08lx): stub !!!\n", This
, iface
, lEvCode
, lParam1
, lParam2
);
5173 /*** IMediaEventEx methods ***/
5174 static HRESULT WINAPI
MediaEvent_SetNotifyWindow(IMediaEventEx
*iface
, OAHWND hwnd
, LONG lMsg
,
5175 LONG_PTR lInstanceData
)
5177 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5179 TRACE("(%p/%p)->(%08lx, %d, %08lx)\n", This
, iface
, hwnd
, lMsg
, lInstanceData
);
5181 This
->notif
.hWnd
= (HWND
)hwnd
;
5182 This
->notif
.msg
= lMsg
;
5183 This
->notif
.instance
= lInstanceData
;
5188 static HRESULT WINAPI
MediaEvent_SetNotifyFlags(IMediaEventEx
*iface
, LONG lNoNotifyFlags
)
5190 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5192 TRACE("(%p/%p)->(%d)\n", This
, iface
, lNoNotifyFlags
);
5194 if ((lNoNotifyFlags
!= 0) && (lNoNotifyFlags
!= 1))
5195 return E_INVALIDARG
;
5197 This
->notif
.disabled
= lNoNotifyFlags
;
5202 static HRESULT WINAPI
MediaEvent_GetNotifyFlags(IMediaEventEx
*iface
, LONG
*lplNoNotifyFlags
)
5204 IFilterGraphImpl
*This
= impl_from_IMediaEventEx(iface
);
5206 TRACE("(%p/%p)->(%p)\n", This
, iface
, lplNoNotifyFlags
);
5208 if (!lplNoNotifyFlags
)
5211 *lplNoNotifyFlags
= This
->notif
.disabled
;
5217 static const IMediaEventExVtbl IMediaEventEx_VTable
=
5219 MediaEvent_QueryInterface
,
5222 MediaEvent_GetTypeInfoCount
,
5223 MediaEvent_GetTypeInfo
,
5224 MediaEvent_GetIDsOfNames
,
5226 MediaEvent_GetEventHandle
,
5227 MediaEvent_GetEvent
,
5228 MediaEvent_WaitForCompletion
,
5229 MediaEvent_CancelDefaultHandling
,
5230 MediaEvent_RestoreDefaultHandling
,
5231 MediaEvent_FreeEventParams
,
5232 MediaEvent_SetNotifyWindow
,
5233 MediaEvent_SetNotifyFlags
,
5234 MediaEvent_GetNotifyFlags
5238 static inline IFilterGraphImpl
*impl_from_IMediaFilter(IMediaFilter
*iface
)
5240 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaFilter_iface
);
5243 static HRESULT WINAPI
MediaFilter_QueryInterface(IMediaFilter
*iface
, REFIID riid
, void **ppv
)
5245 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5247 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
5250 static ULONG WINAPI
MediaFilter_AddRef(IMediaFilter
*iface
)
5252 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5254 return IUnknown_AddRef(This
->outer_unk
);
5257 static ULONG WINAPI
MediaFilter_Release(IMediaFilter
*iface
)
5259 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5261 return IUnknown_Release(This
->outer_unk
);
5264 static HRESULT WINAPI
MediaFilter_GetClassID(IMediaFilter
*iface
, CLSID
* pClassID
)
5266 FIXME("(%p): stub\n", pClassID
);
5271 static HRESULT WINAPI
MediaFilter_Stop(IMediaFilter
*iface
)
5273 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5275 return MediaControl_Stop(&This
->IMediaControl_iface
);
5278 static HRESULT WINAPI
MediaFilter_Pause(IMediaFilter
*iface
)
5280 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5282 return MediaControl_Pause(&This
->IMediaControl_iface
);
5285 static HRESULT WINAPI
MediaFilter_Run(IMediaFilter
*iface
, REFERENCE_TIME tStart
)
5287 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5290 FIXME("Run called with non-null tStart: %x%08x\n",
5291 (int)(tStart
>>32), (int)tStart
);
5293 return MediaControl_Run(&This
->IMediaControl_iface
);
5296 static HRESULT WINAPI
MediaFilter_GetState(IMediaFilter
*iface
, DWORD dwMsTimeout
,
5297 FILTER_STATE
*pState
)
5299 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5301 return MediaControl_GetState(&This
->IMediaControl_iface
, dwMsTimeout
, (OAFilterState
*)pState
);
5304 static HRESULT WINAPI
MediaFilter_SetSyncSource(IMediaFilter
*iface
, IReferenceClock
*pClock
)
5306 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5310 TRACE("(%p/%p)->(%p)\n", iface
, This
, pClock
);
5312 EnterCriticalSection(&This
->cs
);
5314 for (i
= 0;i
< This
->nFilters
;i
++)
5316 hr
= IBaseFilter_SetSyncSource(This
->ppFiltersInGraph
[i
], pClock
);
5324 IBaseFilter_SetSyncSource(This
->ppFiltersInGraph
[i
], This
->refClock
);
5329 IReferenceClock_Release(This
->refClock
);
5330 This
->refClock
= pClock
;
5332 IReferenceClock_AddRef(This
->refClock
);
5333 This
->defaultclock
= FALSE
;
5335 if (This
->HandleEcClockChanged
)
5337 IMediaEventSink
*pEventSink
;
5340 eshr
= IMediaFilter_QueryInterface(iface
, &IID_IMediaEventSink
, (void **)&pEventSink
);
5341 if (SUCCEEDED(eshr
))
5343 IMediaEventSink_Notify(pEventSink
, EC_CLOCK_CHANGED
, 0, 0);
5344 IMediaEventSink_Release(pEventSink
);
5349 LeaveCriticalSection(&This
->cs
);
5354 static HRESULT WINAPI
MediaFilter_GetSyncSource(IMediaFilter
*iface
, IReferenceClock
**ppClock
)
5356 IFilterGraphImpl
*This
= impl_from_IMediaFilter(iface
);
5358 TRACE("(%p/%p)->(%p)\n", iface
, This
, ppClock
);
5363 EnterCriticalSection(&This
->cs
);
5365 *ppClock
= This
->refClock
;
5367 IReferenceClock_AddRef(*ppClock
);
5369 LeaveCriticalSection(&This
->cs
);
5374 static const IMediaFilterVtbl IMediaFilter_VTable
=
5376 MediaFilter_QueryInterface
,
5378 MediaFilter_Release
,
5379 MediaFilter_GetClassID
,
5383 MediaFilter_GetState
,
5384 MediaFilter_SetSyncSource
,
5385 MediaFilter_GetSyncSource
5388 static inline IFilterGraphImpl
*impl_from_IMediaEventSink(IMediaEventSink
*iface
)
5390 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IMediaEventSink_iface
);
5393 static HRESULT WINAPI
MediaEventSink_QueryInterface(IMediaEventSink
*iface
, REFIID riid
, void **ppv
)
5395 IFilterGraphImpl
*This
= impl_from_IMediaEventSink(iface
);
5397 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
5400 static ULONG WINAPI
MediaEventSink_AddRef(IMediaEventSink
*iface
)
5402 IFilterGraphImpl
*This
= impl_from_IMediaEventSink(iface
);
5404 return IUnknown_AddRef(This
->outer_unk
);
5407 static ULONG WINAPI
MediaEventSink_Release(IMediaEventSink
*iface
)
5409 IFilterGraphImpl
*This
= impl_from_IMediaEventSink(iface
);
5411 return IUnknown_Release(This
->outer_unk
);
5414 static HRESULT WINAPI
MediaEventSink_Notify(IMediaEventSink
*iface
, LONG EventCode
,
5415 LONG_PTR EventParam1
, LONG_PTR EventParam2
)
5417 IFilterGraphImpl
*This
= impl_from_IMediaEventSink(iface
);
5420 TRACE("(%p/%p)->(%d, %ld, %ld)\n", This
, iface
, EventCode
, EventParam1
, EventParam2
);
5422 /* We need thread safety here, let's use the events queue's one */
5423 EnterCriticalSection(&This
->evqueue
.msg_crst
);
5425 if ((EventCode
== EC_COMPLETE
) && This
->HandleEcComplete
)
5427 TRACE("Process EC_COMPLETE notification\n");
5428 if (++This
->EcCompleteCount
== This
->nRenderers
)
5430 evt
.lEventCode
= EC_COMPLETE
;
5433 TRACE("Send EC_COMPLETE to app\n");
5434 EventsQueue_PutEvent(&This
->evqueue
, &evt
);
5435 if (!This
->notif
.disabled
&& This
->notif
.hWnd
)
5437 TRACE("Send Window message\n");
5438 PostMessageW(This
->notif
.hWnd
, This
->notif
.msg
, 0, This
->notif
.instance
);
5440 This
->CompletionStatus
= EC_COMPLETE
;
5441 SetEvent(This
->hEventCompletion
);
5444 else if ((EventCode
== EC_REPAINT
) && This
->HandleEcRepaint
)
5446 /* FIXME: Not handled yet */
5450 evt
.lEventCode
= EventCode
;
5451 evt
.lParam1
= EventParam1
;
5452 evt
.lParam2
= EventParam2
;
5453 EventsQueue_PutEvent(&This
->evqueue
, &evt
);
5454 if (!This
->notif
.disabled
&& This
->notif
.hWnd
)
5455 PostMessageW(This
->notif
.hWnd
, This
->notif
.msg
, 0, This
->notif
.instance
);
5458 LeaveCriticalSection(&This
->evqueue
.msg_crst
);
5462 static const IMediaEventSinkVtbl IMediaEventSink_VTable
=
5464 MediaEventSink_QueryInterface
,
5465 MediaEventSink_AddRef
,
5466 MediaEventSink_Release
,
5467 MediaEventSink_Notify
5470 static inline IFilterGraphImpl
*impl_from_IGraphConfig(IGraphConfig
*iface
)
5472 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IGraphConfig_iface
);
5475 static HRESULT WINAPI
GraphConfig_QueryInterface(IGraphConfig
*iface
, REFIID riid
, void **ppv
)
5477 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5479 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
5482 static ULONG WINAPI
GraphConfig_AddRef(IGraphConfig
*iface
)
5484 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5486 return IUnknown_AddRef(This
->outer_unk
);
5489 static ULONG WINAPI
GraphConfig_Release(IGraphConfig
*iface
)
5491 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5493 return IUnknown_Release(This
->outer_unk
);
5496 static HRESULT WINAPI
GraphConfig_Reconnect(IGraphConfig
*iface
, IPin
*pOutputPin
, IPin
*pInputPin
,
5497 const AM_MEDIA_TYPE
*pmtFirstConnection
, IBaseFilter
*pUsingFilter
, HANDLE hAbortEvent
,
5500 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5502 FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This
, pOutputPin
, pInputPin
, pmtFirstConnection
, pUsingFilter
, hAbortEvent
, dwFlags
);
5507 static HRESULT WINAPI
GraphConfig_Reconfigure(IGraphConfig
*iface
, IGraphConfigCallback
*pCallback
,
5508 void *pvContext
, DWORD dwFlags
, HANDLE hAbortEvent
)
5510 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5513 WARN("(%p)->(%p, %p, %x, %p): partial stub!\n", This
, pCallback
, pvContext
, dwFlags
, hAbortEvent
);
5516 FIXME("The parameter hAbortEvent is not handled!\n");
5518 EnterCriticalSection(&This
->cs
);
5520 hr
= IGraphConfigCallback_Reconfigure(pCallback
, pvContext
, dwFlags
);
5522 LeaveCriticalSection(&This
->cs
);
5527 static HRESULT WINAPI
GraphConfig_AddFilterToCache(IGraphConfig
*iface
, IBaseFilter
*pFilter
)
5529 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5531 FIXME("(%p)->(%p): stub!\n", This
, pFilter
);
5536 static HRESULT WINAPI
GraphConfig_EnumCacheFilter(IGraphConfig
*iface
, IEnumFilters
**pEnum
)
5538 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5540 FIXME("(%p)->(%p): stub!\n", This
, pEnum
);
5545 static HRESULT WINAPI
GraphConfig_RemoveFilterFromCache(IGraphConfig
*iface
, IBaseFilter
*pFilter
)
5547 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5549 FIXME("(%p)->(%p): stub!\n", This
, pFilter
);
5554 static HRESULT WINAPI
GraphConfig_GetStartTime(IGraphConfig
*iface
, REFERENCE_TIME
*prtStart
)
5556 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5558 FIXME("(%p)->(%p): stub!\n", This
, prtStart
);
5563 static HRESULT WINAPI
GraphConfig_PushThroughData(IGraphConfig
*iface
, IPin
*pOutputPin
,
5564 IPinConnection
*pConnection
, HANDLE hEventAbort
)
5566 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5568 FIXME("(%p)->(%p, %p, %p): stub!\n", This
, pOutputPin
, pConnection
, hEventAbort
);
5573 static HRESULT WINAPI
GraphConfig_SetFilterFlags(IGraphConfig
*iface
, IBaseFilter
*pFilter
,
5576 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5578 FIXME("(%p)->(%p, %x): stub!\n", This
, pFilter
, dwFlags
);
5583 static HRESULT WINAPI
GraphConfig_GetFilterFlags(IGraphConfig
*iface
, IBaseFilter
*pFilter
,
5586 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5588 FIXME("(%p)->(%p, %p): stub!\n", This
, pFilter
, dwFlags
);
5593 static HRESULT WINAPI
GraphConfig_RemoveFilterEx(IGraphConfig
*iface
, IBaseFilter
*pFilter
,
5596 IFilterGraphImpl
*This
= impl_from_IGraphConfig(iface
);
5598 FIXME("(%p)->(%p, %x): stub!\n", This
, pFilter
, dwFlags
);
5603 static const IGraphConfigVtbl IGraphConfig_VTable
=
5605 GraphConfig_QueryInterface
,
5607 GraphConfig_Release
,
5608 GraphConfig_Reconnect
,
5609 GraphConfig_Reconfigure
,
5610 GraphConfig_AddFilterToCache
,
5611 GraphConfig_EnumCacheFilter
,
5612 GraphConfig_RemoveFilterFromCache
,
5613 GraphConfig_GetStartTime
,
5614 GraphConfig_PushThroughData
,
5615 GraphConfig_SetFilterFlags
,
5616 GraphConfig_GetFilterFlags
,
5617 GraphConfig_RemoveFilterEx
5620 static inline IFilterGraphImpl
*impl_from_IGraphVersion(IGraphVersion
*iface
)
5622 return CONTAINING_RECORD(iface
, IFilterGraphImpl
, IGraphVersion_iface
);
5625 static HRESULT WINAPI
GraphVersion_QueryInterface(IGraphVersion
*iface
, REFIID riid
, void **ppv
)
5627 IFilterGraphImpl
*This
= impl_from_IGraphVersion(iface
);
5629 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
5632 static ULONG WINAPI
GraphVersion_AddRef(IGraphVersion
*iface
)
5634 IFilterGraphImpl
*This
= impl_from_IGraphVersion(iface
);
5636 return IUnknown_AddRef(This
->outer_unk
);
5639 static ULONG WINAPI
GraphVersion_Release(IGraphVersion
*iface
)
5641 IFilterGraphImpl
*This
= impl_from_IGraphVersion(iface
);
5643 return IUnknown_Release(This
->outer_unk
);
5646 static HRESULT WINAPI
GraphVersion_QueryVersion(IGraphVersion
*iface
, LONG
*pVersion
)
5648 IFilterGraphImpl
*This
= impl_from_IGraphVersion(iface
);
5653 TRACE("(%p)->(%p): current version %i\n", This
, pVersion
, This
->version
);
5655 *pVersion
= This
->version
;
5659 static const IGraphVersionVtbl IGraphVersion_VTable
=
5661 GraphVersion_QueryInterface
,
5662 GraphVersion_AddRef
,
5663 GraphVersion_Release
,
5664 GraphVersion_QueryVersion
,
5667 static const IUnknownVtbl IInner_VTable
=
5669 FilterGraphInner_QueryInterface
,
5670 FilterGraphInner_AddRef
,
5671 FilterGraphInner_Release
5674 /* This is the only function that actually creates a FilterGraph class... */
5675 HRESULT
FilterGraph_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
5677 IFilterGraphImpl
*fimpl
;
5680 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
5684 fimpl
= CoTaskMemAlloc(sizeof(*fimpl
));
5685 fimpl
->defaultclock
= TRUE
;
5686 fimpl
->IUnknown_inner
.lpVtbl
= &IInner_VTable
;
5687 fimpl
->IFilterGraph2_iface
.lpVtbl
= &IFilterGraph2_VTable
;
5688 fimpl
->IMediaControl_iface
.lpVtbl
= &IMediaControl_VTable
;
5689 fimpl
->IMediaSeeking_iface
.lpVtbl
= &IMediaSeeking_VTable
;
5690 fimpl
->IBasicAudio_iface
.lpVtbl
= &IBasicAudio_VTable
;
5691 fimpl
->IBasicVideo2_iface
.lpVtbl
= &IBasicVideo_VTable
;
5692 fimpl
->IVideoWindow_iface
.lpVtbl
= &IVideoWindow_VTable
;
5693 fimpl
->IMediaEventEx_iface
.lpVtbl
= &IMediaEventEx_VTable
;
5694 fimpl
->IMediaFilter_iface
.lpVtbl
= &IMediaFilter_VTable
;
5695 fimpl
->IMediaEventSink_iface
.lpVtbl
= &IMediaEventSink_VTable
;
5696 fimpl
->IGraphConfig_iface
.lpVtbl
= &IGraphConfig_VTable
;
5697 fimpl
->IMediaPosition_iface
.lpVtbl
= &IMediaPosition_VTable
;
5698 fimpl
->IObjectWithSite_iface
.lpVtbl
= &IObjectWithSite_VTable
;
5699 fimpl
->IGraphVersion_iface
.lpVtbl
= &IGraphVersion_VTable
;
5701 fimpl
->ppFiltersInGraph
= NULL
;
5702 fimpl
->pFilterNames
= NULL
;
5703 fimpl
->nFilters
= 0;
5704 fimpl
->filterCapacity
= 0;
5705 fimpl
->nameIndex
= 1;
5706 fimpl
->refClock
= NULL
;
5707 fimpl
->hEventCompletion
= CreateEventW(0, TRUE
, FALSE
, 0);
5708 fimpl
->HandleEcComplete
= TRUE
;
5709 fimpl
->HandleEcRepaint
= TRUE
;
5710 fimpl
->HandleEcClockChanged
= TRUE
;
5711 fimpl
->notif
.hWnd
= 0;
5712 fimpl
->notif
.disabled
= FALSE
;
5713 fimpl
->nRenderers
= 0;
5714 fimpl
->EcCompleteCount
= 0;
5715 fimpl
->refClockProvider
= NULL
;
5716 fimpl
->state
= State_Stopped
;
5717 fimpl
->pSite
= NULL
;
5718 EventsQueue_Init(&fimpl
->evqueue
);
5719 InitializeCriticalSection(&fimpl
->cs
);
5720 fimpl
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IFilterGraphImpl.cs");
5721 fimpl
->nItfCacheEntries
= 0;
5722 memcpy(&fimpl
->timeformatseek
, &TIME_FORMAT_MEDIA_TIME
, sizeof(GUID
));
5723 fimpl
->start_time
= fimpl
->pause_time
= 0;
5724 fimpl
->stop_position
= -1;
5725 fimpl
->punkFilterMapper2
= NULL
;
5726 fimpl
->recursioncount
= 0;
5730 fimpl
->outer_unk
= pUnkOuter
;
5732 fimpl
->outer_unk
= &fimpl
->IUnknown_inner
;
5734 /* create Filtermapper aggregated. */
5735 hr
= CoCreateInstance(&CLSID_FilterMapper2
, fimpl
->outer_unk
, CLSCTX_INPROC_SERVER
,
5736 &IID_IUnknown
, (void**)&fimpl
->punkFilterMapper2
);
5739 ERR("Unable to create filter mapper (%x)\n", hr
);
5740 if (fimpl
->punkFilterMapper2
) IUnknown_Release(fimpl
->punkFilterMapper2
);
5741 CloseHandle(fimpl
->hEventCompletion
);
5742 EventsQueue_Destroy(&fimpl
->evqueue
);
5743 fimpl
->cs
.DebugInfo
->Spare
[0] = 0;
5744 DeleteCriticalSection(&fimpl
->cs
);
5745 CoTaskMemFree(fimpl
);
5749 *ppObj
= &fimpl
->IUnknown_inner
;
5753 HRESULT
FilterGraphNoThread_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
5755 FIXME("CLSID_FilterGraphNoThread partially implemented - Forwarding to CLSID_FilterGraph\n");
5756 return FilterGraph_create(pUnkOuter
, ppObj
);