/*
 * Filter Seeking and Control Interfaces
 *
 * Copyright 2003 Robert Shearman
 * Copyright 2012 Aric Stewart, CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
/* FIXME: critical sections */

#define COBJMACROS

#include "dshow.h"
#include "uuids.h"

#include "wine/debug.h"
#include "wine/strmbase.h"

#include <assert.h>

WINE_DEFAULT_DEBUG_CHANNEL(strmbase);

#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))

static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl;

typedef struct PassThruImpl {
    const ISeekingPassThruVtbl *IPassThru_vtbl;
    const IUnknownVtbl *IInner_vtbl;
    const IMediaSeekingVtbl *IMediaSeeking_vtbl;

    LONG ref;
    IUnknown * pUnkOuter;
    IPin * pin;
    BOOL bUnkOuterValid;
    BOOL bAggregatable;
    BOOL renderer;
    CRITICAL_SECTION time_cs;
    BOOL timevalid;
    REFERENCE_TIME time_earliest;
} PassThruImpl;

static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface,
					  REFIID riid,
					  LPVOID *ppvObj) {
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);

    if (This->bAggregatable)
        This->bUnkOuterValid = TRUE;

    if (IsEqualGUID(&IID_IUnknown, riid))
    {
        *ppvObj = &(This->IInner_vtbl);
        TRACE("   returning IUnknown interface (%p)\n", *ppvObj);
    } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) {
        *ppvObj = &(This->IPassThru_vtbl);
        TRACE("   returning ISeekingPassThru interface (%p)\n", *ppvObj);
    } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
        *ppvObj = &(This->IMediaSeeking_vtbl);
        TRACE("   returning IMediaSeeking interface (%p)\n", *ppvObj);
    } else {
        *ppvObj = NULL;
        FIXME("unknown interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown *)(*ppvObj));
    return S_OK;
}

static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) {
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(): new ref = %d\n", This, ref);

    return ref;
}

static ULONG WINAPI SeekInner_Release(IUnknown * iface) {
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(): new ref = %d\n", This, ref);

    if (ref == 0)
    {
        This->time_cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->time_cs);
        CoTaskMemFree(This);
    }
    return ref;
}

static const IUnknownVtbl IInner_VTable =
{
    SeekInner_QueryInterface,
    SeekInner_AddRef,
    SeekInner_Release
};

/* Generic functions for aggregation */
static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv)
{
    if (This->bAggregatable)
        This->bUnkOuterValid = TRUE;

    if (This->pUnkOuter)
    {
        if (This->bAggregatable)
            return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);

        if (IsEqualIID(riid, &IID_IUnknown))
        {
            HRESULT hr;

            IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
            hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
            IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
            This->bAggregatable = TRUE;
            return hr;
        }

        *ppv = NULL;
        return E_NOINTERFACE;
    }

    return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
}

static ULONG SeekOuter_AddRef(PassThruImpl *This)
{
    if (This->pUnkOuter && This->bUnkOuterValid)
        return IUnknown_AddRef(This->pUnkOuter);
    return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
}

static ULONG SeekOuter_Release(PassThruImpl *This)
{
    if (This->pUnkOuter && This->bUnkOuterValid)
        return IUnknown_Release(This->pUnkOuter);
    return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
}

static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj)
{
    ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);

    TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);

    return SeekOuter_QueryInterface(This, riid, ppvObj);
}

static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);

    TRACE("(%p/%p)->()\n", This, iface);

    return SeekOuter_AddRef(This);
}

static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);

    TRACE("(%p/%p)->()\n", This, iface);

    return SeekOuter_Release(This);
}

static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin)
{
    ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);

    TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin);

    if (This->pin)
        FIXME("Re-initializing?\n");

    This->renderer = renderer;
    This->pin = pin;

    return S_OK;
}

static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
{
    SeekingPassThru_QueryInterface,
    SeekingPassThru_AddRef,
    SeekingPassThru_Release,
    SeekingPassThru_Init
};

HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru)
{
    HRESULT hr;
    ISeekingPassThru *passthru;

    hr = CoCreateInstance(&CLSID_SeekingPassThru, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppPassThru);

    IUnknown_QueryInterface(*ppPassThru, &IID_ISeekingPassThru, (void**)&passthru);
    hr = ISeekingPassThru_Init(passthru, bRenderer, pPin);
    ISeekingPassThru_Release(passthru);

    return hr;
}

HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru)
{
    PassThruImpl *fimpl;

    TRACE("(%p,%p)\n", pUnkOuter, ppPassThru);

    *ppPassThru = fimpl = CoTaskMemAlloc(sizeof(*fimpl));
    if (!fimpl)
        return E_OUTOFMEMORY;

    fimpl->pUnkOuter = pUnkOuter;
    fimpl->bUnkOuterValid = FALSE;
    fimpl->bAggregatable = FALSE;
    fimpl->IInner_vtbl = &IInner_VTable;
    fimpl->IPassThru_vtbl = &ISeekingPassThru_Vtbl;
    fimpl->IMediaSeeking_vtbl = &IMediaSeekingPassThru_Vtbl;
    fimpl->ref = 1;
    fimpl->pin = NULL;
    fimpl->timevalid = 0;
    InitializeCriticalSection(&fimpl->time_cs);
    fimpl->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs");
    return S_OK;
}

static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);

    TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);

    return SeekOuter_QueryInterface(This, riid, ppvObj);
}

static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);

    TRACE("(%p/%p)->()\n", iface, This);

    return SeekOuter_AddRef(This);
}

static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);

    TRACE("(%p/%p)->()\n", iface, This);

    return SeekOuter_Release(This);
}

static HRESULT get_connected(PassThruImpl *This, IMediaSeeking **seek) {
    HRESULT hr;
    IPin *pin;
    *seek = NULL;
    hr = IPin_ConnectedTo(This->pin, &pin);
    if (FAILED(hr))
        return VFW_E_NOT_CONNECTED;
    hr = IPin_QueryInterface(pin, &IID_IMediaSeeking, (void**)seek);
    IPin_Release(pin);
    if (FAILED(hr))
        hr = E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetCapabilities(seek, pCapabilities);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_CheckCapabilities(seek, pCapabilities);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_IsFormatSupported(seek, pFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_QueryPreferredFormat(seek, pFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetTimeFormat(seek, pFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_IsUsingTimeFormat(seek, pFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat));
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_SetTimeFormat(seek, pFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pDuration);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetDuration(seek, pDuration);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, pStop);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetStopPosition(seek, pStop);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr = S_OK;
    TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent);
    if (!pCurrent)
        return E_POINTER;
    EnterCriticalSection(&This->time_cs);
    if (This->timevalid)
        *pCurrent = This->time_earliest;
    else
        hr = E_FAIL;
    LeaveCriticalSection(&This->time_cs);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_ConvertTimeFormat(iface, pCurrent, NULL, *pCurrent, &TIME_FORMAT_MEDIA_TIME);
        return hr;
    }
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetCurrentPosition(seek, pCurrent);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat));
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface, This, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
        IMediaSeeking_Release(seek);
    } else if (hr == VFW_E_NOT_CONNECTED)
        hr = S_OK;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_SetRate(seek, dRate);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetRate(seek, dRate);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
{
    ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
    IMediaSeeking *seek;
    HRESULT hr;
    TRACE("(%p)\n", pPreroll);
    hr = get_connected(This, &seek);
    if (SUCCEEDED(hr)) {
        hr = IMediaSeeking_GetPreroll(seek, pPreroll);
        IMediaSeeking_Release(seek);
    }
    else
        return E_NOTIMPL;
    return hr;
}

HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start)
{
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    EnterCriticalSection(&This->time_cs);
    This->time_earliest = start;
    This->timevalid = 1;
    LeaveCriticalSection(&This->time_cs);
    return S_OK;
}

HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    EnterCriticalSection(&This->time_cs);
    This->timevalid = 0;
    LeaveCriticalSection(&This->time_cs);
    return S_OK;
}

HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface)
{
    ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
    REFERENCE_TIME time;
    HRESULT hr;
    hr = IMediaSeeking_GetStopPosition((IMediaSeeking*)&This->IMediaSeeking_vtbl, &time);
    EnterCriticalSection(&This->time_cs);
    if (SUCCEEDED(hr)) {
        This->timevalid = 1;
        This->time_earliest = time;
    } else
        This->timevalid = 0;
    LeaveCriticalSection(&This->time_cs);
    return hr;
}

static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
{
    MediaSeekingPassThru_QueryInterface,
    MediaSeekingPassThru_AddRef,
    MediaSeekingPassThru_Release,
    MediaSeekingPassThru_GetCapabilities,
    MediaSeekingPassThru_CheckCapabilities,
    MediaSeekingPassThru_IsFormatSupported,
    MediaSeekingPassThru_QueryPreferredFormat,
    MediaSeekingPassThru_GetTimeFormat,
    MediaSeekingPassThru_IsUsingTimeFormat,
    MediaSeekingPassThru_SetTimeFormat,
    MediaSeekingPassThru_GetDuration,
    MediaSeekingPassThru_GetStopPosition,
    MediaSeekingPassThru_GetCurrentPosition,
    MediaSeekingPassThru_ConvertTimeFormat,
    MediaSeekingPassThru_SetPositions,
    MediaSeekingPassThru_GetPositions,
    MediaSeekingPassThru_GetAvailable,
    MediaSeekingPassThru_SetRate,
    MediaSeekingPassThru_GetRate,
    MediaSeekingPassThru_GetPreroll
};
