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(strmbase
);
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
);
299 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface
, This
, pTarget
, debugstr_guid(pTargetFormat
), (DWORD
)(Source
>>32), (DWORD
)Source
, debugstr_guid(pSourceFormat
));
300 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
302 hr
= IMediaSeeking_ConvertTimeFormat(seek
, pTarget
, pTargetFormat
, Source
, pSourceFormat
);
303 IMediaSeeking_Release(seek
);
310 static HRESULT WINAPI
MediaSeekingPassThru_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
312 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
315 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface
, This
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
316 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
318 hr
= IMediaSeeking_SetPositions(seek
, pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
319 IMediaSeeking_Release(seek
);
320 } else if (hr
== VFW_E_NOT_CONNECTED
)
325 static HRESULT WINAPI
MediaSeekingPassThru_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
327 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
330 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, pCurrent
, pStop
);
331 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
333 hr
= IMediaSeeking_GetPositions(seek
, pCurrent
, pStop
);
334 IMediaSeeking_Release(seek
);
341 static HRESULT WINAPI
MediaSeekingPassThru_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
343 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
346 TRACE("(%p/%p)->(%p,%p)\n", iface
, This
, pEarliest
, pLatest
);
347 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
349 hr
= IMediaSeeking_GetAvailable(seek
, pEarliest
, pLatest
);
350 IMediaSeeking_Release(seek
);
357 static HRESULT WINAPI
MediaSeekingPassThru_SetRate(IMediaSeeking
* iface
, double dRate
)
359 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
362 TRACE("(%p/%p)->(%e)\n", iface
, This
, dRate
);
363 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
365 hr
= IMediaSeeking_SetRate(seek
, dRate
);
366 IMediaSeeking_Release(seek
);
373 static HRESULT WINAPI
MediaSeekingPassThru_GetRate(IMediaSeeking
* iface
, double * dRate
)
375 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
378 TRACE("(%p/%p)->(%p)\n", iface
, This
, dRate
);
379 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
381 hr
= IMediaSeeking_GetRate(seek
, dRate
);
382 IMediaSeeking_Release(seek
);
389 static HRESULT WINAPI
MediaSeekingPassThru_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
391 struct strmbase_passthrough
*This
= impl_from_IMediaSeeking(iface
);
394 TRACE("(%p)\n", pPreroll
);
395 hr
= get_connected(This
, &IID_IMediaSeeking
, (LPVOID
*)&seek
);
397 hr
= IMediaSeeking_GetPreroll(seek
, pPreroll
);
398 IMediaSeeking_Release(seek
);
405 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl
=
407 MediaSeekingPassThru_QueryInterface
,
408 MediaSeekingPassThru_AddRef
,
409 MediaSeekingPassThru_Release
,
410 MediaSeekingPassThru_GetCapabilities
,
411 MediaSeekingPassThru_CheckCapabilities
,
412 MediaSeekingPassThru_IsFormatSupported
,
413 MediaSeekingPassThru_QueryPreferredFormat
,
414 MediaSeekingPassThru_GetTimeFormat
,
415 MediaSeekingPassThru_IsUsingTimeFormat
,
416 MediaSeekingPassThru_SetTimeFormat
,
417 MediaSeekingPassThru_GetDuration
,
418 MediaSeekingPassThru_GetStopPosition
,
419 MediaSeekingPassThru_GetCurrentPosition
,
420 MediaSeekingPassThru_ConvertTimeFormat
,
421 MediaSeekingPassThru_SetPositions
,
422 MediaSeekingPassThru_GetPositions
,
423 MediaSeekingPassThru_GetAvailable
,
424 MediaSeekingPassThru_SetRate
,
425 MediaSeekingPassThru_GetRate
,
426 MediaSeekingPassThru_GetPreroll
429 static HRESULT WINAPI
MediaPositionPassThru_QueryInterface(IMediaPosition
*iface
, REFIID iid
, void **out
)
431 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
433 return IUnknown_QueryInterface(passthrough
->outer_unk
, iid
, out
);
436 static ULONG WINAPI
MediaPositionPassThru_AddRef(IMediaPosition
*iface
)
438 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
440 return IUnknown_AddRef(passthrough
->outer_unk
);
443 static ULONG WINAPI
MediaPositionPassThru_Release(IMediaPosition
*iface
)
445 struct strmbase_passthrough
*passthrough
= impl_from_IMediaPosition(iface
);
447 return IUnknown_Release(passthrough
->outer_unk
);
450 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfoCount(IMediaPosition
*iface
, UINT
*count
)
452 TRACE("iface %p, count %p.\n", iface
, count
);
457 static HRESULT WINAPI
MediaPositionPassThru_GetTypeInfo(IMediaPosition
*iface
, UINT index
,
458 LCID lcid
, ITypeInfo
**typeinfo
)
460 TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface
, index
, lcid
, typeinfo
);
461 return strmbase_get_typeinfo(IMediaPosition_tid
, typeinfo
);
464 static HRESULT WINAPI
MediaPositionPassThru_GetIDsOfNames(IMediaPosition
*iface
, REFIID iid
,
465 LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*ids
)
470 TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
471 iface
, debugstr_guid(iid
), names
, count
, lcid
, ids
);
473 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IMediaPosition_tid
, &typeinfo
)))
475 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, ids
);
476 ITypeInfo_Release(typeinfo
);
481 static HRESULT WINAPI
MediaPositionPassThru_Invoke(IMediaPosition
*iface
, DISPID id
, REFIID iid
, LCID lcid
,
482 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*error_arg
)
487 TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
488 iface
, id
, debugstr_guid(iid
), lcid
, flags
, params
, result
, excepinfo
, error_arg
);
490 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IMediaPosition_tid
, &typeinfo
)))
492 hr
= ITypeInfo_Invoke(typeinfo
, iface
, id
, flags
, params
, result
, excepinfo
, error_arg
);
493 ITypeInfo_Release(typeinfo
);
498 static HRESULT WINAPI
MediaPositionPassThru_get_Duration(IMediaPosition
*iface
, REFTIME
*plength
)
500 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
504 TRACE("(%p)\n", plength
);
506 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
508 hr
= IMediaPosition_get_Duration(pos
, plength
);
509 IMediaPosition_Release(pos
);
516 static HRESULT WINAPI
MediaPositionPassThru_put_CurrentPosition(IMediaPosition
*iface
, REFTIME llTime
)
518 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
522 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
524 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
526 hr
= IMediaPosition_put_CurrentPosition(pos
, llTime
);
527 IMediaPosition_Release(pos
);
534 static HRESULT WINAPI
MediaPositionPassThru_get_CurrentPosition(IMediaPosition
*iface
, REFTIME
*pllTime
)
536 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
540 TRACE("(%p)\n", pllTime
);
542 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
544 hr
= IMediaPosition_get_CurrentPosition(pos
, pllTime
);
545 IMediaPosition_Release(pos
);
552 static HRESULT WINAPI
MediaPositionPassThru_get_StopTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
554 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
558 TRACE("(%p)\n", pllTime
);
560 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
562 hr
= IMediaPosition_get_StopTime(pos
, pllTime
);
563 IMediaPosition_Release(pos
);
570 static HRESULT WINAPI
MediaPositionPassThru_put_StopTime(IMediaPosition
*iface
, REFTIME llTime
)
572 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
576 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
578 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
580 hr
= IMediaPosition_put_StopTime(pos
, llTime
);
581 IMediaPosition_Release(pos
);
588 static HRESULT WINAPI
MediaPositionPassThru_get_PrerollTime(IMediaPosition
*iface
, REFTIME
*pllTime
)
590 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
594 TRACE("(%p)\n", pllTime
);
596 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
598 hr
= IMediaPosition_get_PrerollTime(pos
, pllTime
);
599 IMediaPosition_Release(pos
);
606 static HRESULT WINAPI
MediaPositionPassThru_put_PrerollTime(IMediaPosition
*iface
, REFTIME llTime
)
608 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
612 TRACE("iface %p, time %.16e.\n", iface
, llTime
);
614 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
616 hr
= IMediaPosition_put_PrerollTime(pos
, llTime
);
617 IMediaPosition_Release(pos
);
624 static HRESULT WINAPI
MediaPositionPassThru_put_Rate(IMediaPosition
*iface
, double dRate
)
626 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
630 TRACE("(%f)\n", dRate
);
632 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
634 hr
= IMediaPosition_put_Rate(pos
, dRate
);
635 IMediaPosition_Release(pos
);
642 static HRESULT WINAPI
MediaPositionPassThru_get_Rate(IMediaPosition
*iface
, double *pdRate
)
644 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
648 TRACE("(%p)\n", pdRate
);
650 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
652 hr
= IMediaPosition_get_Rate(pos
, pdRate
);
653 IMediaPosition_Release(pos
);
660 static HRESULT WINAPI
MediaPositionPassThru_CanSeekForward(IMediaPosition
*iface
, LONG
*pCanSeekForward
)
662 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
666 TRACE("(%p)\n", pCanSeekForward
);
668 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
670 hr
= IMediaPosition_CanSeekForward(pos
, pCanSeekForward
);
671 IMediaPosition_Release(pos
);
678 static HRESULT WINAPI
MediaPositionPassThru_CanSeekBackward(IMediaPosition
*iface
, LONG
*pCanSeekBackward
)
680 struct strmbase_passthrough
*This
= impl_from_IMediaPosition(iface
);
684 TRACE("(%p)\n", pCanSeekBackward
);
686 hr
= get_connected(This
, &IID_IMediaPosition
, (LPVOID
*)&pos
);
688 hr
= IMediaPosition_CanSeekBackward(pos
, pCanSeekBackward
);
689 IMediaPosition_Release(pos
);
696 static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl
=
698 MediaPositionPassThru_QueryInterface
,
699 MediaPositionPassThru_AddRef
,
700 MediaPositionPassThru_Release
,
701 MediaPositionPassThru_GetTypeInfoCount
,
702 MediaPositionPassThru_GetTypeInfo
,
703 MediaPositionPassThru_GetIDsOfNames
,
704 MediaPositionPassThru_Invoke
,
705 MediaPositionPassThru_get_Duration
,
706 MediaPositionPassThru_put_CurrentPosition
,
707 MediaPositionPassThru_get_CurrentPosition
,
708 MediaPositionPassThru_get_StopTime
,
709 MediaPositionPassThru_put_StopTime
,
710 MediaPositionPassThru_get_PrerollTime
,
711 MediaPositionPassThru_put_PrerollTime
,
712 MediaPositionPassThru_put_Rate
,
713 MediaPositionPassThru_get_Rate
,
714 MediaPositionPassThru_CanSeekForward
,
715 MediaPositionPassThru_CanSeekBackward
718 void strmbase_passthrough_init(struct strmbase_passthrough
*passthrough
, IUnknown
*outer
)
720 memset(passthrough
, 0, sizeof(*passthrough
));
722 passthrough
->outer_unk
= outer
;
723 passthrough
->IMediaPosition_iface
.lpVtbl
= &IMediaPositionPassThru_Vtbl
;
724 passthrough
->IMediaSeeking_iface
.lpVtbl
= &IMediaSeekingPassThru_Vtbl
;
725 passthrough
->ISeekingPassThru_iface
.lpVtbl
= &ISeekingPassThru_Vtbl
;
726 InitializeCriticalSection(&passthrough
->time_cs
);
727 passthrough
->time_cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": strmbase_passthrough.time_cs" );
730 void strmbase_passthrough_cleanup(struct strmbase_passthrough
*passthrough
)
732 passthrough
->time_cs
.DebugInfo
->Spare
[0] = 0;
733 DeleteCriticalSection(&passthrough
->time_cs
);
736 void strmbase_passthrough_update_time(struct strmbase_passthrough
*passthrough
, REFERENCE_TIME time
)
738 EnterCriticalSection(&passthrough
->time_cs
);
739 passthrough
->time_earliest
= time
;
740 passthrough
->timevalid
= TRUE
;
741 LeaveCriticalSection(&passthrough
->time_cs
);
744 void strmbase_passthrough_invalidate_time(struct strmbase_passthrough
*passthrough
)
746 EnterCriticalSection(&passthrough
->time_cs
);
747 passthrough
->timevalid
= FALSE
;
748 LeaveCriticalSection(&passthrough
->time_cs
);
751 void strmbase_passthrough_eos(struct strmbase_passthrough
*passthrough
)
756 hr
= IMediaSeeking_GetStopPosition(&passthrough
->IMediaSeeking_iface
, &time
);
757 EnterCriticalSection(&passthrough
->time_cs
);
760 passthrough
->timevalid
= TRUE
;
761 passthrough
->time_earliest
= time
;
764 passthrough
->timevalid
= FALSE
;
765 LeaveCriticalSection(&passthrough
->time_cs
);