/* SV module -- interface to the Indigo video board */

/* WARNING! This module is for hardware that we don't have any more,
   so it hasn't been tested.  It has been converted to the new coding
   style, and it is possible that this conversion has broken something
   -- user beware! */

#include <sys/time.h>
#include <svideo.h>
#include "Python.h"
#include "compile.h"
#include "yuv.h"                /* for YUV conversion functions */

typedef struct {
    PyObject_HEAD
    SV_nodeP ob_svideo;
    svCaptureInfo ob_info;
} svobject;

typedef struct {
    PyObject_HEAD
    void *ob_capture;
    int ob_mustunlock;
    svCaptureInfo ob_info;
    svobject *ob_svideo;
} captureobject;

static PyObject *SvError;               /* exception sv.error */

static PyObject *newcaptureobject(svobject *, void *, int);

/* Set a SV-specific error from svideo_errno and return NULL */
static PyObject *
sv_error(void)
{
    PyErr_SetString(SvError, svStrerror(svideo_errno));
    return NULL;
}

static PyObject *
svc_conversion(captureobject *self, PyObject *args, void (*function)(), float factor)
{
    PyObject *output;
    int invert;
    char* outstr;

    if (!PyArg_Parse(args, "i", &invert))
        return NULL;

    if (!(output = PyString_FromStringAndSize(
        NULL,
        (int)(self->ob_info.width * self->ob_info.height * factor))))
    {
        return NULL;
    }
    if (!(outstr = PyString_AsString(output))) {
        Py_DECREF(output);
        return NULL;
    }

    (*function)((boolean)invert, self->ob_capture,
                outstr,
                self->ob_info.width, self->ob_info.height);

    return output;
}

/*
 * 3 functions to convert from Starter Video YUV 4:1:1 format to
 * Compression Library 4:2:2 Duplicate Chroma format.
 */
static PyObject *
svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}

static PyObject *
svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args,
                          yuv_sv411_to_cl422dc_quartersize, 0.5);
}

static PyObject *
svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_YUV411_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args,
                          yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}

static PyObject *
svc_YUVtoRGB(captureobject *self, PyObject *args)
{
    switch (self->ob_info.format) {
    case SV_YUV411_FRAMES:
    case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
        break;
    default:
        PyErr_SetString(SvError, "data had bad format");
        return NULL;
    }
    return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}

static PyObject *
svc_RGB8toRGB32(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}

static PyObject *
svc_InterleaveFields(captureobject *self, PyObject *args)
{
    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }
    return svc_conversion(self, args, svInterleaveFields, 1.0);
}

static PyObject *
svc_GetFields(captureobject *self, PyObject *args)
{
    PyObject *f1 = NULL;
    PyObject *f2 = NULL;
    PyObject *ret = NULL;
    int fieldsize;
    char* obcapture;

    if (self->ob_info.format != SV_RGB8_FRAMES) {
        PyErr_SetString(SvError, "data has bad format");
        return NULL;
    }

    fieldsize = self->ob_info.width * self->ob_info.height / 2;
    obcapture = (char*)self->ob_capture;

    if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
        goto finally;
    if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
                                          fieldsize)))
        goto finally;
    ret = PyTuple_Pack(2, f1, f2);

  finally:
    Py_XDECREF(f1);
    Py_XDECREF(f2);
    return ret;
}

static PyObject *
svc_UnlockCaptureData(captureobject *self, PyObject *args)
{
    if (!PyArg_Parse(args, ""))
        return NULL;

    if (!self->ob_mustunlock) {
        PyErr_SetString(SvError, "buffer should not be unlocked");
        return NULL;
    }

    if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
        return sv_error();

    self->ob_mustunlock = 0;

    Py_INCREF(Py_None);
    return Py_None;
}

#ifdef USE_GL
#include <gl.h>

static PyObject *
svc_lrectwrite(captureobject *self, PyObject *args)
{
    Screencoord x1, x2, y1, y2;

    if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
        return NULL;

    lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);

    Py_INCREF(Py_None);
    return Py_None;
}
#endif

static PyObject *
svc_writefile(captureobject *self, PyObject *args)
{
    PyObject *file;
    int size;
    FILE* fp;

    if (!PyArg_Parse(args, "O", &file))
        return NULL;

    if (!PyFile_Check(file)) {
        PyErr_SetString(SvError, "not a file object");
        return NULL;
    }

    if (!(fp = PyFile_AsFile(file)))
        return NULL;

    size = self->ob_info.width * self->ob_info.height;

    if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
        PyErr_SetString(SvError, "writing failed");
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
svc_FindVisibleRegion(captureobject *self, PyObject *args)
{
    void *visible;
    int width;

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
                            self->ob_capture, &visible,
                            self->ob_info.width))
        return sv_error();

    if (visible == NULL) {
        PyErr_SetString(SvError, "data in wrong format");
        return NULL;
    }

    return newcaptureobject(self->ob_svideo, visible, 0);
}

static PyMethodDef capture_methods[] = {
    {"YUVtoRGB",                (PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
    {"RGB8toRGB32",             (PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
    {"InterleaveFields",        (PyCFunction)svc_InterleaveFields, METH_OLDARGS},
    {"UnlockCaptureData",       (PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
    {"FindVisibleRegion",       (PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
    {"GetFields",               (PyCFunction)svc_GetFields, METH_OLDARGS},
    {"YUVtoYUV422DC",           (PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
    {"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
    {"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
#ifdef USE_GL
    {"lrectwrite",              (PyCFunction)svc_lrectwrite, METH_OLDARGS},
#endif
    {"writefile",               (PyCFunction)svc_writefile, METH_OLDARGS},
    {NULL,                      NULL}           /* sentinel */
};

static void
capture_dealloc(captureobject *self)
{
    if (self->ob_capture != NULL) {
        if (self->ob_mustunlock)
            (void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
                                      self->ob_capture);
        self->ob_capture = NULL;
        Py_CLEAR(self->ob_svideo);
    }
    PyObject_Del(self);
}

static PyObject *
capture_getattr(svobject *self, char *name)
{
    return Py_FindMethod(capture_methods, (PyObject *)self, name);
}

PyTypeObject Capturetype = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,                                  /*ob_size*/
    "sv.capture",                       /*tp_name*/
    sizeof(captureobject),              /*tp_size*/
    0,                                  /*tp_itemsize*/
    /* methods */
    (destructor)capture_dealloc,        /*tp_dealloc*/
    0,                                  /*tp_print*/
    (getattrfunc)capture_getattr,       /*tp_getattr*/
    0,                                  /*tp_setattr*/
    0,                                  /*tp_compare*/
    0,                                  /*tp_repr*/
};

static PyObject *
newcaptureobject(svobject *self, void *ptr, int mustunlock)
{
    captureobject *p;

    p = PyObject_New(captureobject, &Capturetype);
    if (p == NULL)
        return NULL;
    p->ob_svideo = self;
    Py_INCREF(self);
    p->ob_capture = ptr;
    p->ob_mustunlock = mustunlock;
    p->ob_info = self->ob_info;
    return (PyObject *) p;
}

static PyObject *
sv_GetCaptureData(svobject *self, PyObject *args)
{
    void *ptr;
    long fieldID;
    PyObject *res, *c;

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
        return sv_error();

    if (ptr == NULL) {
        PyErr_SetString(SvError, "no data available");
        return NULL;
    }

    c = newcaptureobject(self, ptr, 1);
    if (c == NULL)
        return NULL;
    res = Py_BuildValue("(Oi)", c, fieldID);
    Py_DECREF(c);
    return res;
}

static PyObject *
sv_BindGLWindow(svobject *self, PyObject *args)
{
    long wid;
    int mode;

    if (!PyArg_Parse(args, "(ii)", &wid, &mode))
        return NULL;

    if (svBindGLWindow(self->ob_svideo, wid, mode))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_EndContinuousCapture(svobject *self, PyObject *args)
{

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svEndContinuousCapture(self->ob_svideo))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_IsVideoDisplayed(svobject *self, PyObject *args)
{
    int v;

    if (!PyArg_Parse(args, ""))
        return NULL;

    v = svIsVideoDisplayed(self->ob_svideo);
    if (v == -1)
        return sv_error();

    return PyInt_FromLong((long) v);
}

static PyObject *
sv_OutputOffset(svobject *self, PyObject *args)
{
    int x_offset;
    int y_offset;

    if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
        return NULL;

    if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_PutFrame(svobject *self, PyObject *args)
{
    char *buffer;

    if (!PyArg_Parse(args, "s", &buffer))
        return NULL;

    if (svPutFrame(self->ob_svideo, buffer))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_QuerySize(svobject *self, PyObject *args)
{
    int w;
    int h;
    int rw;
    int rh;

    if (!PyArg_Parse(args, "(ii)", &w, &h))
        return NULL;

    if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
        return sv_error();

    return Py_BuildValue("(ii)", (long) rw, (long) rh);
}

static PyObject *
sv_SetSize(svobject *self, PyObject *args)
{
    int w;
    int h;

    if (!PyArg_Parse(args, "(ii)", &w, &h))
        return NULL;

    if (svSetSize(self->ob_svideo, w, h))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_SetStdDefaults(svobject *self, PyObject *args)
{

    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svSetStdDefaults(self->ob_svideo))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_UseExclusive(svobject *self, PyObject *args)
{
    boolean onoff;
    int mode;

    if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
        return NULL;

    if (svUseExclusive(self->ob_svideo, onoff, mode))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_WindowOffset(svobject *self, PyObject *args)
{
    int x_offset;
    int y_offset;

    if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
        return NULL;

    if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
        return sv_error();

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
sv_CaptureBurst(svobject *self, PyObject *args)
{
    int bytes, i;
    svCaptureInfo info;
    void *bitvector = NULL;
    PyObject *videodata = NULL;
    PyObject *bitvecobj = NULL;
    PyObject *res = NULL;
    static PyObject *evenitem, *odditem;

    if (!PyArg_Parse(args, "(iiiii)", &info.format,
                     &info.width, &info.height,
                     &info.size, &info.samplingrate))
        return NULL;

    switch (info.format) {
    case SV_RGB8_FRAMES:
        bitvector = malloc(SV_BITVEC_SIZE(info.size));
        break;
    case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
        break;
    default:
        PyErr_SetString(SvError, "illegal format specified");
        return NULL;
    }

    if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
        res = sv_error();
        goto finally;
    }

    if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
        goto finally;

    /* XXX -- need to do something about the bitvector */
    {
        char* str = PyString_AsString(videodata);
        if (!str)
            goto finally;

        if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
            res = sv_error();
            goto finally;
        }
    }

    if (bitvector) {
        if (evenitem == NULL) {
            if (!(evenitem = PyInt_FromLong(0)))
                goto finally;
        }
        if (odditem == NULL) {
            if (!(odditem = PyInt_FromLong(1)))
                goto finally;
        }
        if (!(bitvecobj = PyTuple_New(2 * info.size)))
            goto finally;

        for (i = 0; i < 2 * info.size; i++) {
            int sts;

            if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
                Py_INCREF(evenitem);
                sts = PyTuple_SetItem(bitvecobj, i, evenitem);
            } else {
                Py_INCREF(odditem);
                sts = PyTuple_SetItem(bitvecobj, i, odditem);
            }
            if (sts < 0)
                goto finally;
        }
    } else {
        bitvecobj = Py_None;
        Py_INCREF(Py_None);
    }

    res = Py_BuildValue("((iiiii)OO)", info.format,
                        info.width, info.height,
                        info.size, info.samplingrate,
                        videodata, bitvecobj);

  finally:
    if (bitvector)
        free(bitvector);

    Py_XDECREF(videodata);
    Py_XDECREF(bitvecobj);
    return res;
}

static PyObject *
sv_CaptureOneFrame(svobject *self, PyObject *args)
{
    svCaptureInfo info;
    int format, width, height;
    int bytes;
    PyObject *videodata = NULL;
    PyObject *res = NULL;
    char *str;

    if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
        return NULL;

    info.format = format;
    info.width = width;
    info.height = height;
    info.size = 0;
    info.samplingrate = 0;
    if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
        return sv_error();

    if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
        return NULL;

    str = PyString_AsString(videodata);
    if (!str)
        goto finally;

    if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
        res = sv_error();
        goto finally;
    }

    res = Py_BuildValue("(iiO)", width, height, videodata);

  finally:
    Py_XDECREF(videodata);
    return res;
}

static PyObject *
sv_InitContinuousCapture(svobject *self, PyObject *args)
{
    svCaptureInfo info;

    if (!PyArg_Parse(args, "(iiiii)", &info.format,
                     &info.width, &info.height,
                     &info.size, &info.samplingrate))
        return NULL;

    if (svInitContinuousCapture(self->ob_svideo, &info))
        return sv_error();

    self->ob_info = info;

    return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
                         info.size, info.samplingrate);
}

static PyObject *
sv_LoadMap(svobject *self, PyObject *args)
{
    PyObject *rgb;
    PyObject *res = NULL;
    rgb_tuple *mapp = NULL;
    int maptype;
    int i, j;                                /* indices */

    if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
        return NULL;

    if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
        PyErr_BadArgument();
        return NULL;
    }

    if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
        return PyErr_NoMemory();

    for (i = 0; i < 256; i++) {
        PyObject* v = PyList_GetItem(rgb, i);
        if (!v)
            goto finally;

        if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
            PyErr_BadArgument();
            goto finally;
        }
        for (j = 0; j < 3; j++) {
            PyObject* cell = PyTuple_GetItem(v, j);
            if (!cell)
                goto finally;

            if (!_PyAnyInt_Check(cell)) {
                PyErr_BadArgument();
                goto finally;
            }
            switch (j) {
            case 0: mapp[i].red = PyInt_AsLong(cell); break;
            case 1: mapp[i].blue = PyInt_AsLong(cell); break;
            case 2: mapp[i].green = PyInt_AsLong(cell); break;
            }
            if (PyErr_Occurred())
                goto finally;
        }
    }

    if (svLoadMap(self->ob_svideo, maptype, mapp)) {
        res = sv_error();
        goto finally;
    }

    Py_INCREF(Py_None);
    res = Py_None;

  finally:
    PyMem_DEL(mapp);
    return res;
}

static PyObject *
sv_CloseVideo(svobject *self, PyObject *args)
{
    if (!PyArg_Parse(args, ""))
        return NULL;

    if (svCloseVideo(self->ob_svideo))
        return sv_error();

    self->ob_svideo = NULL;
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
doParams(svobject *self, PyObject *args,
         int (*func)(SV_nodeP, long *, int), int modified)
{
    PyObject *list;
    PyObject *res = NULL;
    long *PVbuffer = NULL;
    long length;
    int i;

    if (!PyArg_Parse(args, "O", &list))
        return NULL;

    if (!PyList_Check(list)) {
        PyErr_BadArgument();
        return NULL;
    }

    if ((length = PyList_Size(list)) < 0)
        return NULL;

    PVbuffer = PyMem_NEW(long, length);
    if (PVbuffer == NULL)
        return PyErr_NoMemory();

    for (i = 0; i < length; i++) {
        PyObject *v = PyList_GetItem(list, i);
        if (!v)
            goto finally;

        if (!_PyAnyInt_Check(v)) {
            PyErr_BadArgument();
            goto finally;
        }
        PVbuffer[i] = PyInt_AsLong(v);
        /* can't just test the return value, because what if the
           value was -1?!
        */
        if (PVbuffer[i] == -1 && PyErr_Occurred())
            goto finally;
    }

    if ((*func)(self->ob_svideo, PVbuffer, length)) {
        res = sv_error();
        goto finally;
    }

    if (modified) {
        for (i = 0; i < length; i++) {
            PyObject* v = PyInt_FromLong(PVbuffer[i]);
            if (!v || PyList_SetItem(list, i, v) < 0)
                goto finally;
        }
    }

    Py_INCREF(Py_None);
    res = Py_None;

  finally:
    PyMem_DEL(PVbuffer);
    return res;
}

static PyObject *
sv_GetParam(PyObject *self, PyObject *args)
{
    return doParams(self, args, svGetParam, 1);
}

static PyObject *
sv_GetParamRange(PyObject *self, PyObject *args)
{
    return doParams(self, args, svGetParamRange, 1);
}

static PyObject *
sv_SetParam(PyObject *self, PyObject *args)
{
    return doParams(self, args, svSetParam, 0);
}

static PyMethodDef svideo_methods[] = {
    {"BindGLWindow",            (PyCFunction)sv_BindGLWindow, METH_OLDARGS},
    {"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
    {"IsVideoDisplayed",        (PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
    {"OutputOffset",            (PyCFunction)sv_OutputOffset, METH_OLDARGS},
    {"PutFrame",                (PyCFunction)sv_PutFrame, METH_OLDARGS},
    {"QuerySize",               (PyCFunction)sv_QuerySize, METH_OLDARGS},
    {"SetSize",                 (PyCFunction)sv_SetSize, METH_OLDARGS},
    {"SetStdDefaults",          (PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
    {"UseExclusive",            (PyCFunction)sv_UseExclusive, METH_OLDARGS},
    {"WindowOffset",            (PyCFunction)sv_WindowOffset, METH_OLDARGS},
    {"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
    {"CaptureBurst",            (PyCFunction)sv_CaptureBurst, METH_OLDARGS},
    {"CaptureOneFrame",         (PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
    {"GetCaptureData",          (PyCFunction)sv_GetCaptureData, METH_OLDARGS},
    {"CloseVideo",              (PyCFunction)sv_CloseVideo, METH_OLDARGS},
    {"LoadMap",                 (PyCFunction)sv_LoadMap, METH_OLDARGS},
    {"GetParam",                (PyCFunction)sv_GetParam, METH_OLDARGS},
    {"GetParamRange",           (PyCFunction)sv_GetParamRange, METH_OLDARGS},
    {"SetParam",                (PyCFunction)sv_SetParam, METH_OLDARGS},
    {NULL,                      NULL}           /* sentinel */
};

static PyObject *
sv_conversion(PyObject *self, PyObject *args, void (*function)(),
              int inputfactor, float factor)
{
    int invert, width, height, inputlength;
    char *input, *str;
    PyObject *output;

    if (!PyArg_Parse(args, "(is#ii)", &invert,
                     &input, &inputlength, &width, &height))
        return NULL;

    if (width * height * inputfactor > inputlength) {
        PyErr_SetString(SvError, "input buffer not long enough");
        return NULL;
    }

    if (!(output = PyString_FromStringAndSize(NULL,
                                          (int)(width * height * factor))))
        return NULL;

    str = PyString_AsString(output);
    if (!str) {
        Py_DECREF(output);
        return NULL;
    }
    (*function)(invert, input, str, width, height);

    return output;
}

static PyObject *
sv_InterleaveFields(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

static PyObject *
sv_RGB8toRGB32(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}

static PyObject *
sv_YUVtoRGB(PyObject *self, PyObject *args)
{
    return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}

static void
svideo_dealloc(svobject *self)
{
    if (self->ob_svideo != NULL)
        (void) svCloseVideo(self->ob_svideo);
    PyObject_Del(self);
}

static PyObject *
svideo_getattr(svobject *self, char *name)
{
    return Py_FindMethod(svideo_methods, (PyObject *)self, name);
}

PyTypeObject Svtype = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,                          /*ob_size*/
    "sv.sv",                    /*tp_name*/
    sizeof(svobject),           /*tp_size*/
    0,                          /*tp_itemsize*/
    /* methods */
    (destructor)svideo_dealloc, /*tp_dealloc*/
    0,                          /*tp_print*/
    (getattrfunc)svideo_getattr, /*tp_getattr*/
    0,                          /*tp_setattr*/
    0,                          /*tp_compare*/
    0,                          /*tp_repr*/
};

static PyObject *
newsvobject(SV_nodeP svp)
{
    svobject *p;

    p = PyObject_New(svobject, &Svtype);
    if (p == NULL)
        return NULL;
    p->ob_svideo = svp;
    p->ob_info.format = 0;
    p->ob_info.size = 0;
    p->ob_info.width = 0;
    p->ob_info.height = 0;
    p->ob_info.samplingrate = 0;
    return (PyObject *) p;
}

static PyObject *
sv_OpenVideo(PyObject *self, PyObject *args)
{
    SV_nodeP svp;

    if (!PyArg_Parse(args, ""))
        return NULL;

    svp = svOpenVideo();
    if (svp == NULL)
        return sv_error();

    return newsvobject(svp);
}

static PyMethodDef sv_methods[] = {
    {"InterleaveFields",        (PyCFunction)sv_InterleaveFields, METH_OLDARGS},
    {"RGB8toRGB32",             (PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
    {"YUVtoRGB",                (PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
    {"OpenVideo",               (PyCFunction)sv_OpenVideo, METH_OLDARGS},
    {NULL,                      NULL}   /* Sentinel */
};

void
initsv(void)
{
    PyObject *m, *d;

    if (PyErr_WarnPy3k("the sv module has been removed in "
                       "Python 3.0", 2) < 0)
        return;

    m = Py_InitModule("sv", sv_methods);
    if (m == NULL)
        return;
    d = PyModule_GetDict(m);

    SvError = PyErr_NewException("sv.error", NULL, NULL);
    if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
        return;
}
