From ad2a2cdcf3a363f27dab9b8236cea35f0340e834 Mon Sep 17 00:00:00 2001 From: AngelCarpintero Date: Wed, 9 Jul 2008 11:45:25 +0000 Subject: [PATCH] - Fix round robin in BSD switching to METEOR_CAP_SINGLE - Some improvements in capture code , added better logging - Free mutex in web control on error --- CHANGELOG | 2 +- motion.h | 1 + video_freebsd.c | 456 +++++++++++++++++++++++++++--------------------- video_freebsd.h | 4 +- webhttpd.c | 4 + 5 files changed, 268 insertions(+), 199 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 73b0cb64..691df98a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,7 +6,7 @@ Bugfixes http://www.lavrsen.dk/twiki/bin/view/Motion/SupportQuestion2008x06x11x183727 (Angel Carpintero) * Add a new parameter netcam_broken, to be less strict with some buggy network cameras firmwares. http://www.lavrsen.dk/twiki/bin/view/Motion/BugReport2008x06x19x123218 (Angel Carpintero) - + * Fix round robin in BSD switching to METEOR_CAP_SINGLE. (Angel Carpintero) 3.2.10.1 Summary of Changes diff --git a/motion.h b/motion.h index ff8fdb1e..55ddf110 100644 --- a/motion.h +++ b/motion.h @@ -104,6 +104,7 @@ /* Debug levels FIXME */ #define CAMERA_WARNINGS 3 /* warnings only */ #define CAMERA_INFO 5 /* info debug */ +#define CAMERA_VIDEO 6 /* video debug */ #define CAMERA_DEBUG 7 /* debug but not verbose */ #define CAMERA_VERBOSE 8 /* verbose level */ #define CAMERA_ALL 9 /* everything */ diff --git a/video_freebsd.c b/video_freebsd.c index daa4220b..11b3be66 100644 --- a/video_freebsd.c +++ b/video_freebsd.c @@ -7,7 +7,7 @@ * */ -/* Common stuff: */ +/* for rotation */ #include "rotate.h" /* already includes motion.h */ #include "video_freebsd.h" @@ -15,7 +15,6 @@ /* for the v4l stuff: */ #include -#include /* Hack from xawtv 4.x */ @@ -83,9 +82,9 @@ static void yuv422to420p(unsigned char *map, unsigned char *cap_map, int width, int i, j; /* Create the Y plane */ - src=cap_map; - dest=map; - for (i= width * height; i; i--) { + src = cap_map; + dest = map; + for (i = width * height; i; i--) { *dest++ = *src; src += 2; } @@ -128,28 +127,27 @@ static void rgb24toyuv420p(unsigned char *map, unsigned char *cap_map, int width memset(u, 0, width * height / 4); memset(v, 0, width * height / 4); - for(loop=0; loop>15; - *u+=((-4784**r-9437**g+14221**b)>>17)+32; - *v+=((20218**r-16941**g-3277**b)>>17)+32; - r+=3; - g+=3; - b+=3; - *y++=(9796**r+19235**g+3736**b)>>15; - *u+=((-4784**r-9437**g+14221**b)>>17)+32; - *v+=((20218**r-16941**g-3277**b)>>17)+32; - r+=3; - g+=3; - b+=3; + for (loop = 0; loop < height; loop++) { + for (i = 0; i < width; i += 2) { + *y++ = (9796 ** r + 19235 ** g + 3736 ** b) >> 15; + *u += ((-4784 ** r - 9437 ** g + 14221 ** b) >> 17) + 32; + *v += ((20218 ** r - 16941**g - 3277 ** b) >> 17) + 32; + r += 3; + g += 3; + b += 3; + *y++ = (9796 ** r + 19235 ** g + 3736 ** b) >> 15; + *u += ((-4784 ** r - 9437 ** g + 14221 ** b) >> 17) + 32; + *v += ((20218 ** r - 16941 ** g - 3277 ** b) >> 17) + 32; + r += 3; + g += 3; + b += 3; u++; v++; } - if ((loop & 1) == 0) - { - u-=width/2; - v-=width/2; + if ((loop & 1) == 0) { + u -= width / 2; + v -= width / 2; } } @@ -170,7 +168,7 @@ static int camparam_normalize( int param, int cfg_value, int *ioctl_val ) val = (cfg_value - CamParams[ param ].min ) / (CamParams[ param ].range + 0.01) * CamParams[param].drv_range + CamParams[param].drv_min; val = MAX( CamParams[ param ].min, - MIN( CamParams[ param ].drv_min + CamParams[ param ].drv_range-1,val )); + MIN( CamParams[ param ].drv_min + CamParams[ param ].drv_range-1, val )); *ioctl_val = val; return cfg_value; } @@ -180,109 +178,126 @@ static int set_hue( int viddev, int new_hue ) { signed char ioctlval = new_hue; - if( ioctl( viddev, METEORSHUE, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORSHUE Error setting hue [%d]",new_hue); + if (ioctl(viddev, METEORSHUE, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORSHUE Error setting hue [%d]", __FUNCTION__, new_hue); return -1; } - motion_log(-1, 0, "set hue to [%d]",ioctlval); + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); return ioctlval; } -static int get_hue( int viddev , int *hue) +static int get_hue(int viddev , int *hue) { signed char ioctlval; - if( ioctl( viddev, METEORGHUE, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORGHUE Error getting hue"); + if (ioctl(viddev, METEORGHUE, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORGHUE Error getting hue", __FUNCTION__); return -1; } + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); + *hue = ioctlval; return ioctlval; } -static int set_saturation( int viddev, int new_saturation ) +static int set_saturation(int viddev, int new_saturation) { unsigned char ioctlval= new_saturation; - if( ioctl( viddev, METEORSCSAT, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORSCSAT Error setting saturation [%d]",new_saturation); + if (ioctl(viddev, METEORSCSAT, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORSCSAT Error setting saturation [%d]", + __FUNCTION__, new_saturation); return -1; } - motion_log(-1, 0, "set saturation to [%d]",ioctlval); + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); return ioctlval; } -static int get_saturation( int viddev , int *saturation) +static int get_saturation(int viddev , int *saturation) { unsigned char ioctlval; - if( ioctl( viddev, METEORGCSAT, &ioctlval ) < 0 ) { + if (ioctl(viddev, METEORGCSAT, &ioctlval) < 0) { - motion_log(LOG_ERR, 1, "METEORGCSAT Error getting saturation"); + motion_log(LOG_ERR, 1, "%s: METEORGCSAT Error getting saturation", __FUNCTION__); return -1; } + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); + *saturation = ioctlval; return ioctlval; } -static int set_contrast( int viddev, int new_contrast ) +static int set_contrast(int viddev, int new_contrast) { unsigned char ioctlval = new_contrast; - if( ioctl( viddev, METEORSCONT, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORSCONT Error setting contrast [%d]", new_contrast); + if (ioctl(viddev, METEORSCONT, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORSCONT Error setting contrast [%d]", __FUNCTION__, new_contrast); return 0; } - motion_log(-1, 0, "set contrast to [%d]",ioctlval); + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); return ioctlval; } -static int get_contrast( int viddev, int *contrast ) +static int get_contrast(int viddev, int *contrast) { unsigned char ioctlval; - if( ioctl (viddev, METEORGCONT, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORGCONT Error getting contrast"); + if (ioctl (viddev, METEORGCONT, &ioctlval ) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORGCONT Error getting contrast", __FUNCTION__); return -1; } + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); + *contrast = ioctlval; return ioctlval; } -static int set_brightness( int viddev, int new_bright ) +static int set_brightness(int viddev, int new_bright) { unsigned char ioctlval = new_bright; - if( ioctl( viddev, METEORSBRIG, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORSBRIG brightness [%d]",new_bright); + if (ioctl(viddev, METEORSBRIG, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORSBRIG brightness [%d]", __FUNCTION__, new_bright); return -1; } - motion_log(-1, 0, "set brightness to [%d]",ioctlval); + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); return ioctlval; } -static int get_brightness( int viddev, int *brightness ) +static int get_brightness(int viddev, int *brightness) { unsigned char ioctlval; - if( ioctl( viddev, METEORGBRIG, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORGBRIG getting brightness"); + if (ioctl(viddev, METEORGBRIG, &ioctlval) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORGBRIG getting brightness", __FUNCTION__); return -1; } + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, ioctlval); + *brightness = ioctlval; return ioctlval; } @@ -295,10 +310,10 @@ static int set_channel( struct video_dev *viddev, int new_channel ) ioctlval = new_channel; if( ioctl( viddev->fd_tuner, TVTUNER_SETCHNL, &ioctlval ) < 0 ) { - motion_log(LOG_ERR, 1, "Error channel %d",ioctlval); + motion_log(LOG_ERR, 1, "Error channel %d", ioctlval); return -1; } else { - motion_log(LOG_DEBUG, 0, "channel set to %d",ioctlval); + motion_log(LOG_DEBUG, 0, "channel set to %d", ioctlval); } viddev->channel = new_channel; @@ -314,25 +329,27 @@ static int set_freq(struct video_dev *viddev, unsigned long freq) int tuner_fd = viddev->fd_tuner; int old_audio; - motion_log(LOG_DEBUG, 0, "Not implemented"); + motion_log(LOG_DEBUG, 0, "%s: Not implemented", __FUNCTION__); + return 0; + /* HACK maybe not need it , but seems that is needed to mute before changing frequency */ - if ( ioctl( tuner_fd, BT848_GAUDIO, &old_audio ) < 0 ) { - motion_log(LOG_ERR, 1, "BT848_GAUDIO"); + if (ioctl(tuner_fd, BT848_GAUDIO, &old_audio) < 0) { + motion_log(LOG_ERR, 1, "%s: BT848_GAUDIO", __FUNCTION__); return -1; } - if (ioctl(tuner_fd, TVTUNER_SETFREQ, &freq) < 0){ - motion_log(LOG_ERR, 1, "Tuning (TVTUNER_SETFREQ) failed , freq [%lu]",freq); + if (ioctl(tuner_fd, TVTUNER_SETFREQ, &freq) < 0) { + motion_log(LOG_ERR, 1, "%s: Tuning (TVTUNER_SETFREQ) failed , freq [%lu]", __FUNCTION__, freq); return -1; } old_audio &= AUDIO_MUTE; - if ( old_audio ){ + if (old_audio) { old_audio = AUDIO_MUTE; - if ( ioctl(tuner_fd , BT848_SAUDIO, &old_audio ) < 0 ) { - motion_log(LOG_ERR, 1, "BT848_SAUDIO %i",old_audio); + if (ioctl(tuner_fd , BT848_SAUDIO, &old_audio) < 0) { + motion_log(LOG_ERR, 1, "%s: BT848_SAUDIO %i", __FUNCTION__, old_audio); return -1; } } @@ -356,29 +373,32 @@ static int set_input(struct video_dev *viddev, unsigned short input) METEOR_INPUT_DEV2, METEOR_INPUT_DEV3, METEOR_INPUT_DEV_SVIDEO }; - if( input >= array_elem( portdata ) ) { - motion_log(LOG_WARNING, 0, "Channel Port %d out of range (0-4)",input); - input = IN_DEFAULT; + if (input >= array_elem(portdata)) { + motion_log(LOG_INFO, 0, "%s: Channel Port %d out of range (0-4)", __FUNCTION__, input); + return -1; } actport = portdata[ input ]; - if( ioctl( viddev->fd_bktr, METEORSINPUT, &actport ) < 0 ) { - if( input != IN_DEFAULT ) { - motion_log(LOG_WARNING, 0, - "METEORSINPUT %d invalid - Trying default %d ", input, IN_DEFAULT ); + if (ioctl(viddev->fd_bktr, METEORSINPUT, &actport) < 0) { + if (input != IN_DEFAULT) { + motion_log(LOG_INFO, 1, "%s: METEORSINPUT %d invalid - Trying default %d", + __FUNCTION__, input, IN_DEFAULT); input = IN_DEFAULT; actport = portdata[ input ]; - if( ioctl( viddev->fd_bktr, METEORSINPUT, &actport ) < 0 ) { - motion_log(LOG_ERR, 1, "METEORSINPUT %d init", input); + if (ioctl(viddev->fd_bktr, METEORSINPUT, &actport) < 0) { + motion_log(LOG_ERR, 1, "%s: METEORSINPUT %d init", __FUNCTION__, input); return -1; } } else { - motion_log(LOG_ERR, 1, "METEORSINPUT %d init",input); + motion_log(LOG_ERR, 1, "%s: METEORSINPUT %d init", __FUNCTION__, input); return -1; } } - return 0; + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d]", __FUNCTION__, input); + + return input; } static int set_geometry(struct video_dev *viddev, int width, int height) @@ -399,17 +419,20 @@ static int set_geometry(struct video_dev *viddev, int width, int height) default: h_max = PAL_HEIGHT; } - if (height <= h_max/2) { + if (height <= h_max / 2) { geom.oformat |= METEOR_GEO_EVEN_ONLY; } geom.frames = 1; - if( ioctl( viddev->fd_bktr, METEORSETGEO, &geom ) < 0 ) { - motion_log(LOG_ERR, 1, "Couldn't set the geometry"); + if (ioctl(viddev->fd_bktr, METEORSETGEO, &geom) < 0) { + motion_log(LOG_ERR, 1, "%s: Couldn't set the geometry", __FUNCTION__); return -1; } + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to [%d/%d] Norm %d", __FUNCTION__, width, height, viddev->norm); + return 0; } @@ -422,25 +445,30 @@ static int set_input_format(struct video_dev *viddev, unsigned short newformat) int input_format[] = { NORM_PAL_NEW, NORM_NTSC_NEW, NORM_SECAM_NEW, NORM_DEFAULT_NEW}; int format; - if( newformat >= array_elem( input_format ) ) { - motion_log(LOG_WARNING, 0, "Input format %d out of range (0-2)",newformat ); - format = NORM_DEFAULT_NEW; - newformat = 3; - } else - format = input_format[newformat]; + if (newformat >= array_elem( input_format )) { + motion_log(LOG_WARNING, 0, "%s: Input format %d out of range (0-2)", __FUNCTION__, newformat); + return -1; + } + + format = input_format[newformat]; if( ioctl( viddev->fd_bktr, BT848SFMT, &format ) < 0 ) { - motion_log(LOG_ERR, 1, "BT848SFMT, Couldn't set the input format , try again with default"); + motion_log(LOG_ERR, 1, "%s: BT848SFMT, Couldn't set the input format , try again with default", + __FUNCTION__); format = NORM_DEFAULT_NEW; newformat = 3; if( ioctl( viddev->fd_bktr, BT848SFMT, &format ) < 0 ) { - motion_log(LOG_ERR, 1, "BT848SFMT, Couldn't set the input format either default"); + motion_log(LOG_ERR, 1, "%s: BT848SFMT, Couldn't set the input format either default", + __FUNCTION__); return -1; } } - return 0; + if (debug_level >= CAMERA_VIDEO) + motion_log(-1, 0, "%s: to %d", __FUNCTION__, newformat); + + return newformat; } /* @@ -450,12 +478,12 @@ statict int setup_pixelformat( int bktr ) struct meteor_pixfmt p; int format=-1; - for( i=0; ; i++ ){ + for( i = 0; ; i++ ){ p.index = i; if( ioctl( bktr, METEORGSUPPIXFMT, &p ) < 0 ){ if( errno == EINVAL ) break; - motion_log(LOG_ERR, 1, "METEORGSUPPIXFMT getting pixformat %d",i); + motion_log(LOG_ERR, 1, "METEORGSUPPIXFMT getting pixformat %d", i); return -1; } @@ -508,8 +536,8 @@ statict int setup_pixelformat( int bktr ) motion_log(LOG_WARNING, 1, "METEORSACTPIXFMT etting pixformat METEOR_PIXTYPE_RGB Bpp == 3"); // Not immediately fatal } - motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_RGB %i",i); - format=i; + motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_RGB %i", i); + format = i; } if( p.type == METEOR_PIXTYPE_YUV_PACKED ){ @@ -518,8 +546,8 @@ statict int setup_pixelformat( int bktr ) motion_log(LOG_WARNING, 1, "METEORSACTPIXFMT setting pixformat METEOR_PIXTYPE_YUV_PACKED"); // Not immediately fatal } - motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_YUV_PACKED %i",i); - format=i; + motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_YUV_PACKED %i", i); + format = i; } } @@ -533,8 +561,8 @@ static void v4l_picture_controls(struct context *cnt, struct video_dev *viddev) { int dev = viddev->fd_bktr; - if ( (cnt->conf.contrast) && (cnt->conf.contrast != viddev->contrast) ){ - set_contrast(dev,cnt->conf.contrast); + if ( (cnt->conf.contrast) && (cnt->conf.contrast != viddev->contrast) ) { + set_contrast(dev, cnt->conf.contrast); viddev->contrast = cnt->conf.contrast; } @@ -550,7 +578,7 @@ static void v4l_picture_controls(struct context *cnt, struct video_dev *viddev) } if ( (cnt->conf.saturation ) && - (cnt->conf.saturation != viddev->saturation) ){ + (cnt->conf.saturation != viddev->saturation) ) { set_saturation(dev, cnt->conf.saturation); viddev->saturation = cnt->conf.saturation; } @@ -572,11 +600,12 @@ static void v4l_picture_controls(struct context *cnt, struct video_dev *viddev) - set_capture_mode */ -static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, int width, int height, unsigned short input, unsigned short norm, unsigned long freq) +static unsigned char *v4l_start(struct video_dev *viddev, int width, int height, + unsigned short input, unsigned short norm, unsigned long freq) { int dev_bktr = viddev->fd_bktr; struct sigaction act, old; - //int dev_tunner=viddev->fd_tuner; + //int dev_tunner = viddev->fd_tuner; /* to ensure that all device will be support the capture mode _TODO_ : Autodected the best capture mode . */ @@ -588,25 +617,34 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i /* if we have choose the tuner is needed to setup the frequency */ if ( (viddev->tuner_device != NULL) && ( input == IN_TV ) ) { if (!freq) { - motion_log(LOG_ERR, 1, "Not valid Frequency [%lu] for Source input [%i]", freq, input); + motion_log(LOG_ERR, 0, "%s: Not valid Frequency [%lu] for Source input [%i]", + __FUNCTION__, freq, input); return (NULL); }else if (set_freq(viddev, freq) == -1) { - motion_log(LOG_ERR, 1, "Frequency [%lu] Source input [%i]", freq, input); + motion_log(LOG_ERR, 0, "%s: Frequency [%lu] Source input [%i]", + __FUNCTION__, freq, input); return (NULL); } } /* FIXME if we set as input tuner , we need to set option for tuner not for bktr */ - if ( set_input_format(viddev, norm) == -1 ) { - motion_log(LOG_ERR, 1, "set input format [%d]",norm); + if ((dummy = set_input(viddev, input)) == -1) { + motion_log(LOG_ERR, 0, "%s: set input [%d]", __FUNCTION__, input); return (NULL); } - viddev->norm = norm; + viddev->input = dummy; + + if ((dummy = set_input_format(viddev, norm)) == -1) { + motion_log(LOG_ERR, 0, "%s: set input format [%d]", __FUNCTION__, norm); + return (NULL); + } + + viddev->norm = dummy; if (set_geometry(viddev, width, height) == -1) { - motion_log(LOG_ERR, 1, "set geometry [%d]x[%d]",width, height); + motion_log(LOG_ERR, 0, "%s: set geometry [%d]x[%d]", __FUNCTION__, width, height); return (NULL); } /* @@ -624,8 +662,8 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i */ if (freq) { - if (cnt->conf.setup_mode) - motion_log(-1, 0, "Frequency set (no implemented yet"); + if (debug_level >= CAMERA_DEBUG) + motion_log(-1, 0, "%s: Frequency set (no implemented yet", __FUNCTION__); /* TODO missing implementation set_channelset(viddev); @@ -642,14 +680,14 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i /* That is the buffer size for capture images , so is dependent of color space of input format / FIXME */ - viddev->v4l_bufsize = (((width*height*3/2)) * sizeof(unsigned char *)); + viddev->v4l_bufsize = (((width * height * 3 / 2)) * sizeof(unsigned char *)); viddev->v4l_fmt = VIDEO_PALETTE_YUV420P; - map = mmap((caddr_t)0,viddev->v4l_bufsize,PROT_READ|PROT_WRITE,MAP_SHARED, dev_bktr, (off_t)0); + map = mmap((caddr_t)0, viddev->v4l_bufsize, PROT_READ|PROT_WRITE, MAP_SHARED, dev_bktr, (off_t)0); if (map == MAP_FAILED){ - motion_log(LOG_ERR, 1, "mmap failed"); + motion_log(LOG_ERR, 1, "%s: mmap failed", __FUNCTION__); return (NULL); } @@ -657,19 +695,19 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i if (0) { viddev->v4l_maxbuffer = 2; viddev->v4l_buffers[0] = map; - viddev->v4l_buffers[1] = (unsigned char *)map+0; /* 0 is not valid just a test */ - //viddev->v4l_buffers[1]=map+vid_buf.offsets[1]; + viddev->v4l_buffers[1] = (unsigned char *)map + 0; /* 0 is not valid just a test */ + //viddev->v4l_buffers[1] = map+vid_buf.offsets[1]; } else { viddev->v4l_buffers[0] = map; viddev->v4l_maxbuffer = 1; } - viddev->v4l_curbuffer=0; + viddev->v4l_curbuffer = 0; /* Clear the buffer */ if (ioctl(dev_bktr, BT848SCBUF, &dummy) < 0) { - motion_log(LOG_ERR, 1, "BT848SCBUF"); + motion_log(LOG_ERR, 1, "%s: BT848SCBUF", __FUNCTION__); return NULL; } @@ -682,54 +720,59 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i dummy = SIGUSR2; - viddev->capture_method = METEOR_CAP_CONTINOUS; + //viddev->capture_method = METEOR_CAP_CONTINOUS; + //viddev->capture_method = METEOR_CAP_SINGLE; - if (ioctl(dev_bktr, METEORSSIGNAL, &dummy) < 0) { - motion_log(LOG_ERR, 1, "METEORSSIGNAL"); - motion_log(LOG_INFO, 0 , "METEORSSIGNAL"); + if ((viddev->capture_method == METEOR_CAP_CONTINOUS) && (ioctl(dev_bktr, METEORSSIGNAL, &dummy) < 0)) { + motion_log(LOG_ERR, 1, "%s: METEORSSIGNAL", __FUNCTION__); + motion_log(LOG_INFO, 0 , "%s: METEORSSIGNAL", __FUNCTION__); viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0){ - motion_log(LOG_ERR, 1, "METEORCAPTUR using single method Error capturing"); - motion_log(LOG_INFO, 0, "METEORCAPTUR using single method Error capturing"); + motion_log(LOG_ERR, 1, "%s: METEORCAPTUR using single method " + "Error capturing", __FUNCTION__); + motion_log(LOG_INFO, 0, "%s: METEORCAPTUR using single method " + "Error capturing", __FUNCTION__); } - }else{ + } else { if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0) { viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0){ - motion_log(LOG_ERR, 1, "METEORCAPTUR using single method Error capturing"); - motion_log(LOG_INFO,0, "METEORCAPTUR using single method Error capturing"); + motion_log(LOG_ERR, 1, "%s: METEORCAPTUR using single method " + "Error capturing", __FUNCTION__); + motion_log(LOG_INFO, 0, "%s: METEORCAPTUR using single method " + "Error capturing", __FUNCTION__); } } } if (viddev->capture_method == METEOR_CAP_CONTINOUS) - motion_log(LOG_INFO, 0, "METEORCAPTUR METEOR_CAP_CONTINOUS"); + motion_log(LOG_INFO, 0, "%s: METEORCAPTUR METEOR_CAP_CONTINOUS", __FUNCTION__); else - motion_log(LOG_INFO, 0, "METEORCAPTUR METEOR_CAP_SINGLE"); + motion_log(LOG_INFO, 0, "%s: METEORCAPTUR METEOR_CAP_SINGLE", __FUNCTION__); // settle , sleep(1) replaced - SLEEP(1,0) + SLEEP(1, 0); /* FIXME*/ switch (viddev->v4l_fmt) { case VIDEO_PALETTE_YUV420P: - viddev->v4l_bufsize=(width*height*3)/2; + viddev->v4l_bufsize = (width * height * 3) / 2; break; case VIDEO_PALETTE_YUV422: - viddev->v4l_bufsize=(width*height*2); + viddev->v4l_bufsize = (width * height * 2); break; case VIDEO_PALETTE_RGB24: - viddev->v4l_bufsize=(width*height*3); + viddev->v4l_bufsize = (width * height * 3); break; case VIDEO_PALETTE_GREY: - viddev->v4l_bufsize=width*height; + viddev->v4l_bufsize = width * height; break; } - motion_log(LOG_INFO,0,"HUE [%d]",get_hue(dev_bktr,&dummy)); - motion_log(LOG_INFO,0,"SATURATION [%d]",get_saturation(dev_bktr,&dummy)); - motion_log(LOG_INFO,0,"BRIGHTNESS [%d]",get_brightness(dev_bktr,&dummy)); - motion_log(LOG_INFO,0,"CONTRAST [%d]",get_contrast(dev_bktr,&dummy)); + motion_log(LOG_INFO, 0, "HUE [%d]", get_hue(dev_bktr, &dummy)); + motion_log(LOG_INFO, 0, "SATURATION [%d]", get_saturation(dev_bktr, &dummy)); + motion_log(LOG_INFO, 0, "BRIGHTNESS [%d]", get_brightness(dev_bktr, &dummy)); + motion_log(LOG_INFO, 0, "CONTRAST [%d]", get_contrast(dev_bktr, &dummy)); return map; } @@ -748,12 +791,12 @@ static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, i * -1 Fatal error * 1 Non fatal error (not implemented) */ -static int v4l_next(struct video_dev *viddev,unsigned char *map, int width, int height) +static int v4l_next(struct video_dev *viddev, unsigned char *map, int width, int height) { - int dev_bktr=viddev->fd_bktr; - unsigned char *cap_map=NULL; - int single = METEOR_CAP_SINGLE; - sigset_t set, old; + int dev_bktr = viddev->fd_bktr; + unsigned char *cap_map = NULL; + int single = METEOR_CAP_SINGLE; + sigset_t set, old; /* ONLY MMAP method is used to Capture */ @@ -766,30 +809,29 @@ static int v4l_next(struct video_dev *viddev,unsigned char *map, int width, int sigaddset (&set, SIGUSR1); sigaddset (&set, SIGTERM); sigaddset (&set, SIGHUP); - pthread_sigmask (SIG_BLOCK, &set, &old); - cap_map=viddev->v4l_buffers[viddev->v4l_curbuffer]; + pthread_sigmask(SIG_BLOCK, &set, &old); + cap_map = viddev->v4l_buffers[viddev->v4l_curbuffer]; viddev->v4l_curbuffer++; if (viddev->v4l_curbuffer >= viddev->v4l_maxbuffer) - viddev->v4l_curbuffer=0; + viddev->v4l_curbuffer = 0; /* capture */ - if (viddev->capture_method == METEOR_CAP_CONTINOUS){ - if (bktr_frame_waiting) { + if (viddev->capture_method == METEOR_CAP_CONTINOUS) { + if (bktr_frame_waiting) bktr_frame_waiting = 0; - } - }else if (ioctl(dev_bktr, METEORCAPTUR, &single) < 0) { - motion_log(LOG_ERR, 1, "Error capturing using single method"); - sigprocmask (SIG_UNBLOCK, &old, NULL); + + } else if (ioctl(dev_bktr, METEORCAPTUR, &single) < 0) { + motion_log(LOG_ERR, 1, "%s: Error capturing using single method", __FUNCTION__); + sigprocmask(SIG_UNBLOCK, &old, NULL); return (-1); } /*undo the signal blocking*/ - pthread_sigmask (SIG_UNBLOCK, &old, NULL); + pthread_sigmask(SIG_UNBLOCK, &old, NULL); - - switch (viddev->v4l_fmt){ + switch (viddev->v4l_fmt) { case VIDEO_PALETTE_RGB24: rgb24toyuv420p(map, cap_map, width, height); break; @@ -799,7 +841,6 @@ static int v4l_next(struct video_dev *viddev,unsigned char *map, int width, int default: memcpy(map, cap_map, viddev->v4l_bufsize); } - return 0; } @@ -808,20 +849,26 @@ static int v4l_next(struct video_dev *viddev,unsigned char *map, int width, int /* set input & freq if needed FIXME not allowed use Tuner yet */ static void v4l_set_input(struct context *cnt, struct video_dev *viddev, unsigned char *map, int width, int height, - unsigned short input, unsigned short norm, int skip, unsigned long freq) + unsigned short input, unsigned short norm, int skip, unsigned long freq) { - int i; - unsigned long frequnits = freq; - if (input != viddev->input || width != viddev->width || height!=viddev->height || freq!=viddev->freq){ - if (set_input(viddev, input) == -1) + if (input != viddev->input || norm != viddev->norm || freq != viddev->freq) { + int dummy; + unsigned long frequnits = freq; + + + if ((dummy = set_input(viddev, input)) == -1) return; - if (set_input_format(viddev, norm) == -1 ) + viddev->input = dummy; + + if ((dummy = set_input_format(viddev, norm)) == -1) return; - if ((viddev->tuner_device != NULL) && ( input == IN_TV ) && (frequnits > 0)) { - if (set_freq (viddev, freq) == -1) + viddev->norm = dummy; + + if ((viddev->tuner_device != NULL) && ( viddev->input == IN_TV ) && (frequnits > 0)) { + if (set_freq(viddev, freq) == -1) return; } @@ -833,20 +880,17 @@ static void v4l_set_input(struct context *cnt, struct video_dev *viddev, unsigne } */ - viddev->norm=norm; - + /* if (set_geometry(viddev, width, height) == -1) return; - + */ + v4l_picture_controls(cnt, viddev); - - viddev->input = input; - viddev->width = width; - viddev->height = height; + viddev->freq = freq; /* skip a few frames if needed */ - for (i=0; inetcam) { + if (cnt->netcam) { netcam_cleanup(cnt->netcam, 0); cnt->netcam = NULL; return; @@ -939,24 +983,26 @@ void vid_close(struct context *cnt) cnt->video_dev = -1; if (dev == NULL) { - motion_log(LOG_ERR, 0, "vid_close: Unable to find video device"); + motion_log(LOG_ERR, 0, "%s: Unable to find video device", __FUNCTION__); return; } if( --dev->usage_count == 0) { - motion_log(LOG_INFO, 0, "Closing video device %s", dev->video_device); + motion_log(LOG_INFO, 0, "%s: Closing video device %s", __FUNCTION__, dev->video_device); if (dev->fd_tuner > 0) close(dev->fd_tuner); - if (dev->fd_bktr > 0){ - dev->fd_tuner = METEOR_CAP_STOP_CONT; - ioctl(dev->fd_bktr, METEORCAPTUR, &dev->fd_tuner); + if (dev->fd_bktr > 0) { + if (dev->capture_method == METEOR_CAP_CONTINOUS) { + dev->fd_tuner = METEOR_CAP_STOP_CONT; + ioctl(dev->fd_bktr, METEORCAPTUR, &dev->fd_tuner); + } close(dev->fd_bktr); dev->fd_tuner = -1; } - munmap(viddevs->v4l_buffers[0],viddevs->v4l_bufsize); + munmap(viddevs->v4l_buffers[0], viddevs->v4l_bufsize); viddevs->v4l_buffers[0] = MAP_FAILED; dev->fd_bktr = -1; @@ -972,7 +1018,8 @@ void vid_close(struct context *cnt) pthread_mutex_destroy(&dev->mutex); free(dev); } else { - motion_log(LOG_INFO, 0, "Still %d users of video device %s, so we don't close it now", dev->usage_count, dev->video_device); + motion_log(LOG_INFO, 0, "%s: Still %d users of video device %s, so we don't close it now", + __FUNCTION__, dev->usage_count, dev->video_device); /* There is still at least one thread using this device * If we own it, release it */ @@ -1001,17 +1048,17 @@ int vid_start(struct context *cnt) } #ifdef WITHOUT_V4L else - motion_log(LOG_ERR, 0,"You must setup netcam_url"); + motion_log(LOG_ERR, 0, "%s: You must setup netcam_url", __FUNCTION__); #else else{ struct video_dev *dev; - int fd_tuner =-1; - int width, height; + int fd_tuner = -1; + int width, height, capture_method; unsigned short input, norm; unsigned long frequency; - motion_log(-1, 0, "vid_start [%s]", conf->video_device); + motion_log(-1, 0, "%s: [%s]", __FUNCTION__, conf->video_device); /* We use width and height from conf in this function. They will be assigned * to width and height in imgs here, and cap_width and cap_height in @@ -1020,14 +1067,14 @@ int vid_start(struct context *cnt) */ if (conf->width % 16) { motion_log(LOG_ERR, 0, - "config image width (%d) is not modulo 16", - conf->width); + "%s: config image width (%d) is not modulo 16", + __FUNCTION__, conf->width); return -1; } if (conf->height % 16) { motion_log(LOG_ERR, 0, - "config image height (%d) is not modulo 16", - conf->height); + "%s: config image height (%d) is not modulo 16", + __FUNCTION__, conf->height); return -1; } width = conf->width; @@ -1035,7 +1082,8 @@ int vid_start(struct context *cnt) input = conf->input; norm = conf->norm; frequency = conf->frequency; - + capture_method = METEOR_CAP_CONTINOUS; + pthread_mutex_lock(&vid_mutex); /* Transfer width and height from conf to imgs. The imgs values are the ones @@ -1053,9 +1101,21 @@ int vid_start(struct context *cnt) dev = viddevs; while (dev) { if (!strcmp(conf->video_device, dev->video_device)) { + int dummy = METEOR_CAP_STOP_CONT; dev->usage_count++; cnt->imgs.type = dev->v4l_fmt; - motion_log(-1, 0, "vid_start cnt->imgs.type [%i]", cnt->imgs.type); + + if (ioctl(dev->fd_bktr, METEORCAPTUR, &dummy) < 0) { + motion_log(LOG_ERR, 1, "%s Stopping capture", __FUNCTION__); + return -1; + } + + motion_log(-1, 0, "%s Reusing [%s] inputs [%d,%d] Change capture method " + "METEOR_CAP_SINGLE", __FUNCTION__, dev->video_device, + dev->input, conf->input); + + dev->capture_method = METEOR_CAP_SINGLE; + switch (cnt->imgs.type) { case VIDEO_PALETTE_GREY: cnt->imgs.motionsize = width * height; @@ -1066,7 +1126,8 @@ int vid_start(struct context *cnt) cnt->imgs.type = VIDEO_PALETTE_YUV420P; case VIDEO_PALETTE_YUV420P: motion_log(-1, 0, - " VIDEO_PALETTE_YUV420P setting imgs.size and imgs.motionsize"); + "%s VIDEO_PALETTE_YUV420P setting imgs.size " + "and imgs.motionsize", __FUNCTION__); cnt->imgs.motionsize = width * height; cnt->imgs.size = (width * height * 3) / 2; break; @@ -1081,10 +1142,10 @@ int vid_start(struct context *cnt) dev = mymalloc(sizeof(struct video_dev)); memset(dev, 0, sizeof(struct video_dev)); - fd_bktr=open(conf->video_device, O_RDWR); + fd_bktr = open(conf->video_device, O_RDWR); if (fd_bktr < 0) { - motion_log(LOG_ERR, 1, "open video device %s",conf->video_device); + motion_log(LOG_ERR, 1, "%s: open video device %s", __FUNCTION__, conf->video_device); free(dev); pthread_mutex_unlock(&vid_mutex); return -1; @@ -1093,9 +1154,10 @@ int vid_start(struct context *cnt) /* Only open tuner if conf->tuner_device has set , freq and input is 1 */ if ( (conf->tuner_device != NULL) && (frequency > 0) && ( input == IN_TV )) { - fd_tuner=open(conf->tuner_device, O_RDWR); + fd_tuner = open(conf->tuner_device, O_RDWR); if (fd_tuner < 0) { - motion_log(LOG_ERR, 1, "open tuner device %s",conf->tuner_device); + motion_log(LOG_ERR, 1, "%s: open tuner device %s", + __FUNCTION__, conf->tuner_device); free(dev); pthread_mutex_unlock(&vid_mutex); return -1; @@ -1115,7 +1177,8 @@ int vid_start(struct context *cnt) dev->width = width; dev->freq = frequency; dev->owner = -1; - + dev->capture_method = capture_method; + /* We set brightness, contrast, saturation and hue = 0 so that they only get * set if the config is not zero. */ @@ -1131,7 +1194,7 @@ int vid_start(struct context *cnt) dev->v4l_curbuffer = 0; dev->v4l_maxbuffer = 1; - if (!v4l_start (cnt, dev, width, height, input, norm, frequency)){ + if (!v4l_start(dev, width, height, input, norm, frequency)) { close(dev->fd_bktr); pthread_mutexattr_destroy(&dev->attr); pthread_mutex_destroy(&dev->mutex); @@ -1141,7 +1204,7 @@ int vid_start(struct context *cnt) return -1; } - cnt->imgs.type=dev->v4l_fmt; + cnt->imgs.type = dev->v4l_fmt; switch (cnt->imgs.type) { case VIDEO_PALETTE_GREY: @@ -1152,7 +1215,7 @@ int vid_start(struct context *cnt) case VIDEO_PALETTE_YUV422: cnt->imgs.type = VIDEO_PALETTE_YUV420P; case VIDEO_PALETTE_YUV420P: - motion_log(-1, 0, "VIDEO_PALETTE_YUV420P imgs.type"); + motion_log(-1, 0, "%s: VIDEO_PALETTE_YUV420P imgs.type", __FUNCTION__); cnt->imgs.size = (width * height * 3) / 2; cnt->imgs.motionsize = width * height; break; @@ -1186,7 +1249,7 @@ int vid_start(struct context *cnt) */ int vid_next(struct context *cnt, unsigned char *map) { - struct config *conf=&cnt->conf; + struct config *conf = &cnt->conf; int ret = -1; if (conf->netcam_url) { @@ -1209,18 +1272,19 @@ int vid_next(struct context *cnt, unsigned char *map) pthread_mutex_lock(&vid_mutex); dev = viddevs; - while (dev){ - if (dev->fd_bktr==dev_bktr) + while (dev) { + if (dev->fd_bktr == dev_bktr) break; dev = dev->next; } + pthread_mutex_unlock(&vid_mutex); if (dev == NULL) return V4L_FATAL_ERROR; //return -1; - if (dev->owner!=cnt->threadnr) { + if (dev->owner != cnt->threadnr) { pthread_mutex_lock(&dev->mutex); dev->owner = cnt->threadnr; dev->frames = conf->roundrobin_frames; @@ -1238,7 +1302,7 @@ int vid_next(struct context *cnt, unsigned char *map) pthread_mutex_unlock(&dev->mutex); } - if(cnt->rotate_data.degrees > 0){ + if (cnt->rotate_data.degrees > 0) { /* rotate the image as specified */ rotate_map(cnt, map); } diff --git a/video_freebsd.h b/video_freebsd.h index 1202dc5a..b548fbb5 100644 --- a/video_freebsd.h +++ b/video_freebsd.h @@ -122,8 +122,8 @@ struct video_dev { /* video functions, video_freebsd.c */ int vid_start(struct context *); -int vid_next(struct context *, unsigned char *map); -void vid_close(struct context *cnt); +int vid_next(struct context *, unsigned char *); +void vid_close(struct context *); #ifndef WITHOUT_V4L void vid_init(void); diff --git a/webhttpd.c b/webhttpd.c index d9db324e..cfd242bf 100644 --- a/webhttpd.c +++ b/webhttpd.c @@ -2292,8 +2292,10 @@ void httpd_run(struct context **cnt) /* create socket */ sd = socket(AF_INET, SOCK_STREAM, 0); + if (sd<0) { motion_log(LOG_ERR, 1, "httpd socket"); + pthread_mutex_destroy(&httpd_mutex); return; } @@ -2312,12 +2314,14 @@ void httpd_run(struct context **cnt) if (bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) { motion_log(LOG_ERR, 1, "httpd bind()"); close(sd); + pthread_mutex_destroy(&httpd_mutex); return; } if (listen(sd,5) == -1){ motion_log(LOG_ERR, 1, "httpd listen()"); close(sd); + pthread_mutex_destroy(&httpd_mutex); return; }