Home | History | Annotate | Download | only in Modules
      1 /* SV module -- interface to the Indigo video board */
      2 
      3 /* WARNING! This module is for hardware that we don't have any more,
      4    so it hasn't been tested.  It has been converted to the new coding
      5    style, and it is possible that this conversion has broken something
      6    -- user beware! */
      7 
      8 #include <sys/time.h>
      9 #include <svideo.h>
     10 #include "Python.h"
     11 #include "compile.h"
     12 #include "yuv.h"                /* for YUV conversion functions */
     13 
     14 typedef struct {
     15     PyObject_HEAD
     16     SV_nodeP ob_svideo;
     17     svCaptureInfo ob_info;
     18 } svobject;
     19 
     20 typedef struct {
     21     PyObject_HEAD
     22     void *ob_capture;
     23     int ob_mustunlock;
     24     svCaptureInfo ob_info;
     25     svobject *ob_svideo;
     26 } captureobject;
     27 
     28 static PyObject *SvError;               /* exception sv.error */
     29 
     30 static PyObject *newcaptureobject(svobject *, void *, int);
     31 
     32 /* Set a SV-specific error from svideo_errno and return NULL */
     33 static PyObject *
     34 sv_error(void)
     35 {
     36     PyErr_SetString(SvError, svStrerror(svideo_errno));
     37     return NULL;
     38 }
     39 
     40 static PyObject *
     41 svc_conversion(captureobject *self, PyObject *args, void (*function)(), float factor)
     42 {
     43     PyObject *output;
     44     int invert;
     45     char* outstr;
     46 
     47     if (!PyArg_Parse(args, "i", &invert))
     48         return NULL;
     49 
     50     if (!(output = PyString_FromStringAndSize(
     51         NULL,
     52         (int)(self->ob_info.width * self->ob_info.height * factor))))
     53     {
     54         return NULL;
     55     }
     56     if (!(outstr = PyString_AsString(output))) {
     57         Py_DECREF(output);
     58         return NULL;
     59     }
     60 
     61     (*function)((boolean)invert, self->ob_capture,
     62                 outstr,
     63                 self->ob_info.width, self->ob_info.height);
     64 
     65     return output;
     66 }
     67 
     68 /*
     69  * 3 functions to convert from Starter Video YUV 4:1:1 format to
     70  * Compression Library 4:2:2 Duplicate Chroma format.
     71  */
     72 static PyObject *
     73 svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
     74 {
     75     if (self->ob_info.format != SV_YUV411_FRAMES) {
     76         PyErr_SetString(SvError, "data has bad format");
     77         return NULL;
     78     }
     79     return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
     80 }
     81 
     82 static PyObject *
     83 svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
     84 {
     85     if (self->ob_info.format != SV_YUV411_FRAMES) {
     86         PyErr_SetString(SvError, "data has bad format");
     87         return NULL;
     88     }
     89     return svc_conversion(self, args,
     90                           yuv_sv411_to_cl422dc_quartersize, 0.5);
     91 }
     92 
     93 static PyObject *
     94 svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
     95 {
     96     if (self->ob_info.format != SV_YUV411_FRAMES) {
     97         PyErr_SetString(SvError, "data has bad format");
     98         return NULL;
     99     }
    100     return svc_conversion(self, args,
    101                           yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
    102 }
    103 
    104 static PyObject *
    105 svc_YUVtoRGB(captureobject *self, PyObject *args)
    106 {
    107     switch (self->ob_info.format) {
    108     case SV_YUV411_FRAMES:
    109     case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
    110         break;
    111     default:
    112         PyErr_SetString(SvError, "data had bad format");
    113         return NULL;
    114     }
    115     return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
    116 }
    117 
    118 static PyObject *
    119 svc_RGB8toRGB32(captureobject *self, PyObject *args)
    120 {
    121     if (self->ob_info.format != SV_RGB8_FRAMES) {
    122         PyErr_SetString(SvError, "data has bad format");
    123         return NULL;
    124     }
    125     return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
    126 }
    127 
    128 static PyObject *
    129 svc_InterleaveFields(captureobject *self, PyObject *args)
    130 {
    131     if (self->ob_info.format != SV_RGB8_FRAMES) {
    132         PyErr_SetString(SvError, "data has bad format");
    133         return NULL;
    134     }
    135     return svc_conversion(self, args, svInterleaveFields, 1.0);
    136 }
    137 
    138 static PyObject *
    139 svc_GetFields(captureobject *self, PyObject *args)
    140 {
    141     PyObject *f1 = NULL;
    142     PyObject *f2 = NULL;
    143     PyObject *ret = NULL;
    144     int fieldsize;
    145     char* obcapture;
    146 
    147     if (self->ob_info.format != SV_RGB8_FRAMES) {
    148         PyErr_SetString(SvError, "data has bad format");
    149         return NULL;
    150     }
    151 
    152     fieldsize = self->ob_info.width * self->ob_info.height / 2;
    153     obcapture = (char*)self->ob_capture;
    154 
    155     if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
    156         goto finally;
    157     if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
    158                                           fieldsize)))
    159         goto finally;
    160     ret = PyTuple_Pack(2, f1, f2);
    161 
    162   finally:
    163     Py_XDECREF(f1);
    164     Py_XDECREF(f2);
    165     return ret;
    166 }
    167 
    168 static PyObject *
    169 svc_UnlockCaptureData(captureobject *self, PyObject *args)
    170 {
    171     if (!PyArg_Parse(args, ""))
    172         return NULL;
    173 
    174     if (!self->ob_mustunlock) {
    175         PyErr_SetString(SvError, "buffer should not be unlocked");
    176         return NULL;
    177     }
    178 
    179     if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
    180         return sv_error();
    181 
    182     self->ob_mustunlock = 0;
    183 
    184     Py_INCREF(Py_None);
    185     return Py_None;
    186 }
    187 
    188 #ifdef USE_GL
    189 #include <gl.h>
    190 
    191 static PyObject *
    192 svc_lrectwrite(captureobject *self, PyObject *args)
    193 {
    194     Screencoord x1, x2, y1, y2;
    195 
    196     if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
    197         return NULL;
    198 
    199     lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);
    200 
    201     Py_INCREF(Py_None);
    202     return Py_None;
    203 }
    204 #endif
    205 
    206 static PyObject *
    207 svc_writefile(captureobject *self, PyObject *args)
    208 {
    209     PyObject *file;
    210     int size;
    211     FILE* fp;
    212 
    213     if (!PyArg_Parse(args, "O", &file))
    214         return NULL;
    215 
    216     if (!PyFile_Check(file)) {
    217         PyErr_SetString(SvError, "not a file object");
    218         return NULL;
    219     }
    220 
    221     if (!(fp = PyFile_AsFile(file)))
    222         return NULL;
    223 
    224     size = self->ob_info.width * self->ob_info.height;
    225 
    226     if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
    227         PyErr_SetString(SvError, "writing failed");
    228         return NULL;
    229     }
    230 
    231     Py_INCREF(Py_None);
    232     return Py_None;
    233 }
    234 
    235 static PyObject *
    236 svc_FindVisibleRegion(captureobject *self, PyObject *args)
    237 {
    238     void *visible;
    239     int width;
    240 
    241     if (!PyArg_Parse(args, ""))
    242         return NULL;
    243 
    244     if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
    245                             self->ob_capture, &visible,
    246                             self->ob_info.width))
    247         return sv_error();
    248 
    249     if (visible == NULL) {
    250         PyErr_SetString(SvError, "data in wrong format");
    251         return NULL;
    252     }
    253 
    254     return newcaptureobject(self->ob_svideo, visible, 0);
    255 }
    256 
    257 static PyMethodDef capture_methods[] = {
    258     {"YUVtoRGB",                (PyCFunction)svc_YUVtoRGB, METH_OLDARGS},
    259     {"RGB8toRGB32",             (PyCFunction)svc_RGB8toRGB32, METH_OLDARGS},
    260     {"InterleaveFields",        (PyCFunction)svc_InterleaveFields, METH_OLDARGS},
    261     {"UnlockCaptureData",       (PyCFunction)svc_UnlockCaptureData, METH_OLDARGS},
    262     {"FindVisibleRegion",       (PyCFunction)svc_FindVisibleRegion, METH_OLDARGS},
    263     {"GetFields",               (PyCFunction)svc_GetFields, METH_OLDARGS},
    264     {"YUVtoYUV422DC",           (PyCFunction)svc_YUVtoYUV422DC, METH_OLDARGS},
    265     {"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter, METH_OLDARGS},
    266     {"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth, METH_OLDARGS},
    267 #ifdef USE_GL
    268     {"lrectwrite",              (PyCFunction)svc_lrectwrite, METH_OLDARGS},
    269 #endif
    270     {"writefile",               (PyCFunction)svc_writefile, METH_OLDARGS},
    271     {NULL,                      NULL}           /* sentinel */
    272 };
    273 
    274 static void
    275 capture_dealloc(captureobject *self)
    276 {
    277     if (self->ob_capture != NULL) {
    278         if (self->ob_mustunlock)
    279             (void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
    280                                       self->ob_capture);
    281         self->ob_capture = NULL;
    282         Py_CLEAR(self->ob_svideo);
    283     }
    284     PyObject_Del(self);
    285 }
    286 
    287 static PyObject *
    288 capture_getattr(svobject *self, char *name)
    289 {
    290     return Py_FindMethod(capture_methods, (PyObject *)self, name);
    291 }
    292 
    293 PyTypeObject Capturetype = {
    294     PyObject_HEAD_INIT(&PyType_Type)
    295     0,                                  /*ob_size*/
    296     "sv.capture",                       /*tp_name*/
    297     sizeof(captureobject),              /*tp_size*/
    298     0,                                  /*tp_itemsize*/
    299     /* methods */
    300     (destructor)capture_dealloc,        /*tp_dealloc*/
    301     0,                                  /*tp_print*/
    302     (getattrfunc)capture_getattr,       /*tp_getattr*/
    303     0,                                  /*tp_setattr*/
    304     0,                                  /*tp_compare*/
    305     0,                                  /*tp_repr*/
    306 };
    307 
    308 static PyObject *
    309 newcaptureobject(svobject *self, void *ptr, int mustunlock)
    310 {
    311     captureobject *p;
    312 
    313     p = PyObject_New(captureobject, &Capturetype);
    314     if (p == NULL)
    315         return NULL;
    316     p->ob_svideo = self;
    317     Py_INCREF(self);
    318     p->ob_capture = ptr;
    319     p->ob_mustunlock = mustunlock;
    320     p->ob_info = self->ob_info;
    321     return (PyObject *) p;
    322 }
    323 
    324 static PyObject *
    325 sv_GetCaptureData(svobject *self, PyObject *args)
    326 {
    327     void *ptr;
    328     long fieldID;
    329     PyObject *res, *c;
    330 
    331     if (!PyArg_Parse(args, ""))
    332         return NULL;
    333 
    334     if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
    335         return sv_error();
    336 
    337     if (ptr == NULL) {
    338         PyErr_SetString(SvError, "no data available");
    339         return NULL;
    340     }
    341 
    342     c = newcaptureobject(self, ptr, 1);
    343     if (c == NULL)
    344         return NULL;
    345     res = Py_BuildValue("(Oi)", c, fieldID);
    346     Py_DECREF(c);
    347     return res;
    348 }
    349 
    350 static PyObject *
    351 sv_BindGLWindow(svobject *self, PyObject *args)
    352 {
    353     long wid;
    354     int mode;
    355 
    356     if (!PyArg_Parse(args, "(ii)", &wid, &mode))
    357         return NULL;
    358 
    359     if (svBindGLWindow(self->ob_svideo, wid, mode))
    360         return sv_error();
    361 
    362     Py_INCREF(Py_None);
    363     return Py_None;
    364 }
    365 
    366 static PyObject *
    367 sv_EndContinuousCapture(svobject *self, PyObject *args)
    368 {
    369 
    370     if (!PyArg_Parse(args, ""))
    371         return NULL;
    372 
    373     if (svEndContinuousCapture(self->ob_svideo))
    374         return sv_error();
    375 
    376     Py_INCREF(Py_None);
    377     return Py_None;
    378 }
    379 
    380 static PyObject *
    381 sv_IsVideoDisplayed(svobject *self, PyObject *args)
    382 {
    383     int v;
    384 
    385     if (!PyArg_Parse(args, ""))
    386         return NULL;
    387 
    388     v = svIsVideoDisplayed(self->ob_svideo);
    389     if (v == -1)
    390         return sv_error();
    391 
    392     return PyInt_FromLong((long) v);
    393 }
    394 
    395 static PyObject *
    396 sv_OutputOffset(svobject *self, PyObject *args)
    397 {
    398     int x_offset;
    399     int y_offset;
    400 
    401     if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
    402         return NULL;
    403 
    404     if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
    405         return sv_error();
    406 
    407     Py_INCREF(Py_None);
    408     return Py_None;
    409 }
    410 
    411 static PyObject *
    412 sv_PutFrame(svobject *self, PyObject *args)
    413 {
    414     char *buffer;
    415 
    416     if (!PyArg_Parse(args, "s", &buffer))
    417         return NULL;
    418 
    419     if (svPutFrame(self->ob_svideo, buffer))
    420         return sv_error();
    421 
    422     Py_INCREF(Py_None);
    423     return Py_None;
    424 }
    425 
    426 static PyObject *
    427 sv_QuerySize(svobject *self, PyObject *args)
    428 {
    429     int w;
    430     int h;
    431     int rw;
    432     int rh;
    433 
    434     if (!PyArg_Parse(args, "(ii)", &w, &h))
    435         return NULL;
    436 
    437     if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
    438         return sv_error();
    439 
    440     return Py_BuildValue("(ii)", (long) rw, (long) rh);
    441 }
    442 
    443 static PyObject *
    444 sv_SetSize(svobject *self, PyObject *args)
    445 {
    446     int w;
    447     int h;
    448 
    449     if (!PyArg_Parse(args, "(ii)", &w, &h))
    450         return NULL;
    451 
    452     if (svSetSize(self->ob_svideo, w, h))
    453         return sv_error();
    454 
    455     Py_INCREF(Py_None);
    456     return Py_None;
    457 }
    458 
    459 static PyObject *
    460 sv_SetStdDefaults(svobject *self, PyObject *args)
    461 {
    462 
    463     if (!PyArg_Parse(args, ""))
    464         return NULL;
    465 
    466     if (svSetStdDefaults(self->ob_svideo))
    467         return sv_error();
    468 
    469     Py_INCREF(Py_None);
    470     return Py_None;
    471 }
    472 
    473 static PyObject *
    474 sv_UseExclusive(svobject *self, PyObject *args)
    475 {
    476     boolean onoff;
    477     int mode;
    478 
    479     if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
    480         return NULL;
    481 
    482     if (svUseExclusive(self->ob_svideo, onoff, mode))
    483         return sv_error();
    484 
    485     Py_INCREF(Py_None);
    486     return Py_None;
    487 }
    488 
    489 static PyObject *
    490 sv_WindowOffset(svobject *self, PyObject *args)
    491 {
    492     int x_offset;
    493     int y_offset;
    494 
    495     if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
    496         return NULL;
    497 
    498     if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
    499         return sv_error();
    500 
    501     Py_INCREF(Py_None);
    502     return Py_None;
    503 }
    504 
    505 static PyObject *
    506 sv_CaptureBurst(svobject *self, PyObject *args)
    507 {
    508     int bytes, i;
    509     svCaptureInfo info;
    510     void *bitvector = NULL;
    511     PyObject *videodata = NULL;
    512     PyObject *bitvecobj = NULL;
    513     PyObject *res = NULL;
    514     static PyObject *evenitem, *odditem;
    515 
    516     if (!PyArg_Parse(args, "(iiiii)", &info.format,
    517                      &info.width, &info.height,
    518                      &info.size, &info.samplingrate))
    519         return NULL;
    520 
    521     switch (info.format) {
    522     case SV_RGB8_FRAMES:
    523         bitvector = malloc(SV_BITVEC_SIZE(info.size));
    524         break;
    525     case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
    526         break;
    527     default:
    528         PyErr_SetString(SvError, "illegal format specified");
    529         return NULL;
    530     }
    531 
    532     if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
    533         res = sv_error();
    534         goto finally;
    535     }
    536 
    537     if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
    538         goto finally;
    539 
    540     /* XXX -- need to do something about the bitvector */
    541     {
    542         char* str = PyString_AsString(videodata);
    543         if (!str)
    544             goto finally;
    545 
    546         if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
    547             res = sv_error();
    548             goto finally;
    549         }
    550     }
    551 
    552     if (bitvector) {
    553         if (evenitem == NULL) {
    554             if (!(evenitem = PyInt_FromLong(0)))
    555                 goto finally;
    556         }
    557         if (odditem == NULL) {
    558             if (!(odditem = PyInt_FromLong(1)))
    559                 goto finally;
    560         }
    561         if (!(bitvecobj = PyTuple_New(2 * info.size)))
    562             goto finally;
    563 
    564         for (i = 0; i < 2 * info.size; i++) {
    565             int sts;
    566 
    567             if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
    568                 Py_INCREF(evenitem);
    569                 sts = PyTuple_SetItem(bitvecobj, i, evenitem);
    570             } else {
    571                 Py_INCREF(odditem);
    572                 sts = PyTuple_SetItem(bitvecobj, i, odditem);
    573             }
    574             if (sts < 0)
    575                 goto finally;
    576         }
    577     } else {
    578         bitvecobj = Py_None;
    579         Py_INCREF(Py_None);
    580     }
    581 
    582     res = Py_BuildValue("((iiiii)OO)", info.format,
    583                         info.width, info.height,
    584                         info.size, info.samplingrate,
    585                         videodata, bitvecobj);
    586 
    587   finally:
    588     if (bitvector)
    589         free(bitvector);
    590 
    591     Py_XDECREF(videodata);
    592     Py_XDECREF(bitvecobj);
    593     return res;
    594 }
    595 
    596 static PyObject *
    597 sv_CaptureOneFrame(svobject *self, PyObject *args)
    598 {
    599     svCaptureInfo info;
    600     int format, width, height;
    601     int bytes;
    602     PyObject *videodata = NULL;
    603     PyObject *res = NULL;
    604     char *str;
    605 
    606     if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
    607         return NULL;
    608 
    609     info.format = format;
    610     info.width = width;
    611     info.height = height;
    612     info.size = 0;
    613     info.samplingrate = 0;
    614     if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
    615         return sv_error();
    616 
    617     if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
    618         return NULL;
    619 
    620     str = PyString_AsString(videodata);
    621     if (!str)
    622         goto finally;
    623 
    624     if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
    625         res = sv_error();
    626         goto finally;
    627     }
    628 
    629     res = Py_BuildValue("(iiO)", width, height, videodata);
    630 
    631   finally:
    632     Py_XDECREF(videodata);
    633     return res;
    634 }
    635 
    636 static PyObject *
    637 sv_InitContinuousCapture(svobject *self, PyObject *args)
    638 {
    639     svCaptureInfo info;
    640 
    641     if (!PyArg_Parse(args, "(iiiii)", &info.format,
    642                      &info.width, &info.height,
    643                      &info.size, &info.samplingrate))
    644         return NULL;
    645 
    646     if (svInitContinuousCapture(self->ob_svideo, &info))
    647         return sv_error();
    648 
    649     self->ob_info = info;
    650 
    651     return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
    652                          info.size, info.samplingrate);
    653 }
    654 
    655 static PyObject *
    656 sv_LoadMap(svobject *self, PyObject *args)
    657 {
    658     PyObject *rgb;
    659     PyObject *res = NULL;
    660     rgb_tuple *mapp = NULL;
    661     int maptype;
    662     int i, j;                                /* indices */
    663 
    664     if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
    665         return NULL;
    666 
    667     if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
    668         PyErr_BadArgument();
    669         return NULL;
    670     }
    671 
    672     if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
    673         return PyErr_NoMemory();
    674 
    675     for (i = 0; i < 256; i++) {
    676         PyObject* v = PyList_GetItem(rgb, i);
    677         if (!v)
    678             goto finally;
    679 
    680         if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
    681             PyErr_BadArgument();
    682             goto finally;
    683         }
    684         for (j = 0; j < 3; j++) {
    685             PyObject* cell = PyTuple_GetItem(v, j);
    686             if (!cell)
    687                 goto finally;
    688 
    689             if (!PyInt_Check(cell)) {
    690                 PyErr_BadArgument();
    691                 goto finally;
    692             }
    693             switch (j) {
    694             case 0: mapp[i].red = PyInt_AsLong(cell); break;
    695             case 1: mapp[i].blue = PyInt_AsLong(cell); break;
    696             case 2: mapp[i].green = PyInt_AsLong(cell); break;
    697             }
    698             if (PyErr_Occurred())
    699                 goto finally;
    700         }
    701     }
    702 
    703     if (svLoadMap(self->ob_svideo, maptype, mapp)) {
    704         res = sv_error();
    705         goto finally;
    706     }
    707 
    708     Py_INCREF(Py_None);
    709     res = Py_None;
    710 
    711   finally:
    712     PyMem_DEL(mapp);
    713     return res;
    714 }
    715 
    716 static PyObject *
    717 sv_CloseVideo(svobject *self, PyObject *args)
    718 {
    719     if (!PyArg_Parse(args, ""))
    720         return NULL;
    721 
    722     if (svCloseVideo(self->ob_svideo))
    723         return sv_error();
    724 
    725     self->ob_svideo = NULL;
    726     Py_INCREF(Py_None);
    727     return Py_None;
    728 }
    729 
    730 static PyObject *
    731 doParams(svobject *self, PyObject *args,
    732          int (*func)(SV_nodeP, long *, int), int modified)
    733 {
    734     PyObject *list;
    735     PyObject *res = NULL;
    736     long *PVbuffer = NULL;
    737     long length;
    738     int i;
    739 
    740     if (!PyArg_Parse(args, "O", &list))
    741         return NULL;
    742 
    743     if (!PyList_Check(list)) {
    744         PyErr_BadArgument();
    745         return NULL;
    746     }
    747 
    748     if ((length = PyList_Size(list)) < 0)
    749         return NULL;
    750 
    751     PVbuffer = PyMem_NEW(long, length);
    752     if (PVbuffer == NULL)
    753         return PyErr_NoMemory();
    754 
    755     for (i = 0; i < length; i++) {
    756         PyObject *v = PyList_GetItem(list, i);
    757         if (!v)
    758             goto finally;
    759 
    760         if (!PyInt_Check(v)) {
    761             PyErr_BadArgument();
    762             goto finally;
    763         }
    764         PVbuffer[i] = PyInt_AsLong(v);
    765         /* can't just test the return value, because what if the
    766            value was -1?!
    767         */
    768         if (PVbuffer[i] == -1 && PyErr_Occurred())
    769             goto finally;
    770     }
    771 
    772     if ((*func)(self->ob_svideo, PVbuffer, length)) {
    773         res = sv_error();
    774         goto finally;
    775     }
    776 
    777     if (modified) {
    778         for (i = 0; i < length; i++) {
    779             PyObject* v = PyInt_FromLong(PVbuffer[i]);
    780             if (!v || PyList_SetItem(list, i, v) < 0)
    781                 goto finally;
    782         }
    783     }
    784 
    785     Py_INCREF(Py_None);
    786     res = Py_None;
    787 
    788   finally:
    789     PyMem_DEL(PVbuffer);
    790     return res;
    791 }
    792 
    793 static PyObject *
    794 sv_GetParam(PyObject *self, PyObject *args)
    795 {
    796     return doParams(self, args, svGetParam, 1);
    797 }
    798 
    799 static PyObject *
    800 sv_GetParamRange(PyObject *self, PyObject *args)
    801 {
    802     return doParams(self, args, svGetParamRange, 1);
    803 }
    804 
    805 static PyObject *
    806 sv_SetParam(PyObject *self, PyObject *args)
    807 {
    808     return doParams(self, args, svSetParam, 0);
    809 }
    810 
    811 static PyMethodDef svideo_methods[] = {
    812     {"BindGLWindow",            (PyCFunction)sv_BindGLWindow, METH_OLDARGS},
    813     {"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture, METH_OLDARGS},
    814     {"IsVideoDisplayed",        (PyCFunction)sv_IsVideoDisplayed, METH_OLDARGS},
    815     {"OutputOffset",            (PyCFunction)sv_OutputOffset, METH_OLDARGS},
    816     {"PutFrame",                (PyCFunction)sv_PutFrame, METH_OLDARGS},
    817     {"QuerySize",               (PyCFunction)sv_QuerySize, METH_OLDARGS},
    818     {"SetSize",                 (PyCFunction)sv_SetSize, METH_OLDARGS},
    819     {"SetStdDefaults",          (PyCFunction)sv_SetStdDefaults, METH_OLDARGS},
    820     {"UseExclusive",            (PyCFunction)sv_UseExclusive, METH_OLDARGS},
    821     {"WindowOffset",            (PyCFunction)sv_WindowOffset, METH_OLDARGS},
    822     {"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture, METH_OLDARGS},
    823     {"CaptureBurst",            (PyCFunction)sv_CaptureBurst, METH_OLDARGS},
    824     {"CaptureOneFrame",         (PyCFunction)sv_CaptureOneFrame, METH_OLDARGS},
    825     {"GetCaptureData",          (PyCFunction)sv_GetCaptureData, METH_OLDARGS},
    826     {"CloseVideo",              (PyCFunction)sv_CloseVideo, METH_OLDARGS},
    827     {"LoadMap",                 (PyCFunction)sv_LoadMap, METH_OLDARGS},
    828     {"GetParam",                (PyCFunction)sv_GetParam, METH_OLDARGS},
    829     {"GetParamRange",           (PyCFunction)sv_GetParamRange, METH_OLDARGS},
    830     {"SetParam",                (PyCFunction)sv_SetParam, METH_OLDARGS},
    831     {NULL,                      NULL}           /* sentinel */
    832 };
    833 
    834 static PyObject *
    835 sv_conversion(PyObject *self, PyObject *args, void (*function)(),
    836               int inputfactor, float factor)
    837 {
    838     int invert, width, height, inputlength;
    839     char *input, *str;
    840     PyObject *output;
    841 
    842     if (!PyArg_Parse(args, "(is#ii)", &invert,
    843                      &input, &inputlength, &width, &height))
    844         return NULL;
    845 
    846     if (width * height * inputfactor > inputlength) {
    847         PyErr_SetString(SvError, "input buffer not long enough");
    848         return NULL;
    849     }
    850 
    851     if (!(output = PyString_FromStringAndSize(NULL,
    852                                           (int)(width * height * factor))))
    853         return NULL;
    854 
    855     str = PyString_AsString(output);
    856     if (!str) {
    857         Py_DECREF(output);
    858         return NULL;
    859     }
    860     (*function)(invert, input, str, width, height);
    861 
    862     return output;
    863 }
    864 
    865 static PyObject *
    866 sv_InterleaveFields(PyObject *self, PyObject *args)
    867 {
    868     return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
    869 }
    870 
    871 static PyObject *
    872 sv_RGB8toRGB32(PyObject *self, PyObject *args)
    873 {
    874     return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
    875 }
    876 
    877 static PyObject *
    878 sv_YUVtoRGB(PyObject *self, PyObject *args)
    879 {
    880     return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
    881 }
    882 
    883 static void
    884 svideo_dealloc(svobject *self)
    885 {
    886     if (self->ob_svideo != NULL)
    887         (void) svCloseVideo(self->ob_svideo);
    888     PyObject_Del(self);
    889 }
    890 
    891 static PyObject *
    892 svideo_getattr(svobject *self, char *name)
    893 {
    894     return Py_FindMethod(svideo_methods, (PyObject *)self, name);
    895 }
    896 
    897 PyTypeObject Svtype = {
    898     PyObject_HEAD_INIT(&PyType_Type)
    899     0,                          /*ob_size*/
    900     "sv.sv",                    /*tp_name*/
    901     sizeof(svobject),           /*tp_size*/
    902     0,                          /*tp_itemsize*/
    903     /* methods */
    904     (destructor)svideo_dealloc, /*tp_dealloc*/
    905     0,                          /*tp_print*/
    906     (getattrfunc)svideo_getattr, /*tp_getattr*/
    907     0,                          /*tp_setattr*/
    908     0,                          /*tp_compare*/
    909     0,                          /*tp_repr*/
    910 };
    911 
    912 static PyObject *
    913 newsvobject(SV_nodeP svp)
    914 {
    915     svobject *p;
    916 
    917     p = PyObject_New(svobject, &Svtype);
    918     if (p == NULL)
    919         return NULL;
    920     p->ob_svideo = svp;
    921     p->ob_info.format = 0;
    922     p->ob_info.size = 0;
    923     p->ob_info.width = 0;
    924     p->ob_info.height = 0;
    925     p->ob_info.samplingrate = 0;
    926     return (PyObject *) p;
    927 }
    928 
    929 static PyObject *
    930 sv_OpenVideo(PyObject *self, PyObject *args)
    931 {
    932     SV_nodeP svp;
    933 
    934     if (!PyArg_Parse(args, ""))
    935         return NULL;
    936 
    937     svp = svOpenVideo();
    938     if (svp == NULL)
    939         return sv_error();
    940 
    941     return newsvobject(svp);
    942 }
    943 
    944 static PyMethodDef sv_methods[] = {
    945     {"InterleaveFields",        (PyCFunction)sv_InterleaveFields, METH_OLDARGS},
    946     {"RGB8toRGB32",             (PyCFunction)sv_RGB8toRGB32, METH_OLDARGS},
    947     {"YUVtoRGB",                (PyCFunction)sv_YUVtoRGB, METH_OLDARGS},
    948     {"OpenVideo",               (PyCFunction)sv_OpenVideo, METH_OLDARGS},
    949     {NULL,                      NULL}   /* Sentinel */
    950 };
    951 
    952 void
    953 initsv(void)
    954 {
    955     PyObject *m, *d;
    956 
    957     if (PyErr_WarnPy3k("the sv module has been removed in "
    958                        "Python 3.0", 2) < 0)
    959         return;
    960 
    961     m = Py_InitModule("sv", sv_methods);
    962     if (m == NULL)
    963         return;
    964     d = PyModule_GetDict(m);
    965 
    966     SvError = PyErr_NewException("sv.error", NULL, NULL);
    967     if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
    968         return;
    969 }
    970