wineps: Handle EMRI_DEVMODE record in spool files.
[wine.git] / libs / strmbase / pospass.c
blob03cb7783f978f47f3a24de32a6a42b597bd517cf
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;
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);
305 if (SUCCEEDED(hr)) {
306 hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat);
307 IMediaSeeking_Release(seek);
309 else
310 return E_NOTIMPL;
311 return hr;
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);
317 IMediaSeeking *seek;
318 HRESULT hr;
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);
324 if (SUCCEEDED(hr)) {
325 hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
326 IMediaSeeking_Release(seek);
327 } else if (hr == VFW_E_NOT_CONNECTED)
328 hr = S_OK;
329 return hr;
332 static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
334 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
335 IMediaSeeking *seek;
336 HRESULT hr;
337 TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
338 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
339 if (SUCCEEDED(hr)) {
340 hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop);
341 IMediaSeeking_Release(seek);
343 else
344 return E_NOTIMPL;
345 return hr;
348 static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
350 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
351 IMediaSeeking *seek;
352 HRESULT hr;
353 TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
354 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
355 if (SUCCEEDED(hr)) {
356 hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest);
357 IMediaSeeking_Release(seek);
359 else
360 return E_NOTIMPL;
361 return hr;
364 static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
366 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
367 IMediaSeeking *seek;
368 HRESULT hr;
369 TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
370 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
371 if (SUCCEEDED(hr)) {
372 hr = IMediaSeeking_SetRate(seek, dRate);
373 IMediaSeeking_Release(seek);
375 else
376 return E_NOTIMPL;
377 return hr;
380 static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
382 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
383 IMediaSeeking *seek;
384 HRESULT hr;
385 TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
386 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
387 if (SUCCEEDED(hr)) {
388 hr = IMediaSeeking_GetRate(seek, dRate);
389 IMediaSeeking_Release(seek);
391 else
392 return E_NOTIMPL;
393 return hr;
396 static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
398 struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface);
399 IMediaSeeking *seek;
400 HRESULT hr;
401 TRACE("(%p)\n", pPreroll);
402 hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek);
403 if (SUCCEEDED(hr)) {
404 hr = IMediaSeeking_GetPreroll(seek, pPreroll);
405 IMediaSeeking_Release(seek);
407 else
408 return E_NOTIMPL;
409 return hr;
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);
460 *count = 1;
461 return S_OK;
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)
474 ITypeInfo *typeinfo;
475 HRESULT hr;
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);
485 return hr;
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)
491 ITypeInfo *typeinfo;
492 HRESULT hr;
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);
502 return hr;
505 static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface, REFTIME *plength)
507 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
508 IMediaPosition *pos;
509 HRESULT hr;
511 TRACE("(%p)\n", plength);
513 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
514 if (SUCCEEDED(hr)) {
515 hr = IMediaPosition_get_Duration(pos, plength);
516 IMediaPosition_Release(pos);
518 else
519 return E_NOTIMPL;
520 return hr;
523 static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *iface, REFTIME llTime)
525 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
526 IMediaPosition *pos;
527 HRESULT hr;
529 TRACE("iface %p, time %.16e.\n", iface, llTime);
531 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
532 if (SUCCEEDED(hr)) {
533 hr = IMediaPosition_put_CurrentPosition(pos, llTime);
534 IMediaPosition_Release(pos);
536 else
537 return E_NOTIMPL;
538 return hr;
541 static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *iface, REFTIME *pllTime)
543 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
544 IMediaPosition *pos;
545 HRESULT hr;
547 TRACE("(%p)\n", pllTime);
549 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
550 if (SUCCEEDED(hr)) {
551 hr = IMediaPosition_get_CurrentPosition(pos, pllTime);
552 IMediaPosition_Release(pos);
554 else
555 return E_NOTIMPL;
556 return hr;
559 static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface, REFTIME *pllTime)
561 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
562 IMediaPosition *pos;
563 HRESULT hr;
565 TRACE("(%p)\n", pllTime);
567 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
568 if (SUCCEEDED(hr)) {
569 hr = IMediaPosition_get_StopTime(pos, pllTime);
570 IMediaPosition_Release(pos);
572 else
573 return E_NOTIMPL;
574 return hr;
577 static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface, REFTIME llTime)
579 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
580 IMediaPosition *pos;
581 HRESULT hr;
583 TRACE("iface %p, time %.16e.\n", iface, llTime);
585 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
586 if (SUCCEEDED(hr)) {
587 hr = IMediaPosition_put_StopTime(pos, llTime);
588 IMediaPosition_Release(pos);
590 else
591 return E_NOTIMPL;
592 return hr;
595 static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *iface, REFTIME *pllTime)
597 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
598 IMediaPosition *pos;
599 HRESULT hr;
601 TRACE("(%p)\n", pllTime);
603 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
604 if (SUCCEEDED(hr)) {
605 hr = IMediaPosition_get_PrerollTime(pos, pllTime);
606 IMediaPosition_Release(pos);
608 else
609 return E_NOTIMPL;
610 return hr;
613 static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *iface, REFTIME llTime)
615 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
616 IMediaPosition *pos;
617 HRESULT hr;
619 TRACE("iface %p, time %.16e.\n", iface, llTime);
621 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
622 if (SUCCEEDED(hr)) {
623 hr = IMediaPosition_put_PrerollTime(pos, llTime);
624 IMediaPosition_Release(pos);
626 else
627 return E_NOTIMPL;
628 return hr;
631 static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, double dRate)
633 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
634 IMediaPosition *pos;
635 HRESULT hr;
637 TRACE("(%f)\n", dRate);
639 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
640 if (SUCCEEDED(hr)) {
641 hr = IMediaPosition_put_Rate(pos, dRate);
642 IMediaPosition_Release(pos);
644 else
645 return E_NOTIMPL;
646 return hr;
649 static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, double *pdRate)
651 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
652 IMediaPosition *pos;
653 HRESULT hr;
655 TRACE("(%p)\n", pdRate);
657 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
658 if (SUCCEEDED(hr)) {
659 hr = IMediaPosition_get_Rate(pos, pdRate);
660 IMediaPosition_Release(pos);
662 else
663 return E_NOTIMPL;
664 return hr;
667 static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface, LONG *pCanSeekForward)
669 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
670 IMediaPosition *pos;
671 HRESULT hr;
673 TRACE("(%p)\n", pCanSeekForward);
675 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
676 if (SUCCEEDED(hr)) {
677 hr = IMediaPosition_CanSeekForward(pos, pCanSeekForward);
678 IMediaPosition_Release(pos);
680 else
681 return E_NOTIMPL;
682 return hr;
685 static HRESULT WINAPI MediaPositionPassThru_CanSeekBackward(IMediaPosition *iface, LONG *pCanSeekBackward)
687 struct strmbase_passthrough *This = impl_from_IMediaPosition(iface);
688 IMediaPosition *pos;
689 HRESULT hr;
691 TRACE("(%p)\n", pCanSeekBackward);
693 hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos);
694 if (SUCCEEDED(hr)) {
695 hr = IMediaPosition_CanSeekBackward(pos, pCanSeekBackward);
696 IMediaPosition_Release(pos);
698 else
699 return E_NOTIMPL;
700 return hr;
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)
760 REFERENCE_TIME time;
761 HRESULT hr;
763 hr = IMediaSeeking_GetStopPosition(&passthrough->IMediaSeeking_iface, &time);
764 EnterCriticalSection(&passthrough->time_cs);
765 if (SUCCEEDED(hr))
767 passthrough->timevalid = TRUE;
768 passthrough->time_earliest = time;
770 else
771 passthrough->timevalid = FALSE;
772 LeaveCriticalSection(&passthrough->time_cs);