1 /**********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
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 or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* SV module -- interface to the Indigo video board */
34 /* WARNING! This module is for hardware that we don't have any more,
35 so it hasn't been tested. It has been converted to the new coding
36 style, and it is possible that this conversion has broken something
43 #include "yuv.h" /* for YUV conversion functions */
48 svCaptureInfo ob_info
;
55 svCaptureInfo ob_info
;
59 static PyObject
*SvError
; /* exception sv.error */
61 static PyObject
*newcaptureobject
Py_PROTO((svobject
*, void *, int));
63 /* Set a SV-specific error from svideo_errno and return NULL */
67 PyErr_SetString(SvError
, svStrerror(svideo_errno
));
72 svc_conversion(self
, args
, function
, factor
)
82 if (!PyArg_Parse(args
, "i", &invert
))
85 if (!(output
= PyString_FromStringAndSize(
87 (int)(self
->ob_info
.width
* self
->ob_info
.height
* factor
))))
91 if (!(outstr
= PyString_AsString(output
))) {
96 (*function
)((boolean
)invert
, self
->ob_capture
,
98 self
->ob_info
.width
, self
->ob_info
.height
);
104 * 3 functions to convert from Starter Video YUV 4:1:1 format to
105 * Compression Library 4:2:2 Duplicate Chroma format.
108 svc_YUVtoYUV422DC(self
, args
)
112 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
113 PyErr_SetString(SvError
, "data has bad format");
116 return svc_conversion(self
, args
, yuv_sv411_to_cl422dc
, 2.0);
120 svc_YUVtoYUV422DC_quarter(self
, args
)
124 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
125 PyErr_SetString(SvError
, "data has bad format");
128 return svc_conversion(self
, args
,
129 yuv_sv411_to_cl422dc_quartersize
, 0.5);
133 svc_YUVtoYUV422DC_sixteenth(self
, args
)
137 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
138 PyErr_SetString(SvError
, "data has bad format");
141 return svc_conversion(self
, args
,
142 yuv_sv411_to_cl422dc_sixteenthsize
, 0.125);
146 svc_YUVtoRGB(self
, args
)
150 switch (self
->ob_info
.format
) {
151 case SV_YUV411_FRAMES
:
152 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER
:
155 PyErr_SetString(SvError
, "data had bad format");
158 return svc_conversion(self
, args
, svYUVtoRGB
, (float) sizeof(long));
162 svc_RGB8toRGB32(self
, args
)
166 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
167 PyErr_SetString(SvError
, "data has bad format");
170 return svc_conversion(self
, args
, svRGB8toRGB32
, (float) sizeof(long));
174 svc_InterleaveFields(self
, args
)
178 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
179 PyErr_SetString(SvError
, "data has bad format");
182 return svc_conversion(self
, args
, svInterleaveFields
, 1.0);
186 svc_GetFields(self
, args
)
192 PyObject
*ret
= NULL
;
196 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
197 PyErr_SetString(SvError
, "data has bad format");
201 fieldsize
= self
->ob_info
.width
* self
->ob_info
.height
/ 2;
202 obcapture
= (char*)self
->ob_capture
;
204 if (!(f1
= PyString_FromStringAndSize(obcapture
, fieldsize
)))
206 if (!(f2
= PyString_FromStringAndSize(obcapture
+ fieldsize
,
209 ret
= Py_BuildValue("(OO)", f1
, f2
);
218 svc_UnlockCaptureData(self
, args
)
222 if (!PyArg_Parse(args
, ""))
225 if (!self
->ob_mustunlock
) {
226 PyErr_SetString(SvError
, "buffer should not be unlocked");
230 if (svUnlockCaptureData(self
->ob_svideo
->ob_svideo
, self
->ob_capture
))
233 self
->ob_mustunlock
= 0;
243 svc_lrectwrite(self
, args
)
247 Screencoord x1
, x2
, y1
, y2
;
249 if (!PyArg_Parse(args
, "(hhhh)", &x1
, &x2
, &y1
, &y2
))
252 lrectwrite(x1
, x2
, y1
, y2
, (unsigned long *) self
->ob_capture
);
260 svc_writefile(self
, args
)
268 if (!PyArg_Parse(args
, "O", &file
))
271 if (!PyFile_Check(file
)) {
272 PyErr_SetString(SvError
, "not a file object");
276 if (!(fp
= PyFile_AsFile(file
)))
279 size
= self
->ob_info
.width
* self
->ob_info
.height
;
281 if (fwrite(self
->ob_capture
, sizeof(long), size
, fp
) != size
) {
282 PyErr_SetString(SvError
, "writing failed");
291 svc_FindVisibleRegion(self
, args
)
298 if (!PyArg_Parse(args
, ""))
301 if (svFindVisibleRegion(self
->ob_svideo
->ob_svideo
,
302 self
->ob_capture
, &visible
,
303 self
->ob_info
.width
))
306 if (visible
== NULL
) {
307 PyErr_SetString(SvError
, "data in wrong format");
311 return newcaptureobject(self
->ob_svideo
, visible
, 0);
314 static PyMethodDef capture_methods
[] = {
315 {"YUVtoRGB", (PyCFunction
)svc_YUVtoRGB
},
316 {"RGB8toRGB32", (PyCFunction
)svc_RGB8toRGB32
},
317 {"InterleaveFields", (PyCFunction
)svc_InterleaveFields
},
318 {"UnlockCaptureData", (PyCFunction
)svc_UnlockCaptureData
},
319 {"FindVisibleRegion", (PyCFunction
)svc_FindVisibleRegion
},
320 {"GetFields", (PyCFunction
)svc_GetFields
},
321 {"YUVtoYUV422DC", (PyCFunction
)svc_YUVtoYUV422DC
},
322 {"YUVtoYUV422DC_quarter",(PyCFunction
)svc_YUVtoYUV422DC_quarter
},
323 {"YUVtoYUV422DC_sixteenth",(PyCFunction
)svc_YUVtoYUV422DC_sixteenth
},
325 {"lrectwrite", (PyCFunction
)svc_lrectwrite
},
327 {"writefile", (PyCFunction
)svc_writefile
},
328 {NULL
, NULL
} /* sentinel */
332 capture_dealloc(self
)
335 if (self
->ob_capture
!= NULL
) {
336 if (self
->ob_mustunlock
)
337 (void)svUnlockCaptureData(self
->ob_svideo
->ob_svideo
,
339 self
->ob_capture
= NULL
;
340 Py_DECREF(self
->ob_svideo
);
341 self
->ob_svideo
= NULL
;
347 capture_getattr(self
, name
)
351 return Py_FindMethod(capture_methods
, (PyObject
*)self
, name
);
354 PyTypeObject Capturetype
= {
355 PyObject_HEAD_INIT(&PyType_Type
)
357 "capture", /*tp_name*/
358 sizeof(captureobject
), /*tp_size*/
361 (destructor
)capture_dealloc
, /*tp_dealloc*/
363 (getattrfunc
)capture_getattr
, /*tp_getattr*/
370 newcaptureobject(self
, ptr
, mustunlock
)
377 p
= PyObject_NEW(captureobject
, &Capturetype
);
383 p
->ob_mustunlock
= mustunlock
;
384 p
->ob_info
= self
->ob_info
;
385 return (PyObject
*) p
;
389 sv_GetCaptureData(self
, args
)
397 if (!PyArg_Parse(args
, ""))
400 if (svGetCaptureData(self
->ob_svideo
, &ptr
, &fieldID
))
404 PyErr_SetString(SvError
, "no data available");
408 c
= newcaptureobject(self
, ptr
, 1);
411 res
= Py_BuildValue("(Oi)", c
, fieldID
);
417 sv_BindGLWindow(self
, args
)
424 if (!PyArg_Parse(args
, "(ii)", &wid
, &mode
))
427 if (svBindGLWindow(self
->ob_svideo
, wid
, mode
))
435 sv_EndContinuousCapture(self
, args
)
440 if (!PyArg_Parse(args
, ""))
443 if (svEndContinuousCapture(self
->ob_svideo
))
451 sv_IsVideoDisplayed(self
, args
)
457 if (!PyArg_Parse(args
, ""))
460 v
= svIsVideoDisplayed(self
->ob_svideo
);
464 return PyInt_FromLong((long) v
);
468 sv_OutputOffset(self
, args
)
475 if (!PyArg_Parse(args
, "(ii)", &x_offset
, &y_offset
))
478 if (svOutputOffset(self
->ob_svideo
, x_offset
, y_offset
))
486 sv_PutFrame(self
, args
)
492 if (!PyArg_Parse(args
, "s", &buffer
))
495 if (svPutFrame(self
->ob_svideo
, buffer
))
503 sv_QuerySize(self
, args
)
512 if (!PyArg_Parse(args
, "(ii)", &w
, &h
))
515 if (svQuerySize(self
->ob_svideo
, w
, h
, &rw
, &rh
))
518 return Py_BuildValue("(ii)", (long) rw
, (long) rh
);
522 sv_SetSize(self
, args
)
529 if (!PyArg_Parse(args
, "(ii)", &w
, &h
))
532 if (svSetSize(self
->ob_svideo
, w
, h
))
540 sv_SetStdDefaults(self
, args
)
545 if (!PyArg_Parse(args
, ""))
548 if (svSetStdDefaults(self
->ob_svideo
))
556 sv_UseExclusive(self
, args
)
563 if (!PyArg_Parse(args
, "(ii)", &onoff
, &mode
))
566 if (svUseExclusive(self
->ob_svideo
, onoff
, mode
))
574 sv_WindowOffset(self
, args
)
581 if (!PyArg_Parse(args
, "(ii)", &x_offset
, &y_offset
))
584 if (svWindowOffset(self
->ob_svideo
, x_offset
, y_offset
))
592 sv_CaptureBurst(self
, args
)
598 void *bitvector
= NULL
;
599 PyObject
*videodata
= NULL
;
600 PyObject
*bitvecobj
= NULL
;
601 PyObject
*res
= NULL
;
602 static PyObject
*evenitem
, *odditem
;
604 if (!PyArg_Parse(args
, "(iiiii)", &info
.format
,
605 &info
.width
, &info
.height
,
606 &info
.size
, &info
.samplingrate
))
609 switch (info
.format
) {
611 bitvector
= malloc(SV_BITVEC_SIZE(info
.size
));
613 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER
:
616 PyErr_SetString(SvError
, "illegal format specified");
620 if (svQueryCaptureBufferSize(self
->ob_svideo
, &info
, &bytes
)) {
625 if (!(videodata
= PyString_FromStringAndSize(NULL
, bytes
)))
628 /* XXX -- need to do something about the bitvector */
630 char* str
= PyString_AsString(videodata
);
634 if (svCaptureBurst(self
->ob_svideo
, &info
, str
, bitvector
)) {
641 if (evenitem
== NULL
) {
642 if (!(evenitem
= PyInt_FromLong(0)))
645 if (odditem
== NULL
) {
646 if (!(odditem
= PyInt_FromLong(1)))
649 if (!(bitvecobj
= PyTuple_New(2 * info
.size
)))
652 for (i
= 0; i
< 2 * info
.size
; i
++) {
655 if (SV_GET_FIELD(bitvector
, i
) == SV_EVEN_FIELD
) {
657 sts
= PyTuple_SetItem(bitvecobj
, i
, evenitem
);
660 sts
= PyTuple_SetItem(bitvecobj
, i
, odditem
);
670 res
= Py_BuildValue("((iiiii)OO)", info
.format
,
671 info
.width
, info
.height
,
672 info
.size
, info
.samplingrate
,
673 videodata
, bitvecobj
);
679 Py_XDECREF(videodata
);
680 Py_XDECREF(bitvecobj
);
685 sv_CaptureOneFrame(self
, args
)
690 int format
, width
, height
;
692 PyObject
*videodata
= NULL
;
693 PyObject
*res
= NULL
;
696 if (!PyArg_Parse(args
, "(iii)", &format
, &width
, &height
))
699 info
.format
= format
;
701 info
.height
= height
;
703 info
.samplingrate
= 0;
704 if (svQueryCaptureBufferSize(self
->ob_svideo
, &info
, &bytes
))
707 if (!(videodata
= PyString_FromStringAndSize(NULL
, bytes
)))
710 str
= PyString_AsString(videodata
);
714 if (svCaptureOneFrame(self
->ob_svideo
, format
, &width
, &height
, str
)) {
719 res
= Py_BuildValue("(iiO)", width
, height
, videodata
);
722 Py_XDECREF(videodata
);
727 sv_InitContinuousCapture(self
, args
)
733 if (!PyArg_Parse(args
, "(iiiii)", &info
.format
,
734 &info
.width
, &info
.height
,
735 &info
.size
, &info
.samplingrate
))
738 if (svInitContinuousCapture(self
->ob_svideo
, &info
))
741 self
->ob_info
= info
;
743 return Py_BuildValue("(iiiii)", info
.format
, info
.width
, info
.height
,
744 info
.size
, info
.samplingrate
);
748 sv_LoadMap(self
, args
)
753 PyObject
*res
= NULL
;
754 rgb_tuple
*mapp
= NULL
;
756 int i
, j
; /* indices */
758 if (!PyArg_Parse(args
, "(iO)", &maptype
, &rgb
))
761 if (!PyList_Check(rgb
) || PyList_Size(rgb
) != 256) {
766 if (!(mapp
= PyMem_NEW(rgb_tuple
, 256)))
767 return PyErr_NoMemory();
769 for (i
= 0; i
< 256; i
++) {
770 PyObject
* v
= PyList_GetItem(rgb
, i
);
774 if (!PyTuple_Check(v
) || PyTuple_Size(v
) != 3) {
778 for (j
= 0; j
< 3; j
++) {
779 PyObject
* cell
= PyTuple_GetItem(v
, j
);
783 if (!PyInt_Check(cell
)) {
788 case 0: mapp
[i
].red
= PyInt_AsLong(cell
); break;
789 case 1: mapp
[i
].blue
= PyInt_AsLong(cell
); break;
790 case 2: mapp
[i
].green
= PyInt_AsLong(cell
); break;
792 if (PyErr_Occurred())
797 if (svLoadMap(self
->ob_svideo
, maptype
, mapp
)) {
811 sv_CloseVideo(self
, args
)
815 if (!PyArg_Parse(args
, ""))
818 if (svCloseVideo(self
->ob_svideo
))
821 self
->ob_svideo
= NULL
;
827 doParams(self
, args
, func
, modified
)
830 int (*func
)(SV_nodeP
, long *, int);
834 PyObject
*res
= NULL
;
835 long *PVbuffer
= NULL
;
839 if (!PyArg_Parse(args
, "O", &list
))
842 if (!PyList_Check(list
)) {
847 if ((length
= PyList_Size(list
)) < 0)
850 PVbuffer
= PyMem_NEW(long, length
);
851 if (PVbuffer
== NULL
)
852 return PyErr_NoMemory();
854 for (i
= 0; i
< length
; i
++) {
855 PyObject
*v
= PyList_GetItem(list
, i
);
859 if (!PyInt_Check(v
)) {
863 PVbuffer
[i
] = PyInt_AsLong(v
);
864 /* can't just test the return value, because what if the
867 if (PVbuffer
[i
] == -1 && PyErr_Occurred())
871 if ((*func
)(self
->ob_svideo
, PVbuffer
, length
)) {
877 for (i
= 0; i
< length
; i
++) {
878 PyObject
* v
= PyInt_FromLong(PVbuffer
[i
]);
879 if (!v
|| PyList_SetItem(list
, i
, v
) < 0)
893 sv_GetParam(self
, args
)
894 PyObject
*self
, *args
;
896 return doParams(self
, args
, svGetParam
, 1);
900 sv_GetParamRange(self
, args
)
901 PyObject
*self
, *args
;
903 return doParams(self
, args
, svGetParamRange
, 1);
907 sv_SetParam(self
, args
)
908 PyObject
*self
, *args
;
910 return doParams(self
, args
, svSetParam
, 0);
913 static PyMethodDef svideo_methods
[] = {
914 {"BindGLWindow", (PyCFunction
)sv_BindGLWindow
},
915 {"EndContinuousCapture",(PyCFunction
)sv_EndContinuousCapture
},
916 {"IsVideoDisplayed", (PyCFunction
)sv_IsVideoDisplayed
},
917 {"OutputOffset", (PyCFunction
)sv_OutputOffset
},
918 {"PutFrame", (PyCFunction
)sv_PutFrame
},
919 {"QuerySize", (PyCFunction
)sv_QuerySize
},
920 {"SetSize", (PyCFunction
)sv_SetSize
},
921 {"SetStdDefaults", (PyCFunction
)sv_SetStdDefaults
},
922 {"UseExclusive", (PyCFunction
)sv_UseExclusive
},
923 {"WindowOffset", (PyCFunction
)sv_WindowOffset
},
924 {"InitContinuousCapture",(PyCFunction
)sv_InitContinuousCapture
},
925 {"CaptureBurst", (PyCFunction
)sv_CaptureBurst
},
926 {"CaptureOneFrame", (PyCFunction
)sv_CaptureOneFrame
},
927 {"GetCaptureData", (PyCFunction
)sv_GetCaptureData
},
928 {"CloseVideo", (PyCFunction
)sv_CloseVideo
},
929 {"LoadMap", (PyCFunction
)sv_LoadMap
},
930 {"GetParam", (PyCFunction
)sv_GetParam
},
931 {"GetParamRange", (PyCFunction
)sv_GetParamRange
},
932 {"SetParam", (PyCFunction
)sv_SetParam
},
933 {NULL
, NULL
} /* sentinel */
937 sv_conversion(self
, args
, function
, inputfactor
, factor
)
938 PyObject
*self
, *args
;
943 int invert
, width
, height
, inputlength
;
947 if (!PyArg_Parse(args
, "(is#ii)", &invert
,
948 &input
, &inputlength
, &width
, &height
))
951 if (width
* height
* inputfactor
> inputlength
) {
952 PyErr_SetString(SvError
, "input buffer not long enough");
956 if (!(output
= PyString_FromStringAndSize(NULL
,
957 (int)(width
* height
* factor
))))
960 str
= PyString_AsString(output
);
965 (*function
)(invert
, input
, str
, width
, height
);
971 sv_InterleaveFields(self
, args
)
972 PyObject
*self
, *args
;
974 return sv_conversion(self
, args
, svInterleaveFields
, 1, 1.0);
978 sv_RGB8toRGB32(self
, args
)
979 PyObject
*self
, *args
;
981 return sv_conversion(self
, args
, svRGB8toRGB32
, 1, (float) sizeof(long));
985 sv_YUVtoRGB(self
, args
)
986 PyObject
*self
, *args
;
988 return sv_conversion(self
, args
, svYUVtoRGB
, 2, (float) sizeof(long));
995 if (self
->ob_svideo
!= NULL
)
996 (void) svCloseVideo(self
->ob_svideo
);
1001 svideo_getattr(self
, name
)
1005 return Py_FindMethod(svideo_methods
, (PyObject
*)self
, name
);
1008 PyTypeObject Svtype
= {
1009 PyObject_HEAD_INIT(&PyType_Type
)
1012 sizeof(svobject
), /*tp_size*/
1015 (destructor
)svideo_dealloc
, /*tp_dealloc*/
1017 (getattrfunc
)svideo_getattr
, /*tp_getattr*/
1029 p
= PyObject_NEW(svobject
, &Svtype
);
1033 p
->ob_info
.format
= 0;
1034 p
->ob_info
.size
= 0;
1035 p
->ob_info
.width
= 0;
1036 p
->ob_info
.height
= 0;
1037 p
->ob_info
.samplingrate
= 0;
1038 return (PyObject
*) p
;
1042 sv_OpenVideo(self
, args
)
1043 PyObject
*self
, *args
;
1047 if (!PyArg_Parse(args
, ""))
1050 svp
= svOpenVideo();
1054 return newsvobject(svp
);
1057 static PyMethodDef sv_methods
[] = {
1058 {"InterleaveFields", (PyCFunction
)sv_InterleaveFields
},
1059 {"RGB8toRGB32", (PyCFunction
)sv_RGB8toRGB32
},
1060 {"YUVtoRGB", (PyCFunction
)sv_YUVtoRGB
},
1061 {"OpenVideo", (PyCFunction
)sv_OpenVideo
},
1062 {NULL
, NULL
} /* Sentinel */
1070 m
= Py_InitModule("sv", sv_methods
);
1071 d
= PyModule_GetDict(m
);
1073 SvError
= PyErr_NewException("sv.error", NULL
, NULL
);
1074 if (SvError
== NULL
|| PyDict_SetItemString(d
, "error", SvError
) != 0)