- 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
This commit is contained in:
AngelCarpintero
2008-07-09 11:45:25 +00:00
parent 1b4a4c8c82
commit ad2a2cdcf3
5 changed files with 268 additions and 199 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 <sys/mman.h>
#include <sys/types.h>
/* 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<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;
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; i<skip; i++)
for (dummy = 0; dummy < skip; dummy++)
v4l_next(viddev, map, width, height);
}else{
/* No round robin - we only adjust picture controls */
@@ -917,7 +961,7 @@ void vid_close(struct context *cnt)
#endif
/* Cleanup the netcam part */
if(cnt->netcam) {
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);
}

View File

@@ -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);

View File

@@ -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;
}