ReactOS  0.4.14-dev-57-g333b8f1
seeking.c
Go to the documentation of this file.
1 /*
2  * Filter Seeking and Control Interfaces
3  *
4  * Copyright 2003 Robert Shearman
5  * Copyright 2010 Aric Stewart, CodeWeavers
6  *
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.
11  *
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.
16  *
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
20  */
21 /* FIXME: critical sections */
22 
23 #define COBJMACROS
24 
25 #include "dshow.h"
26 #include "wine/strmbase.h"
27 
28 #include "uuids.h"
29 #include "wine/debug.h"
30 
31 #include <assert.h>
32 
34 
36 {
37  return CONTAINING_RECORD(iface, SourceSeeking, IMediaSeeking_iface);
38 }
39 
40 HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect)
41 {
42  assert(fnChangeStop && fnChangeStart && fnChangeRate);
43 
44  pSeeking->IMediaSeeking_iface.lpVtbl = Vtbl;
45  pSeeking->refCount = 1;
46  pSeeking->fnChangeRate = fnChangeRate;
47  pSeeking->fnChangeStop = fnChangeStop;
48  pSeeking->fnChangeStart = fnChangeStart;
54  pSeeking->llCurrent = 0;
55  pSeeking->llStop = ((ULONGLONG)0x80000000) << 32;
56  pSeeking->llDuration = pSeeking->llStop;
57  pSeeking->dRate = 1.0;
58  pSeeking->timeformat = TIME_FORMAT_MEDIA_TIME;
59  pSeeking->crst = crit_sect;
60  return S_OK;
61 }
62 
64 {
66 
67  TRACE("(%p)\n", pCapabilities);
68 
69  *pCapabilities = This->dwCapabilities;
70 
71  return S_OK;
72 }
73 
75 {
77  HRESULT hr;
78  DWORD dwCommonCaps;
79 
80  TRACE("(%p)\n", pCapabilities);
81 
82  if (!pCapabilities)
83  return E_POINTER;
84 
85  dwCommonCaps = *pCapabilities & This->dwCapabilities;
86 
87  if (!dwCommonCaps)
88  hr = E_FAIL;
89  else
90  hr = (*pCapabilities == dwCommonCaps) ? S_OK : S_FALSE;
91  *pCapabilities = dwCommonCaps;
92  return hr;
93 }
94 
96 {
97  TRACE("(%s)\n", debugstr_guid(pFormat));
98 
99  return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE);
100 }
101 
103 {
104  TRACE("(%s)\n", debugstr_guid(pFormat));
105 
106  *pFormat = TIME_FORMAT_MEDIA_TIME;
107  return S_OK;
108 }
109 
111 {
113  TRACE("(%s)\n", debugstr_guid(pFormat));
114 
115  EnterCriticalSection(This->crst);
116  *pFormat = This->timeformat;
117  LeaveCriticalSection(This->crst);
118 
119  return S_OK;
120 }
121 
123 {
125  HRESULT hr = S_OK;
126 
127  TRACE("(%s)\n", debugstr_guid(pFormat));
128 
129  EnterCriticalSection(This->crst);
130  if (!IsEqualIID(pFormat, &This->timeformat))
131  hr = S_FALSE;
132  LeaveCriticalSection(This->crst);
133 
134  return hr;
135 }
136 
138 {
140  TRACE("%p %s\n", This, debugstr_guid(pFormat));
141  return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : E_INVALIDARG);
142 }
143 
144 
146 {
148 
149  TRACE("(%p)\n", pDuration);
150 
151  EnterCriticalSection(This->crst);
152  *pDuration = This->llDuration;
153  LeaveCriticalSection(This->crst);
154 
155  return S_OK;
156 }
157 
159 {
161 
162  TRACE("(%p)\n", pStop);
163 
164  EnterCriticalSection(This->crst);
165  *pStop = This->llStop;
166  LeaveCriticalSection(This->crst);
167 
168  return S_OK;
169 }
170 
171 /* FIXME: Make use of the info the filter should expose */
173 {
175 
176  TRACE("(%p)\n", pCurrent);
177 
178  EnterCriticalSection(This->crst);
179  *pCurrent = This->llCurrent;
180  LeaveCriticalSection(This->crst);
181 
182  return S_OK;
183 }
184 
185 HRESULT WINAPI SourceSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
186 {
188  if (!pTargetFormat)
189  pTargetFormat = &This->timeformat;
190  if (!pSourceFormat)
191  pSourceFormat = &This->timeformat;
192  if (IsEqualIID(pTargetFormat, &TIME_FORMAT_MEDIA_TIME) && IsEqualIID(pSourceFormat, &TIME_FORMAT_MEDIA_TIME))
193  {
194  *pTarget = Source;
195  return S_OK;
196  }
197  /* FIXME: clear pTarget? */
198  return E_INVALIDARG;
199 }
200 
201 static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD dwFlags)
202 {
204  {
206  return value;
208  return *pModifier;
211  return value + *pModifier;
212  default:
213  assert(FALSE);
214  return 0;
215  }
216 }
217 
218 HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
219 {
221  BOOL bChangeCurrent = FALSE, bChangeStop = FALSE;
222  LONGLONG llNewCurrent, llNewStop;
223 
224  TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags);
225  EnterCriticalSection(This->crst);
226 
227  llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags);
228  llNewStop = Adjust(This->llStop, pStop, dwStopFlags);
229 
230  if (pCurrent)
231  bChangeCurrent = TRUE;
232  if (llNewStop != This->llStop)
233  bChangeStop = TRUE;
234 
235  TRACE("Old: %u, New: %u\n", (DWORD)(This->llCurrent/10000000), (DWORD)(llNewCurrent/10000000));
236 
237  This->llCurrent = llNewCurrent;
238  This->llStop = llNewStop;
239 
240  if (pCurrent && (dwCurrentFlags & AM_SEEKING_ReturnTime))
241  *pCurrent = llNewCurrent;
242  if (pStop && (dwStopFlags & AM_SEEKING_ReturnTime))
243  *pStop = llNewStop;
244  LeaveCriticalSection(This->crst);
245 
246  if (bChangeCurrent)
247  This->fnChangeStart(iface);
248  if (bChangeStop)
249  This->fnChangeStop(iface);
250 
251  return S_OK;
252 }
253 
255 {
257 
258  TRACE("(%p, %p)\n", pCurrent, pStop);
259 
260  EnterCriticalSection(This->crst);
261  IMediaSeeking_GetCurrentPosition(iface, pCurrent);
262  IMediaSeeking_GetStopPosition(iface, pStop);
263  LeaveCriticalSection(This->crst);
264 
265  return S_OK;
266 }
267 
269 {
271 
272  TRACE("(%p, %p)\n", pEarliest, pLatest);
273 
274  EnterCriticalSection(This->crst);
275  *pEarliest = 0;
276  *pLatest = This->llDuration;
277  LeaveCriticalSection(This->crst);
278 
279  return S_OK;
280 }
281 
283 {
285  BOOL bChangeRate = (dRate != This->dRate);
286  HRESULT hr = S_OK;
287 
288  TRACE("(%e)\n", dRate);
289 
290  if (dRate > 100 || dRate < .001)
291  {
292  FIXME("Excessive rate %e, ignoring\n", dRate);
294  }
295 
296  EnterCriticalSection(This->crst);
297  This->dRate = dRate;
298  if (bChangeRate)
299  hr = This->fnChangeRate(iface);
300  LeaveCriticalSection(This->crst);
301 
302  return hr;
303 }
304 
306 {
308 
309  TRACE("(%p)\n", dRate);
310 
311  EnterCriticalSection(This->crst);
312  /* Forward? */
313  *dRate = This->dRate;
314  LeaveCriticalSection(This->crst);
315 
316  return S_OK;
317 }
318 
320 {
321  TRACE("(%p)\n", pPreroll);
322 
323  *pPreroll = 0;
324  return S_OK;
325 }
HRESULT(WINAPI * SourceSeeking_ChangeRate)(IMediaSeeking *iface)
Definition: strmbase.h:270
SourceSeeking_ChangeStart fnChangeStart
Definition: strmbase.h:280
#define TRUE
Definition: types.h:120
DWORD dwCapabilities
Definition: strmbase.h:282
#define VFW_E_UNSUPPORTED_AUDIO
Definition: vfwmsgs.h:112
HRESULT hr
Definition: shlfolder.c:183
LONGLONG llStop
Definition: strmbase.h:284
static LONGLONG Adjust(LONGLONG value, const LONGLONG *pModifier, DWORD dwFlags)
Definition: seeking.c:201
HRESULT WINAPI SourceSeekingImpl_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *pCurrent)
Definition: seeking.c:172
#define assert(x)
Definition: debug.h:53
HRESULT WINAPI SourceSeekingImpl_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat)
Definition: seeking.c:185
HRESULT WINAPI SourceSeekingImpl_GetPositions(IMediaSeeking *iface, LONGLONG *pCurrent, LONGLONG *pStop)
Definition: seeking.c:254
IMediaSeeking IMediaSeeking_iface
Definition: strmbase.h:276
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI SourceSeekingImpl_GetStopPosition(IMediaSeeking *iface, LONGLONG *pStop)
Definition: seeking.c:158
HRESULT(WINAPI * SourceSeeking_ChangeStop)(IMediaSeeking *iface)
Definition: strmbase.h:272
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT(WINAPI * SourceSeeking_ChangeStart)(IMediaSeeking *iface)
Definition: strmbase.h:271
#define FIXME(fmt,...)
Definition: debug.h:110
GUID timeformat
Definition: strmbase.h:285
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT WINAPI SourceSeekingImpl_IsFormatSupported(IMediaSeeking *iface, const GUID *pFormat)
Definition: seeking.c:95
WINE_DEFAULT_DEBUG_CHANNEL(strmbase)
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
SourceSeeking_ChangeStop fnChangeStop
Definition: strmbase.h:279
int64_t LONGLONG
Definition: typedefs.h:66
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI SourceSeekingImpl_GetDuration(IMediaSeeking *iface, LONGLONG *pDuration)
Definition: seeking.c:145
HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking *iface, LONGLONG *pPreroll)
Definition: seeking.c:319
LONG HRESULT
Definition: typedefs.h:77
uint64_t ULONGLONG
Definition: typedefs.h:65
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
LONGLONG llDuration
Definition: strmbase.h:284
HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect)
Definition: seeking.c:40
static SourceSeeking * impl_from_IMediaSeeking(IMediaSeeking *iface)
Definition: seeking.c:35
HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking *iface, double dRate)
Definition: seeking.c:282
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
HRESULT WINAPI SourceSeekingImpl_GetCapabilities(IMediaSeeking *iface, DWORD *pCapabilities)
Definition: seeking.c:63
LONGLONG llCurrent
Definition: strmbase.h:284
HRESULT WINAPI SourceSeekingImpl_QueryPreferredFormat(IMediaSeeking *iface, GUID *pFormat)
Definition: seeking.c:102
GLsizei const GLfloat * value
Definition: glext.h:6069
HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking *iface, LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags)
Definition: seeking.c:218
HRESULT WINAPI SourceSeekingImpl_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *pFormat)
Definition: seeking.c:122
#define S_OK
Definition: intsafe.h:59
HRESULT WINAPI SourceSeekingImpl_CheckCapabilities(IMediaSeeking *iface, DWORD *pCapabilities)
Definition: seeking.c:74
HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking *iface, double *dRate)
Definition: seeking.c:305
HRESULT WINAPI SourceSeekingImpl_GetAvailable(IMediaSeeking *iface, LONGLONG *pEarliest, LONGLONG *pLatest)
Definition: seeking.c:268
double dRate
Definition: strmbase.h:283
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
HRESULT WINAPI SourceSeekingImpl_GetTimeFormat(IMediaSeeking *iface, GUID *pFormat)
Definition: seeking.c:110
SourceSeeking_ChangeRate fnChangeRate
Definition: strmbase.h:281
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define E_POINTER
Definition: winerror.h:2365
PCRITICAL_SECTION crst
Definition: strmbase.h:286
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
HRESULT WINAPI SourceSeekingImpl_SetTimeFormat(IMediaSeeking *iface, const GUID *pFormat)
Definition: seeking.c:137
ULONG refCount
Definition: strmbase.h:278