LV11-03-MJPGstreamer-01-移植过程
本文主要是MJPG-streamer移植的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
Linux开发板 | 华清远见 底板: FS4412_DEV_V5 核心板: FS4412 V2 |
u-boot | 2013.01 |
linux内核 | linuz-3.14 |
点击查看本文参考资料
参考方向 | 参考原文 |
华清远见课程 | 华清远见课程 |
MJPG-streamer | MJPG-streamer download | SourceForge.net |
jpeg库 | Independent JPEG Group (ijg.org) |
点击查看相关文件下载
文件 | 下载链接 |
--- | --- |
一、mjpg-streamer简介
1. MJPG
MJPG 是 MJPEG 的缩写,但是 MJPEG 还可以表示一种文件格式扩展名。MJPEG 全名为 “Motion Joint Photographic Experts Group”,是一种视频编码格式,Motion JPEG 技术常用与闭合电路的电视摄像机的模拟视频信号“翻译”成视频流,并存储在硬盘上。
典型的应用如数字视频记录器等。 MJPEG 不像 MPEG,不使用帧间编码,因此用一个非线性编辑器就很容易编辑。
MJPEG 的压缩算法与 MPEG 一脉相承,功能很强大,能发送高质图片,生成完全动画视频等。但相应地, MJPEG 对带宽的要求也很高,相当于 T-1, MJPEG 信息是存储在数字媒体中的庞然大物,需要大量的存储空间以满足如今多数用户的需求。因此从另一个角度说,在某些条件下, MJPEG 也许是效率最低的编码/解码器之一。
MJPEG 是 24-bit 的 “true-color” 影像标准, MJPEG 的工作是将 RGB 格式的影像转换成 YCrCB 格式,目的是为了减少档案大小,一般约可减少 1/3 ~ 1/2 左右。
2. 摄像头
免驱动摄像头,是一种遵循视频设备类(USB Video Class,简称 UVC )标准协议的摄像头产品。将符合标准的摄像头连接到符合标准的操作系统,系统就会自动为其安装驱动并进行设置,使摄像头实现真正意义上的即插即用。
UVC 是一种硬件的框架结构,只有当其是通过一种标准的设计使其实现了免驱;而 V4L2 是一种驱动程序,其是实现系统与 UVC 设备等的通信。
3. mjpg-streamer视频流服务器
mjpg-streamer简单来说就是一个jpeg文件的传输流服务器,它最常用的用途就是采集摄像头的数据,然后启动 http server,用户就可以通过浏览器查看图像数据了。
UVC摄像头 + 驱动 + JPEG图库 + mjpeg-streamer + HTML 就完成了对用户远程提供视屏展示的服务。首先底层通过摄像头采集图片,通过驱动将数据流存储到JPEG图库,最终通过html交给用户的浏览器来解析,而mjpeg-streamer用来实现对这一流程的的控制。构成mjpeg-streamer视频流服务器。
当所有的工作完成后,启动mjpg-streamer视频流服务器,然后在打开这个网页:
1 | http://<开发板IP>:8080/?action=stream |
就可以看到我们采集到的视频流了,后边一直完成的测试会有演示。
二、文件准备
1. jpeg 库
1.1 源码获取途径
关于 jpeg 库的官方源码我们可以从这里获取:Directory Listing of /files (ijg.org)
1.2 获取源码文件
我下载的是 jpegsrc.v8b.tar.gz 这个压缩包并将其存放于 ubuntu 下的共享文件夹下,路径为:
1 | /mnt/hgfs/Sharedfiles/jpegsrc.v8b.tar.gz |
1.3 拷贝解压
然后我们可以将这个源码文件拷贝解压到 ubuntu 中,方便后边编译,我们可以在终端执行以下命令:
1 | cp /mnt/hgfs/Sharedfiles/jpegsrc.v8b.tar.gz ~/5linux/ # 拷贝压缩包 |
然后我们可以得到下边这些文件(通过 ls 命令查看):
还有很多文件,图中仅显示了一部分。
2. mjpg-stream
2.1 源码获取途径
关于 mjpg-stream 的官方源码我们可以从这里获取:MJPG-streamer-Code-r182 (sourceforge.net)
2.2 获取源码文件
我下载的是 182 版本的压缩包,并将其存放于 ubuntu 下的共享文件夹下,路径为:
1 | /mnt/hgfs/Sharedfiles/mjpg-streamer-code-r182.zip |
1.3 拷贝解压
然后我们可以将这个源码文件拷贝解压到 ubuntu 中,方便后边编译,我们可以在终端执行以下命令:
1 | cp /mnt/hgfs/Sharedfiles/mjpg-streamer-code-r182.zip ~/5linux/ # 拷贝压缩包 |
然后我们可以得到下边这些文件(通过 ls 命令查看):
点击查看部分文件说明
目录名 | 说明 |
---|---|
mjpg-streamer | 提供了执行程序和各个输入输出设备组件 |
uvc-streamer | 提供了 uvc-streamer的可执行目录 |
mjpeg-client | 分别有 linux和windows 的客户端 |
三、 USB 支持
我们后边要使用 USB 摄像头,就需要先添加 USB 驱动的支持,之前的时候我们已经移植了 USB 驱动,可以看这篇笔记:《LV10-06-USB驱动移植》,但是这里还需要一些其他的支持。
1. 已有配置
我们还是先来看一下之前做驱动移植的时候已经配置过的选项:
1.1 USB support
1 | Device Drivers ---> |
1.2 SCSI device support
1 | Device Drivers ---> |
2. 新增配置
2.1 Multimedia support
我们首先进入 Multimedia support 选项中:
然后开始进行自选项的配置:
1 | Device Drivers ---> |
3. 编译内核
配置完成后我们重新编译内核:
1 | cd ~/5linux/linux-3.14/ |
最后将重新生成的 uImage 拷贝到 tftp 服务器中:
1 | cp ~/5linux/linux-3.14/arch/arm/boot/uImage ~/3tftp/fs4412/ |
4. 重启测试
我们重启开发板,让其重新加载内核,然后我们插上 USB 摄像头,若有以下信息输出,说明摄像头已被开发板识别:
1 | [ 293.180000] usb 1-3.1: new high-speed USB device number 5 using exynos-ehci |
摄像头的设备节点一般是 video 开头,我们查看一下 /dev/ 下是否有这样的设备:
1 | ls /dev/video* |
四、jpeg 库移植
我们移植 mjpg-stream 的时候需要用到 jpeg 的库,所以需要先移植 jpeg 的库。我们首先进入刚才解压的目录:
1 | cd ~/5linux/jpeg-8b/ |
1. 创建一个目录
我们首先创建一个目录用于存放最终生成的文件:
1 | mkdir jpegarm |
应该是创建在哪都可以,我比较懒,直接创建到解压的目录下了,所以这个新建的目录路径为(后边有用):
1 | /home/hk/5linux/jpeg-8b/jpegarm |
老师给的文档中说这个目录建议自己创建一个在 mjpeg-streamer (后边移植它的时候就会看到这个目录了)的上一级目录下。
2. 配置源码
我们在 jpeg 源码目录下执行以下命令:
1 | ./configure --prefix=/home/hk/5linux/jpeg-8b/jpegarm --host=arm-none-linux-gnueabi |
- –prefix 表示最终生成的库和头文件等存放的目录,自己指定一个存在的路径就可以,后面编译 mjpeg-streamer 的时候会用到,此处必须使用绝对路径。
- –host=arm-none-linux-gnueabi 中 –host 表示生成的库的运行平台,注意是两个 - ,末尾不能加 - 。
【注意】 ./configure 之后为一行命令。
3. 编译源码
我们在 jpeg 源码目录下执行:
1 | cd ~/5linux/jpeg-8b/ |
这样便会完成 jpeg 源码的编译了。
4. 安装到创建的目录
我们在 jpeg 源码目录下执行:
1 | cd ~/5linux/jpeg-8b/ |
然后我们查看一下我们刚才创建的目录(使用 ls 命令),将会生成以下文件:
1 | hk@vm:~/5linux/jpeg-8b$ ls jpegarm |
5. 拷贝库文件到系统
这里我们需要把生成的 jpegarm/lib 目录下的所有文件拷贝到根文件系统的 /lib 目录下:
1 | sudo cp -v ~/5linux/jpeg-8b/jpegarm/lib/* ~/4nfs/rootfs/lib/ |
五、mjpg-streamer 移植
前边我们已经解压好了文件,我们可以进入解压后的目录:
1 | cd ~/5linux/mjpg-streamer-code-r182/ |
1. 源码修改
这里我们主要是修改 Makefile 文件,我们进入 mjpg-streamer 目录,并打开 plugins/input_uvc/Makfile 文件:
1 | cd ~/5linux/mjpg-streamer-code-r182/mjpg-streamer |
(1)我们找到如下语句:
1 | CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC |
将其修改为:
1 | CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I /home/hk/5linux/jpeg-8b/jpegarm/include |
其实就是添加了 -I 参数,后边的路径记得换成自己上一步在 jpeg 库移植部分创建的那个目录中的 include 目录。
(2)我们找到如下语句:
1 | input_uvc.so: $(OTHER_HEADERS) input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo |
将其修改为:
1 | input_uvc.so: $(OTHER_HEADERS) input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo |
其实就是添加了 -L 参数,后边的路径记得换成自己上一步在 jpeg 库移植部分创建的那个目录中的 lib 目录。
2. 编译源码
然后我们到 mjpg-streamer 目录,编译源码:
1 | cd ~/5linux/mjpg-streamer-code-r182/mjpg-streamer |
点击查看可能出现的问题
我们编译的时候可能会报以下问题:
1 | make: svnversion: Command not found |
我们执行以下命令安装 subversion 即可:
1 | sudo apt-get update # 更新软件源 |
编译完成后会生成一些库和可执行文件:
1 | hk@vm:~/5linux/mjpg-streamer-code-r182/mjpg-streamer$ ls *.so |
文件名 | 说明 |
---|---|
input_testpicture.so | 这是一个图像测试插件,它将预设好的图像编译成一个头文件,可以在没有摄像头的情况下传输图像,从而方便调试程序。 |
input_uvc.so | 此文件调用USB摄像头驱动程序V4L2,从摄像头读取视频数据。 |
output_http.so | 这是一个功能齐全的网站服务器,它不仅可以从单一文件夹中处理文件,还可以执行一定的命令,它可以从输入插件中处理一幅图像,也可以将输入插件的视频文件根据现有M-JPEG标准以HTTP视频数据服务流形式输出。 |
output_file.so | 这个插件的功能是将输入插件的JPEG图像存储到特定的文件夹下,它可以用来抓取图像。 |
3. 修改 start.sh
mjpg-stream 支持 JPEG 和 YUV 两种格式的输出,默认输出格式为 JPEG ,而后边经过实验证明我使用的这款摄像头是 YUV 输出的,所以就需要修改 start.sh 啦(不修改的话可能就是可以正常启动摄像头,但是没有视频输出),我们打开 start.sh 文件:
1 | vim /home/hk/5linux/mjpg-streamer-code-r182/mjpg-streamer/start.sh |
然后找到如下语句:
1 | ./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www" |
我们修改为以下内容,就可以指定输出格式为 YUV 啦:
1 | ./mjpg_streamer -i "./input_uvc.so -y" -o "./output_http.so -w ./www" |
【注意】这里需要我们提前确认好摄像头的图像输出格式。
4. 安装到开发板
- 创建相关目录
我们在开发板的根文件系统创建文件夹用于存放 mjpg_streamer 所需要的文件:
1 | sudo mkdir /home/hk/4nfs/rootfs/mjpg-streamer |
- 拷贝文件
接下来向根文件系统中的 mjpg-streamer 目录中添加文件:
1 | cd /home/hk/5linux/mjpg-streamer-code-r182/mjpg-streamer/ |
5. 启动测试
我们来到开发板根文件系统的 mjpg-streamer 目录,执行以下命令:
1 | cd /mjpg-streamer/ |
这样便可以启动 mjpg-streamer 了,若是启动不报错,启动正常的话可能会出现下边的提示信息:
点击查看详情
1 | MJPG-streamer [1410]: starting application |
上边的那些 error 可以忽略掉,并不影响我们采集图像。我们打开一个网页,在地址栏输入以下内容,便可以看到图像啦:
1 | http://<开发板IP>:8080/?action=stream |
若是一切正常的话,我们将会看到如下信息:
一般来说 mjpg-streamer 默认使用的是 8080 端口。但是似乎并不会这么顺利的看到图像,可能会出现各种问题,出现的问题及解决方法笔记的第五章中。
六、问题解决
1. 问题一
MJPEG 格式错误的话可能会报以下问题:
1 | ERROR opening V4L interface: No such file or directory |
【解决方法】
一般来讲出现这个问题应该都是没有这个设备节点的,插上 USB 摄像头,查看设备节点,确认是否成功创建了设备节点
1 | ls /dev/video0 |
没有设备节点的话说明我们的 USB 驱动很可能移植的有问题,这个时候我们需要重新看一下 USB 支持这一部分相关的笔记,看一下是不是有哪里忘记配置了,然后重新编译内核,重启开发板即可。
- 《LV13-03-mjpg-stream移植——二、USB支持》
- 《LV10-06-USB驱动移植》
2. 问题二
视频流格式错误可能会报以下问题:
1 | cannot be displayed because it contains errors |
【解决方法】
修改 start.sh 文件,加参数 -y ,然后运行 start.sh
1 | ./mjpg_streamer -i “./input_uvc.so -y” -o “./output_http.so -w ./www” |
3. 问题三
缺少相关库的支持,可能会报下边的问题:
1 | MJPG-streamer [1308]: starting application |
【解决方法】
重新拷贝相关库:
1 | sudo cp -v ~/5linux/jpeg-8b/jpegarm/lib/* ~/4nfs/rootfs/lib/ |
需要注意的是,要保证我们拷贝的库是 arm 格式的,我们可以用 file 命令确认,如
1 | file libjpeg.so.8 |
4. 问题四
1 | Init v4L2 failed !! exit fatal |
市面上大部分摄像头都是支持 YUV 的,而不是 JPEG 的,这个问题一般会出现在 ./start.sh 过程中。
【解决方法】
由于 mjpg-stream 支持 JPEG 和 YUV 两种格式,所以只需修改 start.sh ,在输入中加入 - y :
1 | ./mjpg_streamer -i “./input_uvc.so -y” -o “./output_http.so -w ./www” |