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

📄 motion.c

📁 video motion detection of linux base
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* fork */	if (fork()) {		motion_log(-1, 0, "Motion going to daemon mode");		exit(0);	}		/* Create the pid file if defined, if failed exit	 * If we fail we report it. If we succeed we postpone the log entry till	 * later when we have closed stdout. Otherwise Motion hangs in the terminal waiting	 * for an enter.	 */	if (cnt_list[0]->conf.pid_file) {		pidf = fopen(cnt_list[0]->conf.pid_file, "w+");			if ( pidf ) {			(void)fprintf(pidf, "%d\n", getpid());			fclose(pidf);		} else {			motion_log(LOG_ERR, 1, "Exit motion, cannot create process id file (pid file) %s",			           cnt_list[0]->conf.pid_file);				exit(0);			}	}	/* changing dir to root enables people to unmount a disk	   without having to stop Motion */	if (chdir("/")) {		motion_log(LOG_ERR, 1, "Could not change directory");	}#if (defined(BSD))	setpgrp(0, getpid());#else	setpgrp();#endif /* BSD */		if ((i = open("/dev/tty", O_RDWR)) >= 0) {		ioctl(i, TIOCNOTTY, NULL);		close(i);	}	setsid();	i = open("/dev/null", O_RDONLY);	if(i != -1) {		dup2(i, STDIN_FILENO);		close(i);	}	i = open("/dev/null", O_WRONLY);	if(i != -1) {		dup2(i, STDOUT_FILENO);		dup2(i, STDERR_FILENO);		close(i);	}		/* Now it is safe to add the PID creation to the logs */	if ( pidf )		motion_log(LOG_INFO, 0, "Created process id file %s. Process ID is %d",		           cnt_list[0]->conf.pid_file, getpid());		sigaction(SIGTTOU, &sig_ign_action, NULL);	sigaction(SIGTTIN, &sig_ign_action, NULL);	sigaction(SIGTSTP, &sig_ign_action, NULL);}/** * cntlist_create * *   Sets up the 'cnt_list' variable by allocating room for (and actually *   allocating) one context struct. Also loads the configuration from *   the config file(s). * * Parameters: *   argc - size of argv *   argv - command-line options, passed initially from 'main' * * Returns: nothing */static void cntlist_create(int argc, char *argv[]){	/* cnt_list is an array of pointers to the context structures cnt for each thread.	 * First we reserve room for a pointer to thread 0's context structure	 * and a NULL pointer which indicates that end of the array of pointers to	 * thread context structures.	 */	cnt_list = mymalloc(sizeof(struct context *)*2);	/* Now we reserve room for thread 0's context structure and let cnt_list[0] point to it */	cnt_list[0] = mymalloc(sizeof(struct context));	/* Populate context structure with start/default values */	context_init(cnt_list[0]);	/* cnt_list[1] pointing to zero indicates no more thread context structures - they get added later */	cnt_list[1] = NULL;	/* Command line arguments are being pointed to from cnt_list[0] and we call conf_load which loads	 * the config options from motion.conf, thread config files and the command line.	 */	cnt_list[0]->conf.argv = argv;	cnt_list[0]->conf.argc = argc;	cnt_list = conf_load(cnt_list);}/** * motion_shutdown * *   Responsible for performing cleanup when Motion is shut down or restarted, *   including freeing memory for all the context structs as well as for the *   context struct list itself. * * Parameters: none * * Returns:    nothing */static void motion_shutdown(void){	int i = -1;	motion_remove_pid();		while (cnt_list[++i]){		context_destroy(cnt_list[i]);	}	free(cnt_list);#ifndef WITHOUT_V4L	vid_close();	vid_cleanup();#endif}/** * motion_startup * *   Responsible for initializing stuff when Motion starts up or is restarted, *   including daemon initialization and creating the context struct list. * * Parameters: * *   daemonize - non-zero to do daemon init (if the config parameters says so), *               or 0 to skip it *   argc      - size of argv *   argv      - command-line options, passed initially from 'main' * * Returns: nothing */static void motion_startup(int daemonize, int argc, char *argv[]){	/* Initialize our global mutex */	pthread_mutex_init(&global_lock, NULL);	/* Create the list of context structures and load the	 * configuration.	 */	cntlist_create(argc, argv);	initialize_chars();	if (daemonize) {		/* If daemon mode is requested, and we're not going into setup mode,		 * become daemon.		 */		if (cnt_list[0]->daemon && cnt_list[0]->conf.setup_mode == 0) {			become_daemon();			motion_log(LOG_INFO, 0, "Motion running as daemon process");			if (cnt_list[0]->conf.low_cpu) {				motion_log(LOG_INFO, 0, "Capturing %d frames/s when idle",				           cnt_list[0]->conf.low_cpu);			}		}	}#ifndef WITHOUT_V4L	vid_init();#endif}/** * setup_signals * *   Attaches handlers to a number of signals that Motion need to catch. * * Parameters: sigaction structs for signals in general and SIGCHLD. * * Returns:    nothing */static void setup_signals(struct sigaction *sig_handler_action, struct sigaction *sigchild_action){#ifdef SA_NOCLDWAIT	sigchild_action->sa_flags = SA_NOCLDWAIT;#else	sigchild_action->sa_flags = 0;#endif	sigchild_action->sa_handler = sigchild_handler;	sigemptyset(&sigchild_action->sa_mask);#ifdef SA_RESTART	sig_handler_action->sa_flags = SA_RESTART;#else	sig_handler_action->sa_flags = 0;#endif	sig_handler_action->sa_handler = sig_handler;	sigemptyset(&sig_handler_action->sa_mask);	/* Enable automatic zombie reaping */	sigaction(SIGCHLD, sigchild_action, NULL);	sigaction(SIGPIPE, sigchild_action, NULL);	sigaction(SIGALRM, sig_handler_action, NULL);	sigaction(SIGHUP,  sig_handler_action, NULL);	sigaction(SIGINT,  sig_handler_action, NULL);	sigaction(SIGQUIT, sig_handler_action, NULL);	sigaction(SIGTERM, sig_handler_action, NULL);	sigaction(SIGUSR1, sig_handler_action, NULL);}/** * main * *   Main entry point of Motion. Launches all the motion threads and contains *   the logic for starting up, restarting and cleaning up everything. * * Parameters: * *   argc - size of argv *   argv - command-line options * * Returns: Motion exit status = 0 always */int main (int argc, char **argv){	int i, j;	int webcam_port;	pthread_attr_t thread_attr;	pthread_t thread_id;	/* Setup signals and do some initialization. 1 in the call to	 * 'motion_startup' means that Motion will become a daemon if so has been	 * requested, and argc and argc are necessary for reading the command	 * line options.	 */	struct sigaction sig_handler_action;	struct sigaction sigchild_action;	setup_signals(&sig_handler_action, &sigchild_action);	motion_startup(1, argc, argv);#ifdef HAVE_FFMPEG	/* FFMpeg initialization is only performed if FFMpeg support was found	 * and not disabled during the configure phase.	 */	ffmpeg_init();#endif /* HAVE_FFMPEG */	/* In setup mode, Motion is very communicative towards the user, which	 * allows the user to experiment with the config parameters in order to	 * optimize motion detection and stuff.	 */	if(cnt_list[0]->conf.setup_mode)		motion_log(-1, 0, "Motion running in setup mode.");	/* Create and a thread attribute for the threads we spawn later on.	 * PTHREAD_CREATE_DETACHED means to create threads detached, i.e.	 * their termination cannot be synchronized through 'pthread_join'.	 */	pthread_attr_init(&thread_attr);	pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);	/* Create the TLS key for thread number. */	pthread_key_create(&tls_key_threadnr, NULL);	do {		if (restart) {			/* Handle the restart situation. Currently the approach is to			 * cleanup everything, and then initialize everything again			 * (including re-reading the config file(s)).			 */			motion_shutdown();			restart = 0; /* only one reset for now */#ifndef WITHOUT_V4L			SLEEP(5,0); // maybe some cameras needs less time#endif			motion_startup(0, argc, argv); /* 0 = skip daemon init */		}		/* Check the webcam port number for conflicts.		 * First we check for conflict with the control port.		 * Second we check for that two threads does not use the same port number		 * for the webcam. If a duplicate port is found the webcam feature gets disabled (port =0)		 * for this thread and a warning is written to console and syslog.		 */		for (i = 1; cnt_list[i]; i++) {			/* Get the webcam port for thread 'i', may be 0. */			webcam_port = cnt_list[i]->conf.webcam_port;			if (cnt_list[0]->conf.setup_mode)				motion_log(LOG_ERR, 0, "Webcam port %d", webcam_port);			/* Compare against the control port. */			if (cnt_list[0]->conf.control_port == webcam_port && webcam_port != 0) {				cnt_list[i]->conf.webcam_port = 0;				motion_log(LOG_ERR, 0,				           "Webcam port number %d for thread %d conflicts with the control port",				           webcam_port, i);				motion_log(LOG_ERR, 0, "Webcam feature for thread %d is disabled.", i);			}			/* Compare against webcam ports of other threads. */			j = i;			while (cnt_list[++j]) {				if (cnt_list[j]->conf.webcam_port == webcam_port && webcam_port != 0) {					cnt_list[j]->conf.webcam_port = 0;					motion_log(LOG_ERR, 0,					           "Webcam port number %d for thread %d conflicts with thread %d",					           webcam_port, j, i);					motion_log(LOG_ERR, 0,					           "Webcam feature for thread %d is disabled.", j);				}			}		}		/* Start the motion threads. First 'cnt_list' item is global if 'thread'		 * option is used, so start at 1 then and 0 otherwise.		 */		for (i = cnt_list[1] != NULL ? 1 : 0; cnt_list[i]; i++) {			/* Assign the thread number for this thread. This is done within a			 * mutex lock to prevent multiple simultaneous updates to			 * 'threads_running'.			 */			pthread_mutex_lock(&global_lock);			cnt_list[i]->threadnr = ++threads_running;			pthread_mutex_unlock(&global_lock);			if ( strcmp(cnt_list[i]->conf_filename,"") )				motion_log(LOG_INFO, 0, "Thread %d is from %s", threads_running, cnt_list[i]->conf_filename );			if (cnt_list[0]->conf.setup_mode) {				motion_log(-1, 0, "Thread %d is device: %s input %d", threads_running,				           cnt_list[i]->conf.netcam_url ? cnt_list[i]->conf.netcam_url : cnt_list[i]->conf.video_device,				           cnt_list[i]->conf.netcam_url ? -1 : cnt_list[i]->conf.input				          );			}			/* Create the actual thread. Use 'motion_loop' as the thread			 * function.			 */			pthread_create(&thread_id, &thread_attr, &motion_loop, cnt_list[i]);		}		/* Create a thread for the control interface if requested. Create it		 * detached and with 'motion_web_control' as the thread function.		 */		if (cnt_list[0]->conf.control_port)			pthread_create(&thread_id, &thread_attr, &motion_web_control, cnt_list);		if (cnt_list[0]->conf.setup_mode)			motion_log(-1, 0,"Waiting for threads to finish, pid: %d", getpid());		/* Crude way of waiting for all threads to finish - check the thread		 * counter (because we cannot do join on the detached threads).		 */		while(threads_running > 0) {			SLEEP(1,0);		}		if (cnt_list[0]->conf.setup_mode)			motion_log(LOG_DEBUG, 0, "Threads finished");		/* Rest for a while if we're supposed to restart. */		if (restart)			SLEEP(2,0);	} while (restart); /* loop if we're supposed to restart */	motion_log(LOG_INFO, 0, "Motion terminating");	/* Perform final cleanup. */	pthread_key_delete(tls_key_threadnr);	pthread_attr_destroy(&thread_attr);	pthread_mutex_destroy(&global_lock);	motion_shutdown();	return 0;}/** * mymalloc * *   Allocates some memory and checks if that succeeded or not. If it failed, *   do some errorlogging and bail out. * *   NOTE: Kenneth Lavrsen changed printing of size_t types so instead of using *   conversion s

⌨️ 快捷键说明

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