/*              DirectShow Sample Grabber object (QEDIT.DLL)
 *
 * Copyright 2009 Paul Chitescu
 *
 * 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
 */

#include <assert.h>
#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(qedit);

static const WCHAR vendor_name[] = { 'W', 'i', 'n', 'e', 0 };
static const WCHAR pin_in_name[] = { 'I', 'n', 0 };
static const WCHAR pin_out_name[] = { 'O', 'u', 't', 0 };

static IEnumMediaTypes *mediaenum_create(const AM_MEDIA_TYPE *mtype, BOOL past);

/* Single media type enumerator */
typedef struct _ME_Impl {
    IEnumMediaTypes IEnumMediaTypes_iface;
    LONG refCount;
    BOOL past;
    AM_MEDIA_TYPE mtype;
} ME_Impl;


/* IEnumMediaTypes interface implementation */

static inline ME_Impl *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
{
    return CONTAINING_RECORD(iface, ME_Impl, IEnumMediaTypes_iface);
}

static HRESULT WINAPI Single_IEnumMediaTypes_QueryInterface(IEnumMediaTypes *iface, REFIID riid,
        void **ret_iface)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);

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

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumMediaTypes)) {
        *ret_iface = iface;
        IEnumMediaTypes_AddRef(iface);
        return S_OK;
    }
    *ret_iface = NULL;
    WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ret_iface);
    return E_NOINTERFACE;
}

static ULONG WINAPI Single_IEnumMediaTypes_AddRef(IEnumMediaTypes *iface)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);
    ULONG refCount = InterlockedIncrement(&This->refCount);

    TRACE("(%p) new ref = %u\n", This, refCount);
    return refCount;
}

static ULONG WINAPI Single_IEnumMediaTypes_Release(IEnumMediaTypes *iface)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);
    ULONG refCount = InterlockedDecrement(&This->refCount);

    TRACE("(%p) new ref = %u\n", This, refCount);
    if (refCount == 0)
    {
        CoTaskMemFree(This->mtype.pbFormat);
        CoTaskMemFree(This);
    }
    return refCount;
}

/* IEnumMediaTypes */
static HRESULT WINAPI Single_IEnumMediaTypes_Next(IEnumMediaTypes *iface, ULONG nTypes,
        AM_MEDIA_TYPE **types, ULONG *fetched)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);
    ULONG count = 0;

    TRACE("(%p)->(%u, %p, %p)\n", This, nTypes, types, fetched);
    if (!nTypes)
        return E_INVALIDARG;
    if (!types || ((nTypes != 1) && !fetched))
        return E_POINTER;
    if (!This->past && !IsEqualGUID(&This->mtype.majortype,&GUID_NULL)) {
        AM_MEDIA_TYPE *mtype = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
        *mtype = This->mtype;
        if (mtype->cbFormat) {
            mtype->pbFormat = CoTaskMemAlloc(mtype->cbFormat);
            CopyMemory(mtype->pbFormat, This->mtype.pbFormat, mtype->cbFormat);
        }
        *types = mtype;
        This->past = TRUE;
        count = 1;
    }
    if (fetched)
        *fetched = count;
    return (count == nTypes) ? S_OK : S_FALSE;
}

static HRESULT WINAPI Single_IEnumMediaTypes_Skip(IEnumMediaTypes *iface, ULONG nTypes)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);

    TRACE("(%p)->(%u)\n", This, nTypes);
    if (nTypes)
        This->past = TRUE;
    return This->past ? S_FALSE : S_OK;
}

static HRESULT WINAPI Single_IEnumMediaTypes_Reset(IEnumMediaTypes *iface)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);

    TRACE("(%p)->()\n", This);
    This->past = FALSE;
    return S_OK;
}

static HRESULT WINAPI Single_IEnumMediaTypes_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **me)
{
    ME_Impl *This = impl_from_IEnumMediaTypes(iface);

    TRACE("(%p)->(%p)\n", This, me);
    if (!me)
        return E_POINTER;
    *me = mediaenum_create(&This->mtype, This->past);
    if (!*me)
        return E_OUTOFMEMORY;
    return S_OK;
}


/* Virtual tables and constructor */

static const IEnumMediaTypesVtbl IEnumMediaTypes_VTable =
{
    Single_IEnumMediaTypes_QueryInterface,
    Single_IEnumMediaTypes_AddRef,
    Single_IEnumMediaTypes_Release,
    Single_IEnumMediaTypes_Next,
    Single_IEnumMediaTypes_Skip,
    Single_IEnumMediaTypes_Reset,
    Single_IEnumMediaTypes_Clone,
};

static IEnumMediaTypes *mediaenum_create(const AM_MEDIA_TYPE *mtype, BOOL past)
{
    ME_Impl *obj = CoTaskMemAlloc(sizeof(ME_Impl));

    if (!obj)
        return NULL;
    ZeroMemory(obj, sizeof(*obj));
    obj->IEnumMediaTypes_iface.lpVtbl = &IEnumMediaTypes_VTable;
    obj->refCount = 1;
    obj->past = past;
    if (mtype) {
        obj->mtype = *mtype;
        obj->mtype.pUnk = NULL;
        if (mtype->cbFormat) {
            obj->mtype.pbFormat = CoTaskMemAlloc(mtype->cbFormat);
            CopyMemory(obj->mtype.pbFormat, mtype->pbFormat, mtype->cbFormat);
        }
        else
            obj->mtype.pbFormat = NULL;
    }
    else
        obj->mtype.majortype = GUID_NULL;

    return &obj->IEnumMediaTypes_iface;
}


/* Sample Grabber pin implementation */
typedef struct _SG_Pin {
    IPin IPin_iface;
    PIN_DIRECTION dir;
    WCHAR const *name;
    struct _SG_Impl *sg;
    IPin *pair;
} SG_Pin;

static inline SG_Pin *impl_from_IPin(IPin *iface)
{
    return CONTAINING_RECORD(iface, SG_Pin, IPin_iface);
}

/* Sample Grabber filter implementation */
typedef struct _SG_Impl {
    IUnknown IUnknown_inner;
    BaseFilter filter;
    ISampleGrabber ISampleGrabber_iface;
    /* IMediaSeeking and IMediaPosition are implemented by ISeekingPassThru */
    IUnknown* seekthru_unk;
    IUnknown *outer_unk;
    AM_MEDIA_TYPE mtype;
    SG_Pin pin_in;
    SG_Pin pin_out;
    IMemInputPin IMemInputPin_iface;
    IMemAllocator *allocator;
    IMemInputPin *memOutput;
    ISampleGrabberCB *grabberIface;
    LONG grabberMethod;
    LONG oneShot;
    LONG bufferLen;
    void* bufferData;
} SG_Impl;

enum {
    OneShot_None,
    OneShot_Wait,
    OneShot_Past,
};

static inline SG_Impl *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, SG_Impl, IUnknown_inner);
}

static inline SG_Impl *impl_from_BaseFilter(BaseFilter *iface)
{
    return CONTAINING_RECORD(iface, SG_Impl, filter);
}

static inline SG_Impl *impl_from_IBaseFilter(IBaseFilter *iface)
{
    return CONTAINING_RECORD(iface, SG_Impl, filter.IBaseFilter_iface);
}

static inline SG_Impl *impl_from_ISampleGrabber(ISampleGrabber *iface)
{
    return CONTAINING_RECORD(iface, SG_Impl, ISampleGrabber_iface);
}

static inline SG_Impl *impl_from_IMemInputPin(IMemInputPin *iface)
{
    return CONTAINING_RECORD(iface, SG_Impl, IMemInputPin_iface);
}


/* Cleanup at end of life */
static void SampleGrabber_cleanup(SG_Impl *This)
{
    TRACE("(%p)\n", This);
    if (This->filter.filterInfo.pGraph)
        WARN("(%p) still joined to filter graph %p\n", This, This->filter.filterInfo.pGraph);
    if (This->allocator)
        IMemAllocator_Release(This->allocator);
    if (This->memOutput)
        IMemInputPin_Release(This->memOutput);
    if (This->grabberIface)
        ISampleGrabberCB_Release(This->grabberIface);
    CoTaskMemFree(This->mtype.pbFormat);
    CoTaskMemFree(This->bufferData);
    if(This->seekthru_unk)
        IUnknown_Release(This->seekthru_unk);
}

/* SampleGrabber inner IUnknown */
static HRESULT WINAPI SampleGrabber_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    SG_Impl *This = impl_from_IUnknown(iface);

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

    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = &This->IUnknown_inner;
    else if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IMediaFilter) ||
        IsEqualIID(riid, &IID_IBaseFilter))
        *ppv = &This->filter.IBaseFilter_iface;
    else if (IsEqualIID(riid, &IID_ISampleGrabber))
        *ppv = &This->ISampleGrabber_iface;
    else if (IsEqualIID(riid, &IID_IMediaPosition))
        return IUnknown_QueryInterface(This->seekthru_unk, riid, ppv);
    else if (IsEqualIID(riid, &IID_IMediaSeeking))
        return IUnknown_QueryInterface(This->seekthru_unk, riid, ppv);
    else
        WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppv);

    if (!*ppv)
        return E_NOINTERFACE;

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

static ULONG WINAPI SampleGrabber_AddRef(IUnknown *iface)
{
    SG_Impl *This = impl_from_IUnknown(iface);
    ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI SampleGrabber_Release(IUnknown *iface)
{
    SG_Impl *This = impl_from_IUnknown(iface);
    ULONG ref = BaseFilterImpl_Release(&This->filter.IBaseFilter_iface);

    TRACE("(%p) ref=%d\n", This, ref);

    if (ref == 0)
    {
        SampleGrabber_cleanup(This);
        CoTaskMemFree(This);
    }
    return ref;
}

static const IUnknownVtbl samplegrabber_vtbl =
{
    SampleGrabber_QueryInterface,
    SampleGrabber_AddRef,
    SampleGrabber_Release,
};

static IPin *WINAPI SampleGrabber_GetPin(BaseFilter *iface, int pos)
{
    SG_Impl *This = impl_from_BaseFilter(iface);
    IPin *pin;

    if (pos == 0)
        pin = &This->pin_in.IPin_iface;
    else if (pos == 1)
        pin = &This->pin_out.IPin_iface;
    else
        return NULL;

    IPin_AddRef(pin);
    return pin;
}

static LONG WINAPI SampleGrabber_GetPinCount(BaseFilter *iface)
{
    return 2;
}

static const BaseFilterFuncTable basefunc_vtbl = {
    SampleGrabber_GetPin,
    SampleGrabber_GetPinCount
};

/* Helper that buffers data and/or calls installed sample callbacks */
static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample)
{
    double time = 0.0;
    REFERENCE_TIME tStart, tEnd;
    if (This->bufferLen >= 0) {
        BYTE *data = 0;
        LONG size = IMediaSample_GetActualDataLength(sample);
        if (size >= 0 && SUCCEEDED(IMediaSample_GetPointer(sample, &data))) {
            if (!data)
                size = 0;
            EnterCriticalSection(&This->filter.csFilter);
            if (This->bufferLen != size) {
                CoTaskMemFree(This->bufferData);
                This->bufferData = size ? CoTaskMemAlloc(size) : NULL;
                This->bufferLen = size;
            }
            if (size)
                CopyMemory(This->bufferData, data, size);
            LeaveCriticalSection(&This->filter.csFilter);
        }
    }
    if (!This->grabberIface)
        return;
    if (SUCCEEDED(IMediaSample_GetTime(sample, &tStart, &tEnd)))
        time = 1e-7 * tStart;
    switch (This->grabberMethod) {
        case 0:
	    {
		ULONG ref = IMediaSample_AddRef(sample);
		ISampleGrabberCB_SampleCB(This->grabberIface, time, sample);
		ref = IMediaSample_Release(sample) + 1 - ref;
		if (ref)
		{
		    ERR("(%p) Callback referenced sample %p by %u\n", This, sample, ref);
		    /* ugly as hell but some apps are sooo buggy */
		    while (ref--)
			IMediaSample_Release(sample);
		}
	    }
            break;
        case 1:
            {
                BYTE *data = 0;
                LONG size = IMediaSample_GetActualDataLength(sample);
                if (size && SUCCEEDED(IMediaSample_GetPointer(sample, &data)) && data)
                    ISampleGrabberCB_BufferCB(This->grabberIface, time, data, size);
            }
            break;
        case -1:
            break;
        default:
            FIXME("unsupported method %d\n", This->grabberMethod);
            /* do not bother us again */
            This->grabberMethod = -1;
    }
}


/* SampleGrabber implementation of IBaseFilter interface */

/* IUnknown */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IBaseFilter_AddRef(IBaseFilter *iface)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    return IUnknown_AddRef(This->outer_unk);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IBaseFilter_Release(IBaseFilter *iface)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    return IUnknown_Release(This->outer_unk);
}

/* IMediaFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_Stop(IBaseFilter *iface)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    TRACE("(%p)\n", This);
    This->filter.state = State_Stopped;
    return S_OK;
}

/* IMediaFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_Pause(IBaseFilter *iface)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    TRACE("(%p)\n", This);
    This->filter.state = State_Paused;
    return S_OK;
}

/* IMediaFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    TRACE("(%p)\n", This);
    This->filter.state = State_Running;
    return S_OK;
}

/* IBaseFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_FindPin(IBaseFilter *iface, LPCWSTR id, IPin **pin)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_w(id), pin);
    if (!id || !pin)
        return E_POINTER;
    if (!lstrcmpiW(id,pin_in_name))
    {
        *pin = &This->pin_in.IPin_iface;
        IPin_AddRef(*pin);
        return S_OK;
    }
    else if (!lstrcmpiW(id,pin_out_name))
    {
        *pin = &This->pin_out.IPin_iface;
        IPin_AddRef(*pin);
        return S_OK;
    }
    *pin = NULL;
    return VFW_E_NOT_FOUND;
}

/* IBaseFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *graph, LPCWSTR name)
{
    SG_Impl *This = impl_from_IBaseFilter(iface);

    TRACE("(%p)->(%p, %s)\n", This, graph, debugstr_w(name));

    BaseFilterImpl_JoinFilterGraph(iface, graph, name);
    This->oneShot = OneShot_None;

    return S_OK;
}

/* IBaseFilter */
static HRESULT WINAPI
SampleGrabber_IBaseFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR *vendor)
{
    TRACE("(%p)\n", vendor);
    if (!vendor)
        return E_POINTER;
    *vendor = CoTaskMemAlloc(sizeof(vendor_name));
    CopyMemory(*vendor, vendor_name, sizeof(vendor_name));
    return S_OK;
}


/* SampleGrabber implementation of ISampleGrabber interface */

/* IUnknown */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber *iface, REFIID riid, void **ppv)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber *iface)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    return IUnknown_AddRef(This->outer_unk);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_ISampleGrabber_Release(ISampleGrabber *iface)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    return IUnknown_Release(This->outer_unk);
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_SetOneShot(ISampleGrabber *iface, BOOL oneShot)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    TRACE("(%p)->(%u)\n", This, oneShot);
    This->oneShot = oneShot ? OneShot_Wait : OneShot_None;
    return S_OK;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_SetMediaType(ISampleGrabber *iface, const AM_MEDIA_TYPE *type)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    TRACE("(%p)->(%p)\n", This, type);
    if (!type)
        return E_POINTER;
    TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
	debugstr_guid(&type->majortype), debugstr_guid(&type->subtype),
	type->lSampleSize,
	debugstr_guid(&type->formattype), type->cbFormat);
    CoTaskMemFree(This->mtype.pbFormat);
    This->mtype = *type;
    This->mtype.pUnk = NULL;
    if (type->cbFormat) {
        This->mtype.pbFormat = CoTaskMemAlloc(type->cbFormat);
        CopyMemory(This->mtype.pbFormat, type->pbFormat, type->cbFormat);
    }
    else
        This->mtype.pbFormat = NULL;
    return S_OK;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_GetConnectedMediaType(ISampleGrabber *iface, AM_MEDIA_TYPE *type)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    TRACE("(%p)->(%p)\n", This, type);
    if (!type)
        return E_POINTER;
    if (!This->pin_in.pair)
        return VFW_E_NOT_CONNECTED;
    *type = This->mtype;
    if (type->cbFormat) {
        type->pbFormat = CoTaskMemAlloc(type->cbFormat);
        CopyMemory(type->pbFormat, This->mtype.pbFormat, type->cbFormat);
    }
    return S_OK;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_SetBufferSamples(ISampleGrabber *iface, BOOL bufferEm)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    TRACE("(%p)->(%u)\n", This, bufferEm);
    EnterCriticalSection(&This->filter.csFilter);
    if (bufferEm) {
        if (This->bufferLen < 0)
            This->bufferLen = 0;
    }
    else
        This->bufferLen = -1;
    LeaveCriticalSection(&This->filter.csFilter);
    return S_OK;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber *iface, LONG *bufSize, LONG *buffer)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    HRESULT ret = S_OK;
    TRACE("(%p)->(%p, %p)\n", This, bufSize, buffer);
    if (!bufSize)
        return E_POINTER;
    EnterCriticalSection(&This->filter.csFilter);
    if (!This->pin_in.pair)
        ret = VFW_E_NOT_CONNECTED;
    else if (This->bufferLen < 0)
        ret = E_INVALIDARG;
    else if (This->bufferLen == 0)
        ret = VFW_E_WRONG_STATE;
    else {
        if (buffer) {
            if (*bufSize >= This->bufferLen)
                CopyMemory(buffer, This->bufferData, This->bufferLen);
            else
                ret = E_OUTOFMEMORY;
        }
        *bufSize = This->bufferLen;
    }
    LeaveCriticalSection(&This->filter.csFilter);
    return ret;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber *iface, IMediaSample **sample)
{
    /* MS doesn't implement it either, no one should call it */
    WARN("(%p): not implemented\n", sample);
    return E_NOTIMPL;
}

/* ISampleGrabber */
static HRESULT WINAPI
SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber *iface, ISampleGrabberCB *cb, LONG whichMethod)
{
    SG_Impl *This = impl_from_ISampleGrabber(iface);
    TRACE("(%p)->(%p, %u)\n", This, cb, whichMethod);
    if (This->grabberIface)
        ISampleGrabberCB_Release(This->grabberIface);
    This->grabberIface = cb;
    This->grabberMethod = whichMethod;
    if (cb)
        ISampleGrabberCB_AddRef(cb);
    return S_OK;
}


/* SampleGrabber implementation of IMemInputPin interface */

/* IUnknown */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    return IUnknown_AddRef(This->outer_unk);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IMemInputPin_Release(IMemInputPin *iface)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    return IUnknown_Release(This->outer_unk);
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **allocator)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    TRACE("(%p)->(%p) allocator = %p\n", This, allocator, This->allocator);
    if (!allocator)
        return E_POINTER;
    *allocator = This->allocator;
    if (!*allocator)
        return VFW_E_NO_ALLOCATOR;
    IMemAllocator_AddRef(*allocator);
    return S_OK;
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_NotifyAllocator(IMemInputPin *iface, IMemAllocator *allocator, BOOL readOnly)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    TRACE("(%p)->(%p, %u) allocator = %p\n", This, allocator, readOnly, This->allocator);
    if (This->allocator == allocator)
        return S_OK;
    if (This->allocator)
        IMemAllocator_Release(This->allocator);
    This->allocator = allocator;
    if (allocator)
        IMemAllocator_AddRef(allocator);
    return S_OK;
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_GetAllocatorRequirements(IMemInputPin *iface, ALLOCATOR_PROPERTIES *props)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    FIXME("(%p)->(%p): semi-stub\n", This, props);
    if (!props)
        return E_POINTER;
    return This->memOutput ? IMemInputPin_GetAllocatorRequirements(This->memOutput, props) : E_NOTIMPL;
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_Receive(IMemInputPin *iface, IMediaSample *sample)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    HRESULT hr;
    TRACE("(%p)->(%p) output = %p, grabber = %p\n", This, sample, This->memOutput, This->grabberIface);
    if (!sample)
        return E_POINTER;
    if (This->oneShot == OneShot_Past)
        return S_FALSE;
    SampleGrabber_callback(This, sample);
    hr = This->memOutput ? IMemInputPin_Receive(This->memOutput, sample) : S_OK;
    if (This->oneShot == OneShot_Wait) {
        This->oneShot = OneShot_Past;
        hr = S_FALSE;
        if (This->pin_out.pair)
            IPin_EndOfStream(This->pin_out.pair);
    }
    return hr;
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_ReceiveMultiple(IMemInputPin *iface, IMediaSample **samples, LONG nSamples, LONG *nProcessed)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    LONG idx;
    TRACE("(%p)->(%p, %u, %p) output = %p, grabber = %p\n", This, samples, nSamples, nProcessed, This->memOutput, This->grabberIface);
    if (!samples || !nProcessed)
        return E_POINTER;
    if ((This->filter.state != State_Running) || (This->oneShot == OneShot_Past))
        return S_FALSE;
    for (idx = 0; idx < nSamples; idx++)
        SampleGrabber_callback(This, samples[idx]);
    return This->memOutput ? IMemInputPin_ReceiveMultiple(This->memOutput, samples, nSamples, nProcessed) : S_OK;
}

/* IMemInputPin */
static HRESULT WINAPI
SampleGrabber_IMemInputPin_ReceiveCanBlock(IMemInputPin *iface)
{
    SG_Impl *This = impl_from_IMemInputPin(iface);
    TRACE("(%p)\n", This);
    return This->memOutput ? IMemInputPin_ReceiveCanBlock(This->memOutput) : S_OK;
}


/* SampleGrabber member pin implementation */

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IPin_AddRef(IPin *iface)
{
    SG_Pin *This = impl_from_IPin(iface);
    return ISampleGrabber_AddRef(&This->sg->ISampleGrabber_iface);
}

/* IUnknown */
static ULONG WINAPI
SampleGrabber_IPin_Release(IPin *iface)
{
    SG_Pin *This = impl_from_IPin(iface);
    return ISampleGrabber_Release(&This->sg->ISampleGrabber_iface);
}

/* IUnknown */
static HRESULT WINAPI
SampleGrabber_IPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
{
    SG_Pin *This = impl_from_IPin(iface);
    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);

    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IMemInputPin))
        *ppv = &This->sg->IMemInputPin_iface;
    else if (IsEqualIID(riid, &IID_IMediaSeeking))
        return IUnknown_QueryInterface(&This->sg->IUnknown_inner, riid, ppv);
    else if (IsEqualIID(riid, &IID_IMediaPosition))
        return IUnknown_QueryInterface(&This->sg->IUnknown_inner, riid, ppv);
    else {
        WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppv);
        return E_NOINTERFACE;
    }

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

/* IPin - input pin */
static HRESULT WINAPI
SampleGrabber_In_IPin_Connect(IPin *iface, IPin *receiver, const AM_MEDIA_TYPE *mtype)
{
    WARN("(%p, %p): unexpected\n", receiver, mtype);
    return E_UNEXPECTED;
}

/* IPin - output pin */
static HRESULT WINAPI
SampleGrabber_Out_IPin_Connect(IPin *iface, IPin *receiver, const AM_MEDIA_TYPE *type)
{
    SG_Pin *This = impl_from_IPin(iface);
    HRESULT hr;

    TRACE("(%p)->(%p, %p)\n", This, receiver, type);
    if (!receiver)
        return E_POINTER;
    if (This->pair)
        return VFW_E_ALREADY_CONNECTED;
    if (This->sg->filter.state != State_Stopped)
        return VFW_E_NOT_STOPPED;
    if (type) {
	TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
	    debugstr_guid(&type->majortype), debugstr_guid(&type->subtype),
	    type->lSampleSize,
	    debugstr_guid(&type->formattype), type->cbFormat);
	if (!IsEqualGUID(&This->sg->mtype.majortype,&GUID_NULL) &&
	    !IsEqualGUID(&This->sg->mtype.majortype,&type->majortype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
	if (!IsEqualGUID(&This->sg->mtype.subtype,&MEDIASUBTYPE_None) &&
	    !IsEqualGUID(&This->sg->mtype.subtype,&type->subtype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
	if (!IsEqualGUID(&This->sg->mtype.formattype,&GUID_NULL) &&
	    !IsEqualGUID(&This->sg->mtype.formattype,&FORMAT_None) &&
	    !IsEqualGUID(&This->sg->mtype.formattype,&type->formattype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
    }
    else
	type = &This->sg->mtype;
    if (!IsEqualGUID(&type->formattype, &FORMAT_None) &&
	!IsEqualGUID(&type->formattype, &GUID_NULL) &&
	!type->pbFormat)
	return VFW_E_TYPE_NOT_ACCEPTED;
    hr = IPin_ReceiveConnection(receiver, &This->IPin_iface, type);
    if (FAILED(hr))
	return hr;
    This->pair = receiver;
    if (This->sg->memOutput) {
        IMemInputPin_Release(This->sg->memOutput);
        This->sg->memOutput = NULL;
    }
    IPin_QueryInterface(receiver,&IID_IMemInputPin,(void **)&(This->sg->memOutput));
    TRACE("(%p) Accepted IPin %p, IMemInputPin %p\n", This, receiver, This->sg->memOutput);
    return S_OK;
}

/* IPin - input pin */
static HRESULT WINAPI
SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *type)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p, %p)\n", This, connector, type);
    if (!connector)
        return E_POINTER;
    if (This->pair)
        return VFW_E_ALREADY_CONNECTED;
    if (This->sg->filter.state != State_Stopped)
        return VFW_E_NOT_STOPPED;
    if (type) {
	TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n",
	    debugstr_guid(&type->majortype), debugstr_guid(&type->subtype),
	    type->lSampleSize,
	    debugstr_guid(&type->formattype), type->cbFormat);
	if (!IsEqualGUID(&type->formattype, &FORMAT_None) &&
	    !IsEqualGUID(&type->formattype, &GUID_NULL) &&
	    !type->pbFormat)
	    return VFW_E_INVALIDMEDIATYPE;
	if (!IsEqualGUID(&This->sg->mtype.majortype,&GUID_NULL) &&
	    !IsEqualGUID(&This->sg->mtype.majortype,&type->majortype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
	if (!IsEqualGUID(&This->sg->mtype.subtype,&MEDIASUBTYPE_None) &&
	    !IsEqualGUID(&This->sg->mtype.subtype,&type->subtype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
	if (!IsEqualGUID(&This->sg->mtype.formattype,&GUID_NULL) &&
	    !IsEqualGUID(&This->sg->mtype.formattype,&FORMAT_None) &&
	    !IsEqualGUID(&This->sg->mtype.formattype,&type->formattype))
	    return VFW_E_TYPE_NOT_ACCEPTED;
        CoTaskMemFree(This->sg->mtype.pbFormat);
        This->sg->mtype = *type;
        This->sg->mtype.pUnk = NULL;
        if (type->cbFormat) {
            This->sg->mtype.pbFormat = CoTaskMemAlloc(type->cbFormat);
            CopyMemory(This->sg->mtype.pbFormat, type->pbFormat, type->cbFormat);
        }
        else
            This->sg->mtype.pbFormat = NULL;
    }
    This->pair = connector;
    TRACE("(%p) Accepted IPin %p\n", This, connector);
    return S_OK;
}

/* IPin - output pin */
static HRESULT WINAPI
SampleGrabber_Out_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *mtype)
{
    WARN("(%p, %p): unexpected\n", connector, mtype);
    return E_UNEXPECTED;
}

/* IPin - input pin */
static HRESULT WINAPI
SampleGrabber_In_IPin_Disconnect(IPin *iface)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->() pair = %p\n", This, This->pair);
    if (This->sg->filter.state != State_Stopped)
        return VFW_E_NOT_STOPPED;
    if (This->pair) {
        This->pair = NULL;
        return S_OK;
    }
    return S_FALSE;
}

/* IPin - output pin */
static HRESULT WINAPI
SampleGrabber_Out_IPin_Disconnect(IPin *iface)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->() pair = %p\n", This, This->pair);
    if (This->sg->filter.state != State_Stopped)
        return VFW_E_NOT_STOPPED;
    if (This->pair) {
        This->pair = NULL;
        if (This->sg->memOutput) {
            IMemInputPin_Release(This->sg->memOutput);
            This->sg->memOutput = NULL;
        }
        return S_OK;
    }
    return S_FALSE;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_ConnectedTo(IPin *iface, IPin **pin)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p) pair = %p\n", This, pin, This->pair);
    if (!pin)
        return E_POINTER;
    *pin = This->pair;
    if (*pin) {
        IPin_AddRef(*pin);
        return S_OK;
    }
    return VFW_E_NOT_CONNECTED;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mtype)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p)\n", This, mtype);
    if (!mtype)
        return E_POINTER;
    if (!This->pair)
        return VFW_E_NOT_CONNECTED;
    *mtype = This->sg->mtype;
    if (mtype->cbFormat) {
        mtype->pbFormat = CoTaskMemAlloc(mtype->cbFormat);
        CopyMemory(mtype->pbFormat, This->sg->mtype.pbFormat, mtype->cbFormat);
    }
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_QueryPinInfo(IPin *iface, PIN_INFO *info)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p)\n", This, info);
    if (!info)
        return E_POINTER;
    info->pFilter = &This->sg->filter.IBaseFilter_iface;
    IBaseFilter_AddRef(info->pFilter);
    info->dir = This->dir;
    lstrcpynW(info->achName,This->name,MAX_PIN_NAME);
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p)\n", This, dir);
    if (!dir)
        return E_POINTER;
    *dir = This->dir;
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_QueryId(IPin *iface, LPWSTR *id)
{
    SG_Pin *This = impl_from_IPin(iface);

    int len;
    TRACE("(%p)->(%p)\n", This, id);
    if (!id)
        return E_POINTER;
    len = sizeof(WCHAR)*(1+lstrlenW(This->name));
    *id = CoTaskMemAlloc(len);
    CopyMemory(*id, This->name, len);
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mtype)
{
    TRACE("(%p)\n", mtype);
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **mtypes)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p)\n", This, mtypes);
    if (!mtypes)
        return E_POINTER;
    *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : NULL, FALSE);
    return *mtypes ? S_OK : E_OUTOFMEMORY;
}

/* IPin - input pin */
static HRESULT WINAPI
SampleGrabber_In_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *nPins)
{
    SG_Pin *This = impl_from_IPin(iface);

    TRACE("(%p)->(%p, %p) size = %u\n", This, pins, nPins, (nPins ? *nPins : 0));
    if (!nPins)
        return E_POINTER;
    if (*nPins) {
	if (!pins)
	    return E_POINTER;
        IPin_AddRef(&This->sg->pin_out.IPin_iface);
        *pins = &This->sg->pin_out.IPin_iface;
	*nPins = 1;
	return S_OK;
    }
    *nPins = 1;
    return S_FALSE;
}

/* IPin - output pin */
static HRESULT WINAPI
SampleGrabber_Out_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *nPins)
{
    WARN("(%p, %p): unexpected\n", pins, nPins);
    if (nPins)
        *nPins = 0;
    return E_NOTIMPL;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_EndOfStream(IPin *iface)
{
    FIXME(": stub\n");
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_BeginFlush(IPin *iface)
{
    FIXME(": stub\n");
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_EndFlush(IPin *iface)
{
    FIXME(": stub\n");
    return S_OK;
}

/* IPin */
static HRESULT WINAPI
SampleGrabber_IPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double rate)
{
    FIXME(": stub\n");
    return S_OK;
}


/* SampleGrabber vtables and constructor */

static const IBaseFilterVtbl IBaseFilter_VTable =
{
    SampleGrabber_IBaseFilter_QueryInterface,
    SampleGrabber_IBaseFilter_AddRef,
    SampleGrabber_IBaseFilter_Release,
    BaseFilterImpl_GetClassID,
    SampleGrabber_IBaseFilter_Stop,
    SampleGrabber_IBaseFilter_Pause,
    SampleGrabber_IBaseFilter_Run,
    BaseFilterImpl_GetState,
    BaseFilterImpl_SetSyncSource,
    BaseFilterImpl_GetSyncSource,
    BaseFilterImpl_EnumPins,
    SampleGrabber_IBaseFilter_FindPin,
    BaseFilterImpl_QueryFilterInfo,
    SampleGrabber_IBaseFilter_JoinFilterGraph,
    SampleGrabber_IBaseFilter_QueryVendorInfo,
};

static const ISampleGrabberVtbl ISampleGrabber_VTable =
{
    SampleGrabber_ISampleGrabber_QueryInterface,
    SampleGrabber_ISampleGrabber_AddRef,
    SampleGrabber_ISampleGrabber_Release,
    SampleGrabber_ISampleGrabber_SetOneShot,
    SampleGrabber_ISampleGrabber_SetMediaType,
    SampleGrabber_ISampleGrabber_GetConnectedMediaType,
    SampleGrabber_ISampleGrabber_SetBufferSamples,
    SampleGrabber_ISampleGrabber_GetCurrentBuffer,
    SampleGrabber_ISampleGrabber_GetCurrentSample,
    SampleGrabber_ISampleGrabber_SetCallback,
};

static const IMemInputPinVtbl IMemInputPin_VTable =
{
    SampleGrabber_IMemInputPin_QueryInterface,
    SampleGrabber_IMemInputPin_AddRef,
    SampleGrabber_IMemInputPin_Release,
    SampleGrabber_IMemInputPin_GetAllocator,
    SampleGrabber_IMemInputPin_NotifyAllocator,
    SampleGrabber_IMemInputPin_GetAllocatorRequirements,
    SampleGrabber_IMemInputPin_Receive,
    SampleGrabber_IMemInputPin_ReceiveMultiple,
    SampleGrabber_IMemInputPin_ReceiveCanBlock,
};

static const IPinVtbl IPin_In_VTable =
{
    SampleGrabber_IPin_QueryInterface,
    SampleGrabber_IPin_AddRef,
    SampleGrabber_IPin_Release,
    SampleGrabber_In_IPin_Connect,
    SampleGrabber_In_IPin_ReceiveConnection,
    SampleGrabber_In_IPin_Disconnect,
    SampleGrabber_IPin_ConnectedTo,
    SampleGrabber_IPin_ConnectionMediaType,
    SampleGrabber_IPin_QueryPinInfo,
    SampleGrabber_IPin_QueryDirection,
    SampleGrabber_IPin_QueryId,
    SampleGrabber_IPin_QueryAccept,
    SampleGrabber_IPin_EnumMediaTypes,
    SampleGrabber_In_IPin_QueryInternalConnections,
    SampleGrabber_IPin_EndOfStream,
    SampleGrabber_IPin_BeginFlush,
    SampleGrabber_IPin_EndFlush,
    SampleGrabber_IPin_NewSegment,
};

static const IPinVtbl IPin_Out_VTable =
{
    SampleGrabber_IPin_QueryInterface,
    SampleGrabber_IPin_AddRef,
    SampleGrabber_IPin_Release,
    SampleGrabber_Out_IPin_Connect,
    SampleGrabber_Out_IPin_ReceiveConnection,
    SampleGrabber_Out_IPin_Disconnect,
    SampleGrabber_IPin_ConnectedTo,
    SampleGrabber_IPin_ConnectionMediaType,
    SampleGrabber_IPin_QueryPinInfo,
    SampleGrabber_IPin_QueryDirection,
    SampleGrabber_IPin_QueryId,
    SampleGrabber_IPin_QueryAccept,
    SampleGrabber_IPin_EnumMediaTypes,
    SampleGrabber_Out_IPin_QueryInternalConnections,
    SampleGrabber_IPin_EndOfStream,
    SampleGrabber_IPin_BeginFlush,
    SampleGrabber_IPin_EndFlush,
    SampleGrabber_IPin_NewSegment,
};

HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
{
    SG_Impl* obj = NULL;
    ISeekingPassThru *passthru;
    HRESULT hr;

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

    obj = CoTaskMemAlloc(sizeof(SG_Impl));
    if (NULL == obj) {
        *ppv = NULL;
        return E_OUTOFMEMORY;
    }
    ZeroMemory(obj, sizeof(SG_Impl));

    BaseFilter_Init(&obj->filter, &IBaseFilter_VTable, &CLSID_SampleGrabber,
            (DWORD_PTR)(__FILE__ ": SG_Impl.csFilter"), &basefunc_vtbl);
    obj->IUnknown_inner.lpVtbl = &samplegrabber_vtbl;
    obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;
    obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
    obj->pin_in.IPin_iface.lpVtbl = &IPin_In_VTable;
    obj->pin_in.dir = PINDIR_INPUT;
    obj->pin_in.name = pin_in_name;
    obj->pin_in.sg = obj;
    obj->pin_in.pair = NULL;
    obj->pin_out.IPin_iface.lpVtbl = &IPin_Out_VTable;
    obj->pin_out.dir = PINDIR_OUTPUT;
    obj->pin_out.name = pin_out_name;
    obj->pin_out.sg = obj;
    obj->pin_out.pair = NULL;
    obj->mtype.majortype = GUID_NULL;
    obj->mtype.subtype = MEDIASUBTYPE_None;
    obj->mtype.formattype = FORMAT_None;
    obj->allocator = NULL;
    obj->memOutput = NULL;
    obj->grabberIface = NULL;
    obj->grabberMethod = -1;
    obj->oneShot = OneShot_None;
    obj->bufferLen = -1;
    obj->bufferData = NULL;

    if (pUnkOuter)
        obj->outer_unk = pUnkOuter;
    else
        obj->outer_unk = &obj->IUnknown_inner;

    hr = CoCreateInstance(&CLSID_SeekingPassThru, &obj->IUnknown_inner, CLSCTX_INPROC_SERVER,
                          &IID_IUnknown, (void**)&obj->seekthru_unk);
    if(hr)
        return hr;
    IUnknown_QueryInterface(obj->seekthru_unk, &IID_ISeekingPassThru, (void**)&passthru);
    ISeekingPassThru_Init(passthru, FALSE, &obj->pin_in.IPin_iface);
    ISeekingPassThru_Release(passthru);

    *ppv = &obj->IUnknown_inner;
    return S_OK;
}
