EDA365电子论坛网
标题: 用全志A40i开发板玩转FFmpeg [打印本页]
作者: 罗罗诺亚 时间: 2022-12-17 09:25
标题: 用全志A40i开发板玩转FFmpeg
1. FFmpeg的安装
FFmpeg是用来记录、转换数字音频、视频的开源软件,它支持文件和网络流操作。它支持以函数库的方式使用,所以有很多软件都依赖它,比如VLC、暴风影音、腾讯会议等。它的命令行程序也非常强大,各种命令行选项学起来虽然困难,但是几乎能够满足日常对音视频的各种处理需求。今天我们就通过飞凌嵌入式OKA40i-C开发板保定飞凌嵌入式技术有限公司来介绍它的命令行工作方式。
9 z6 v* t+ M* r2 v
FFmpeg提供了全部源代码,所以在网上可以找到很多教程是关于交叉编译ARM版本的。我们测试的版本使用的是FFmpeg-release-armel-static.tar.xz。解压缩以后拷贝到飞凌嵌入式OKA40i-C开发板上并设置好权限就可以使用了。
3 s1 U& E# E1 b$ q
2. USB摄像头测试
OKA40i-C开发板接口丰富,它支持USB摄像头、CMOS-OV5640摄像头、模拟摄像头。把USB摄像头插入开发板,然后使用
v4l2-ctl --list-devices
6 t2 s1 z4 w4 A3 k可以看到/dev/video0就是我们的USB摄像头,如下图。

使用下面的命令可以看到该摄像头的全部参数:
% F9 }- L( \/ ^1 ~, i" B5 \+ `
v4l2-ctl -d /dev/video0 --all- 9 o G9 L/ m, r- {# P# p( S3 `& e
8 B I) |0 Z- C! I! i- P* J: `/ q0 U4 h6 G% C0 B2 `& Q
) ]8 {) C: d, j1 o$ H5 B: J5 { |4 t0 M. h5 s
6 ~ N7 _; w6 L6 \; w; I2 }- ]( ? z+ ^# W0 \9 ` z% |
Driver Info (not using libv4l2):
- z3 N9 \1 r5 Y! l& `3 `: }- r0 j. @2 V% C# Y, i4 R) h" z1 i
1 b: {) G8 L2 q3 Z9 [# |; o. K( f3 V. N0 v* R+ I
Driver name : uvcvideo- d; m$ \8 J% X/ u C- H% H
/ p9 r9 C m/ @! o" z9 E
- " G1 s) W! F, s0 W9 g
0 R: K: N; ?- G) Z& W# M
Card type : USB2.0 PC CAMERA/ P" t% ^# k; `# F/ q# |7 S
& r! h9 f( \; w9 |2 b$ d) ^) U
- * V% ?0 q8 y& |' Z! g
' u* ^) `5 F' ^# H$ H# s0 h Bus info : usb-sunxi-ehci-1
4 F. S' j! I; F$ a* Z# i; I
& y& W3 W3 f- \6 K5 h, E5 ?" e
" l7 N$ s8 s5 L$ L8 S- `5 j9 J& L* e: \# `9 V
Driver version : 3.10.65! M P/ i _; q8 z( k
7 y8 B& ]7 G. @; S, ]& H
$ m. Q4 S' c \* ^9 V7 Y# J3 L* @9 s w$ E
Capabilities : 0x040000016 h- H0 }* X1 ^0 Y& E
6 Y; f8 ^2 W$ o) P; t0 O/ Z& U1 y/ s- 9 ~& _; a/ a& m6 @) L4 t$ Q
% O& h0 c O% X4 Y0 P6 j Video Capture- D, V! g3 G$ H$ k {
8 I( ]) Y- n& A& r" V8 o - 6 J- A" E- G' {( Z, ~& o. x
$ u' s: {0 I9 q( @% G0 v
Streaming
& y2 C4 z4 g; ]( c; p+ n [4 p" M+ y5 F; j+ h( U+ m
4 g$ y) |0 E( D- E" B3 ?
/ ~( m Y# s: B- P! K3 g6 c1 LVideo input : 0 (Camera 1: ok)7 L* l& i% o6 }4 i5 e
4 b: n' { K* D4 F E' a: ^& N- 5 j A4 _) @. y& G- L+ n8 H# N/ j/ b' o
- f6 ^ ~" S2 W- Y, y* PFormat Video Capture: ! R3 g: k, U P2 L. A
! L7 w3 b1 N# j" `" n
9 `# A/ R- F2 I; M
, l/ s0 T P M, ` Width/Height : 640/480
' _3 ~ X) _! ?6 \4 ?$ }" y& Z! O! ~( [8 i# E( z/ z( |, \0 J5 [% [1 ?
2 b7 x8 h% T. @- x+ ]- W
* n* U) ]" S# {& I2 H! j Pixel Format : 'YUYV'
0 d; H3 T0 n; b5 j
- I3 g" H+ ^) J- ]- 9 ]6 W3 m/ k4 c1 p) ^
6 S6 A3 x$ R$ x8 |
Field : None
4 j* q; e6 y; X N& l r. I- r" K% l' s6 _
) R0 ^1 g: f6 ? a3 L$ q! ~4 ]( W# o. G! [
Bytes per Line : 1280
* I# M( q' ^- w! g2 d5 f
% V% }2 C8 h& O- o1 I& |' N+ J- 4 B, D8 z$ A: E" H: x
. T8 C6 K3 D' G1 k
Size Image : 614400
* M6 [+ _" G/ g- s+ x
, j& r% x8 J& L( }5 W
/ f+ m R) C2 H+ t+ c
9 H7 A8 ?! Y9 v' j0 E. B; ^* O, k Colorspace : Default& y- d, a1 m2 e2 ]6 k
: \' h9 r! [2 u& J6 a5 Q$ n
* r; l( I' f0 M! j }- l1 B1 P x% D8 [
Transfer Function : Default
& Q3 [& H8 }, C9 E$ m r3 X4 P: g: b$ v
- 1 s z1 f1 i" G% ^ d- j" U3 U6 M
4 @& l* I9 j( _9 f YCbCr Encoding : Default: B, F5 o7 [8 X# \+ X3 f
/ J5 M$ h. G" J: c7 r
. U1 c; c* H7 ]7 M! E$ q* r" e+ E F% e$ L" O* k- N0 p
Quantization : Default* _' r! m1 {, D& X- J
! Y e$ I/ W( ~, [/ k2 L) a) G9 t! Y
& u/ Y3 ]- {5 Z# J2 Q: E
$ ^5 J2 R, t# S( {4 L2 H. HCrop Capability Video Capture:1 M- g2 W- ^4 P1 M
# s9 B6 o' l3 S9 D- ; e' l( D4 \ Z8 x+ D, m
, j7 K3 t( a' q1 E# Q- w& H# [
Bounds : Left 0, Top 0, Width 640, Height 480
# T1 N& @) G8 b, L0 Y
+ [$ m0 ?5 ^/ N - + P2 P- B4 g+ y
3 K8 K. p$ c5 x/ o$ Z% U
Default : Left 0, Top 0, Width 640, Height 480
6 @4 G9 S7 A6 }5 v" |, E! S# l& t( U+ b: i5 Y
- ! M1 ]' v5 B$ p4 f. j/ x1 t
9 c- L" u7 T2 l1 }0 {7 V6 \ Pixel Aspect: 1/1
5 m% P' L; F$ f6 A- _
, o2 Z* ^! \; S
9 T/ X5 T& w& ^3 G g6 H$ J7 i; w) z- c" u+ R# m5 i1 N6 d
Streaming Parameters VideoCapture:! ?9 o$ E9 ^3 G
5 t* C; ]/ W0 \3 _
* Z1 L" a& k0 |9 `# B% e) F4 A% X9 ^8 O- z
Capabilities : timeperframe
/ S" S, L) a- C% X+ d% J2 D+ O' U# v/ I
- ) l, ]* f- _8 ^4 q7 u( w& M6 ]' X8 [
& K/ a2 G& ?7 S Frames per second: 30.000 (30/1) 9 {) k( F5 ]* w) \
$ O1 R+ z; x3 S Y' v' ^
- & o. b2 C& l3 Q+ {% H
% x: u1 B3 j% p5 u0 v) J: C Read buffers : 0 ; }+ c8 z# r v) C
; o C" E- l7 R
- / M# O& O5 y. A( k; l* S
$ x: e5 b+ a9 o& X2 { b$ M
brightness (int) : min=0 max=255 step=1 default=128value=128 1 Y" ?: d C" G8 B
. s1 ?: x# s. {: F% \$ i- p
& u/ @3 J* U% t1 i( z5 N2 g6 c" }3 l% V
contrast (int) : min=0 max=255 step=1 default=135value=135
% H# A G1 S9 g5 C& k; T [
5 B" g+ C, I4 L1 y( j& J2 y. ~
; c6 M% w; x9 r) R/ s& G- ]! \2 b' ]5 D: i' V) j
saturation (int) : min=0 max=255 step=1 default=75 value=75 ( _& h$ s1 e4 {8 X* V; u
9 O2 g( k) ~3 Z3 W
3 X/ p' Q7 t3 H" j7 |+ ]4 `
* r" X* n# O/ o+ t" n* I6 u hue (int) : min=-127 max=127 step=1 default=0 value=0
4 _# H+ F3 l5 x, b1 ^/ H; @
- s4 p* \% t8 X) i. ]2 ?
, f' s7 N1 R( E- L
: g( |' A" S9 s# z; | gamma (int) : min=1 max=8 step=1 default=4 value=4
4 }1 z+ d8 q5 ]: ~4 t# D* M: J+ \2 Q. `! z: ?1 ~% u* ~0 [
0 L4 E/ ]* S+ b2 g1 y+ f1 H% }& [- }6 [9 h$ z/ n+ ~4 P; _
power_line_frequency (menu) : min=0 max=2 default=1 value=1
& [8 c2 m3 X* {+ ^: i
2 B% R, @7 }! @; k8 N- - @7 {& v J5 `* I7 ^
( j9 d9 [2 I4 [3 ?
sharpness (int) : min=0 max=15 step=1 default=5 value=5, n9 {" r! h$ B4 |& u/ P, |
( s9 L1 s1 {% ]3 `( [. z9 J
- ) n; |+ K2 S* h% I" H7 _ G
" ?( t+ B& q' y+ ^- b, F& ybacklight_compensation (int) : min=1 max=5 step=1 default=1 value=1
! Z4 m5 n+ K& z4 X2 {
9 I& K) u& I9 T
7 s' a2 I) s" ^$ m+ l
1 p9 A7 i( z7 @5 h
我们使用了两种型号的USB摄像头,按照手册说明使用内置的uvccamera程序进行测试,不过都没有成功,得到的错误信息如下图所示。


我们使用FFmpeg可以抓取视频,命令行如下:
- ' u9 O& Q" ?7 m$ }5 y s: R
ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv
4 u- E9 @% J4 Y* R& _2 F3 J" @使用Windows版本的ffplay可以正常播放抓取的视频,命令行如下:
- 2 I, ^4 l, L% N4 Z5 t- w, z; t
ffplay -s 640x480 -pix_fmt yuyv422 out.yuv% }0 T. Z9 r7 B1 L8 T; p0 v3 U( t
上面保存的是YUV格式的原始视频,如果要保存压缩视频,可以用下面的命令行:
, N1 n- F9 B B5 A7 i) o. Q
ffmpeg -y -t 15 -r 25 -f video4linux2 -i /dev/video0 out3.mp4-timestamps bs
6 U( M6 E/ v# [/ G# d, x其中的-r 25表示每秒采样25帧,这个参数必须有,否则FFmpeg可能会不断地采集并压缩同一视频帧。-r参数超过30没有什么意义,因为USB摄像头的最大能力就是30fps。
3 m* ]; o* r* v5 N7 R' Q: @8 B飞凌嵌入式OKA40i-C开发板可以对于1080P的视频压缩达到45fps,所以对USB摄像头的视频压缩应该没有什么压力。
5 D" P y3 P U- o3. FFmpeg性能测试
FFmpeg有个benchmark参数可以方便进行性能测试。我们对A40i开发板自带的一个MP4视频就行解码测试,命令行如下:
ffmpeg-benchmark -i translate.mp4 -f null –: m( V3 \/ M4 K% a7 l
得到的测试数据如下:
7 P4 x# z+ p2 _7 ?) c! p
# B6 W# K* Y/ m; w; N* qvideo:
) O' R: c. t$ j# n
$ }; n% g2 @9 n8 {3 `- 8 s! P/ y) a: }! Y. Q
; _& `" j% o2 U. L148kB/ V" p$ M5 A, ~% A+ W8 @
% @3 b& i v, f5 d* }5 V
& T! I& S- q l2 }$ }$ A& K2 N! X2 Y/ `
audio:
6 ^# i* h( M: B9 G9 w8 F4 J
( O0 G. Y% D: F& B- ' T a9 N9 P2 e' m
& m: _: }8 @: _2 N/ y3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
# b1 m2 D2 B" _* g
( w" N! u* u- r$ ` - 6 R5 g: b" ]& `: Z8 S: a4 M7 |$ H
6 e4 }7 W% o v0 t8 y! B
overhead: * _0 L6 h+ B( I6 w: d& t/ H6 t" h! a
% S& ] k6 j" o
^# p4 D3 ]+ b, u2 I( g( ]7 y$ v5 H6 I! J# n& o
unknown' M5 @$ q2 U9 i% g
; j" q% }5 C3 Y/ Q! ]6 U5 |3 k- |& a# j+ _3 U) h" L
, M! V: y ^; B0 a
bench:
9 u: z2 `( q/ B {; ]# b- I: R- x
- ( h6 t8 M( @/ E2 r+ C8 _ _: W
4 `+ o" f$ K" b' P5 W3 W
utime=2.820s stime=0.110s rtime=0.956s) Z8 g, G# x, u5 l8 y# b
i# O7 m7 g# A) f4 V. x
) \1 @+ X7 [) [6 ~0 Z. [. x: }& \& [& I8 t' N7 \8 e- V7 T
bench:6 `& N% t8 V/ E0 w) _# @% I) }2 W
( \8 ]5 R5 L$ J# r, a- |8 \
4 ~! r/ T g4 Y5 {( i) Q* l! Q* X* k6 p- \$ k6 z
maxrss=14208kB
: f' ` H, R q6 D+ @
# p* L! P3 @! h8 X
* j p: s1 n1 K" l; ^
, n6 _% h7 i( }* R Y由于我手上暂时没有其他的开发板可以对比,于是就通过我用了5年的i7-6500笔记本测试了一下,测试结果如下:
0 o3 m+ {* Z; Z4 U3 ^ g' V
* d* ^0 G+ s, R' w, G0 bvideo:
8 P& l# v$ ~3 p0 R8 ]1 c4 `4 |, P$ g, k' A5 r; n4 ^
- 3 q% p8 {$ P; z* N
, ^4 I& b5 z9 h. ^; B3 f241kB/ O. z6 z1 _/ q: G9 u* j
9 D3 t) |3 y; k2 I) {( W5 f# n& n
/ T3 U; A& g$ b3 M
( ]! Y! \% s( r# C( p$ Naudio:% x+ Z* I& @: L% |3 @, H F; g5 i
8 H6 G0 {. k4 i" f6 i. y
p7 @3 S) b; G: ]( Q- I& B5 g l1 T. Y9 a# e+ ~
3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
1 m* c' Z* m5 B/ [7 z
6 s5 o( Z& Z: i
$ E9 a9 h" G9 Y7 n0 Z |" o3 y+ g' U
overhead: . `. U8 H( K. q v: V. l
: p4 M7 p0 I! a6 @/ m- H0 G7 [
, E) b" m( F8 w$ A7 V! v6 u+ o
& X0 |* [7 a9 m5 J: a) D1 E3 kunknown
9 b3 h. b( f8 }0 \: H
) T3 m' D* H# K+ D$ l8 q7 u5 U
: w: x2 g3 W* ~) M
v- C) M0 l* U4 V7 Y) Pbench:
* v+ W1 V9 o7 N
8 ]* [$ _$ M1 Z; \6 N
7 L6 |6 d9 k3 e. E2 g& ?8 u1 t/ |
utime=0.391s stime=0.000s rtime=0.228s
1 ]+ x; B8 a$ t6 q) l2 n7 g( [1 ~$ S( S2 }+ g% t* B4 \8 T. E
5 t7 [# f1 O8 g5 \) l7 b9 @0 p
/ n; _, E7 x) b2 ~' Ibench:
" A& \7 o/ l- A5 W, Q0 U$ Q) X" s. z8 E3 X1 a* T& Z/ U5 ?6 k
" I0 i; j% R \* D; C2 P2 v: S/ [1 L v
maxrss=20316kB
5 l6 i& W' l, h' L$ [* q
9 U$ h2 X5 l0 ]
2 i9 m' w2 a& @" v3 I: M9 e k+ h
4 I/ A2 y7 r( S1 s* k% v- @4. FFmpeg产生实时视频流
FFmpeg可以支持实时视频流的发送和接收,从而可以把OKA40i-C开发板上的视频实时发送到PC上,由PC上的软件实时接收并显示。我们可以使用下面的命令将OKA40i-C开发板上的一个MP4转换为RTP码流发送的PC上:
. B F; h/ n- D$ D h. Y. Q4 i2 I
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234
1 `5 J, ]' L* E使用Wireshark可以看到在PC机的1234端口收到大量来自OKA40i-C开发板的H.264视频流。

5 Q7 W% p$ h# v) i# S& z) w5 \1 c, V" m, P, b/ a) {$ y
如果想在PC上显示视频流,需要建立一个SDP文件,它描述视频流中的端口和编码信息。
# g8 E q5 }2 D, c9 L7 e! }
SDP是来自SIP标准中定义,目前VLC、Apple QuickTime和ffplay等很多软件都可以打开SDP文件,并按照SDP中的描述显示视频流。SDP文件并不需要手工编写,在ffmpeg运行时它会显示命令行所对应的SDP定义,如下图所示。

也可以用重定向将输出写入一个SDP文件,如:
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234 > rtp.sdp' z* B! I, s6 h, O0 u* Q2 t
下面就是使用VLC显示的接收到的视频流。

2 v) g# z; Y, l7 k& i: }" E k0 c7 T) E2 i* R6 \, Q/ t
5. FFmpeg转发USB摄像头的视频流
前面演示了将MP4文件转换为视频流,我们也可以将USB摄像头采集的内容实时转发到PC上,使用下面的命令行即可。
ffmpeg -y -t 15 -r 25 -f video4linux2 -i /dev/video0 -f rtprtp://192.168.0.105:1234 > usb.sdp
- y1 S( `; D! A' R. N, p3 A
作者: somethingabc 时间: 2022-12-19 08:38
步骤很详细,小白式操作
| 欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) |
Powered by Discuz! X3.2 |