2 * Filter Seeking and Control Interfaces
4 * Copyright 2003 Robert Shearman
5 * Copyright 2010 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 */
26 #include "wine/strmbase.h"
29 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(strmbase
);
35 HRESULT
SourceSeeking_Init(SourceSeeking
*pSeeking
, const IMediaSeekingVtbl
*Vtbl
, SourceSeeking_ChangeStop fnChangeStop
, SourceSeeking_ChangeStart fnChangeStart
, SourceSeeking_ChangeRate fnChangeRate
, PCRITICAL_SECTION crit_sect
)
37 assert(fnChangeStop
&& fnChangeStart
&& fnChangeRate
);
39 pSeeking
->lpVtbl
= Vtbl
;
40 pSeeking
->refCount
= 1;
41 pSeeking
->fnChangeRate
= fnChangeRate
;
42 pSeeking
->fnChangeStop
= fnChangeStop
;
43 pSeeking
->fnChangeStart
= fnChangeStart
;
44 pSeeking
->dwCapabilities
= AM_SEEKING_CanSeekForwards
|
45 AM_SEEKING_CanSeekBackwards
|
46 AM_SEEKING_CanSeekAbsolute
|
47 AM_SEEKING_CanGetStopPos
|
48 AM_SEEKING_CanGetDuration
;
49 pSeeking
->llCurrent
= 0;
50 pSeeking
->llStop
= ((ULONGLONG
)0x80000000) << 32;
51 pSeeking
->llDuration
= pSeeking
->llStop
;
52 pSeeking
->dRate
= 1.0;
53 pSeeking
->timeformat
= TIME_FORMAT_MEDIA_TIME
;
54 pSeeking
->crst
= crit_sect
;
58 HRESULT WINAPI
SourceSeekingImpl_GetCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
60 SourceSeeking
*This
= (SourceSeeking
*)iface
;
62 TRACE("(%p)\n", pCapabilities
);
64 *pCapabilities
= This
->dwCapabilities
;
69 HRESULT WINAPI
SourceSeekingImpl_CheckCapabilities(IMediaSeeking
* iface
, DWORD
* pCapabilities
)
71 SourceSeeking
*This
= (SourceSeeking
*)iface
;
75 TRACE("(%p)\n", pCapabilities
);
80 dwCommonCaps
= *pCapabilities
& This
->dwCapabilities
;
85 hr
= (*pCapabilities
== dwCommonCaps
) ? S_OK
: S_FALSE
;
86 *pCapabilities
= dwCommonCaps
;
90 HRESULT WINAPI
SourceSeekingImpl_IsFormatSupported(IMediaSeeking
* iface
, const GUID
* pFormat
)
92 TRACE("(%s)\n", debugstr_guid(pFormat
));
94 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: S_FALSE
);
97 HRESULT WINAPI
SourceSeekingImpl_QueryPreferredFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
99 TRACE("(%s)\n", debugstr_guid(pFormat
));
101 *pFormat
= TIME_FORMAT_MEDIA_TIME
;
105 HRESULT WINAPI
SourceSeekingImpl_GetTimeFormat(IMediaSeeking
* iface
, GUID
* pFormat
)
107 SourceSeeking
*This
= (SourceSeeking
*)iface
;
108 TRACE("(%s)\n", debugstr_guid(pFormat
));
110 EnterCriticalSection(This
->crst
);
111 *pFormat
= This
->timeformat
;
112 LeaveCriticalSection(This
->crst
);
117 HRESULT WINAPI
SourceSeekingImpl_IsUsingTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
119 SourceSeeking
*This
= (SourceSeeking
*)iface
;
122 TRACE("(%s)\n", debugstr_guid(pFormat
));
124 EnterCriticalSection(This
->crst
);
125 if (!IsEqualIID(pFormat
, &This
->timeformat
))
127 LeaveCriticalSection(This
->crst
);
132 HRESULT WINAPI
SourceSeekingImpl_SetTimeFormat(IMediaSeeking
* iface
, const GUID
* pFormat
)
134 SourceSeeking
*This
= (SourceSeeking
*)iface
;
135 TRACE("%p %s\n", This
, debugstr_guid(pFormat
));
136 return (IsEqualIID(pFormat
, &TIME_FORMAT_MEDIA_TIME
) ? S_OK
: E_INVALIDARG
);
140 HRESULT WINAPI
SourceSeekingImpl_GetDuration(IMediaSeeking
* iface
, LONGLONG
* pDuration
)
142 SourceSeeking
*This
= (SourceSeeking
*)iface
;
144 TRACE("(%p)\n", pDuration
);
146 EnterCriticalSection(This
->crst
);
147 *pDuration
= This
->llDuration
;
148 LeaveCriticalSection(This
->crst
);
153 HRESULT WINAPI
SourceSeekingImpl_GetStopPosition(IMediaSeeking
* iface
, LONGLONG
* pStop
)
155 SourceSeeking
*This
= (SourceSeeking
*)iface
;
157 TRACE("(%p)\n", pStop
);
159 EnterCriticalSection(This
->crst
);
160 *pStop
= This
->llStop
;
161 LeaveCriticalSection(This
->crst
);
166 /* FIXME: Make use of the info the filter should expose */
167 HRESULT WINAPI
SourceSeekingImpl_GetCurrentPosition(IMediaSeeking
* iface
, LONGLONG
* pCurrent
)
169 SourceSeeking
*This
= (SourceSeeking
*)iface
;
171 TRACE("(%p)\n", pCurrent
);
173 EnterCriticalSection(This
->crst
);
174 *pCurrent
= This
->llCurrent
;
175 LeaveCriticalSection(This
->crst
);
180 HRESULT WINAPI
SourceSeekingImpl_ConvertTimeFormat(IMediaSeeking
* iface
, LONGLONG
* pTarget
, const GUID
* pTargetFormat
, LONGLONG Source
, const GUID
* pSourceFormat
)
182 SourceSeeking
*This
= (SourceSeeking
*)iface
;
184 pTargetFormat
= &This
->timeformat
;
186 pSourceFormat
= &This
->timeformat
;
187 if (IsEqualIID(pTargetFormat
, &TIME_FORMAT_MEDIA_TIME
) && IsEqualIID(pSourceFormat
, &TIME_FORMAT_MEDIA_TIME
))
192 /* FIXME: clear pTarget? */
196 static inline LONGLONG
Adjust(LONGLONG value
, const LONGLONG
* pModifier
, DWORD dwFlags
)
198 switch (dwFlags
& AM_SEEKING_PositioningBitsMask
)
200 case AM_SEEKING_NoPositioning
:
202 case AM_SEEKING_AbsolutePositioning
:
204 case AM_SEEKING_RelativePositioning
:
205 case AM_SEEKING_IncrementalPositioning
:
206 return value
+ *pModifier
;
213 HRESULT WINAPI
SourceSeekingImpl_SetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
215 SourceSeeking
*This
= (SourceSeeking
*)iface
;
216 BOOL bChangeCurrent
= FALSE
, bChangeStop
= FALSE
;
217 LONGLONG llNewCurrent
, llNewStop
;
219 TRACE("(%p, %x, %p, %x)\n", pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
220 EnterCriticalSection(This
->crst
);
222 llNewCurrent
= Adjust(This
->llCurrent
, pCurrent
, dwCurrentFlags
);
223 llNewStop
= Adjust(This
->llStop
, pStop
, dwStopFlags
);
226 bChangeCurrent
= TRUE
;
227 if (llNewStop
!= This
->llStop
)
230 TRACE("Old: %u, New: %u\n", (DWORD
)(This
->llCurrent
/10000000), (DWORD
)(llNewCurrent
/10000000));
232 This
->llCurrent
= llNewCurrent
;
233 This
->llStop
= llNewStop
;
235 if (pCurrent
&& (dwCurrentFlags
& AM_SEEKING_ReturnTime
))
236 *pCurrent
= llNewCurrent
;
237 if (pStop
&& (dwStopFlags
& AM_SEEKING_ReturnTime
))
239 LeaveCriticalSection(This
->crst
);
242 This
->fnChangeStart(iface
);
244 This
->fnChangeStop(iface
);
249 HRESULT WINAPI
SourceSeekingImpl_GetPositions(IMediaSeeking
* iface
, LONGLONG
* pCurrent
, LONGLONG
* pStop
)
251 SourceSeeking
*This
= (SourceSeeking
*)iface
;
253 TRACE("(%p, %p)\n", pCurrent
, pStop
);
255 EnterCriticalSection(This
->crst
);
256 IMediaSeeking_GetCurrentPosition(iface
, pCurrent
);
257 IMediaSeeking_GetStopPosition(iface
, pStop
);
258 LeaveCriticalSection(This
->crst
);
263 HRESULT WINAPI
SourceSeekingImpl_GetAvailable(IMediaSeeking
* iface
, LONGLONG
* pEarliest
, LONGLONG
* pLatest
)
265 SourceSeeking
*This
= (SourceSeeking
*)iface
;
267 TRACE("(%p, %p)\n", pEarliest
, pLatest
);
269 EnterCriticalSection(This
->crst
);
271 *pLatest
= This
->llDuration
;
272 LeaveCriticalSection(This
->crst
);
277 HRESULT WINAPI
SourceSeekingImpl_SetRate(IMediaSeeking
* iface
, double dRate
)
279 SourceSeeking
*This
= (SourceSeeking
*)iface
;
280 BOOL bChangeRate
= (dRate
!= This
->dRate
);
283 TRACE("(%e)\n", dRate
);
285 if (dRate
> 100 || dRate
< .001)
287 FIXME("Excessive rate %e, ignoring\n", dRate
);
288 return VFW_E_UNSUPPORTED_AUDIO
;
291 EnterCriticalSection(This
->crst
);
294 hr
= This
->fnChangeRate(iface
);
295 LeaveCriticalSection(This
->crst
);
300 HRESULT WINAPI
SourceSeekingImpl_GetRate(IMediaSeeking
* iface
, double * dRate
)
302 SourceSeeking
*This
= (SourceSeeking
*)iface
;
304 TRACE("(%p)\n", dRate
);
306 EnterCriticalSection(This
->crst
);
308 *dRate
= This
->dRate
;
309 LeaveCriticalSection(This
->crst
);
314 HRESULT WINAPI
SourceSeekingImpl_GetPreroll(IMediaSeeking
* iface
, LONGLONG
* pPreroll
)
316 TRACE("(%p)\n", pPreroll
);