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 = 0;
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;
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);
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);
625 This->time_earliest = time;
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