EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1. FFmpeg的安装 FFmpeg是用来记录、转换数字音频、视频的开源软件,它支持文件和网络流操作。它支持以函数库的方式使用,所以有很多软件都依赖它,比如VLC、暴风影音、腾讯会议等。它的命令行程序也非常强大,各种命令行选项学起来虽然困难,但是几乎能够满足日常对音视频的各种处理需求。今天我们就通过飞凌嵌入式OKA40i-C开发板保定飞凌嵌入式技术有限公司来介绍它的命令行工作方式。
+ D8 b7 |8 \* t/ D, M3 h- gFFmpeg提供了全部源代码,所以在网上可以找到很多教程是关于交叉编译ARM版本的。我们测试的版本使用的是FFmpeg-release-armel-static.tar.xz。解压缩以后拷贝到飞凌嵌入式OKA40i-C开发板上并设置好权限就可以使用了。 7 {: u2 ~# A: A$ J5 W: ~9 d( K8 [
2. USB摄像头测试 OKA40i-C开发板接口丰富,它支持USB摄像头、CMOS-OV5640摄像头、模拟摄像头。把USB摄像头插入开发板,然后使用 v4l2-ctl --list-devices
5 T# b. L( R" ?* \+ g可以看到/dev/video0就是我们的USB摄像头,如下图。 ![]()
使用下面的命令可以看到该摄像头的全部参数: v4l2-ctl -d /dev/video0 --all
3 s e/ _; q& X. }+ ^
0 P$ L% f8 q( w' e/ j4 n
3 Y9 g; B5 N$ X- o& `6 X8 z/ x5 q% o, Y0 G4 p \( `
- 7 a, A! g) v" e# v& _- A
8 I6 f5 y7 t0 ]' A$ V
Driver Info (not using libv4l2):
7 p7 h. Q! ?6 Q# [+ R7 q9 N7 [/ V8 y
4 _4 i; n- A) b+ l4 I+ E- u* k4 Y3 o
0 e& m& a* J: D6 A
+ F" J& Y; C1 k4 r. V9 C g Driver name : uvcvideo) w" A+ e* g* T4 U: k% \" {
+ v/ R ] i) l. L' R3 @
1 G) d0 ^4 y7 I
! O* y$ Y4 j& J2 K5 m* d Card type : USB2.0 PC CAMERA: H6 ^, @) d/ ^5 E
; L3 q( d9 P& }5 U' z( K: P
- * [5 f4 I6 t! A/ G$ u, M3 s. T
3 y( n: L+ D. R h0 C5 n8 O2 N- c7 A Bus info : usb-sunxi-ehci-1
7 A( B. W, j3 E( E; o6 S- T8 x6 _0 x p6 h
- 5 B& o! K0 C) r4 ?
! k- h" E) o5 e" K/ k( S! E$ r Driver version : 3.10.658 L) L( v4 l/ ~7 d. @
9 n7 e$ P! b7 P, ?1 i( Z - 4 r3 ]4 n+ P U9 f+ O8 J
1 V- }0 }+ [( g
Capabilities : 0x04000001& W! ~( A: {: `! _. ~
+ Y4 `) k1 `4 `" t* r3 C. H - $ C" s3 [9 c2 v, W1 |3 @% j
/ P5 z2 h6 t* Y+ B) E' S) Q- y
Video Capture
* k4 U1 C: Y5 b, d2 I R" t- r3 n+ h+ v+ U, q- d) c# r2 q- _ D
( H) R) q) p, J' {5 ^
4 Z6 V9 ~8 }/ h4 B/ k Streaming4 p. n9 l2 k. T& E9 o7 s h* b4 ?
! i; E! P1 \' K! r% |
" L* V* D4 c- _2 Y1 j# t4 N3 G2 @' ?( N* `
Video input : 0 (Camera 1: ok)
% v: A, |0 `5 |3 g% T
$ k5 m* \( V) r9 j% b- 0 m& b( S( C$ e1 V. f4 K" Y
; `! n0 O5 h/ _$ m3 b& z# O3 \Format Video Capture: 1 T3 R# {# F6 B8 q
& Y; B5 v% Z* G4 ~- j- g
6 c# U; i% g7 b; s3 O
3 l2 [3 i. e4 B; K6 L Width/Height : 640/480$ }# X* \; H! b
- d. b( q/ h) f3 J' f! W
! O# |9 g) V8 I. n* U( g1 b& O% k8 r( N1 f
Pixel Format : 'YUYV'
3 [, x- O# U. S) V2 S1 m; d
V6 s' S C7 ~2 S- 0 _5 Y7 j9 S9 p U3 @7 H* m8 b
* m5 I# `' z! k# x C( B r Field : None+ H* L. @: z) C/ u
1 {6 o7 I4 @- ?' c r) m) r; k0 G - % c. L* m* R" e6 w- C* E
4 x3 U4 \" Y4 e# a5 p4 @) {# s! h Bytes per Line : 1280 R1 ~# O6 P( J' K
+ ~; B3 Y. Z- r" b# [+ |8 D3 G - ! M- {# ^, @* ?# m) v
! {. x9 C7 v# [- U7 i) \, z3 x
Size Image : 6144000 b# b4 ]4 _: Q' c( `6 f
6 \* D' g) @( q7 k0 q
. ^, J, G& \8 I# o5 j+ J
1 @! X1 p3 c1 ]4 J1 p Colorspace : Default
8 h' U! B% V8 R4 Z+ H, G4 l x% u K+ k$ y& d- H
7 | z0 }5 y4 q
) L: o. ^4 t+ t Transfer Function : Default
- N, i5 N2 X8 M' ^3 A8 m# A+ `. Y+ B C" }: t0 D! `2 U, e5 h) b- x
0 o B, S6 m' X5 N1 R5 G4 W; I' ~4 u) F
YCbCr Encoding : Default. o) x$ l1 N( g. m! O3 }
$ ?; E: i" t x2 t! R& F- ! {/ k/ P/ U5 H, ?* d6 Z' r
/ W2 g+ \6 W" q- I1 F8 D3 R; L( T Quantization : Default
" w3 e# |6 s3 o! T( T0 q* A4 p" r/ ^5 L; |6 f8 Q9 x
- # N% s4 O2 G# M5 d. O
" W+ Z9 y4 }! e: q
Crop Capability Video Capture:! N$ L" f7 q* N0 e4 G9 l
T7 ^/ o# k% ?2 |2 T n6 L0 |! P
- 8 t* s( C* m* ~2 B s
N, S3 O$ N$ e
Bounds : Left 0, Top 0, Width 640, Height 480
4 H+ E! s* i# j5 W( l" T- p" j# W. U/ s* _ E; S2 o4 d3 M5 V
+ W% }, T9 l' { {# b/ ~( X b
3 g! g, ^9 i9 V, s" r Default : Left 0, Top 0, Width 640, Height 480
) }5 X3 v4 Q1 O
3 Z b# b. U4 X3 A0 l7 N7 N! b- ) q' Z% q8 p6 s( G% w% X3 F
- `1 F2 s' ~& z+ I, u6 a4 x Pixel Aspect: 1/1& f- W! g3 Y: c% ?8 W1 H: H
1 f" |1 W( i( ^- b) p4 f. D/ X
2 ^3 i4 J+ t4 ?+ D* n6 N( ]# z
* w: T( ^( d4 qStreaming Parameters VideoCapture: s$ v# V( K O( `# P- J3 \0 O
, |6 l3 j3 p* @: K
- 5 y7 q9 j5 r9 G8 Z
4 M5 Y* C' `. _. M! K& ]9 p Capabilities : timepeRFrame
9 u# ]7 P" I i) j: m9 v3 W/ m
' `) e/ E& A7 H) J - 3 o6 |5 K9 z' |" K
$ r; a( F4 T& f+ H/ L6 E' P Frames per second: 30.000 (30/1)
g' d% O. g2 |% Y" D6 g* C7 k6 w) f9 P6 l
- ( s7 _. _( g; u! u5 b$ Y3 {
" Q" @/ K R: x7 Y& N
Read buffers : 0
1 V% l3 B7 R/ S# o* Z$ o6 |! B$ V/ l5 N4 F* h& V) o, I
; ~" r3 H% N8 |5 e* `: D8 G; D6 x6 F# i: p
brightness (int) : min=0 max=255 step=1 default=128value=128
7 E$ N- t! S- T" q* c+ h, p: R0 c2 X9 \8 V$ `
u3 Z) ?- F7 a' C: h/ u/ ~5 P, s" W% _; l
contrast (int) : min=0 max=255 step=1 default=135value=135
1 {4 _+ K6 o, [9 d
- w' M8 P! z8 t; {1 _8 i: ]- $ u `; r \* p' }4 i; G$ ?! @
& _0 }' `# J& ~# ]0 u saturation (int) : min=0 max=255 step=1 default=75 value=75
6 ^6 L! b/ ]% J+ ~8 L) ^( c$ |1 o; S. f! K) {+ ]
1 H4 F( T6 k- e! r. n& n7 f8 E7 _+ \; T2 ^0 X
# |2 C( K: M: R4 t hue (int) : min=-127 max=127 step=1 default=0 value=0
3 ]2 g5 t: f" `- Y" Y/ _. r" @( \! }# r3 }4 `) Q: l1 q' m
6 R. K$ \2 N: V! T* k k1 a+ P
gamma (int) : min=1 max=8 step=1 default=4 value=4 # j4 h2 y$ f" J: ^5 x
6 d- L q3 ?1 \% o9 {$ e4 `
( R$ L0 d# _: E# s/ S, R5 p, D6 j% Q2 x, O2 M9 M- S4 @2 r7 J
power_line_frequency (menu) : min=0 max=2 default=1 value=1 , Y0 ^/ e. ?, B
* [! ^8 b; {# V( ~
- + k" q# C- }9 m! L/ G2 d2 [
! U8 I: ]% X% d7 e. }( c
sharpness (int) : min=0 max=15 step=1 default=5 value=5% H' N$ r$ p' t1 M' A* q
+ G+ ~' ?( }5 D& h( I o
- E- a6 C8 [" |, [: D3 k8 V
- W; q9 D( N, xbacklight_compensation (int) : min=1 max=5 step=1 default=1 value=1
' {% T. P3 I# H8 K6 I2 m" y1 r& F2 J0 J4 x8 l( u9 X3 |$ G
8 t, f( D a6 E) e" O) p
![]()
E2 {5 E% l2 W6 H我们使用了两种型号的USB摄像头,按照手册说明使用内置的uvccamera程序进行测试,不过都没有成功,得到的错误信息如下图所示。 ![]()
![]()
我们使用FFmpeg可以抓取视频,命令行如下: ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv# L3 M3 K: M# d
使用Windows版本的ffplay可以正常播放抓取的视频,命令行如下: ffplay -s 640x480 -pix_fmt yuyv422 out.yuv
/ _( C9 a! O7 ]0 _上面保存的是YUV格式的原始视频,如果要保存压缩视频,可以用下面的命令行: - 0 M/ | E7 U s0 {+ }6 O9 M
ffmpeg -y -t 15 -r 25 -f video4linux2 -i /dev/video0 out3.mp4-timestamps bs; m$ \! C" L% }5 e. W
其中的-r 25表示每秒采样25帧,这个参数必须有,否则FFmpeg可能会不断地采集并压缩同一视频帧。-r参数超过30没有什么意义,因为USB摄像头的最大能力就是30fps。 - g) i, A; t. P1 {
飞凌嵌入式OKA40i-C开发板可以对于1080P的视频压缩达到45fps,所以对USB摄像头的视频压缩应该没有什么压力。 4 l3 v- t4 \' Z1 a: W) h* Q: M3 C, _
3. FFmpeg性能测试 FFmpeg有个benchmark参数可以方便进行性能测试。我们对A40i开发板自带的一个MP4视频就行解码测试,命令行如下: ffmpeg-benchmark -i translate.mp4 -f null –! X/ \3 }" Y M" i/ m" ?6 H9 s
得到的测试数据如下: - 4 r5 C) s" [( e$ n- H
$ Y. h# P9 g- G; |2 k( ]( dvideo:9 O, @: t* }; Z5 r. l! I! z
' b6 b: W3 d; `- S - - Q: V2 F- [' x- \ e l2 X# d
; p! }$ q4 x: J, A148kB
5 |9 X% ~* B5 s0 f& v' K, m- t( E& Z( ~) a7 m; E
7 T9 }0 B5 u) p9 L0 v( e( H6 t8 y( E2 n
audio:
( c3 X& b. h* R% d3 U
( i8 j# S; |; c2 |: F- + X( f# o3 v$ r
/ u& ?* }8 k9 A2 R* H5 K- Y! N
3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
/ p% H- Y2 X2 P7 O9 v' p7 ?3 m$ B# h- ^) d! r4 y: s, r- ~
" H4 ?$ |; G- s Q% o8 G+ L8 M+ _2 _9 {" A# P( e% L9 x; e
overhead: 1 N, ]- y! g: P$ B
! U- E3 q3 C- P( y( k
2 F( H2 |5 _% I& f$ V0 T- B( }
3 Q5 J& t; X$ S+ P( m$ ~: f( c1 yunknown% A% ^& c6 g0 n+ I, R/ u* b5 }
# F: x) r1 u% ]9 f% _9 o# _) O& t
- , W! N( A# i2 I6 l/ K! s( b
& s+ o# i' b" j; Pbench:
6 E( o X/ S9 m5 i: j5 G. b$ Y0 d6 |2 j0 k# v: z8 C* U4 ?
- T; y* W) ]1 f: B" J
* P- N2 k; [& \: Sutime=2.820s stime=0.110s rtime=0.956s" P) h& K# j' E; c: q% R, B
- C; {+ B1 o! o0 n. C- 3 X( E8 V0 I! x, P
- \8 V' R# J2 V+ x
bench:
- Y4 [" ]% _: H) I/ w
" v0 u+ t/ v z' S8 j - - D; D2 w9 V* }: W0 e! _
/ d8 S. \4 y$ A7 b: `) d
maxrss=14208kB/ O! g; F( H: T7 y5 \: A1 O+ u
: {' G" n2 Q* P Y+ ?
7 `$ Y+ ~! v, U+ i 3 C3 S0 t1 L# x( \
由于我手上暂时没有其他的开发板可以对比,于是就通过我用了5年的i7-6500笔记本测试了一下,测试结果如下: - $ y% { |$ w4 t
5 Z. M; B2 g; n& Gvideo:
$ W V3 w6 T2 E0 J, H" C4 s& p; z; C6 t k3 ]$ i( Q
7 Y' B. w0 k% e9 ^$ ?1 W1 N
' `# B: S) y5 V/ G& w: f241kB
+ G( }" f& i& U. @2 B/ k- b% v2 K8 l# |+ J
- 4 M9 J' ]- ]* R1 W2 |
1 O3 F+ E8 K8 R8 x9 s t
audio:. S) _$ y b, N2 M
4 c5 P- f& C5 O& M
R5 @& H; \! U# Q/ U9 P) x( h; C% r, C
3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
a* k" B, f n" o; n- Q1 v3 w
8 Y6 m( x. e n4 w! F! ]. ~3 G- - X9 ?! [+ J% }
- j8 v5 v; q) g, E/ c# v# poverhead:
]$ a9 s+ Q1 O$ n `6 B2 [4 F$ ]4 D4 {, n& D- m% Z
5 W8 X0 J( A3 ?2 P1 q
1 A/ S2 T# M* Iunknown! }/ l+ J$ t# \0 y
" B: `! B9 Y( @- {& [) B9 F
* h$ ^$ x. U7 v% x
$ P7 z" i6 [7 D% p& I5 Mbench:
8 k2 i3 S9 ]; V( o5 @/ e, @6 n! t0 g
, O; Y) b' p4 b1 ?6 S
* M! V6 `/ d3 M9 @4 }5 xutime=0.391s stime=0.000s rtime=0.228s, q# R* r$ k1 g4 I& C; f N
, A" m; _' H" q* M' H4 s! Z ~- " \' K0 O6 M, U" \; I: M
& ?2 M$ f( C; O! c$ _4 P1 c6 R
bench:+ F. t. H, Q, h0 U. ?
8 `: Y6 e4 _' R% H' ?7 p
9 L1 m% D# L$ h8 |5 x# w0 o2 J4 N3 z; O
maxrss=20316kB5 f+ W0 V0 d! c# U1 Z( d
- v" I9 o# D- z& x
L. h' V( n- }) N) D+ A
' ?2 K2 q( e& [2 _2 w3 b
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:12348 \2 z2 E% \; K) w$ k4 p7 E9 [# d% |
使用Wireshark可以看到在PC机的1234端口收到大量来自OKA40i-C开发板的H.264视频流。 ![]()
+ E7 Q* I/ D$ N% ]: w7 h" g, H
' l4 ?# Z) X B( f( \( f i: \如果想在PC上显示视频流,需要建立一个SDP文件,它描述视频流中的端口和编码信息。 ) A6 e- ~6 H' B+ s* `' I- {5 ?/ ]& o
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! E8 _8 I. V2 j下面就是使用VLC显示的接收到的视频流。 ![]()
3 f! [% ]% |4 O8 G" P2 z, \
. U3 {! l9 Q4 x5. 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
: o- z3 P3 z r, C7 g$ k: A1 S |