找回密码
 注册
关于网站域名变更的通知
查看: 463|回复: 1
打印 上一主题 下一主题

用全志A40i开发板玩转FFmpeg

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-12-17 09:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

1. FFmpeg的安装

FFmpeg是用来记录、转换数字音频、视频的开源软件,它支持文件和网络流操作。它支持以函数库的方式使用,所以有很多软件都依赖它,比如VLC、暴风影音、腾讯会议等。它的命令行程序也非常强大,各种命令行选项学起来虽然困难,但是几乎能够满足日常对音视频的各种处理需求。今天我们就通过飞凌嵌入式OKA40i-C开发板保定飞凌嵌入式技术有限公司来介绍它的命令行工作方式。


+ D8 b7 |8 \* t/ D, M3 h- g

FFmpeg提供了全部源代码,所以在网上可以找到很多教程是关于交叉编译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摄像头插入开发板,然后使用


  • ( s: t4 Z8 ^8 j/ }  v# b
v4l2-ctl --list-devices
5 T# b. L( R" ?* \+ g

可以看到/dev/video0就是我们的USB摄像头,如下图。

使用下面的命令可以看到该摄像头的全部参数:

  • : U! b( @* B4 `8 q/ O
v4l2-ctl -d  /dev/video0 --all

  • 2 Q5 [3 o$ d" c1 P! K8 d

  • 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- T
    8 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 R
    5 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$ o
    6 |! 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, D
    6 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" y
    1 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可以抓取视频,命令行如下:

  • $ _5 Q. l7 v. i1 j8 ?7 ~
ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv# L3 M3 K: M# d

使用Windows版本的ffplay可以正常播放抓取的视频,命令行如下:


  • 6 }8 d3 M% |& e/ B6 T7 W
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视频就行解码测试,命令行如下:


  • 2 j* r( N& Y# j# H$ e
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 L
    0 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" C
    4 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/ U
    9 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( o
    5 @/ 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上:


  • 0 b& g4 Y; G& v- R0 ^/ W
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文件,如:

  • ! e7 n# `; @3 a9 @4 ~0 P
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 x

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
: o- z3 P3 z  r, C7 g$ k: A1 S
  • TA的每日心情
    开心
    2023-1-11 15:38
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2022-12-19 08:38 | 只看该作者
    步骤很详细,小白式操作
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-9-11 04:15 , Processed in 0.140625 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表