/*
 * Memory Allocator and Media Sample Implementation
 *
 * Copyright 2003 Robert Shearman
 *
 * 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 <limits.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "vfwmsgs.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

typedef struct StdMediaSample2
{
    IMediaSample2 IMediaSample2_iface;
    LONG ref;
    AM_SAMPLE2_PROPERTIES props;
    IMemAllocator * pParent;
    struct list listentry;
    LONGLONG tMediaStart;
    LONGLONG tMediaEnd;
} StdMediaSample2;

typedef struct BaseMemAllocator
{
    IMemAllocator IMemAllocator_iface;

    LONG ref;
    ALLOCATOR_PROPERTIES props;
    HRESULT (* fnAlloc) (IMemAllocator *);
    HRESULT (* fnFree)(IMemAllocator *);
    HRESULT (* fnVerify)(IMemAllocator *, ALLOCATOR_PROPERTIES *);
    HRESULT (* fnBufferPrepare)(IMemAllocator *, StdMediaSample2 *, DWORD flags);
    HRESULT (* fnBufferReleased)(IMemAllocator *, StdMediaSample2 *);
    void (* fnDestroyed)(IMemAllocator *);
    HANDLE hSemWaiting;
    BOOL bDecommitQueued;
    BOOL bCommitted;
    LONG lWaiting;
    struct list free_list;
    struct list used_list;
    CRITICAL_SECTION *pCritSect;
} BaseMemAllocator;

static inline BaseMemAllocator *impl_from_IMemAllocator(IMemAllocator *iface)
{
    return CONTAINING_RECORD(iface, BaseMemAllocator, IMemAllocator_iface);
}

static const IMemAllocatorVtbl BaseMemAllocator_VTable;
static const IMediaSample2Vtbl StdMediaSample2_VTable;
static inline StdMediaSample2 *unsafe_impl_from_IMediaSample(IMediaSample * iface);

#define AM_SAMPLE2_PROP_SIZE_WRITABLE FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer)

#define INVALID_MEDIA_TIME (((ULONGLONG)0x7fffffff << 32) | 0xffffffff)

static HRESULT BaseMemAllocator_Init(HRESULT (* fnAlloc)(IMemAllocator *),
                                     HRESULT (* fnFree)(IMemAllocator *),
                                     HRESULT (* fnVerify)(IMemAllocator *, ALLOCATOR_PROPERTIES *),
                                     HRESULT (* fnBufferPrepare)(IMemAllocator *, StdMediaSample2 *, DWORD),
                                     HRESULT (* fnBufferReleased)(IMemAllocator *, StdMediaSample2 *),
                                     void (* fnDestroyed)(IMemAllocator *),
                                     CRITICAL_SECTION *pCritSect,
                                     BaseMemAllocator * pMemAlloc)
{
    assert(fnAlloc && fnFree && fnDestroyed);

    pMemAlloc->IMemAllocator_iface.lpVtbl = &BaseMemAllocator_VTable;

    pMemAlloc->ref = 1;
    ZeroMemory(&pMemAlloc->props, sizeof(pMemAlloc->props));
    list_init(&pMemAlloc->free_list);
    list_init(&pMemAlloc->used_list);
    pMemAlloc->fnAlloc = fnAlloc;
    pMemAlloc->fnFree = fnFree;
    pMemAlloc->fnVerify = fnVerify;
    pMemAlloc->fnBufferPrepare = fnBufferPrepare;
    pMemAlloc->fnBufferReleased = fnBufferReleased;
    pMemAlloc->fnDestroyed = fnDestroyed;
    pMemAlloc->bDecommitQueued = FALSE;
    pMemAlloc->bCommitted = FALSE;
    pMemAlloc->hSemWaiting = NULL;
    pMemAlloc->lWaiting = 0;
    pMemAlloc->pCritSect = pCritSect;

    return S_OK;
}

static HRESULT WINAPI BaseMemAllocator_QueryInterface(IMemAllocator * iface, REFIID riid, LPVOID * ppv)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    TRACE("(%p)->(%s, %p)\n", This, qzdebugstr_guid(riid), ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = &This->IMemAllocator_iface;
    else if (IsEqualIID(riid, &IID_IMemAllocator))
        *ppv = &This->IMemAllocator_iface;

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

    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));

    return E_NOINTERFACE;
}

static ULONG WINAPI BaseMemAllocator_AddRef(IMemAllocator * iface)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->() AddRef from %d\n", iface, ref - 1);

    return ref;
}

static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->() Release from %d\n", iface, ref + 1);

    if (!ref)
    {
        CloseHandle(This->hSemWaiting);
        if (This->bCommitted)
            This->fnFree(iface);

        This->fnDestroyed(iface);
        return 0;
    }
    return ref;
}

static HRESULT WINAPI BaseMemAllocator_SetProperties(IMemAllocator * iface, ALLOCATOR_PROPERTIES *pRequest, ALLOCATOR_PROPERTIES *pActual)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr;

    TRACE("(%p)->(%p, %p)\n", This, pRequest, pActual);

    EnterCriticalSection(This->pCritSect);
    {
        if (!list_empty(&This->used_list))
            hr = VFW_E_BUFFERS_OUTSTANDING;
        else if (This->bCommitted)
            hr = VFW_E_ALREADY_COMMITTED;
        else if (pRequest->cbAlign == 0)
            hr = VFW_E_BADALIGN;
        else
        {
            if (This->fnVerify)
                 hr = This->fnVerify(iface, pRequest);
            else
                 hr = S_OK;

            if (SUCCEEDED(hr))
                 This->props = *pRequest;

            *pActual = This->props;
        }
    }
    LeaveCriticalSection(This->pCritSect);

    return hr;
}

static HRESULT WINAPI BaseMemAllocator_GetProperties(IMemAllocator * iface, ALLOCATOR_PROPERTIES *pProps)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr = S_OK;

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

    EnterCriticalSection(This->pCritSect);
    {
         memcpy(pProps, &This->props, sizeof(*pProps));
    }
    LeaveCriticalSection(This->pCritSect);

    return hr;
}

static HRESULT WINAPI BaseMemAllocator_Commit(IMemAllocator * iface)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr;

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

    EnterCriticalSection(This->pCritSect);
    {
        if (!This->props.cbAlign)
            hr = VFW_E_BADALIGN;
        else if (!This->props.cbBuffer)
            hr = VFW_E_SIZENOTSET;
        else if (!This->props.cBuffers)
            hr = VFW_E_BUFFER_NOTSET;
        else if (This->bDecommitQueued && This->bCommitted)
        {
            This->bDecommitQueued = FALSE;
            hr = S_OK;
        }
        else if (This->bCommitted)
            hr = S_OK;
        else
        {
            if (!(This->hSemWaiting = CreateSemaphoreW(NULL, This->props.cBuffers, This->props.cBuffers, NULL)))
            {
                ERR("Couldn't create semaphore (error was %u)\n", GetLastError());
                hr = HRESULT_FROM_WIN32(GetLastError());
            }
            else
            {
                hr = This->fnAlloc(iface);
                if (SUCCEEDED(hr))
                    This->bCommitted = TRUE;
                else
                    ERR("fnAlloc failed with error 0x%x\n", hr);
            }
        }
    }
    LeaveCriticalSection(This->pCritSect);

    return hr;
}

static HRESULT WINAPI BaseMemAllocator_Decommit(IMemAllocator * iface)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr;

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

    EnterCriticalSection(This->pCritSect);
    {
        if (!This->bCommitted)
            hr = S_OK;
        else
        {
            if (!list_empty(&This->used_list))
            {
                This->bDecommitQueued = TRUE;
                /* notify ALL waiting threads that they cannot be allocated a buffer any more */
                ReleaseSemaphore(This->hSemWaiting, This->lWaiting, NULL);
                
                hr = S_OK;
            }
            else
            {
                if (This->lWaiting != 0)
                    ERR("Waiting: %d\n", This->lWaiting);

                This->bCommitted = FALSE;
                CloseHandle(This->hSemWaiting);
                This->hSemWaiting = NULL;

                hr = This->fnFree(iface);
                if (FAILED(hr))
                    ERR("fnFree failed with error 0x%x\n", hr);
            }
        }
    }
    LeaveCriticalSection(This->pCritSect);

    return hr;
}

static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSample ** pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr = S_OK;

    /* NOTE: The pStartTime and pEndTime parameters are not applied to the sample. 
     * The allocator might use these values to determine which buffer it retrieves */
    
    TRACE("(%p)->(%p, %p, %p, %x)\n", This, pSample, pStartTime, pEndTime, dwFlags);

    *pSample = NULL;

    EnterCriticalSection(This->pCritSect);
    if (!This->bCommitted || This->bDecommitQueued)
    {
        WARN("Not committed\n");
        hr = VFW_E_NOT_COMMITTED;
    }
    else
        ++This->lWaiting;
    LeaveCriticalSection(This->pCritSect);
    if (FAILED(hr))
        return hr;

    if (WaitForSingleObject(This->hSemWaiting, (dwFlags & AM_GBF_NOWAIT) ? 0 : INFINITE) != WAIT_OBJECT_0)
    {
        EnterCriticalSection(This->pCritSect);
        --This->lWaiting;
        LeaveCriticalSection(This->pCritSect);
        WARN("Timed out\n");
        return VFW_E_TIMEOUT;
    }

    EnterCriticalSection(This->pCritSect);
    {
        --This->lWaiting;
        if (!This->bCommitted)
            hr = VFW_E_NOT_COMMITTED;
        else if (This->bDecommitQueued)
            hr = VFW_E_TIMEOUT;
        else
        {
            StdMediaSample2 *ms;
            struct list * free = list_head(&This->free_list);
            list_remove(free);
            list_add_head(&This->used_list, free);

            ms = LIST_ENTRY(free, StdMediaSample2, listentry);
            assert(ms->ref == 0);
            *pSample = (IMediaSample *)&ms->IMediaSample2_iface;
            IMediaSample_AddRef(*pSample);
        }
    }
    LeaveCriticalSection(This->pCritSect);

    if (hr != S_OK)
        WARN("%08x\n", hr);
    return hr;
}

static HRESULT WINAPI BaseMemAllocator_ReleaseBuffer(IMemAllocator * iface, IMediaSample * pSample)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    StdMediaSample2 * pStdSample = unsafe_impl_from_IMediaSample(pSample);
    HRESULT hr = S_OK;

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

    /* FIXME: make sure that sample is currently on the used list */

    /* FIXME: we should probably check the ref count on the sample before freeing
     * it to make sure that it is not still in use */
    EnterCriticalSection(This->pCritSect);
    {
        if (!This->bCommitted)
            ERR("Releasing a buffer when the allocator is not committed?!?\n");

		/* remove from used_list */
        list_remove(&pStdSample->listentry);

        list_add_head(&This->free_list, &pStdSample->listentry);

        if (list_empty(&This->used_list) && This->bDecommitQueued && This->bCommitted)
        {
            HRESULT hrfree;

            if (This->lWaiting != 0)
                ERR("Waiting: %d\n", This->lWaiting);

            This->bCommitted = FALSE;
            This->bDecommitQueued = FALSE;

            CloseHandle(This->hSemWaiting);
            This->hSemWaiting = NULL;
            
            if (FAILED(hrfree = This->fnFree(iface)))
                ERR("fnFree failed with error 0x%x\n", hrfree);
        }
    }
    LeaveCriticalSection(This->pCritSect);

    /* notify a waiting thread that there is now a free buffer */
    if (This->hSemWaiting && !ReleaseSemaphore(This->hSemWaiting, 1, NULL))
    {
        ERR("ReleaseSemaphore failed with error %u\n", GetLastError());
        hr = HRESULT_FROM_WIN32(GetLastError());
    }

    return hr;
}

static const IMemAllocatorVtbl BaseMemAllocator_VTable = 
{
    BaseMemAllocator_QueryInterface,
    BaseMemAllocator_AddRef,
    BaseMemAllocator_Release,
    BaseMemAllocator_SetProperties,
    BaseMemAllocator_GetProperties,
    BaseMemAllocator_Commit,
    BaseMemAllocator_Decommit,
    BaseMemAllocator_GetBuffer,
    BaseMemAllocator_ReleaseBuffer
};

static HRESULT StdMediaSample2_Construct(BYTE * pbBuffer, LONG cbBuffer, IMemAllocator * pParent, StdMediaSample2 ** ppSample)
{
    assert(pbBuffer && pParent && (cbBuffer > 0));

    if (!(*ppSample = CoTaskMemAlloc(sizeof(StdMediaSample2))))
        return E_OUTOFMEMORY;

    (*ppSample)->IMediaSample2_iface.lpVtbl = &StdMediaSample2_VTable;
    (*ppSample)->ref = 0;
    ZeroMemory(&(*ppSample)->props, sizeof((*ppSample)->props));

    /* NOTE: no need to AddRef as the parent is guaranteed to be around
     * at least as long as us and we don't want to create circular
     * dependencies on the ref count */
    (*ppSample)->pParent = pParent;
    (*ppSample)->props.cbData = sizeof(AM_SAMPLE2_PROPERTIES);
    (*ppSample)->props.cbBuffer = (*ppSample)->props.lActual = cbBuffer;
    (*ppSample)->props.pbBuffer = pbBuffer;
    (*ppSample)->tMediaStart = INVALID_MEDIA_TIME;
    (*ppSample)->tMediaEnd = 0;

    return S_OK;
}

static void StdMediaSample2_Delete(StdMediaSample2 * This)
{
    /* NOTE: does not remove itself from the list it belongs to */
    CoTaskMemFree(This);
}

static inline StdMediaSample2 *impl_from_IMediaSample2(IMediaSample2 * iface)
{
    return CONTAINING_RECORD(iface, StdMediaSample2, IMediaSample2_iface);
}

static HRESULT WINAPI StdMediaSample2_QueryInterface(IMediaSample2 * iface, REFIID riid, void ** ppv)
{
    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMediaSample) ||
            IsEqualIID(riid, &IID_IMediaSample2))
    {
        *ppv = iface;
        IMediaSample2_AddRef(iface);
        return S_OK;
    }

    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI StdMediaSample2_AddRef(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI StdMediaSample2_Release(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref)
    {
        if (This->pParent)
            IMemAllocator_ReleaseBuffer(This->pParent, (IMediaSample *)iface);
        else
            StdMediaSample2_Delete(This);
    }
    return ref;
}

static HRESULT WINAPI StdMediaSample2_GetPointer(IMediaSample2 * iface, BYTE ** ppBuffer)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    *ppBuffer = This->props.pbBuffer;

    if (!*ppBuffer)
    {
        ERR("Requested an unlocked surface and trying to lock regardless\n");
        return E_FAIL;
    }

    return S_OK;
}

static LONG WINAPI StdMediaSample2_GetSize(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("StdMediaSample2_GetSize()\n");

    return This->props.cbBuffer;
}

static HRESULT WINAPI StdMediaSample2_GetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);
    HRESULT hr;

    TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd);

    if (!(This->props.dwSampleFlags & AM_SAMPLE_TIMEVALID))
        hr = VFW_E_SAMPLE_TIME_NOT_SET;
    else if (!(This->props.dwSampleFlags & AM_SAMPLE_STOPVALID))
    {
        *pStart = This->props.tStart;
        *pEnd = This->props.tStart + 1;
        
        hr = VFW_S_NO_STOP_TIME;
    }
    else
    {
        *pStart = This->props.tStart;
        *pEnd = This->props.tStop;

        hr = S_OK;
    }

    return hr;
}

static HRESULT WINAPI StdMediaSample2_SetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd);

    if (pStart)
    {
        This->props.tStart = *pStart;
        This->props.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
    }
    else
        This->props.dwSampleFlags &= ~AM_SAMPLE_TIMEVALID;

    if (pEnd)
    {
        This->props.tStop = *pEnd;
        This->props.dwSampleFlags |= AM_SAMPLE_STOPVALID;
    }
    else
        This->props.dwSampleFlags &= ~AM_SAMPLE_STOPVALID;

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_IsSyncPoint(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    return (This->props.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
}

static HRESULT WINAPI StdMediaSample2_SetSyncPoint(IMediaSample2 * iface, BOOL bIsSyncPoint)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%s)\n", iface, bIsSyncPoint ? "TRUE" : "FALSE");

    if (bIsSyncPoint)
        This->props.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
    else
        This->props.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_IsPreroll(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    return (This->props.dwSampleFlags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
}

static HRESULT WINAPI StdMediaSample2_SetPreroll(IMediaSample2 * iface, BOOL bIsPreroll)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%s)\n", iface, bIsPreroll ? "TRUE" : "FALSE");

    if (bIsPreroll)
        This->props.dwSampleFlags |= AM_SAMPLE_PREROLL;
    else
        This->props.dwSampleFlags &= ~AM_SAMPLE_PREROLL;

    return S_OK;
}

static LONG WINAPI StdMediaSample2_GetActualDataLength(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    return This->props.lActual;
}

static HRESULT WINAPI StdMediaSample2_SetActualDataLength(IMediaSample2 * iface, LONG len)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%d)\n", iface, len);

    if ((len > This->props.cbBuffer) || (len < 0))
    {
        WARN("Tried to set length to %d, while max is %d\n", len, This->props.cbBuffer);
        return VFW_E_BUFFER_OVERFLOW;
    }
    else
    {
        This->props.lActual = len;
        return S_OK;
    }
}

static HRESULT WINAPI StdMediaSample2_GetMediaType(IMediaSample2 * iface, AM_MEDIA_TYPE ** ppMediaType)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    if (!This->props.pMediaType) {
        /* Make sure we return a NULL pointer (required by native Quartz dll) */
        if (ppMediaType)
            *ppMediaType = NULL;
        return S_FALSE;
    }

    if (!(*ppMediaType = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))))
        return E_OUTOFMEMORY;

    return CopyMediaType(*ppMediaType, This->props.pMediaType);
}

static HRESULT WINAPI StdMediaSample2_SetMediaType(IMediaSample2 * iface, AM_MEDIA_TYPE * pMediaType)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    if (This->props.pMediaType)
    {
        FreeMediaType(This->props.pMediaType);
        This->props.pMediaType = NULL;
    }
    if (!pMediaType)
        return S_FALSE;
    if (!(This->props.pMediaType = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))))
        return E_OUTOFMEMORY;

    return CopyMediaType(This->props.pMediaType, pMediaType);
}

static HRESULT WINAPI StdMediaSample2_IsDiscontinuity(IMediaSample2 * iface)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

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

    return (This->props.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
}

static HRESULT WINAPI StdMediaSample2_SetDiscontinuity(IMediaSample2 * iface, BOOL bIsDiscontinuity)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%s)\n", iface, bIsDiscontinuity ? "TRUE" : "FALSE");

    if (bIsDiscontinuity)
        This->props.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
    else
        This->props.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_GetMediaTime(IMediaSample2 * iface, LONGLONG * pStart, LONGLONG * pEnd)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd);

    if (This->tMediaStart == INVALID_MEDIA_TIME)
        return VFW_E_MEDIA_TIME_NOT_SET;

    *pStart = This->tMediaStart;
    *pEnd = This->tMediaEnd;

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_SetMediaTime(IMediaSample2 * iface, LONGLONG * pStart, LONGLONG * pEnd)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd);

    if (pStart)
        This->tMediaStart = *pStart;
    else
        This->tMediaStart = INVALID_MEDIA_TIME;

    if (pEnd)
        This->tMediaEnd = *pEnd;
    else
        This->tMediaEnd = 0;

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_GetProperties(IMediaSample2 * iface, DWORD cbProperties, BYTE * pbProperties)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%d, %p)\n", iface, cbProperties, pbProperties);

    memcpy(pbProperties, &This->props, min(cbProperties, sizeof(This->props)));

    return S_OK;
}

static HRESULT WINAPI StdMediaSample2_SetProperties(IMediaSample2 * iface, DWORD cbProperties, const BYTE * pbProperties)
{
    StdMediaSample2 *This = impl_from_IMediaSample2(iface);

    TRACE("(%p)->(%d, %p)\n", iface, cbProperties, pbProperties);

    /* NOTE: pbBuffer and cbBuffer are read-only */
    memcpy(&This->props, pbProperties, min(cbProperties, AM_SAMPLE2_PROP_SIZE_WRITABLE));

    return S_OK;
}

static const IMediaSample2Vtbl StdMediaSample2_VTable = 
{
    StdMediaSample2_QueryInterface,
    StdMediaSample2_AddRef,
    StdMediaSample2_Release,
    StdMediaSample2_GetPointer,
    StdMediaSample2_GetSize,
    StdMediaSample2_GetTime,
    StdMediaSample2_SetTime,
    StdMediaSample2_IsSyncPoint,
    StdMediaSample2_SetSyncPoint,
    StdMediaSample2_IsPreroll,
    StdMediaSample2_SetPreroll,
    StdMediaSample2_GetActualDataLength,
    StdMediaSample2_SetActualDataLength,
    StdMediaSample2_GetMediaType,
    StdMediaSample2_SetMediaType,
    StdMediaSample2_IsDiscontinuity,
    StdMediaSample2_SetDiscontinuity,
    StdMediaSample2_GetMediaTime,
    StdMediaSample2_SetMediaTime,
    StdMediaSample2_GetProperties,
    StdMediaSample2_SetProperties
};

static inline StdMediaSample2 *unsafe_impl_from_IMediaSample(IMediaSample * iface)
{
    IMediaSample2 *iface2 = (IMediaSample2 *)iface;

    if (!iface)
        return NULL;
    assert(iface2->lpVtbl == &StdMediaSample2_VTable);
    return impl_from_IMediaSample2(iface2);
}

typedef struct StdMemAllocator
{
    BaseMemAllocator base;
    CRITICAL_SECTION csState;
    LPVOID pMemory;
} StdMemAllocator;

static inline StdMemAllocator *StdMemAllocator_from_IMemAllocator(IMemAllocator * iface)
{
    return CONTAINING_RECORD(iface, StdMemAllocator, base.IMemAllocator_iface);
}

static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface)
{
    StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface);
    StdMediaSample2 * pSample = NULL;
    SYSTEM_INFO si;
    LONG i;

    assert(list_empty(&This->base.free_list));

    /* check alignment */
    GetSystemInfo(&si);

    /* we do not allow a courser alignment than the OS page size */
    if ((si.dwPageSize % This->base.props.cbAlign) != 0)
        return VFW_E_BADALIGN;

    /* FIXME: each sample has to have its buffer start on the right alignment.
     * We don't do this at the moment */

    /* allocate memory */
    This->pMemory = VirtualAlloc(NULL, (This->base.props.cbBuffer + This->base.props.cbPrefix) * This->base.props.cBuffers, MEM_COMMIT, PAGE_READWRITE);

    if (!This->pMemory)
        return E_OUTOFMEMORY;

    for (i = This->base.props.cBuffers - 1; i >= 0; i--)
    {
        /* pbBuffer does not start at the base address, it starts at base + cbPrefix */
        BYTE * pbBuffer = (BYTE *)This->pMemory + i * (This->base.props.cbBuffer + This->base.props.cbPrefix) + This->base.props.cbPrefix;
        
        StdMediaSample2_Construct(pbBuffer, This->base.props.cbBuffer, iface, &pSample);

        list_add_head(&This->base.free_list, &pSample->listentry);
    }

    return S_OK;
}

static HRESULT StdMemAllocator_Free(IMemAllocator * iface)
{
    StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface);
    struct list * cursor;

    if (!list_empty(&This->base.used_list))
    {
        WARN("Freeing allocator with outstanding samples!\n");
        while ((cursor = list_head(&This->base.used_list)) != NULL)
        {
            StdMediaSample2 *pSample;
            list_remove(cursor);
            pSample = LIST_ENTRY(cursor, StdMediaSample2, listentry);
            pSample->pParent = NULL;
        }
    }

    while ((cursor = list_head(&This->base.free_list)) != NULL)
    {
        list_remove(cursor);
        StdMediaSample2_Delete(LIST_ENTRY(cursor, StdMediaSample2, listentry));
    }
    
    /* free memory */
    if (!VirtualFree(This->pMemory, 0, MEM_RELEASE))
    {
        ERR("Couldn't free memory. Error: %u\n", GetLastError());
        return HRESULT_FROM_WIN32(GetLastError());
    }

    return S_OK;
}

static void StdMemAllocator_Destroy(IMemAllocator *iface)
{
    StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface);

    This->csState.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->csState);

    CoTaskMemFree(This);
}

HRESULT StdMemAllocator_create(LPUNKNOWN lpUnkOuter, LPVOID * ppv)
{
    StdMemAllocator * pMemAlloc;
    HRESULT hr;

    *ppv = NULL;
    
    if (lpUnkOuter)
        return CLASS_E_NOAGGREGATION;

    if (!(pMemAlloc = CoTaskMemAlloc(sizeof(*pMemAlloc))))
        return E_OUTOFMEMORY;

    InitializeCriticalSection(&pMemAlloc->csState);
    pMemAlloc->csState.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StdMemAllocator.csState");

    pMemAlloc->pMemory = NULL;

    if (SUCCEEDED(hr = BaseMemAllocator_Init(StdMemAllocator_Alloc, StdMemAllocator_Free, NULL, NULL, NULL, StdMemAllocator_Destroy, &pMemAlloc->csState, &pMemAlloc->base)))
        *ppv = pMemAlloc;
    else
        CoTaskMemFree(pMemAlloc);

    return hr;
}
