Mercurial > pygame
diff src/_camera.c @ 1849:301bc61643a9 math_module
merged changes from trunk
| author | lorenz |
|---|---|
| date | Mon, 16 Nov 2009 18:31:40 +0000 |
| parents | 19a59d1c410b |
| children |
line wrap: on
line diff
--- a/src/_camera.c Mon Nov 16 18:05:30 2009 +0000 +++ b/src/_camera.c Mon Nov 16 18:31:40 2009 +0000 @@ -35,11 +35,14 @@ #include "camera.h" -#if defined(__unix__) +/* +#if defined(__unix__) || !defined(__APPLE__) #else #define V4L2_PIX_FMT_RGB24 1 #define V4L2_PIX_FMT_RGB444 1 #endif +*/ + /* functions available to pygame users */ PyObject* surf_colorspace (PyObject* self, PyObject* arg); @@ -62,8 +65,7 @@ */ /* colorspace() - Surface colorspace conversion */ -PyObject* surf_colorspace (PyObject* self, PyObject* arg) -{ +PyObject* surf_colorspace (PyObject* self, PyObject* arg) { PyObject *surfobj, *surfobj2; SDL_Surface* surf, *newsurf; char* color; @@ -125,9 +127,8 @@ } /* list_cameras() - lists cameras available on the computer */ -PyObject* list_cameras (PyObject* self, PyObject* arg) -{ -#if defined(__unix__) +PyObject* list_cameras (PyObject* self, PyObject* arg) { +#if defined(__unix__) || defined (__APPLE__) PyObject* ret_list; PyObject* string; char** devices; @@ -138,8 +139,12 @@ ret_list = PyList_New (0); if (!ret_list) return NULL; - + + #if defined(__unix__) devices = v4l2_list_cameras(&num_devices); + # elif defined(__APPLE__) + devices = mac_list_cameras(&num_devices); + # endif for(i = 0; i < num_devices; i++) { string = PyString_FromString(devices[i]); @@ -156,8 +161,7 @@ } /* start() - opens, inits, and starts capturing on the camera */ -PyObject* camera_start (PyCameraObject* self) -{ +PyObject* camera_start (PyCameraObject* self) { #if defined(__unix__) if (v4l2_open_device(self) == 0) { if (v4l_open_device(self) == 0) { @@ -185,13 +189,17 @@ return NULL; } } +#elif defined(__APPLE__) + if (! (mac_open_device(self) == 1 && mac_init_device(self) == 1 && mac_start_capturing(self) == 1)) { + mac_close_device(self); + return NULL; + } #endif Py_RETURN_NONE; } /* stop() - stops capturing, uninits, and closes the camera */ -PyObject* camera_stop (PyCameraObject* self) -{ +PyObject* camera_stop (PyCameraObject* self) { #if defined(__unix__) if (v4l2_stop_capturing(self) == 0) return NULL; @@ -199,16 +207,20 @@ return NULL; if (v4l2_close_device(self) == 0) return NULL; +#elif defined(__APPLE__) + if (mac_stop_capturing(self) == 0) + return NULL; + if (mac_close_device(self) == 0) + return NULL; #endif Py_RETURN_NONE; } /* get_controls() - gets current values of user controls */ /* TODO: Support brightness, contrast, and other common controls */ -PyObject* camera_get_controls (PyCameraObject* self) -{ +PyObject* camera_get_controls (PyCameraObject* self) { +#if defined(__unix__) int value; -#if defined(__unix__) if (v4l2_get_control(self->fd, V4L2_CID_HFLIP, &value)) self->hflip = value; @@ -217,13 +229,17 @@ if (v4l2_get_control(self->fd, V4L2_CID_BRIGHTNESS, &value)) self->brightness = value; -#endif + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness)); +#elif defined(__APPLE__) + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1)); +#endif + Py_RETURN_NONE; } /* set_controls() - changes camera settings if supported by the camera */ -PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds) -{ +PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds) { +#if defined(__unix__) int hflip = 0, vflip = 0, brightness = 0; char *kwids[] = {"hflip", "vflip", "brightness", NULL}; @@ -234,7 +250,8 @@ if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness)) return NULL; -#if defined(__unix__) + +/* #if defined(__unix__) */ if (v4l2_set_control(self->fd, V4L2_CID_HFLIP, hflip)) self->hflip = hflip; @@ -243,29 +260,51 @@ if (v4l2_set_control(self->fd, V4L2_CID_BRIGHTNESS, brightness)) self->brightness = brightness; -#endif + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness)); -} + +#elif defined(__APPLE__) + int hflip = 0, vflip = 0, brightness = 0; + char *kwids[] = {"hflip", "vflip", "brightness", NULL}; -/* get_size() - returns the dimensions of the images being recorded */ -PyObject* camera_get_size (PyCameraObject* self) -{ - return Py_BuildValue ("(ii)", self->width, self->height); -} - -/* query_image() - checks if a frame is ready */ -PyObject* camera_query_image (PyCameraObject* self) -{ -#if defined(__unix__) - return PyBool_FromLong(v4l2_query_buffer(self)); + camera_get_controls(self); + hflip = self->hflip; + vflip = self->vflip; + brightness = -1; + + if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness)) + return NULL; + + self->hflip = hflip; + self->vflip = vflip; + + return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1)); #endif Py_RETURN_NONE; } +/* get_size() - returns the dimensions of the images being recorded */ +PyObject* camera_get_size (PyCameraObject* self) { +#if defined(__unix__) + return Py_BuildValue ("(ii)", self->width, self->height); +#elif defined(__APPLE__) + return Py_BuildValue ("(ii)", self->boundsRect.right, self->boundsRect.bottom); +#endif + Py_RETURN_NONE; +} + +/* query_image() - checks if a frame is ready */ +PyObject* camera_query_image(PyCameraObject* self) { +#if defined(__unix__) + return PyBool_FromLong(v4l2_query_buffer(self)); +#endif + Py_RETURN_TRUE; +} + /* get_image() - returns an RGB Surface */ /* code to reuse Surface from René Dudfield */ -PyObject* camera_get_image (PyCameraObject* self, PyObject* arg) -{ +PyObject* camera_get_image (PyCameraObject* self, PyObject* arg) { +#if defined(__unix__) SDL_Surface* surf = NULL; PyObject *surfobj = NULL; @@ -286,12 +325,12 @@ return RAISE (PyExc_ValueError, "Destination surface not the correct width or height."); } -#if defined(__unix__) + Py_BEGIN_ALLOW_THREADS; if (!v4l2_read_frame(self, surf)) return NULL; Py_END_ALLOW_THREADS; -#endif + if (!surf) return NULL; @@ -301,13 +340,60 @@ } else { return PySurface_New (surf); } +#elif defined(__APPLE__) + SDL_Surface* surf = NULL; + PyObject *surfobj = NULL; + + if (!PyArg_ParseTuple (arg, "|O!", &PySurface_Type, &surfobj)) + return NULL; + + if (!surfobj) { + surf = SDL_CreateRGBSurface( + 0, + self->boundsRect.right, + self->boundsRect.bottom, + 24, + 0xFF<<16, + 0xFF<<8, + 0xFF, + 0); + + } else { + surf = PySurface_AsSurface(surfobj); + } + + if (!surf) + return NULL; + + if (surf->w != self->boundsRect.right || surf->h != self->boundsRect.bottom) { + return RAISE (PyExc_ValueError, + "Destination surface not the correct width or height."); + } + /*is dit nodig op osx... */ + Py_BEGIN_ALLOW_THREADS; + + if (!mac_read_frame(self, surf)) + return NULL; + Py_END_ALLOW_THREADS; + if (!surf) + return NULL; + + if (surfobj) { + Py_INCREF (surfobj); + return surfobj; + } else { + return PySurface_New (surf); + } +#endif + Py_RETURN_NONE; } /* get_raw() - returns an unmodified image as a string from the buffer */ -PyObject* camera_get_raw(PyCameraObject* self) -{ +PyObject* camera_get_raw(PyCameraObject* self) { #if defined(__unix__) return v4l2_read_raw(self); +#elif defined(__APPLE__) + return mac_read_raw(self); #endif Py_RETURN_NONE; } @@ -318,8 +404,7 @@ /* converts from rgb Surface to yuv or hsv */ /* TODO: Allow for conversion from yuv and hsv to all */ -void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace) -{ +void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace) { switch (cspace) { case YUV_OUT: rgb_to_yuv (src->pixels, dst->pixels, src->h * src->w, 0, src->format); @@ -671,8 +756,7 @@ } /* Converts from rgb444 (R444) to rgb24 (RGB3) */ -void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint16 *d16; Uint32 *d32; @@ -731,8 +815,7 @@ /* convert from 4:2:2 YUYV interlaced to RGB */ /* colorspace conversion routine from libv4l. Licensed LGPL 2.1 (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> */ -void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint16 *d16; Uint32 *d32; @@ -802,8 +885,7 @@ } /* turn yuyv into packed yuv. */ -void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format) -{ +void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format) { Uint8 *s, *d8; Uint8 y1, u, y2, v; Uint16 *d16; @@ -896,8 +978,7 @@ /* FIXME: Seems to be grayscale and kind of dark on the OLPC XO Maybe the result of a different Bayer color order on the screen? */ /* TODO: Certainly not the most efficient way of doing this conversion. */ -void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { Uint8 *rawpt, *d8; Uint16 *d16; Uint32 *d32; @@ -999,8 +1080,7 @@ /* convert from YUV 4:2:0 (YU12) to RGB24 */ /* based on v4lconvert_yuv420_to_rgb24 in libv4l (C) 2008 Hans de Goede. LGPL */ -void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { int rshift, gshift, bshift, rloss, gloss, bloss, i, j, u1, v1, rg, y; const Uint8 *y1, *y2, *u, *v; Uint8 *d8_1, *d8_2; @@ -1190,8 +1270,7 @@ } /* turn yuv420 into packed yuv. */ -void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) -{ +void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) { const Uint8 *y1, *y2, *u, *v; Uint8 *d8_1, *d8_2; Uint16 *d16_1, *d16_2; @@ -1290,12 +1369,14 @@ } + + /* * Python API stuff */ - -PyMethodDef cameraobj_builtins[] = -{ + +/* Camera class definition */ +PyMethodDef cameraobj_builtins[] = { { "start", (PyCFunction) camera_start, METH_NOARGS, DOC_CAMERASTART }, { "stop", (PyCFunction) camera_stop, METH_NOARGS, DOC_CAMERASTOP }, { "get_controls", (PyCFunction) camera_get_controls, METH_NOARGS, DOC_CAMERAGETCONTROLS }, @@ -1307,19 +1388,16 @@ { NULL, NULL, 0, NULL } }; -void camera_dealloc (PyObject* self) -{ +void camera_dealloc (PyObject* self) { free(((PyCameraObject*) self)->device_name); PyObject_DEL (self); } -PyObject* camera_getattr(PyObject* self, char* attrname) -{ +PyObject* camera_getattr(PyObject* self, char* attrname) { return Py_FindMethod(cameraobj_builtins, self, attrname); } -PyTypeObject PyCamera_Type = -{ +PyTypeObject PyCamera_Type = { PyObject_HEAD_INIT(NULL) 0, "Camera", @@ -1328,21 +1406,21 @@ camera_dealloc, 0, camera_getattr, - NULL, /*setattr*/ - NULL, /*compare*/ - NULL, /*repr*/ - NULL, /*as_number*/ - NULL, /*as_sequence*/ - NULL, /*as_mapping*/ + NULL, /*setattr*/ + NULL, /*compare*/ + NULL, /*repr*/ + NULL, /*as_number*/ + NULL, /*as_sequence*/ + NULL, /*as_mapping*/ (hashfunc)NULL, /*hash*/ (ternaryfunc)NULL, /*call*/ (reprfunc)NULL, /*str*/ 0L,0L,0L,0L, - DOC_PYGAMECAMERACAMERA /* Documentation string */ + DOC_PYGAMECAMERACAMERA /* Documentation string */ }; -PyObject* Camera (PyCameraObject* self, PyObject* arg) -{ +PyObject* Camera (PyCameraObject* self, PyObject* arg) { +# if defined(__unix__) int w, h; char* dev_name = NULL; char* color = NULL; @@ -1384,36 +1462,78 @@ } return (PyObject*)cameraobj; + +# elif defined(__APPLE__) + int w, h; + char* dev_name = NULL; + char* color = NULL; + PyCameraObject *cameraobj; + + w = DEFAULT_WIDTH; + h = DEFAULT_HEIGHT; + + if (!PyArg_ParseTuple(arg, "s|(ii)s", &dev_name, &w, &h, &color)) + return NULL; + + cameraobj = PyObject_NEW (PyCameraObject, &PyCamera_Type); + + if (cameraobj) { + cameraobj->device_name = (char*) malloc((strlen(dev_name)+1)*sizeof(char)); + strcpy(cameraobj->device_name, dev_name); + if (color) { + if (!strcmp(color, "YUV")) { + cameraobj->color_out = YUV_OUT; + } else if (!strcmp(color, "HSV")) { + cameraobj->color_out = HSV_OUT; + } else { + cameraobj->color_out = RGB_OUT; + } + } else { + cameraobj->color_out = RGB_OUT; + } + cameraobj->component = NULL; + cameraobj->channel = NULL; + cameraobj->gworld = NULL; + cameraobj->boundsRect.top = 0; + cameraobj->boundsRect.left = 0; + cameraobj->boundsRect.bottom = h; + cameraobj->boundsRect.right = w; + cameraobj->size = w * h; + cameraobj->hflip = 0; + cameraobj->vflip = 0; + } + + return (PyObject*)cameraobj; + # endif } -PyMethodDef camera_builtins[] = -{ - { "colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE }, - { "list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS }, - { "Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA }, - { NULL, NULL, 0, NULL } +/* Camera module definition */ +PyMethodDef camera_builtins[] = { + {"colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE }, + {"list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS }, + {"Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA }, + {NULL, NULL, 0, NULL } }; -void init_camera(void) -{ - PyObject *module, *dict; - /* imported needed apis; Do this first so if there is an error - the module is not loaded. - */ - import_pygame_base (); - if (PyErr_Occurred ()) { - return; - } - import_pygame_surface (); - if (PyErr_Occurred ()) { - return; - } +void init_camera(void) { + PyObject *module, *dict; + /* imported needed apis; Do this first so if there is an error + * the module is not loaded. + */ + import_pygame_base(); + if (PyErr_Occurred()) { + return; + } + import_pygame_surface(); + if (PyErr_Occurred()) { + return; + } - /* type preparation */ - PyType_Init(PyCamera_Type); + /* type preparation */ + PyType_Init(PyCamera_Type); - /* create the module */ - module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA); - dict = PyModule_GetDict(module); - PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type); + /* create the module */ + module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA); + dict = PyModule_GetDict(module); + PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type); }
