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), %p)\n", This
, debugstr_guid(riid
), 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((IUnknown
*)&(This
->IUnknown_inner
));
156 hr
= IUnknown_QueryInterface((IUnknown
*)&(This
->IUnknown_inner
), riid
, ppv
);
157 IUnknown_Release((IUnknown
*)&(This
->IUnknown_inner
));
158 This
->bAggregatable
= TRUE
;
163 return E_NOINTERFACE
;
166 return IUnknown_QueryInterface((IUnknown
*)&(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((IUnknown
*)&(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((IUnknown
*)&(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), %p)\n", This
, iface
, debugstr_guid(riid
), 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), %p)\n", This
, iface
, debugstr_guid(riid
), 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
);
535 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
537 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
540 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
541 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
543 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
544 IMediaSeeking_Release(seek
);
551 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
553 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
556 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
557 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
559 hr
= IMediaSeeking_SetRate(seek
, dRate
);
560 IMediaSeeking_Release(seek
);
567 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
569 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
572 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
573 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
575 hr
= IMediaSeeking_GetRate(seek
, dRate
);
576 IMediaSeeking_Release(seek
);
583 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
585 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
588 TRACE("(%p)\n", pPreroll
);
589 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
591 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
592 IMediaSeeking_Release(seek
);
599 HRESULT WINAPI
RendererPosPassThru_RegisterMediaTime(IUnknown
*iface
, REFERENCE_TIME start
)
601 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
602 EnterCriticalSection(&This
->time_cs
);
603 This
->time_earliest
= start
;
604 This
->timevalid
= TRUE
;
605 LeaveCriticalSection(&This
->time_cs
);
609 HRESULT WINAPI
RendererPosPassThru_ResetMediaTime(IUnknown
*iface
)
611 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
612 EnterCriticalSection(&This
->time_cs
);
613 This
->timevalid
= FALSE
;
614 LeaveCriticalSection(&This
->time_cs
);
618 HRESULT WINAPI
RendererPosPassThru_EOS(IUnknown
*iface
)
620 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
623 hr
= IMediaSeeking_GetStopPosition(&This
->IMediaSeeking_iface
, &time
);
624 EnterCriticalSection(&This
->time_cs
);
626 This
->timevalid
= TRUE
;
627 This
->time_earliest
= time
;
629 This
->timevalid
= FALSE
;
630 LeaveCriticalSection(&This
->time_cs
);
634 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
636 MediaSeekingPassThru_QueryInterface
,
637 MediaSeekingPassThru_AddRef
,
638 MediaSeekingPassThru_Release
,
639 MediaSeekingPassThru_GetCapabilities
,
640 MediaSeekingPassThru_CheckCapabilities
,
641 MediaSeekingPassThru_IsFormatSupported
,
642 MediaSeekingPassThru_QueryPreferredFormat
,
643 MediaSeekingPassThru_GetTimeFormat
,
644 MediaSeekingPassThru_IsUsingTimeFormat
,
645 MediaSeekingPassThru_SetTimeFormat
,
646 MediaSeekingPassThru_GetDuration
,
647 MediaSeekingPassThru_GetStopPosition
,
648 MediaSeekingPassThru_GetCurrentPosition
,
649 MediaSeekingPassThru_ConvertTimeFormat
,
650 MediaSeekingPassThru_SetPositions
,
651 MediaSeekingPassThru_GetPositions
,
652 MediaSeekingPassThru_GetAvailable
,
653 MediaSeekingPassThru_SetRate
,
654 MediaSeekingPassThru_GetRate
,
655 MediaSeekingPassThru_GetPreroll
658 static HRESULT WINAPI
MediaPositionPassThru_QueryInterface(IMediaPosition
*iface
, REFIID riid
, LPVOID
*ppvObj
)
660 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
662 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
664 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
667 static ULONG WINAPI
MediaPositionPassThru_AddRef(IMediaPosition
*iface
)
669 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
671 TRACE("(%p/%p)->()\n", iface
, This
);
673 return SeekOuter_AddRef(This
);
676 static ULONG WINAPI
MediaPositionPassThru_Release(IMediaPosition
*iface
)
678 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
680 TRACE("(%p/%p)->()\n", iface
, This
);
682 return SeekOuter_Release(This
);
685 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfoCount(IMediaPosition
*iface
, UINT
*pctinfo
)
687 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
689 return BaseDispatchImpl_GetTypeInfoCount(&This
->baseDispatch
, pctinfo
);
692 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfo(IMediaPosition
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
694 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
696 return BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, &IID_NULL
, iTInfo
, lcid
, ppTInfo
);
699 static HRESULT WINAPI
MediaPositionPassThru_GetIDsOfNames(IMediaPosition
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
701 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
703 return BaseDispatchImpl_GetIDsOfNames(&This
->baseDispatch
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
706 static HRESULT WINAPI
MediaPositionPassThru_Invoke(IMediaPosition
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
, UINT
*puArgErr
)
708 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
710 ITypeInfo
*pTypeInfo
;
712 hr
= BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, riid
, 1, lcid
, &pTypeInfo
);
715 hr
= ITypeInfo_Invoke(pTypeInfo
, &This
->IMediaPosition_iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
716 ITypeInfo_Release(pTypeInfo
);
722 static HRESULT WINAPI
MediaPositionPassThru_get_Duration(IMediaPosition
*iface
, REFTIME
*plength
)
724 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
728 TRACE("(%p)\n", plength
);
730 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
732 hr
= IMediaPosition_get_Duration(pos
, plength
);
733 IMediaPosition_Release(pos
);
740 static HRESULT WINAPI
MediaPositionPassThru_put_CurrentPosition(IMediaPosition
*iface
, REFTIME llTime
)
742 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
746 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
748 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
750 hr
= IMediaPosition_put_CurrentPosition(pos
, llTime
);
751 IMediaPosition_Release(pos
);
758 static HRESULT WINAPI
MediaPositionPassThru_get_CurrentPosition(IMediaPosition
*iface
, REFTIME
*pllTime
)
760 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
764 TRACE("(%p)\n", pllTime
);
766 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
768 hr
= IMediaPosition_get_CurrentPosition(pos
, pllTime
);
769 IMediaPosition_Release(pos
);
776 static HRESULT WINAPI
MediaPositionPassThru_get_StopTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
778 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
782 TRACE("(%p)\n", pllTime
);
784 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
786 hr
= IMediaPosition_get_StopTime(pos
, pllTime
);
787 IMediaPosition_Release(pos
);
794 static HRESULT WINAPI
MediaPositionPassThru_put_StopTime(IMediaPosition
*iface
, REFTIME llTime
)
796 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
800 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
802 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
804 hr
= IMediaPosition_put_StopTime(pos
, llTime
);
805 IMediaPosition_Release(pos
);
812 static HRESULT WINAPI
MediaPositionPassThru_get_PrerollTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
814 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
818 TRACE("(%p)\n", pllTime
);
820 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
822 hr
= IMediaPosition_get_PrerollTime(pos
, pllTime
);
823 IMediaPosition_Release(pos
);
830 static HRESULT WINAPI
MediaPositionPassThru_put_PrerollTime(IMediaPosition
*iface
, REFTIME llTime
)
832 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
836 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
838 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
840 hr
= IMediaPosition_put_PrerollTime(pos
, llTime
);
841 IMediaPosition_Release(pos
);
848 static HRESULT WINAPI
MediaPositionPassThru_put_Rate(IMediaPosition
*iface
, double dRate
)
850 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
854 TRACE("(%f)\n", dRate
);
856 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
858 hr
= IMediaPosition_put_Rate(pos
, dRate
);
859 IMediaPosition_Release(pos
);
866 static HRESULT WINAPI
MediaPositionPassThru_get_Rate(IMediaPosition
*iface
, double *pdRate
)
868 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
872 TRACE("(%p)\n", pdRate
);
874 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
876 hr
= IMediaPosition_get_Rate(pos
, pdRate
);
877 IMediaPosition_Release(pos
);
884 static HRESULT WINAPI
MediaPositionPassThru_CanSeekForward(IMediaPosition
*iface
, LONG
*pCanSeekForward
)
886 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
890 TRACE("(%p)\n", pCanSeekForward
);
892 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
894 hr
= IMediaPosition_CanSeekForward(pos
, pCanSeekForward
);
895 IMediaPosition_Release(pos
);
902 static HRESULT WINAPI
MediaPositionPassThru_CanSeekBackward(IMediaPosition
*iface
, LONG
*pCanSeekBackward
)
904 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
908 TRACE("(%p)\n", pCanSeekBackward
);
910 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
912 hr
= IMediaPosition_CanSeekBackward(pos
, pCanSeekBackward
);
913 IMediaPosition_Release(pos
);
920 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
=
922 MediaPositionPassThru_QueryInterface
,
923 MediaPositionPassThru_AddRef
,
924 MediaPositionPassThru_Release
,
925 MediaPositionPassThru_GetTypeInfoCount
,
926 MediaPositionPassThru_GetTypeInfo
,
927 MediaPositionPassThru_GetIDsOfNames
,
928 MediaPositionPassThru_Invoke
,
929 MediaPositionPassThru_get_Duration
,
930 MediaPositionPassThru_put_CurrentPosition
,
931 MediaPositionPassThru_get_CurrentPosition
,
932 MediaPositionPassThru_get_StopTime
,
933 MediaPositionPassThru_put_StopTime
,
934 MediaPositionPassThru_get_PrerollTime
,
935 MediaPositionPassThru_put_PrerollTime
,
936 MediaPositionPassThru_put_Rate
,
937 MediaPositionPassThru_get_Rate
,
938 MediaPositionPassThru_CanSeekForward
,
939 MediaPositionPassThru_CanSeekBackward