Don't reference removed files in Makefile
[python/dscho.git] / Modules / svmodule.c
blobdd48b7aea948cca848e59025c55e447bf3f94d52
1 /**********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* SV module -- interface to the Indigo video board */
27 #include <sys/time.h>
28 #include <svideo.h>
29 #include "allobjects.h"
30 #include "import.h"
31 #include "modsupport.h"
32 #include "compile.h"
33 #include "ceval.h"
34 #include "yuv.h" /* for YUV conversion functions */
36 typedef struct {
37 OB_HEAD
38 SV_nodeP ob_svideo;
39 svCaptureInfo ob_info;
40 } svobject;
42 typedef struct {
43 OB_HEAD
44 void *ob_capture;
45 int ob_mustunlock;
46 svCaptureInfo ob_info;
47 svobject *ob_svideo;
48 } captureobject;
50 static object *SvError; /* exception sv.error */
52 static object *newcaptureobject PROTO((svobject *, void *, int));
54 /* Set a SV-specific error from svideo_errno and return NULL */
55 static object *
56 sv_error()
58 err_setstr(SvError, svStrerror(svideo_errno));
59 return NULL;
62 static object *
63 svc_conversion(self, args, function, factor)
64 captureobject *self;
65 object *args;
66 void (*function)();
67 float factor;
69 object *output;
70 int invert;
72 if (!getargs(args, "i", &invert))
73 return NULL;
75 output = newsizedstringobject(NULL, (int) (self->ob_info.width * self->ob_info.height * factor));
76 if (output == NULL)
77 return NULL;
79 (*function)((boolean) invert, self->ob_capture, getstringvalue(output),
80 self->ob_info.width, self->ob_info.height);
82 return output;
86 * 3 functions to convert from Starter Video YUV 4:1:1 format to
87 * Compression Library 4:2:2 Duplicate Chroma format.
89 static object *
90 svc_YUVtoYUV422DC(self, args)
91 captureobject *self;
92 object *args;
94 if (self->ob_info.format != SV_YUV411_FRAMES) {
95 err_setstr(SvError, "data has bad format");
96 return NULL;
98 return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
101 static object *
102 svc_YUVtoYUV422DC_quarter(self, args)
103 captureobject *self;
104 object *args;
106 if (self->ob_info.format != SV_YUV411_FRAMES) {
107 err_setstr(SvError, "data has bad format");
108 return NULL;
110 return svc_conversion(self, args, yuv_sv411_to_cl422dc_quartersize, 0.5);
113 static object *
114 svc_YUVtoYUV422DC_sixteenth(self, args)
115 captureobject *self;
116 object *args;
118 if (self->ob_info.format != SV_YUV411_FRAMES) {
119 err_setstr(SvError, "data has bad format");
120 return NULL;
122 return svc_conversion(self, args, yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
125 static object *
126 svc_YUVtoRGB(self, args)
127 captureobject *self;
128 object *args;
130 switch (self->ob_info.format) {
131 case SV_YUV411_FRAMES:
132 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
133 break;
134 default:
135 err_setstr(SvError, "data had bad format");
136 return NULL;
138 return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
141 static object *
142 svc_RGB8toRGB32(self, args)
143 captureobject *self;
144 object *args;
146 if (self->ob_info.format != SV_RGB8_FRAMES) {
147 err_setstr(SvError, "data has bad format");
148 return NULL;
150 return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
153 static object *
154 svc_InterleaveFields(self, args)
155 captureobject *self;
156 object *args;
158 if (self->ob_info.format != SV_RGB8_FRAMES) {
159 err_setstr(SvError, "data has bad format");
160 return NULL;
162 return svc_conversion(self, args, svInterleaveFields, 1.0);
165 static object *
166 svc_GetFields(self, args)
167 captureobject *self;
168 object *args;
170 object *f1, *f2, *ret;
171 int fieldsize;
173 if (self->ob_info.format != SV_RGB8_FRAMES) {
174 err_setstr(SvError, "data has bad format");
175 return NULL;
178 fieldsize = self->ob_info.width * self->ob_info.height / 2;
179 f1 = newsizedstringobject((char *) self->ob_capture, fieldsize);
180 f2 = newsizedstringobject((char *) self->ob_capture + fieldsize, fieldsize);
181 ret = mkvalue("(OO)", f1, f2);
182 XDECREF(f1);
183 XDECREF(f2);
184 return ret;
187 static object *
188 svc_UnlockCaptureData(self, args)
189 captureobject *self;
190 object *args;
192 if (!getnoarg(args))
193 return NULL;
195 if (!self->ob_mustunlock) {
196 err_setstr(SvError, "buffer should not be unlocked");
197 return NULL;
200 if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
201 return sv_error();
203 self->ob_mustunlock = 0;
205 INCREF(None);
206 return None;
209 #ifdef USE_GL
210 #include <gl.h>
212 static object *
213 svc_lrectwrite(self, args)
214 captureobject *self;
215 object *args;
217 Screencoord x1, x2, y1, y2;
219 if (!getargs(args, "(hhhh)", &x1, &x2, &y1, &y2))
220 return NULL;
222 lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);
224 INCREF(None);
225 return None;
227 #endif
229 static object *
230 svc_writefile(self, args)
231 captureobject *self;
232 object *args;
234 object *file;
235 int size;
237 if (!getargs(args, "O", &file))
238 return NULL;
240 if (!is_fileobject(file)) {
241 err_setstr(SvError, "not a file object");
242 return NULL;
245 size = self->ob_info.width * self->ob_info.height;
247 if (fwrite(self->ob_capture, sizeof(long), size, getfilefile(file)) != size) {
248 err_setstr(SvError, "writing failed");
249 return NULL;
252 INCREF(None);
253 return None;
256 static object *
257 svc_FindVisibleRegion(self, args)
258 captureobject *self;
259 object *args;
261 void *visible;
262 int width;
264 if (!getnoarg(args))
265 return NULL;
267 if (svFindVisibleRegion(self->ob_svideo->ob_svideo, self->ob_capture, &visible, self->ob_info.width))
268 return sv_error();
270 if (visible == NULL) {
271 err_setstr(SvError, "data in wrong format");
272 return NULL;
275 return newcaptureobject(self->ob_svideo, visible, 0);
278 static struct methodlist capture_methods[] = {
279 {"YUVtoRGB", (method)svc_YUVtoRGB},
280 {"RGB8toRGB32", (method)svc_RGB8toRGB32},
281 {"InterleaveFields", (method)svc_InterleaveFields},
282 {"UnlockCaptureData", (method)svc_UnlockCaptureData},
283 {"FindVisibleRegion", (method)svc_FindVisibleRegion},
284 {"GetFields", (method)svc_GetFields},
285 {"YUVtoYUV422DC", (method)svc_YUVtoYUV422DC},
286 {"YUVtoYUV422DC_quarter",(method)svc_YUVtoYUV422DC_quarter},
287 {"YUVtoYUV422DC_sixteenth",(method)svc_YUVtoYUV422DC_sixteenth},
288 #ifdef USE_GL
289 {"lrectwrite", (method)svc_lrectwrite},
290 #endif
291 {"writefile", (method)svc_writefile},
292 {NULL, NULL} /* sentinel */
295 static void
296 capture_dealloc(self)
297 captureobject *self;
299 if (self->ob_capture != NULL) {
300 if (self->ob_mustunlock)
301 (void) svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture);
302 self->ob_capture = NULL;
303 DECREF(self->ob_svideo);
304 self->ob_svideo = NULL;
306 DEL(self);
309 static object *
310 capture_getattr(self, name)
311 svobject *self;
312 char *name;
314 return findmethod(capture_methods, (object *)self, name);
317 typeobject Capturetype = {
318 OB_HEAD_INIT(&Typetype)
319 0, /*ob_size*/
320 "capture", /*tp_name*/
321 sizeof(captureobject), /*tp_size*/
322 0, /*tp_itemsize*/
323 /* methods */
324 (destructor)capture_dealloc, /*tp_dealloc*/
325 0, /*tp_print*/
326 (getattrfunc)capture_getattr, /*tp_getattr*/
327 0, /*tp_setattr*/
328 0, /*tp_compare*/
329 0, /*tp_repr*/
332 static object *
333 newcaptureobject(self, ptr, mustunlock)
334 svobject *self;
335 void *ptr;
336 int mustunlock;
338 captureobject *p;
340 p = NEWOBJ(captureobject, &Capturetype);
341 if (p == NULL)
342 return NULL;
343 p->ob_svideo = self;
344 INCREF(self);
345 p->ob_capture = ptr;
346 p->ob_mustunlock = mustunlock;
347 p->ob_info = self->ob_info;
348 return (object *) p;
351 static object *
352 sv_GetCaptureData(self, args)
353 svobject *self;
354 object *args;
356 void *ptr;
357 long fieldID;
358 object *res, *c;
360 if (!getnoarg(args))
361 return NULL;
363 if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
364 return sv_error();
366 if (ptr == NULL) {
367 err_setstr(SvError, "no data available");
368 return NULL;
371 c = newcaptureobject(self, ptr, 1);
372 if (c == NULL)
373 return NULL;
374 res = mkvalue("(Oi)", c, fieldID);
375 DECREF(c);
376 return res;
379 static object *
380 sv_BindGLWindow(self, args)
381 svobject *self;
382 object *args;
384 long wid;
385 int mode;
387 if (!getargs(args, "(ii)", &wid, &mode))
388 return NULL;
390 if (svBindGLWindow(self->ob_svideo, wid, mode))
391 return sv_error();
393 INCREF(None);
394 return None;
397 static object *
398 sv_EndContinuousCapture(self, args)
399 svobject *self;
400 object *args;
403 if (!getnoarg(args))
404 return NULL;
406 if (svEndContinuousCapture(self->ob_svideo))
407 return sv_error();
409 INCREF(None);
410 return None;
413 static object *
414 sv_IsVideoDisplayed(self, args)
415 svobject *self;
416 object *args;
418 int v;
420 if (!getnoarg(args))
421 return NULL;
423 v = svIsVideoDisplayed(self->ob_svideo);
424 if (v == -1)
425 return sv_error();
427 return newintobject((long) v);
430 static object *
431 sv_OutputOffset(self, args)
432 svobject *self;
433 object *args;
435 int x_offset;
436 int y_offset;
438 if (!getargs(args, "(ii)", &x_offset, &y_offset))
439 return NULL;
441 if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
442 return sv_error();
444 INCREF(None);
445 return None;
448 static object *
449 sv_PutFrame(self, args)
450 svobject *self;
451 object *args;
453 char *buffer;
455 if (!getargs(args, "s", &buffer))
456 return NULL;
458 if (svPutFrame(self->ob_svideo, buffer))
459 return sv_error();
461 INCREF(None);
462 return None;
465 static object *
466 sv_QuerySize(self, args)
467 svobject *self;
468 object *args;
470 int w;
471 int h;
472 int rw;
473 int rh;
475 if (!getargs(args, "(ii)", &w, &h))
476 return NULL;
478 if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
479 return sv_error();
481 return mkvalue("(ii)", (long) rw, (long) rh);
484 static object *
485 sv_SetSize(self, args)
486 svobject *self;
487 object *args;
489 int w;
490 int h;
492 if (!getargs(args, "(ii)", &w, &h))
493 return NULL;
495 if (svSetSize(self->ob_svideo, w, h))
496 return sv_error();
498 INCREF(None);
499 return None;
502 static object *
503 sv_SetStdDefaults(self, args)
504 svobject *self;
505 object *args;
508 if (!getnoarg(args))
509 return NULL;
511 if (svSetStdDefaults(self->ob_svideo))
512 return sv_error();
514 INCREF(None);
515 return None;
518 static object *
519 sv_UseExclusive(self, args)
520 svobject *self;
521 object *args;
523 boolean onoff;
524 int mode;
526 if (!getargs(args, "(ii)", &onoff, &mode))
527 return NULL;
529 if (svUseExclusive(self->ob_svideo, onoff, mode))
530 return sv_error();
532 INCREF(None);
533 return None;
536 static object *
537 sv_WindowOffset(self, args)
538 svobject *self;
539 object *args;
541 int x_offset;
542 int y_offset;
544 if (!getargs(args, "(ii)", &x_offset, &y_offset))
545 return NULL;
547 if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
548 return sv_error();
550 INCREF(None);
551 return None;
554 static object *
555 sv_CaptureBurst(self, args)
556 svobject *self;
557 object *args;
559 int bytes, i;
560 svCaptureInfo info;
561 void *bitvector = NULL;
562 object *videodata, *bitvecobj, *res;
563 static object *evenitem, *odditem;
565 if (!getargs(args, "(iiiii)", &info.format, &info.width, &info.height,
566 &info.size, &info.samplingrate))
567 return NULL;
569 switch (info.format) {
570 case SV_RGB8_FRAMES:
571 bitvector = malloc(SV_BITVEC_SIZE(info.size));
572 break;
573 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
574 break;
575 default:
576 err_setstr(SvError, "illegal format specified");
577 return NULL;
580 if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
581 if (bitvector)
582 free(bitvector);
583 return sv_error();
586 videodata = newsizedstringobject(NULL, bytes);
587 if (videodata == NULL) {
588 if (bitvector)
589 free(bitvector);
590 return NULL;
593 /* XXX -- need to do something about the bitvector */
594 if (svCaptureBurst(self->ob_svideo, &info, getstringvalue(videodata),
595 bitvector)) {
596 if (bitvector)
597 free(bitvector);
598 DECREF(videodata);
599 return sv_error();
602 if (bitvector) {
603 if (evenitem == NULL) {
604 evenitem = newintobject(0);
605 if (evenitem == NULL) {
606 free(bitvector);
607 DECREF(videodata);
608 return NULL;
611 if (odditem == NULL) {
612 odditem = newintobject(1);
613 if (odditem == NULL) {
614 free(bitvector);
615 DECREF(videodata);
616 return NULL;
619 bitvecobj = newtupleobject(2 * info.size);
620 if (bitvecobj == NULL) {
621 free(bitvecobj);
622 DECREF(videodata);
623 return NULL;
625 for (i = 0; i < 2 * info.size; i++) {
626 if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
627 INCREF(evenitem);
628 settupleitem(bitvecobj, i, evenitem);
629 } else {
630 INCREF(odditem);
631 settupleitem(bitvecobj, i, odditem);
634 free(bitvector);
635 } else {
636 bitvecobj = None;
637 INCREF(None);
640 res = mkvalue("((iiiii)OO)", info.format, info.width, info.height,
641 info.size, info.samplingrate, videodata, bitvecobj);
642 DECREF(videodata);
643 DECREF(bitvecobj);
644 return res;
647 static object *
648 sv_CaptureOneFrame(self, args)
649 svobject *self;
650 object *args;
652 svCaptureInfo info;
653 int format, width, height;
654 int bytes;
655 object *videodata, *res;
657 if (!getargs(args, "(iii)", &format, &width, &height))
658 return NULL;
659 info.format = format;
660 info.width = width;
661 info.height = height;
662 info.size = 0;
663 info.samplingrate = 0;
664 if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
665 return sv_error();
666 videodata = newsizedstringobject(NULL, bytes);
667 if (videodata == NULL)
668 return NULL;
669 if (svCaptureOneFrame(self->ob_svideo, format, &width, &height,
670 getstringvalue(videodata))) {
671 DECREF(videodata);
672 return sv_error();
675 res = mkvalue("(iiO)", width, height, videodata);
676 DECREF(videodata);
677 return res;
680 static object *
681 sv_InitContinuousCapture(self, args)
682 svobject *self;
683 object *args;
685 svCaptureInfo info;
687 if (!getargs(args, "(iiiii)", &info.format, &info.width, &info.height,
688 &info.size, &info.samplingrate))
689 return NULL;
691 if (svInitContinuousCapture(self->ob_svideo, &info))
692 return sv_error();
694 self->ob_info = info;
696 return mkvalue("(iiiii)", info.format, info.width, info.height,
697 info.size, info.samplingrate);
700 static object *
701 sv_LoadMap(self, args)
702 svobject *self;
703 object *args;
705 object *rgb, *v, *cell;
706 rgb_tuple *mapp;
707 int maptype;
708 int i, j; /* indices */
710 if (!getargs(args, "(iO)", &maptype, &rgb))
711 return NULL;
712 if (!is_listobject(rgb) || getlistsize(rgb) != 256) {
713 err_badarg();
714 return NULL;
716 mapp = NEW(rgb_tuple, 256);
717 if (mapp == NULL)
718 return err_nomem();
719 for (i = 0; i < 256; i++) {
720 v = getlistitem(rgb, i);
721 if (!is_tupleobject(v) || gettuplesize(v) != 3) {
722 DEL(mapp);
723 err_badarg();
724 return NULL;
726 for (j = 0; j < 3; j++) {
727 cell = gettupleitem(v, j);
728 if (!is_intobject(cell)) {
729 DEL(mapp);
730 err_badarg();
731 return NULL;
733 switch (j) {
734 case 0: mapp[i].red = getintvalue(cell); break;
735 case 1: mapp[i].blue = getintvalue(cell); break;
736 case 2: mapp[i].green = getintvalue(cell); break;
741 if (svLoadMap(self->ob_svideo, maptype, mapp)) {
742 DEL(mapp);
743 return sv_error();
746 DEL(mapp);
748 INCREF(None);
749 return None;
752 static object *
753 sv_CloseVideo(self, args)
754 svobject *self;
755 object *args;
757 if (!getnoarg(args))
758 return NULL;
760 if (svCloseVideo(self->ob_svideo))
761 return sv_error();
762 self->ob_svideo = NULL;
764 INCREF(None);
765 return None;
768 static object *
769 doParams(self, args, func, modified)
770 svobject *self;
771 object *args;
772 int (*func)(SV_nodeP, long *, int);
773 int modified;
775 object *list, *v;
776 long *PVbuffer;
777 long length;
778 int i;
780 if (!getargs(args, "O", &list))
781 return NULL;
782 if (!is_listobject(list)) {
783 err_badarg();
784 return NULL;
786 length = getlistsize(list);
787 PVbuffer = NEW(long, length);
788 if (PVbuffer == NULL)
789 return err_nomem();
790 for (i = 0; i < length; i++) {
791 v = getlistitem(list, i);
792 if (!is_intobject(v)) {
793 DEL(PVbuffer);
794 err_badarg();
795 return NULL;
797 PVbuffer[i] = getintvalue(v);
800 if ((*func)(self->ob_svideo, PVbuffer, length)) {
801 DEL(PVbuffer);
802 return sv_error();
805 if (modified) {
806 for (i = 0; i < length; i++)
807 setlistitem(list, i, newintobject(PVbuffer[i]));
810 DEL(PVbuffer);
812 INCREF(None);
813 return None;
816 static object *
817 sv_GetParam(self, args)
818 object *self, *args;
820 return doParams(self, args, svGetParam, 1);
823 static object *
824 sv_GetParamRange(self, args)
825 object *self, *args;
827 return doParams(self, args, svGetParamRange, 1);
830 static object *
831 sv_SetParam(self, args)
832 object *self, *args;
834 return doParams(self, args, svSetParam, 0);
837 static struct methodlist svideo_methods[] = {
838 {"BindGLWindow", (method)sv_BindGLWindow},
839 {"EndContinuousCapture",(method)sv_EndContinuousCapture},
840 {"IsVideoDisplayed", (method)sv_IsVideoDisplayed},
841 {"OutputOffset", (method)sv_OutputOffset},
842 {"PutFrame", (method)sv_PutFrame},
843 {"QuerySize", (method)sv_QuerySize},
844 {"SetSize", (method)sv_SetSize},
845 {"SetStdDefaults", (method)sv_SetStdDefaults},
846 {"UseExclusive", (method)sv_UseExclusive},
847 {"WindowOffset", (method)sv_WindowOffset},
848 {"InitContinuousCapture",(method)sv_InitContinuousCapture},
849 {"CaptureBurst", (method)sv_CaptureBurst},
850 {"CaptureOneFrame", (method)sv_CaptureOneFrame},
851 {"GetCaptureData", (method)sv_GetCaptureData},
852 {"CloseVideo", (method)sv_CloseVideo},
853 {"LoadMap", (method)sv_LoadMap},
854 {"GetParam", (method)sv_GetParam},
855 {"GetParamRange", (method)sv_GetParamRange},
856 {"SetParam", (method)sv_SetParam},
857 {NULL, NULL} /* sentinel */
860 static object *
861 sv_conversion(self, args, function, inputfactor, factor)
862 object *self, *args;
863 void (*function)();
864 int inputfactor;
865 float factor;
867 int invert, width, height, inputlength;
868 char *input;
869 object *output;
871 if (!getargs(args, "(is#ii)", &invert, &input, &inputlength, &width, &height))
872 return NULL;
874 if (width * height * inputfactor > inputlength) {
875 err_setstr(SvError, "input buffer not long enough");
876 return NULL;
879 output = newsizedstringobject(NULL, (int) (width * height * factor));
880 if (output == NULL)
881 return NULL;
883 (*function)(invert, input, getstringvalue(output), width, height);
885 return output;
888 static object *
889 sv_InterleaveFields(self, args)
890 object *self, *args;
892 return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
895 static object *
896 sv_RGB8toRGB32(self, args)
897 object *self, *args;
899 return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
902 static object *
903 sv_YUVtoRGB(self, args)
904 object *self, *args;
906 return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
909 static void
910 svideo_dealloc(self)
911 svobject *self;
913 if (self->ob_svideo != NULL)
914 (void) svCloseVideo(self->ob_svideo);
915 DEL(self);
918 static object *
919 svideo_getattr(self, name)
920 svobject *self;
921 char *name;
923 return findmethod(svideo_methods, (object *)self, name);
926 typeobject Svtype = {
927 OB_HEAD_INIT(&Typetype)
928 0, /*ob_size*/
929 "sv", /*tp_name*/
930 sizeof(svobject), /*tp_size*/
931 0, /*tp_itemsize*/
932 /* methods */
933 (destructor)svideo_dealloc, /*tp_dealloc*/
934 0, /*tp_print*/
935 (getattrfunc)svideo_getattr, /*tp_getattr*/
936 0, /*tp_setattr*/
937 0, /*tp_compare*/
938 0, /*tp_repr*/
941 static object *
942 newsvobject(svp)
943 SV_nodeP svp;
945 svobject *p;
947 p = NEWOBJ(svobject, &Svtype);
948 if (p == NULL)
949 return NULL;
950 p->ob_svideo = svp;
951 p->ob_info.format = 0;
952 p->ob_info.size = 0;
953 p->ob_info.width = 0;
954 p->ob_info.height = 0;
955 p->ob_info.samplingrate = 0;
956 return (object *) p;
959 static object *
960 sv_OpenVideo(self, args)
961 object *self, *args;
963 SV_nodeP svp;
965 if (!getnoarg(args))
966 return NULL;
968 svp = svOpenVideo();
969 if (svp == NULL)
970 return sv_error();
972 return newsvobject(svp);
975 static struct methodlist sv_methods[] = {
976 {"InterleaveFields", (method)sv_InterleaveFields},
977 {"RGB8toRGB32", (method)sv_RGB8toRGB32},
978 {"YUVtoRGB", (method)sv_YUVtoRGB},
979 {"OpenVideo", (method)sv_OpenVideo},
980 {NULL, NULL} /* Sentinel */
983 void
984 initsv()
986 object *m, *d;
988 m = initmodule("sv", sv_methods);
989 d = getmoduledict(m);
991 SvError = newstringobject("sv.error");
992 if (SvError == NULL || dictinsert(d, "error", SvError) != 0)
993 fatal("can't define sv.error");