1 /* SV module -- interface to the Indigo video board */
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
12 #include "yuv.h" /* for YUV conversion functions */
17 svCaptureInfo ob_info
;
24 svCaptureInfo ob_info
;
28 static PyObject
*SvError
; /* exception sv.error */
30 static PyObject
*newcaptureobject(svobject
*, void *, int);
32 /* Set a SV-specific error from svideo_errno and return NULL */
36 PyErr_SetString(SvError
, svStrerror(svideo_errno
));
41 svc_conversion(captureobject
*self
, PyObject
*args
, void (*function
)(), float factor
)
47 if (!PyArg_Parse(args
, "i", &invert
))
50 if (!(output
= PyString_FromStringAndSize(
52 (int)(self
->ob_info
.width
* self
->ob_info
.height
* factor
))))
56 if (!(outstr
= PyString_AsString(output
))) {
61 (*function
)((boolean
)invert
, self
->ob_capture
,
63 self
->ob_info
.width
, self
->ob_info
.height
);
69 * 3 functions to convert from Starter Video YUV 4:1:1 format to
70 * Compression Library 4:2:2 Duplicate Chroma format.
73 svc_YUVtoYUV422DC(captureobject
*self
, PyObject
*args
)
75 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
76 PyErr_SetString(SvError
, "data has bad format");
79 return svc_conversion(self
, args
, yuv_sv411_to_cl422dc
, 2.0);
83 svc_YUVtoYUV422DC_quarter(captureobject
*self
, PyObject
*args
)
85 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
86 PyErr_SetString(SvError
, "data has bad format");
89 return svc_conversion(self
, args
,
90 yuv_sv411_to_cl422dc_quartersize
, 0.5);
94 svc_YUVtoYUV422DC_sixteenth(captureobject
*self
, PyObject
*args
)
96 if (self
->ob_info
.format
!= SV_YUV411_FRAMES
) {
97 PyErr_SetString(SvError
, "data has bad format");
100 return svc_conversion(self
, args
,
101 yuv_sv411_to_cl422dc_sixteenthsize
, 0.125);
105 svc_YUVtoRGB(captureobject
*self
, PyObject
*args
)
107 switch (self
->ob_info
.format
) {
108 case SV_YUV411_FRAMES
:
109 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER
:
112 PyErr_SetString(SvError
, "data had bad format");
115 return svc_conversion(self
, args
, svYUVtoRGB
, (float) sizeof(long));
119 svc_RGB8toRGB32(captureobject
*self
, PyObject
*args
)
121 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
122 PyErr_SetString(SvError
, "data has bad format");
125 return svc_conversion(self
, args
, svRGB8toRGB32
, (float) sizeof(long));
129 svc_InterleaveFields(captureobject
*self
, PyObject
*args
)
131 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
132 PyErr_SetString(SvError
, "data has bad format");
135 return svc_conversion(self
, args
, svInterleaveFields
, 1.0);
139 svc_GetFields(captureobject
*self
, PyObject
*args
)
143 PyObject
*ret
= NULL
;
147 if (self
->ob_info
.format
!= SV_RGB8_FRAMES
) {
148 PyErr_SetString(SvError
, "data has bad format");
152 fieldsize
= self
->ob_info
.width
* self
->ob_info
.height
/ 2;
153 obcapture
= (char*)self
->ob_capture
;
155 if (!(f1
= PyString_FromStringAndSize(obcapture
, fieldsize
)))
157 if (!(f2
= PyString_FromStringAndSize(obcapture
+ fieldsize
,
160 ret
= PyTuple_Pack(2, f1
, f2
);
169 svc_UnlockCaptureData(captureobject
*self
, PyObject
*args
)
171 if (!PyArg_Parse(args
, ""))
174 if (!self
->ob_mustunlock
) {
175 PyErr_SetString(SvError
, "buffer should not be unlocked");
179 if (svUnlockCaptureData(self
->ob_svideo
->ob_svideo
, self
->ob_capture
))
182 self
->ob_mustunlock
= 0;
192 svc_lrectwrite(captureobject
*self
, PyObject
*args
)
194 Screencoord x1
, x2
, y1
, y2
;
196 if (!PyArg_Parse(args
, "(hhhh)", &x1
, &x2
, &y1
, &y2
))
199 lrectwrite(x1
, x2
, y1
, y2
, (unsigned long *) self
->ob_capture
);
207 svc_writefile(captureobject
*self
, PyObject
*args
)
213 if (!PyArg_Parse(args
, "O", &file
))
216 if (!PyFile_Check(file
)) {
217 PyErr_SetString(SvError
, "not a file object");
221 if (!(fp
= PyFile_AsFile(file
)))
224 size
= self
->ob_info
.width
* self
->ob_info
.height
;
226 if (fwrite(self
->ob_capture
, sizeof(long), size
, fp
) != size
) {
227 PyErr_SetString(SvError
, "writing failed");
236 svc_FindVisibleRegion(captureobject
*self
, PyObject
*args
)
241 if (!PyArg_Parse(args
, ""))
244 if (svFindVisibleRegion(self
->ob_svideo
->ob_svideo
,
245 self
->ob_capture
, &visible
,
246 self
->ob_info
.width
))
249 if (visible
== NULL
) {
250 PyErr_SetString(SvError
, "data in wrong format");
254 return newcaptureobject(self
->ob_svideo
, visible
, 0);
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
},
268 {"lrectwrite", (PyCFunction
)svc_lrectwrite
, METH_OLDARGS
},
270 {"writefile", (PyCFunction
)svc_writefile
, METH_OLDARGS
},
271 {NULL
, NULL
} /* sentinel */
275 capture_dealloc(captureobject
*self
)
277 if (self
->ob_capture
!= NULL
) {
278 if (self
->ob_mustunlock
)
279 (void)svUnlockCaptureData(self
->ob_svideo
->ob_svideo
,
281 self
->ob_capture
= NULL
;
282 Py_DECREF(self
->ob_svideo
);
283 self
->ob_svideo
= NULL
;
289 capture_getattr(svobject
*self
, char *name
)
291 return Py_FindMethod(capture_methods
, (PyObject
*)self
, name
);
294 PyTypeObject Capturetype
= {
295 PyObject_HEAD_INIT(&PyType_Type
)
297 "sv.capture", /*tp_name*/
298 sizeof(captureobject
), /*tp_size*/
301 (destructor
)capture_dealloc
, /*tp_dealloc*/
303 (getattrfunc
)capture_getattr
, /*tp_getattr*/
310 newcaptureobject(svobject
*self
, void *ptr
, int mustunlock
)
314 p
= PyObject_New(captureobject
, &Capturetype
);
320 p
->ob_mustunlock
= mustunlock
;
321 p
->ob_info
= self
->ob_info
;
322 return (PyObject
*) p
;
326 sv_GetCaptureData(svobject
*self
, PyObject
*args
)
332 if (!PyArg_Parse(args
, ""))
335 if (svGetCaptureData(self
->ob_svideo
, &ptr
, &fieldID
))
339 PyErr_SetString(SvError
, "no data available");
343 c
= newcaptureobject(self
, ptr
, 1);
346 res
= Py_BuildValue("(Oi)", c
, fieldID
);
352 sv_BindGLWindow(svobject
*self
, PyObject
*args
)
357 if (!PyArg_Parse(args
, "(ii)", &wid
, &mode
))
360 if (svBindGLWindow(self
->ob_svideo
, wid
, mode
))
368 sv_EndContinuousCapture(svobject
*self
, PyObject
*args
)
371 if (!PyArg_Parse(args
, ""))
374 if (svEndContinuousCapture(self
->ob_svideo
))
382 sv_IsVideoDisplayed(svobject
*self
, PyObject
*args
)
386 if (!PyArg_Parse(args
, ""))
389 v
= svIsVideoDisplayed(self
->ob_svideo
);
393 return PyInt_FromLong((long) v
);
397 sv_OutputOffset(svobject
*self
, PyObject
*args
)
402 if (!PyArg_Parse(args
, "(ii)", &x_offset
, &y_offset
))
405 if (svOutputOffset(self
->ob_svideo
, x_offset
, y_offset
))
413 sv_PutFrame(svobject
*self
, PyObject
*args
)
417 if (!PyArg_Parse(args
, "s", &buffer
))
420 if (svPutFrame(self
->ob_svideo
, buffer
))
428 sv_QuerySize(svobject
*self
, PyObject
*args
)
435 if (!PyArg_Parse(args
, "(ii)", &w
, &h
))
438 if (svQuerySize(self
->ob_svideo
, w
, h
, &rw
, &rh
))
441 return Py_BuildValue("(ii)", (long) rw
, (long) rh
);
445 sv_SetSize(svobject
*self
, PyObject
*args
)
450 if (!PyArg_Parse(args
, "(ii)", &w
, &h
))
453 if (svSetSize(self
->ob_svideo
, w
, h
))
461 sv_SetStdDefaults(svobject
*self
, PyObject
*args
)
464 if (!PyArg_Parse(args
, ""))
467 if (svSetStdDefaults(self
->ob_svideo
))
475 sv_UseExclusive(svobject
*self
, PyObject
*args
)
480 if (!PyArg_Parse(args
, "(ii)", &onoff
, &mode
))
483 if (svUseExclusive(self
->ob_svideo
, onoff
, mode
))
491 sv_WindowOffset(svobject
*self
, PyObject
*args
)
496 if (!PyArg_Parse(args
, "(ii)", &x_offset
, &y_offset
))
499 if (svWindowOffset(self
->ob_svideo
, x_offset
, y_offset
))
507 sv_CaptureBurst(svobject
*self
, PyObject
*args
)
511 void *bitvector
= NULL
;
512 PyObject
*videodata
= NULL
;
513 PyObject
*bitvecobj
= NULL
;
514 PyObject
*res
= NULL
;
515 static PyObject
*evenitem
, *odditem
;
517 if (!PyArg_Parse(args
, "(iiiii)", &info
.format
,
518 &info
.width
, &info
.height
,
519 &info
.size
, &info
.samplingrate
))
522 switch (info
.format
) {
524 bitvector
= malloc(SV_BITVEC_SIZE(info
.size
));
526 case SV_YUV411_FRAMES_AND_BLANKING_BUFFER
:
529 PyErr_SetString(SvError
, "illegal format specified");
533 if (svQueryCaptureBufferSize(self
->ob_svideo
, &info
, &bytes
)) {
538 if (!(videodata
= PyString_FromStringAndSize(NULL
, bytes
)))
541 /* XXX -- need to do something about the bitvector */
543 char* str
= PyString_AsString(videodata
);
547 if (svCaptureBurst(self
->ob_svideo
, &info
, str
, bitvector
)) {
554 if (evenitem
== NULL
) {
555 if (!(evenitem
= PyInt_FromLong(0)))
558 if (odditem
== NULL
) {
559 if (!(odditem
= PyInt_FromLong(1)))
562 if (!(bitvecobj
= PyTuple_New(2 * info
.size
)))
565 for (i
= 0; i
< 2 * info
.size
; i
++) {
568 if (SV_GET_FIELD(bitvector
, i
) == SV_EVEN_FIELD
) {
570 sts
= PyTuple_SetItem(bitvecobj
, i
, evenitem
);
573 sts
= PyTuple_SetItem(bitvecobj
, i
, odditem
);
583 res
= Py_BuildValue("((iiiii)OO)", info
.format
,
584 info
.width
, info
.height
,
585 info
.size
, info
.samplingrate
,
586 videodata
, bitvecobj
);
592 Py_XDECREF(videodata
);
593 Py_XDECREF(bitvecobj
);
598 sv_CaptureOneFrame(svobject
*self
, PyObject
*args
)
601 int format
, width
, height
;
603 PyObject
*videodata
= NULL
;
604 PyObject
*res
= NULL
;
607 if (!PyArg_Parse(args
, "(iii)", &format
, &width
, &height
))
610 info
.format
= format
;
612 info
.height
= height
;
614 info
.samplingrate
= 0;
615 if (svQueryCaptureBufferSize(self
->ob_svideo
, &info
, &bytes
))
618 if (!(videodata
= PyString_FromStringAndSize(NULL
, bytes
)))
621 str
= PyString_AsString(videodata
);
625 if (svCaptureOneFrame(self
->ob_svideo
, format
, &width
, &height
, str
)) {
630 res
= Py_BuildValue("(iiO)", width
, height
, videodata
);
633 Py_XDECREF(videodata
);
638 sv_InitContinuousCapture(svobject
*self
, PyObject
*args
)
642 if (!PyArg_Parse(args
, "(iiiii)", &info
.format
,
643 &info
.width
, &info
.height
,
644 &info
.size
, &info
.samplingrate
))
647 if (svInitContinuousCapture(self
->ob_svideo
, &info
))
650 self
->ob_info
= info
;
652 return Py_BuildValue("(iiiii)", info
.format
, info
.width
, info
.height
,
653 info
.size
, info
.samplingrate
);
657 sv_LoadMap(svobject
*self
, PyObject
*args
)
660 PyObject
*res
= NULL
;
661 rgb_tuple
*mapp
= NULL
;
663 int i
, j
; /* indices */
665 if (!PyArg_Parse(args
, "(iO)", &maptype
, &rgb
))
668 if (!PyList_Check(rgb
) || PyList_Size(rgb
) != 256) {
673 if (!(mapp
= PyMem_NEW(rgb_tuple
, 256)))
674 return PyErr_NoMemory();
676 for (i
= 0; i
< 256; i
++) {
677 PyObject
* v
= PyList_GetItem(rgb
, i
);
681 if (!PyTuple_Check(v
) || PyTuple_Size(v
) != 3) {
685 for (j
= 0; j
< 3; j
++) {
686 PyObject
* cell
= PyTuple_GetItem(v
, j
);
690 if (!PyInt_Check(cell
)) {
695 case 0: mapp
[i
].red
= PyInt_AsLong(cell
); break;
696 case 1: mapp
[i
].blue
= PyInt_AsLong(cell
); break;
697 case 2: mapp
[i
].green
= PyInt_AsLong(cell
); break;
699 if (PyErr_Occurred())
704 if (svLoadMap(self
->ob_svideo
, maptype
, mapp
)) {
718 sv_CloseVideo(svobject
*self
, PyObject
*args
)
720 if (!PyArg_Parse(args
, ""))
723 if (svCloseVideo(self
->ob_svideo
))
726 self
->ob_svideo
= NULL
;
732 doParams(svobject
*self
, PyObject
*args
,
733 int (*func
)(SV_nodeP
, long *, int), int modified
)
736 PyObject
*res
= NULL
;
737 long *PVbuffer
= NULL
;
741 if (!PyArg_Parse(args
, "O", &list
))
744 if (!PyList_Check(list
)) {
749 if ((length
= PyList_Size(list
)) < 0)
752 PVbuffer
= PyMem_NEW(long, length
);
753 if (PVbuffer
== NULL
)
754 return PyErr_NoMemory();
756 for (i
= 0; i
< length
; i
++) {
757 PyObject
*v
= PyList_GetItem(list
, i
);
761 if (!PyInt_Check(v
)) {
765 PVbuffer
[i
] = PyInt_AsLong(v
);
766 /* can't just test the return value, because what if the
769 if (PVbuffer
[i
] == -1 && PyErr_Occurred())
773 if ((*func
)(self
->ob_svideo
, PVbuffer
, length
)) {
779 for (i
= 0; i
< length
; i
++) {
780 PyObject
* v
= PyInt_FromLong(PVbuffer
[i
]);
781 if (!v
|| PyList_SetItem(list
, i
, v
) < 0)
795 sv_GetParam(PyObject
*self
, PyObject
*args
)
797 return doParams(self
, args
, svGetParam
, 1);
801 sv_GetParamRange(PyObject
*self
, PyObject
*args
)
803 return doParams(self
, args
, svGetParamRange
, 1);
807 sv_SetParam(PyObject
*self
, PyObject
*args
)
809 return doParams(self
, args
, svSetParam
, 0);
812 static PyMethodDef svideo_methods
[] = {
813 {"BindGLWindow", (PyCFunction
)sv_BindGLWindow
, METH_OLDARGS
},
814 {"EndContinuousCapture",(PyCFunction
)sv_EndContinuousCapture
, METH_OLDARGS
},
815 {"IsVideoDisplayed", (PyCFunction
)sv_IsVideoDisplayed
, METH_OLDARGS
},
816 {"OutputOffset", (PyCFunction
)sv_OutputOffset
, METH_OLDARGS
},
817 {"PutFrame", (PyCFunction
)sv_PutFrame
, METH_OLDARGS
},
818 {"QuerySize", (PyCFunction
)sv_QuerySize
, METH_OLDARGS
},
819 {"SetSize", (PyCFunction
)sv_SetSize
, METH_OLDARGS
},
820 {"SetStdDefaults", (PyCFunction
)sv_SetStdDefaults
, METH_OLDARGS
},
821 {"UseExclusive", (PyCFunction
)sv_UseExclusive
, METH_OLDARGS
},
822 {"WindowOffset", (PyCFunction
)sv_WindowOffset
, METH_OLDARGS
},
823 {"InitContinuousCapture",(PyCFunction
)sv_InitContinuousCapture
, METH_OLDARGS
},
824 {"CaptureBurst", (PyCFunction
)sv_CaptureBurst
, METH_OLDARGS
},
825 {"CaptureOneFrame", (PyCFunction
)sv_CaptureOneFrame
, METH_OLDARGS
},
826 {"GetCaptureData", (PyCFunction
)sv_GetCaptureData
, METH_OLDARGS
},
827 {"CloseVideo", (PyCFunction
)sv_CloseVideo
, METH_OLDARGS
},
828 {"LoadMap", (PyCFunction
)sv_LoadMap
, METH_OLDARGS
},
829 {"GetParam", (PyCFunction
)sv_GetParam
, METH_OLDARGS
},
830 {"GetParamRange", (PyCFunction
)sv_GetParamRange
, METH_OLDARGS
},
831 {"SetParam", (PyCFunction
)sv_SetParam
, METH_OLDARGS
},
832 {NULL
, NULL
} /* sentinel */
836 sv_conversion(PyObject
*self
, PyObject
*args
, void (*function
)(),
837 int inputfactor
, float factor
)
839 int invert
, width
, height
, inputlength
;
843 if (!PyArg_Parse(args
, "(is#ii)", &invert
,
844 &input
, &inputlength
, &width
, &height
))
847 if (width
* height
* inputfactor
> inputlength
) {
848 PyErr_SetString(SvError
, "input buffer not long enough");
852 if (!(output
= PyString_FromStringAndSize(NULL
,
853 (int)(width
* height
* factor
))))
856 str
= PyString_AsString(output
);
861 (*function
)(invert
, input
, str
, width
, height
);
867 sv_InterleaveFields(PyObject
*self
, PyObject
*args
)
869 return sv_conversion(self
, args
, svInterleaveFields
, 1, 1.0);
873 sv_RGB8toRGB32(PyObject
*self
, PyObject
*args
)
875 return sv_conversion(self
, args
, svRGB8toRGB32
, 1, (float) sizeof(long));
879 sv_YUVtoRGB(PyObject
*self
, PyObject
*args
)
881 return sv_conversion(self
, args
, svYUVtoRGB
, 2, (float) sizeof(long));
885 svideo_dealloc(svobject
*self
)
887 if (self
->ob_svideo
!= NULL
)
888 (void) svCloseVideo(self
->ob_svideo
);
893 svideo_getattr(svobject
*self
, char *name
)
895 return Py_FindMethod(svideo_methods
, (PyObject
*)self
, name
);
898 PyTypeObject Svtype
= {
899 PyObject_HEAD_INIT(&PyType_Type
)
902 sizeof(svobject
), /*tp_size*/
905 (destructor
)svideo_dealloc
, /*tp_dealloc*/
907 (getattrfunc
)svideo_getattr
, /*tp_getattr*/
914 newsvobject(SV_nodeP svp
)
918 p
= PyObject_New(svobject
, &Svtype
);
922 p
->ob_info
.format
= 0;
924 p
->ob_info
.width
= 0;
925 p
->ob_info
.height
= 0;
926 p
->ob_info
.samplingrate
= 0;
927 return (PyObject
*) p
;
931 sv_OpenVideo(PyObject
*self
, PyObject
*args
)
935 if (!PyArg_Parse(args
, ""))
942 return newsvobject(svp
);
945 static PyMethodDef sv_methods
[] = {
946 {"InterleaveFields", (PyCFunction
)sv_InterleaveFields
, METH_OLDARGS
},
947 {"RGB8toRGB32", (PyCFunction
)sv_RGB8toRGB32
, METH_OLDARGS
},
948 {"YUVtoRGB", (PyCFunction
)sv_YUVtoRGB
, METH_OLDARGS
},
949 {"OpenVideo", (PyCFunction
)sv_OpenVideo
, METH_OLDARGS
},
950 {NULL
, NULL
} /* Sentinel */
958 m
= Py_InitModule("sv", sv_methods
);
961 d
= PyModule_GetDict(m
);
963 SvError
= PyErr_NewException("sv.error", NULL
, NULL
);
964 if (SvError
== NULL
|| PyDict_SetItemString(d
, "error", SvError
) != 0)