2 * Filter Seeking and Control Interfaces
4 * Copyright 2003 Robert Shearman
5 * Copyright 2012 Aric Stewart, CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* FIXME: critical sections */
28 #include "wine/debug.h"
29 #include "wine/strmbase.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(strmbase
);
35 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
;
36 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
;
38 typedef struct PassThruImpl
{
39 IUnknown IUnknown_inner
;
40 ISeekingPassThru ISeekingPassThru_iface
;
41 IMediaSeeking IMediaSeeking_iface
;
42 IMediaPosition IMediaPosition_iface
;
43 BaseDispatch baseDispatch
;
51 CRITICAL_SECTION time_cs
;
53 REFERENCE_TIME time_earliest
;
56 static inline PassThruImpl
*impl_from_IUnknown_inner(IUnknown
*iface
)
58 return CONTAINING_RECORD(iface
, PassThruImpl
, IUnknown_inner
);
61 static inline PassThruImpl
*impl_from_ISeekingPassThru(ISeekingPassThru
*iface
)
63 return CONTAINING_RECORD(iface
, PassThruImpl
, ISeekingPassThru_iface
);
66 static inline PassThruImpl
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
68 return CONTAINING_RECORD(iface
, PassThruImpl
, IMediaSeeking_iface
);
71 static inline PassThruImpl
*impl_from_IMediaPosition(IMediaPosition
*iface
)
73 return CONTAINING_RECORD(iface
, PassThruImpl
, IMediaPosition_iface
);
76 static HRESULT WINAPI
SeekInner_QueryInterface(IUnknown
* iface
,
79 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
80 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObj
);
82 if (This
->bAggregatable
)
83 This
->bUnkOuterValid
= TRUE
;
85 if (IsEqualGUID(&IID_IUnknown
, riid
))
87 *ppvObj
= &(This
->IUnknown_inner
);
88 TRACE(" returning IUnknown interface (%p)\n", *ppvObj
);
89 } else if (IsEqualGUID(&IID_ISeekingPassThru
, riid
)) {
90 *ppvObj
= &(This
->ISeekingPassThru_iface
);
91 TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj
);
92 } else if (IsEqualGUID(&IID_IMediaSeeking
, riid
)) {
93 *ppvObj
= &(This
->IMediaSeeking_iface
);
94 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj
);
95 } else if (IsEqualGUID(&IID_IMediaPosition
, riid
)) {
96 *ppvObj
= &(This
->IMediaPosition_iface
);
97 TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj
);
100 FIXME("unknown interface %s\n", debugstr_guid(riid
));
101 return E_NOINTERFACE
;
104 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
108 static ULONG WINAPI
SeekInner_AddRef(IUnknown
* iface
) {
109 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
110 ULONG ref
= InterlockedIncrement(&This
->ref
);
112 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
117 static ULONG WINAPI
SeekInner_Release(IUnknown
* iface
) {
118 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
119 ULONG ref
= InterlockedDecrement(&This
->ref
);
121 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
125 BaseDispatch_Destroy(&This
->baseDispatch
);
126 This
->time_cs
.DebugInfo
->Spare
[0] = 0;
127 DeleteCriticalSection(&This
->time_cs
);
133 static const IUnknownVtbl IInner_VTable
=
135 SeekInner_QueryInterface
,
140 /* Generic functions for aggregation */
141 static HRESULT
SeekOuter_QueryInterface(PassThruImpl
*This
, REFIID riid
, LPVOID
*ppv
)
143 if (This
->bAggregatable
)
144 This
->bUnkOuterValid
= TRUE
;
148 if (This
->bAggregatable
)
149 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
151 if (IsEqualIID(riid
, &IID_IUnknown
))
155 IUnknown_AddRef(&This
->IUnknown_inner
);
156 hr
= IUnknown_QueryInterface(&This
->IUnknown_inner
, riid
, ppv
);
157 IUnknown_Release(&This
->IUnknown_inner
);
158 This
->bAggregatable
= TRUE
;
163 return E_NOINTERFACE
;
166 return IUnknown_QueryInterface(&This
->IUnknown_inner
, riid
, ppv
);
169 static ULONG
SeekOuter_AddRef(PassThruImpl
*This
)
171 if (This
->outer_unk
&& This
->bUnkOuterValid
)
172 return IUnknown_AddRef(This
->outer_unk
);
173 return IUnknown_AddRef(&This
->IUnknown_inner
);
176 static ULONG
SeekOuter_Release(PassThruImpl
*This
)
178 if (This
->outer_unk
&& This
->bUnkOuterValid
)
179 return IUnknown_Release(This
->outer_unk
);
180 return IUnknown_Release(&This
->IUnknown_inner
);
183 static HRESULT WINAPI
SeekingPassThru_QueryInterface(ISeekingPassThru
*iface
, REFIID riid
, LPVOID
*ppvObj
)
185 PassThruImpl
*This
= impl_from_ISeekingPassThru(iface
);
187 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_guid(riid
), ppvObj
);
189 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
192 static ULONG WINAPI
SeekingPassThru_AddRef(ISeekingPassThru
*iface
)
194 PassThruImpl
*This
= impl_from_ISeekingPassThru(iface
);
196 TRACE("(%p/%p)->()\n", This
, iface
);
198 return SeekOuter_AddRef(This
);
201 static ULONG WINAPI
SeekingPassThru_Release(ISeekingPassThru
*iface
)
203 PassThruImpl
*This
= impl_from_ISeekingPassThru(iface
);
205 TRACE("(%p/%p)->()\n", This
, iface
);
207 return SeekOuter_Release(This
);
210 static HRESULT WINAPI
SeekingPassThru_Init(ISeekingPassThru
*iface
, BOOL renderer
, IPin
*pin
)
212 PassThruImpl
*This
= impl_from_ISeekingPassThru(iface
);
214 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, renderer
, pin
);
217 FIXME("Re-initializing?\n");
219 This
->renderer
= renderer
;
225 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl
=
227 SeekingPassThru_QueryInterface
,
228 SeekingPassThru_AddRef
,
229 SeekingPassThru_Release
,
233 HRESULT WINAPI
CreatePosPassThru(IUnknown
* pUnkOuter
, BOOL bRenderer
, IPin
*pPin
, IUnknown
**ppPassThru
)
236 ISeekingPassThru
*passthru
;
238 hr
= CoCreateInstance(&CLSID_SeekingPassThru
, pUnkOuter
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void**)ppPassThru
);
242 IUnknown_QueryInterface(*ppPassThru
, &IID_ISeekingPassThru
, (void**)&passthru
);
243 hr
= ISeekingPassThru_Init(passthru
, bRenderer
, pPin
);
244 ISeekingPassThru_Release(passthru
);
249 HRESULT WINAPI
PosPassThru_Construct(IUnknown
*pUnkOuter
, LPVOID
*ppPassThru
)
253 TRACE("(%p,%p)\n", pUnkOuter
, ppPassThru
);
255 *ppPassThru
= fimpl
= CoTaskMemAlloc(sizeof(*fimpl
));
257 return E_OUTOFMEMORY
;
259 fimpl
->outer_unk
= pUnkOuter
;
260 fimpl
->bUnkOuterValid
= FALSE
;
261 fimpl
->bAggregatable
= FALSE
;
262 fimpl
->IUnknown_inner
.lpVtbl
= &IInner_VTable
;
263 fimpl
->ISeekingPassThru_iface
.lpVtbl
= &ISeekingPassThru_Vtbl
;
264 fimpl
->IMediaSeeking_iface
.lpVtbl
= &IMediaSeekingPassThru_Vtbl
;
265 fimpl
->IMediaPosition_iface
.lpVtbl
= &IMediaPositionPassThru_Vtbl
;
268 fimpl
->timevalid
= FALSE
;
269 InitializeCriticalSection(&fimpl
->time_cs
);
270 fimpl
->time_cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": PassThruImpl.time_cs");
271 BaseDispatch_Init(&fimpl
->baseDispatch
, &IID_IMediaPosition
);
275 static HRESULT WINAPI
MediaSeekingPassThru_QueryInterface(IMediaSeeking
*iface
, REFIID riid
, LPVOID
*ppvObj
)
277 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
279 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_guid(riid
), ppvObj
);
281 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
284 static ULONG WINAPI
MediaSeekingPassThru_AddRef(IMediaSeeking
*iface
)
286 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
288 TRACE("(%p/%p)->()\n", iface
, This
);
290 return SeekOuter_AddRef(This
);
293 static ULONG WINAPI
MediaSeekingPassThru_Release(IMediaSeeking
*iface
)
295 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
297 TRACE("(%p/%p)->()\n", iface
, This
);
299 return SeekOuter_Release(This
);
302 static HRESULT
get_connected(PassThruImpl
*This
, REFIID riid
, LPVOID
*ppvObj
) {
306 hr
= IPin_ConnectedTo(This
->pin
, &pin
);
308 return VFW_E_NOT_CONNECTED
;
309 hr
= IPin_QueryInterface(pin
, riid
, ppvObj
);
316 static HRESULT WINAPI
MediaSeekingPassThru_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
318 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
321 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
322 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
324 hr
= IMediaSeeking_GetCapabilities(seek
, pCapabilities
);
325 IMediaSeeking_Release(seek
);
332 static HRESULT WINAPI
MediaSeekingPassThru_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
334 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
337 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
338 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
340 hr
= IMediaSeeking_CheckCapabilities(seek
, pCapabilities
);
341 IMediaSeeking_Release(seek
);
348 static HRESULT WINAPI
MediaSeekingPassThru_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
350 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
353 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
354 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
356 hr
= IMediaSeeking_IsFormatSupported(seek
, pFormat
);
357 IMediaSeeking_Release(seek
);
364 static HRESULT WINAPI
MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
366 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
369 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
370 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
372 hr
= IMediaSeeking_QueryPreferredFormat(seek
, pFormat
);
373 IMediaSeeking_Release(seek
);
380 static HRESULT WINAPI
MediaSeekingPassThru_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
382 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
385 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
386 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
388 hr
= IMediaSeeking_GetTimeFormat(seek
, pFormat
);
389 IMediaSeeking_Release(seek
);
396 static HRESULT WINAPI
MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
398 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
401 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
402 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
404 hr
= IMediaSeeking_IsUsingTimeFormat(seek
, pFormat
);
405 IMediaSeeking_Release(seek
);
412 static HRESULT WINAPI
MediaSeekingPassThru_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
414 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
417 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
418 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
420 hr
= IMediaSeeking_SetTimeFormat(seek
, pFormat
);
421 IMediaSeeking_Release(seek
);
428 static HRESULT WINAPI
MediaSeekingPassThru_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
430 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
433 TRACE("(%p/%p)->(%p)\n", iface
, This
, pDuration
);
434 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
436 hr
= IMediaSeeking_GetDuration(seek
, pDuration
);
437 IMediaSeeking_Release(seek
);
444 static HRESULT WINAPI
MediaSeekingPassThru_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
446 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
449 TRACE("(%p/%p)->(%p)\n", iface
, This
, pStop
);
450 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
452 hr
= IMediaSeeking_GetStopPosition(seek
, pStop
);
453 IMediaSeeking_Release(seek
);
460 static HRESULT WINAPI
MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
462 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
465 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCurrent
);
468 EnterCriticalSection(&This
->time_cs
);
470 *pCurrent
= This
->time_earliest
;
473 LeaveCriticalSection(&This
->time_cs
);
475 hr
= IMediaSeeking_ConvertTimeFormat(iface
, pCurrent
, NULL
, *pCurrent
, &TIME_FORMAT_MEDIA_TIME
);
478 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
480 hr
= IMediaSeeking_GetCurrentPosition(seek
, pCurrent
);
481 IMediaSeeking_Release(seek
);
488 static HRESULT WINAPI
MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
490 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
493 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface
, This
, pTarget
, debugstr_guid(pTargetFormat
), (DWORD
)(Source
>>32), (DWORD
)Source
, debugstr_guid(pSourceFormat
));
494 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
496 hr
= IMediaSeeking_ConvertTimeFormat(seek
, pTarget
, pTargetFormat
, Source
, pSourceFormat
);
497 IMediaSeeking_Release(seek
);
504 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
506 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
509 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface
, This
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
510 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
512 hr
= IMediaSeeking_SetPositions(seek
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
513 IMediaSeeking_Release(seek
);
514 } else if (hr
== VFW_E_NOT_CONNECTED
)
519 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
521 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
524 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
525 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
527 hr
= IMediaSeeking_GetPositions(seek
, pCurrent
, pStop
);
528 IMediaSeeking_Release(seek
);
529 } else if (hr
== VFW_E_NOT_CONNECTED
) {
537 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
539 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
542 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
543 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
545 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
546 IMediaSeeking_Release(seek
);
553 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
555 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
558 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
559 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
561 hr
= IMediaSeeking_SetRate(seek
, dRate
);
562 IMediaSeeking_Release(seek
);
569 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
571 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
574 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
575 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
577 hr
= IMediaSeeking_GetRate(seek
, dRate
);
578 IMediaSeeking_Release(seek
);
585 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
587 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
590 TRACE("(%p)\n", pPreroll
);
591 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
593 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
594 IMediaSeeking_Release(seek
);
601 HRESULT WINAPI
RendererPosPassThru_RegisterMediaTime(IUnknown
*iface
, REFERENCE_TIME start
)
603 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
604 EnterCriticalSection(&This
->time_cs
);
605 This
->time_earliest
= start
;
606 This
->timevalid
= TRUE
;
607 LeaveCriticalSection(&This
->time_cs
);
611 HRESULT WINAPI
RendererPosPassThru_ResetMediaTime(IUnknown
*iface
)
613 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
614 EnterCriticalSection(&This
->time_cs
);
615 This
->timevalid
= FALSE
;
616 LeaveCriticalSection(&This
->time_cs
);
620 HRESULT WINAPI
RendererPosPassThru_EOS(IUnknown
*iface
)
622 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
625 hr
= IMediaSeeking_GetStopPosition(&This
->IMediaSeeking_iface
, &time
);
626 EnterCriticalSection(&This
->time_cs
);
628 This
->timevalid
= TRUE
;
629 This
->time_earliest
= time
;
631 This
->timevalid
= FALSE
;
632 LeaveCriticalSection(&This
->time_cs
);
636 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
638 MediaSeekingPassThru_QueryInterface
,
639 MediaSeekingPassThru_AddRef
,
640 MediaSeekingPassThru_Release
,
641 MediaSeekingPassThru_GetCapabilities
,
642 MediaSeekingPassThru_CheckCapabilities
,
643 MediaSeekingPassThru_IsFormatSupported
,
644 MediaSeekingPassThru_QueryPreferredFormat
,
645 MediaSeekingPassThru_GetTimeFormat
,
646 MediaSeekingPassThru_IsUsingTimeFormat
,
647 MediaSeekingPassThru_SetTimeFormat
,
648 MediaSeekingPassThru_GetDuration
,
649 MediaSeekingPassThru_GetStopPosition
,
650 MediaSeekingPassThru_GetCurrentPosition
,
651 MediaSeekingPassThru_ConvertTimeFormat
,
652 MediaSeekingPassThru_SetPositions
,
653 MediaSeekingPassThru_GetPositions
,
654 MediaSeekingPassThru_GetAvailable
,
655 MediaSeekingPassThru_SetRate
,
656 MediaSeekingPassThru_GetRate
,
657 MediaSeekingPassThru_GetPreroll
660 static HRESULT WINAPI
MediaPositionPassThru_QueryInterface(IMediaPosition
*iface
, REFIID riid
, LPVOID
*ppvObj
)
662 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
664 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_guid(riid
), ppvObj
);
666 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
669 static ULONG WINAPI
MediaPositionPassThru_AddRef(IMediaPosition
*iface
)
671 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
673 TRACE("(%p/%p)->()\n", iface
, This
);
675 return SeekOuter_AddRef(This
);
678 static ULONG WINAPI
MediaPositionPassThru_Release(IMediaPosition
*iface
)
680 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
682 TRACE("(%p/%p)->()\n", iface
, This
);
684 return SeekOuter_Release(This
);
687 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfoCount(IMediaPosition
*iface
, UINT
*pctinfo
)
689 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
691 return BaseDispatchImpl_GetTypeInfoCount(&This
->baseDispatch
, pctinfo
);
694 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfo(IMediaPosition
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
696 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
698 return BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, &IID_NULL
, iTInfo
, lcid
, ppTInfo
);
701 static HRESULT WINAPI
MediaPositionPassThru_GetIDsOfNames(IMediaPosition
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
703 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
705 return BaseDispatchImpl_GetIDsOfNames(&This
->baseDispatch
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
708 static HRESULT WINAPI
MediaPositionPassThru_Invoke(IMediaPosition
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
, UINT
*puArgErr
)
710 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
712 ITypeInfo
*pTypeInfo
;
714 hr
= BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, riid
, 1, lcid
, &pTypeInfo
);
717 hr
= ITypeInfo_Invoke(pTypeInfo
, &This
->IMediaPosition_iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
718 ITypeInfo_Release(pTypeInfo
);
724 static HRESULT WINAPI
MediaPositionPassThru_get_Duration(IMediaPosition
*iface
, REFTIME
*plength
)
726 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
730 TRACE("(%p)\n", plength
);
732 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
734 hr
= IMediaPosition_get_Duration(pos
, plength
);
735 IMediaPosition_Release(pos
);
742 static HRESULT WINAPI
MediaPositionPassThru_put_CurrentPosition(IMediaPosition
*iface
, REFTIME llTime
)
744 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
748 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
750 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
752 hr
= IMediaPosition_put_CurrentPosition(pos
, llTime
);
753 IMediaPosition_Release(pos
);
760 static HRESULT WINAPI
MediaPositionPassThru_get_CurrentPosition(IMediaPosition
*iface
, REFTIME
*pllTime
)
762 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
766 TRACE("(%p)\n", pllTime
);
768 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
770 hr
= IMediaPosition_get_CurrentPosition(pos
, pllTime
);
771 IMediaPosition_Release(pos
);
778 static HRESULT WINAPI
MediaPositionPassThru_get_StopTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
780 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
784 TRACE("(%p)\n", pllTime
);
786 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
788 hr
= IMediaPosition_get_StopTime(pos
, pllTime
);
789 IMediaPosition_Release(pos
);
796 static HRESULT WINAPI
MediaPositionPassThru_put_StopTime(IMediaPosition
*iface
, REFTIME llTime
)
798 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
802 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
804 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
806 hr
= IMediaPosition_put_StopTime(pos
, llTime
);
807 IMediaPosition_Release(pos
);
814 static HRESULT WINAPI
MediaPositionPassThru_get_PrerollTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
816 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
820 TRACE("(%p)\n", pllTime
);
822 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
824 hr
= IMediaPosition_get_PrerollTime(pos
, pllTime
);
825 IMediaPosition_Release(pos
);
832 static HRESULT WINAPI
MediaPositionPassThru_put_PrerollTime(IMediaPosition
*iface
, REFTIME llTime
)
834 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
838 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
840 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
842 hr
= IMediaPosition_put_PrerollTime(pos
, llTime
);
843 IMediaPosition_Release(pos
);
850 static HRESULT WINAPI
MediaPositionPassThru_put_Rate(IMediaPosition
*iface
, double dRate
)
852 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
856 TRACE("(%f)\n", dRate
);
858 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
860 hr
= IMediaPosition_put_Rate(pos
, dRate
);
861 IMediaPosition_Release(pos
);
868 static HRESULT WINAPI
MediaPositionPassThru_get_Rate(IMediaPosition
*iface
, double *pdRate
)
870 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
874 TRACE("(%p)\n", pdRate
);
876 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
878 hr
= IMediaPosition_get_Rate(pos
, pdRate
);
879 IMediaPosition_Release(pos
);
886 static HRESULT WINAPI
MediaPositionPassThru_CanSeekForward(IMediaPosition
*iface
, LONG
*pCanSeekForward
)
888 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
892 TRACE("(%p)\n", pCanSeekForward
);
894 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
896 hr
= IMediaPosition_CanSeekForward(pos
, pCanSeekForward
);
897 IMediaPosition_Release(pos
);
904 static HRESULT WINAPI
MediaPositionPassThru_CanSeekBackward(IMediaPosition
*iface
, LONG
*pCanSeekBackward
)
906 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
910 TRACE("(%p)\n", pCanSeekBackward
);
912 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
914 hr
= IMediaPosition_CanSeekBackward(pos
, pCanSeekBackward
);
915 IMediaPosition_Release(pos
);
922 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
=
924 MediaPositionPassThru_QueryInterface
,
925 MediaPositionPassThru_AddRef
,
926 MediaPositionPassThru_Release
,
927 MediaPositionPassThru_GetTypeInfoCount
,
928 MediaPositionPassThru_GetTypeInfo
,
929 MediaPositionPassThru_GetIDsOfNames
,
930 MediaPositionPassThru_Invoke
,
931 MediaPositionPassThru_get_Duration
,
932 MediaPositionPassThru_put_CurrentPosition
,
933 MediaPositionPassThru_get_CurrentPosition
,
934 MediaPositionPassThru_get_StopTime
,
935 MediaPositionPassThru_put_StopTime
,
936 MediaPositionPassThru_get_PrerollTime
,
937 MediaPositionPassThru_put_PrerollTime
,
938 MediaPositionPassThru_put_Rate
,
939 MediaPositionPassThru_get_Rate
,
940 MediaPositionPassThru_CanSeekForward
,
941 MediaPositionPassThru_CanSeekBackward