From e20d5ae3622d5d656dc28d7a090aee76b08158b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADn?= Date: Sun, 7 Sep 2003 20:01:24 +0000 Subject: updating pdp to current version 0.12.2 svn path=/trunk/externals/pdp/; revision=936 --- modules/pdp_v4l.c | 757 ------------------------------------------------------ 1 file changed, 757 deletions(-) delete mode 100644 modules/pdp_v4l.c (limited to 'modules/pdp_v4l.c') diff --git a/modules/pdp_v4l.c b/modules/pdp_v4l.c deleted file mode 100644 index f1195c3..0000000 --- a/modules/pdp_v4l.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * 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 - -#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; - - 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_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) -{ - /* todo add detection code for pwc */ - -#ifdef HAVE_PWCV4L - - 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: framerate: %d", (x->x_vwin.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); - post("pdp_v4l: pwc: setting 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: pwc: framerate: %d", (x->x_vwin.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); - - } - - - return; - - - - closit: - pdp_v4l_close_error(x); - return; - -#else - post("pdp_v4l: additional pwc support disabled"); - return; -#endif -} - -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); - } - - 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; - } - - 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; - } - - - //goto test; - - //try yuv planar format - x->x_v4l_palette = VIDEO_PALETTE_YUV420P; - 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?)"); - } - else{ - post("pdp_v4l: using VIDEO_PALETTE_YUV420P"); - goto capture_ok; - } - - - //try VIDEO_PALETTE_YUV422 format - x->x_v4l_palette = VIDEO_PALETTE_YUV422; - 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?)"); - } - else{ - post("pdp_v4l: using VIDEO_PALETTE_YUV422"); - goto capture_ok; - } - - - test: - - //try rgb packed format - x->x_v4l_palette = VIDEO_PALETTE_RGB24; - 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?)"); - } - else{ - post("pdp_v4l: using VIDEO_PALETTE_RGB24"); - goto capture_ok; - } - - - // 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_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; - 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(PDP_IMAGE, packet_size); - header = pdp_packet_header(object); - data = (short int *) pdp_packet_data(object); - - //header->info.image.encoding = x->x_pdp_image_type; - header->info.image.encoding = PDP_IMAGE_YV12; - header->info.image.width = w; - header->info.image.height = h; - - /* read from the "other" frame */ - 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; - - case VIDEO_PALETTE_RGB24: - pdp_llconv(newimage, RIF_RGB__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_mark_unused(object); - outlet_pdp(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_free(t_pdp_v4l *x) -{ - pdp_v4l_close(x); -} - -t_class *pdp_v4l_class; - - - -void *pdp_v4l_new(void) -{ - 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; - x->x_device = gensym("/dev/video0"); - - 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_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_NULL); - - - class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_bang, gensym("bang"), 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_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); - - - -} - -#ifdef __cplusplus -} -#endif -- cgit v1.2.1