ntdll: Make wine_build a hidden symbol.
[wine.git] / dlls / strmbase / pospass.c
blob7478c0e67c59d997a2e447bd22089fdbf666015f
1 /*
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);
69 if (This->pin)
70 FIXME("Re-initializing?\n");
72 This->renderer = renderer;
73 This->pin = pin;
75 return S_OK;
78 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
80 SeekingPassThru_QueryInterface,
81 SeekingPassThru_AddRef,
82 SeekingPassThru_Release,
83 SeekingPassThru_Init
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)
109 HRESULT hr;
110 IPin *pin;
111 *ppvObj = NULL;
112 hr = IPin_ConnectedTo(This->pin, &pin);
113 if (FAILED(hr))
114 return VFW_E_NOT_CONNECTED;
115 hr = IPin_QueryInterface(pin, riid, ppvObj);
116 IPin_Release(pin);
117 if (FAILED(hr))
118 hr = E_NOTIMPL;
119 return hr;
122 static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
124 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
125 IMediaSeeking *seek;
126 HRESULT hr;
127 TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
128 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
129 if (SUCCEEDED(hr)) {
130 hr = IMediaSeeking_GetCapabilities(seek, pCapabilities);
131 IMediaSeeking_Release(seek);
133 else
134 return E_NOTIMPL;
135 return hr;
138 static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
140 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
141 IMediaSeeking *seek;
142 HRESULT hr;
143 TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
144 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
145 if (SUCCEEDED(hr)) {
146 hr = IMediaSeeking_CheckCapabilities(seek, pCapabilities);
147 IMediaSeeking_Release(seek);
149 else
150 return E_NOTIMPL;
151 return hr;
154 static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
156 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
157 IMediaSeeking *seek;
158 HRESULT hr;
159 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
160 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
161 if (SUCCEEDED(hr)) {
162 hr = IMediaSeeking_IsFormatSupported(seek, pFormat);
163 IMediaSeeking_Release(seek);
165 else
166 return E_NOTIMPL;
167 return hr;
170 static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
172 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
173 IMediaSeeking *seek;
174 HRESULT hr;
175 TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
176 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
177 if (SUCCEEDED(hr)) {
178 hr = IMediaSeeking_QueryPreferredFormat(seek, pFormat);
179 IMediaSeeking_Release(seek);
181 else
182 return E_NOTIMPL;
183 return hr;
186 static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
188 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
189 IMediaSeeking *seek;
190 HRESULT hr;
191 TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
192 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
193 if (SUCCEEDED(hr)) {
194 hr = IMediaSeeking_GetTimeFormat(seek, pFormat);
195 IMediaSeeking_Release(seek);
197 else
198 return E_NOTIMPL;
199 return hr;
202 static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
204 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
205 IMediaSeeking *seek;
206 HRESULT hr;
207 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
208 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
209 if (SUCCEEDED(hr)) {
210 hr = IMediaSeeking_IsUsingTimeFormat(seek, pFormat);
211 IMediaSeeking_Release(seek);
213 else
214 return E_NOTIMPL;
215 return hr;
218 static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
220 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
221 IMediaSeeking *seek;
222 HRESULT hr;
223 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
224 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
225 if (SUCCEEDED(hr)) {
226 hr = IMediaSeeking_SetTimeFormat(seek, pFormat);
227 IMediaSeeking_Release(seek);
229 else
230 return E_NOTIMPL;
231 return hr;
234 static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
236 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
237 IMediaSeeking *seek;
238 HRESULT hr;
239 TRACE("(%p/%p)->(%p)\n", iface, This, pDuration);
240 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
241 if (SUCCEEDED(hr)) {
242 hr = IMediaSeeking_GetDuration(seek, pDuration);
243 IMediaSeeking_Release(seek);
245 else
246 return E_NOTIMPL;
247 return hr;
250 static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
252 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
253 IMediaSeeking *seek;
254 HRESULT hr;
255 TRACE("(%p/%p)->(%p)\n", iface, This, pStop);
256 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
257 if (SUCCEEDED(hr)) {
258 hr = IMediaSeeking_GetStopPosition(seek, pStop);
259 IMediaSeeking_Release(seek);
261 else
262 return E_NOTIMPL;
263 return hr;
266 static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
268 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
269 IMediaSeeking *seek;
270 HRESULT hr = S_OK;
271 TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent);
272 if (!pCurrent)
273 return E_POINTER;
274 EnterCriticalSection(&This->time_cs);
275 if (This->timevalid)
276 *pCurrent = This->time_earliest;
277 else
278 hr = E_FAIL;
279 LeaveCriticalSection(&This->time_cs);
280 if (SUCCEEDED(hr)) {
281 hr = IMediaSeeking_ConvertTimeFormat(iface, pCurrent, NULL, *pCurrent, &TIME_FORMAT_MEDIA_TIME);
282 return hr;
284 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
285 if (SUCCEEDED(hr)) {
286 hr = IMediaSeeking_GetCurrentPosition(seek, pCurrent);
287 IMediaSeeking_Release(seek);
289 else
290 return E_NOTIMPL;
291 return hr;
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);
297 IMediaSeeking *seek;
298 HRESULT hr;
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);
301 if (SUCCEEDED(hr)) {
302 hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat);
303 IMediaSeeking_Release(seek);
305 else
306 return E_NOTIMPL;
307 return hr;
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);
313 IMediaSeeking *seek;
314 HRESULT hr;
315 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface, This, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
316 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
317 if (SUCCEEDED(hr)) {
318 hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
319 IMediaSeeking_Release(seek);
320 } else if (hr == VFW_E_NOT_CONNECTED)
321 hr = S_OK;
322 return hr;
325 static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
327 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
328 IMediaSeeking *seek;
329 HRESULT hr;
330 TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
331 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
332 if (SUCCEEDED(hr)) {
333 hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop);
334 IMediaSeeking_Release(seek);
336 else
337 return E_NOTIMPL;
338 return hr;
341 static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
343 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
344 IMediaSeeking *seek;
345 HRESULT hr;
346 TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
347 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
348 if (SUCCEEDED(hr)) {
349 hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest);
350 IMediaSeeking_Release(seek);
352 else
353 return E_NOTIMPL;
354 return hr;
357 static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
359 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
360 IMediaSeeking *seek;
361 HRESULT hr;
362 TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
363 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
364 if (SUCCEEDED(hr)) {
365 hr = IMediaSeeking_SetRate(seek, dRate);
366 IMediaSeeking_Release(seek);
368 else
369 return E_NOTIMPL;
370 return hr;
373 static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
375 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
376 IMediaSeeking *seek;
377 HRESULT hr;
378 TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
379 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
380 if (SUCCEEDED(hr)) {
381 hr = IMediaSeeking_GetRate(seek, dRate);
382 IMediaSeeking_Release(seek);
384 else
385 return E_NOTIMPL;
386 return hr;
389 static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
391 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
392 IMediaSeeking *seek;
393 HRESULT hr;
394 TRACE("(%p)\n", pPreroll);
395 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
396 if (SUCCEEDED(hr)) {
397 hr = IMediaSeeking_GetPreroll(seek, pPreroll);
398 IMediaSeeking_Release(seek);
400 else
401 return E_NOTIMPL;
402 return hr;
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);
453 *count = 1;
454 return S_OK;
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)
467 ITypeInfo *typeinfo;
468 HRESULT hr;
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);
478 return hr;
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)
484 ITypeInfo *typeinfo;
485 HRESULT hr;
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);
495 return hr;
498 static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface, REFTIME *plength)
500 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
501 IMediaPosition *pos;
502 HRESULT hr;
504 TRACE("(%p)\n", plength);
506 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
507 if (SUCCEEDED(hr)) {
508 hr = IMediaPosition_get_Duration(pos, plength);
509 IMediaPosition_Release(pos);
511 else
512 return E_NOTIMPL;
513 return hr;
516 static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *iface, REFTIME llTime)
518 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
519 IMediaPosition *pos;
520 HRESULT hr;
522 TRACE("iface %p, time %.16e.\n", iface, llTime);
524 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
525 if (SUCCEEDED(hr)) {
526 hr = IMediaPosition_put_CurrentPosition(pos, llTime);
527 IMediaPosition_Release(pos);
529 else
530 return E_NOTIMPL;
531 return hr;
534 static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *iface, REFTIME *pllTime)
536 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
537 IMediaPosition *pos;
538 HRESULT hr;
540 TRACE("(%p)\n", pllTime);
542 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
543 if (SUCCEEDED(hr)) {
544 hr = IMediaPosition_get_CurrentPosition(pos, pllTime);
545 IMediaPosition_Release(pos);
547 else
548 return E_NOTIMPL;
549 return hr;
552 static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface, REFTIME *pllTime)
554 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
555 IMediaPosition *pos;
556 HRESULT hr;
558 TRACE("(%p)\n", pllTime);
560 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
561 if (SUCCEEDED(hr)) {
562 hr = IMediaPosition_get_StopTime(pos, pllTime);
563 IMediaPosition_Release(pos);
565 else
566 return E_NOTIMPL;
567 return hr;
570 static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface, REFTIME llTime)
572 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
573 IMediaPosition *pos;
574 HRESULT hr;
576 TRACE("iface %p, time %.16e.\n", iface, llTime);
578 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
579 if (SUCCEEDED(hr)) {
580 hr = IMediaPosition_put_StopTime(pos, llTime);
581 IMediaPosition_Release(pos);
583 else
584 return E_NOTIMPL;
585 return hr;
588 static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *iface, REFTIME *pllTime)
590 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
591 IMediaPosition *pos;
592 HRESULT hr;
594 TRACE("(%p)\n", pllTime);
596 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
597 if (SUCCEEDED(hr)) {
598 hr = IMediaPosition_get_PrerollTime(pos, pllTime);
599 IMediaPosition_Release(pos);
601 else
602 return E_NOTIMPL;
603 return hr;
606 static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *iface, REFTIME llTime)
608 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
609 IMediaPosition *pos;
610 HRESULT hr;
612 TRACE("iface %p, time %.16e.\n", iface, llTime);
614 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
615 if (SUCCEEDED(hr)) {
616 hr = IMediaPosition_put_PrerollTime(pos, llTime);
617 IMediaPosition_Release(pos);
619 else
620 return E_NOTIMPL;
621 return hr;
624 static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, double dRate)
626 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
627 IMediaPosition *pos;
628 HRESULT hr;
630 TRACE("(%f)\n", dRate);
632 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
633 if (SUCCEEDED(hr)) {
634 hr = IMediaPosition_put_Rate(pos, dRate);
635 IMediaPosition_Release(pos);
637 else
638 return E_NOTIMPL;
639 return hr;
642 static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, double *pdRate)
644 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
645 IMediaPosition *pos;
646 HRESULT hr;
648 TRACE("(%p)\n", pdRate);
650 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
651 if (SUCCEEDED(hr)) {
652 hr = IMediaPosition_get_Rate(pos, pdRate);
653 IMediaPosition_Release(pos);
655 else
656 return E_NOTIMPL;
657 return hr;
660 static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface, LONG *pCanSeekForward)
662 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
663 IMediaPosition *pos;
664 HRESULT hr;
666 TRACE("(%p)\n", pCanSeekForward);
668 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
669 if (SUCCEEDED(hr)) {
670 hr = IMediaPosition_CanSeekForward(pos, pCanSeekForward);
671 IMediaPosition_Release(pos);
673 else
674 return E_NOTIMPL;
675 return hr;
678 static HRESULT WINAPI MediaPositionPassThru_CanSeekBackward(IMediaPosition *iface, LONG *pCanSeekBackward)
680 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
681 IMediaPosition *pos;
682 HRESULT hr;
684 TRACE("(%p)\n", pCanSeekBackward);
686 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
687 if (SUCCEEDED(hr)) {
688 hr = IMediaPosition_CanSeekBackward(pos, pCanSeekBackward);
689 IMediaPosition_Release(pos);
691 else
692 return E_NOTIMPL;
693 return hr;
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)
753 REFERENCE_TIME time;
754 HRESULT hr;
756 hr = IMediaSeeking_GetStopPosition(&passthrough->IMediaSeeking_iface, &time);
757 EnterCriticalSection(&passthrough->time_cs);
758 if (SUCCEEDED(hr))
760 passthrough->timevalid = TRUE;
761 passthrough->time_earliest = time;
763 else
764 passthrough->timevalid = FALSE;
765 LeaveCriticalSection(&passthrough->time_cs);