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

用全志A40i开发板玩转FFmpeg

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

1. FFmpeg的安装

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

1 A) F: f" k0 r+ E

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


: s3 W0 H2 @+ S# @; j$ x

2. USB摄像头测试

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

  • 6 A- F) Y0 U) l$ F% h9 p. M, O
v4l2-ctl --list-devices
6 \2 W% W7 ^+ ~0 L$ ]9 a4 J

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

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

  • & _. w1 k% E. e  \
v4l2-ctl -d  /dev/video0 --all

  • / Q" e: R; o7 A' z, i

  • 3 W* b$ a0 k, w7 F
    2 s, v4 X$ |, @3 @  t

    & G' I* ?5 Y' ^: o

    ) [: A8 ~! \& m' K5 U

  • . R# b4 ~* X8 B1 b$ R
    % o+ Q: K* [( F6 t6 ^
    Driver Info (not using libv4l2):6 ~* B# Y% f$ `  ]2 y4 Q! J* [

    / z& s& F& i  r- J: |5 [$ e, K( m
  • 6 y' S0 z1 |/ f$ J

    ) n/ f3 @' Q1 O+ {      Driver name   : uvcvideo. C3 q( X! c% N7 C1 n% e
    - x- \: B. m2 |* d+ c
  • , {2 q  X" t3 M' z' |  Q0 @
    - Z, W& d$ _' U& s) s* o0 D2 M' _
          Card type     : USB2.0 PC CAMERA7 a& y6 b& l" D% {0 [2 M4 m1 }

    5 r: O3 A" N5 T) O* ]
  • * K# a5 @% S& u! A
    : U! d4 m; k1 ~
          Bus info      : usb-sunxi-ehci-1$ O: n7 v2 @# @3 ], J6 |4 [

    / F0 k6 D# [, w" H# t' N

  • % P0 m2 Q+ f  O; m
    : E# ]8 t' Z9 h0 Q
          Driver version      : 3.10.65! [9 V9 T4 r/ P
    5 Z3 @; W$ j% c5 Y& [
  • 3 T8 B! Y/ W( h+ B) f
    0 k; _: c: R4 q2 U1 b4 j  j
          Capabilities      : 0x04000001. `2 p) h# x' _7 F

    / L% b# s7 L8 }" i

  • / o2 ^# N3 h" f- E* H8 t" Y  m
    4 o0 Z; I6 n3 [" K, H; M% b, r
                  Video Capture1 c; {1 c$ y, k% d3 q

    : h. h6 u- U, ^+ T- J2 a, I
  • 7 V. T' v4 a% @3 Y

    - `! c6 F3 o$ S: q0 D$ s; `& Z' ]              Streaming* I' j1 Y9 D4 s
    9 N8 r. x1 h/ ^- y7 o

  • : @, v% P& @5 m7 K$ R& \$ A
    ( ?/ p* N+ _. J2 l0 @2 p/ T9 Z
    Video input : 0 (Camera 1: ok)
    1 \# L. y- `' j8 p4 E1 e
    ' h) G' l  c1 N. R

  • , Z, e3 }6 G0 o: V4 ^6 e
    4 t, E3 L  u! b9 X9 \4 K
    Format Video Capture:
    0 c1 d& K, }* ]; m; C' H
    # J" n2 |7 f. }# K2 p, m
  • 9 V: t/ I: X% n- E1 Q8 s
    ' q* J9 v+ M+ g
          Width/Height    : 640/480" o8 p. g' e: g: A7 U& ?+ c

    & |  c' w7 r" R% I( h8 H/ e! ^
  • , J  O8 K( `# y. L. V& x

    4 q7 a, |" b2 T8 n$ A4 Y      Pixel Format    : 'YUYV'0 i! Z) k# n( m" M$ I! ^

    2 I; ~1 }+ I: ^
  • / }# I; k3 v7 ^& Y

    8 J, `7 t) i) @  E+ c6 j' P8 x/ s      Field      : None
    8 p, y& ~  o5 ?; \+ M* D

    ( U2 b' I- |9 R( c; B/ r

  • 4 Y9 x: Q. G5 H5 q

    8 R7 C, Q3 O$ T1 O. R$ p- m* H      Bytes per Line      : 1280/ G/ O! y3 A) D# u" U

    6 N1 i4 B7 u% Y' d
  • & I; n1 h: E) n6 s5 t; |: C9 U

    / i8 s$ s1 I# X- ?" w- u6 b      Size Image      : 614400
    * d0 d' s3 D$ [4 h) r& {
    : \- I- d( [( E; y& F- w9 n
  •   ~4 z1 e# {$ r) z; ~" o% u
    + ^, _. W# Z! c4 r% ~/ V" P
          Colorspace      : Default9 c7 l$ J# U2 r" }8 B
    " c, D8 _8 _1 X' M, P
  • 4 S0 M1 M2 b6 Q6 G  ?3 ~8 g

    2 @0 b* s( z5 ?/ Z      Transfer Function     : Default3 O6 o: f2 y3 C: w

    7 U( d7 G& E3 o1 }( ?4 M" D

  • 7 m' \, W) X1 U( J

    2 J/ U$ x0 p5 a0 `! T6 N      YCbCr Encoding      : Default
    : s% b) ?8 a, S1 s) o
    ( A2 f/ x8 d% H1 f& ]6 y: _0 q
  • 8 t/ S' }' `1 k- j; X! \3 v9 I9 B3 W
    ' d) M* Z1 R& M$ ?" F* W+ ]( C
          Quantization      : Default
    * v( i* @4 d( l) a( X

    * C: U3 J* Q7 \6 s; A  @# Y" \
  • 3 f) |8 a( C* N/ x  r

    , D- T, V0 m7 bCrop Capability Video Capture:  n1 y* x! U. ?% E1 ?
    : A4 C4 @3 C% o% A& N
  • 9 r3 s0 o1 V1 ]. R: u6 Y

    : W$ r, u' O* i& H+ X      Bounds     : Left 0, Top 0, Width 640, Height 480
    3 L2 ^' K2 n" V8 f; K4 P' _4 s
    7 [3 Z( @7 A* u( A# \
  •   P; B) w, C' E2 V3 M

    $ ]/ o& a; {% y. Y. f0 R      Default    : Left 0, Top 0, Width 640, Height 480
    ( R  [- N( O' E9 z  f/ o) x
    * P- u8 m5 _' D
  • % I9 j" u; t( \( L) I5 r" N! Z* z( A
    / J( @0 y2 G& w/ j4 \
          Pixel Aspect: 1/1" o+ S( ]2 U. M9 h% G. E
    ! D3 Z% F% h+ ?2 _; S
  • 5 N  W2 e  j, X2 V1 o( C: P# ~, j
    1 I" g3 v$ d3 W4 ^* T" g
    Streaming Parameters VideoCapture:
    8 x8 Z. K# ?/ N/ b6 B8 }2 o/ k

    0 C/ ?, m7 U' c% u0 g

  • $ F7 R& o5 x3 @% k5 n! c

    " F+ F  J6 F  {' O* o, E- n      Capabilities    : timepeRFrame ) h( v: u& C1 d' {' S
    4 r+ S& a) b$ Z. S' P4 A5 t4 L
  • % }# T# c5 {9 ~3 b
    6 a+ _5 P# m1 r% O- i$ A  k2 L: O
          Frames per second: 30.000 (30/1)
    # B$ D) S9 ~7 w
    5 d( e" l" {* E) J; `: z  ~
  • ; N* L: \- K( k' q
    / B* d4 \* H1 P8 W* U3 e7 N
          Read buffers     : 0               
    5 o2 o* I) t8 ?, G7 |3 A3 K

    & @: \+ M4 C6 w3 G9 w

  • ( k3 H0 a, j. v" [
    . D0 Z+ }" d) k3 y+ H
    brightness (int)    : min=0 max=255 step=1 default=128value=128               & w& B# [  K" Z! W3 M9 P

    / K6 ~' g: |( h, i7 m. J' p. f9 H4 V

  • 8 y$ R) o$ j$ o$ o
    . N) [' [, D/ p+ e
       contrast (int)    : min=0 max=255 step=1 default=135value=135                 
    $ `1 W3 D5 {" _- n) Q# x8 w% W
    : Y( Q+ a/ c. L

  • # \) b  Z( e% t

    * l. R$ c0 Z: ~" V7 u saturation (int)    : min=0 max=255 step=1 default=75 value=75                 ; V- Q! X0 `2 V' s. B4 D  z
    : g. g; _5 L: F0 D# s% v

  • ; R1 L' r) K3 N
    $ ]/ c: F* E! T4 r0 N
            hue (int)    : min=-127 max=127 step=1 default=0 value=0               % m) t' g' l0 n1 s3 L
    5 X* l4 c; L4 p, i3 F4 ~

  • ! t/ a" D0 I# d1 Q

    : o% T9 b8 B1 c8 k% j      gamma (int)    : min=1 max=8 step=1 default=4 value=4        1 }  Y! ~# l- ?% D% Z

    + F" J7 `! a9 s. i2 h, V+ ?7 N

  • 9 b) S! z' {; o. Y7 p+ p" L9 O

    5 ?* v$ d  G( t7 ]3 D  K7 \: ^6 S1 [power_line_frequency (menu)   : min=0 max=2 default=1 value=1                 
    % r1 S* M$ w9 _) }. H  Y

    ! r" t* Y" u3 H5 C/ a8 [
  • . T6 \$ S7 ~# n, o

    0 g, n% ^, }: w7 K9 l  |" z. ?sharpness (int)    : min=0 max=15 step=1 default=5 value=5& E2 V! T  B5 g: a; Q' b+ e8 |
    + N1 Q6 J3 `% S  d+ y3 A' C9 [: d

  • 6 v7 f% U; h) c3 ^8 x! \
    5 G; O. {0 Q! k1 j
    backlight_compensation (int)    : min=1 max=5 step=1 default=1 value=1
    ; u, D. S; e+ J" @5 T
    6 J9 z8 k/ m' ^  \* w6 T
    ! q0 e( H; V) P3 y/ _
$ J6 g, `* D9 R

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

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


  • " K" O- i, v5 B
ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv& P. R, ^% s$ S

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

  • 7 y8 K3 k. ^" m; Z- g1 {
ffplay -s 640x480 -pix_fmt yuyv422 out.yuv8 B1 y! S" K6 e1 M/ u5 E

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

  • " I' a7 D1 A" O/ C, u+ v4 O
ffmpeg -y -t 15 -r 25 -f video4linux2  -i /dev/video0 out3.mp4-timestamps bs
+ @+ H3 C- F" P' q  _! j9 v

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


( l) f% U0 P; V* B

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

' \# i9 U2 _* |8 |- s/ x

3. FFmpeg性能测试

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

  • / F' u7 |/ d! l: }# Z8 k. n
ffmpeg-benchmark -i translate.mp4 -f null
$ d8 R8 R4 H* H; C. K8 c, S' a6 i

得到的测试数据如下:

  • 7 F# R' m6 h% y  J& _
    3 I- S( W) B0 n  Q" \
    video:6 t' C0 M6 I  }, ?+ C# \
    # `- Y$ K# W* U$ e
  • % U; Q1 W' N& S

    # }$ B8 G, }" ^1 H! C, y148kB' s+ }1 A+ ?& M5 J: T3 i) C
    , |# J2 T  l  K; X" }. {

  • % f# Z' P  ^. f: d! q) {8 y# t
    2 p) Q3 `7 S& k- R
    audio:
    % j: ^5 ]1 H$ k. c2 z' d$ R) W

    ; z( |( c" S7 [5 j5 U! t4 A, t4 _8 P

  • 5 o; D; {- K% _! u3 H, y

    ; O& C0 e3 l; x- P7 P6 m+ \. c3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing' z! T  i- X7 I" p: c! }/ U; A( A- e
    8 F- V& q# m  N2 ^9 C
  • . V, h7 j6 I% p, k+ \; ~" F

    ' C- t7 q3 v& g' Foverhead:
    ( x! o5 J, t4 o+ w# ^5 a* S

    7 R) |, K; p9 O" F7 J5 A( ?

  •   P6 f: x, `2 i& U5 B4 Z

    % p' J5 X0 U# C+ R2 k" Cunknown
    ( r6 \% z4 U  G- Q4 S% z
    " Q/ R( v* ~* }& k* Y

  • 0 m$ Z+ V1 [/ `, v5 h% j$ F( L

      X- x! g8 Y3 M0 obench:! A; f6 N4 n' G/ W" L
    " ?  i% p% A# a. e. K; K, o+ I( L

  • 8 q4 Y, z8 x9 N7 m; f

    7 F: \! M. p, G4 L. T* Y) T% Xutime=2.820s stime=0.110s rtime=0.956s& F5 b, m- n% P9 S6 E
    / ^; H4 w' j# K. ~8 o; t

  • & H5 f3 \9 _0 {$ v# {7 X4 j* c

    - m" U/ V# D* i. Mbench:
    " H! e1 m" E+ [

    , [/ H" `! b, L3 w5 a2 a

  • ' _/ g: L' T. f- _# c% h6 Y. ]! n
    & n$ T2 w/ ?8 D0 H- y- w
    maxrss=14208kB
    & F6 @. m- d3 v: g
    ; g: v" I/ T9 M' O, y

    ! |  U/ W+ n. V5 e0 K3 a) C
! L( L$ w% T: a5 J; Z

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


  • # @5 l, [" W) ]+ J
    ) W2 W  [/ N) e  a8 Q
    video:
    ( ^4 s. e' Z3 j% V
    4 D/ @; y4 j& C
  • . H- i( A* D  [; K

    8 A; q5 s: T' w3 i: [241kB% B  N; {# v/ Z" l; i8 H
    , y: d6 N# ]' R. `# K
  • 2 ?8 W! v* G. O. A

    $ X) r7 u8 x3 C; |audio:
    ' q5 t1 {3 k) C6 x# ]
    - L  F/ ]+ F+ G. ]' U  h+ F6 O) h
  • $ @" X9 l" `  \, v; M% B
    # C3 M4 N1 S& r" }
    3428kB subtitle:0kB other streams:0kB globalheaders:0kB muxing$ @" y1 W4 S4 b$ I

    5 ]% R" u1 `" U* j$ V7 Z; I' d3 l

  • # o! J. N: c5 S: s: V) G/ B
    & S% J& c0 l; _& X: K
    overhead: . P9 Q: M1 `" b' G5 ^

    / l+ {0 o9 E$ k# O$ X& \4 @2 ~
  • * Z: L, `5 r* ~7 I, D8 Y. V

    , m$ P  D( d7 tunknown% |& j9 i( h/ l/ x! p+ A* y

    5 U5 B* d1 s- C3 b. N3 P

  • 6 p6 j8 d7 c: _5 p, w+ |
    . Z; u1 s/ w9 i  U. R  N/ P
    bench:: t, k1 g7 i3 u8 C. c9 z

    ) m) E. |! c8 V, W
  • - U, @1 x# H5 l
    ! L+ o5 E! _  z0 \
    utime=0.391s stime=0.000s rtime=0.228s0 T: A+ f3 Q' G% b8 u

    8 E, n  y7 b# c+ c
  • ! x4 T3 _5 }, ^
    9 }/ |9 i; \. {
    bench:- q% m; q( p6 Q# f% a0 L
    3 K( A0 Z; U6 z4 w

  • ! K3 b6 L9 Z2 D& ]- c

    5 ]$ c; B5 f# S$ Zmaxrss=20316kB8 f' @0 H- Z# N& M. k
    & _: |( f1 Q9 N5 m

    7 k1 I  y& M# Q% U: D

% T; ]9 f) x% E) G9 M3 t

4.  FFmpeg产生实时视频流

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

  • " T9 O3 y; r1 F' u) l2 C, g1 w
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:12340 g! l1 C7 G; }& l% v/ H, U

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


6 a  V1 a0 D% q& U
) `$ E  p5 x, H# v. w- h5 n

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

, ?( S# ^7 q& c: P

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

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

  • 5 j; W3 I3 |- A" @- [# ?
ffmpeg -re -i test.mp4 -an -c copy -f rtp rtp://192.168.0.105:1234 > rtp.sdp
/ u7 W0 v. i  L, l; x. W

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


5 [! U( Y9 I- R% E6 n) m
$ g  ?5 A, T# ?" b* L) R* ~

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! ?+ m; ^9 i$ U8 l* t! M) o
  • TA的每日心情
    开心
    2023-1-11 15:38
  • 签到天数: 1 天

    [LV.1]初来乍到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-24 10:24 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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