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
;
45 CRITICAL_SECTION time_cs
;
47 REFERENCE_TIME time_earliest
;
50 static HRESULT WINAPI
SeekInner_QueryInterface(IUnknown
* iface
,
53 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
54 TRACE("(%p)->(%s (%p), %p)\n", This
, debugstr_guid(riid
), riid
, ppvObj
);
56 if (This
->bAggregatable
)
57 This
->bUnkOuterValid
= TRUE
;
59 if (IsEqualGUID(&IID_IUnknown
, riid
))
61 *ppvObj
= &(This
->IInner_vtbl
);
62 TRACE(" returning IUnknown interface (%p)\n", *ppvObj
);
63 } else if (IsEqualGUID(&IID_ISeekingPassThru
, riid
)) {
64 *ppvObj
= &(This
->IPassThru_vtbl
);
65 TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj
);
66 } else if (IsEqualGUID(&IID_IMediaSeeking
, riid
)) {
67 *ppvObj
= &(This
->IMediaSeeking_vtbl
);
68 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj
);
71 FIXME("unknown interface %s\n", debugstr_guid(riid
));
75 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
79 static ULONG WINAPI
SeekInner_AddRef(IUnknown
* iface
) {
80 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
81 ULONG ref
= InterlockedIncrement(&This
->ref
);
83 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
88 static ULONG WINAPI
SeekInner_Release(IUnknown
* iface
) {
89 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
90 ULONG ref
= InterlockedDecrement(&This
->ref
);
92 TRACE("(%p)->(): new ref = %d\n", This
, ref
);
96 This
->time_cs
.DebugInfo
->Spare
[0] = 0;
97 DeleteCriticalSection(&This
->time_cs
);
103 static const IUnknownVtbl IInner_VTable
=
105 SeekInner_QueryInterface
,
110 /* Generic functions for aggregation */
111 static HRESULT
SeekOuter_QueryInterface(PassThruImpl
*This
, REFIID riid
, LPVOID
*ppv
)
113 if (This
->bAggregatable
)
114 This
->bUnkOuterValid
= TRUE
;
118 if (This
->bAggregatable
)
119 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppv
);
121 if (IsEqualIID(riid
, &IID_IUnknown
))
125 IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
126 hr
= IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
127 IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
128 This
->bAggregatable
= TRUE
;
133 return E_NOINTERFACE
;
136 return IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
139 static ULONG
SeekOuter_AddRef(PassThruImpl
*This
)
141 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
142 return IUnknown_AddRef(This
->pUnkOuter
);
143 return IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
146 static ULONG
SeekOuter_Release(PassThruImpl
*This
)
148 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
149 return IUnknown_Release(This
->pUnkOuter
);
150 return IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
153 static HRESULT WINAPI
SeekingPassThru_QueryInterface(ISeekingPassThru
*iface
, REFIID riid
, LPVOID
*ppvObj
)
155 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
157 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
159 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
162 static ULONG WINAPI
SeekingPassThru_AddRef(ISeekingPassThru
*iface
)
164 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
166 TRACE("(%p/%p)->()\n", This
, iface
);
168 return SeekOuter_AddRef(This
);
171 static ULONG WINAPI
SeekingPassThru_Release(ISeekingPassThru
*iface
)
173 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
175 TRACE("(%p/%p)->()\n", This
, iface
);
177 return SeekOuter_Release(This
);
180 static HRESULT WINAPI
SeekingPassThru_Init(ISeekingPassThru
*iface
, BOOL renderer
, IPin
*pin
)
182 ICOM_THIS_MULTI(PassThruImpl
, IPassThru_vtbl
, iface
);
184 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, renderer
, pin
);
187 FIXME("Re-initializing?\n");
189 This
->renderer
= renderer
;
195 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl
=
197 SeekingPassThru_QueryInterface
,
198 SeekingPassThru_AddRef
,
199 SeekingPassThru_Release
,
203 HRESULT
SeekingPassThru_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
207 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
209 *ppObj
= fimpl
= CoTaskMemAlloc(sizeof(*fimpl
));
211 return E_OUTOFMEMORY
;
213 fimpl
->pUnkOuter
= pUnkOuter
;
214 fimpl
->bUnkOuterValid
= FALSE
;
215 fimpl
->bAggregatable
= FALSE
;
216 fimpl
->IInner_vtbl
= &IInner_VTable
;
217 fimpl
->IPassThru_vtbl
= &ISeekingPassThru_Vtbl
;
218 fimpl
->IMediaSeeking_vtbl
= &IMediaSeekingPassThru_Vtbl
;
221 fimpl
->timevalid
= 0;
222 InitializeCriticalSection(&fimpl
->time_cs
);
223 fimpl
->time_cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": PassThruImpl.time_cs");
227 HRESULT
MediaSeekingImpl_Init(IBaseFilter
*pUserData
, CHANGEPROC fnChangeStop
, CHANGEPROC fnChangeCurrent
, CHANGEPROC fnChangeRate
, MediaSeekingImpl
* pSeeking
, PCRITICAL_SECTION crit_sect
)
229 assert(fnChangeStop
&& fnChangeCurrent
&& fnChangeRate
);
231 pSeeking
->refCount
= 1;
232 pSeeking
->pUserData
= pUserData
;
233 pSeeking
->fnChangeRate
= fnChangeRate
;
234 pSeeking
->fnChangeStop
= fnChangeStop
;
235 pSeeking
->fnChangeCurrent
= fnChangeCurrent
;
236 pSeeking
->dwCapabilities
= AM_SEEKING_CanSeekForwards
|
237 AM_SEEKING_CanSeekBackwards
|
238 AM_SEEKING_CanSeekAbsolute
|
239 AM_SEEKING_CanGetStopPos
|
240 AM_SEEKING_CanGetDuration
;
241 pSeeking
->llCurrent
= 0;
242 pSeeking
->llStop
= ((ULONGLONG
)0x80000000) << 32;
243 pSeeking
->llDuration
= pSeeking
->llStop
;
244 pSeeking
->dRate
= 1.0;
245 pSeeking
->timeformat
= TIME_FORMAT_MEDIA_TIME
;
246 pSeeking
->crst
= crit_sect
;
250 HRESULT WINAPI
MediaSeekingImpl_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
252 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
254 TRACE("(%p)\n", pCapabilities
);
256 *pCapabilities
= This
->dwCapabilities
;
261 HRESULT WINAPI
MediaSeekingImpl_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
263 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
267 TRACE("(%p)\n", pCapabilities
);
272 dwCommonCaps
= *pCapabilities
& This
->dwCapabilities
;
277 hr
= (*pCapabilities
== dwCommonCaps
) ? S_OK
: S_FALSE
;
278 *pCapabilities
= dwCommonCaps
;
282 HRESULT WINAPI
MediaSeekingImpl_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
284 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
286 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: S_FALSE
);
289 HRESULT WINAPI
MediaSeekingImpl_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
291 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
293 *pFormat
= TIME_FORMAT_MEDIA_TIME
;
297 HRESULT WINAPI
MediaSeekingImpl_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
299 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
300 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
302 EnterCriticalSection(This
->crst
);
303 *pFormat
= This
->timeformat
;
304 LeaveCriticalSection(This
->crst
);
309 HRESULT WINAPI
MediaSeekingImpl_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
311 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
314 TRACE("(%s)\n", qzdebugstr_guid(pFormat
));
316 EnterCriticalSection(This
->crst
);
317 if (!IsEqualIID(pFormat
, &This
->timeformat
))
319 LeaveCriticalSection(This
->crst
);
324 HRESULT WINAPI
MediaSeekingImpl_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
326 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
327 TRACE("%p %s\n", This
, qzdebugstr_guid(pFormat
));
328 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: E_INVALIDARG
);
332 HRESULT WINAPI
MediaSeekingImpl_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
334 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
336 TRACE("(%p)\n", pDuration
);
338 EnterCriticalSection(This
->crst
);
339 *pDuration
= This
->llDuration
;
340 LeaveCriticalSection(This
->crst
);
345 HRESULT WINAPI
MediaSeekingImpl_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
347 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
349 TRACE("(%p)\n", pStop
);
351 EnterCriticalSection(This
->crst
);
352 *pStop
= This
->llStop
;
353 LeaveCriticalSection(This
->crst
);
358 /* FIXME: Make use of the info the filter should expose */
359 HRESULT WINAPI
MediaSeekingImpl_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
361 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
363 TRACE("(%p)\n", pCurrent
);
365 EnterCriticalSection(This
->crst
);
366 *pCurrent
= This
->llCurrent
;
367 LeaveCriticalSection(This
->crst
);
372 HRESULT WINAPI
MediaSeekingImpl_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
374 if (IsEqualIID(pTargetFormat
, &TIME_FORMAT_MEDIA_TIME
) && IsEqualIID(pSourceFormat
, &TIME_FORMAT_MEDIA_TIME
))
379 /* FIXME: clear pTarget? */
383 static inline LONGLONG
Adjust(LONGLONG value
, const LONGLONG
* pModifier
, DWORD dwFlags
)
385 switch (dwFlags
& AM_SEEKING_PositioningBitsMask
)
387 case AM_SEEKING_NoPositioning
:
389 case AM_SEEKING_AbsolutePositioning
:
391 case AM_SEEKING_RelativePositioning
:
392 case AM_SEEKING_IncrementalPositioning
:
393 return value
+ *pModifier
;
400 HRESULT WINAPI
MediaSeekingImpl_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
402 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
403 BOOL bChangeCurrent
= FALSE
, bChangeStop
= FALSE
;
404 LONGLONG llNewCurrent
, llNewStop
;
406 TRACE("(%p, %x, %p, %x)\n", pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
407 EnterCriticalSection(This
->crst
);
409 llNewCurrent
= Adjust(This
->llCurrent
, pCurrent
, dwCurrentFlags
);
410 llNewStop
= Adjust(This
->llStop
, pStop
, dwStopFlags
);
413 bChangeCurrent
= TRUE
;
414 if (llNewStop
!= This
->llStop
)
417 TRACE("Old: %u, New: %u\n", (DWORD
)(This
->llCurrent
/10000000), (DWORD
)(llNewCurrent
/10000000));
419 This
->llCurrent
= llNewCurrent
;
420 This
->llStop
= llNewStop
;
422 if (pCurrent
&& (dwCurrentFlags
& AM_SEEKING_ReturnTime
))
423 *pCurrent
= llNewCurrent
;
424 if (pStop
&& (dwStopFlags
& AM_SEEKING_ReturnTime
))
426 LeaveCriticalSection(This
->crst
);
429 This
->fnChangeCurrent(This
->pUserData
);
431 This
->fnChangeStop(This
->pUserData
);
436 HRESULT WINAPI
MediaSeekingImpl_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
438 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
440 TRACE("(%p, %p)\n", pCurrent
, pStop
);
442 EnterCriticalSection(This
->crst
);
443 IMediaSeeking_GetCurrentPosition(iface
, pCurrent
);
444 IMediaSeeking_GetStopPosition(iface
, pStop
);
445 LeaveCriticalSection(This
->crst
);
450 HRESULT WINAPI
MediaSeekingImpl_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
452 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
454 TRACE("(%p, %p)\n", pEarliest
, pLatest
);
456 EnterCriticalSection(This
->crst
);
458 *pLatest
= This
->llDuration
;
459 LeaveCriticalSection(This
->crst
);
464 HRESULT WINAPI
MediaSeekingImpl_SetRate(IMediaSeeking
* iface
, double dRate
)
466 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
467 BOOL bChangeRate
= (dRate
!= This
->dRate
);
470 TRACE("(%e)\n", dRate
);
472 if (dRate
> 100 || dRate
< .001)
474 FIXME("Excessive rate %e, ignoring\n", dRate
);
475 return VFW_E_UNSUPPORTED_AUDIO
;
478 EnterCriticalSection(This
->crst
);
481 hr
= This
->fnChangeRate(This
->pUserData
);
482 LeaveCriticalSection(This
->crst
);
487 HRESULT WINAPI
MediaSeekingImpl_GetRate(IMediaSeeking
* iface
, double * dRate
)
489 MediaSeekingImpl
*This
= (MediaSeekingImpl
*)iface
;
491 TRACE("(%p)\n", dRate
);
493 EnterCriticalSection(This
->crst
);
495 *dRate
= This
->dRate
;
496 LeaveCriticalSection(This
->crst
);
501 HRESULT WINAPI
MediaSeekingImpl_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
503 TRACE("(%p)\n", pPreroll
);
509 static HRESULT WINAPI
MediaSeekingPassThru_QueryInterface(IMediaSeeking
*iface
, REFIID riid
, LPVOID
*ppvObj
)
511 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
513 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
515 return SeekOuter_QueryInterface(This
, riid
, ppvObj
);
518 static ULONG WINAPI
MediaSeekingPassThru_AddRef(IMediaSeeking
*iface
)
520 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
522 TRACE("(%p/%p)->()\n", iface
, This
);
524 return SeekOuter_AddRef(This
);
527 static ULONG WINAPI
MediaSeekingPassThru_Release(IMediaSeeking
*iface
)
529 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
531 TRACE("(%p/%p)->()\n", iface
, This
);
533 return SeekOuter_Release(This
);
536 static HRESULT
get_connected(PassThruImpl
*This
, IMediaSeeking
**seek
) {
540 hr
= IPin_ConnectedTo(This
->pin
, &pin
);
542 return VFW_E_NOT_CONNECTED
;
543 hr
= IPin_QueryInterface(pin
, &IID_IMediaSeeking
, (void**)seek
);
550 static HRESULT WINAPI
MediaSeekingPassThru_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
552 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
555 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
556 hr
= get_connected(This
, &seek
);
558 hr
= IMediaSeeking_GetCapabilities(seek
, pCapabilities
);
559 IMediaSeeking_Release(seek
);
566 static HRESULT WINAPI
MediaSeekingPassThru_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
568 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
571 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
572 hr
= get_connected(This
, &seek
);
574 hr
= IMediaSeeking_CheckCapabilities(seek
, pCapabilities
);
575 IMediaSeeking_Release(seek
);
582 static HRESULT WINAPI
MediaSeekingPassThru_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
584 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
587 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
588 hr
= get_connected(This
, &seek
);
590 hr
= IMediaSeeking_IsFormatSupported(seek
, pFormat
);
591 IMediaSeeking_Release(seek
);
598 static HRESULT WINAPI
MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
600 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
603 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
604 hr
= get_connected(This
, &seek
);
606 hr
= IMediaSeeking_QueryPreferredFormat(seek
, pFormat
);
607 IMediaSeeking_Release(seek
);
614 static HRESULT WINAPI
MediaSeekingPassThru_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
616 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
619 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
620 hr
= get_connected(This
, &seek
);
622 hr
= IMediaSeeking_GetTimeFormat(seek
, pFormat
);
623 IMediaSeeking_Release(seek
);
630 static HRESULT WINAPI
MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
632 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
635 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
636 hr
= get_connected(This
, &seek
);
638 hr
= IMediaSeeking_IsUsingTimeFormat(seek
, pFormat
);
639 IMediaSeeking_Release(seek
);
646 static HRESULT WINAPI
MediaSeekingPassThru_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
648 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
651 TRACE("(%p/%p)->(%s)\n", iface
, This
, qzdebugstr_guid(pFormat
));
652 hr
= get_connected(This
, &seek
);
654 hr
= IMediaSeeking_SetTimeFormat(seek
, pFormat
);
655 IMediaSeeking_Release(seek
);
662 static HRESULT WINAPI
MediaSeekingPassThru_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
664 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
667 TRACE("(%p/%p)->(%p)\n", iface
, This
, pDuration
);
668 hr
= get_connected(This
, &seek
);
670 hr
= IMediaSeeking_GetDuration(seek
, pDuration
);
671 IMediaSeeking_Release(seek
);
678 static HRESULT WINAPI
MediaSeekingPassThru_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
680 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
683 TRACE("(%p/%p)->(%p)\n", iface
, This
, pStop
);
684 hr
= get_connected(This
, &seek
);
686 hr
= IMediaSeeking_GetStopPosition(seek
, pStop
);
687 IMediaSeeking_Release(seek
);
694 static HRESULT WINAPI
MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
696 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
699 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCurrent
);
702 EnterCriticalSection(&This
->time_cs
);
704 *pCurrent
= This
->time_earliest
;
707 LeaveCriticalSection(&This
->time_cs
);
709 hr
= IMediaSeeking_ConvertTimeFormat(iface
, pCurrent
, NULL
, *pCurrent
, &TIME_FORMAT_MEDIA_TIME
);
712 hr
= get_connected(This
, &seek
);
714 hr
= IMediaSeeking_GetCurrentPosition(seek
, pCurrent
);
715 IMediaSeeking_Release(seek
);
722 static HRESULT WINAPI
MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
724 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
727 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface
, This
, pTarget
, debugstr_guid(pTargetFormat
), (DWORD
)(Source
>>32), (DWORD
)Source
, debugstr_guid(pSourceFormat
));
728 hr
= get_connected(This
, &seek
);
730 hr
= IMediaSeeking_ConvertTimeFormat(seek
, pTarget
, pTargetFormat
, Source
, pSourceFormat
);
731 IMediaSeeking_Release(seek
);
738 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
740 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
743 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface
, This
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
744 hr
= get_connected(This
, &seek
);
746 hr
= IMediaSeeking_SetPositions(seek
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
747 IMediaSeeking_Release(seek
);
748 } else if (hr
== VFW_E_NOT_CONNECTED
)
753 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
755 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
758 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
759 hr
= get_connected(This
, &seek
);
761 hr
= IMediaSeeking_GetPositions(seek
, pCurrent
, pStop
);
762 IMediaSeeking_Release(seek
);
769 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
771 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
774 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
775 hr
= get_connected(This
, &seek
);
777 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
778 IMediaSeeking_Release(seek
);
785 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
787 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
790 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
791 hr
= get_connected(This
, &seek
);
793 hr
= IMediaSeeking_SetRate(seek
, dRate
);
794 IMediaSeeking_Release(seek
);
801 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
803 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
806 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
807 hr
= get_connected(This
, &seek
);
809 hr
= IMediaSeeking_GetRate(seek
, dRate
);
810 IMediaSeeking_Release(seek
);
817 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
819 ICOM_THIS_MULTI(PassThruImpl
, IMediaSeeking_vtbl
, iface
);
822 TRACE("(%p)\n", pPreroll
);
823 hr
= get_connected(This
, &seek
);
825 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
826 IMediaSeeking_Release(seek
);
833 void MediaSeekingPassThru_RegisterMediaTime(IUnknown
*iface
, REFERENCE_TIME start
) {
834 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
835 EnterCriticalSection(&This
->time_cs
);
836 This
->time_earliest
= start
;
838 LeaveCriticalSection(&This
->time_cs
);
841 void MediaSeekingPassThru_ResetMediaTime(IUnknown
*iface
) {
842 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
843 EnterCriticalSection(&This
->time_cs
);
845 LeaveCriticalSection(&This
->time_cs
);
848 void MediaSeekingPassThru_EOS(IUnknown
*iface
) {
849 ICOM_THIS_MULTI(PassThruImpl
, IInner_vtbl
, iface
);
852 hr
= IMediaSeeking_GetStopPosition((IMediaSeeking
*)&This
->IMediaSeeking_vtbl
, &time
);
853 EnterCriticalSection(&This
->time_cs
);
856 This
->time_earliest
= time
;
859 LeaveCriticalSection(&This
->time_cs
);
862 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
864 MediaSeekingPassThru_QueryInterface
,
865 MediaSeekingPassThru_AddRef
,
866 MediaSeekingPassThru_Release
,
867 MediaSeekingPassThru_GetCapabilities
,
868 MediaSeekingPassThru_CheckCapabilities
,
869 MediaSeekingPassThru_IsFormatSupported
,
870 MediaSeekingPassThru_QueryPreferredFormat
,
871 MediaSeekingPassThru_GetTimeFormat
,
872 MediaSeekingPassThru_IsUsingTimeFormat
,
873 MediaSeekingPassThru_SetTimeFormat
,
874 MediaSeekingPassThru_GetDuration
,
875 MediaSeekingPassThru_GetStopPosition
,
876 MediaSeekingPassThru_GetCurrentPosition
,
877 MediaSeekingPassThru_ConvertTimeFormat
,
878 MediaSeekingPassThru_SetPositions
,
879 MediaSeekingPassThru_GetPositions
,
880 MediaSeekingPassThru_GetAvailable
,
881 MediaSeekingPassThru_SetRate
,
882 MediaSeekingPassThru_GetRate
,
883 MediaSeekingPassThru_GetPreroll