/*
 * DirectShow capture services (QCAP.DLL)
 *
 * Copyright 2005 Maarten Lankhorst
 *
 * This file contains the part of the vfw capture interface that
 * does the actual Video4Linux(1/2) stuff required for capturing
 * and setting/getting media format..
 *
 * 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 "config.h"
#include "wine/port.h"

#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#define COBJMACROS

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "wingdi.h"
#include "winuser.h"
#include "dshow.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "wine/debug.h"

#include "capture.h"
#include "qcap_main.h"
#include "pin.h"

#include <stdio.h>
#include <fcntl.h>

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
#ifdef HAVE_LINUX_VIDEODEV_H
#include <linux/videodev.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

WINE_DEFAULT_DEBUG_CHANNEL(qcap_v4l);

#ifdef HAVE_LINUX_VIDEODEV_H

typedef void (* Renderer)(Capture *, LPBYTE bufferin, LPBYTE stream);

struct _Capture
{
    UINT width, height, bitDepth, fps, outputwidth, outputheight;
    BOOL swresize;

    CRITICAL_SECTION CritSect;

    IPin *pOut;
    int fd, mmap;
    int iscommitted, stopped;
    struct video_picture pict;
    int dbrightness, dhue, dcolour, dcontrast;

    /* mmap (V4l1) */
    struct video_mmap *grab_buf;
    struct video_mbuf gb_buffers;
    unsigned char *pmap;
    int buffers;

    /* read (V4l1) */
    int imagesize;
    char * grab_data;

    int curframe;

    HANDLE thread;
    Renderer renderer;
};

struct renderlist
{
    int depth;
    const char* name;
    Renderer renderer;
};

static void renderer_RGB(Capture *capBox, LPBYTE bufferin, LPBYTE stream);
static void renderer_YUV(Capture *capBox, LPBYTE bufferin, LPBYTE stream);

static const struct renderlist renderlist_V4l[] = {
    {  0, "NULL renderer",               NULL },
    {  8, "Gray scales",                 NULL }, /* 1,  Don't support  */
    {  0, "High 240 cube (BT848)",       NULL }, /* 2,  Don't support  */
    { 16, "16 bit RGB (565)",            NULL }, /* 3,  Don't support  */
    { 24, "24 bit RGB values",   renderer_RGB }, /* 4,  Supported,     */
    { 32, "32 bit RGB values",   renderer_RGB }, /* 5,  Supported      */
    { 16, "15 bit RGB (555)",            NULL }, /* 6,  Don't support  */
    { 16, "YUV 422 (Not P)",     renderer_YUV }, /* 7,  Supported */
    { 16, "YUYV (Not P)",        renderer_YUV }, /* 8,  Supported */
    { 16, "UYVY (Not P)",        renderer_YUV }, /* 9,  Supported */
    { 16, "YUV 420 (Not P)", NULL }, /* 10, Not supported, if I had to guess it's YYUYYV */
    { 12, "YUV 411 (Not P)",     renderer_YUV }, /* 11, Supported */
    {  0, "Raw capturing (BT848)",       NULL }, /* 12, Don't support  */
    { 16, "YUV 422 (Planar)",    renderer_YUV }, /* 13, Supported */
    { 12, "YUV 411 (Planar)",    renderer_YUV }, /* 14, Supported */
    { 12, "YUV 420 (Planar)",    renderer_YUV }, /* 15, Supported */
    { 10, "YUV 410 (Planar)",    renderer_YUV }, /* 16, Supported */
    /* FIXME: add YUV420 support */
    {  0, NULL,                          NULL },
};

static const int fallback_V4l[] = { 4, 5, 7, 8, 9, 13, 15, 14, 16, 11, -1 };
/* Fallback: First try raw formats (Should try yuv first perhaps?), then yuv */

/* static const Capture defbox; */

static int xioctl(int fd, int request, void * arg)
{
    int r;

    do {
        r = ioctl (fd, request, arg);
    } while (-1 == r && EINTR == errno);

    return r;
}

/* Prepare the capture buffers */
static HRESULT V4l_Prepare(Capture *capBox)
{
    TRACE("%p: Preparing for %dx%d resolution\n", capBox, capBox->width, capBox->height);

    /* Try mmap */
    capBox->mmap = 0;
    if (xioctl(capBox->fd, VIDIOCGMBUF, &capBox->gb_buffers) != -1 &&
        capBox->gb_buffers.frames)
    {
        capBox->buffers = capBox->gb_buffers.frames;
        if (capBox->gb_buffers.frames > 1)
            capBox->buffers = 1;
        TRACE("%p: Using %d/%d buffers\n", capBox,
              capBox->buffers, capBox->gb_buffers.frames);

        capBox->pmap = mmap( 0, capBox->gb_buffers.size, PROT_READ|PROT_WRITE,
                             MAP_SHARED, capBox->fd, 0 );
        if (capBox->pmap != MAP_FAILED)
        {
            int i;

            capBox->grab_buf = CoTaskMemAlloc(sizeof(struct video_mmap) * capBox->buffers);
            if (!capBox->grab_buf)
            {
                munmap(capBox->pmap, capBox->gb_buffers.size);
                return E_OUTOFMEMORY;
            }

            /* Setup mmap capture buffers. */
            for (i = 0; i < capBox->buffers; i++)
            {
                capBox->grab_buf[i].format = capBox->pict.palette;
                capBox->grab_buf[i].frame = i;
                capBox->grab_buf[i].width = capBox->width;
                capBox->grab_buf[i].height = capBox->height;
            }
            capBox->mmap = 1;
        }
    }
    if (!capBox->mmap)
    {
        capBox->buffers = 1;
        capBox->imagesize = renderlist_V4l[capBox->pict.palette].depth *
                                capBox->height * capBox->width / 8;
        capBox->grab_data = CoTaskMemAlloc(capBox->imagesize);
        if (!capBox->grab_data)
            return E_OUTOFMEMORY;
    }
    TRACE("Using mmap: %d\n", capBox->mmap);
    return S_OK;
}

static void V4l_Unprepare(Capture *capBox)
{
    if (capBox->mmap)
    {
        for (capBox->curframe = 0; capBox->curframe < capBox->buffers; capBox->curframe++) 
            xioctl(capBox->fd, VIDIOCSYNC, &capBox->grab_buf[capBox->curframe]);
        munmap(capBox->pmap, capBox->gb_buffers.size);
        CoTaskMemFree(capBox->grab_buf);
    }
    else
        CoTaskMemFree(capBox->grab_data);
}

HRESULT qcap_driver_destroy(Capture *capBox)
{
    TRACE("%p\n", capBox);

    if( capBox->fd != -1 )
        close(capBox->fd);
    DeleteCriticalSection(&capBox->CritSect);
    CoTaskMemFree(capBox);
    return S_OK;
}

HRESULT qcap_driver_set_format(Capture *capBox, AM_MEDIA_TYPE * mT)
{
    int newheight, newwidth;
    struct video_window window;
    VIDEOINFOHEADER *format;

    TRACE("%p\n", capBox);

    format = (VIDEOINFOHEADER *) mT->pbFormat;
    if (format->bmiHeader.biBitCount != 24 ||
        format->bmiHeader.biCompression != BI_RGB)
    {
        FIXME("unsupported media type %d %d\n", format->bmiHeader.biBitCount,
              format->bmiHeader.biCompression );
        return VFW_E_INVALIDMEDIATYPE;
    }

    newwidth = format->bmiHeader.biWidth;
    newheight = format->bmiHeader.biHeight;

    TRACE("%p -> (%p) - %d %d\n", capBox, mT, newwidth, newheight);

    if (capBox->height == newheight && capBox->width == newwidth)
        return S_OK;

    if(-1 == xioctl(capBox->fd, VIDIOCGWIN, &window))
    {
        ERR("ioctl(VIDIOCGWIN) failed (%d)\n", errno);
        return E_FAIL;
    }
    window.width = newwidth;
    window.height = newheight;
    if (xioctl(capBox->fd, VIDIOCSWIN, &window) == -1)
    {
        TRACE("using software resize: %dx%d -> %dx%d\n",
               window.width, window.height, capBox->width, capBox->height);
        capBox->swresize = TRUE;
    }
    else
    {
        capBox->height = window.height;
        capBox->width = window.width;
        capBox->swresize = FALSE;
    }
    capBox->outputwidth = window.width;
    capBox->outputheight = window.height;
    return S_OK;
}

HRESULT qcap_driver_get_format(Capture *capBox, AM_MEDIA_TYPE ** mT)
{
    VIDEOINFOHEADER *vi;

    mT[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
    if (!mT[0])
        return E_OUTOFMEMORY;
    vi = CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
    mT[0]->cbFormat = sizeof(VIDEOINFOHEADER);
    if (!vi)
    {
        CoTaskMemFree(mT[0]);
        return E_OUTOFMEMORY;
    }
    memcpy(&mT[0]->majortype, &MEDIATYPE_Video, sizeof(GUID));
    memcpy(&mT[0]->subtype, &MEDIASUBTYPE_RGB24, sizeof(GUID));
    memcpy(&mT[0]->formattype, &FORMAT_VideoInfo, sizeof(GUID));
    mT[0]->bFixedSizeSamples = TRUE;
    mT[0]->bTemporalCompression = FALSE;
    mT[0]->pUnk = NULL;
    mT[0]->lSampleSize = capBox->outputwidth * capBox->outputheight * capBox->bitDepth / 8;
    TRACE("Output format: %dx%d - %d bits = %u KB\n", capBox->outputwidth,
          capBox->outputheight, capBox->bitDepth, mT[0]->lSampleSize/1024);
    vi->rcSource.left = 0; vi->rcSource.top = 0;
    vi->rcTarget.left = 0; vi->rcTarget.top = 0;
    vi->rcSource.right = capBox->width; vi->rcSource.bottom = capBox->height;
    vi->rcTarget.right = capBox->outputwidth; vi->rcTarget.bottom = capBox->outputheight;
    vi->dwBitRate = capBox->fps * mT[0]->lSampleSize;
    vi->dwBitErrorRate = 0;
    vi->AvgTimePerFrame = (LONGLONG)10000000.0 / (LONGLONG)capBox->fps;
    vi->bmiHeader.biSize = 40;
    vi->bmiHeader.biWidth = capBox->outputwidth;
    vi->bmiHeader.biHeight = capBox->outputheight;
    vi->bmiHeader.biPlanes = 1;
    vi->bmiHeader.biBitCount = 24;
    vi->bmiHeader.biCompression = BI_RGB;
    vi->bmiHeader.biSizeImage = mT[0]->lSampleSize;
    vi->bmiHeader.biClrUsed = vi->bmiHeader.biClrImportant = 0;
    vi->bmiHeader.biXPelsPerMeter = 100;
    vi->bmiHeader.biYPelsPerMeter = 100;
    mT[0]->pbFormat = (void *)vi;
    dump_AM_MEDIA_TYPE(mT[0]);
    return S_OK;
}

HRESULT qcap_driver_get_prop_range( Capture *capBox, long Property, long *pMin,
            long *pMax, long *pSteppingDelta, long *pDefault, long *pCapsFlags )
{
    TRACE("%p -> %ld %p %p %p %p %p\n", capBox, Property,
          pMin, pMax, pSteppingDelta, pDefault, pCapsFlags);

    switch (Property)
    {
    case VideoProcAmp_Brightness:
        *pDefault = capBox->dbrightness;
        break;
    case VideoProcAmp_Contrast:
        *pDefault = capBox->dcontrast;
        break;
    case VideoProcAmp_Hue:
        *pDefault = capBox->dhue;
        break;
    case VideoProcAmp_Saturation:
        *pDefault = capBox->dcolour;
        break;
    default:
        FIXME("Not implemented %ld\n", Property);
        return E_NOTIMPL;
    }
    *pMin = 0;
    *pMax = 65535;
    *pSteppingDelta = 65536/256;
    *pCapsFlags = VideoProcAmp_Flags_Manual;
    return S_OK;
}

HRESULT qcap_driver_get_prop( Capture *capBox, long Property, long *lValue, long *Flags )
{
    TRACE("%p -> %ld %p %p\n", capBox, Property, lValue, Flags);

    switch (Property)
    {
    case VideoProcAmp_Brightness:
        *lValue = capBox->pict.brightness;
        break;
    case VideoProcAmp_Contrast:
        *lValue = capBox->pict.contrast;
        break;
    case VideoProcAmp_Hue:
        *lValue = capBox->pict.hue;
        break;
    case VideoProcAmp_Saturation:
        *lValue = capBox->pict.colour;
        break;
    default:
        FIXME("Not implemented %ld\n", Property);
        return E_NOTIMPL;
    }
    *Flags = VideoProcAmp_Flags_Manual;
    return S_OK;
}

HRESULT qcap_driver_set_prop(Capture *capBox, long Property, long lValue, long Flags)
{
    TRACE("%p -> %ld %ld %ld\n", capBox, Property, lValue, Flags);

    switch (Property)
    {
    case VideoProcAmp_Brightness:
        capBox->pict.brightness = lValue;
        break;
    case VideoProcAmp_Contrast:
        capBox->pict.contrast = lValue;
        break;
    case VideoProcAmp_Hue:
        capBox->pict.hue = lValue;
        break;
    case VideoProcAmp_Saturation:
        capBox->pict.colour = lValue;
        break;
    default:
        FIXME("Not implemented %ld\n", Property);
        return E_NOTIMPL;
    }

    if (xioctl(capBox->fd, VIDIOCSPICT, &capBox->pict) == -1)
    {
        ERR("ioctl(VIDIOCSPICT) failed (%d)\n",errno);
        return E_FAIL;
    }
    return S_OK;
}

static void renderer_RGB(Capture *capBox, LPBYTE bufferin, LPBYTE stream)
{
    int depth = renderlist_V4l[capBox->pict.palette].depth;
    int size = capBox->height * capBox->width * depth / 8;
    int pointer, offset;

    switch (depth)
    {
    case 24:
        memcpy(bufferin, stream, size);
        break;
    case 32:
        pointer = 0;
        offset = 1;
        while (pointer + offset <= size)
        {
            bufferin[pointer] = stream[pointer + offset];
            pointer++;
            bufferin[pointer] = stream[pointer + offset];
            pointer++;
            bufferin[pointer] = stream[pointer + offset];
            pointer++;
            offset++;
        }
        break;
    default:
        ERR("Unknown bit depth %d\n", depth);
        return;
    }
}

static void renderer_YUV(Capture *capBox, LPBYTE bufferin, LPBYTE stream)
{
    enum YUV_Format format;

    switch (capBox->pict.palette)
    {
    case  7: /* YUV422  -  same as YUYV */
    case  8: /* YUYV    */
        format = YUYV;
        break;
    case  9: /* UYVY    */
        format = UYVY;
        break;
    case 11: /* YUV411  */
        format = UYYVYY;
        break;
    case 13: /* YUV422P */
        format = YUVP_421;
        break;
    case 14: /* YUV411P */
        format = YUVP_441;
        break;
    case 15: /* YUV420P */
        format = YUVP_422;
        break;
    case 16: /* YUV410P */
        format = YUVP_444;
        break;
    default:
        ERR("Unknown palette %d\n", capBox->pict.palette);
        return;
    }
    YUV_To_RGB24(format, bufferin, stream, capBox->width, capBox->height);
}

static void Resize(Capture * capBox, LPBYTE output, LPBYTE input)
{
    /* the whole image needs to be reversed,
       because the dibs are messed up in windows */
    if (!capBox->swresize)
    {
        int depth = capBox->bitDepth / 8;
        int inoffset = 0, outoffset = capBox->height * capBox->width * depth;
        int ow = capBox->width * depth;
        while (outoffset > 0)
        {
            int x;
            outoffset -= ow;
            for (x = 0; x < ow; x++)
                output[outoffset + x] = input[inoffset + x];
            inoffset += ow;
        }
    }
    else
    {
        HDC dc_s, dc_d;
        HBITMAP bmp_s, bmp_d;
        int depth = capBox->bitDepth / 8;
        int inoffset = 0, outoffset = (capBox->outputheight) * capBox->outputwidth * depth;
        int ow = capBox->outputwidth * depth;
        LPBYTE myarray;

        /* FIXME: Improve software resizing: add error checks and optimize */

        myarray = CoTaskMemAlloc(capBox->outputwidth * capBox->outputheight * depth);
        dc_s = CreateCompatibleDC(NULL);
        dc_d = CreateCompatibleDC(NULL);
        bmp_s = CreateBitmap(capBox->width, capBox->height, 1, capBox->bitDepth, input);
        bmp_d = CreateBitmap(capBox->outputwidth, capBox->outputheight, 1, capBox->bitDepth, NULL);
        SelectObject(dc_s, bmp_s);
        SelectObject(dc_d, bmp_d);
        StretchBlt(dc_d, 0, 0, capBox->outputwidth, capBox->outputheight,
                   dc_s, 0, 0, capBox->width, capBox->height, SRCCOPY);
        GetBitmapBits(bmp_d, capBox->outputwidth * capBox->outputheight * depth, myarray);
        while (outoffset > 0)
        {
            int i;

            outoffset -= ow;
            for (i = 0; i < ow; i++)
                output[outoffset + i] = myarray[inoffset + i];
            inoffset += ow;
        }
        CoTaskMemFree(myarray);
        DeleteObject(dc_s);
        DeleteObject(dc_d);
        DeleteObject(bmp_s);
        DeleteObject(bmp_d);
    }
}

static void V4l_GetFrame(Capture * capBox, unsigned char ** pInput)
{
    if (capBox->pmap)
    {
        if (xioctl(capBox->fd, VIDIOCSYNC, &capBox->grab_buf[capBox->curframe]) == -1)
            WARN("Syncing ioctl failed: %d\n", errno);

        *pInput = capBox->pmap + capBox->gb_buffers.offsets[capBox->curframe];
    }
    else
    {
        int retval;
        while ((retval = read(capBox->fd, capBox->grab_data, capBox->imagesize)) == -1)
            if (errno != EAGAIN) break;
        if (retval == -1)
            WARN("Error occurred while reading from device: %s\n", strerror(errno));
        *pInput = (unsigned char*) capBox->grab_data;
    }
}

static void V4l_FreeFrame(Capture * capBox)
{
    TRACE("\n");
    if (capBox->mmap)
    {
        if (xioctl(capBox->fd, VIDIOCMCAPTURE, &capBox->grab_buf[capBox->curframe]) == -1)
           ERR("Freeing frame for capture failed: %s\n", strerror(errno));
    }
    if (++capBox->curframe == capBox->buffers)
        capBox->curframe = 0;
}

static DWORD WINAPI ReadThread(LPVOID lParam)
{
    Capture * capBox = (Capture *)lParam;
    HRESULT hr;
    IMediaSample *pSample = NULL;
    unsigned long framecount = 0;
    unsigned char *pTarget, *pInput, *pOutput;

    hr = V4l_Prepare(capBox);
    if (FAILED(hr))
        goto fail;

    pOutput = CoTaskMemAlloc(capBox->width * capBox->height * capBox->bitDepth / 8);
    capBox->curframe = 0;
    do {
        V4l_FreeFrame(capBox);
    } while (capBox->curframe != 0);

    while (1)
    {
        EnterCriticalSection(&capBox->CritSect);
        if (capBox->stopped)
            break;
        hr = OutputPin_GetDeliveryBuffer((OutputPin *)capBox->pOut, &pSample, NULL, NULL, 0);
        if (SUCCEEDED(hr))
        {
            int len;
            
            if (!capBox->swresize)
                len = capBox->height * capBox->width * capBox->bitDepth / 8;
            else
                len = capBox->outputheight * capBox->outputwidth * capBox->bitDepth / 8;
            IMediaSample_SetActualDataLength(pSample, len);

            len = IMediaSample_GetActualDataLength(pSample);
            TRACE("Data length: %d KB\n", len / 1024);

            IMediaSample_GetPointer(pSample, &pTarget);
            /* FIXME: Check return values.. */
            V4l_GetFrame(capBox, &pInput);
            capBox->renderer(capBox, pOutput, pInput);
            Resize(capBox, pTarget, pOutput);
            hr = OutputPin_SendSample((OutputPin *)capBox->pOut, pSample);
            TRACE("%p -> Frame %lu: %x\n", capBox, ++framecount, hr);
            IMediaSample_Release(pSample);
            V4l_FreeFrame(capBox);
        }
        LeaveCriticalSection(&capBox->CritSect);
        if (FAILED(hr) && hr != VFW_E_NOT_CONNECTED)
        {
            ERR("Received error: %x\n", hr);
            goto cfail;
        }
    }
    LeaveCriticalSection(&capBox->CritSect);
    CoTaskMemFree(pOutput);

    return 0;

cfail:
    CoTaskMemFree(pOutput);
    V4l_Unprepare(capBox);
    LeaveCriticalSection(&capBox->CritSect);

fail:
    capBox->thread = 0; capBox->stopped = 1;
    FIXME("Stop IFilterGraph\n");
    return 0;
}

HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
{
    HANDLE thread;
    HRESULT hr;

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

    if (*state == State_Running) return S_OK;

    EnterCriticalSection(&capBox->CritSect);

    capBox->stopped = 0;

    if (*state == State_Stopped)
    {
        *state = State_Running;
        if (!capBox->iscommitted++)
        {
            IMemAllocator * pAlloc = NULL;
            ALLOCATOR_PROPERTIES ap, actual;
            OutputPin *out;

            ap.cBuffers = 3;
            if (!capBox->swresize)
                ap.cbBuffer = capBox->width * capBox->height;
            else
                ap.cbBuffer = capBox->outputwidth * capBox->outputheight;
            ap.cbBuffer = (ap.cbBuffer * capBox->bitDepth) / 8;
            ap.cbAlign = 1;
            ap.cbPrefix = 0;

            out = (OutputPin *)capBox->pOut;
            hr = IMemInputPin_GetAllocator(out->pMemInputPin, &pAlloc);

            if (SUCCEEDED(hr))
                hr = IMemAllocator_SetProperties(pAlloc, &ap, &actual);

            if (SUCCEEDED(hr))
                hr = IMemAllocator_Commit(pAlloc);

            if (pAlloc)
                IMemAllocator_Release(pAlloc);

            TRACE("Committing allocator: %x\n", hr);
        }

        thread = CreateThread(NULL, 0, ReadThread, capBox, 0, NULL);
        if (thread)
        {
            capBox->thread = thread;
            SetThreadPriority(thread, THREAD_PRIORITY_LOWEST);
            LeaveCriticalSection(&capBox->CritSect);
            return S_OK;
        }
        ERR("Creating thread failed.. %u\n", GetLastError());
        LeaveCriticalSection(&capBox->CritSect);
        return E_FAIL;
    }

    ResumeThread(capBox->thread);
    *state = State_Running;
    LeaveCriticalSection(&capBox->CritSect);
    return S_OK;
}

HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
{
    TRACE("%p -> (%p)\n", capBox, state);     

    if (*state == State_Paused)
        return S_OK;
    if (*state == State_Stopped)
        qcap_driver_run(capBox, state);

    EnterCriticalSection(&capBox->CritSect);
    *state = State_Paused;
    SuspendThread(capBox->thread);
    LeaveCriticalSection(&capBox->CritSect);

    return S_OK;
}

HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
{
    TRACE("%p -> (%p)\n", capBox, state);

    if (*state == State_Stopped)
        return S_OK;

    EnterCriticalSection(&capBox->CritSect);

    if (capBox->thread)
    {
        if (*state == State_Paused)
            ResumeThread(capBox->thread);
        capBox->stopped = 1;
        capBox->thread = 0;
        if (capBox->iscommitted)
        {
            IMemInputPin *pMem = NULL;
            IMemAllocator * pAlloc = NULL;
            IPin *pConnect = NULL;
            HRESULT hr;

            capBox->iscommitted = 0;

            hr = IPin_ConnectedTo(capBox->pOut, &pConnect);

            if (SUCCEEDED(hr))
                hr = IPin_QueryInterface(pConnect, &IID_IMemInputPin, (void **) &pMem);

            if (SUCCEEDED(hr))
                hr = IMemInputPin_GetAllocator(pMem, &pAlloc);

            if (SUCCEEDED(hr))
                hr = IMemAllocator_Decommit(pAlloc);

            if (pAlloc)
                IMemAllocator_Release(pAlloc);

            if (pMem)
                IMemInputPin_Release(pMem);

            if (pConnect)
                IPin_Release(pConnect);

            if (hr != S_OK && hr != VFW_E_NOT_COMMITTED)
                WARN("Decommitting allocator: %x\n", hr);
        }
        V4l_Unprepare(capBox);
    }

    *state = State_Stopped;
    LeaveCriticalSection(&capBox->CritSect);
    return S_OK;
}

Capture * qcap_driver_init( IPin *pOut, USHORT card )
{
    Capture * capBox = NULL;
    char device[20];
    struct video_capability capa;
    struct video_picture pict;
    struct video_window window;

    YUV_Init();

    capBox = CoTaskMemAlloc(sizeof(Capture));
    if (!capBox)
        goto error;

    /* capBox->vtbl = &defboxVtbl; */

    InitializeCriticalSection( &capBox->CritSect );

    sprintf(device, "/dev/video%i", card);
    TRACE("opening %s\n", device);
    capBox->fd = open(device, O_RDWR | O_NONBLOCK);
    if (capBox->fd == -1)
    {
        WARN("open failed (%d)\n", errno);
        goto error;
    }

    memset(&capa, 0, sizeof(capa));

    if (xioctl(capBox->fd, VIDIOCGCAP, &capa) == -1)
    {
        WARN("ioctl(VIDIOCGCAP) failed (%d)\n", errno);
        goto error;
    }

    if (!(capa.type & VID_TYPE_CAPTURE))
    {
        WARN("not a video capture device\n");
        goto error;
    }

    TRACE("%d inputs on %s\n", capa.channels, capa.name );

    if (xioctl(capBox->fd, VIDIOCGPICT, &pict) == -1)
    {
        ERR("ioctl(VIDIOCGPICT) failed (%d)\n", errno );
        goto error;
    }

    TRACE("depth %d palette %d (%s) hue %d color %d contrast %d\n",
          pict.depth, pict.palette, renderlist_V4l[pict.palette].name,
          pict.hue, pict.colour, pict.contrast );

    capBox->dbrightness = pict.brightness;
    capBox->dcolour = pict.colour;
    capBox->dhue = pict.hue;
    capBox->dcontrast = pict.contrast;

    if (!renderlist_V4l[pict.palette].renderer)
    {
        int palet = pict.palette, i;

        TRACE("No renderer available for %s, falling back to defaults\n",
             renderlist_V4l[pict.palette].name);
        capBox->renderer = NULL;
        for (i = 0; fallback_V4l[i] >=0 ; i++)
        {
            int n = fallback_V4l[i];

            if (renderlist_V4l[n].renderer == NULL)
                continue;

            pict.depth = renderlist_V4l[n].depth;
            pict.palette = n;
            if (xioctl(capBox->fd, VIDIOCSPICT, &pict) == -1)
            {
                TRACE("Could not render with %s (%d)\n",
                      renderlist_V4l[n].name, n);
                continue;
            }
            TRACE("using renderer %s (%d)\n", 
                  renderlist_V4l[n].name, n);
            capBox->renderer = renderlist_V4l[n].renderer;
            break;
        }

        if (!capBox->renderer)
        {
            ERR("video format %s isn't available\n",
                 renderlist_V4l[palet].name);
            goto error;
        }
    }
    else
    {
        TRACE("Using the suggested format\n");
        capBox->renderer = renderlist_V4l[pict.palette].renderer;
    }
    memcpy(&capBox->pict, &pict, sizeof(struct video_picture));

    memset(&window, 0, sizeof(window));
    if (xioctl(capBox->fd, VIDIOCGWIN, &window) == -1)
    {
        WARN("VIDIOCGWIN failed (%d)\n", errno);
        goto error;
    }

    capBox->height = capBox->outputheight = window.height;
    capBox->width = capBox->outputwidth = window.width;
    capBox->swresize = FALSE;
    capBox->bitDepth = 24;
    capBox->pOut = pOut;
    capBox->fps = 3;
    capBox->stopped = 0;
    capBox->curframe = 0;
    capBox->iscommitted = 0;

    TRACE("format: %d bits - %d x %d\n", capBox->bitDepth, capBox->width, capBox->height);

    return (Capture*) capBox;

error:
    if (capBox)
        qcap_driver_destroy( (Capture*) capBox );

    return NULL;
}

#else

Capture * qcap_driver_init( IPin *pOut, USHORT card )
{
    const char msg[] = 
        "The v4l headers were not available at compile time,\n"
        "so video capture support is not available.\n";
    MESSAGE(msg);
    return NULL;
}

#define FAIL_WITH_ERR \
    ERR("v4l absent: shouldn't be called\n"); \
    return E_NOTIMPL

HRESULT qcap_driver_destroy(Capture *capBox)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_set_format(Capture *capBox, AM_MEDIA_TYPE * mT)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_get_format(Capture *capBox, AM_MEDIA_TYPE ** mT)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_get_prop_range( Capture *capBox, long Property, long *pMin,
          long *pMax, long *pSteppingDelta, long *pDefault, long *pCapsFlags )
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_get_prop(Capture *capBox, long Property, long *lValue, long *Flags)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_set_prop(Capture *capBox, long Property, long lValue, long Flags)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
{
    FAIL_WITH_ERR;
}

HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
{
    FAIL_WITH_ERR;
}

#endif /* HAVE_LINUX_VIDEODEV_H */
