2 * Filter Seeking and Control Interfaces
4 * Copyright 2003 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* FIXME: critical sections */
22 #include "quartz_private.h"
23 #include "control_private.h"
26 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
32 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
;
34 typedef struct PassThruImpl
{
35 const ISeekingPassThruVtbl
*IPassThru_vtbl
;
36 const IUnknownVtbl
*IInner_vtbl
;
37 const IMediaSeekingVtbl
*IMediaSeeking_vtbl
;
47 static HRESULT WINAPI
SeekInner_QueryInterface(IUnknown
* iface
,
50 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
51 TRACE("(%p)->(%s (%p), %p)\n", This
, debugstr_guid(riid
), riid
, ppvObj
);
53 if (This
->bAggregatable
)
54 This
->bUnkOuterValid
= TRUE
;
56 if (IsEqualGUID(&IID_IUnknown
, riid
))
58 *ppvObj
= &(This
->IInner_vtbl
);
59 TRACE(" returning IUnknown interface (%p)\n", *ppvObj
);
60 } else if (IsEqualGUID(&IID_ISeekingPassThru
, riid
)) {
61 *ppvObj
= &(This
->IPassThru_vtbl
);
62 TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj
);
63 } else if (IsEqualGUID(&IID_IMediaSeeking
, riid
)) {
64 *ppvObj
= &(This
->IMediaSeeking_vtbl
);
65 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj
);
68 FIXME("unknown interface %s\n", debugstr_guid(riid
));
72 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
76 static ULONG WINAPI
SeekInner_AddRef(IUnknown
* iface
) {
77 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
78 ULONG ref
= InterlockedIncrement(&This
->ref
);
80 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
85 static ULONG WINAPI
SeekInner_Release(IUnknown
* iface
) {
86 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
87 ULONG ref
= InterlockedDecrement(&This
->ref
);
89 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
98 static const IUnknownVtbl IInner_VTable
=
100 SeekInner_QueryInterface
,
105 /* Generic functions for aggregation */
106 static HRESULT
SeekOuter_QueryInterface(PassThruImpl
*This
, REFIID riid
, LPVOID
*ppv
)
108 if (This
->bAggregatable
)
109 This
->bUnkOuterValid
= TRUE
;
113 if (This
->bAggregatable
)
114 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppv
);
116 if (IsEqualIID(riid
, &IID_IUnknown
))
120 IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
121 hr
= IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
122 IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
123 This
->bAggregatable
= TRUE
;
128 return E_NOINTERFACE
;
131 return IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
134 static ULONG
SeekOuter_AddRef(PassThruImpl
*This
)
136 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
137 return IUnknown_AddRef(This
->pUnkOuter
);
138 return IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
141 static ULONG
SeekOuter_Release(PassThruImpl
*This
)
143 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
144 return IUnknown_Release(This
->pUnkOuter
);
145 return IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
148 static HRESULT WINAPI
SeekingPassThru_QueryInterface(ISeekingPassThru
*iface
, REFIID riid
, LPVOID
*ppvObj
)
150 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
152 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
154 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
157 static ULONG WINAPI
SeekingPassThru_AddRef(ISeekingPassThru
*iface
)
159 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
161 TRACE("(%p/%p)->()\n", This
, iface
);
163 return SeekOuter_AddRef(This
);
166 static ULONG WINAPI
SeekingPassThru_Release(ISeekingPassThru
*iface
)
168 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
170 TRACE("(%p/%p)->()\n", This
, iface
);
172 return SeekOuter_Release(This
);
175 static HRESULT WINAPI
SeekingPassThru_Init(ISeekingPassThru
*iface
, BOOL renderer
, IPin
*pin
)
177 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
179 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, renderer
, pin
);
182 FIXME("Re-initializing?\n");
184 This
->renderer
= renderer
;
190 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl
=
192 SeekingPassThru_QueryInterface
,
193 SeekingPassThru_AddRef
,
194 SeekingPassThru_Release
,
198 HRESULT
SeekingPassThru_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
202 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
204 *ppObj
= fimpl
= CoTaskMemAlloc(sizeof(*fimpl
));
206 return E_OUTOFMEMORY
;
208 fimpl
->pUnkOuter
= pUnkOuter
;
209 fimpl
->bUnkOuterValid
= FALSE
;
210 fimpl
->bAggregatable
= FALSE
;
211 fimpl
->IInner_vtbl
= &IInner_VTable
;
212 fimpl
->IPassThru_vtbl
= &ISeekingPassThru_Vtbl
;
213 fimpl
->IMediaSeeking_vtbl
= &IMediaSeekingPassThru_Vtbl
;
219 typedef HRESULT (*SeekFunc
)( IMediaSeeking
*to
, LPVOID arg
);
221 static HRESULT
ForwardCmdSeek( PCRITICAL_SECTION crit_sect
, IBaseFilter
* from
, SeekFunc fnSeek
, LPVOID arg
)
224 HRESULT hr_return
= S_OK
;
225 IEnumPins
*enumpins
= NULL
;
226 BOOL foundend
= FALSE
, allnotimpl
= TRUE
;
228 hr
= IBaseFilter_EnumPins( from
, &enumpins
);
232 hr
= IEnumPins_Reset( enumpins
);
235 hr
= IEnumPins_Next( enumpins
, 1, &pin
, NULL
);
236 if (hr
== VFW_E_ENUM_OUT_OF_SYNC
)
238 hr
= IEnumPins_Reset( enumpins
);
245 IPin_QueryDirection( pin
, &dir
);
246 if (dir
== PINDIR_INPUT
)
248 IPin
*connected
= NULL
;
250 IPin_ConnectedTo( pin
, &connected
);
254 IMediaSeeking
*seek
= NULL
;
256 hr_local
= IPin_QueryInterface( connected
, &IID_IMediaSeeking
, (void**)&seek
);
257 if (hr_local
== S_OK
)
262 LeaveCriticalSection( crit_sect
);
263 hr_local
= fnSeek( seek
, arg
);
264 EnterCriticalSection( crit_sect
);
267 hr_local
= fnSeek( seek
, arg
);
269 if (hr_local
!= E_NOTIMPL
)
272 hr_return
= updatehres( hr_return
, hr_local
);
273 IMediaSeeking_Release( seek
);
275 IPin_Release(connected
);
281 IEnumPins_Release( enumpins
);
283 if (foundend
&& allnotimpl
)
289 TRACE("Returning: %08x\n", hr
);
294 HRESULT
MediaSeekingImpl_Init(IBaseFilter
*pUserData
, CHANGEPROC fnChangeStop
, CHANGEPROC fnChangeCurrent
, CHANGEPROC fnChangeRate
, MediaSeekingImpl
* pSeeking
, PCRITICAL_SECTION crit_sect
)
296 assert(fnChangeStop
&& fnChangeCurrent
&& fnChangeRate
);
298 pSeeking
->refCount
= 1;
299 pSeeking
->pUserData
= pUserData
;
300 pSeeking
->fnChangeRate
= fnChangeRate
;
301 pSeeking
->fnChangeStop
= fnChangeStop
;
302 pSeeking
->fnChangeCurrent
= fnChangeCurrent
;
303 pSeeking
->dwCapabilities
= AM_SEEKING_CanSeekForwards
|
304 AM_SEEKING_CanSeekBackwards
|
305 AM_SEEKING_CanSeekAbsolute
|
306 AM_SEEKING_CanGetStopPos
|
307 AM_SEEKING_CanGetDuration
;
308 pSeeking
->llCurrent
= 0;
309 pSeeking
->llStop
= ((ULONGLONG
)0x80000000) << 32;
310 pSeeking
->llDuration
= pSeeking
->llStop
;
311 pSeeking
->dRate
= 1.0;
312 pSeeking
->timeformat
= TIME_FORMAT_MEDIA_TIME
;
313 pSeeking
->crst
= crit_sect
;
319 LONGLONG
* current
, *stop
;
320 DWORD curflags
, stopflags
;
323 static HRESULT
fwd_setposition(IMediaSeeking
*seek
, LPVOID pargs
)
325 struct pos_args
*args
= (void*)pargs
;
327 return IMediaSeeking_SetPositions(seek
, args
->current
, args
->curflags
, args
->stop
, args
->stopflags
);
330 static HRESULT
fwd_checkcaps(IMediaSeeking
*iface
, LPVOID pcaps
)
333 return IMediaSeeking_CheckCapabilities(iface
, caps
);
336 static HRESULT
fwd_settimeformat(IMediaSeeking
*iface
, LPVOID pformat
)
338 const GUID
*format
= pformat
;
339 return IMediaSeeking_SetTimeFormat(iface
, format
);
342 static HRESULT
fwd_getduration(IMediaSeeking
*iface
, LPVOID pdur
)
344 LONGLONG
*duration
= pdur
;
345 LONGLONG mydur
= *duration
;
348 hr
= IMediaSeeking_GetDuration(iface
, &mydur
);
352 if ((mydur
< *duration
) || (*duration
< 0 && mydur
> 0))
357 static HRESULT
fwd_getstopposition(IMediaSeeking
*iface
, LPVOID pdur
)
359 LONGLONG
*duration
= pdur
;
360 LONGLONG mydur
= *duration
;
363 hr
= IMediaSeeking_GetStopPosition(iface
, &mydur
);
367 if ((mydur
< *duration
) || (*duration
< 0 && mydur
> 0))
372 static HRESULT
fwd_getcurposition(IMediaSeeking
*iface
, LPVOID pdur
)
374 LONGLONG
*duration
= pdur
;
375 LONGLONG mydur
= *duration
;
378 hr
= IMediaSeeking_GetCurrentPosition(iface
, &mydur
);
382 if ((mydur
< *duration
) || (*duration
< 0 && mydur
> 0))
387 static HRESULT
fwd_setrate(IMediaSeeking
*iface
, LPVOID prate
)
389 double *rate
= prate
;
393 hr
= IMediaSeeking_SetRate(iface
, *rate
);
401 HRESULT WINAPI
MediaSeekingImpl_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
403 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
405 TRACE("(%p)\n", pCapabilities
);
407 *pCapabilities
= This
->dwCapabilities
;
412 HRESULT WINAPI
MediaSeekingImpl_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
414 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
418 TRACE("(%p)\n", pCapabilities
);
423 EnterCriticalSection(This
->crst
);
424 hr
= ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_checkcaps
, pCapabilities
);
425 LeaveCriticalSection(This
->crst
);
426 if (FAILED(hr
) && hr
!= E_NOTIMPL
)
429 dwCommonCaps
= *pCapabilities
& This
->dwCapabilities
;
434 hr
= (*pCapabilities
== dwCommonCaps
) ? S_OK
: S_FALSE
;
435 *pCapabilities
= dwCommonCaps
;
440 HRESULT WINAPI
MediaSeekingImpl_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
442 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
444 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: S_FALSE
);
447 HRESULT WINAPI
MediaSeekingImpl_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
449 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
451 *pFormat
= TIME_FORMAT_MEDIA_TIME
;
455 HRESULT WINAPI
MediaSeekingImpl_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
457 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
458 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
460 EnterCriticalSection(This
->crst
);
461 *pFormat
= This
->timeformat
;
462 LeaveCriticalSection(This
->crst
);
467 HRESULT WINAPI
MediaSeekingImpl_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
469 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
472 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
474 EnterCriticalSection(This
->crst
);
475 if (!IsEqualIID(pFormat
, &This
->timeformat
))
477 LeaveCriticalSection(This
->crst
);
483 HRESULT WINAPI
MediaSeekingImpl_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
485 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
486 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
488 EnterCriticalSection(This
->crst
);
489 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_settimeformat
, (LPVOID
)pFormat
);
490 LeaveCriticalSection(This
->crst
);
492 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: S_FALSE
);
496 HRESULT WINAPI
MediaSeekingImpl_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
498 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
500 TRACE("(%p)\n", pDuration
);
502 EnterCriticalSection(This
->crst
);
503 *pDuration
= This
->llDuration
;
504 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_getduration
, pDuration
);
505 LeaveCriticalSection(This
->crst
);
510 HRESULT WINAPI
MediaSeekingImpl_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
512 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
514 TRACE("(%p)\n", pStop
);
516 EnterCriticalSection(This
->crst
);
517 *pStop
= This
->llStop
;
518 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_getstopposition
, pStop
);
519 LeaveCriticalSection(This
->crst
);
524 /* FIXME: Make use of the info the filter should expose */
525 HRESULT WINAPI
MediaSeekingImpl_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
527 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
529 TRACE("(%p)\n", pCurrent
);
531 EnterCriticalSection(This
->crst
);
532 *pCurrent
= This
->llCurrent
;
533 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_getcurposition
, pCurrent
);
534 LeaveCriticalSection(This
->crst
);
539 HRESULT WINAPI
MediaSeekingImpl_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
541 if (IsEqualIID(pTargetFormat
, &TIME_FORMAT_MEDIA_TIME
) && IsEqualIID(pSourceFormat
, &TIME_FORMAT_MEDIA_TIME
))
546 /* FIXME: clear pTarget? */
550 static inline LONGLONG
Adjust(LONGLONG value
, const LONGLONG
* pModifier
, DWORD dwFlags
)
552 switch (dwFlags
& AM_SEEKING_PositioningBitsMask
)
554 case AM_SEEKING_NoPositioning
:
556 case AM_SEEKING_AbsolutePositioning
:
558 case AM_SEEKING_RelativePositioning
:
559 case AM_SEEKING_IncrementalPositioning
:
560 return value
+ *pModifier
;
567 HRESULT WINAPI
MediaSeekingImpl_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
569 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
570 BOOL bChangeCurrent
= FALSE
, bChangeStop
= FALSE
;
571 LONGLONG llNewCurrent
, llNewStop
;
572 struct pos_args args
;
574 TRACE("(%p, %x, %p, %x)\n", pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
576 args
.current
= pCurrent
;
578 args
.curflags
= dwCurrentFlags
;
579 args
.stopflags
= dwStopFlags
;
581 EnterCriticalSection(This
->crst
);
583 llNewCurrent
= Adjust(This
->llCurrent
, pCurrent
, dwCurrentFlags
);
584 llNewStop
= Adjust(This
->llStop
, pStop
, dwStopFlags
);
587 bChangeCurrent
= TRUE
;
588 if (llNewStop
!= This
->llStop
)
591 TRACE("Old: %u, New: %u\n", (DWORD
)(This
->llCurrent
/10000000), (DWORD
)(llNewCurrent
/10000000));
593 This
->llCurrent
= llNewCurrent
;
594 This
->llStop
= llNewStop
;
596 if (pCurrent
&& (dwCurrentFlags
& AM_SEEKING_ReturnTime
))
597 *pCurrent
= llNewCurrent
;
598 if (pStop
&& (dwStopFlags
& AM_SEEKING_ReturnTime
))
601 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_setposition
, &args
);
602 LeaveCriticalSection(This
->crst
);
605 This
->fnChangeCurrent(This
->pUserData
);
607 This
->fnChangeStop(This
->pUserData
);
612 HRESULT WINAPI
MediaSeekingImpl_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
614 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
616 TRACE("(%p, %p)\n", pCurrent
, pStop
);
618 EnterCriticalSection(This
->crst
);
619 *pCurrent
= This
->llCurrent
;
620 *pStop
= This
->llStop
;
621 LeaveCriticalSection(This
->crst
);
626 HRESULT WINAPI
MediaSeekingImpl_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
628 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
630 TRACE("(%p, %p)\n", pEarliest
, pLatest
);
632 EnterCriticalSection(This
->crst
);
634 *pLatest
= This
->llDuration
;
635 LeaveCriticalSection(This
->crst
);
640 HRESULT WINAPI
MediaSeekingImpl_SetRate(IMediaSeeking
* iface
, double dRate
)
642 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
643 BOOL bChangeRate
= (dRate
!= This
->dRate
);
646 TRACE("(%e)\n", dRate
);
648 if (dRate
> 100 || dRate
< .001)
650 FIXME("Excessive rate %e, ignoring\n", dRate
);
651 return VFW_E_UNSUPPORTED_AUDIO
;
654 EnterCriticalSection(This
->crst
);
657 hr
= This
->fnChangeRate(This
->pUserData
);
658 ForwardCmdSeek(This
->crst
, This
->pUserData
, fwd_setrate
, &dRate
);
659 LeaveCriticalSection(This
->crst
);
664 HRESULT WINAPI
MediaSeekingImpl_GetRate(IMediaSeeking
* iface
, double * dRate
)
666 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
668 TRACE("(%p)\n", dRate
);
670 EnterCriticalSection(This
->crst
);
672 *dRate
= This
->dRate
;
673 LeaveCriticalSection(This
->crst
);
678 HRESULT WINAPI
MediaSeekingImpl_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
680 TRACE("(%p)\n", pPreroll
);
686 static HRESULT WINAPI
MediaSeekingPassThru_QueryInterface(IMediaSeeking
*iface
, REFIID riid
, LPVOID
*ppvObj
)
688 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
690 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
692 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
695 static ULONG WINAPI
MediaSeekingPassThru_AddRef(IMediaSeeking
*iface
)
697 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
699 TRACE("(%p/%p)->()\n", iface
, This
);
701 return SeekOuter_AddRef(This
);
704 static ULONG WINAPI
MediaSeekingPassThru_Release(IMediaSeeking
*iface
)
706 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
708 TRACE("(%p/%p)->()\n", iface
, This
);
710 return SeekOuter_Release(This
);
713 static HRESULT WINAPI
MediaSeekingPassThru_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
715 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
717 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
723 static HRESULT WINAPI
MediaSeekingPassThru_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
725 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
727 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
736 static HRESULT WINAPI
MediaSeekingPassThru_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
738 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
739 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
745 static HRESULT WINAPI
MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
747 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
748 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
754 static HRESULT WINAPI
MediaSeekingPassThru_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
756 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
757 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
763 static HRESULT WINAPI
MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
765 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
767 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
774 static HRESULT WINAPI
MediaSeekingPassThru_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
776 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
777 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
784 static HRESULT WINAPI
MediaSeekingPassThru_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
786 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
790 TRACE("(%p/%p)->(%p)\n", iface
, This
, pDuration
);
792 IPin_QueryPinInfo(This
->pin
, &info
);
794 hr
= ForwardCmdSeek(NULL
, info
.pFilter
, fwd_getduration
, pDuration
);
795 IBaseFilter_Release(info
.pFilter
);
800 static HRESULT WINAPI
MediaSeekingPassThru_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
802 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
804 TRACE("(%p/%p)->(%p)\n", iface
, This
, pStop
);
810 /* FIXME: Make use of the info the filter should expose */
811 static HRESULT WINAPI
MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
813 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
815 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCurrent
);
821 static HRESULT WINAPI
MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
823 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
825 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface
, This
, pTarget
, debugstr_guid(pTargetFormat
), (DWORD
)(Source
>>32), (DWORD
)Source
, debugstr_guid(pSourceFormat
));
831 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
833 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
834 struct pos_args args
;
838 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
839 args
.current
= pCurrent
;
841 args
.curflags
= dwCurrentFlags
;
842 args
.stopflags
= dwStopFlags
;
844 IPin_QueryPinInfo(This
->pin
, &info
);
846 hr
= ForwardCmdSeek(NULL
, info
.pFilter
, fwd_setposition
, &args
);
847 IBaseFilter_Release(info
.pFilter
);
851 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
853 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
855 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
861 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
863 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
865 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
871 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
873 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
875 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
881 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
883 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
885 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
891 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
893 TRACE("(%p)\n", pPreroll
);
899 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
901 MediaSeekingPassThru_QueryInterface
,
902 MediaSeekingPassThru_AddRef
,
903 MediaSeekingPassThru_Release
,
904 MediaSeekingPassThru_GetCapabilities
,
905 MediaSeekingPassThru_CheckCapabilities
,
906 MediaSeekingPassThru_IsFormatSupported
,
907 MediaSeekingPassThru_QueryPreferredFormat
,
908 MediaSeekingPassThru_GetTimeFormat
,
909 MediaSeekingPassThru_IsUsingTimeFormat
,
910 MediaSeekingPassThru_SetTimeFormat
,
911 MediaSeekingPassThru_GetDuration
,
912 MediaSeekingPassThru_GetStopPosition
,
913 MediaSeekingPassThru_GetCurrentPosition
,
914 MediaSeekingPassThru_ConvertTimeFormat
,
915 MediaSeekingPassThru_SetPositions
,
916 MediaSeekingPassThru_GetPositions
,
917 MediaSeekingPassThru_GetAvailable
,
918 MediaSeekingPassThru_SetRate
,
919 MediaSeekingPassThru_GetRate
,
920 MediaSeekingPassThru_GetPreroll