strmbase: COM cleanup for PosPassThru.
[wine/multimedia.git] / dlls / strmbase / pospass.c
blobb62aff6949e3be2b1736867a2ebb20512cc73e03
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 #define COBJMACROS
25 #include "dshow.h"
26 #include "uuids.h"
28 #include "wine/debug.h"
29 #include "wine/strmbase.h"
31 #include <assert.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
35 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl;
37 typedef struct PassThruImpl {
38 IUnknown IUnknown_inner;
39 ISeekingPassThru ISeekingPassThru_iface;
40 IMediaSeeking IMediaSeeking_iface;
42 LONG ref;
43 IUnknown * outer_unk;
44 IPin * pin;
45 BOOL bUnkOuterValid;
46 BOOL bAggregatable;
47 BOOL renderer;
48 CRITICAL_SECTION time_cs;
49 BOOL timevalid;
50 REFERENCE_TIME time_earliest;
51 } PassThruImpl;
53 static inline PassThruImpl *impl_from_IUnknown_inner(IUnknown *iface)
55 return CONTAINING_RECORD(iface, PassThruImpl, IUnknown_inner);
58 static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface)
60 return CONTAINING_RECORD(iface, PassThruImpl, ISeekingPassThru_iface);
63 static inline PassThruImpl *impl_from_IMediaSeeking(IMediaSeeking *iface)
65 return CONTAINING_RECORD(iface, PassThruImpl, IMediaSeeking_iface);
68 static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface,
69 REFIID riid,
70 LPVOID *ppvObj) {
71 PassThruImpl *This = impl_from_IUnknown_inner(iface);
72 TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
74 if (This->bAggregatable)
75 This->bUnkOuterValid = TRUE;
77 if (IsEqualGUID(&IID_IUnknown, riid))
79 *ppvObj = &(This->IUnknown_inner);
80 TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
81 } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) {
82 *ppvObj = &(This->ISeekingPassThru_iface);
83 TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj);
84 } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
85 *ppvObj = &(This->IMediaSeeking_iface);
86 TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj);
87 } else {
88 *ppvObj = NULL;
89 FIXME("unknown interface %s\n", debugstr_guid(riid));
90 return E_NOINTERFACE;
93 IUnknown_AddRef((IUnknown *)(*ppvObj));
94 return S_OK;
97 static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) {
98 PassThruImpl *This = impl_from_IUnknown_inner(iface);
99 ULONG ref = InterlockedIncrement(&This->ref);
101 TRACE("(%p)->(): new ref = %d\n", This, ref);
103 return ref;
106 static ULONG WINAPI SeekInner_Release(IUnknown * iface) {
107 PassThruImpl *This = impl_from_IUnknown_inner(iface);
108 ULONG ref = InterlockedDecrement(&This->ref);
110 TRACE("(%p)->(): new ref = %d\n", This, ref);
112 if (ref == 0)
114 This->time_cs.DebugInfo->Spare[0] = 0;
115 DeleteCriticalSection(&This->time_cs);
116 CoTaskMemFree(This);
118 return ref;
121 static const IUnknownVtbl IInner_VTable =
123 SeekInner_QueryInterface,
124 SeekInner_AddRef,
125 SeekInner_Release
128 /* Generic functions for aggregation */
129 static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv)
131 if (This->bAggregatable)
132 This->bUnkOuterValid = TRUE;
134 if (This->outer_unk)
136 if (This->bAggregatable)
137 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
139 if (IsEqualIID(riid, &IID_IUnknown))
141 HRESULT hr;
143 IUnknown_AddRef((IUnknown *)&(This->IUnknown_inner));
144 hr = IUnknown_QueryInterface((IUnknown *)&(This->IUnknown_inner), riid, ppv);
145 IUnknown_Release((IUnknown *)&(This->IUnknown_inner));
146 This->bAggregatable = TRUE;
147 return hr;
150 *ppv = NULL;
151 return E_NOINTERFACE;
154 return IUnknown_QueryInterface((IUnknown *)&(This->IUnknown_inner), riid, ppv);
157 static ULONG SeekOuter_AddRef(PassThruImpl *This)
159 if (This->outer_unk && This->bUnkOuterValid)
160 return IUnknown_AddRef(This->outer_unk);
161 return IUnknown_AddRef((IUnknown *)&(This->IUnknown_inner));
164 static ULONG SeekOuter_Release(PassThruImpl *This)
166 if (This->outer_unk && This->bUnkOuterValid)
167 return IUnknown_Release(This->outer_unk);
168 return IUnknown_Release((IUnknown *)&(This->IUnknown_inner));
171 static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj)
173 PassThruImpl *This = impl_from_ISeekingPassThru(iface);
175 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
177 return SeekOuter_QueryInterface(This, riid, ppvObj);
180 static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface)
182 PassThruImpl *This = impl_from_ISeekingPassThru(iface);
184 TRACE("(%p/%p)->()\n", This, iface);
186 return SeekOuter_AddRef(This);
189 static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface)
191 PassThruImpl *This = impl_from_ISeekingPassThru(iface);
193 TRACE("(%p/%p)->()\n", This, iface);
195 return SeekOuter_Release(This);
198 static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin)
200 PassThruImpl *This = impl_from_ISeekingPassThru(iface);
202 TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin);
204 if (This->pin)
205 FIXME("Re-initializing?\n");
207 This->renderer = renderer;
208 This->pin = pin;
210 return S_OK;
213 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
215 SeekingPassThru_QueryInterface,
216 SeekingPassThru_AddRef,
217 SeekingPassThru_Release,
218 SeekingPassThru_Init
221 HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru)
223 HRESULT hr;
224 ISeekingPassThru *passthru;
226 hr = CoCreateInstance(&CLSID_SeekingPassThru, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppPassThru);
228 IUnknown_QueryInterface(*ppPassThru, &IID_ISeekingPassThru, (void**)&passthru);
229 hr = ISeekingPassThru_Init(passthru, bRenderer, pPin);
230 ISeekingPassThru_Release(passthru);
232 return hr;
235 HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru)
237 PassThruImpl *fimpl;
239 TRACE("(%p,%p)\n", pUnkOuter, ppPassThru);
241 *ppPassThru = fimpl = CoTaskMemAlloc(sizeof(*fimpl));
242 if (!fimpl)
243 return E_OUTOFMEMORY;
245 fimpl->outer_unk = pUnkOuter;
246 fimpl->bUnkOuterValid = FALSE;
247 fimpl->bAggregatable = FALSE;
248 fimpl->IUnknown_inner.lpVtbl = &IInner_VTable;
249 fimpl->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl;
250 fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl;
251 fimpl->ref = 1;
252 fimpl->pin = NULL;
253 fimpl->timevalid = 0;
254 InitializeCriticalSection(&fimpl->time_cs);
255 fimpl->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs");
256 return S_OK;
259 static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj)
261 PassThruImpl *This = impl_from_IMediaSeeking(iface);
263 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
265 return SeekOuter_QueryInterface(This, riid, ppvObj);
268 static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface)
270 PassThruImpl *This = impl_from_IMediaSeeking(iface);
272 TRACE("(%p/%p)->()\n", iface, This);
274 return SeekOuter_AddRef(This);
277 static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface)
279 PassThruImpl *This = impl_from_IMediaSeeking(iface);
281 TRACE("(%p/%p)->()\n", iface, This);
283 return SeekOuter_Release(This);
286 static HRESULT get_connected(PassThruImpl *This, IMediaSeeking **seek) {
287 HRESULT hr;
288 IPin *pin;
289 *seek = NULL;
290 hr = IPin_ConnectedTo(This->pin, &pin);
291 if (FAILED(hr))
292 return VFW_E_NOT_CONNECTED;
293 hr = IPin_QueryInterface(pin, &IID_IMediaSeeking, (void**)seek);
294 IPin_Release(pin);
295 if (FAILED(hr))
296 hr = E_NOTIMPL;
297 return hr;
300 static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
302 PassThruImpl *This = impl_from_IMediaSeeking(iface);
303 IMediaSeeking *seek;
304 HRESULT hr;
305 TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
306 hr = get_connected(This, &seek);
307 if (SUCCEEDED(hr)) {
308 hr = IMediaSeeking_GetCapabilities(seek, pCapabilities);
309 IMediaSeeking_Release(seek);
311 else
312 return E_NOTIMPL;
313 return hr;
316 static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
318 PassThruImpl *This = impl_from_IMediaSeeking(iface);
319 IMediaSeeking *seek;
320 HRESULT hr;
321 TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
322 hr = get_connected(This, &seek);
323 if (SUCCEEDED(hr)) {
324 hr = IMediaSeeking_CheckCapabilities(seek, pCapabilities);
325 IMediaSeeking_Release(seek);
327 else
328 return E_NOTIMPL;
329 return hr;
332 static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
334 PassThruImpl *This = impl_from_IMediaSeeking(iface);
335 IMediaSeeking *seek;
336 HRESULT hr;
337 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
338 hr = get_connected(This, &seek);
339 if (SUCCEEDED(hr)) {
340 hr = IMediaSeeking_IsFormatSupported(seek, pFormat);
341 IMediaSeeking_Release(seek);
343 else
344 return E_NOTIMPL;
345 return hr;
348 static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
350 PassThruImpl *This = impl_from_IMediaSeeking(iface);
351 IMediaSeeking *seek;
352 HRESULT hr;
353 TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
354 hr = get_connected(This, &seek);
355 if (SUCCEEDED(hr)) {
356 hr = IMediaSeeking_QueryPreferredFormat(seek, pFormat);
357 IMediaSeeking_Release(seek);
359 else
360 return E_NOTIMPL;
361 return hr;
364 static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
366 PassThruImpl *This = impl_from_IMediaSeeking(iface);
367 IMediaSeeking *seek;
368 HRESULT hr;
369 TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
370 hr = get_connected(This, &seek);
371 if (SUCCEEDED(hr)) {
372 hr = IMediaSeeking_GetTimeFormat(seek, pFormat);
373 IMediaSeeking_Release(seek);
375 else
376 return E_NOTIMPL;
377 return hr;
380 static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
382 PassThruImpl *This = impl_from_IMediaSeeking(iface);
383 IMediaSeeking *seek;
384 HRESULT hr;
385 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
386 hr = get_connected(This, &seek);
387 if (SUCCEEDED(hr)) {
388 hr = IMediaSeeking_IsUsingTimeFormat(seek, pFormat);
389 IMediaSeeking_Release(seek);
391 else
392 return E_NOTIMPL;
393 return hr;
396 static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
398 PassThruImpl *This = impl_from_IMediaSeeking(iface);
399 IMediaSeeking *seek;
400 HRESULT hr;
401 TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
402 hr = get_connected(This, &seek);
403 if (SUCCEEDED(hr)) {
404 hr = IMediaSeeking_SetTimeFormat(seek, pFormat);
405 IMediaSeeking_Release(seek);
407 else
408 return E_NOTIMPL;
409 return hr;
412 static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
414 PassThruImpl *This = impl_from_IMediaSeeking(iface);
415 IMediaSeeking *seek;
416 HRESULT hr;
417 TRACE("(%p/%p)->(%p)\n", iface, This, pDuration);
418 hr = get_connected(This, &seek);
419 if (SUCCEEDED(hr)) {
420 hr = IMediaSeeking_GetDuration(seek, pDuration);
421 IMediaSeeking_Release(seek);
423 else
424 return E_NOTIMPL;
425 return hr;
428 static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
430 PassThruImpl *This = impl_from_IMediaSeeking(iface);
431 IMediaSeeking *seek;
432 HRESULT hr;
433 TRACE("(%p/%p)->(%p)\n", iface, This, pStop);
434 hr = get_connected(This, &seek);
435 if (SUCCEEDED(hr)) {
436 hr = IMediaSeeking_GetStopPosition(seek, pStop);
437 IMediaSeeking_Release(seek);
439 else
440 return E_NOTIMPL;
441 return hr;
444 static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
446 PassThruImpl *This = impl_from_IMediaSeeking(iface);
447 IMediaSeeking *seek;
448 HRESULT hr = S_OK;
449 TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent);
450 if (!pCurrent)
451 return E_POINTER;
452 EnterCriticalSection(&This->time_cs);
453 if (This->timevalid)
454 *pCurrent = This->time_earliest;
455 else
456 hr = E_FAIL;
457 LeaveCriticalSection(&This->time_cs);
458 if (SUCCEEDED(hr)) {
459 hr = IMediaSeeking_ConvertTimeFormat(iface, pCurrent, NULL, *pCurrent, &TIME_FORMAT_MEDIA_TIME);
460 return hr;
462 hr = get_connected(This, &seek);
463 if (SUCCEEDED(hr)) {
464 hr = IMediaSeeking_GetCurrentPosition(seek, pCurrent);
465 IMediaSeeking_Release(seek);
467 else
468 return E_NOTIMPL;
469 return hr;
472 static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
474 PassThruImpl *This = impl_from_IMediaSeeking(iface);
475 IMediaSeeking *seek;
476 HRESULT hr;
477 TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat));
478 hr = get_connected(This, &seek);
479 if (SUCCEEDED(hr)) {
480 hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat);
481 IMediaSeeking_Release(seek);
483 else
484 return E_NOTIMPL;
485 return hr;
488 static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
490 PassThruImpl *This = impl_from_IMediaSeeking(iface);
491 IMediaSeeking *seek;
492 HRESULT hr;
493 TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface, This, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
494 hr = get_connected(This, &seek);
495 if (SUCCEEDED(hr)) {
496 hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
497 IMediaSeeking_Release(seek);
498 } else if (hr == VFW_E_NOT_CONNECTED)
499 hr = S_OK;
500 return hr;
503 static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
505 PassThruImpl *This = impl_from_IMediaSeeking(iface);
506 IMediaSeeking *seek;
507 HRESULT hr;
508 TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
509 hr = get_connected(This, &seek);
510 if (SUCCEEDED(hr)) {
511 hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop);
512 IMediaSeeking_Release(seek);
514 else
515 return E_NOTIMPL;
516 return hr;
519 static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
521 PassThruImpl *This = impl_from_IMediaSeeking(iface);
522 IMediaSeeking *seek;
523 HRESULT hr;
524 TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
525 hr = get_connected(This, &seek);
526 if (SUCCEEDED(hr)) {
527 hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest);
528 IMediaSeeking_Release(seek);
530 else
531 return E_NOTIMPL;
532 return hr;
535 static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
537 PassThruImpl *This = impl_from_IMediaSeeking(iface);
538 IMediaSeeking *seek;
539 HRESULT hr;
540 TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
541 hr = get_connected(This, &seek);
542 if (SUCCEEDED(hr)) {
543 hr = IMediaSeeking_SetRate(seek, dRate);
544 IMediaSeeking_Release(seek);
546 else
547 return E_NOTIMPL;
548 return hr;
551 static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
553 PassThruImpl *This = impl_from_IMediaSeeking(iface);
554 IMediaSeeking *seek;
555 HRESULT hr;
556 TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
557 hr = get_connected(This, &seek);
558 if (SUCCEEDED(hr)) {
559 hr = IMediaSeeking_GetRate(seek, dRate);
560 IMediaSeeking_Release(seek);
562 else
563 return E_NOTIMPL;
564 return hr;
567 static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
569 PassThruImpl *This = impl_from_IMediaSeeking(iface);
570 IMediaSeeking *seek;
571 HRESULT hr;
572 TRACE("(%p)\n", pPreroll);
573 hr = get_connected(This, &seek);
574 if (SUCCEEDED(hr)) {
575 hr = IMediaSeeking_GetPreroll(seek, pPreroll);
576 IMediaSeeking_Release(seek);
578 else
579 return E_NOTIMPL;
580 return hr;
583 HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start)
585 PassThruImpl *This = impl_from_IUnknown_inner(iface);
586 EnterCriticalSection(&This->time_cs);
587 This->time_earliest = start;
588 This->timevalid = 1;
589 LeaveCriticalSection(&This->time_cs);
590 return S_OK;
593 HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface)
595 PassThruImpl *This = impl_from_IUnknown_inner(iface);
596 EnterCriticalSection(&This->time_cs);
597 This->timevalid = 0;
598 LeaveCriticalSection(&This->time_cs);
599 return S_OK;
602 HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface)
604 PassThruImpl *This = impl_from_IUnknown_inner(iface);
605 REFERENCE_TIME time;
606 HRESULT hr;
607 hr = IMediaSeeking_GetStopPosition(&This->IMediaSeeking_iface, &time);
608 EnterCriticalSection(&This->time_cs);
609 if (SUCCEEDED(hr)) {
610 This->timevalid = 1;
611 This->time_earliest = time;
612 } else
613 This->timevalid = 0;
614 LeaveCriticalSection(&This->time_cs);
615 return hr;
618 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
620 MediaSeekingPassThru_QueryInterface,
621 MediaSeekingPassThru_AddRef,
622 MediaSeekingPassThru_Release,
623 MediaSeekingPassThru_GetCapabilities,
624 MediaSeekingPassThru_CheckCapabilities,
625 MediaSeekingPassThru_IsFormatSupported,
626 MediaSeekingPassThru_QueryPreferredFormat,
627 MediaSeekingPassThru_GetTimeFormat,
628 MediaSeekingPassThru_IsUsingTimeFormat,
629 MediaSeekingPassThru_SetTimeFormat,
630 MediaSeekingPassThru_GetDuration,
631 MediaSeekingPassThru_GetStopPosition,
632 MediaSeekingPassThru_GetCurrentPosition,
633 MediaSeekingPassThru_ConvertTimeFormat,
634 MediaSeekingPassThru_SetPositions,
635 MediaSeekingPassThru_GetPositions,
636 MediaSeekingPassThru_GetAvailable,
637 MediaSeekingPassThru_SetRate,
638 MediaSeekingPassThru_GetRate,
639 MediaSeekingPassThru_GetPreroll