mjpg_streamer的源码学习(详解)

源码阅读顺序

mjpg_streamer/mjpg_streamer.c
       ->int main(int argc, char argv[])

mjpg_streamer/plugins/input_uvc.c
               ->input_init()
                     ->intput_run()
                         *->cam_thread()

mjpg-streamer\plugins\output_http.c
              ->output_init()
                   ->output_run()
                      ->*server_thread()
                       ->*client_thread()


源码结构分析流程图

这里借用一下韦东山老师画的流程图

image-20220308155236986
从这张流程图中,我们可以看出 *.so 的文件一共有7个 ,分别为三个输入插件(动态库):视频从文件读入(input_file);视频从摄像头读入(input_uvc);视频从网页读入(input_http)。 四个输出插件:视频输出到文件(output_file);视频输出到网页(output_http)。以input_uvc.so为例,通过dlopen()函数,调用该动态库的函数input_init() 完成摄像头的初始化,再创建一条线程,该线程负责完成视频流的读入,转化,导入到缓存区。 以output_http.so 为例 主进程main会通过dlopen,调用到该动态库的函数output_init来处理用户传入的参数,之后进入循环,等待input线程的请求连接,为每一对确认连接创建一个线程,该线程会读取缓存区中的视频流,然后将其输入到浏览器。

mjpg_streamer.c源码分析

下面我们来看看mjpg_streamer.c中主进程的源码

//为了不使篇幅过长,进行了一些删减
int main(int argc, char *argv[])
{
   
    //char *input  = "input_uvc.so --resolution 640x480 --fps 5 --device /dev/video0";
    char *input[MAX_INPUT_PLUGINS];
    char *output[MAX_OUTPUT_PLUGINS];
    int daemon = 0, i;
    size_t tmp = 0;

    output[0] = "output_http.so --port 8080";//定义默认输出的插件和端口
    global.outcnt = 0;



    /* parameter parsing */
    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}
        };
			
/*
getopt_long_only():
				
用于解析命令行选项

根据传入的参数,一个一个的在struct option 数组里面进行匹配,当匹配到相同的参数,返回在数组中的下标。如传入-i选项 ,argv中自然有i选项,就会和struct option 数组项进行匹配,找到时返回数组下标。option_index索引值为2.
*/

        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[global.incnt++] = strdup(optarg);/*在getopt_long_only函数中,把传入的-i选项对应的字符串"input_uvc.so -f 10 -r 320*240"赋给变量optarg,
          												  而strdup()函数用于将变量optarg的值赋予指针input */
            break;

            /* o, output */                   //这一块就是把数据流的出入流和输出流给定义,如果执行时,用户未指定则采用默认配置->开头定义处
        case 4:
        case 5:
            output[global.outcnt++] = strdup(optarg);/*在getopt_long_only函数中,把传入的-o选项对应的字符串"output_uvc.so ......"赋给变量optarg,
          												  而strdup()函数用于将变量optarg的值赋予指针output */
            break;

            /* v, version */
        case 6:
        case 7:
            printf("MJPG Streamer Version: %s\n" \
            "Compilation Date.....: %s\n" \
            "Compilation Time.....: %s\n",
#ifdef SVN_REV
            SVN_REV,
#else
            SOURCE_VERSION,
mjpg_streamer是一个开源的多线程实时流媒体服务器,可用于将应用程序产生的多种形式的视频流(如MJPEG,JPEG以及YUV等)转换为HTTP流的格式,可通过网络从任何支持流媒体的设备或程序进行接收和播放。LCD则是液晶显示屏的简称,它是一种常用的显示设备,可以在各种电子设备中使用。 mjpg_streamer可以与LCD配合使用,通过将LCD设备与mjpg_streamer服务器连接,我们可以将来自摄像头或其他视频源的实时图像流转发到LCD显示屏上,从而实现图像的实时显示。 使用mjpg_streamer连接LCD的具体步骤如下: 1. 配置mjpg_streamer服务器,确保其能够接收并处理来自摄像头或其他视频源的流数据。 2. 将LCD连接到计算机或嵌入式设备,确保其正常工作。 3. 在mjpg_streamer服务器的配置文件中,指定将视频流输出到LCD设备。 4. 启动mjpg_streamer服务器,开始传输视频流到LCD设备。 5. 在LCD设备上,显示传输过来的视频流。可以根据需要进行调整和优化。 通过将mjpg_streamer和LCD结合使用,可以实现在LCD设备上显示来自摄像头或其他视频源的实时图像流。这在监控系统、视讯会议、机器视觉等领域具有广泛应用,为用户提供了方便快捷的图像展示方式。同时,通过调整mjpg_streamer服务器和LCD设备的配置,还可以实现多种不同的显示效果和功能,满足用户的个性化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值