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

arm mini2440 基于v4l2 ffmpeg x264的视频远程监控

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-2-1 18:34 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

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

x

( @3 k9 ~- j2 ^; `网络上盛传的基于mini2440的摄像头监控一般是基于 MJPEG-Streamer。( g9 h; Y: G$ L

- T4 T! q; Y1 o7 w8 ?; D这种方法利用的是V4L2的底层驱动,然后配合mjpeg这种格式的流传输,然后通过浏览器浏览视频和控制。
' ~3 ]4 ?+ \$ j6 X9 Q1 M! O- a* m1 r. g6 u3 Y" c
下面用一个更接近真实的IP-camera的方案来实现。
( Z. ^/ @) o* W! T7 ~# M) s
, f, [% [$ u( |# f% Q( X; n这种方案是用的V4L2的视频驱动,然后配合ffmpeg、x264的软件编解码,通过udp上传至pc显示,视频的编解码真的非常麻烦,幸好有很多开源的编解码库可以使用,几百行的代码就可以实现h.264的流编码与传输。
2 G' @: v0 u7 Z+ F( }5 g! h$ O6 j9 A
usb摄像头得到的数据格式一般是YUV422,如果用的是cmos 摄像头可能是raw原始数据格式,YUV422,是在raw基础上色彩抽点编码,因为人眼对亮度的敏感大于对色彩的敏感,所以并非对所有的色彩编码,这样的数据量会非常的大,视频编解码格式就不讨论了,很多很复杂,当然,你会了,就不会觉得难。
" U; B6 U% h' v) O. F+ d
* o+ D& B7 l% H- J- p) ?6 [5 k8 L/ effmpeg和x264的作用是将YUV422再编码成H.264
# r7 A' Q& ]$ \, y( u, M1 P1 ~2 J. p

+ d: g! B3 N  k& ?) [, g6 D3 c+ V上图看效果,这是在linux中接的图,窗口中显示的是从2440usb摄像头上传上来的视频# T( X  A& f: G2 n3 S% ?

2 k9 Y) J  S7 o9 e
  {& ?& c' l; V
3 w7 A, Y, `2 J* N2 c1 S/ N* A7 U这是实物图,手机拍的
+ N& k' Z2 }/ o9 {. a0 y' f: J4 L
4 h* o. l# g7 ^; ]$ ?' C4 p8 s$ B
, J( e' f6 d7 l) J, [$ E
7 j6 ^4 O+ B0 L- _7 g) P% O1 A废话少说,一步一步实现
$ n) n6 Q( Y7 y9 k. F# q" B: w3 {- G7 o" X
1、平台
2 i4 {0 T( B& z" g& R" T4 ?4 s7 l& m5 Z* b' l
硬件:ARM mini2440,usb摄像头* _9 R4 D, A  ?" [

( s5 k: }. p6 m, W9 c软件:fedora14,arm-linux-gcc v4.4.3
8 G. L; {: h/ V. w! `  S! `  ]! Y# c7 q: _5 X/ P7 D
2、源文件/ g2 r8 q  A! K0 t: E( L/ o
& N+ Y' _- ^4 `( N& b
ffmpeg-0.10.1.tar.gz
- c3 h8 [7 \, s2 i2 `9 w! y! k6 r1 a$ G9 ^" s. }
last_x264.tar.bz2
% s6 G2 b& v1 |" A% U! ]zlib-1.2.5.tar.gz (mini2440中没有libz.so,但是程序运行时需要这个库支持,所以下载源文件交叉编译)
: T$ O$ m7 m1 _: S以上文件只要会搜索的人都能找到
, \$ |7 J' ~) n" [( {2 ~; N
6 ^% x: h3 d4 v$ R下面开始交叉编译,编译过程中会遇到几个小问题,一一解决* H/ ^! v& i) u

2 z4 N, Y6 _; o/ M& o1、编译zlib
; L: O1 J  q* q9 p- a
) }+ K# B: O( J0 u% x) q解压zlib-1.2.5.tar.gz
" E8 d1 J( {$ s. Y$ B: m/ h$ I3 c9 A. D' W4 K) s# Q% `
#tar -xzvf zlib-1.2.5.tar.gz
2 b3 B/ `5 p7 d5 P! p/ [9 v  A* j$ _/ A9 ?4 h# U: H0 t9 o) W$ m  S' h
进入源文件目录3 M1 W- F2 x% T7 N! D$ C  G

9 m5 g( \4 o, }3 A" v. T. Q#cd zlib-1.2.5
; f8 c4 X5 |6 h- ^; U: x0 k: r
! v% u) `. F. ?运行configure配置makefile
  D6 ?0 L! G9 `" F( D+ Q6 A6 D$ R2 u7 A6 A6 n- p  v2 i
#./configure --prefix=/opt/webcam/ffpeg
0 c' a, A; T$ F( ?$ A8 F0 V$ c: \$ T; A
--prefix=/opt/webcam/ffpeg的意思是最后执行make install时,将文件安装在/opt/webcam/ffmpeg,不然会默认安装在/usr/local/lib中,其实这里不写这个参数,最后一起在makefile中修改也可以的。1 M. c# {3 Z% P, L6 g
0 G* S) Z' S5 L% W7 L6 Y. Q
配置后会在当前目录下生成Makefile
/ L* J9 v  o! i2 Q% K$ l& l2 c# N8 }; y0 f
修改Makefile以便能够用arm-linux-gcc编译,其实就是把gcc 改成arm-linux-gcc,ar改成arm-linux-ar等+ K9 E' S) J, G0 ~% y3 c

' D& c0 @% b" \; J) q下面是改好的makefile部分, K- b( ~1 ]' L4 }& w* _5 ]/ o+ C; N
% N3 d: o- H0 T: y& J* H- {
SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1
* x, p+ l/ v0 }. ?2 ~LDFLAGS= -L. libz.a
3 I" \* j* \. [3 a' k; qTEST_LDFLAGS=-L. libz.a  v) b6 X& x: s' m: n
LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map& r/ i" j: o! ?9 }' P$ `, g7 Q
CPP=arm-linux-gcc -E6 F# m0 w" {7 O3 |

% M, q) W/ O0 J, a2 u( C+ USTATICLIB=libz.a
( z) @" t' e! \9 _4 V% DSHAREDLIB=libz.so+ B4 Q9 j' Z6 A5 Z
SHAREDLIBV=libz.so.1.2.5
4 t- N6 X+ Y( \; }' tSHAREDLIBM=libz.so.1
% {1 l0 ^" m3 ?: o3 H6 OLIBS=$(STATICLIB) $(SHAREDLIBV)
. ?) }2 l, |! Z
) H( O# N) a) I$ kAR=arm-linux-ar rc5 x5 p& F  z  M: `/ l6 a% |
RANLIB=arm-linux-ranlib
! W! c6 q* V7 i' d7 U; y$ t* m  xLDCONFIG=ldconfig- U' n1 S; ]' w$ V% p
LDSHAREDLIBC=-lc# b/ x; M  \; ]
TAR=tar( w4 `" _7 M6 w: ]
SHELL=/bin/sh4 {  W* i5 S& X9 v
EXE=& M5 O& e: \4 n% M2 [! o
3 t+ \- G+ e6 r/ N0 m. }
prefix =/opt/webcam/ffmpeg1 z- l4 ]/ Q8 j# }& F; p
运行configure是的--prefix 就是最后这个参数,这里修改也行的
, S# |5 _0 P+ c) w' I2 B然后make,make install% @6 i; ^  ?7 B' K
: F- k  J0 p7 x" `3 p" Q$ q: @( A* x3 P
#make7 Y+ O+ V  N9 w  }# n5 T0 t

6 x, j& L; k/ p; q/ v#make install' w( h0 |' l/ |* g# r$ a. i

" a: v3 b) {/ Kzlib的编译应该不会出现问题,在/opt/wecam/ffmpeg中是编译好的文件,在子文件夹lib中的.so文件最后要复制到2440里
( ?  L/ q8 ~8 A! ]0 a, L1 b/ F7 N% q  N
6 h* d* Y% g" R. J+ M8 W
2、编译x264
% Y' o+ K5 a/ q6 R7 k6 `. }6 _! X
4 I% Y7 p) x. X/ B% @/ {8 i应为编译ffmpeg时需要要添加对x264的支持,所以要先编译好x264,一边让编译ffmpeg时能够找到它( r% i+ o4 ]% o2 f3 Z* _
  ^* f. c+ x3 t1 I! b
解压last_x264.tar.bz2
# B' ^" i9 u+ e* o! n. K! N( o' o, {
# @" N4 g5 p( o0 m, w* g#tar -xvzf last_x264.tar.bz21 V- ?3 U; j1 e

- h& W; D5 I8 A% l/ A+ Q#cd x264-snapshot-20120316-2245
' g4 n/ I) W1 x
8 K) O6 X/ r6 H7 {& U# ./configure --host=arm-linux --prefix=/opt/wecam/ffmpeg --enable-shared --disable-asm9 w1 A4 R8 a% n5 ?

9 h  A+ h" i9 D1 ?配置选项中已经添加了host的选项,所以makefile就不用再修改了,但是要修改config.mak7 G' X- E0 N7 s1 Z2 p; h
! W8 f& G- l/ \) Q8 l
SRCPATH=.
% o# w4 R" Y  l" J! ^prefix=/opt/webcam/ffmpeg
9 ~' s/ F! x+ o7 Uexec_prefix=${prefix}* Y, o& R% Q& }
bindir=${exec_prefix}/bin7 `5 h' `& b; v, {( o1 _
libdir=${exec_prefix}/lib3 c+ c1 ]; `6 t7 d" e! Y0 n
includedir=${prefix}/include! ?5 p7 U1 |  o! y3 ]; c
ARCH=ARM3 j, Q4 r# p7 k% e. Y
SYS=LINUX
' p( E' Y$ Q2 F7 v( n: KCC=arm-linux-gcc
6 k5 R5 i8 f" k: |4 n/ _: W* `1 P8 L" PCFLAGS=-Wshadow -O3 -fno-fast-math  -Wall -I. -I$(SRCPATH) -std=gnu99 -fPIC -fomit-frame-pointer -fno-tree-vectorize0 b. b/ \0 ~. b3 d6 |
DEPMM=-MM -g0
: s7 c4 T; j# TDEPMT=-MT6 P- r( [6 d+ b! W1 c' k0 ]
LD=arm-linux-gcc -o * ^& A/ Y1 e( g
LDFLAGS= -lm -lpthread
: ], ~" K; \4 D" a# G1 yLIBX264=libx264.a
& H, Q7 ?, z& s* J* A: O  GAR=arm-linux-ar rc
( r; J/ ]/ z/ M) eRANLIB=arm-linux-ranlib& s4 W6 o( E- I! u7 `) F2 [- A
STRIP=arm-linux-strip7 B( L2 N: L8 _4 a* v8 [
#make
5 ^# `4 A. D* }/ j* `# d- r6 q; S2 u6 j" l5 `2 V$ @; f2 W
#make install3 X5 r, r4 Z  }6 q

& K% J0 V, w/ s4 z) l" j  w, Hx264编译也不会出现问题的,如果有,把之前安装的pc端的x264全部删掉
& d& ^! u6 B& Q& [! Y) |) v2 P9 u& k: a5 h0 i$ I
& N, D& {4 z/ N( G' @8 T
3、编译ffmpeg
7 }3 Y. A; O. H* o" F" z) F8 [( A  A: B5 W* B$ P. X
解压ffmpeg-0.10.1.tar.gz+ U* L* r" e- D( R$ T3 A  @
% j3 {/ l/ G" y8 D3 t9 P
#tar -xzvf ffmpeg-0.10.1.tar.gz
+ k8 U2 r# ]# x% e9 d& X1 s8 w+ P! C  N6 E- j
#cd ffmpeg-0.10.1
' G1 O+ H# `# g! o' M/ S; I- M
/ q6 q9 i8 u- a7 W3 t& `. ~( h#./configure --enable-cross-compile --target-os=linux --cross-prefix=arm-linux- --cc=arm-linux-gcc --enable-shared --arch=armv6 --enable-gpl --enable-libx264 --prefix=/opt/webcam/ffmpeg --extra-cflags=-I/opt/webcam/x264/include --extra-ldflags=-L/opt/webcam/x264/lib/8 V5 |1 I- ?  P* p4 r8 _

; C$ t3 C2 k+ s0 I配置需要注意的是--extra-cflags=-I/opt/webcam/ffmpeg/include --extra-ldflags=-L/opt/webcam/ffmpeg/lib/ 指定x264库的位置
7 A) a2 {5 V& ?; `$ c5 k* x
% c2 U% M) }$ Z6 P  V#make
" U* C" ~. }% I5 b/ |0 y
! h3 ?; Q% y4 i# I& x" f# G#make install
4 g* W! G* ~0 N* g2 v5 o/ f3 d  e
# E0 B$ e3 h# ]$ Q$ h以上,所有依赖的库就都编译好了,下面编译webcam应用程序" V; [8 T; S1 w8 j2 d
+ P6 f0 n" R/ x9 V/ q" ?

8 n4 r( v8 z$ [& K0 M& }  ]( b5 A所有的源文件不做除了修改udp上传用的ip地址和makefile文件外,不做任何修改,源码存放位置/opt/webcam% C' E& U  V+ w& n7 B& i0 @. t# h

+ K1 E+ p, F+ \) S4 p" x; m1、修改server.cpp ip; x# S9 s% k+ e( k, R9 @: A+ ?

7 p) w+ A' b0 D) H+ {7 V- n1 f  s将#define TARGET_IP "192.168.1.220" 后面的ip改成你的pc linux的ip,依旧是客户端webcam_shower所在的pc的ip地址4 k( H1 o  F/ V; t2 K( H, `

. f' B  T3 {" N2、修改shower.cpp中的( x3 a5 t' J2 o
7 }9 N( X; a! I* x
inet_addr("192.168.1.220"); 将ip修改为pc linux的ip,就是自己的ip,socket绑定端口用' v; w# N7 \- R, M

2 }3 c+ J  E0 H3、修改makefile,以便交叉编译webcam_server,注意,之前编译zlib x264 ffmpeg都在放在webcam/ffmpeg中了. ~5 R+ y* }& Q* ?' _
& ?7 l" J, @! k' h+ J: d3 C
all: webcam_server6 Q6 l; q$ i2 c
#webcam_shower
' v' Q9 o3 E0 G9 W. L8 l' ~+ p# \! XCC=arm-linux-g++" i! p4 V1 s/ Y
LD=arm-linux-ld
* H, h8 i* c4 u" W1 `9 ^CXXFLAGS=        -c -g -O0 -fPIC -I./ffmpeg/include -L./ffmpeg/lib
( w: a: m7 ]- K& I3 f* Z" t4 Q# |: @4 K2 ?; A4 j; M% d# L& ]
OBJS_SERVER=        capture.o vcompress.o sender.o server.o
$ G! @. O7 {3 H5 {; `2 NOBJS_SHOWER=         vshow.o recver.o shower.o0 X. B6 j/ P5 e0 Q+ E
LIBS_SERVER=        -lavcodec -lswscale -lavutil -lx264 -lpthread -lz! n% F$ Q0 _! A/ J4 P
LIBS_SHOWER=    -lavcodec -lswscale -lavutil" x/ _2 K' i8 z4 x& i' R

! N( W+ R$ Q5 y5 C! s7 ].cpp.o:* t/ j0 o. z4 {4 n( c  q
        $(CC) $(CXXFLAGS) $<
9 i" ]; h# N; E; Q
6 |- H7 B7 Y. R- P1 Lwebcam_server: $(OBJS_SERVER)' I9 A! [  _# I2 @. i1 ~( Q5 I1 w
        $(CC) -o $@ $^ -L./ffmpeg/lib $(LIBS_SERVER) 1 l( ]4 p' K" ]: P- a) J" W5 ?8 O

$ D' ]; {, `" u/ f" awebcam_shower: $(OBJS_SHOWER)3 T7 F) J) h' [! R
        $(CC) -o $@ $^ $(LIBS_SHOWER)# h0 R0 f  g3 t# A
: y1 c/ Q! X' S/ y6 N* G9 L
clean:
) F. H, v; m3 e4 Q        rm -f *.o
/ c' `& J5 h4 D% l        rm -f webcam_server
( J7 O% k6 n: ?- n" Z0 ^        rm -f webcam_shower% G; Z) k& B0 C% x4 Y

- j5 e: E$ u* `7 b- F' Y, s; b#make
* Q( `, g  p) Z& o- e3 W, q这一步会出错,报c与c++兼容问题,在include/libavutil/common.h中添加如下,即可
; u: e. C/ r0 I" ]  U- ]4 z( M. g. F. W! l- s* Q0 u
#ifndef   UINT64_C
4 N7 w/ @" j; ^: k0 b6 b#define   UINT64_C(value)__CONCAT(value,ULL)( w' a9 w( s7 K" N6 ~/ t
#endif
: \: L- S" [: H- X$ i& s2 j# L/ N% z' R* m/ x) A: v
# p- I* ^& S. Z
最后就得到了编译好的web_server了,将web_server复制到mini2440中,并且将之前编译的第三方编解码库/lib下的所有.so文件复制到mini2440的 /usr/lib中
) M6 |: D+ z& p: j
  y5 I4 T" ~+ S& I) i6 M: ~* T插上usb摄像头,webcam_server就可以再mini2440中运行了
1 v  W" {+ y- L4 _7 m8 N% ~2 J8 J, a5 M" [0 E" {0 b
. f$ q4 D, p6 u- x, q; s
最后是编译pc端的webcam_shower,这个很简单,按顺序从头编译就好了

该用户从未签到

2#
发表于 2021-2-1 19:02 | 只看该作者
arm mini2440 基于v4l2 ffmpeg x264的视频远程监控
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 22:42 , Processed in 0.187500 second(s), 27 queries , Gzip On.

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

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

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