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
);
240 IUnknown_QueryInterface(*ppPassThru
, &IID_ISeekingPassThru
, (void**)&passthru
);
241 hr
= ISeekingPassThru_Init(passthru
, bRenderer
, pPin
);
242 ISeekingPassThru_Release(passthru
);
247 HRESULT WINAPI
PosPassThru_Construct(IUnknown
*pUnkOuter
, LPVOID
*ppPassThru
)
251 TRACE("(%p,%p)\n", pUnkOuter
, ppPassThru
);
253 *ppPassThru
= fimpl
= CoTaskMemAlloc(sizeof(*fimpl
));
255 return E_OUTOFMEMORY
;
257 fimpl
->outer_unk
= pUnkOuter
;
258 fimpl
->bUnkOuterValid
= FALSE
;
259 fimpl
->bAggregatable
= FALSE
;
260 fimpl
->IUnknown_inner
.lpVtbl
= &IInner_VTable
;
261 fimpl
->ISeekingPassThru_iface
.lpVtbl
= &ISeekingPassThru_Vtbl
;
262 fimpl
->IMediaSeeking_iface
.lpVtbl
= &IMediaSeekingPassThru_Vtbl
;
263 fimpl
->IMediaPosition_iface
.lpVtbl
= &IMediaPositionPassThru_Vtbl
;
266 fimpl
->timevalid
= FALSE
;
267 InitializeCriticalSection(&fimpl
->time_cs
);
268 fimpl
->time_cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": PassThruImpl.time_cs");
269 BaseDispatch_Init(&fimpl
->baseDispatch
, &IID_IMediaPosition
);
273 static HRESULT WINAPI
MediaSeekingPassThru_QueryInterface(IMediaSeeking
*iface
, REFIID riid
, LPVOID
*ppvObj
)
275 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
277 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
279 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
282 static ULONG WINAPI
MediaSeekingPassThru_AddRef(IMediaSeeking
*iface
)
284 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
286 TRACE("(%p/%p)->()\n", iface
, This
);
288 return SeekOuter_AddRef(This
);
291 static ULONG WINAPI
MediaSeekingPassThru_Release(IMediaSeeking
*iface
)
293 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
295 TRACE("(%p/%p)->()\n", iface
, This
);
297 return SeekOuter_Release(This
);
300 static HRESULT
get_connected(PassThruImpl
*This
, REFIID riid
, LPVOID
*ppvObj
) {
304 hr
= IPin_ConnectedTo(This
->pin
, &pin
);
306 return VFW_E_NOT_CONNECTED
;
307 hr
= IPin_QueryInterface(pin
, riid
, ppvObj
);
314 static HRESULT WINAPI
MediaSeekingPassThru_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
316 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
319 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
320 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
322 hr
= IMediaSeeking_GetCapabilities(seek
, pCapabilities
);
323 IMediaSeeking_Release(seek
);
330 static HRESULT WINAPI
MediaSeekingPassThru_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
332 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
335 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
336 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
338 hr
= IMediaSeeking_CheckCapabilities(seek
, pCapabilities
);
339 IMediaSeeking_Release(seek
);
346 static HRESULT WINAPI
MediaSeekingPassThru_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
348 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
351 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
352 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
354 hr
= IMediaSeeking_IsFormatSupported(seek
, pFormat
);
355 IMediaSeeking_Release(seek
);
362 static HRESULT WINAPI
MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
364 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
367 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
368 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
370 hr
= IMediaSeeking_QueryPreferredFormat(seek
, pFormat
);
371 IMediaSeeking_Release(seek
);
378 static HRESULT WINAPI
MediaSeekingPassThru_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
380 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
383 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
384 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
386 hr
= IMediaSeeking_GetTimeFormat(seek
, pFormat
);
387 IMediaSeeking_Release(seek
);
394 static HRESULT WINAPI
MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
396 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
399 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
400 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
402 hr
= IMediaSeeking_IsUsingTimeFormat(seek
, pFormat
);
403 IMediaSeeking_Release(seek
);
410 static HRESULT WINAPI
MediaSeekingPassThru_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
412 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
415 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
416 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
418 hr
= IMediaSeeking_SetTimeFormat(seek
, pFormat
);
419 IMediaSeeking_Release(seek
);
426 static HRESULT WINAPI
MediaSeekingPassThru_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
428 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
431 TRACE("(%p/%p)->(%p)\n", iface
, This
, pDuration
);
432 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
434 hr
= IMediaSeeking_GetDuration(seek
, pDuration
);
435 IMediaSeeking_Release(seek
);
442 static HRESULT WINAPI
MediaSeekingPassThru_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
444 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
447 TRACE("(%p/%p)->(%p)\n", iface
, This
, pStop
);
448 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
450 hr
= IMediaSeeking_GetStopPosition(seek
, pStop
);
451 IMediaSeeking_Release(seek
);
458 static HRESULT WINAPI
MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
460 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
463 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCurrent
);
466 EnterCriticalSection(&This
->time_cs
);
468 *pCurrent
= This
->time_earliest
;
471 LeaveCriticalSection(&This
->time_cs
);
473 hr
= IMediaSeeking_ConvertTimeFormat(iface
, pCurrent
, NULL
, *pCurrent
, &TIME_FORMAT_MEDIA_TIME
);
476 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
478 hr
= IMediaSeeking_GetCurrentPosition(seek
, pCurrent
);
479 IMediaSeeking_Release(seek
);
486 static HRESULT WINAPI
MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
488 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
491 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface
, This
, pTarget
, debugstr_guid(pTargetFormat
), (DWORD
)(Source
>>32), (DWORD
)Source
, debugstr_guid(pSourceFormat
));
492 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
494 hr
= IMediaSeeking_ConvertTimeFormat(seek
, pTarget
, pTargetFormat
, Source
, pSourceFormat
);
495 IMediaSeeking_Release(seek
);
502 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
504 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
507 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface
, This
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
508 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
510 hr
= IMediaSeeking_SetPositions(seek
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
511 IMediaSeeking_Release(seek
);
512 } else if (hr
== VFW_E_NOT_CONNECTED
)
517 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
519 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
522 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
523 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
525 hr
= IMediaSeeking_GetPositions(seek
, pCurrent
, pStop
);
526 IMediaSeeking_Release(seek
);
533 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
535 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
538 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
539 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
541 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
542 IMediaSeeking_Release(seek
);
549 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
551 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
554 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
555 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
557 hr
= IMediaSeeking_SetRate(seek
, dRate
);
558 IMediaSeeking_Release(seek
);
565 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
567 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
570 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
571 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
573 hr
= IMediaSeeking_GetRate(seek
, dRate
);
574 IMediaSeeking_Release(seek
);
581 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
583 PassThruImpl
*This
= impl_from_IMediaSeeking(iface
);
586 TRACE("(%p)\n", pPreroll
);
587 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
589 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
590 IMediaSeeking_Release(seek
);
597 HRESULT WINAPI
RendererPosPassThru_RegisterMediaTime(IUnknown
*iface
, REFERENCE_TIME start
)
599 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
600 EnterCriticalSection(&This
->time_cs
);
601 This
->time_earliest
= start
;
602 This
->timevalid
= TRUE
;
603 LeaveCriticalSection(&This
->time_cs
);
607 HRESULT WINAPI
RendererPosPassThru_ResetMediaTime(IUnknown
*iface
)
609 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
610 EnterCriticalSection(&This
->time_cs
);
611 This
->timevalid
= FALSE
;
612 LeaveCriticalSection(&This
->time_cs
);
616 HRESULT WINAPI
RendererPosPassThru_EOS(IUnknown
*iface
)
618 PassThruImpl
*This
= impl_from_IUnknown_inner(iface
);
621 hr
= IMediaSeeking_GetStopPosition(&This
->IMediaSeeking_iface
, &time
);
622 EnterCriticalSection(&This
->time_cs
);
624 This
->timevalid
= TRUE
;
625 This
->time_earliest
= time
;
627 This
->timevalid
= FALSE
;
628 LeaveCriticalSection(&This
->time_cs
);
632 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
634 MediaSeekingPassThru_QueryInterface
,
635 MediaSeekingPassThru_AddRef
,
636 MediaSeekingPassThru_Release
,
637 MediaSeekingPassThru_GetCapabilities
,
638 MediaSeekingPassThru_CheckCapabilities
,
639 MediaSeekingPassThru_IsFormatSupported
,
640 MediaSeekingPassThru_QueryPreferredFormat
,
641 MediaSeekingPassThru_GetTimeFormat
,
642 MediaSeekingPassThru_IsUsingTimeFormat
,
643 MediaSeekingPassThru_SetTimeFormat
,
644 MediaSeekingPassThru_GetDuration
,
645 MediaSeekingPassThru_GetStopPosition
,
646 MediaSeekingPassThru_GetCurrentPosition
,
647 MediaSeekingPassThru_ConvertTimeFormat
,
648 MediaSeekingPassThru_SetPositions
,
649 MediaSeekingPassThru_GetPositions
,
650 MediaSeekingPassThru_GetAvailable
,
651 MediaSeekingPassThru_SetRate
,
652 MediaSeekingPassThru_GetRate
,
653 MediaSeekingPassThru_GetPreroll
656 static HRESULT WINAPI
MediaPositionPassThru_QueryInterface(IMediaPosition
*iface
, REFIID riid
, LPVOID
*ppvObj
)
658 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
660 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
662 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
665 static ULONG WINAPI
MediaPositionPassThru_AddRef(IMediaPosition
*iface
)
667 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
669 TRACE("(%p/%p)->()\n", iface
, This
);
671 return SeekOuter_AddRef(This
);
674 static ULONG WINAPI
MediaPositionPassThru_Release(IMediaPosition
*iface
)
676 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
678 TRACE("(%p/%p)->()\n", iface
, This
);
680 return SeekOuter_Release(This
);
683 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfoCount(IMediaPosition
*iface
, UINT
*pctinfo
)
685 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
687 return BaseDispatchImpl_GetTypeInfoCount(&This
->baseDispatch
, pctinfo
);
690 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfo(IMediaPosition
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
692 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
694 return BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, &IID_NULL
, iTInfo
, lcid
, ppTInfo
);
697 static HRESULT WINAPI
MediaPositionPassThru_GetIDsOfNames(IMediaPosition
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
699 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
701 return BaseDispatchImpl_GetIDsOfNames(&This
->baseDispatch
, riid
, rgszNames
, cNames
, lcid
, rgDispId
);
704 static HRESULT WINAPI
MediaPositionPassThru_Invoke(IMediaPosition
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExepInfo
, UINT
*puArgErr
)
706 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
708 ITypeInfo
*pTypeInfo
;
710 hr
= BaseDispatchImpl_GetTypeInfo(&This
->baseDispatch
, riid
, 1, lcid
, &pTypeInfo
);
713 hr
= ITypeInfo_Invoke(pTypeInfo
, &This
->IMediaPosition_iface
, dispIdMember
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
714 ITypeInfo_Release(pTypeInfo
);
720 static HRESULT WINAPI
MediaPositionPassThru_get_Duration(IMediaPosition
*iface
, REFTIME
*plength
)
722 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
726 TRACE("(%p)\n", plength
);
728 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
730 hr
= IMediaPosition_get_Duration(pos
, plength
);
731 IMediaPosition_Release(pos
);
738 static HRESULT WINAPI
MediaPositionPassThru_put_CurrentPosition(IMediaPosition
*iface
, REFTIME llTime
)
740 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
744 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
746 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
748 hr
= IMediaPosition_put_CurrentPosition(pos
, llTime
);
749 IMediaPosition_Release(pos
);
756 static HRESULT WINAPI
MediaPositionPassThru_get_CurrentPosition(IMediaPosition
*iface
, REFTIME
*pllTime
)
758 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
762 TRACE("(%p)\n", pllTime
);
764 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
766 hr
= IMediaPosition_get_CurrentPosition(pos
, pllTime
);
767 IMediaPosition_Release(pos
);
774 static HRESULT WINAPI
MediaPositionPassThru_get_StopTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
776 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
780 TRACE("(%p)\n", pllTime
);
782 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
784 hr
= IMediaPosition_get_StopTime(pos
, pllTime
);
785 IMediaPosition_Release(pos
);
792 static HRESULT WINAPI
MediaPositionPassThru_put_StopTime(IMediaPosition
*iface
, REFTIME llTime
)
794 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
798 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
800 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
802 hr
= IMediaPosition_put_StopTime(pos
, llTime
);
803 IMediaPosition_Release(pos
);
810 static HRESULT WINAPI
MediaPositionPassThru_get_PrerollTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
812 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
816 TRACE("(%p)\n", pllTime
);
818 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
820 hr
= IMediaPosition_get_PrerollTime(pos
, pllTime
);
821 IMediaPosition_Release(pos
);
828 static HRESULT WINAPI
MediaPositionPassThru_put_PrerollTime(IMediaPosition
*iface
, REFTIME llTime
)
830 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
834 TRACE("(%s)\n", wine_dbgstr_longlong(llTime
));
836 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
838 hr
= IMediaPosition_put_PrerollTime(pos
, llTime
);
839 IMediaPosition_Release(pos
);
846 static HRESULT WINAPI
MediaPositionPassThru_put_Rate(IMediaPosition
*iface
, double dRate
)
848 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
852 TRACE("(%f)\n", dRate
);
854 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
856 hr
= IMediaPosition_put_Rate(pos
, dRate
);
857 IMediaPosition_Release(pos
);
864 static HRESULT WINAPI
MediaPositionPassThru_get_Rate(IMediaPosition
*iface
, double *pdRate
)
866 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
870 TRACE("(%p)\n", pdRate
);
872 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
874 hr
= IMediaPosition_get_Rate(pos
, pdRate
);
875 IMediaPosition_Release(pos
);
882 static HRESULT WINAPI
MediaPositionPassThru_CanSeekForward(IMediaPosition
*iface
, LONG
*pCanSeekForward
)
884 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
888 TRACE("(%p)\n", pCanSeekForward
);
890 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
892 hr
= IMediaPosition_CanSeekForward(pos
, pCanSeekForward
);
893 IMediaPosition_Release(pos
);
900 static HRESULT WINAPI
MediaPositionPassThru_CanSeekBackward(IMediaPosition
*iface
, LONG
*pCanSeekBackward
)
902 PassThruImpl
*This
= impl_from_IMediaPosition(iface
);
906 TRACE("(%p)\n", pCanSeekBackward
);
908 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
910 hr
= IMediaPosition_CanSeekBackward(pos
, pCanSeekBackward
);
911 IMediaPosition_Release(pos
);
918 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
=
920 MediaPositionPassThru_QueryInterface
,
921 MediaPositionPassThru_AddRef
,
922 MediaPositionPassThru_Release
,
923 MediaPositionPassThru_GetTypeInfoCount
,
924 MediaPositionPassThru_GetTypeInfo
,
925 MediaPositionPassThru_GetIDsOfNames
,
926 MediaPositionPassThru_Invoke
,
927 MediaPositionPassThru_get_Duration
,
928 MediaPositionPassThru_put_CurrentPosition
,
929 MediaPositionPassThru_get_CurrentPosition
,
930 MediaPositionPassThru_get_StopTime
,
931 MediaPositionPassThru_put_StopTime
,
932 MediaPositionPassThru_get_PrerollTime
,
933 MediaPositionPassThru_put_PrerollTime
,
934 MediaPositionPassThru_put_Rate
,
935 MediaPositionPassThru_get_Rate
,
936 MediaPositionPassThru_CanSeekForward
,
937 MediaPositionPassThru_CanSeekBackward