diff options
author | lluís gómez i bigordà <lluisbigorda@users.sourceforge.net> | 2009-09-26 12:57:59 +0000 |
---|---|---|
committer | lluís gómez i bigordà <lluisbigorda@users.sourceforge.net> | 2009-09-26 12:57:59 +0000 |
commit | fd6e79aec6693b14ad234eb6c31fb88c01cc5e07 (patch) | |
tree | 18cb1754c80912613d4e6a1bdd2e17039711cdac /modules | |
parent | c8914c3217d54862370902fd36b1f8496cea7c51 (diff) |
added pdp_dc1394
svn path=/trunk/externals/pidip/; revision=12457
Diffstat (limited to 'modules')
-rw-r--r-- | modules/Makefile.in | 2 | ||||
-rwxr-xr-x | modules/pdp_dc1394.c | 456 |
2 files changed, 457 insertions, 1 deletions
diff --git a/modules/Makefile.in b/modules/Makefile.in index 5b3df36..4e408a5 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -21,6 +21,6 @@ OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \ pdp_theorout~.o pdp_cropper.o pdp_background.o \ pdp_mapper.o pdp_theonice~.o pdp_icedthe~.o\ pdp_fdiff.o pdp_hue.o pdp_dot.o pdp_qtext.o\ - @PDP_CAPTURE_OBJECT@ @PDP_STREAMING_OBJECTS@ # pdp_xcanvas.o pdp_aa.o + @PDP_CAPTURE_OBJECT@ @PDP_STREAMING_OBJECTS@ @PDP_DC1394_OBJECT@ # pdp_xcanvas.o pdp_aa.o all_modules: $(OBJECTS) diff --git a/modules/pdp_dc1394.c b/modules/pdp_dc1394.c new file mode 100755 index 0000000..6930fe6 --- /dev/null +++ b/modules/pdp_dc1394.c @@ -0,0 +1,456 @@ +/* + * PiDiP module + * Authors : Yves Degoyon ( ydegoyon@free.fr ) and Lluis Gomez i Bigorda + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* This object is a video 4 linux 2 driver wrapper, + * inspired by pdp_v4l by Tom Schouten + * and some driver code from xawtv ( thanks to Gerd Knorr <kraxel@bytesex.org> ) + */ + + +#include "pdp_config.h" +#include "pdp.h" +#include "pdp_llconv.h" +#include "pdp_imageproc.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <linux/types.h> +#include <sys/mman.h> +#include <sched.h> +#include <pthread.h> +#include <stdint.h> +#include <inttypes.h> +#include <dc1394/dc1394.h> + +// dont open any more after a set number +// of failed attempts +// this is to prevent locks on auto-open +// is reset when manually opened or closed +#define PDP_XV_RETRIES 10 + + +#define DEVICENO 0 +#define NBUF 2 +#define COMPOSITEIN 1 +#define WANTED_BUFFERS 2 +#define MAX_INPUT 16 +#define MAX_NORM 16 +#define MAX_FORMAT 32 +#define MAX_CTRL 32 + +#define IMAGE_FILE_NAME "image.pgm" +/*----------------------------------------------------------------------- + * Releases the cameras and exits + *-----------------------------------------------------------------------*/ +void cleanup_and_exit(dc1394camera_t *camera) +{ + dc1394_video_set_transmission(camera, DC1394_OFF); + dc1394_capture_stop(camera); + dc1394_camera_free(camera); + exit(1); +} + + + +typedef struct pdp_dc1394_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + + bool x_initialized; + bool x_auto_open; + + unsigned int x_width; + unsigned int x_height; + + int x_curinput; + int x_curstandard; + int x_curformat; + int x_freq; + + // video 4 linux 2 structures + int x_ninputs; + int x_nstandards; + int x_nformats; + + unsigned char *x_pdp_buf[WANTED_BUFFERS]; + + int x_tvfd; + int x_frame; + int x_skipnext; + int x_mytopmargin, x_mybottommargin; + int x_myleftmargin, x_myrightmargin; + + t_symbol *x_device; + + pthread_t x_thread_id; + int x_continue_thread; + int x_frame_ready; + int x_only_new_frames; + int x_last_frame; + + int x_open_retry; + + u32 x_minwidth; + u32 x_maxwidth; + u32 x_minheight; + u32 x_maxheight; + + int x_debug; + + + dc1394camera_t *camera; + int i; + dc1394featureset_t features; + dc1394framerates_t framerates; + dc1394video_modes_t video_modes; + dc1394framerate_t framerate; + dc1394video_mode_t video_mode; + dc1394color_coding_t coding; + unsigned int width, height; + dc1394video_frame_t *frame; + dc1394_t * d; + dc1394camera_list_t * list; + + dc1394error_t err; + +} t_pdp_dc1394; + +static void pdp_dc1394_close(t_pdp_dc1394 *x) +{ + +} + +static void pdp_dc1394_close_manual(t_pdp_dc1394 *x) +{ +} + +static void pdp_dc1394_close_error(t_pdp_dc1394 *x) +{ +} + +static int pdp_dc1394_capture_frame(t_pdp_dc1394* x) +{ + return 0; +} + +static void pdp_dc1394_wait_frame(t_pdp_dc1394* x) +{ +} + +static int pdp_dc1394_start_capturing(t_pdp_dc1394 *x) +{ + return 0; +} + +static int pdp_dc1394_stop_capturing(t_pdp_dc1394 *x) +{ + return 0; +} + +static void *pdp_dc1394_thread(void *voidx) +{ + return 0; +} + +static void pdp_dc1394_setlegaldim(t_pdp_dc1394 *x, int xx, int yy); + +static int pdp_dc1394_set_format(t_pdp_dc1394 *x, t_int index) +{ + return 0; +} + +static int pdp_dc1394_init_mmap(t_pdp_dc1394 *x) +{ + return 0; +} + +static void pdp_dc1394_open(t_pdp_dc1394 *x, t_symbol *name) +{ + +} + +static void pdp_dc1394_open_manual(t_pdp_dc1394 *x, t_symbol *name) +{ +} + + + +static void pdp_dc1394_standard(t_pdp_dc1394 *x, t_float f) +{ +} + +static void pdp_dc1394_format(t_pdp_dc1394 *x, t_float f) +{ +} + +static void pdp_dc1394_freq(t_pdp_dc1394 *x, t_float f) +{ +} + +static void pdp_dc1394_freqMHz(t_pdp_dc1394 *x, t_float f) +{ +} + + +static void pdp_dc1394_bang(t_pdp_dc1394 *x) +{ + + /* if initialized, grab a frame and output it */ + + unsigned int w,h,nbpixels,packet_size,plane1,plane2; + unsigned char *newimage=NULL; + int pdp_packt,length,pos,i,encoding; + t_pdp* header; + t_image* image; + unsigned char * data; + + static short int gain[4] = {0x7fff, 0x7fff, 0x7fff, 0x7fff}; + + /*----------------------------------------------------------------------- + * capture one frame + *-----------------------------------------------------------------------*/ + //x->err=dc1394_capture_dequeue(x->camera, DC1394_CAPTURE_POLICY_WAIT, &x->frame); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not capture a frame"); + //post("Could not capture a frame"); + if (x->err=dc1394_capture_dequeue(x->camera, DC1394_CAPTURE_POLICY_WAIT, &x->frame)!=DC1394_SUCCESS) { + post("Failed to capture from camera %d", x->err); + return; + } + + /* create new packet */ + dc1394_get_image_size_from_video_mode(x->camera, x->video_mode, &x->width, &x->height); + + pdp_packt = pdp_packet_new_bitmap_rgb(x->width, x->height); + header = pdp_packet_header(pdp_packt); + //image = pdp_packet_image_info(pdp_packt); + + if (!header){ + post("pdp_dc1394: ERROR: can't allocate packet"); + return; + } + + data = ( unsigned char *) pdp_packet_data(pdp_packt); + int j; + + for (i=0; i<x->width; i++) + for (j=0; j<x->height; j++) { + data[(j*x->width+i)*3] = x->frame->image[j*x->width+i]; + data[(j*x->width+i)*3+1] = x->frame->image[j*x->width+i]; + data[(j*x->width+i)*3+2] = x->frame->image[j*x->width+i]; + } + + //memcpy( data, x->frame->image, x->width*x->height*sizeof( unsigned char) ); + + /*FILE* imagefile=fopen(IMAGE_FILE_NAME, "wb"); + + if( imagefile == NULL) { + perror( "Can't create '" IMAGE_FILE_NAME "'"); + cleanup_and_exit(x->camera); + } + + fprintf(imagefile,"P5\n%u %u 255\n", x->width, x->height); + fwrite(x->frame->image, 1, x->height*x->width, imagefile); + fclose(imagefile); + fprintf(stderr,"wrote: " IMAGE_FILE_NAME "\n");*/ + + if (x->frame) + dc1394_capture_enqueue (x->camera, x->frame); + + pdp_packet_pass_if_valid(x->x_outlet0, &pdp_packt); + +} + + +static void pdp_dc1394_setlegaldim(t_pdp_dc1394 *x, int xx, int yy) +{ + + unsigned int w,h; + + w = pdp_imageproc_legalwidth((int)xx); + h = pdp_imageproc_legalheight((int)yy); + + w = (w < x->x_maxwidth) ? w : x->x_maxwidth; + w = (w > x->x_minwidth) ? w : x->x_minwidth; + + h = (h < x->x_maxheight) ? h : x->x_maxheight; + h = (h > x->x_minheight) ? h : x->x_minheight; + + x->x_width = w; + x->x_height = h; +} + +static void pdp_dc1394_dim(t_pdp_dc1394 *x, t_floatarg xx, t_floatarg yy) +{ + if (!x->x_initialized){ + post( "pdp_dc1394 : cannot set dim : no device opened "); + return; + } + if (x->x_initialized){ + pdp_dc1394_close(x); + pdp_dc1394_setlegaldim(x, (int)xx, (int)yy); + pdp_dc1394_open(x, x->x_device); + } +} + +static void pdp_dc1394_free(t_pdp_dc1394 *x) +{ + dc1394_video_set_transmission(x->camera, DC1394_OFF); + dc1394_capture_stop(x->camera); + dc1394_camera_free(x->camera); + dc1394_free (x->d); +} + +t_class *pdp_dc1394_class; + +void *pdp_dc1394_new(t_symbol *vdef) +{ + t_pdp_dc1394 *x = (t_pdp_dc1394 *)pd_new(pdp_dc1394_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->d = dc1394_new (); + x->err=dc1394_camera_enumerate (x->d, &x->list); + //DC1394_ERR_RTN(x->err,"Failed to enumerate cameras"); + //post("Failed to enumerate cameras"); + + if (x->list->num == 0) { + dc1394_log_error("No cameras found"); + return 1; + } + + x->camera = dc1394_camera_new (x->d, x->list->ids[0].guid); + if (!x->camera) { + //dc1394_log_error("Failed to initialize camera with guid %"PRIx64, list->ids[0].guid); + return 1; + } + dc1394_camera_free_list (x->list); + + //printf("Using camera with GUID %"PRIx64"\n", camera->guid); + + /*----------------------------------------------------------------------- + * get the best video mode and highest framerate. This can be skipped + * if you already know which mode/framerate you want... + *-----------------------------------------------------------------------*/ + // get video modes: + x->err=dc1394_video_get_supported_modes(x->camera,&x->video_modes); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Can't get video modes"); + + // select highest res mode: + for (x->i=x->video_modes.num-1;x->i>=0;x->i--) { + if (!dc1394_is_video_mode_scalable(x->video_modes.modes[x->i])) { + dc1394_get_color_coding_from_video_mode(x->camera,x->video_modes.modes[x->i], &x->coding); + if (x->coding==DC1394_COLOR_CODING_MONO8) { + x->video_mode=x->video_modes.modes[x->i]; + fprintf(stderr,"video_mode %d: %d\n",x->i,x->video_modes.modes[x->i]); + break; + } + } + } + if (x->i < 0) { + dc1394_log_error("Could not get a valid MONO8 mode"); + cleanup_and_exit(x->camera); + } + + x->err=dc1394_get_color_coding_from_video_mode(x->camera, x->video_mode,&x->coding); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not get color coding"); + fprintf(stderr,"color_coding : %d\n",x->coding); + + // get highest framerate + x->err=dc1394_video_get_supported_framerates(x->camera,x->video_mode,&x->framerates); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not get framrates"); + x->framerate=x->framerates.framerates[x->framerates.num-1]; + fprintf(stderr,"framerate : %d\n",x->framerate); + + /*----------------------------------------------------------------------- + * setup capture + *-----------------------------------------------------------------------*/ + + x->err=dc1394_video_set_iso_speed(x->camera, DC1394_ISO_SPEED_400); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not set iso speed"); + + x->err=dc1394_video_set_mode(x->camera, x->video_mode); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not set video mode"); + + x->err=dc1394_video_set_framerate(x->camera, x->framerate); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not set framerate"); + + x->err=dc1394_capture_setup(x->camera,4, DC1394_CAPTURE_FLAGS_DEFAULT); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not setup camera-\nmake sure that the video mode and framerate are\nsupported by your camera"); + + /*----------------------------------------------------------------------- + * report camera's features + *-----------------------------------------------------------------------*/ + x->err=dc1394_feature_get_all(x->camera,&x->features); + if (x->err!=DC1394_SUCCESS) { + dc1394_log_warning("Could not get feature set"); + } + else { + dc1394_feature_print_all(&x->features, stdout); + } + + /*----------------------------------------------------------------------- + * have the camera start sending us data + *-----------------------------------------------------------------------*/ + x->err=dc1394_video_set_transmission(x->camera, DC1394_ON); + //DC1394_ERR_CLN_RTN(x->err,cleanup_and_exit(x->camera),"Could not start camera iso transmission"); + + + + x->x_initialized = true; + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_dc1394_setup(void) +{ + pdp_dc1394_class = class_new(gensym("pdp_dc1394"), (t_newmethod)pdp_dc1394_new, + (t_method)pdp_dc1394_free, sizeof(t_pdp_dc1394), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); + + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_close_manual, gensym("close"), A_NULL); + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_open_manual, gensym("open"), A_SYMBOL, A_NULL); + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_format, gensym("format"), A_FLOAT, A_NULL); + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_standard, gensym("standard"), A_FLOAT, A_NULL); + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_dc1394_class, (t_method)pdp_dc1394_bang, gensym("bang"), A_NULL); + +} + +#ifdef __cplusplus +} +#endif |