2452|6

1237

帖子

66

TA的资源

纯净的硅(中级)

楼主
 

【正点原子阿尔法 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种命令下载代码:

svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code

或者

svn checkout https://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code

在编译前需要对源码的mjpg-streamer-code-r182/mjpg-streamer/Makefile做以下修改:
将源码的所有Makefile(包含其子目录)中的编译工具链CC修改为IMX6ULL的编译工具链arm-linux-gnueabihf-gcc。

###############################################################
#
# Purpose: Makefile for "M-JPEG Streamer"
# Author.: Tom Stoeveken (TST)
# Version: 0.4
# License: GPL
#
###############################################################

# specifies where to install the binaries after compilation
# to use another directory you can specify it with:
# $ sudo make DESTDIR=/some/path install
DESTDIR = /usr/local

# set the compiler to use
CC = arm-linux-gnueabihf-gcc

SVNDEV := -D'SVN_REV="$(shell svnversion -c .)"'
CFLAGS += $(SVNDEV)

# general compile flags, enable all warnings to make compile more verbose
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall 
# CFLAGS += -g 
#CFLAGS +=  -DDEBUG

# we are using the libraries "libpthread" and "libdl"
# libpthread is used to run several tasks (virtually) in parallel
# libdl is used to load the plugins (shared objects) at runtime
LFLAGS += -lpthread -ldl

# define the name of the program
APP_BINARY = mjpg_streamer

# define the names and targets of the plugins
PLUGINS = input_uvc.so
#PLUGINS += output_file.so
#PLUGINS += output_udp.so
PLUGINS += output_http.so
#PLUGINS += input_testpicture.so
#PLUGINS += output_autofocus.so
#PLUGINS += input_gspcav1.so
#PLUGINS += input_file.so
# PLUGINS += output_rtsp.so
# PLUGINS += output_ptp2.so # commented out because it depends on libgphoto
# PLUGINS += input_control.so # commented out because the output_http does it's job
# PLUGINS += input_http.so 
# PLUGINS += output_viewer.so # commented out because it depends on SDL

# define the names of object files
OBJECTS=mjpg_streamer.o utils.o

# this is the first target, thus it will be used implictely if no other target
# was given. It defines that it is dependent on the application target and
# the plugins
all: application plugins

application: $(APP_BINARY)

plugins: $(PLUGINS)

$(APP_BINARY): mjpg_streamer.c mjpg_streamer.h mjpg_streamer.o utils.c utils.h utils.o
	$(CC) $(CFLAGS) $(OBJECTS) $(LFLAGS) -o $(APP_BINARY)
	chmod 755 $(APP_BINARY)

output_autofocus.so: mjpg_streamer.h utils.h
	make -C plugins/output_autofocus all
	cp plugins/output_autofocus/output_autofocus.so .

input_testpicture.so: mjpg_streamer.h utils.h
	make -C plugins/input_testpicture all
	cp plugins/input_testpicture/input_testpicture.so .


ifeq ($(USE_LIBV4L2),true)
input_uvc.so: mjpg_streamer.h utils.h
	make -C plugins/input_uvc USE_LIBV4L2=true all
	cp plugins/input_uvc/input_uvc.so .
else
input_uvc.so: mjpg_streamer.h utils.h
	make -C plugins/input_uvc all
	cp plugins/input_uvc/input_uvc.so .
endif

input_control.so: mjpg_streamer.h utils.h
	make -C plugins/input_control all
	cp plugins/input_control/input_control.so .

output_file.so: mjpg_streamer.h utils.h
	make -C plugins/output_file all
	cp plugins/output_file/output_file.so .

ifeq ($(WXP_COMPAT),true)
output_http.so: mjpg_streamer.h utils.h
	make -C plugins/output_http -DWXP_COMPAT all
	cp plugins/output_http/output_http.so .
else
output_http.so: mjpg_streamer.h utils.h
	make -C plugins/output_http all
	cp plugins/output_http/output_http.so .
endif

output_udp.so: mjpg_streamer.h utils.h
	make -C plugins/output_udp all
	cp plugins/output_udp/output_udp.so .

input_gspcav1.so: mjpg_streamer.h utils.h
	make -C plugins/input_gspcav1 all
	cp plugins/input_gspcav1/input_gspcav1.so .

input_file.so: mjpg_streamer.h utils.h
	make -C plugins/input_file all
	cp plugins/input_file/input_file.so .

output_rtsp.so: mjpg_streamer.h utils.h
	make -C plugins/output_rtsp all
	cp plugins/output_rtsp/output_rtsp.so .
	
output_ptp2.so: mjpg_streamer.h utils.h
	make -C plugins/input_ptp2 all
	cp plugins/input_ptp2/input_ptp2.so .	

#input_http.so: mjpg_streamer.h utils.h
#	make -C plugins/input_http all
#	cp plugins/input_http/input_http.so .

# The viewer plugin requires the SDL library for compilation
# This is very uncommmon on embedded devices, so it is commented out and will
# not be build automatically. If you compile for PC, install libsdl and then
# execute the following command:
# make output_viewer.so
output_viewer.so: mjpg_streamer.h utils.h
	make -C plugins/output_viewer all
	cp plugins/output_viewer/output_viewer.so .

# cleanup
clean:
	make -C plugins/input_uvc $@
	make -C plugins/input_testpicture $@
	make -C plugins/output_file $@
	make -C plugins/output_http $@
	make -C plugins/output_udp $@
	make -C plugins/output_autofocus $@
	make -C plugins/input_gspcav1 $@
	make -C plugins/output_viewer $@
	make -C plugins/input_control $@
	make -C plugins/output_rtsp $@
#	make -C plugins/input_http $@
	rm -f *.a *.o $(APP_BINARY) core *~ *.so *.lo

# useful to make a backup "make tgz"
tgz: clean
	mkdir -p backups
	tar czvf ./backups/mjpg_streamer_`date +"%Y_%m_%d_%H.%M.%S"`.tgz --exclude backups --exclude .svn *

# install MJPG-streamer and example webpages
install: all
	install --mode=755 $(APP_BINARY) $(DESTDIR)/bin
	install --mode=644 $(PLUGINS) $(DESTDIR)/lib/
	install --mode=755 -d $(DESTDIR)/www
	install --mode=644 -D www/* $(DESTDIR)/www

# remove the files installed above
uninstall:
	rm -f $(DESTDIR)/bin/$(APP_BINARY)
	for plug in $(PLUGINS); do \
	  rm -f $(DESTDIR)/lib/$$plug; \
	done;

本次测试只需要 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修改后如下:

###############################################################
#
# Purpose: Makefile for "M-JPEG Streamer"
# Author.: Tom Stoeveken (TST)
# Version: 0.3
# License: GPL
#
###############################################################

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

#CFLAGS += -g
#CFLAGS += -DDEBUG

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修改后如下:

###############################################################
#
# Purpose: Makefile for "M-JPEG Streamer"
# Author.: Tom Stoeveken (TST)
# Version: 0.3
# License: GPL
#
###############################################################

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
#CFLAGS +=  -g
#CFLAGS += -DDEBUG
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)
修改好后重新测试效果:

视频

抓拍

 

 

最新回复

我明儿问下技术哈   详情 回复 发表于 2023-5-23 23:02
点赞 关注

回复
举报

1万

帖子

2854

TA的资源

管理员

沙发
 

镜像吗?

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

镜像啥意思  详情 回复 发表于 2023-5-22 19:15
 
个人签名

玩板看这里:

https://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!

 

回复

1237

帖子

66

TA的资源

纯净的硅(中级)

板凳
 
okhxyyo 发表于 2023-5-22 08:57 镜像吗?

镜像啥意思


点评

你晒上来的两个图看着方向是反的呀,所以我问是不是摄像头出来视频是镜像的之类的  详情 回复 发表于 2023-5-23 11:05
 
 
 

回复

1万

帖子

2854

TA的资源

管理员

4
 

你晒上来的两个图看着方向是反的呀,所以我问是不是摄像头出来视频是镜像的之类的

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

gif不知为何不显示动图效果?文件大小有限制?  详情 回复 发表于 2023-5-23 22:10
是滴是滴  详情 回复 发表于 2023-5-23 22:09
 
个人签名

玩板看这里:

https://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!

 
 

回复

1237

帖子

66

TA的资源

纯净的硅(中级)

5
 
okhxyyo 发表于 2023-5-23 11:05 你晒上来的两个图看着方向是反的呀,所以我问是不是摄像头出来视频是镜像的之类的

是滴是滴


 
 
 

回复

1237

帖子

66

TA的资源

纯净的硅(中级)

6
 
okhxyyo 发表于 2023-5-23 11:05 你晒上来的两个图看着方向是反的呀,所以我问是不是摄像头出来视频是镜像的之类的

gif不知为何不显示动图效果?文件大小有限制?


点评

我明儿问下技术哈  详情 回复 发表于 2023-5-23 23:02
 
 
 

回复

1万

帖子

2854

TA的资源

管理员

7
 
dql2016 发表于 2023-5-23 22:10 gif不知为何不显示动图效果?文件大小有限制?

我明儿问下技术哈

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

玩板看这里:

https://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表