/* SV module -- interface to the Indigo video board */

/* WARNING! This module is for hardware that we don't have any more,
   so it hasn't been tested.  It has been converted to the new coding
   style, and it is possible that this conversion has broken something
   -- user beware! */

#include <sys/time.h>
#include <svideo.h>
#include "Python.h"
#include "compile.h"
#include "yuv.h"		/* for YUV conversion functions */

typedef struct {
	PyObject_HEAD
	SV_nodeP ob_svideo;
	svCaptureInfo ob_info;
} svobject;

typedef struct {
	PyObject_HEAD
	void *ob_capture;
	int ob_mustunlock;
	svCaptureInfo ob_info;
	svobject *ob_svideo;
} captureobject;

static PyObject *SvError;		/* exception sv.error */

static PyObject *newcaptureobject(svobject *, void *, int);

/* Set a SV-specific error from svideo_errno and return NULL */
static PyObject *
sv_error(void)
{
	PyErr_SetString(SvError, svStrerror(svideo_errno));
	return NULL;
}

static PyObject *
svc_conversion(captureobject *self, PyObject *args, void (*function)(),	float factor)
{
	PyObject *output;
	int invert;
	char* outstr;

	if (!PyArg_Parse(args, "i", &invert))
		return NULL;

	if (!(output = PyString_FromStringAndSize(
		NULL,
		(int)(self->ob_info.width * self->ob_info.height * factor))))
	{
		return NULL;
	}
	if (!(outstr = PyString_AsString(output))) {
		Py_DECREF(output);
		return NULL;
	}

	(*function)((boolean)invert, self->ob_capture,
		    outstr,
		    self->ob_info.width, self->ob_info.height);

	return output;
}

/*
 * 3 functions to convert from Starter Video YUV 4:1:1 format to
 * Compression Library 4:2:2 Duplicate Chroma format.
 */
static PyObject *
svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}

static PyObject *
svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args,
			      yuv_sv411_to_cl422dc_quartersize, 0.5);
}

static PyObject *
svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args,
			      yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}

static PyObject *
svc_YUVtoRGB(captureobject *self, PyObject *args)
{
	switch (self->ob_info.format) {
	case SV_YUV411_FRAMES:
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		PyErr_SetString(SvError, "data had bad format");
		return NULL;
	}
	return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}

static PyObject *
svc_RGB8toRGB32(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}

static PyObject *
svc_InterleaveFields(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svInterleaveFields, 1.0);
}

static PyObject *
svc_GetFields(captureobject *self, PyObject *args)
{
	PyObject *f1 = NULL;
	PyObject *f2 = NULL;
	PyObject *ret = NULL;
	int fieldsize;
	char* obcapture;

	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}

	fieldsize = self->ob_info.width * self->ob_info.height / 2;
	obcapture = (char*)self->ob_capture;
	
	if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
		goto finally;
	if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
					      fieldsize)))
		goto finally;
	ret = Py_BuildValue("(OO)", f1, f2);

  finally:
	Py_XDECREF(f1);
	Py_XDECREF(f2);
	return ret;
}
	
static PyObject *
svc_UnlockCaptureData(captureobject *self, PyObject *args)
{
	if (!PyArg_Parse(args, ""))
		return NULL;

	if (!self->ob_mustunlock) {
		PyErr_SetString(SvError, "buffer should not be unlocked");
		return NULL;
	}

	if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
		return sv_error();

	self->ob_mustunlock = 0;

	Py_INCREF(Py_None);
	return Py_None;
}

#ifdef USE_GL
#include <gl.h>

static PyObject *
svc_lrectwrite(captureobject *self, PyObject *args)
{
	Screencoord x1, x2, y1, y2;

	if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
		return NULL;

	lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);

	Py_INCREF(Py_None);
	return Py_None;
}
#endif

static PyObject *
svc_writefile(captureobject *self, PyObject *args)
{
	PyObject *file;
	int size;
	FILE* fp;

	if (!PyArg_Parse(args, "O", &file))
		return NULL;

	if (!PyFile_Check(file)) {
		PyErr_SetString(SvError, "not a file object");
		return NULL;
	}

	if (!(fp = PyFile_AsFile(file)))
		return NULL;

	size = self->ob_info.width * self->ob_info.height;

	if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
		PyErr_SetString(SvError, "writing failed");
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
svc_FindVisibleRegion(captureobject *self, PyObject *args)
{
	void *visible;
	int width;

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
				self->ob_capture, &visible,
				self->ob_info.width))
		return sv_error();

	if (visible == NULL) {
		PyErr_SetString(SvError, "data in wrong format");
		return NULL;
	}

	return newcaptureobject(self->ob_svideo, visible, 0);
}

static PyMethodDef capture_methods[] = {
	{"YUVtoRGB",		(PyCFunction)svc_YUVtoRGB},
	{"RGB8toRGB32",		(PyCFunction)svc_RGB8toRGB32},
	{"InterleaveFields",	(PyCFunction)svc_InterleaveFields},
	{"UnlockCaptureData",	(PyCFunction)svc_UnlockCaptureData},
	{"FindVisibleRegion",	(PyCFunction)svc_FindVisibleRegion},
	{"GetFields",		(PyCFunction)svc_GetFields},
	{"YUVtoYUV422DC",	(PyCFunction)svc_YUVtoYUV422DC},
	{"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter},
	{"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth},
#ifdef USE_GL
	{"lrectwrite",		(PyCFunction)svc_lrectwrite},
#endif
	{"writefile",		(PyCFunction)svc_writefile},
	{NULL,			NULL} 		/* sentinel */
};

static void
capture_dealloc(captureobject *self)
{
	if (self->ob_capture != NULL) {
		if (self->ob_mustunlock)
			(void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
						  self->ob_capture);
		self->ob_capture = NULL;
		Py_DECREF(self->ob_svideo);
		self->ob_svideo = NULL;
	}
	PyObject_Del(self);
}

static PyObject *
capture_getattr(svobject *self, char *name)
{
	return Py_FindMethod(capture_methods, (PyObject *)self, name);
}

PyTypeObject Capturetype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"sv.capture",			/*tp_name*/
	sizeof(captureobject),		/*tp_size*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)capture_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)capture_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
};

static PyObject *
newcaptureobject(svobject *self, void *ptr, int mustunlock)
{
	captureobject *p;

	p = PyObject_New(captureobject, &Capturetype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = self;
	Py_INCREF(self);
	p->ob_capture = ptr;
	p->ob_mustunlock = mustunlock;
	p->ob_info = self->ob_info;
	return (PyObject *) p;
}

static PyObject *
sv_GetCaptureData(svobject *self, PyObject *args)
{
	void *ptr;
	long fieldID;
	PyObject *res, *c;

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
		return sv_error();

	if (ptr == NULL) {
		PyErr_SetString(SvError, "no data available");
		return NULL;
	}

	c = newcaptureobject(self, ptr, 1);
	if (c == NULL)
		return NULL;
	res = Py_BuildValue("(Oi)", c, fieldID);
	Py_DECREF(c);
	return res;
}

static PyObject *
sv_BindGLWindow(svobject *self, PyObject *args)
{
	long wid;
	int mode;

	if (!PyArg_Parse(args, "(ii)", &wid, &mode))
		return NULL;

	if (svBindGLWindow(self->ob_svideo, wid, mode))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_EndContinuousCapture(svobject *self, PyObject *args)
{

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svEndContinuousCapture(self->ob_svideo))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_IsVideoDisplayed(svobject *self, PyObject *args)
{
	int v;

	if (!PyArg_Parse(args, ""))
		return NULL;

	v = svIsVideoDisplayed(self->ob_svideo);
	if (v == -1)
		return sv_error();

	return PyInt_FromLong((long) v);
}

static PyObject *
sv_OutputOffset(svobject *self, PyObject *args)
{
	int x_offset;
	int y_offset;

	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_PutFrame(svobject *self, PyObject *args)
{
	char *buffer;

	if (!PyArg_Parse(args, "s", &buffer))
		return NULL;

	if (svPutFrame(self->ob_svideo, buffer))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_QuerySize(svobject *self, PyObject *args)
{
	int w;
	int h;
	int rw;
	int rh;

	if (!PyArg_Parse(args, "(ii)", &w, &h))
		return NULL;

	if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
		return sv_error();

	return Py_BuildValue("(ii)", (long) rw, (long) rh);
}

static PyObject *
sv_SetSize(svobject *self, PyObject *args)
{
	int w;
	int h;

	if (!PyArg_Parse(args, "(ii)", &w, &h))
		return NULL;

	if (svSetSize(self->ob_svideo, w, h))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_SetStdDefaults(svobject *self, PyObject *args)
{

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svSetStdDefaults(self->ob_svideo))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_UseExclusive(svobject *self, PyObject *args)
{
	boolean onoff;
	int mode;

	if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
		return NULL;

	if (svUseExclusive(self->ob_svideo, onoff, mode))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_WindowOffset(svobject *self, PyObject *args)
{
	int x_offset;
	int y_offset;

	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_CaptureBurst(svobject *self, PyObject *args)
{
	int bytes, i;
	svCaptureInfo info;
	void *bitvector = NULL;
	PyObject *videodata = NULL;
	PyObject *bitvecobj = NULL;
	PyObject *res = NULL;
	static PyObject *evenitem, *odditem;

	if (!PyArg_Parse(args, "(iiiii)", &info.format,
			 &info.width, &info.height,
			 &info.size, &info.samplingrate))
		return NULL;

	switch (info.format) {
	case SV_RGB8_FRAMES:
		bitvector = malloc(SV_BITVEC_SIZE(info.size));
		break;
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		PyErr_SetString(SvError, "illegal format specified");
		return NULL;
	}

	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
		res = sv_error();
		goto finally;
	}

	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
		goto finally;

	/* XXX -- need to do something about the bitvector */
	{
		char* str = PyString_AsString(videodata);
		if (!str)
			goto finally;
		
		if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
			res = sv_error();
			goto finally;
		}
	}

	if (bitvector) {
		if (evenitem == NULL) {
			if (!(evenitem = PyInt_FromLong(0)))
				goto finally;
		}
		if (odditem == NULL) {
			if (!(odditem = PyInt_FromLong(1)))
				goto finally;
		}
		if (!(bitvecobj = PyTuple_New(2 * info.size)))
			goto finally;

		for (i = 0; i < 2 * info.size; i++) {
			int sts;

			if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
				Py_INCREF(evenitem);
				sts = PyTuple_SetItem(bitvecobj, i, evenitem);
			} else {
				Py_INCREF(odditem);
				sts = PyTuple_SetItem(bitvecobj, i, odditem);
			}
			if (sts < 0)
				goto finally;
		}
	} else {
		bitvecobj = Py_None;
		Py_INCREF(Py_None);
	}

	res = Py_BuildValue("((iiiii)OO)", info.format,
			    info.width, info.height,
			    info.size, info.samplingrate,
			    videodata, bitvecobj);

  finally:
	if (bitvector)
		free(bitvector);

	Py_XDECREF(videodata);
	Py_XDECREF(bitvecobj);
	return res;
}

static PyObject *
sv_CaptureOneFrame(svobject *self, PyObject *args)
{
	svCaptureInfo info;
	int format, width, height;
	int bytes;
	PyObject *videodata = NULL;
	PyObject *res = NULL;
	char *str;
	
	if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
		return NULL;

	info.format = format;
	info.width = width;
	info.height = height;
	info.size = 0;
	info.samplingrate = 0;
	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
		return sv_error();

	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
		return NULL;
	
	str = PyString_AsString(videodata);
	if (!str)
		goto finally;

	if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
		res = sv_error();
		goto finally;
	}

	res = Py_BuildValue("(iiO)", width, height, videodata);

  finally:
	Py_XDECREF(videodata);
	return res;
}

static PyObject *
sv_InitContinuousCapture(svobject *self, PyObject *args)
{
	svCaptureInfo info;

	if (!PyArg_Parse(args, "(iiiii)", &info.format,
			 &info.width, &info.height,
			 &info.size, &info.samplingrate))
		return NULL;

	if (svInitContinuousCapture(self->ob_svideo, &info))
		return sv_error();

	self->ob_info = info;

	return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
			     info.size, info.samplingrate);
}

static PyObject *
sv_LoadMap(svobject *self, PyObject *args)
{
	PyObject *rgb;
	PyObject *res = NULL;
	rgb_tuple *mapp = NULL;
	int maptype;
	int i, j;			     /* indices */

	if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
		return NULL;

	if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
		PyErr_BadArgument();
		return NULL;
	}

	if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
		return PyErr_NoMemory();

	for (i = 0; i < 256; i++) {
		PyObject* v = PyList_GetItem(rgb, i);
		if (!v)
			goto finally;

		if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
			PyErr_BadArgument();
			goto finally;
		}
		for (j = 0; j < 3; j++) {
			PyObject* cell = PyTuple_GetItem(v, j);
			if (!cell)
				goto finally;

			if (!PyInt_Check(cell)) {
				PyErr_BadArgument();
				goto finally;
			}
			switch (j) {
			case 0: mapp[i].red = PyInt_AsLong(cell); break;
			case 1: mapp[i].blue = PyInt_AsLong(cell); break;
			case 2: mapp[i].green = PyInt_AsLong(cell); break;
			}
			if (PyErr_Occurred())
				goto finally;
		}
	}

	if (svLoadMap(self->ob_svideo, maptype, mapp)) {
		res = sv_error();
		goto finally;
	}

	Py_INCREF(Py_None);
	res = Py_None;

  finally:
	PyMem_DEL(mapp);
	return res;
}
		
static PyObject *
sv_CloseVideo(svobject *self, PyObject *args)
{
	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svCloseVideo(self->ob_svideo))
		return sv_error();

	self->ob_svideo = NULL;
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
doParams(svobject *self, PyObject *args,
         int (*func)(SV_nodeP, long *, int), int modified)
{
	PyObject *list;
	PyObject *res = NULL;
	long *PVbuffer = NULL;
	long length;
	int i;
	
	if (!PyArg_Parse(args, "O", &list))
		return NULL;

	if (!PyList_Check(list)) {
		PyErr_BadArgument();
		return NULL;
	}

	if ((length = PyList_Size(list)) < 0)
		return NULL;

	PVbuffer = PyMem_NEW(long, length);
	if (PVbuffer == NULL)
		return PyErr_NoMemory();

	for (i = 0; i < length; i++) {
		PyObject *v = PyList_GetItem(list, i);
		if (!v)
			goto finally;

		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			goto finally;
		}
		PVbuffer[i] = PyInt_AsLong(v);
		/* can't just test the return value, because what if the
		   value was -1?!
		*/
		if (PVbuffer[i] == -1 && PyErr_Occurred())
			goto finally;
	}

	if ((*func)(self->ob_svideo, PVbuffer, length)) {
		res = sv_error();
		goto finally;
	}

	if (modified) {
		for (i = 0; i < length; i++) {
			PyObject* v = PyInt_FromLong(PVbuffer[i]);
			if (!v || PyList_SetItem(list, i, v) < 0)
				goto finally;
		}
	}

	Py_INCREF(Py_None);
	res = Py_None;

  finally:
	PyMem_DEL(PVbuffer);
	return res;
}

static PyObject *
sv_GetParam(PyObject *self, PyObject *args)
{
	return doParams(self, args, svGetParam, 1);
}

static PyObject *
sv_GetParamRange(PyObject *self, PyObject *args)
{
	return doParams(self, args, svGetParamRange, 1);
}

static PyObject *
sv_SetParam(PyObject *self, PyObject *args)
{
	return doParams(self, args, svSetParam, 0);
}

static PyMethodDef svideo_methods[] = {
	{"BindGLWindow",	(PyCFunction)sv_BindGLWindow},
	{"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture},
	{"IsVideoDisplayed",	(PyCFunction)sv_IsVideoDisplayed},
	{"OutputOffset",	(PyCFunction)sv_OutputOffset},
	{"PutFrame",		(PyCFunction)sv_PutFrame},
	{"QuerySize",		(PyCFunction)sv_QuerySize},
	{"SetSize",		(PyCFunction)sv_SetSize},
	{"SetStdDefaults",	(PyCFunction)sv_SetStdDefaults},
	{"UseExclusive",	(PyCFunction)sv_UseExclusive},
	{"WindowOffset",	(PyCFunction)sv_WindowOffset},
	{"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture},
	{"CaptureBurst",	(PyCFunction)sv_CaptureBurst},
	{"CaptureOneFrame",	(PyCFunction)sv_CaptureOneFrame},
	{"GetCaptureData",	(PyCFunction)sv_GetCaptureData},
	{"CloseVideo",		(PyCFunction)sv_CloseVideo},
	{"LoadMap",		(PyCFunction)sv_LoadMap},
	{"GetParam",		(PyCFunction)sv_GetParam},
	{"GetParamRange",	(PyCFunction)sv_GetParamRange},
	{"SetParam",		(PyCFunction)sv_SetParam},
	{NULL,			NULL} 		/* sentinel */
};

static PyObject *
sv_conversion(PyObject *self, PyObject *args, void (*function)(),
              int inputfactor, float factor)
{
	int invert, width, height, inputlength;
	char *input, *str;
	PyObject *output;

	if (!PyArg_Parse(args, "(is#ii)", &invert,
			 &input, &inputlength, &width, &height))
		return NULL;

	if (width * height * inputfactor > inputlength) {
		PyErr_SetString(SvError, "input buffer not long enough");
		return NULL;
	}

	if (!(output = PyString_FromStringAndSize(NULL,
					      (int)(width * height * factor))))
		return NULL;

	str = PyString_AsString(output);
	if (!str) {
		Py_DECREF(output);
		return NULL;
	}
	(*function)(invert, input, str, width, height);

	return output;
}

static PyObject *
sv_InterleaveFields(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

static PyObject *
sv_RGB8toRGB32(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}

static PyObject *
sv_YUVtoRGB(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}

static void
svideo_dealloc(svobject *self)
{
	if (self->ob_svideo != NULL)
		(void) svCloseVideo(self->ob_svideo);
	PyObject_Del(self);
}

static PyObject *
svideo_getattr(svobject *self, char *name)
{
	return Py_FindMethod(svideo_methods, (PyObject *)self, name);
}

PyTypeObject Svtype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,			/*ob_size*/
	"sv.sv",		/*tp_name*/
	sizeof(svobject),	/*tp_size*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)svideo_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)svideo_getattr, /*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
};

static PyObject *
newsvobject(SV_nodeP svp)
{
	svobject *p;

	p = PyObject_New(svobject, &Svtype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = svp;
	p->ob_info.format = 0;
	p->ob_info.size = 0;
	p->ob_info.width = 0;
	p->ob_info.height = 0;
	p->ob_info.samplingrate = 0;
	return (PyObject *) p;
}

static PyObject *
sv_OpenVideo(PyObject *self, PyObject *args)
{
	SV_nodeP svp;

	if (!PyArg_Parse(args, ""))
		return NULL;

	svp = svOpenVideo();
	if (svp == NULL)
		return sv_error();

	return newsvobject(svp);
}

static PyMethodDef sv_methods[] = {
	{"InterleaveFields",	(PyCFunction)sv_InterleaveFields},
	{"RGB8toRGB32",		(PyCFunction)sv_RGB8toRGB32},
	{"YUVtoRGB",		(PyCFunction)sv_YUVtoRGB},
	{"OpenVideo",		(PyCFunction)sv_OpenVideo},
	{NULL,			NULL}	/* Sentinel */
};

void
initsv(void)
{
	PyObject *m, *d;

	m = Py_InitModule("sv", sv_methods);
	d = PyModule_GetDict(m);

	SvError = PyErr_NewException("sv.error", NULL, NULL);
	if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
		return;
}
