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