EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1. FFmpeg的安装 FFmpeg是用来记录、转换数字音频、视频的开源软件,它支持文件和网络流操作。它支持以函数库的方式使用,所以有很多软件都依赖它,比如VLC、暴风影音、腾讯会议等。它的命令行程序也非常强大,各种命令行选项学起来虽然困难,但是几乎能够满足日常对音视频的各种处理需求。今天我们就通过飞凌嵌入式OKA40i-C开发板保定飞凌嵌入式技术有限公司来介绍它的命令行工作方式。 1 Z0 h" C7 I1 Y2 }$ ?* d& E
FFmpeg提供了全部源代码,所以在网上可以找到很多教程是关于交叉编译ARM版本的。我们测试的版本使用的是FFmpeg-release-armel-static.tar.xz。解压缩以后拷贝到飞凌嵌入式OKA40i-C开发板上并设置好权限就可以使用了。
6 @# n+ c! E# x% p3 \% S2. USB摄像头测试 OKA40i-C开发板接口丰富,它支持USB摄像头、CMOS-OV5640摄像头、模拟摄像头。把USB摄像头插入开发板,然后使用 v4l2-ctl --list-devices* m5 M, Z N8 ~6 V$ I% j r
可以看到/dev/video0就是我们的USB摄像头,如下图。 ![]()
使用下面的命令可以看到该摄像头的全部参数: v4l2-ctl -d /dev/video0 --all
. I2 M% a7 ~* @! h- _- D8 V( z& O5 Y4 ~+ I* [' P6 ]& |
, c$ e6 J% P) I G
8 G& h7 b: ~0 {% b
- 9 u; \( N3 O M* ]/ J
S+ ^- K8 K& MDriver Info (not using libv4l2):
7 j0 q d- t7 _+ c7 X9 u" U3 I% S& N8 A' X
% P, R# x5 t+ B! ^; s M* W
: q- o# x; _/ a6 b/ O Driver name : uvcvideo% @9 M" I8 Q' G- i! C2 y+ ]( Y
1 w9 e5 p# b6 y4 C' r/ T. _& q+ R/ u
+ Z9 {& R5 B: P1 |4 Z- J; ?3 M& S5 [3 u0 X2 J
Card type : USB2.0 PC CAMERA6 }5 Y: e, }5 k% i' [/ V# b
$ @$ t) x/ H% j0 \7 e3 a
, v; a9 i: h' Y7 F9 {9 I- Y6 k
* e9 c* ]4 w5 X- W. L& C: t6 G0 } Bus info : usb-sunxi-ehci-1! B. `# M# c- x z3 D2 P5 r2 a" q
" C( T- z0 M! f3 }: `
/ G1 K1 g/ P' ~' D7 G# R# C0 D- Q! ^; i, N. e
Driver version : 3.10.65
5 g! q0 D6 Z( i5 G& H% _% f
# y a3 }! w. z5 T( Q. h
0 F! ?+ p! N7 L: D
" R. f6 l% m! t2 }$ q7 V, P1 G Capabilities : 0x04000001
( D9 c% `6 \8 h9 ^/ M. I$ M# _9 C4 r+ Y8 [$ E/ r9 M
2 x% }8 Q0 ^3 P! H& L& h+ h5 t" l3 i
Video Capture
' }$ L6 J) k) b/ T6 {+ \
$ s/ K" _% w; T& k J7 H3 V
6 d& X* A3 F7 _" M, n
7 D; E2 H, C! N8 Q$ I Streaming$ Q. g- F6 q8 A" T, R3 B: Y; b
* B% J9 S+ m4 ~/ n# x
/ K+ D1 V e& F+ N# [2 }( d1 c
5 s9 u; n1 I: q% d* w1 e! ]( |Video input : 0 (Camera 1: ok)
& ^5 Q0 E1 b! C3 N# G3 b- m0 r
v; g. ~* v; K- [/ Y" K6 ?# _- 7 E. ^1 c2 }) y3 K* d
; Z: p: z9 b3 Z1 M0 P" u; ZFormat Video Capture: * q; V: ?# S1 C/ p! _2 J! t
$ \8 w2 K# K0 Z& z7 \- O5 A7 r+ k$ Z - 0 q: J. s) |7 C" I$ d
# L% Z% F3 o2 v+ k. t# i# u Width/Height : 640/480 F+ @* D# Z5 X
; G7 d1 @9 b% T M' Y7 @
- & _5 _! `( F! @8 t$ a
3 J$ P) K3 P' q- l( j5 H
Pixel Format : 'YUYV'
* g: _7 ^% S" I& f
6 e" _/ `* i2 s) U- C
b, G3 h8 y; H5 u
% r6 Q4 B( f& S, b4 d# q6 J Field : None
: \4 Z! S# t" O% d' ^9 T; N, a% V: S4 p2 B8 ~3 M
- : S' B* z& r7 n7 `$ J; ^
8 z' x N+ N/ I4 U# T- i+ ~ Bytes per Line : 1280/ @) t, R A, M3 b2 d
2 F% \- q- A/ v( Q; f- i
/ b' A) Y \2 R0 I; i9 d" I1 y6 }$ d# h M! h9 `
Size Image : 6144008 Y! ~) t- Q9 N9 Z7 i
0 s: P# ~/ u. U0 V% V$ C9 D
$ g, ]. o% a+ N% K
+ k% h+ Z+ y0 Y# E Colorspace : Default4 o6 T; \1 }: }- Y, F# K; Y
" j( Z5 |1 t8 ]7 n. C, y
- ! U/ f( Q' S+ U0 y! b
( R( j' u/ L9 H, k Transfer Function : Default
) I1 Y0 s; X6 i! Q9 _
" L5 v. M5 c) G
2 b+ j |6 d& N [0 v) C4 o! @ X k4 J
YCbCr Encoding : Default5 A+ f# Y r, _. g" f
# D; P" c3 o4 o0 ]3 p% |
- $ `/ _7 F( X2 f$ H$ G
T' A! L6 Z1 M, [7 ^% f
Quantization : Default3 h. t9 V4 I8 o V+ ]) Q
3 n. v; J# I7 C
1 Z" x; S' i$ |) E4 n1 H `5 r7 m6 I. T- M/ i9 v& N F5 I' j
Crop Capability Video Capture:
* n) v0 j4 I8 m% O3 S
7 K$ u5 L1 n: W* q; T* I' U3 n- % R/ x5 N1 x# A# [1 F1 M
6 |3 s+ d2 k) z( { \( O Bounds : Left 0, Top 0, Width 640, Height 480
g7 A# k% l' Y" `
6 k8 n& z8 C3 M, z3 s% I& d
5 e J; V' w6 ~. u8 x% _3 ^8 ^+ r/ ]* C9 e5 s
Default : Left 0, Top 0, Width 640, Height 480 - s. K9 ~3 C# y" X0 w- m3 G
* H" ]; A2 j/ K {/ U# n" d9 a9 L
- % _0 G) m! D+ |" K- T3 v
8 P4 ~! ^: u" A. |0 w! U
Pixel Aspect: 1/15 t o, S( i) K6 x
" ?# Y/ m# V4 V Q- q3 ?4 y1 T
- ( Z/ d2 Y7 k4 t: w: \' Q0 \
9 U {. }! }8 _! `) s* N
Streaming Parameters VideoCapture:
; @ W/ v8 J7 S
: i- u q) U) a g. h% B5 q6 d: G - 7 P" U+ K$ u+ \( {* I3 d5 N
5 x$ [; h% X7 r Capabilities : timepeRFrame
) _. J2 { i; e0 ~* k7 K W$ V
, B' p5 l- e, i! M; }# a' V - ) r7 X; O# ~( c3 i
/ }8 M1 c% p, Q6 D& |& v1 Q. v9 X2 | Frames per second: 30.000 (30/1)
! ~; h$ H5 c0 A: Q0 o0 {4 D5 l8 k4 Z4 o' y2 v7 G. {/ M
6 p/ z) j7 z$ J! T \) H+ I `6 l4 V0 Y$ K- @1 h! T& J1 l
Read buffers : 0
+ }( `- Z% ~' p; ~& c4 ?. D2 B
- . d% O0 G K2 S3 c
% F8 D. n+ h; X% {+ g& t
brightness (int) : min=0 max=255 step=1 default=128value=128 3 \9 O0 ^* O- N" y2 S# o% v
( ^. }8 Y! T: P. M7 i& K% F |
# x$ j! s% P4 x8 N" Y; ?5 O/ P- q# G# o7 E" K' {0 b1 I+ ~5 x
contrast (int) : min=0 max=255 step=1 default=135value=135 . S- X9 e) N" @' I. ]$ z' N
9 G. o) ^) }$ K+ l7 Q
% H9 p4 U$ F/ U
! f& [0 {* W# y5 r saturation (int) : min=0 max=255 step=1 default=75 value=75
, [0 Y! |3 O+ G5 K! v& x5 O9 _; f: m
- , x; f* ?' m4 j9 B2 u
; k: n3 @, h; u8 W1 D% ~- V0 [
hue (int) : min=-127 max=127 step=1 default=0 value=0
. N& F, L: v( e7 z$ X2 F% J k- [+ Q/ _
1 c q& G8 v7 P# ]5 y/ [# ] ^
! N+ i1 D+ H. F v8 j( _6 k
9 j Y5 ^% l+ u gamma (int) : min=1 max=8 step=1 default=4 value=4
# W& d$ n6 Z2 G1 c- S, P! O
) `7 H8 [' m0 ^, e, c& c- ( [+ H$ Z: `& t8 V3 x
* _2 f$ W' g, q; N
power_line_frequency (menu) : min=0 max=2 default=1 value=1
- {3 W% j! \! I1 j* c6 `
5 T' t- a7 C6 J6 Q- R - * f- k$ `2 C" t7 [8 [- N
`5 ]5 s/ M0 m9 g/ m
sharpness (int) : min=0 max=15 step=1 default=5 value=5
( D! \, }. G% M
( N8 [7 r0 t% w/ @1 q' ?1 I - / t% v4 V- m5 v3 I, e6 W' V
; K: V1 H ]$ u7 D0 zbacklight_compensation (int) : min=1 max=5 step=1 default=1 value=16 }/ u {$ L1 X- x) x8 ?+ d
/ n. E; N. o/ b/ R: U
4 @! {( r" P. \% |- @4 F
![]()
3 [1 v2 D0 ]: d; T5 L* i1 D/ u我们使用了两种型号的USB摄像头,按照手册说明使用内置的uvccamera程序进行测试,不过都没有成功,得到的错误信息如下图所示。 ![]()
![]()
我们使用FFmpeg可以抓取视频,命令行如下: - 7 X$ d5 P% b- W3 Y. p; l# W0 C
ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv
2 z! n/ t1 X# @; F1 h: L7 b3 V使用Windows版本的ffplay可以正常播放抓取的视频,命令行如下:
# [3 O" Z7 y# g" _8 o# h8 t5 k6 b ffplay -s 640x480 -pix_fmt yuyv422 out.yuv
. c* C6 K9 }& N8 k9 a! s4 t7 o上面保存的是YUV格式的原始视频,如果要保存压缩视频,可以用下面的命令行:
$ ~0 U/ h% _ a. X" P1 B& F) [ ffmpeg -y -t 15 -r 25 -f video4linux2 -i /dev/video0 out3.mp4-timestamps bs
& \3 h/ V& n" K' i) V! K其中的-r 25表示每秒采样25帧,这个参数必须有,否则FFmpeg可能会不断地采集并压缩同一视频帧。-r参数超过30没有什么意义,因为USB摄像头的最大能力就是30fps。
" q6 w- D# m7 d* A飞凌嵌入式OKA40i-C开发板可以对于1080P的视频压缩达到45fps,所以对USB摄像头的视频压缩应该没有什么压力。 ' n7 d6 n3 f2 g9 Y( f* }# H
3. FFmpeg性能测试 FFmpeg有个benchmark参数可以方便进行性能测试。我们对A40i开发板自带的一个MP4视频就行解码测试,命令行如下: ffmpeg-benchmark -i translate.mp4 -f null –
. g: \; \1 C5 e: H得到的测试数据如下: - " U1 D$ t' B; [
$ b+ h9 M" F# j* P3 F' @
video:
* [2 \" @$ K" N# c8 x& s9 x3 ?" z8 b
) q. `* @* ]6 j/ S6 \) _ ]. h# |9 M! [
148kB; V$ P' T0 R, V- A5 H
, p$ u$ U6 V$ s! x- R
- 7 B1 ~7 z/ L) Q; w3 m
B# |$ u1 h5 _audio:$ D+ M, D, X& D5 e% \8 y) I
D9 y ]- s+ d" z8 ^8 F
- : x3 B A( u) V7 H/ X8 w
( Q; ~# Q) I3 t
3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
Y9 r3 ]$ W: d; q; n4 o! }4 t
) s* n |: D1 k2 u) x& w7 W
5 U% `* a0 u5 C" ` Q: T
9 f8 k& X# p) k- k n- z- G, r# n7 @overhead:
4 l- t! L# m& Q7 b ]# F( U8 j8 P
* N: U7 O8 J G+ e- % \0 q+ f2 |: J7 u" r
: O: S# L5 ~5 _( a7 O
unknown
2 s0 E) t& `& j# {: Z W( V' ~5 S1 U% ]- S
0 j/ [6 `% m! P; Z) W q
6 {; u5 X1 w5 T4 i5 Dbench:
* X& P7 S: V6 n
- r% y) q% M5 I; ]- 9 d" l F& Q p) x
1 r, V% V' e* G6 u9 {! l
utime=2.820s stime=0.110s rtime=0.956s+ K: `& u; D8 O* A5 q# n
, J! E* o9 A# W
4 v' S! S' }6 B; E% x6 O9 a/ ~: K1 [; n0 N
bench:/ \. o% T- }* p/ v
8 s" X( f# o# s8 ~+ x" v: j
- . U" \/ ~* C* z/ P6 T e: V
4 ]3 q Y* ]5 R4 Z
maxrss=14208kB
" n/ L3 f9 G. a9 {* k" }* \/ e! C$ ]. K/ Z
. y n1 I/ w+ G
1 J" {7 q1 l" S+ z- {; m* n2 k
由于我手上暂时没有其他的开发板可以对比,于是就通过我用了5年的i7-6500笔记本测试了一下,测试结果如下:
9 b/ J( }( G2 } I; n2 `. D+ l' V6 |+ A1 i) d$ b
video:% M/ K0 t9 }# m8 [+ h! R
5 N& x; T* v4 r3 C- ( W: |1 p- R* u# Z; b. n
. b: _& ]9 j+ z! d+ O
241kB2 C' v& M9 i4 T7 g+ |$ M
X/ r! H, ^# ]! ?& X1 L
' `6 F- q3 n4 p" f0 G q% L1 U: \0 U- o0 a+ Z
audio:! Z6 H4 v4 e4 J5 Y1 d7 ^% k* s, r
2 ~7 `$ g* ]/ P, s4 L
- # _" k; e% R1 [1 s1 ~
6 z" b2 M7 \; W3 g: Z$ t& q
3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
+ o& ]) ~7 ?3 m1 |
) |. R7 v- |% ^3 W
- G. N P( r- _& F& I$ y: E$ U
5 y' D: s0 j) T# @overhead: 8 l8 M, o3 n' k
, O9 N' Q4 F: v$ C L3 D- # o: d0 x; ~2 P K
) E2 y! V R1 ~6 L1 p: J
unknown
' i9 b! y/ q3 U! j! M' D0 c2 a" K6 s6 s& z" u1 W+ Y- p7 |# ~9 [2 [2 c
2 q8 B# F7 f2 H/ a: M+ E$ L
, O7 H& O/ s _, k( g: qbench:6 m3 N; h) w% t2 ?$ e7 V% x
! [# q4 G$ z& @+ ^ F# V# n/ t$ m
- ; q( }$ K: T& M3 u& Q9 M9 N
, q5 s" w& B# v4 M! iutime=0.391s stime=0.000s rtime=0.228s: g- W6 r6 N# F9 D) u( ` N2 x9 g
5 T0 r3 ~( W% x
; e0 u g7 G) H$ t2 P* W
6 m6 u5 r' o: u' Dbench:
1 t7 j: D# t$ L$ i& I v$ ^
& F2 i' o8 f( g! [+ W- ! m4 F- Y5 z0 r9 B
- y0 n8 L* l! cmaxrss=20316kB
1 R; g& Y7 V1 h r* _7 c, t( T
9 |/ j4 m) ^' K3 ?2 Y" [0 |( `. D' R6 f0 _( A) Y, C( [
) \3 b3 P" s$ m4 M- F
4. FFmpeg产生实时视频流 FFmpeg可以支持实时视频流的发送和接收,从而可以把OKA40i-C开发板上的视频实时发送到PC上,由PC上的软件实时接收并显示。我们可以使用下面的命令将OKA40i-C开发板上的一个MP4转换为RTP码流发送的PC上: ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234
5 }, L3 d" y- K% C2 P L. p' r; Q, ]使用Wireshark可以看到在PC机的1234端口收到大量来自OKA40i-C开发板的H.264视频流。 ![]()
8 u! w5 t( I1 b- j! p t) M
; x& p7 z p0 L$ Q8 Q+ U+ u如果想在PC上显示视频流,需要建立一个SDP文件,它描述视频流中的端口和编码信息。
: }: [2 h, y4 Q' R, m: vSDP是来自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
; N" K. _2 ~3 g. r; g下面就是使用VLC显示的接收到的视频流。 ![]() , L* Z( T9 v* O a7 {
/ [9 \% O0 T2 ?# I1 R" h8 Z5. 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: n" C& _% S/ f9 D
|