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

用全志A40i开发板玩转FFmpeg

[复制链接]

该用户从未签到

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

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 \% S

2. USB摄像头测试

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

  • + R  E0 R1 |- c) K
v4l2-ctl --list-devices* m5 M, Z  N8 ~6 V$ I% j  r

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

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


  • $ d) {1 n3 p; w9 |$ X
v4l2-ctl -d  /dev/video0 --all

  • 2 r# C7 ]; n. L" z

  • . 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 _+ c
    7 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 o
    0 {4 D5 l8 k4 Z4 o' y2 v7 G. {/ M

  • 6 p/ z) j7 z$ J! T  \) H+ I  `6 l
    4 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视频就行解码测试,命令行如下:

  • 4 [+ V' {8 j2 m
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/ S
    6 \) _  ]. 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. a
    9 {* 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% L
    1 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" K
    6 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上:

  • ! \  S! _6 H8 _6 |
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: v

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

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

  • ; q7 s1 Y" h) ?/ o: B" f
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 Z

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: n" C& _% S/ f9 D
  • 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 21:08 , Processed in 0.171875 second(s), 23 queries , Gzip On.

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

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

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