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

📄 netcam.c

📁 motion motion
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * Note that the average frame time is held in microseconds.	 */	if (netcam->last_image.tv_sec) {		netcam->av_frame_time = (9.0 * netcam->av_frame_time +		                         1000000.0 * (curtime.tv_sec - netcam->last_image.tv_sec) +		                         (curtime.tv_usec- netcam->last_image.tv_usec)) / 10.0;		if (debug_level > CAMERA_INFO) 			motion_log(-1, 0, "Calculated frame time %f", netcam->av_frame_time);	}	netcam->last_image = curtime;	pthread_mutex_lock(&netcam->mutex);	xchg = netcam->latest;	netcam->latest = netcam->receiving;	netcam->receiving = xchg;	netcam->imgcnt++;	/*	 * We have a new frame ready.  We send a signal so that	 * any thread (e.g. the motion main loop) waiting for the	 * next frame to become available may proceed.	 */	pthread_cond_signal(&netcam->pic_ready);	pthread_mutex_unlock(&netcam->mutex);	if (!netcam->caps.streaming) {		if (!netcam->connect_keepalive) {			if (debug_level > CAMERA_INFO )	 			motion_log(LOG_DEBUG, 0, "netcam_read_html_jpeg disconnecting netcam since keep-alive not set." );			netcam_disconnect(netcam);		} else if (debug_level > CAMERA_INFO ) {			motion_log(LOG_DEBUG, 0, "netcam_read_html_jpeg leaving netcam connected." );		}	}	return 0;}/** * netcam_read_ftp_jpeg * *      This routine reads from a netcam using the FTP protocol. *      The current implementation is still a little experimental, *      and needs some additional code for error detection and *      recovery. */static int netcam_read_ftp_jpeg(netcam_context_ptr netcam){	netcam_buff_ptr buffer;	int len;	netcam_buff *xchg;	struct timeval curtime;	/* Point to our working buffer */	buffer = netcam->receiving;	buffer->used = 0;	/* Request the image from the remote server */	if (ftp_get_socket(netcam->ftp) <= 0) {		motion_log(LOG_ERR, 0, "ftp_get_socket failed in netcam_read_jpeg");		return -1;	}	/* Now fetch the image using ftp_read.  Note this is a blocking call */	do {		/* Assure there's enough room in the buffer */		netcam_check_buffsize(buffer, FTP_BUF_SIZE);		/* Do the read */		if ((len = ftp_read(netcam->ftp, buffer->ptr + buffer->used, FTP_BUF_SIZE)) < 0)			return -1;		buffer->used += len;	} while (len > 0);	if (gettimeofday(&curtime, NULL) < 0) {		motion_log(LOG_ERR, 1, "gettimeofday in netcam_read_jpeg");	}	netcam->receiving->image_time = curtime;	/*	 * Calculate our "running average" time for this netcam's	 * frame transmissions (except for the first time).	 * Note that the average frame time is held in microseconds.	 */	if (netcam->last_image.tv_sec) {		netcam->av_frame_time =		  ((9.0 * netcam->av_frame_time) + 1000000.0 *		  (curtime.tv_sec - netcam->last_image.tv_sec) +		  (curtime.tv_usec- netcam->last_image.tv_usec))		  / 10.0;		if (debug_level > CAMERA_INFO)			motion_log(-1, 0, "Calculated frame time %f", netcam->av_frame_time);	}	netcam->last_image = curtime;	/*	 * read is complete - set the current 'receiving' buffer atomically	 * as 'latest', and make the buffer previously in 'latest' become	 * the new 'receiving'	 */	pthread_mutex_lock(&netcam->mutex);	xchg = netcam->latest;	netcam->latest = netcam->receiving;	netcam->receiving = xchg;	netcam->imgcnt++;	/*	 * We have a new frame ready.  We send a signal so that	 * any thread (e.g. the motion main loop) waiting for the	 * next frame to become available may proceed.	 */	pthread_cond_signal(&netcam->pic_ready);	pthread_mutex_unlock(&netcam->mutex);	return 0;}/** * netcam_read_file_jpeg * *      This routine reads local image file. ( netcam_url file:///path/image.jpg ) *      The current implementation is still a little experimental, *      and needs some additional code for error detection and *      recovery. */static int netcam_read_file_jpeg(netcam_context_ptr netcam){	int loop_counter=0;	if (debug_level > CAMERA_VERBOSE) {		motion_log(-1,0,"Begin %s", __FUNCTION__);	}	netcam_buff_ptr buffer;	int len;	netcam_buff *xchg;	struct timeval curtime;	struct stat statbuf;	/* Point to our working buffer */	buffer = netcam->receiving;	buffer->used = 0;	/*int fstat(int filedes, struct stat *buf);*/	do {		if( stat( netcam->file->path, &statbuf) ) {			motion_log(-1, 0, "stat(%s) error", netcam->file->path );			return -1;		}			if (debug_level > CAMERA_VERBOSE) {			motion_log(-1, 0, "statbuf.st_mtime[%d] != last_st_mtime[%d]", statbuf.st_mtime,  netcam->file->last_st_mtime);		}		if( loop_counter>((POLLING_TIMEOUT*1000*1000)/(POLLING_TIME/1000)) ) { //its waits POLLING_TIMEOUT			motion_log(-1, 0, "waiting new file image timeout" );			return -1;		}		if (debug_level > CAMERA_VERBOSE) {			motion_log(-1, 0, "delay waiting new file image ");		}		//SLEEP(netcam->timeout.tv_sec, netcam->timeout.tv_usec*1000 ); //its waits 5seconds - READ_TIMEOUT		SLEEP( 0, POLLING_TIME ); // its waits 500ms		/*return -1;*/		loop_counter++;	} while(statbuf.st_mtime==netcam->file->last_st_mtime);	netcam->file->last_st_mtime = statbuf.st_mtime;	if (debug_level > CAMERA_INFO) {		motion_log(LOG_INFO, 0, "processing new file image - st_mtime "		                        "%d", netcam->file->last_st_mtime );	}	/* Assure there's enough room in the buffer */	while( buffer->size < (size_t)statbuf.st_size ) {		netcam_check_buffsize(buffer, statbuf.st_size ); 	}	/* Do the read */	netcam->file->control_file_desc = open( netcam->file->path, O_RDONLY );	if( netcam->file->control_file_desc < 0 ) {		motion_log(-1, 0, "open(%s) error:%d", netcam->file->path, netcam->file->control_file_desc );		return -1;	}	if ((len = read(netcam->file->control_file_desc, buffer->ptr + buffer->used, statbuf.st_size)) < 0) {		motion_log(-1, 0, "read(%s) error:%d", netcam->file->control_file_desc, len );		return -1;	}	buffer->used += len;	close( netcam->file->control_file_desc );	if (gettimeofday(&curtime, NULL) < 0) {		motion_log(LOG_ERR, 1, "gettimeofday in netcam_read_jpeg");	}	netcam->receiving->image_time = curtime;	/*	 * Calculate our "running average" time for this netcam's	 * frame transmissions (except for the first time).	 * Note that the average frame time is held in microseconds.	 */	if (netcam->last_image.tv_sec) {		netcam->av_frame_time =		  ((9.0 * netcam->av_frame_time) + 1000000.0 *		  (curtime.tv_sec - netcam->last_image.tv_sec) +		  (curtime.tv_usec- netcam->last_image.tv_usec))		  / 10.0;			if (debug_level > CAMERA_INFO)			motion_log(-1, 0, "Calculated frame time %f", netcam->av_frame_time);	}	netcam->last_image = curtime;	/*	 * read is complete - set the current 'receiving' buffer atomically	 * as 'latest', and make the buffer previously in 'latest' become	 * the new 'receiving'	 */	pthread_mutex_lock(&netcam->mutex);	xchg = netcam->latest;	netcam->latest = netcam->receiving;	netcam->receiving = xchg;	netcam->imgcnt++;	/*	 * We have a new frame ready.  We send a signal so that	 * any thread (e.g. the motion main loop) waiting for the	 * next frame to become available may proceed.	 */	pthread_cond_signal(&netcam->pic_ready);	pthread_mutex_unlock(&netcam->mutex);	if (debug_level > CAMERA_VERBOSE) {		motion_log(-1,0,"End %s", __FUNCTION__);	}	return 0;}tfile_context *file_new_context(void) {	tfile_context *ret;	/* note that mymalloc will exit on any problem */	ret = mymalloc(sizeof(tfile_context));	if (!ret)		return ret;	memset(ret, 0, sizeof(tfile_context));	return ret;}void file_free_context(tfile_context* ctxt) {	if (ctxt == NULL)		return;	if (ctxt->path != NULL)		free(ctxt->path);	free(ctxt);}static int netcam_setup_file(netcam_context_ptr netcam, struct url_t *url) {	if ((netcam->file = file_new_context()) == NULL)		return -1;	/*	 * We copy the strings out of the url structure into the ftp_context	 * structure.  By setting url->{string} to NULL we effectively "take	 * ownership" of the string away from the URL (i.e. it won't be freed	 * when we cleanup the url structure later).	 */	netcam->file->path = url->path;	url->path = NULL;	if (debug_level > CAMERA_INFO)		motion_log(LOG_INFO, 0, "netcam_setup_file: netcam->file->path %s",netcam->file->path);	netcam_url_free(url);	netcam->get_image = netcam_read_file_jpeg;	return 0;}/** * netcam_handler_loop *      This is the "main loop" for the handler thread.  It is created *      in netcam_start when a streaming camera is detected. * * Parameters * *      arg     Pointer to the motion context for this camera * * Returns:     NULL pointer * */static void *netcam_handler_loop(void *arg){	int retval;	int open_error = 0;	netcam_context_ptr netcam = arg;	struct context *cnt = netcam->cnt; /* needed for the SETUP macro :-( */	/* Store the corresponding motion thread number in TLS also for this	 * thread (necessary for 'motion_log' to function properly).	 */	pthread_setspecific(tls_key_threadnr, (void *)((unsigned long)cnt->threadnr));	if (SETUP)		motion_log(LOG_INFO, 0, "Camera handler thread [%d]  started", netcam->threadnr);	/*	 * The logic of our loop is very simple.  If this is a non-	 * streaming camera, we re-establish connection with the camera	 * and read the header record.  If it's a streaming camera, we	 * position to the next "boundary string" in the input stream.	 * In either case, we then read the following JPEG image into the	 * next available buffer, updating the "next" and "latest" indices	 * in our netcam * structure.  The loop continues until netcam->finish	 * or cnt->finish is set.	 */	while (!netcam->finish) {		if (netcam->response) {    /* if html input */			if (!netcam->caps.streaming) {				/* Non-streaming ie. jpeg */				if (!netcam->connect_keepalive || (netcam->connect_keepalive && netcam->keepalive_timeup)) {					/* If keepalive flag set but time up, time to close this socket */					if (netcam->connect_keepalive && netcam->keepalive_timeup) {						motion_log(LOG_INFO, 0, "Closing netcam socket as Keep-Alive time is up "						                        "(camera sent Close field). A reconnect should happen.");						netcam_disconnect(netcam);						netcam->keepalive_timeup = FALSE;					}					/* And the netcam_connect call below will open a new one */					if (netcam_connect(netcam, open_error) < 0) {						if (!open_error) { /* log first error */							motion_log(LOG_ERR, 0,					    		"re-opening camera (non-streaming)");							open_error = 1;						}						/* need to have a dynamic delay here */						SLEEP(5,0);						continue;					}					if (open_error) {          /* log re-connection */						motion_log(LOG_ERR, 0,				    		"camera re-connected");						open_error = 0;					}				}				/* Send our request and look at the response */				if ((retval = netcam_read_first_header(netcam)) != 1) {					if (retval > 0) {						motion_log(LOG_ERR, 0,						    "Unrecognized image header (%d)", retval);					} else if (retval != -1) {						motion_log(LOG_ERR, 0,						           "Error in header (%d)", retval);					}					/* need to have a dynamic delay here */					continue;				}			} else {	/* Streaming */				if (netcam_read_next_header(netcam) < 0) {					if (netcam_connect(netcam, open_error) < 0) {						if (!open_error) { /* log first error */							motion_log(LOG_ERR, 0,							    "re-opening camera (streaming)");							open_error = 1;						}						SLEEP(5,0);						continue;					}					if ((retval = netcam_read_first_header(netcam) != 2)) {						if (retval > 0) {							motion_log(LOG_ERR, 0,							    "Unrecognized image header (%d)",							     retval);						} else if (retval != -1) {							motion_log(LOG_ERR, 0,							    "Error in header (%d)", retval);						}						/* FIXME need some limit */						continue;					}				}				if (open_error) {          /* log re-connection */					motion_log(LOG_ERR, 0,					    "camera re-connected");					open_error = 0;				}			}		}		if (netcam->get_image(netcam) < 0) {			motion_log(LOG_ERR, 0, "Error getting jpeg image");			/* if FTP connection, attempt to re-connect to server */			if (netcam->ftp) {				close(netcam->ftp->control_file_desc);				if (ftp_connect(netcam) < 0) {					motion_log(LOG_ERR, 0, "Trying to re-connect");				}

⌨️ 快捷键说明

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