远程视频监控之应用篇(mjpg-streamer)

转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38515311


       这篇文章将主要结合源码介绍mjpg-streamer使小伙伴们了解视频监控的实现。

一.移植

tar xvf mjpg-streamer-r63.tar.gz
cd mjpg-streamer-r63

修改所有的Makefile 
--(1) 将 CC=gcc 修改为 CC=arm-linux-gcc 
--(2) 修改plugins/input_uvc/Makfile 
a. 将 
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC 
改为 
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
注意: 
-I /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include   //  是编译libjpeg 生成的文件
 
b. 将 
input_uvc.so: $(OTHER_HEADERS) input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo 
                $(CC) $(CFLAGS) -ljpeg -o $@ input_uvc.c v4l2uvc.lo  
jpeg_utils.lo dynctrl.lo 
改为 
input_uvc.so: $(OTHER_HEADERS) input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
        $(CC) $(CFLAGS) -ljpeg -L /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
                                
make
cp mjpg_streamer 靠别到开发板的/bin目录
cp *so* 拷贝到开发板的/lib

二.软件结构

        软件MJPG-streamer采用模块化的设计方法,以功能块为单位进行描述,这些功能块被称为plug-in(组件)。软件中定义好了各组件的输入、输出,以及组件之间的衔接关系。用户可自行根据对功能的需求,选择需要的模块。这种模块化的程序设计简化了代码的编写、调试、维护,程序员只需要遵守设计的规范,就可以轻松地改写软件,或者编写新的模块以增强软件的功能。


input_uvc                  <-----------------------                                       ------------------------>         output_autofocus

input_file                   <--------------------          MJPG-streamer           -------------------->          output_file

input_testpicture       <--------------------                                                

input_gspcav            <-----------------------                                       ------------------------>          output_http

我们选择的组件是input_uvc (输入USB摄像头数据)和output_http(输出网页)output_file(输出图片)


三.初始化

              从mjpg_streamer.c文件开始分析

        1.输入初始化(input_init();)

               global.in.init(&global.in.param)             //打开input_init()函数

                        input_init()                              //input_uvc.c

                              1.识别参数

                              2.调用init_videoIn()          //设置结构体,调用init_v4l2,分配缓冲区(存放摄像头数据)

                                      init_v4l2()                 //根据设置的参数,做相应的操作,这里是真正调用驱动的地方

                         

        2.输出初始化(output_init();)

               global.out[i].init(&global.out[i].param)                         //调用output_run();

                       output_init()                                                    //解析参数,相应变量赋值   


四.运行

             从mjpg_streamer.c文件开始分析

        1.输入运行(input_run();)

              global.in.run();                                    //调用input_run();

                     input_run()                                       

                           pthread_create(&cam, 0, cam_thread, NULL);   //创建线程

                                void *cam_thread( void *arg ) 

                                      uvcGrab(videoIn)                                //获得一帧数据

                                       if (videoIn->formatIn == V4L2_PIX_FMT_YUYV) //如果YUV则压缩,否则直接拷贝buffer中


        2.输出运行(output_run();)

              global.out[i].run(global.out[i].param.id);        //调用output_run();

                     output_run(int id)

                            pthread_create(&(servers[id].threadID), NULL, server_thread, &(servers[id]));   //创建线程

                                 void *server_thread( void *arg )

                                       pthread_create(&client, NULL, &client_thread, pcfd)

                                             void *client_thread( void *arg )                     //客户端连接服务

                                                  _readline(lcfd.fd, &iobuf, buffer, sizeof(buffer)-1, 5)

                                                        _read(fd, iobuf, &c, 1, timeout)

                                                             read(fd, &iobuf->buffer, IO_BUFFER))    //读取数据   

                                                  send_stream(lcfd.fd);                                          //发送流

                                                       pthread_cond_wait(&pglobal->db_update, &pglobal->db);  //等待数据更新

                                                       memcpy(frame, pglobal->buf, frame_size);                         //从buf中取出数据

                                                       write(fd, frame, frame_size)                                                 //发出数据                               


                                 

五.命令参数

     这个是我设置的参数:输入UVC,网页输出,图片输出(更详细的设置,建议去看源码)

         mjpg_streamer -i "input_uvc.so -f 10 -r 320*240 -y" -o "output_http.so -c "ruoyun:liufeng" -w www -p 8888" -o "output_file.so -d 1000 -f /mnt "  

      -i 输入

       "input_uvc.so -f 10 -r 320*240 -y"

       input_uvc.so:UVC输入组件

     -f  10             :表示10帧

     -r 320*240     :分辨率

     -y                   :YUV格式输入(有卡顿),不加表示MJPG输入(需要摄像头支持)


      -o输出

          "output_http.so -c "ruoyun:liufeng" -w www -p 8888" 

          output_http.so          网页输出组件

          -c "ruoyun:liufeng"       :用户名:ruoyun        密码:liufeng

          -w www                                  : 网页输出

         -p 8888                                   :端口   8888


         "output_file.so -d 1000 -f /mnt "   

          output_file.so                  :图片输出组件

          -d 1000                                   : 时间1S

          -f /mnt                                       :输出图片放在哪,我是开机直接把/mnu挂载到本地文件夹了

原文地址:https://www.cnblogs.com/alan666/p/8312297.html