motion源代码解析

    很久没有更新blog,这样不好,工作之后仍然需要不断的学习新的技术,工作外的技术等等……

    motion是一个基于Linux平台的开源项目,其功能是检测视频流中的画面运动,类似于移动侦测。整个项目只有30多个文件,非常小巧。据说axis这个网络摄像机的大牌厂商也使用该算法处理。所有我也需要啃一啃才行啊~!   

    程序的入口是在motion.c中的main函数

/** * 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; 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 */ motion_log(LOG_INFO,0,"motion restarted"); #ifndef WITHOUT_V4L SLEEP(5,0); // maybe some cameras needs less time #endif motion_startup(0, argc, argv); /* 0 = skip daemon init */ } /* 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++) { /* If i is 0 it means no thread files and we then set the thread number to 1 */ cnt_list[i]->threadnr = i ? i : 1; if (strcmp(cnt_list[i]->conf_filename,"") ) motion_log(LOG_INFO, 0, "Thread %d is from %s", cnt_list[i]->threadnr, cnt_list[i]->conf_filename ); if (cnt_list[0]->conf.setup_mode) { motion_log(-1, 0, "Thread %d is device: %s input %d", cnt_list[i]->threadnr, 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 ); } if (cnt_list[0]->conf.setup_mode) motion_log(LOG_ERR, 0, "Webcam port %d", cnt_list[i]->conf.webcam_port); start_motion_thread(cnt_list[i], &thread_attr); } /* 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 (1) { SLEEP(1,0); /* Calculate how many threads runnig or wants to run * if zero and we want to finish, break out */ int motion_threads_running = 0; for (i = (cnt_list[1] != NULL ? 1 : 0); cnt_list[i]; i++) { if (cnt_list[i]->running || cnt_list[i]->restart) motion_threads_running++; } if (((motion_threads_running == 0 ) && finish ) || ((motion_threads_running == 0 ) && (threads_running == 0)) ){ if (debug_level >= CAMERA_DEBUG){ motion_log(LOG_INFO, 0, "DEBUG-1 threads_running %d motion_threads_running %d , finish %d", threads_running, motion_threads_running, finish); } break; } for (i = (cnt_list[1] != NULL ? 1 : 0); cnt_list[i]; i++) { /* Check if threads wants to be restarted */ if ((!cnt_list[i]->running) && (cnt_list[i]->restart) ) { motion_log(LOG_INFO, 0, "Motion thread %d restart", cnt_list[i]->threadnr); start_motion_thread(cnt_list[i], &thread_attr); } if (cnt_list[i]->watchdog > WATCHDOG_OFF) { cnt_list[i]->watchdog--; if (cnt_list[i]->watchdog == 0) { motion_log(LOG_ERR, 0, "Thread %d - Watchdog timeout, trying to do a graceful restart", cnt_list[i]->threadnr); cnt_list[i]->finish = 1; } if (cnt_list[i]->watchdog == -60) { motion_log(LOG_ERR, 0, "Thread %d - Watchdog timeout, did NOT restart graceful," "killing it!", cnt_list[i]->threadnr); pthread_cancel(cnt_list[i]->thread_id); pthread_mutex_lock(&global_lock); threads_running--; pthread_mutex_unlock(&global_lock); motion_cleanup(cnt_list[i]); cnt_list[i]->running = 0; cnt_list[i]->finish = 0; } } } if (debug_level >= CAMERA_DEBUG){ motion_log(LOG_INFO, 0, "DEBUG-2 threads_running %d motion_threads_running %d , finish %d", threads_running, motion_threads_running, finish); } } /* Reset end main loop flag */ finish = 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 */ // Be sure that http control exits fine cnt_list[0]->finish = 1; SLEEP(1,0); 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; }

 

 

 

你可能感兴趣的:(motion源代码解析)