From b694c274836ac8b04d644711ac324eac2e9ab83e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 16 Dec 2005 01:05:40 +0000 Subject: checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz svn path=/trunk/externals/pdp/; revision=4232 --- modules/image_io/pdp_v4l.c | 835 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 835 insertions(+) create mode 100644 modules/image_io/pdp_v4l.c (limited to 'modules/image_io/pdp_v4l.c') diff --git a/modules/image_io/pdp_v4l.c b/modules/image_io/pdp_v4l.c new file mode 100644 index 0000000..85c34f1 --- /dev/null +++ b/modules/image_io/pdp_v4l.c @@ -0,0 +1,835 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten + * + * 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. + * + */ + + +#include "pdp_config.h" +#include "pdp.h" +#include "pdp_llconv.h" +#include "pdp_imageproc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 + +//include it anyway +//#ifdef HAVE_PWCV4L +#include "pwc-ioctl.h" +//#endif + + +#define DEVICENO 0 +#define NBUF 2 +#define COMPOSITEIN 1 + + + + +typedef struct pdp_v4l_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet0; + + int x_format; // 0 means autodetect + + bool x_initialized; + bool x_auto_open; + + unsigned int x_width; + unsigned int x_height; + int x_channel; + unsigned int x_norm; + int x_freq; + + unsigned int x_framerate; + + struct video_tuner x_vtuner; + struct video_picture x_vpicture; + struct video_buffer x_vbuffer; + struct video_capability x_vcap; + struct video_channel x_vchannel; + struct video_audio x_vaudio; + struct video_mbuf x_vmbuf; + struct video_mmap x_vmmap[NBUF]; + struct video_window x_vwin; + int x_tvfd; + int x_frame; + unsigned char *x_videobuf; + int x_skipnext; + int x_mytopmargin, x_mybottommargin; + int x_myleftmargin, x_myrightmargin; + + t_symbol *x_device; + t_symbol *x_image_type; + //int x_pdp_image_type; + int x_v4l_palette; + + 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; + + +} t_pdp_v4l; + + + + + +static void pdp_v4l_audio(t_pdp_v4l *x, t_floatarg f) +{ + int i = 0; + if (x->x_initialized){ + fprintf(stderr," audios : %d\n",x->x_vcap.audios); + x->x_vaudio.audio = 0; + ioctl(x->x_tvfd,VIDIOCGAUDIO, &x->x_vaudio); + + fprintf(stderr," %d (%s): ",i,x->x_vaudio.name); + if (x->x_vaudio.flags & VIDEO_AUDIO_MUTABLE) + fprintf(stderr,"muted=%s ", + (x->x_vaudio.flags & VIDEO_AUDIO_MUTE) ? "yes":"no"); + if (x->x_vaudio.flags & VIDEO_AUDIO_VOLUME) + fprintf(stderr,"volume=%d ",x->x_vaudio.volume); + if (x->x_vaudio.flags & VIDEO_AUDIO_BASS) + fprintf(stderr,"bass=%d ",x->x_vaudio.bass); + if (x->x_vaudio.flags & VIDEO_AUDIO_TREBLE) + fprintf(stderr,"treble=%d ",x->x_vaudio.treble); + fprintf(stderr,"\n"); + + } +} + + +static void pdp_v4l_close(t_pdp_v4l *x) +{ + /* close the v4l device and dealloc buffer */ + + void *dummy; + + /* terminate thread if there is one */ + if(x->x_continue_thread){ + x->x_continue_thread = 0; + pthread_join (x->x_thread_id, &dummy); + } + + + if (x->x_tvfd >= 0) + { + close(x->x_tvfd); + x->x_tvfd = -1; + } + + if (x->x_initialized){ + munmap(x->x_videobuf, x->x_vmbuf.size); + x->x_initialized = false; + } + +} + +static void pdp_v4l_close_manual(t_pdp_v4l *x) +{ + x->x_open_retry = PDP_XV_RETRIES; + pdp_v4l_close(x); + +} + +static void pdp_v4l_close_error(t_pdp_v4l *x) +{ + pdp_v4l_close(x); + if(x->x_open_retry) x->x_open_retry--; +} + + +static void pdp_v4l_pwc_init(t_pdp_v4l *x) +{ + struct pwc_probe probe; + int isPhilips = 0; + +#ifdef HAVE_PWCV4L + /* skip test */ + isPhilips = 1; +#else + /* test for pwc */ + if (ioctl(x->x_tvfd, VIDIOCPWCPROBE, &probe) == 0) + if (!strcmp(x->x_vcap.name, probe.name)) + isPhilips = 1; + +#endif + + /* don't do pwc specific stuff */ + if (!isPhilips) return; + + post("pdp_v4l: detected pwc"); + + if(ioctl(x->x_tvfd, VIDIOCPWCRUSER)){ + perror("pdp_v4l: pwc: VIDIOCPWCRUSER"); + goto closit; + } + + if (ioctl(x->x_tvfd, VIDIOCGWIN, &x->x_vwin)){ + perror("pdp_v4l: pwc: VIDIOCGWIN"); + goto closit; + } + + + + if (x->x_vwin.flags & PWC_FPS_MASK){ + //post("pdp_v4l: pwc: camera framerate: %d", (x->x_vwin.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); + //post("pdp_v4l: pwc: setting camera framerate to %d", x->x_framerate); + x->x_vwin.flags &= PWC_FPS_MASK; + x->x_vwin.flags |= (x->x_framerate << PWC_FPS_SHIFT); + if (ioctl(x->x_tvfd, VIDIOCSWIN, &x->x_vwin)){ + perror("pdp_v4l: pwc: VIDIOCSWIN"); + goto closit; + } + if (ioctl(x->x_tvfd, VIDIOCGWIN, &x->x_vwin)){ + perror("pdp_v4l: pwc: VIDIOCGWIN"); + goto closit; + } + post("pdp_v4l: camera framerate set to %d fps", (x->x_vwin.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); + + } + + + return; + + + + closit: + pdp_v4l_close_error(x); + return; + +} + +static void pdp_v4l_sync_frame(t_pdp_v4l* x){ + /* grab frame */ + if (ioctl(x->x_tvfd, VIDIOCSYNC, &x->x_vmmap[x->x_frame].frame) < 0){ + perror("pdp_v4l: VIDIOCSYNC"); + pdp_v4l_close(x); + return; + } +} + +static void pdp_v4l_capture_frame(t_pdp_v4l* x){ + if (ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_vmmap[x->x_frame]) < 0){ + if (errno == EAGAIN) + post("pdp_v4l: can't sync (no video source?)\n"); + else + perror("pdp_v4l: VIDIOCMCAPTURE"); + if (ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_vmmap[x->x_frame]) < 0) + perror("pdp_v4l: VIDIOCMCAPTURE2"); + + post("pdp_v4l: frame %d %d, format %d, width %d, height %d", + x->x_frame, x->x_vmmap[x->x_frame].frame, x->x_vmmap[x->x_frame].format, + x->x_vmmap[x->x_frame].width, x->x_vmmap[x->x_frame].height); + + pdp_v4l_close(x); + return; + } +} + + +static void *pdp_v4l_thread(void *voidx) +{ + t_pdp_v4l *x = ((t_pdp_v4l *)voidx); + + + /* flip buffers */ + x->x_frame ^= 0x1; + + /* capture with a double buffering scheme */ + while (x->x_continue_thread){ + + /* schedule capture command for next frame */ + pdp_v4l_capture_frame(x); + + /* wait until previous capture is ready */ + x->x_frame ^= 0x1; + pdp_v4l_sync_frame(x); + + /* setup pointers for main thread */ + x->x_frame_ready = 1; + x->x_last_frame = x->x_frame; + + } + + return 0; +} + +static void pdp_v4l_setlegaldim(t_pdp_v4l *x, int xx, int yy); + +static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name) +{ + /* open a v4l device and allocate a buffer */ + + unsigned int size; + int i; + + unsigned int width, height; + + + /* if already opened -> close */ + if (x->x_initialized) pdp_v4l_close(x); + + + /* exit if retried too much */ + if (!x->x_open_retry){ + post("pdp_v4l: retry count reached zero for %s", name->s_name); + post("pdp_v4l: try to open manually"); + return; + } + + post("pdp_v4l: opening %s", name->s_name); + + x->x_device = name; + + if ((x->x_tvfd = open(name->s_name, O_RDWR)) < 0) + { + post("pdp_v4l: error:"); + perror(name->s_name); + goto closit; + } + + + if (ioctl(x->x_tvfd, VIDIOCGCAP, &x->x_vcap) < 0) + { + perror("get capabilities"); + goto closit; + } + + post("pdp_v4l: cap: name %s type %d channels %d maxw %d maxh %d minw %d minh %d", + x->x_vcap.name, x->x_vcap.type, x->x_vcap.channels, x->x_vcap.maxwidth, x->x_vcap.maxheight, + x->x_vcap.minwidth, x->x_vcap.minheight); + + x->x_minwidth = pdp_imageproc_legalwidth(x->x_vcap.minwidth); + x->x_maxwidth = pdp_imageproc_legalwidth_round_down(x->x_vcap.maxwidth); + x->x_minheight = pdp_imageproc_legalheight(x->x_vcap.minheight); + x->x_maxheight = pdp_imageproc_legalheight_round_down(x->x_vcap.maxheight); + + + if (ioctl(x->x_tvfd, VIDIOCGPICT, &x->x_vpicture) < 0) + { + perror("VIDIOCGCAP"); + goto closit; + } + + post("pdp_v4l: picture: brightness %d depth %d palette %d", + x->x_vpicture.brightness, x->x_vpicture.depth, x->x_vpicture.palette); + + /* get channel info */ + for (i = 0; i < x->x_vcap.channels; i++) + { + x->x_vchannel.channel = i; + if (ioctl(x->x_tvfd, VIDIOCGCHAN, &x->x_vchannel) < 0) + { + perror("VDIOCGCHAN"); + goto closit; + } + post("pdp_v4l: channel %d name %s type %d flags %d", + x->x_vchannel.channel, x->x_vchannel.name, + x->x_vchannel.type, x->x_vchannel.flags); + } + + /* switch to the desired channel */ + if (x->x_channel < 0) x->x_channel = 0; + if (x->x_channel >= x->x_vcap.channels) x->x_channel = x->x_vcap.channels - 1; + + x->x_vchannel.channel = x->x_channel; + if (ioctl(x->x_tvfd, VIDIOCGCHAN, &x->x_vchannel) < 0) + { + perror("pdp_v4l: warning: VDIOCGCHAN"); + post("pdp_v4l: cant change to channel %d",x->x_channel); + + // ignore error + // goto closit; + } + else{ + post("pdp_v4l: switched to channel %d", x->x_channel); + } + + + /* set norm */ + x->x_vchannel.norm = x->x_norm; + if (ioctl(x->x_tvfd, VIDIOCSCHAN, &x->x_vchannel) < 0) + { + perror("pdp_v4l: warning: VDIOCSCHAN"); + post("pdp_v4l: cant change to norm %d",x->x_norm); + + // ignore error + // goto closit; + } + else { + post("pdp_v4l: set norm to %u", x->x_norm); + } + + if (x->x_freq > 0){ + if (ioctl(x->x_tvfd, VIDIOCSFREQ, &x->x_freq) < 0) + perror ("couldn't set frequency :"); + } + + + + + /* get mmap numbers */ + if (ioctl(x->x_tvfd, VIDIOCGMBUF, &x->x_vmbuf) < 0) + { + perror("pdp_v4l: VIDIOCGMBUF"); + goto closit; + } + post("pdp_v4l: buffer size %d, frames %d, offset %d %d", x->x_vmbuf.size, + x->x_vmbuf.frames, x->x_vmbuf.offsets[0], x->x_vmbuf.offsets[1]); + if (!(x->x_videobuf = (unsigned char *) + mmap(0, x->x_vmbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, x->x_tvfd, 0))) + { + perror("pdp_v4l: mmap"); + goto closit; + } + + pdp_v4l_setlegaldim(x, x->x_width, x->x_height); + width = x->x_width; + height = x->x_height; + + for (i = 0; i < NBUF; i++) + { + //x->x_vmmap[i].format = VIDEO_PALETTE_YUV420P; + //x->x_vmmap[i].format = VIDEO_PALETTE_UYVY; + x->x_vmmap[i].width = width; + x->x_vmmap[i].height = height; + x->x_vmmap[i].frame = i; + } + + +/* fallthrough macro for case statement */ +#define TRYPALETTE(palette) \ + x->x_v4l_palette = palette; \ + for (i = 0; i < NBUF; i++) x->x_vmmap[i].format = x->x_v4l_palette; \ + if (ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_vmmap[x->x_frame]) < 0) \ + { \ + if (errno == EAGAIN) \ + post("pdp_v4l: can't sync (no video source?)"); \ + if (x->x_format) break; /* only break if not autodetecting */ \ + } \ + else{ \ + post("pdp_v4l: using " #palette); \ + goto capture_ok; \ + } + + switch(x->x_format){ + default: + case 0: + case 1: TRYPALETTE(VIDEO_PALETTE_YUV420P); + case 2: TRYPALETTE(VIDEO_PALETTE_YUV422); + case 3: TRYPALETTE(VIDEO_PALETTE_RGB24); + case 4: TRYPALETTE(VIDEO_PALETTE_RGB32); + } + + // none of the formats are supported + perror("pdp_v4l: VIDIOCMCAPTURE: format not supported"); + goto closit; + + + capture_ok: + + post("pdp_v4l: frame %d %d, format %d, width %d, height %d", + x->x_frame, x->x_vmmap[x->x_frame].frame, x->x_vmmap[x->x_frame].format, + x->x_vmmap[x->x_frame].width, x->x_vmmap[x->x_frame].height); + + x->x_width = width; + x->x_height = height; + + post("pdp_v4l: Opened video connection (%dx%d)",x->x_width,x->x_height); + + + /* do some pwc specific inits */ + pdp_v4l_pwc_init(x); + + + x->x_initialized = true; + + /* create thread */ + x->x_continue_thread = 1; + x->x_frame_ready = 0; + pthread_create(&x->x_thread_id, 0, pdp_v4l_thread, x); + + return; + closit: + pdp_v4l_close_error(x); + +} + +static void pdp_v4l_open_manual(t_pdp_v4l *x, t_symbol *name) +{ + x->x_open_retry = PDP_XV_RETRIES; + pdp_v4l_open(x, name); +} + + +static void pdp_v4l_channel(t_pdp_v4l *x, t_float f) +{ + int channel = (float)f; + + if (x->x_initialized){ + pdp_v4l_close(x); + x->x_channel = channel; + pdp_v4l_open(x, x->x_device); + } + else + x->x_channel = channel; +} + +static void pdp_v4l_norm(t_pdp_v4l *x, t_symbol *s) +{ + unsigned int norm; + + if (gensym("PAL") == s) norm = VIDEO_MODE_PAL; + else if (gensym("NTSC") == s) norm = VIDEO_MODE_NTSC; + else if (gensym("SECAM") == s) norm = VIDEO_MODE_SECAM; + else norm = VIDEO_MODE_AUTO; + + + + if (x->x_initialized){ + pdp_v4l_close(x); + x->x_norm = norm; + pdp_v4l_open(x, x->x_device); + } + else + x->x_norm = norm; +} + +static void pdp_v4l_freq(t_pdp_v4l *x, t_float f) +{ + int freq = (int)f; + + x->x_freq = freq; + if (x->x_freq > 0){ + if (ioctl(x->x_tvfd, VIDIOCSFREQ, &x->x_freq) < 0) + perror ("couldn't set frequency :"); + //else {post("pdp_v4l: tuner frequency: %f MHz", f / 16.0f);} + } + +} + +static void pdp_v4l_freqMHz(t_pdp_v4l *x, t_float f) +{ + pdp_v4l_freq(x, f*16.0f); +} + + +static void pdp_v4l_bang(t_pdp_v4l *x) +{ + + /* if initialized, grab a frame and output it */ + + unsigned int w,h,nbpixels,packet_size,plane1,plane2; + unsigned char *newimage; + int object,length,pos,i,encoding; + t_pdp* header; + t_image* image; + short int * data; + + + static short int gain[4] = {0x7fff, 0x7fff, 0x7fff, 0x7fff}; + + if (!(x->x_initialized)){ + post("pdp_v4l: no device opened"); + + if (x->x_auto_open){ + post("pdp_v4l: attempting auto open"); + pdp_v4l_open(x, x->x_device); + if (!(x->x_initialized)){ + post("pdp_v4l: auto open failed"); + return; + } + } + + else return; + } + + + /* do nothing if there is no frame ready */ + if((!x->x_frame_ready) && (x->x_only_new_frames)) return; + x->x_frame_ready = 0; + + /* get the address of the "other" frame */ + newimage = x->x_videobuf + x->x_vmbuf.offsets[x->x_last_frame]; + + /* create new packet */ + w = x->x_width; + h = x->x_height; + + //nbpixels = w * h; + +/* + switch(x->x_pdp_image_type){ + case PDP_IMAGE_GREY: + packet_size = nbpixels << 1; + break; + case PDP_IMAGE_YV12: + packet_size = (nbpixels + (nbpixels >> 1)) << 1; + break; + default: + packet_size = 0; + post("pdp_v4l: internal error"); + } +*/ + + //packet_size = (nbpixels + (nbpixels >> 1)) << 1; + + + //plane1 = nbpixels; + //plane2 = nbpixels + (nbpixels>>2); + + object = pdp_packet_new_image(PDP_IMAGE_YV12, w, h); + header = pdp_packet_header(object); + image = pdp_packet_image_info(object); + + if (!header){ + post("pdp_v4l: ERROR: can't allocate packet"); + return; + } + + data = (short int *) pdp_packet_data(object); + newimage = x->x_videobuf + x->x_vmbuf.offsets[x->x_frame ^ 0x1]; + + + /* convert data to pdp packet */ + + switch(x->x_v4l_palette){ + case VIDEO_PALETTE_YUV420P: + pdp_llconv(newimage, RIF_YUV__P411_U8, data, RIF_YVU__P411_S16, w, h); + break; + + /* long live standards. v4l's rgb is in fact ogl's bgr */ + case VIDEO_PALETTE_RGB24: + pdp_llconv(newimage, RIF_BGR__P____U8, data, RIF_YVU__P411_S16, w, h); + break; + + case VIDEO_PALETTE_RGB32: + pdp_llconv(newimage, RIF_BGRA_P____U8, data, RIF_YVU__P411_S16, w, h); + break; + + case VIDEO_PALETTE_YUV422: + pdp_llconv(newimage, RIF_YUYV_P____U8, data, RIF_YVU__P411_S16, w, h); + break; + + + default: + post("pdp_v4l: unsupported palette"); + break; + } + +/* + if (PDP_IMAGE_YV12 == x->x_pdp_image_type){ + pixel_unpack_u8s16_y(&newimage[0], data, nbpixels>>3, x->x_state_data->gain); + pixel_unpack_u8s16_uv(&newimage[plane1], &data[plane2], nbpixels>>5, x->x_state_data->gain); + pixel_unpack_u8s16_uv(&newimage[plane2], &data[plane1], nbpixels>>5, x->x_state_data->gain); + } +*/ + //x->x_v4l_palette = VIDEO_PALETTE_YUV420P; + //x->x_v4l_palette = VIDEO_PALETTE_RGB24; + +/* + + else if(PDP_IMAGE_GREY == x->x_pdp_image_type){ + pixel_unpack_u8s16_y(&newimage[0], data, nbpixels>>3, x->x_state_data->gain); + } +*/ + //post("pdp_v4l: mark unused %d", object); + + pdp_packet_pass_if_valid(x->x_outlet0, &object); + +} + + +static void pdp_v4l_setlegaldim(t_pdp_v4l *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_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy) +{ + if (x->x_initialized){ + pdp_v4l_close(x); + pdp_v4l_setlegaldim(x, (int)xx, (int)yy); + pdp_v4l_open(x, x->x_device); + + } + else{ + pdp_v4l_setlegaldim(x, (int)xx, (int)yy); + } +} + +static void pdp_v4l_format(t_pdp_v4l *x, t_symbol *s) +{ + if (s == gensym("YUV420P")) x->x_format = 1; + else if (s == gensym("YUV422")) x->x_format = 2; + else if (s == gensym("RGB24")) x->x_format = 3; + else if (s == gensym("RGB32")) x->x_format = 4; + else if (s == gensym("auto")) x->x_format = 0; + else { + post("pdp_v4l: format %s unknown, using autodetect", s->s_name); + x->x_format = 0; + } + + if (x->x_initialized){ + pdp_v4l_close(x); + pdp_v4l_open(x, x->x_device); + } +} + + +static void pdp_v4l_free(t_pdp_v4l *x) +{ + pdp_v4l_close(x); +} + +t_class *pdp_v4l_class; + + + +void *pdp_v4l_new(t_symbol *vdef, t_symbol *format) +{ + t_pdp_v4l *x = (t_pdp_v4l *)pd_new(pdp_v4l_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_initialized = false; + + + x->x_tvfd = -1; + x->x_frame = 0; + x->x_last_frame = 0; + + x->x_framerate = 27; + + x->x_auto_open = true; + if (vdef != gensym("")){ + x->x_device = vdef; + } + else{ + x->x_device = gensym("/dev/video0"); + } + + if (format != gensym("")){ + pdp_v4l_format(x, format); + } + else { + x->x_format = 0; // default is autodetect + } + + x->x_continue_thread = 0; + x->x_only_new_frames = 1; + + x->x_width = 320; + x->x_height = 240; + +// pdp_v4l_type(x, gensym("yv12")); + + + x->x_open_retry = PDP_XV_RETRIES; + + x->x_channel = 0; + x->x_norm = 0; // PAL + x->x_freq = -1; //don't set freq by default + + x->x_minwidth = pdp_imageproc_legalwidth(0); + x->x_maxwidth = pdp_imageproc_legalwidth_round_down(0x7fffffff); + x->x_minheight = pdp_imageproc_legalheight(0); + x->x_maxheight = pdp_imageproc_legalheight_round_down(0x7fffffff); + + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_v4l_setup(void) +{ + + + pdp_v4l_class = class_new(gensym("pdp_v4l"), (t_newmethod)pdp_v4l_new, + (t_method)pdp_v4l_free, sizeof(t_pdp_v4l), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); + + + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_bang, gensym("bang"), A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_audio, gensym("audio"), A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_close_manual, gensym("close"), A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_open_manual, gensym("open"), A_SYMBOL, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_channel, gensym("channel"), A_FLOAT, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_norm, gensym("norm"), A_SYMBOL, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_freq, gensym("freq"), A_FLOAT, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_freqMHz, gensym("freqMHz"), A_FLOAT, A_NULL); + class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_format, gensym("captureformat"), A_SYMBOL, A_NULL); + + + +} + +#ifdef __cplusplus +} +#endif -- cgit v1.2.1