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

用全志A40i开发板玩转FFmpeg

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

1. FFmpeg的安装

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


" V- C/ K" O5 ?

FFmpeg提供了全部源代码,所以在网上可以找到很多教程是关于交叉编译ARM版本的。我们测试的版本使用的是FFmpeg-release-armel-static.tar.xz。解压缩以后拷贝到飞凌嵌入式OKA40i-C开发板上并设置好权限就可以使用了。


. Z+ Y4 h* w% O, U. D- L

2. USB摄像头测试

OKA40i-C开发板接口丰富,它支持USB摄像头、CMOS-OV5640摄像头、模拟摄像头。把USB摄像头插入开发板,然后使用

  • * w* a: z4 n6 x! F) ~+ ~' y
v4l2-ctl --list-devices+ p: C3 Y( G8 C

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

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


  • 6 V+ R# ?& q: Y1 {( e
v4l2-ctl -d  /dev/video0 --all
  • ' h+ k1 W, C) W4 G/ u
  • ' k' \6 T6 }, s
    ! Z' |7 m' t7 k+ |/ V+ S
    1 x1 |4 M) p& k. l( C$ z: q1 Q

    " ^5 p. C' V% f+ U2 Z! w5 Z
  • 6 R- G* P; P! G5 V

    2 v8 z+ I$ t( X1 n5 ^5 ~9 Z, Q  ZDriver Info (not using libv4l2):7 y! g  n) b& F$ m, F+ c2 x. y

    4 n" J* ?) r0 x
  • 5 }& P, V9 c7 @, N: |% T, v. j
    4 I* Z, g/ W4 u5 E
          Driver name   : uvcvideo+ R0 B! [0 P& J

    7 _& ~" _/ v$ b4 i  l$ A5 Z# v
  • 6 \' h* [! s2 W" n0 |7 m, D0 h

    ! m* _9 v! b5 [! D9 L5 ^; z      Card type     : USB2.0 PC CAMERA% C6 ^9 E: n) J' h" r  ^
    ! T6 b# U% a5 e; a% Y
  • $ t( s7 i8 m' }% O8 ]7 ?

    ; C$ Z, \/ ?) g6 b6 D, Q0 w      Bus info      : usb-sunxi-ehci-1
    5 K7 G# c: }1 \  }! I1 E! U* U3 I

    * G: k6 B9 i% t& r" m8 a; u

  • * `# B0 d+ v; D$ `, p6 Z
    1 G$ [4 g0 x. e7 P, D' ~; L% n
          Driver version      : 3.10.65
    # q. U# n' w$ G" `# p2 J# T
    3 i" b' K; p# j" X

  • 8 S; z6 K0 P+ ?* G2 S2 r( `

    $ D  |0 W$ w3 ]- q      Capabilities      : 0x04000001" v7 p) L- n% I! [8 z4 V+ f$ V
    + ~6 C) p) M2 p. s
  • 1 S- c) |7 z$ Z
    $ k( s/ T" i/ s* P2 n
                  Video Capture+ p# H: w6 q1 h, N: m

    : k6 A5 M- y% `6 t5 C

  • 2 Q( c/ T: y$ U3 W; T% i1 E
    1 R& `, ^2 i* g
                  Streaming
    % m- X- B  R9 G9 H9 ?! j7 w

    . N* [; Z/ d7 F5 O  ?# X
  • + M- q  ~5 Y% M7 B0 O3 b1 X
    8 M( k% o! Y) Z
    Video input : 0 (Camera 1: ok)1 H1 |# u4 t4 `4 g% G0 V9 ^
    , j8 M4 P( U! U5 M& B* ?6 b; k
  • 0 R0 `$ S, r4 k" ]" G& R4 [8 L

      c/ C8 }1 E, Q  t1 \, cFormat Video Capture:
    * p' q0 W; H+ p6 t6 M# A7 O% _

    # E: Z- [' h2 B9 p1 m! }
  • # {. }0 @' [2 o8 r1 V
    ' T: S! q! @( P; Y& y5 a: l6 f% G
          Width/Height    : 640/480
    ( q2 u+ V: a% t. t: h! \3 E
      G, T3 s7 \6 v, R" y* A

  • ' z8 Y" ^1 f. A8 k1 X3 U

    9 h  K# u, o1 c      Pixel Format    : 'YUYV'
    ( S$ m5 j3 P$ a. h2 b4 Z3 ?

    3 |. ?( P6 i9 Q1 g, _4 R
  • 4 F/ h3 N; M& B- U
    9 Q$ o% Z5 ]% O- E) D( L- m$ h
          Field      : None
    % O( [  e7 |# O+ z* Q
    6 C8 k* ?' N# X0 p9 z0 t
  • % `; P; O4 s) n4 d/ \& J  j, @

    8 P. ^" G/ f+ r4 I5 m' |4 f      Bytes per Line      : 1280# w& V- @* ^, S- T+ b; S
    - @3 Z# m5 N' i

  • % T! N  D2 \3 i
    1 c+ @" F7 t: @9 y7 n
          Size Image      : 614400+ H- i$ {+ g0 j( n

    0 d$ K1 v( @- Y% u  k' T
  • + |) s, a# ?) i: k8 Q9 {
    5 }5 o& D" N! _; R
          Colorspace      : Default4 w' q9 a$ k8 D: A) ?: y
    , b/ m1 Q3 o! H& Z4 }
  • 7 \5 u3 a/ `. p
    , {- l8 v; h! |7 z8 N/ C
          Transfer Function     : Default+ Z3 l% ^& J! V* U, j
    2 n( @% {- Y' u& F( Y

  • # S% D3 V1 \- p# N+ {2 F

    , e5 x' s6 K8 X8 q! z* t      YCbCr Encoding      : Default
    9 b9 Z% W& `: N4 i

    8 Z9 U8 E' x; q2 L: D5 x
  • 3 W7 t, ]# W% f8 y% \
    ( u- ^1 V1 n( i6 w4 J+ n$ t( n* K" g
          Quantization      : Default
    9 e3 c, {6 _% E! M! o

      m. k$ ?) [. @' U- z9 L/ B

  • 4 @" Q  C" j6 ~- W. \. @
    1 E: ]3 b# w+ s' I7 @0 z
    Crop Capability Video Capture:
    $ G  V* n" V- t6 D" |
    5 c6 h. D3 V& d/ `* p

  • 7 B5 _/ f6 w( X# p

    , a, w# W  r: N: N4 `8 H      Bounds     : Left 0, Top 0, Width 640, Height 480
    ( r) |; N* l! u+ N# w! G

    8 q5 {- p4 E1 V" n* D) M) S
  • ; c& A+ {# d6 M. i7 U$ e
    & O  p) m7 W1 ~1 [# m
          Default    : Left 0, Top 0, Width 640, Height 480 0 g. r$ g* n/ m  |9 b- O
    ' E3 k! {5 W$ f' h5 g) Y
  • , D% f% U7 h* N
    ! o3 ^( \9 \: e7 \; s1 c
          Pixel Aspect: 1/1
    & c7 n0 P' p" C( _' x

    8 W( ?: K5 F# A# x" |
  • ' \7 m. o, m9 g1 W' X  h9 o
    * ?" w6 H& ~" l3 T: Y) [
    Streaming Parameters VideoCapture:; |, V- y  R2 r

    % D. U  L1 b& z  B& M
  •   B- ^  k7 B6 l* v

    0 E) y2 r8 T+ z& Y3 M( ~5 Q      Capabilities    : timepeRFrame
    5 x# i5 N5 J( |0 l! @$ X
    - a+ ~- d( v' X* ^
  • $ V% B/ I$ _! x
    7 a$ R' `) H' [5 y
          Frames per second: 30.000 (30/1)
    4 L5 n/ Z( h( B+ K2 O
    , Z4 O- p6 i* S' p7 d

  • ) ^6 Y5 Z, Q0 ~) {+ H6 g/ q! c/ B

    9 |1 f* i- ]! E8 I( f      Read buffers     : 0               
    3 d, D. S: B. G6 T

    , B/ u4 i; y) V9 l" |
  • ; v! G, m6 C  ~7 u7 o. o! i3 A3 P
    ! t+ T) z8 e) l( O) I
    brightness (int)    : min=0 max=255 step=1 default=128value=128               
    , C; r0 ?% j7 K4 ^, p4 O4 `

    9 k5 U( b" U* C7 q- g! R; f' ^! G

  • % @" I+ O1 j8 L0 F
    7 M4 k7 }8 Q1 _4 t% \) {
       contrast (int)    : min=0 max=255 step=1 default=135value=135                 
    ) q" U) `3 y% p  _+ b$ o
    ' P! X, g' l5 n/ j' D  M

  • # r) v. ?9 }: O; o
    # j; E' X3 `( j0 I' C1 s
    saturation (int)    : min=0 max=255 step=1 default=75 value=75                 , H; p2 N; c, \$ P, O0 o2 G- [* ^

    1 i+ p6 D' a! I% b
  • 4 v4 t  [. m: i* p3 X- @$ [

    3 ^! Z3 b/ Q" y/ n        hue (int)    : min=-127 max=127 step=1 default=0 value=0               9 S# r$ I7 V" ]! t' i( o7 u9 F, _! ~

    : S- V6 j  t% X- d
  • 9 ]* v0 s9 h+ u4 [1 }* `
    0 {* X1 ?5 k# o/ }1 W9 v
          gamma (int)    : min=1 max=8 step=1 default=4 value=4        
    * ]7 V6 \2 g( S' G6 G

    ' j/ |% d/ T8 b0 i' X
  • & M, L! ?" S) z

    8 J, m) o& L% U6 I* @# @power_line_frequency (menu)   : min=0 max=2 default=1 value=1                 
    ' O7 u9 `% `1 X5 j# f5 a1 r

    1 Y/ s" L" h9 l: R8 D+ _. ]

  • ) z5 q8 x; C: J! Q' B) _
    0 s. L2 u& a- H
    sharpness (int)    : min=0 max=15 step=1 default=5 value=5; C1 `$ N4 K$ v+ l1 h0 |( _

    7 [7 ?3 `, P5 r+ g' O8 T

  • . |, j5 s4 J0 k" G" c
    8 B' Q9 q8 F/ z, p8 _2 }3 M% a5 T
    backlight_compensation (int)    : min=1 max=5 step=1 default=1 value=1
    . e8 N2 F1 j8 c' z3 I* }6 I9 @8 E

    * L0 U$ Q2 A( V9 }
    / d# X: K1 I. E
! ?# T4 j. t" m$ g* C

我们使用了两种型号的USB摄像头,按照手册说明使用内置的uvccamera程序进行测试,不过都没有成功,得到的错误信息如下图所示。

我们使用FFmpeg可以抓取视频,命令行如下:


  • 0 l9 M$ o  c5 h1 A  p
ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv
! N! _( S3 l7 i" T- w' _/ M! _) j% Y

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


  • - I4 v! K5 c8 Z6 _* u
ffplay -s 640x480 -pix_fmt yuyv422 out.yuv
1 I8 [1 c( g# V1 r

上面保存的是YUV格式的原始视频,如果要保存压缩视频,可以用下面的命令行:

  • , [; V/ W3 W6 A1 q
ffmpeg -y -t 15 -r 25 -f video4linux2  -i /dev/video0 out3.mp4-timestamps bs5 \4 M& i/ n# Z  {

其中的-r 25表示每秒采样25帧,这个参数必须有,否则FFmpeg可能会不断地采集并压缩同一视频帧。-r参数超过30没有什么意义,因为USB摄像头的最大能力就是30fps。


! q" R; [4 y0 H0 V% |' @% g

飞凌嵌入式OKA40i-C开发板可以对于1080P的视频压缩达到45fps,所以对USB摄像头的视频压缩应该没有什么压力。

: d' R: l- j' o9 W' V1 V: s

3. FFmpeg性能测试

FFmpeg有个benchmark参数可以方便进行性能测试。我们对A40i开发板自带的一个MP4视频就行解码测试,命令行如下:


  • ) u% ^$ L9 i% C9 \9 P; ~0 h
ffmpeg-benchmark -i translate.mp4 -f null6 H" F" w  r$ }* Y/ |1 Q! K

得到的测试数据如下:

  • - p1 E9 j% L, I* \
    $ w; ?% X7 J/ v. @1 _' E! p
    video:
    7 v  ?6 |: M! T, f. V$ \

    : }/ `4 i  \9 w) K
  • + a3 B- B, n& Y& P/ Q

    . R/ i3 l5 t2 {1 I3 V8 c: }( p148kB& ~" }- d; p& h# q( f, e

    & E" F5 z% c! Y- k  B

  • ) v$ {( J. H& G0 |0 D0 e" B- Z8 A
    % R# C* {& _. `
    audio:
    . s5 p$ [) d7 M. j1 S; o7 R1 k
    % }5 Z& `2 k2 O9 k; v. ~, z
  • 8 V) i  A2 i; _7 n4 p) o
    ' T* F. {( e% k$ k4 t' n9 V; L
    3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing, _6 W, b0 q  N+ Y+ U# K5 J( U
    - P# E" o$ A0 f% g

  • / ]% d) W) b# T! v- i
    2 ?$ E" b% I  v/ P0 H, E
    overhead:
    ( _9 x" L# ]" Q' H1 ^, `

    " j! d0 j& c$ o! Y% M0 y

  • ( L  [; q+ M1 e; T, g' f
    ) N2 a* Z' k- ], D6 Y8 V3 y2 f
    unknown
    ; z' F' n0 ]* o; I0 p
    ( E* h1 ?  {% H$ J
  • ! \! a$ z9 \$ y1 b% u0 N( Y; I  Z: K

    # h6 p6 k% M4 z; fbench:
    0 |/ Z. ]! m4 J* L, I0 |0 O
    $ J6 M; Z0 Q7 h# m/ ]
  •   ~+ \% I) z5 {* `' ]* ?( `
      {0 x0 g! r! C1 V  @/ h' Q# i
    utime=2.820s stime=0.110s rtime=0.956s
    $ a; z( R3 A. X/ r" ^) u' _& A) T

    % X3 B* `2 H% Z; D

  • 4 t  L7 z8 ^/ p+ Q" G& v3 b

    % M# L+ j/ [$ H# f/ Sbench:
    ! Z% g4 a# {+ H4 ?

    # l3 p9 ?, T& W$ X/ A$ {' i

  • + r( R. ^( z5 u; I, f
    6 N( _2 @: g/ H7 K
    maxrss=14208kB
    : p3 o% P3 n# u  ]) F5 G

    " X7 K- }+ \. V# E0 ^0 w/ y6 `( ?/ @, x( b6 T2 M

5 r0 Y4 l6 ]) I/ J4 x3 m, F

由于我手上暂时没有其他的开发板可以对比,于是就通过我用了5年的i7-6500笔记本测试了一下,测试结果如下:


  • & o9 Q  b8 {' Z

    ) `7 g6 {) `; ~# i: q. m2 o$ q/ Qvideo:+ Y. t( @* s# X; A7 W0 y- q

    , K' |- C4 I3 b/ d5 O0 P& ]) [* q

  • " c3 z; z. B5 X% ]2 z
    * L2 e. r1 k3 L& x$ C/ \( ]8 V
    241kB
    * {+ q' E& f0 Y. v4 b& T; ?
    2 R: @# k4 R' A- {

  • 5 `! x) `( p1 X$ H2 I/ t
    ; ^2 i5 p, c+ H; w
    audio:
    7 ?! M' Q+ f) E7 F' ?8 ]# r
    2 q  k! o1 u5 J! a) w( [! ~7 e9 ?
  • + e1 b/ }# f+ u7 ^( y+ P. K

    ( G/ b$ X) u8 E8 u5 |3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing
    ' h1 D) h/ E9 G" _- o

    1 p$ g/ g) r  @# U8 @7 k

  • 9 M7 t; d% ?) I9 ?! w+ S1 \5 Q9 m1 W4 X

    / U3 M9 p" G; p" i) v& Zoverhead:
    . x1 c5 @, t$ X! M& ^) M. G
    * \, m5 {- q% n0 |; o4 _/ M, {

  • 9 D- V; `$ }6 b) n
    9 E7 Y  T4 W) |7 k
    unknown9 y4 K6 Y7 i0 R. k

    ' n$ G% w9 T: }+ U) J* G
  • 0 ?/ n8 s# y& \0 T
    $ }3 P( `8 S$ y7 A
    bench:
    * p! y2 L/ s8 i- _- }
    / w7 b; n6 J2 w% t

  • - O/ X6 Q9 p. [2 M

    / @6 o2 P- Q0 B' s* P6 jutime=0.391s stime=0.000s rtime=0.228s, @* M* L) Z! r+ Z) L% n

    5 }0 j9 v# Q3 Q
  • % Z! [3 r' G! v0 t! ~  B

    ( M, [8 n1 N! J& `* Tbench:
    3 {" U7 i$ k1 h( @' I; g8 N( t

    # x$ F. W! i& A( _! S' ^

  • 2 {" M3 `/ `3 o7 O) [; U

    1 [: {: j% f9 ~' M/ W* Pmaxrss=20316kB6 l* [: |: H( p7 |

    - G3 H$ {- `- [+ Z' x8 H# k1 w" e, K& Q4 h$ D* J- b( [
2 Y9 L7 i+ Q2 B* ?! o) q

4.  FFmpeg产生实时视频流

FFmpeg可以支持实时视频流的发送和接收,从而可以把OKA40i-C开发板上的视频实时发送到PC上,由PC上的软件实时接收并显示。我们可以使用下面的命令将OKA40i-C开发板上的一个MP4转换为RTP码流发送的PC上:


  • 0 L( n3 Y& d; Q) T
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234
0 F" D" S3 p$ U: [

使用Wireshark可以看到在PC机的1234端口收到大量来自OKA40i-C开发板的H.264视频流。

' E% b9 \- ~4 E+ i& O. Y: l3 @
! v) _5 _2 I: t% G

如果想在PC上显示视频流,需要建立一个SDP文件,它描述视频流中的端口和编码信息。


1 T/ J4 f0 g1 {- \& L3 n6 {

SDP是来自SIP标准中定义,目前VLC、Apple QuickTime和ffplay等很多软件都可以打开SDP文件,并按照SDP中的描述显示视频流。SDP文件并不需要手工编写,在ffmpeg运行时它会显示命令行所对应的SDP定义,如下图所示。

也可以用重定向将输出写入一个SDP文件,如:


  • $ z9 C& r# o  H; V& k
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234 > rtp.sdp
) n$ w2 D- a: I8 q* G4 s

下面就是使用VLC显示的接收到的视频流。


4 q* a7 V  e" ]. F9 o% P. ]$ S5 B- F/ [, V5 K6 e$ M

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
7 b. v  b0 H3 ?* ]
  • TA的每日心情
    开心
    2023-1-11 15:38
  • 签到天数: 1 天

    [LV.1]初来乍到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-23 15:56 , Processed in 0.156250 second(s), 24 queries , Gzip On.

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

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

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