⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_freebsd.c

📁 motion motion
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		*/		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++)			v4l_next(viddev, map, width, height);	}else{		/* No round robin - we only adjust picture controls */		v4l_picture_controls(cnt, viddev);	}}/*****************************************************************************	Wrappers calling the current capture routines *****************************************************************************//*vid_init - Initi vid_mutex.vid_start - Setup Device parameters ( device , channel , freq , contrast , hue , saturation , brightness ) and open it.vid_next - Capture a frame and set input , contrast , hue , saturation and brightness if necessary. vid_close - close devices. vid_cleanup - Destroy vid_mutex.*//* big lock for vid_start to ensure exclusive access to viddevs while adding * devices during initialization of each thread */static pthread_mutex_t vid_mutex;/* Here we setup the viddevs structure which is used globally in the vid_* * functions. */      static struct video_dev *viddevs = NULL;/* * vid_init * * Called from motion.c at the very beginning before setting up the threads. * Function prepares the vid_mutex */void vid_init(void){	pthread_mutex_init(&vid_mutex, NULL);}                /** * vid_cleanup * * vid_cleanup is called from motion.c when Motion is stopped or restarted */void vid_cleanup(void){	pthread_mutex_destroy(&vid_mutex);}#endif /*WITHOUT_V4L*//** * vid_close * * vid_close is called from motion.c when a Motion thread is stopped or restarted */void vid_close(struct context *cnt)   {#ifndef WITHOUT_V4L        struct video_dev *dev = viddevs;        struct video_dev *prev = NULL;#endif        /* Cleanup the netcam part */        if(cnt->netcam) {                netcam_cleanup(cnt->netcam, 0);                cnt->netcam = NULL;                return;        } #ifndef WITHOUT_V4L        /* Cleanup the v4l part */        pthread_mutex_lock(&vid_mutex);        while (dev) {                if (dev->fd_bktr == cnt->video_dev)                        break;                prev = dev;                dev = dev->next;        }        pthread_mutex_unlock(&vid_mutex);         /* Set it as closed in thread context */        cnt->video_dev = -1;         if (dev == NULL) {                motion_log(LOG_ERR, 0, "vid_close: Unable to find video device");                   return;        }        if( --dev->usage_count == 0) {                motion_log(LOG_INFO, 0, "Closing video device %s", 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);			close(dev->fd_bktr);			dev->fd_tuner = -1;		}		munmap(viddevs->v4l_buffers[0],viddevs->v4l_bufsize);		viddevs->v4l_buffers[0] = MAP_FAILED;                dev->fd_bktr = -1;                pthread_mutex_lock(&vid_mutex);                /* Remove from list */                if (prev == NULL)                        viddevs = dev->next;                else                        prev->next = dev->next;                pthread_mutex_unlock(&vid_mutex);                pthread_mutexattr_destroy(&dev->attr);                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);                /* There is still at least one thread using this device                 * If we own it, release it                 */                if (dev->owner == cnt->threadnr) {                        dev->frames = 0;                        dev->owner = -1;                        pthread_mutex_unlock(&dev->mutex);                }        }#endif /* WITHOUT_V4L */}int vid_start(struct context *cnt){	struct config *conf = &cnt->conf;	int fd_bktr = -1;	if (conf->netcam_url) {		fd_bktr = netcam_start(cnt);		if (fd_bktr < 0) {			netcam_cleanup(cnt->netcam, 1);			cnt->netcam = NULL;		}	}	#ifdef WITHOUT_V4L	else 		motion_log(LOG_ERR, 0,"You must setup netcam_url");	#else	else{		struct video_dev *dev;		int fd_tuner =-1;		int width, height;		unsigned short input, norm;		unsigned long frequency;		motion_log(-1, 0, "vid_start [%s]", 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 		 * rotate_data won't be set until in rotate_init.		 * Motion requires that width and height are multiples of 16 so we check for this		 */		if (conf->width % 16) {			motion_log(LOG_ERR, 0,			           "config image width (%d) is not modulo 16",			           conf->width);			return -1;		}		if (conf->height % 16) {			motion_log(LOG_ERR, 0,			           "config image height (%d) is not modulo 16",			           conf->height);			return -1;		}		width = conf->width;		height = conf->height;		input = conf->input;		norm = conf->norm;		frequency = conf->frequency;		pthread_mutex_lock(&vid_mutex);		/* Transfer width and height from conf to imgs. The imgs values are the ones		 * that is used internally in Motion. That way, setting width and height via		 * http remote control won't screw things up.		 */		cnt->imgs.width = width;		cnt->imgs.height = height;		/* First we walk through the already discovered video devices to see		 * if we have already setup the same device before. If this is the case		 * the device is a Round Robin device and we set the basic settings		 * and return the file descriptor		 */		dev = viddevs;		while (dev) { 			if (!strcmp(conf->video_device, dev->video_device)) {				dev->usage_count++;				cnt->imgs.type = dev->v4l_fmt;				motion_log(-1, 0, "vid_start cnt->imgs.type [%i]", cnt->imgs.type);				switch (cnt->imgs.type) {					case VIDEO_PALETTE_GREY:						cnt->imgs.motionsize = width * height;						cnt->imgs.size = width * height;					break;					case VIDEO_PALETTE_RGB24:					case VIDEO_PALETTE_YUV422:						cnt->imgs.type = VIDEO_PALETTE_YUV420P;					case VIDEO_PALETTE_YUV420P:						motion_log(-1, 0,						           " VIDEO_PALETTE_YUV420P setting imgs.size and imgs.motionsize");						cnt->imgs.motionsize = width * height;						cnt->imgs.size = (width * height * 3) / 2;					break;				}				pthread_mutex_unlock(&vid_mutex);				return dev->fd_bktr; // FIXME return fd_tuner ?!			}			dev = dev->next;		}		dev = mymalloc(sizeof(struct video_dev));		memset(dev, 0, sizeof(struct video_dev));		fd_bktr=open(conf->video_device, O_RDWR);		if (fd_bktr < 0) { 			motion_log(LOG_ERR, 1, "open video device %s",conf->video_device);			free(dev);			pthread_mutex_unlock(&vid_mutex);			return -1;		}		/* 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);			if (fd_tuner < 0) { 				motion_log(LOG_ERR, 1, "open tuner device %s",conf->tuner_device);				free(dev);				pthread_mutex_unlock(&vid_mutex);				return -1;			}		}		pthread_mutexattr_init(&dev->attr);		pthread_mutex_init(&dev->mutex, &dev->attr);		dev->usage_count = 1;		dev->video_device = conf->video_device;		dev->tuner_device = conf->tuner_device;		dev->fd_bktr = fd_bktr;		dev->fd_tuner = fd_tuner;		dev->input = input;		dev->height = height;		dev->width = width;		dev->freq = frequency;		dev->owner = -1;		/* We set brightness, contrast, saturation and hue = 0 so that they only get                 * set if the config is not zero.                 */				dev->brightness = 0;		dev->contrast = 0;		dev->saturation = 0;		dev->hue = 0;		dev->owner = -1;		/* default palette */ 		dev->v4l_fmt = VIDEO_PALETTE_YUV420P;		dev->v4l_curbuffer = 0;		dev->v4l_maxbuffer = 1;		if (!v4l_start (cnt, dev, width, height, input, norm, frequency)){ 			close(dev->fd_bktr);			pthread_mutexattr_destroy(&dev->attr);                        pthread_mutex_destroy(&dev->mutex);                        free(dev);			pthread_mutex_unlock(&vid_mutex);			return -1;		}			cnt->imgs.type=dev->v4l_fmt;			switch (cnt->imgs.type) { 			case VIDEO_PALETTE_GREY:				cnt->imgs.size = width * height;				cnt->imgs.motionsize = width * height;			break;			case VIDEO_PALETTE_RGB24:			case VIDEO_PALETTE_YUV422:				cnt->imgs.type = VIDEO_PALETTE_YUV420P;			case VIDEO_PALETTE_YUV420P:				motion_log(-1, 0, "VIDEO_PALETTE_YUV420P imgs.type");				cnt->imgs.size = (width * height * 3) / 2;				cnt->imgs.motionsize = width * height;			break;		}		/* Insert into linked list */		dev->next = viddevs;		viddevs = dev;			pthread_mutex_unlock(&vid_mutex);	}#endif /* WITHOUT_V4L */	/* FIXME needed tuner device ?! */	return fd_bktr;}/** * vid_next fetches a video frame from a either v4l device or netcam * Parameters: *     cnt        Pointer to the context for this thread *     map        Pointer to the buffer in which the function puts the new image * * Returns *     0          Success *    -1          Fatal V4L error *    -2          Fatal Netcam error *     1          Non fatal V4L error (not implemented) *     2          Non fatal Netcam error */int vid_next(struct context *cnt, unsigned char *map){	struct config *conf=&cnt->conf;	int ret = -1;	if (conf->netcam_url) {		if (cnt->video_dev == -1)			return NETCAM_GENERAL_ERROR;		ret = netcam_next(cnt, map);		return ret;	}#ifndef WITHOUT_V4L	struct video_dev *dev;		int width, height;	int dev_bktr = cnt->video_dev;	/* NOTE: Since this is a capture, we need to use capture dimensions. */	width = cnt->rotate_data.cap_width;	height = cnt->rotate_data.cap_height;		pthread_mutex_lock(&vid_mutex);	dev = viddevs;		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) { 		pthread_mutex_lock(&dev->mutex);		dev->owner = cnt->threadnr;		dev->frames = conf->roundrobin_frames;	}	v4l_set_input(cnt, dev, map, width, height, conf->input, conf->norm,	              conf->roundrobin_skip, conf->frequency);		ret = v4l_next(dev, map, width, height);	if (--dev->frames <= 0) { 		dev->owner = -1;		dev->frames = 0;		pthread_mutex_unlock(&dev->mutex);	}	 	if(cnt->rotate_data.degrees > 0){ 		/* rotate the image as specified */		rotate_map(cnt, map); 	}	#endif /*WITHOUT_V4L*/	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -