【正点原子阿尔法 IMX6ULL Linux开发板】5、mjpg-streamer搭建网络摄像头视频监控
[复制链接]
一、mjpg-streamer介绍
mjpg-streamer是一款免费基于IP地址的视频流服务器,它的输入插件从摄像头读取视频数据,这个输入插件产生视频数据并将视频数据复制到内存中,它有多个输出插件将这些视频数据经过处理,其中最重要的输出插件是网站服务器插件,它将视频数据传送到用户浏览器中,mjpg-streamer的工作就是将其中的一个输入插件和多个输出插件绑定在一起,所有的工作都是通过它的各个插件完成的。mjpg-streamer各个文件如下:
(1)input_testpicture.so。这是一个图像测试插件,它将预设好的图像编译成一个头文件,可以在没有摄像头的情况下传输图像,从而方便调试程序。
(2)input_uvc.so。此文件调用USB摄像头驱动程序V4L2,从摄像头读取视频数据。
(3)input_control.so。这个文件实现对摄像头转动的控制接口。
(4)output_http.so。这是一个功能齐全的网站服务器,它不仅可以从单一文件夹中处理文件,还可以执行一定的命令,它可以从输入插件中处理一幅图像,也可以将输入插件的视频文件根据现有M-JPEG标准以HTTP视频数据服务流形式输出。
(5)output_file.so。这个插件的功能是将输入插件的JPEG图像存储到特定的文件夹下,它可以用来抓取图像。
mjpg-streamer优点是对RAM和CPU的消耗比较少,可以快速的传输jpeg流。
二、libjpeg交叉编译
有些UVC摄像头只支持输出YUV原始图像,此时mjpg-streamer会将其转码为mjpeg,然后进行传输,此时会对CPU的消耗以及实时流的流畅度有影响,特别是分辨率比较大的时候。
因此mjpg-streamer 依赖 libjpeg, libjpeg下载地址:
http://www.ijg.org/
目前最新版本是v9e。这里下载v9d版本,libjpeg交叉编译命令:
- cd jpeg-9d
- make clean
- ./configure CC=arm-linux-gnueabihf-gcc --host=arm-linux --prefix=/home/alientek/linux/nfs/mjpg_streamer/build_jpeg
- make
- make install
编译成功后得到动态库:
正点原子阿尔法 IMX6ULL Linux内核已经配置好了UVC和USB 驱动,因此无需重新配置编译内核。
三、mjpg-streamer交叉编译
mjpeg-streamer下载
https://sourceforge.net/p/mjpg-streamer/code/HEAD/tree/
目前最新版本为r182,本次测试使用版本r182。
在ubuntu可通过2种命令下载代码:
或者
在编译前需要对源码的mjpg-streamer-code-r182/mjpg-streamer/Makefile做以下修改:
将源码的所有Makefile(包含其子目录)中的编译工具链CC修改为IMX6ULL的编译工具链arm-linux-gnueabihf-gcc。
本次测试只需要 input_uvc.so 和 output_http.so,在主目录中的Makefile里面只选择这两个,其它的去掉。
插件input_uvc依赖jpeg,因此修改plugins/input_uvc/Makefile文件,指定jpeg库头文件路径:CFLAGS += -I/home/alientek/linux/nfs/mjpg_streamer/build_jpeg/include
指定链接jpeg动态库路径:-ljpeg -L/home/alientek/linux/nfs/mjpg_streamer/build_jpeg/lib
input_uvc插件的Makefile修改后如下:
-
-
-
-
-
-
-
-
-
- CC = arm-linux-gnueabihf-gcc
-
- OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
-
- CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I/home/alientek/linux/nfs/mjpg_streamer/build_jpeg/include
-
-
-
-
- ifeq ($(USE_LIBV4L2),true)
- LFLAGS += -lv4l2
- CFLAGS += -DUSE_LIBV4L2
- endif
-
-
- LFLAGS += -ljpeg -L/home/alientek/linux/nfs/mjpg_streamer/build_jpeg/lib
-
- all: input_uvc.so
-
- clean:
- rm -f *.a *.o core *~ *.so *.lo
-
- input_uvc.so: $(OTHER_HEADERS) input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
- $(CC) $(CFLAGS) -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo $(LFLAGS)
-
- v4l2uvc.lo: huffman.h uvc_compat.h v4l2uvc.c v4l2uvc.h
- $(CC) -c $(CFLAGS) -o $@ v4l2uvc.c
-
- jpeg_utils.lo: jpeg_utils.c jpeg_utils.h
- $(CC) -c $(CFLAGS) -o $@ jpeg_utils.c
-
- dynctrl.lo: dynctrl.c dynctrl.h
- $(CC) -c $(CFLAGS) -o $@ dynctrl.c
mjpg-streamer-code-r182/mjpg-streamer/plugins/output_http/Makefile修改后如下:
-
-
- CC = arm-linux-gnueabihf-gcc
-
- OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
-
- CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
-
-
- LFLAGS += -lpthread -ldl
-
- all: output_http.so
-
- clean:
- rm -f *.a *.o core *~ *.so *.lo
-
- output_http.so: $(OTHER_HEADERS) output_http.c httpd.lo
- $(CC) $(CFLAGS) -o $@ output_http.c httpd.lo
-
- httpd.lo: $(OTHER_HEADERS) httpd.h httpd.c
- $(CC) -c $(CFLAGS) -o $@ httpd.c
在mjpg-streamer-code-r182/mjpg-streamer目录生成mjpg-streamer可执行文件和动态库input_uvc.so、output_http.so:
将上面生成的可执行文件和动态库文件、文件夹mjpg-streamer-code-r182/mjpg-streamer/www都复制到test目录:
接下来使用nfs挂载方式进行测试(开发板ip为192.168.2.136、ubuntu虚拟机ip为192.168.2.11、win10主机ip为192.168.2.10,按照正点原子网络搭建章节确保三者能互相ping通)。
在开发板终端执行:
- mount -t nfs -o nolock,nfsvers=3 192.168.2.11:/home/alientek/linux/nfs /mnt
进入test目录
手动指定一下库路径:
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
执行下列命令启动mjpg-streamer:
- ./mjpg_streamer -i "input_uvc.so -d /dev/video2 -r 640x480" -o "output_http.so -w ./www"
如果是输出YUV格式的UVC摄像头,则执行命令:
- ./mjpg_streamer -i "input_uvc.so -y -r 640x480" -o "output_http.so -w ./www
查看图片,在浏览器输入:
http://192.168.2.136:8080/?action=snapshot
查看视频,在浏览器输入:
http://192.168.2.136:8080/?action=stream
使用命令:
- v4l2-ctl --list-framesizes=MJPG -d /dev/video2
查看摄像头支持的分辨率。
按照上述方法是无法正常使用的,r182源码有点小bug,需要修改3个文件:
一是:
mjpg-streamer/plugins/input_uvc/v4l2uvc.h文件第108行增加变量int dd;
二是:
mjpg-streamer/plugins/input_uvc/v4l2uvc.c文件第453行增加代码vd->dd=vd->buf.bytesused;
三是:
mjpg-streamer/plugins/input_uvc/input_uvc.c文件第391行代码if(pcontext->videoIn->buf.bytesused < minimum_size)修改为if ( pcontext->videoIn->dd < minimum_size )
第410行代码pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused)修改为pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->dd)
修改好后重新测试效果:
视频
抓拍
|