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 */
23 #include "strmbase_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
27 static struct strmbase_passthrough
*impl_from_ISeekingPassThru(ISeekingPassThru
*iface
)
29 return CONTAINING_RECORD(iface
, struct strmbase_passthrough
, ISeekingPassThru_iface
);
32 static struct strmbase_passthrough
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
34 return CONTAINING_RECORD(iface
, struct strmbase_passthrough
, IMediaSeeking_iface
);
37 static struct strmbase_passthrough
*impl_from_IMediaPosition(IMediaPosition
*iface
)
39 return CONTAINING_RECORD(iface
, struct strmbase_passthrough
, IMediaPosition_iface
);
42 static HRESULT WINAPI
SeekingPassThru_QueryInterface(ISeekingPassThru
*iface
, REFIID iid
, void **out
)
44 struct strmbase_passthrough
*passthrough
= impl_from_ISeekingPassThru(iface
);
46 return IUnknown_QueryInterface(passthrough
->outer_unk
, iid
, out
);
49 static ULONG WINAPI
SeekingPassThru_AddRef(ISeekingPassThru
*iface
)
51 struct strmbase_passthrough
*passthrough
= impl_from_ISeekingPassThru(iface
);
53 return IUnknown_AddRef(passthrough
->outer_unk
);
56 static ULONG WINAPI
SeekingPassThru_Release(ISeekingPassThru
*iface
)
58 struct strmbase_passthrough
*passthrough
= impl_from_ISeekingPassThru(iface
);
60 return IUnknown_Release(passthrough
->outer_unk
);
63 static HRESULT WINAPI
SeekingPassThru_Init(ISeekingPassThru
*iface
, BOOL renderer
, IPin
*pin
)
65 struct strmbase_passthrough
*This
= impl_from_ISeekingPassThru(iface
);
67 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, renderer
, pin
);
70 FIXME("Re-initializing?\n");
72 This
->renderer
= renderer
;
78 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl
=
80 SeekingPassThru_QueryInterface
,
81 SeekingPassThru_AddRef
,
82 SeekingPassThru_Release
,
86 static HRESULT WINAPI
MediaSeekingPassThru_QueryInterface(IMediaSeeking
*iface
, REFIID iid
, void **out
)
88 struct strmbase_passthrough
*passthrough
= impl_from_IMediaSeeking(iface
);
90 return IUnknown_QueryInterface(passthrough
->outer_unk
, iid
, out
);
93 static ULONG WINAPI
MediaSeekingPassThru_AddRef(IMediaSeeking
*iface
)
95 struct strmbase_passthrough
*passthrough
= impl_from_IMediaSeeking(iface
);
97 return IUnknown_AddRef(passthrough
->outer_unk
);
100 static ULONG WINAPI
MediaSeekingPassThru_Release(IMediaSeeking
*iface
)
102 struct strmbase_passthrough
*passthrough
= impl_from_IMediaSeeking(iface
);
104 return IUnknown_Release(passthrough
->outer_unk
);
107 static HRESULT
get_connected(struct strmbase_passthrough
*This
, REFIID riid
, void **ppvObj
)
112 hr
= IPin_ConnectedTo(This
->pin
, &pin
);
114 return VFW_E_NOT_CONNECTED
;
115 hr
= IPin_QueryInterface(pin
, riid
, ppvObj
);
122 static HRESULT WINAPI
MediaSeekingPassThru_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
124 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
127 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
128 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
130 hr
= IMediaSeeking_GetCapabilities(seek
, pCapabilities
);
131 IMediaSeeking_Release(seek
);
138 static HRESULT WINAPI
MediaSeekingPassThru_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
140 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
143 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCapabilities
);
144 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
146 hr
= IMediaSeeking_CheckCapabilities(seek
, pCapabilities
);
147 IMediaSeeking_Release(seek
);
154 static HRESULT WINAPI
MediaSeekingPassThru_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
156 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
159 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
160 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
162 hr
= IMediaSeeking_IsFormatSupported(seek
, pFormat
);
163 IMediaSeeking_Release(seek
);
170 static HRESULT WINAPI
MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
172 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
175 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
176 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
178 hr
= IMediaSeeking_QueryPreferredFormat(seek
, pFormat
);
179 IMediaSeeking_Release(seek
);
186 static HRESULT WINAPI
MediaSeekingPassThru_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
188 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
191 TRACE("(%p/%p)->(%p)\n", iface
, This
, pFormat
);
192 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
194 hr
= IMediaSeeking_GetTimeFormat(seek
, pFormat
);
195 IMediaSeeking_Release(seek
);
202 static HRESULT WINAPI
MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
204 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
207 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
208 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
210 hr
= IMediaSeeking_IsUsingTimeFormat(seek
, pFormat
);
211 IMediaSeeking_Release(seek
);
218 static HRESULT WINAPI
MediaSeekingPassThru_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
220 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
223 TRACE("(%p/%p)->(%s)\n", iface
, This
, debugstr_guid(pFormat
));
224 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
226 hr
= IMediaSeeking_SetTimeFormat(seek
, pFormat
);
227 IMediaSeeking_Release(seek
);
234 static HRESULT WINAPI
MediaSeekingPassThru_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
236 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
239 TRACE("(%p/%p)->(%p)\n", iface
, This
, pDuration
);
240 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
242 hr
= IMediaSeeking_GetDuration(seek
, pDuration
);
243 IMediaSeeking_Release(seek
);
250 static HRESULT WINAPI
MediaSeekingPassThru_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
252 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
255 TRACE("(%p/%p)->(%p)\n", iface
, This
, pStop
);
256 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
258 hr
= IMediaSeeking_GetStopPosition(seek
, pStop
);
259 IMediaSeeking_Release(seek
);
266 static HRESULT WINAPI
MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
268 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
271 TRACE("(%p/%p)->(%p)\n", iface
, This
, pCurrent
);
274 EnterCriticalSection(&This
->time_cs
);
276 *pCurrent
= This
->time_earliest
;
279 LeaveCriticalSection(&This
->time_cs
);
281 hr
= IMediaSeeking_ConvertTimeFormat(iface
, pCurrent
, NULL
, *pCurrent
, &TIME_FORMAT_MEDIA_TIME
);
284 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
286 hr
= IMediaSeeking_GetCurrentPosition(seek
, pCurrent
);
287 IMediaSeeking_Release(seek
);
294 static HRESULT WINAPI
MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
296 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
300 TRACE("iface %p, target %p, target_format %s, source %s, source_format %s.\n",
301 iface
, pTarget
, debugstr_guid(pTargetFormat
),
302 wine_dbgstr_longlong(Source
), debugstr_guid(pSourceFormat
));
304 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
306 hr
= IMediaSeeking_ConvertTimeFormat(seek
, pTarget
, pTargetFormat
, Source
, pSourceFormat
);
307 IMediaSeeking_Release(seek
);
314 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
316 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
320 TRACE("iface %p, current %p, current_flags %#lx, stop %p, stop_flags %#lx.\n",
321 iface
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
323 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
325 hr
= IMediaSeeking_SetPositions(seek
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
326 IMediaSeeking_Release(seek
);
327 } else if (hr
== VFW_E_NOT_CONNECTED
)
332 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
334 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
337 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
338 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
340 hr
= IMediaSeeking_GetPositions(seek
, pCurrent
, pStop
);
341 IMediaSeeking_Release(seek
);
348 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
350 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
353 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
354 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
356 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
357 IMediaSeeking_Release(seek
);
364 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
366 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
369 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
370 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
372 hr
= IMediaSeeking_SetRate(seek
, dRate
);
373 IMediaSeeking_Release(seek
);
380 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
382 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
385 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
386 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
388 hr
= IMediaSeeking_GetRate(seek
, dRate
);
389 IMediaSeeking_Release(seek
);
396 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
398 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
401 TRACE("(%p)\n", pPreroll
);
402 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
404 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
405 IMediaSeeking_Release(seek
);
412 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
414 MediaSeekingPassThru_QueryInterface
,
415 MediaSeekingPassThru_AddRef
,
416 MediaSeekingPassThru_Release
,
417 MediaSeekingPassThru_GetCapabilities
,
418 MediaSeekingPassThru_CheckCapabilities
,
419 MediaSeekingPassThru_IsFormatSupported
,
420 MediaSeekingPassThru_QueryPreferredFormat
,
421 MediaSeekingPassThru_GetTimeFormat
,
422 MediaSeekingPassThru_IsUsingTimeFormat
,
423 MediaSeekingPassThru_SetTimeFormat
,
424 MediaSeekingPassThru_GetDuration
,
425 MediaSeekingPassThru_GetStopPosition
,
426 MediaSeekingPassThru_GetCurrentPosition
,
427 MediaSeekingPassThru_ConvertTimeFormat
,
428 MediaSeekingPassThru_SetPositions
,
429 MediaSeekingPassThru_GetPositions
,
430 MediaSeekingPassThru_GetAvailable
,
431 MediaSeekingPassThru_SetRate
,
432 MediaSeekingPassThru_GetRate
,
433 MediaSeekingPassThru_GetPreroll
436 static HRESULT WINAPI
MediaPositionPassThru_QueryInterface(IMediaPosition
*iface
, REFIID iid
, void **out
)
438 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
440 return IUnknown_QueryInterface(passthrough
->outer_unk
, iid
, out
);
443 static ULONG WINAPI
MediaPositionPassThru_AddRef(IMediaPosition
*iface
)
445 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
447 return IUnknown_AddRef(passthrough
->outer_unk
);
450 static ULONG WINAPI
MediaPositionPassThru_Release(IMediaPosition
*iface
)
452 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
454 return IUnknown_Release(passthrough
->outer_unk
);
457 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfoCount(IMediaPosition
*iface
, UINT
*count
)
459 TRACE("iface %p, count %p.\n", iface
, count
);
464 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfo(IMediaPosition
*iface
, UINT index
,
465 LCID lcid
, ITypeInfo
**typeinfo
)
467 TRACE("iface %p, index %u, lcid %#lx, typeinfo %p.\n", iface
, index
, lcid
, typeinfo
);
468 return strmbase_get_typeinfo(IMediaPosition_tid
, typeinfo
);
471 static HRESULT WINAPI
MediaPositionPassThru_GetIDsOfNames(IMediaPosition
*iface
, REFIID iid
,
472 LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*ids
)
477 TRACE("iface %p, iid %s, names %p, count %u, lcid %#lx, ids %p.\n",
478 iface
, debugstr_guid(iid
), names
, count
, lcid
, ids
);
480 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IMediaPosition_tid
, &typeinfo
)))
482 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, ids
);
483 ITypeInfo_Release(typeinfo
);
488 static HRESULT WINAPI
MediaPositionPassThru_Invoke(IMediaPosition
*iface
, DISPID id
, REFIID iid
, LCID lcid
,
489 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*error_arg
)
494 TRACE("iface %p, id %ld, iid %s, lcid %#lx, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
495 iface
, id
, debugstr_guid(iid
), lcid
, flags
, params
, result
, excepinfo
, error_arg
);
497 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IMediaPosition_tid
, &typeinfo
)))
499 hr
= ITypeInfo_Invoke(typeinfo
, iface
, id
, flags
, params
, result
, excepinfo
, error_arg
);
500 ITypeInfo_Release(typeinfo
);
505 static HRESULT WINAPI
MediaPositionPassThru_get_Duration(IMediaPosition
*iface
, REFTIME
*plength
)
507 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
511 TRACE("(%p)\n", plength
);
513 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
515 hr
= IMediaPosition_get_Duration(pos
, plength
);
516 IMediaPosition_Release(pos
);
523 static HRESULT WINAPI
MediaPositionPassThru_put_CurrentPosition(IMediaPosition
*iface
, REFTIME llTime
)
525 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
529 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
531 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
533 hr
= IMediaPosition_put_CurrentPosition(pos
, llTime
);
534 IMediaPosition_Release(pos
);
541 static HRESULT WINAPI
MediaPositionPassThru_get_CurrentPosition(IMediaPosition
*iface
, REFTIME
*pllTime
)
543 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
547 TRACE("(%p)\n", pllTime
);
549 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
551 hr
= IMediaPosition_get_CurrentPosition(pos
, pllTime
);
552 IMediaPosition_Release(pos
);
559 static HRESULT WINAPI
MediaPositionPassThru_get_StopTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
561 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
565 TRACE("(%p)\n", pllTime
);
567 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
569 hr
= IMediaPosition_get_StopTime(pos
, pllTime
);
570 IMediaPosition_Release(pos
);
577 static HRESULT WINAPI
MediaPositionPassThru_put_StopTime(IMediaPosition
*iface
, REFTIME llTime
)
579 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
583 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
585 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
587 hr
= IMediaPosition_put_StopTime(pos
, llTime
);
588 IMediaPosition_Release(pos
);
595 static HRESULT WINAPI
MediaPositionPassThru_get_PrerollTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
597 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
601 TRACE("(%p)\n", pllTime
);
603 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
605 hr
= IMediaPosition_get_PrerollTime(pos
, pllTime
);
606 IMediaPosition_Release(pos
);
613 static HRESULT WINAPI
MediaPositionPassThru_put_PrerollTime(IMediaPosition
*iface
, REFTIME llTime
)
615 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
619 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
621 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
623 hr
= IMediaPosition_put_PrerollTime(pos
, llTime
);
624 IMediaPosition_Release(pos
);
631 static HRESULT WINAPI
MediaPositionPassThru_put_Rate(IMediaPosition
*iface
, double dRate
)
633 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
637 TRACE("(%f)\n", dRate
);
639 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
641 hr
= IMediaPosition_put_Rate(pos
, dRate
);
642 IMediaPosition_Release(pos
);
649 static HRESULT WINAPI
MediaPositionPassThru_get_Rate(IMediaPosition
*iface
, double *pdRate
)
651 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
655 TRACE("(%p)\n", pdRate
);
657 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
659 hr
= IMediaPosition_get_Rate(pos
, pdRate
);
660 IMediaPosition_Release(pos
);
667 static HRESULT WINAPI
MediaPositionPassThru_CanSeekForward(IMediaPosition
*iface
, LONG
*pCanSeekForward
)
669 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
673 TRACE("(%p)\n", pCanSeekForward
);
675 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
677 hr
= IMediaPosition_CanSeekForward(pos
, pCanSeekForward
);
678 IMediaPosition_Release(pos
);
685 static HRESULT WINAPI
MediaPositionPassThru_CanSeekBackward(IMediaPosition
*iface
, LONG
*pCanSeekBackward
)
687 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
691 TRACE("(%p)\n", pCanSeekBackward
);
693 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
695 hr
= IMediaPosition_CanSeekBackward(pos
, pCanSeekBackward
);
696 IMediaPosition_Release(pos
);
703 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
=
705 MediaPositionPassThru_QueryInterface
,
706 MediaPositionPassThru_AddRef
,
707 MediaPositionPassThru_Release
,
708 MediaPositionPassThru_GetTypeInfoCount
,
709 MediaPositionPassThru_GetTypeInfo
,
710 MediaPositionPassThru_GetIDsOfNames
,
711 MediaPositionPassThru_Invoke
,
712 MediaPositionPassThru_get_Duration
,
713 MediaPositionPassThru_put_CurrentPosition
,
714 MediaPositionPassThru_get_CurrentPosition
,
715 MediaPositionPassThru_get_StopTime
,
716 MediaPositionPassThru_put_StopTime
,
717 MediaPositionPassThru_get_PrerollTime
,
718 MediaPositionPassThru_put_PrerollTime
,
719 MediaPositionPassThru_put_Rate
,
720 MediaPositionPassThru_get_Rate
,
721 MediaPositionPassThru_CanSeekForward
,
722 MediaPositionPassThru_CanSeekBackward
725 void strmbase_passthrough_init(struct strmbase_passthrough
*passthrough
, IUnknown
*outer
)
727 memset(passthrough
, 0, sizeof(*passthrough
));
729 passthrough
->outer_unk
= outer
;
730 passthrough
->IMediaPosition_iface
.lpVtbl
= &IMediaPositionPassThru_Vtbl
;
731 passthrough
->IMediaSeeking_iface
.lpVtbl
= &IMediaSeekingPassThru_Vtbl
;
732 passthrough
->ISeekingPassThru_iface
.lpVtbl
= &ISeekingPassThru_Vtbl
;
733 InitializeCriticalSection(&passthrough
->time_cs
);
734 passthrough
->time_cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": strmbase_passthrough.time_cs" );
737 void strmbase_passthrough_cleanup(struct strmbase_passthrough
*passthrough
)
739 passthrough
->time_cs
.DebugInfo
->Spare
[0] = 0;
740 DeleteCriticalSection(&passthrough
->time_cs
);
743 void strmbase_passthrough_update_time(struct strmbase_passthrough
*passthrough
, REFERENCE_TIME time
)
745 EnterCriticalSection(&passthrough
->time_cs
);
746 passthrough
->time_earliest
= time
;
747 passthrough
->timevalid
= TRUE
;
748 LeaveCriticalSection(&passthrough
->time_cs
);
751 void strmbase_passthrough_invalidate_time(struct strmbase_passthrough
*passthrough
)
753 EnterCriticalSection(&passthrough
->time_cs
);
754 passthrough
->timevalid
= FALSE
;
755 LeaveCriticalSection(&passthrough
->time_cs
);
758 void strmbase_passthrough_eos(struct strmbase_passthrough
*passthrough
)
763 hr
= IMediaSeeking_GetStopPosition(&passthrough
->IMediaSeeking_iface
, &time
);
764 EnterCriticalSection(&passthrough
->time_cs
);
767 passthrough
->timevalid
= TRUE
;
768 passthrough
->time_earliest
= time
;
771 passthrough
->timevalid
= FALSE
;
772 LeaveCriticalSection(&passthrough
->time_cs
);