最近想弄个USB camera, 测试下视频功能。看到网上推荐使用FFmpeg这个开源工具。
FFmpeg: A complete, cross-platform solution to record, convert and stream audio and video.
官网地址: http://ffmpeg.org/
下载最新的 FFmpeg 4.2.2源码。参考了其他文章,FFmpeg编译还需要以下3个开源库:
1)x264 -- library and application for encoding video streams into the H.264/MPEG-4 AVC compression format
官网地址: http://www.videolan.org/developers/x264.html
2)YASM -- a complete rewrite of the NASM assembler
官网地址:http://yasm.tortall.net/
3)SDL2 -- Simple DirectMedia Layer
官网地址:http://www.libsdl.org/index.php
在编译之前,准备好交叉工具链, 初始化编译工具交叉变量 CROSS_COMPILE
推荐用绝对路径:
export CROSS_COMPILE=/home/golden/gcc/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-
export CC=${CROSS_COMPILE}gcc
也可以 export CROSS_COMPILE=arm-oe-linux-gnueabi- ,但在后续编译过程中,会经常遇到类似的错误:
INSTALL libavdevice/libavdevice.so
STRIP install-libavdevice-shared
/bin/sh: 1: arm-oe-linux-gnueabi-strip: not found
make: *** [ffbuild/library.mak:104: install-libavdevice-shared] Error 127
解决办法就是需要手动用绝对路径代替,
./ffbuild/config.mak~:STRIP=arm-oe-linux-gnueabi-strip
./ffbuild/config.mak:STRIP=/home/golden/gcc/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-strip
源码编译
1) 编译x264
# wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
# tar xvjf x264-master.tar.bz2
# cd x264-master
# ./configure --host=arm-linux --prefix=/usr/local/x264-arm --enable-shared --enable-debug --disable-asm
接下来,打上下面的patch
diff --git a/Makefile~ b/Makefile
index efc863f..2ad60af 100644
--- a/Makefile~
+++ b/Makefile
@@ -243,7 +243,7 @@ lib-shared: $(SONAME)
$(LIBX264): $(GENERATED) .depend $(OBJS) $(OBJASM)
rm -f $(LIBX264)
- $(AR)$@ $(OBJS) $(OBJASM)
+ $(AR) $@ $(OBJS) $(OBJASM)
$(if $(RANLIB), $(RANLIB) $@)
$(SONAME): $(GENERATED) .depend $(OBJS) $(OBJASM) $(OBJSO)
diff --git a/config.mak~ b/config.mak
index f10ce66..5eaa865 100644
--- a/config.mak~
+++ b/config.mak
@@ -6,7 +6,7 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include
SYS_ARCH=ARM
SYS=LINUX
-CC=gcc
+CC?=${CROSS_COMPILE}gcc
CFLAGS=-Wno-maybe-uninitialized -Wshadow -O1 -g -Wall -I. -I$(SRCPATH) -std=gnu99 -D_GNU_SOURCE -fPIC -fno-tree-vectorize -fvisibility=hidden
CFLAGSSO= -DX264_API_EXPORTS
CFLAGSCLI=
@@ -14,13 +14,13 @@ COMPILER=GNU
COMPILER_STYLE=GNU
DEPMM=-MM -g0
DEPMT=-MT
-LD=gcc -o
+LD=${CROSS_COMPILE}gcc -o
LDFLAGS= -lm -lpthread -ldl
LDFLAGSCLI=-ldl
LIBX264=libx264.a
CLI_LIBX264=$(LIBX264)
-AR=gcc-ar rc
-RANLIB=gcc-ranlib
+AR=${CROSS_COMPILE}gcc-ar rc
+RANLIB=${CROSS_COMPILE}gcc-ranlib
STRIP=strip
INSTALL=install
AS=
# make
# make install
2) 编译YASM
# wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
# tar xvzf yasm-1.3.0.tar.gz
# cd yasm-1.3.0
# ./configure --prefix=/usr/local/ --host=arm-linux
# make
# make install
3) 编译SDL2
# wget http://www.libsdl.org/release/SDL2-2.0.12.tar.gz
# tar xvzf SDL2-2.0.12.tar.gz
# cd SDL2-2.0.12
# ./configure --prefix=/usr/local/ --host=arm-linux --target=arm-linux
# make
# make install
4) 最后编译FFmpeg
# wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
# tar xvjf ffmpeg-4.2.2.tar.bz2
# cd ffmpeg-4.2.2
# ./configure --cross-prefix=$CROSS_COMPILE --enable-cross-compile --target-os=linux --cc="$CC" --arch=arm --prefix=/usr/local/arm_ffmpeg --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-swscale --enable-pthreads --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-yasm --enable-ffmpeg --enable-ffplay --enable-sdl2
关于这一步,如果你不加上最后“ --enable-sdl2” ,那么编译出来后, 只有ffmpeg ffprobe, 是没有ffplay, 之前网上其他文章说修改config.mak文件的CONFIG_FFPLAY宏, 在4.2.2版本上,行不通,首先文件跑到 ffbuild/config.mak中了,另外还有config.h也得改,最终一点是ffplay依赖sdl2库:
configure:ffplay_deps="avcodec avformat swscale swresample sdl2"
这一步,报过一个错误: ERROR: sdl2 requested but not found
这是因为configure文件中SDL2_CONFIG定义无效,
if enabled sdl2; then
SDL2_CONFIG="${cross_prefix}sdl2-config"
test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h SDL_PollEvent
if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then
我的做法就是添加一个链接:
# which sdl2-config
/usr/local/bin/sdl2-config
# sudo ln -s sdl2-config /usr/local/bin/arm-oe-linux-gnueabi-sdl2-confi
# make
# make install
最后编译出来的结果,就在 /usr/local/arm_ffmpeg/。
![](https://img-blog.csdnimg.cn/20200316145851926.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dvbGRlbl9DaGVu,size_16,color_FFFFFF,t_70)
这里提一点, ./configure配置这一步,千万不要加上 --disable-stripping
否则编译出来的大小和内存要求,超乎你的想象,一张对比图
![](https://img-blog.csdnimg.cn/2020031615043725.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dvbGRlbl9DaGVu,size_16,color_FFFFFF,t_70)
将bin 和lib目录下的内容分别复制到板子中的/usr/bin 、/usr/lib中,除此之外,不要忘了也要把SDL2.so也复制到/usr/lib,
如果发现so过大,也可以用strip命令裁剪掉冗余。
![](https://img-blog.csdnimg.cn/20200317164043154.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dvbGRlbl9DaGVu,size_16,color_FFFFFF,t_70)
这样就可以测试ffmpeg了
# ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 /data/test.avi 录制视频
# ffmpeg -i /dev/video0 -r 1 -f image2 image-%3d.jpg 截图,以1PFS的速度保存成JPEG图片 imag-001.jpg image-002....
# ffplay -i /dev/video0 实时视频
# ffplay -i /data/test.avi 播放视频
参考文章: https://mp.csdn.net/console/editor/html/104897666
FFmpeg/FFplay使用: https://blog.csdn.net/weixin_38513602/article/details/85165023
性能测试
root@mdm9607:/data# ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 /data/test.
avi
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.4.0 (GCC)
configuration: --cross-prefix=arm-oe-linux-gnueabi- --enable-cross-compile --t
arget-os=linux --cc='arm-oe-linux-gnueabi-gcc -march=armv7-a -marm -mfpu=neon -m
float-abi=hard' --arch=arm --prefix=/usr/local/arm_ffmpeg --enable-shared --disa
ble-static --enable-gpl --enable-nonfree --enable-swscale --enable-pthreads --di
sable-armv5te --disable-armv6 --disable-armv6t2 --disable-yasm --enable-sdl2 --d
isable-lzma
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 6541.122738, bitrate: 147456 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 147456 k
b/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
File '/data/test.avi' already exists. Overwrite ? [y/N] y
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
Output #0, avi, to '/data/test.avi':
Metadata:
ISFT : Lavf58.29.100
Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 640x480, q=2-31, 200
kb/s, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc58.54.100 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame= 10 fps=0.0 q=2.3 size= 6kB time=00:00:02.43 bitrate= 18.7kbits/s
frame= 21 fps= 19 q=2.7 size= 6kB time=00:00:02.90 bitrate= 15.7kbits/s
frame= 35 fps= 21 q=2.7 size= 6kB time=00:00:03.43 bitrate= 13.2kbits/s
frame= 45 fps= 21 q=2.2 size= 6kB time=00:00:03.83 bitrate= 11.8kbits/s
frame= 60 fps= 22 q=2.7 size= 6kB time=00:00:04.43 bitrate= 10.2kbits/s
frame= 70 fps= 22 q=2.6 size= 6kB time=00:00:04.83 bitrate= 9.4kbits/s
frame= 85 fps= 23 q=2.5 size= 6kB time=00:00:05.43 bitrate= 8.4kbits/s
frame= 95 fps= 22 q=2.5 size= 6kB time=00:00:05.83 bitrate= 7.8kbits/s
frame= 107 fps= 22 q=2.6 size= 6kB time=00:00:06.33 bitrate= 7.2kbits/s
frame= 117 fps= 22 q=2.7 size= 6kB time=00:00:06.73 bitrate= 6.7kbits/s
frame= 133 fps= 23 q=2.4 size= 6kB time=00:00:07.36 bitrate= 6.2kbits/s
frame= 145 fps= 23 q=2.1 size= 6kB time=00:00:07.83 bitrate= 5.8kbits/s
frame= 160 fps= 23 q=2.7 size= 6kB time=00:00:08.46 bitrate= 5.4kbits/s
frame= 172 fps= 23 q=2.9 size= 6kB time=00:00:08.93 bitrate= 5.1kbits/s
frame= 186 fps= 24 q=2.5 size= 6kB time=00:00:09.50 bitrate= 4.8kbits/s
frame= 200 fps= 24 q=2.7 size= 262kB time=00:00:10.03 bitrate= 213.5kbits/s
frame= 213 fps= 24 q=2.8 size= 262kB time=00:00:10.56 bitrate= 202.8kbits/s
frame= 229 fps= 24 q=2.1 size= 262kB time=00:00:11.20 bitrate= 191.3kbits/s
frame= 239 fps= 24 q=2.5 size= 262kB time=00:00:11.60 bitrate= 184.7kbits/s
frame= 254 fps= 24 q=2.7 size= 262kB time=00:00:12.20 bitrate= 175.6kbits/s
frame= 265 fps= 24 q=1.9 size= 262kB time=00:00:12.63 bitrate= 169.6kbits/s
frame= 280 fps= 24 q=2.8 size= 262kB time=00:00:13.23 bitrate= 161.9kbits/s
frame= 290 fps= 24 q=2.6 size= 262kB time=00:00:13.66 bitrate= 156.8kbits/s
frame= 304 fps= 24 q=3.2 size= 262kB time=00:00:14.20 bitrate= 150.9kbits/s
frame= 315 fps= 24 q=3.2 size= 262kB time=00:00:14.63 bitrate= 146.4kbits/s
frame= 328 fps= 24 q=2.9 size= 262kB time=00:00:15.16 bitrate= 141.3kbits/s
frame= 341 fps= 24 q=3.4 size= 262kB time=00:00:15.70 bitrate= 136.5kbits/s
frame= 352 fps= 24 q=3.2 size= 262kB time=00:00:16.13 bitrate= 132.8kbits/s
frame= 366 fps= 24 q=3.0 size= 262kB time=00:00:16.70 bitrate= 128.3kbits/s
frame= 379 fps= 24 q=2.8 size= 262kB time=00:00:17.20 bitrate= 124.6kbits/s
frame= 395 fps= 24 q=2.7 size= 262kB time=00:00:17.86 bitrate= 119.9kbits/s
frame= 407 fps= 24 q=2.9 size= 518kB time=00:00:18.33 bitrate= 231.3kbits/s
frame= 423 fps= 24 q=3.3 size= 518kB time=00:00:18.96 bitrate= 223.5kbits/s
frame= 436 fps= 24 q=3.1 size= 518kB time=00:00:19.50 bitrate= 217.4kbits/s
frame= 452 fps= 24 q=2.7 size= 518kB time=00:00:20.13 bitrate= 210.6kbits/s
frame= 464 fps= 24 q=2.6 size= 518kB time=00:00:20.60 bitrate= 205.8kbits/s
frame= 480 fps= 25 q=2.8 size= 518kB time=00:00:21.26 bitrate= 199.4kbits/s
frame= 491 fps= 24 q=2.9 size= 518kB time=00:00:21.70 bitrate= 195.4kbits/s
frame= 506 fps= 25 q=3.1 size= 518kB time=00:00:22.30 bitrate= 190.1kbits/s
frame= 517 fps= 24 q=2.5 size= 518kB time=00:00:22.73 bitrate= 186.5kbits/s
speed=1.08x
内存消耗: 43.4MB
ROM空间: 16.9MB (stripped)
CPU Loading: cat /proc/loadavg(armv7/1.2GHz单核)
1.35 1.54 1.52 1/394 10703 运行前
1.58 1.59 1.54 2/394 11321 运行2分钟后
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)