int main(int argc, char *argv[])
{
char *input = "input_uvc.so --resolution 640x480 --fps 5 --device /dev/video0";
// 指向输入选项参数字符串
char *output[MAX_OUTPUT_PLUGINS];
/* 指向输出选项参数字符串 */
int daemon=0, i;
/* 是否让程序在后台运行的标志 */
size_t tmp=0;
output[0] = "output_http.so --port 8080";
global.outcnt = 0; /* 输出方式个数*/
while(1)
{
int option_index = 0, c=0;
static struct option long_options[] = \
{
{"h", no_argument, 0, 0},
{"help", no_argument, 0, 0},
{"i", required_argument, 0, 0},
{"input", required_argument, 0, 0},
{"o", required_argument, 0, 0},
{"output", required_argument, 0, 0},
{"v", no_argument, 0, 0},
{"version", no_argument, 0, 0},
{"b", no_argument, 0, 0},
{"background", no_argument, 0, 0},
{0, 0, 0, 0}
};
/* -i "input_uvc.so -f 10 -r 320*240" -o "output_http.so -w www" */
c = getopt_long_only(argc, argv, "", long_options, &option_index);
/* no more options to parse */
/* 参数解析完成 */
if (c == -1)
break;
/* unrecognized option */
/* 如果传人参数不正确,则打印帮助信息 */
if(c=='?')
{
help(argv[0]);
return 0;
}
switch (option_index)
{
/* h, help */
case 0:
case 1:
help(argv[0]);
return 0;
break;
/* i, input */
case 2:
case 3:
input = strdup(optarg); // input = "input_uvc.so -f 10 -r 320*240"
break;
/* o, output */
case 4:
case 5:
output[global.outcnt++] = strdup(optarg);//output[0] = "output_http.so -w www"
break;
/* v, version */
case 6:
case 7:
printf("MJPG Streamer Version: %s\n" \
"Compilation Date.....: %s\n" \
"Compilation Time.....: %s\n", SOURCE_VERSION, __DATE__, __TIME__);
return 0;
break;
/* b, background */
case 8:
case 9:
daemon=1;
break;
default:
help(argv[0]);
return 0;
}
}
openlog("MJPG-streamer ", LOG_PID|LOG_CONS, LOG_USER);
syslog(LOG_INFO, "starting application");
/* fork to the background */
/* 如daemon = 1,则让程序后台运行 */
if ( daemon )
{
LOG("enabling daemon mode");
daemon_mode();
}
/* initialise the global variables */
global.stop = 0;
global.buf = NULL;
global.size = 0;
global.in.plugin = NULL;
/* this mutex and the conditional variable are used to synchronize access to the
global picture buffer */
if( pthread_mutex_init(&global.db, NULL) != 0 )
{
LOG("could not initialize mutex variable\n");
closelog();
exit(EXIT_FAILURE);
}
if( pthread_cond_init(&global.db_update, NULL) != 0 ) /* 条件变量,用于线程间通讯 */
{
LOG("could not initialize condition variable\n");
closelog();
exit(EXIT_FAILURE);
}
/* ignore SIGPIPE (send by OS if transmitting to closed TCP sockets) */
signal(SIGPIPE, SIG_IGN);
/* register signal handler for <CTRL>+C in order to clean up */
if (signal(SIGINT, signal_handler) == SIG_ERR)
{
LOG("could not register signal handler\n");
closelog();
exit(EXIT_FAILURE);
}
/*
* messages like the following will only be visible on your terminal
* if not running in daemon mode
*/
LOG("MJPG Streamer Version.: %s\n", SOURCE_VERSION);
/* check if at least one output plugin was selected */
if ( global.outcnt == 0 )
{
/* no? Then use the default plugin instead */
global.outcnt = 1;
}
/* open input plugin */
/* "input_uvc.so -f 10 -r 320*240" */
tmp = (size_t)(strchr(input, ' ')-input); // 让tmp 等于 "input_uvc.so"字符串的长度
global.in.plugin = (tmp > 0)?strndup(input, tmp):strdup(input);//plugin="input_uvc.so"
global.in.handle = dlopen(global.in.plugin, RTLD_LAZY); // 打开"input_uvc.so"动态链接库
if ( !global.in.handle )
{
LOG("ERROR: could not find input plugin\n");
LOG(" Perhaps you want to adjust the search path with:\n");
LOG(" # export LD_LIBRARY_PATH=/path/to/plugin/folder\n");
LOG(" dlopen: %s\n", dlerror() );
closelog();
exit(EXIT_FAILURE);
}
global.in.init = dlsym(global.in.handle, "input_init");//让 global.in.init = input_init
if ( global.in.init == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
global.in.stop = dlsym(global.in.handle, "input_stop");
if ( global.in.stop == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
global.in.run = dlsym(global.in.handle, "input_run");
if ( global.in.run == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
/* try to find optional command */
global.in.cmd = dlsym(global.in.handle, "input_cmd");
global.in.param.parameter_string = strchr(input, ' ');
// global.in.param.parameter_string = "-f 10 -r 320*240"
global.in.param.global = &global;
if ( global.in.init(&global.in.param) )
{
LOG("input_init() return value signals to exit");
closelog();
exit(0);
}
/* open output plugin */
for (i=0; i<global.outcnt; i++) // outcnt = 1
{
/* "output_http.so -w www" */
tmp = (size_t)(strchr(output[i], ' ')-output[i]);
global.out[i].plugin = (tmp > 0)?strndup(output[i], tmp):strdup(output[i]);
global.out[i].handle = dlopen(global.out[i].plugin, RTLD_LAZY);
if ( !global.out[i].handle )
{
LOG("ERROR: could not find output plugin %s\n", global.out[i].plugin);
LOG(" Perhaps you want to adjust the search path with:\n");
LOG(" # export LD_LIBRARY_PATH=/path/to/plugin/folder\n");
LOG(" dlopen: %s\n", dlerror() );
closelog();
exit(EXIT_FAILURE);
}
global.out[i].init = dlsym(global.out[i].handle, "output_init");
if ( global.out[i].init == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
global.out[i].stop = dlsym(global.out[i].handle, "output_stop");
if ( global.out[i].stop == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
global.out[i].run = dlsym(global.out[i].handle, "output_run");
if ( global.out[i].run == NULL )
{
LOG("%s\n", dlerror());
exit(EXIT_FAILURE);
}
/* try to find optional command */
global.out[i].cmd = dlsym(global.out[i].handle, "output_cmd");
global.out[i].param.parameter_string = strchr(output[i], ' ');
global.out[i].param.global = &global;
global.out[i].param.id = i;
if ( global.out[i].init(&global.out[i].param) )
{
LOG("output_init() return value signals to exit");
closelog();
exit(0);
}
}
/* start to read the input, push pictures into global buffer */
DBG("starting input plugin\n");
syslog(LOG_INFO, "starting input plugin");
global.in.run();
DBG("starting %d output plugin(s)\n", global.outcnt);
for(i=0; i<global.outcnt; i++)
{
syslog(LOG_INFO, "starting output plugin: %s (ID: %02d)",
global.out[i].plugin, global.out[i].param.id);
global.out[i].run(global.out[i].param.id);
}
/* wait for signals */
pause();
return 0;
}
Mjpg_streamer.c的main函数分析
最新推荐文章于 2021-09-27 11:56:34 发布