• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
sv_error(void)34  sv_error(void)
35  {
36      PyErr_SetString(SvError, svStrerror(svideo_errno));
37      return NULL;
38  }
39  
40  static PyObject *
svc_conversion(captureobject * self,PyObject * args,void (* function)(),float factor)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 *
svc_YUVtoYUV422DC(captureobject * self,PyObject * args)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 *
svc_YUVtoYUV422DC_quarter(captureobject * self,PyObject * args)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 *
svc_YUVtoYUV422DC_sixteenth(captureobject * self,PyObject * args)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 *
svc_YUVtoRGB(captureobject * self,PyObject * args)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 *
svc_RGB8toRGB32(captureobject * self,PyObject * args)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 *
svc_InterleaveFields(captureobject * self,PyObject * args)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 *
svc_GetFields(captureobject * self,PyObject * args)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 *
svc_UnlockCaptureData(captureobject * self,PyObject * args)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 *
svc_lrectwrite(captureobject * self,PyObject * args)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 *
svc_writefile(captureobject * self,PyObject * args)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 *
svc_FindVisibleRegion(captureobject * self,PyObject * args)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
capture_dealloc(captureobject * self)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 *
capture_getattr(svobject * self,char * name)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 *
newcaptureobject(svobject * self,void * ptr,int mustunlock)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 *
sv_GetCaptureData(svobject * self,PyObject * args)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 *
sv_BindGLWindow(svobject * self,PyObject * args)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 *
sv_EndContinuousCapture(svobject * self,PyObject * args)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 *
sv_IsVideoDisplayed(svobject * self,PyObject * args)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 *
sv_OutputOffset(svobject * self,PyObject * args)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 *
sv_PutFrame(svobject * self,PyObject * args)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 *
sv_QuerySize(svobject * self,PyObject * args)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 *
sv_SetSize(svobject * self,PyObject * args)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 *
sv_SetStdDefaults(svobject * self,PyObject * args)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 *
sv_UseExclusive(svobject * self,PyObject * args)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 *
sv_WindowOffset(svobject * self,PyObject * args)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 *
sv_CaptureBurst(svobject * self,PyObject * args)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 *
sv_CaptureOneFrame(svobject * self,PyObject * args)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 *
sv_InitContinuousCapture(svobject * self,PyObject * args)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 *
sv_LoadMap(svobject * self,PyObject * args)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 (!_PyAnyInt_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 *
sv_CloseVideo(svobject * self,PyObject * args)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 *
doParams(svobject * self,PyObject * args,int (* func)(SV_nodeP,long *,int),int modified)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 (!_PyAnyInt_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 *
sv_GetParam(PyObject * self,PyObject * args)794  sv_GetParam(PyObject *self, PyObject *args)
795  {
796      return doParams(self, args, svGetParam, 1);
797  }
798  
799  static PyObject *
sv_GetParamRange(PyObject * self,PyObject * args)800  sv_GetParamRange(PyObject *self, PyObject *args)
801  {
802      return doParams(self, args, svGetParamRange, 1);
803  }
804  
805  static PyObject *
sv_SetParam(PyObject * self,PyObject * args)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 *
sv_conversion(PyObject * self,PyObject * args,void (* function)(),int inputfactor,float factor)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 *
sv_InterleaveFields(PyObject * self,PyObject * args)866  sv_InterleaveFields(PyObject *self, PyObject *args)
867  {
868      return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
869  }
870  
871  static PyObject *
sv_RGB8toRGB32(PyObject * self,PyObject * args)872  sv_RGB8toRGB32(PyObject *self, PyObject *args)
873  {
874      return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
875  }
876  
877  static PyObject *
sv_YUVtoRGB(PyObject * self,PyObject * args)878  sv_YUVtoRGB(PyObject *self, PyObject *args)
879  {
880      return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
881  }
882  
883  static void
svideo_dealloc(svobject * self)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 *
svideo_getattr(svobject * self,char * name)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 *
newsvobject(SV_nodeP svp)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 *
sv_OpenVideo(PyObject * self,PyObject * args)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
initsv(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