|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# K& p$ g5 g/ M1 l0 o1 q网络上盛传的基于mini2440的摄像头监控一般是基于 MJPEG-Streamer。
* Y! e+ S% N/ j
0 q$ F6 U7 C5 n) `4 E+ H这种方法利用的是V4L2的底层驱动,然后配合mjpeg这种格式的流传输,然后通过浏览器浏览视频和控制。
' ], Y# R* w; i' c# X1 k2 L& o
& S s( C; j7 G8 _下面用一个更接近真实的IP-camera的方案来实现。 T; y# Y3 B2 C* F
* |# Y3 p1 H; v ?1 t7 Q这种方案是用的V4L2的视频驱动,然后配合ffmpeg、x264的软件编解码,通过udp上传至pc显示,视频的编解码真的非常麻烦,幸好有很多开源的编解码库可以使用,几百行的代码就可以实现h.264的流编码与传输。
# a" v0 v7 B: g7 _7 I
4 ]* u( M7 O( {- Kusb摄像头得到的数据格式一般是YUV422,如果用的是cmos 摄像头可能是raw原始数据格式,YUV422,是在raw基础上色彩抽点编码,因为人眼对亮度的敏感大于对色彩的敏感,所以并非对所有的色彩编码,这样的数据量会非常的大,视频编解码格式就不讨论了,很多很复杂,当然,你会了,就不会觉得难。' s, u1 ?$ a9 ~
" P, j2 e- e4 i: H7 a" a# Y
ffmpeg和x264的作用是将YUV422再编码成H.264
7 z4 I* O1 c v: W+ [& j! S, d* a c" e: i$ ?8 X' d
9 R* T- Q: ?+ P6 ^8 r8 M
上图看效果,这是在linux中接的图,窗口中显示的是从2440usb摄像头上传上来的视频
# i, H; `8 d" o+ q, k0 F" @$ y% q: H# P# b3 _7 t
4 @' ^4 Y% j7 L g1 W' a# P$ @
2 Z6 P+ O, _$ i% Q* _2 G3 O9 S! z这是实物图,手机拍的* `7 g+ N& K% b V( F
. A( P& U1 Z5 {, G
# P6 n2 j! F. h% x# t+ @' O5 G3 ^
0 J$ [# _ J3 o3 K废话少说,一步一步实现
$ N7 {7 H& {3 \
, x( p/ T( s9 C7 W1 m/ h# J1 U# w1、平台+ U0 ~3 P) r4 w) n: s
; u- G9 x7 g; w) p! p+ Z; }' D硬件:ARM mini2440,usb摄像头4 |8 }; G D. R# j W( ^+ A3 k
& b7 z( P2 e. ^
软件:fedora14,arm-linux-gcc v4.4.3
$ L3 u3 Q6 f$ h6 z3 D2 [2 {" v) ]3 t) S. ^3 L5 r$ H$ u
2、源文件
8 J: u8 _3 O- Z" q! c6 `4 k$ N: O1 v2 n" c1 n5 K" w! M9 @
ffmpeg-0.10.1.tar.gz) m% l3 H4 ^% \0 V6 I" w2 s
5 Z. {# ?) J- I6 z7 D
last_x264.tar.bz2
. t/ i2 S8 O+ Y7 vzlib-1.2.5.tar.gz (mini2440中没有libz.so,但是程序运行时需要这个库支持,所以下载源文件交叉编译)( V0 Z" a7 M& w, E( I4 I
以上文件只要会搜索的人都能找到3 Z) ]: _+ U! T) A
) B" P! Z( Y0 [( Y2 @! f9 U
下面开始交叉编译,编译过程中会遇到几个小问题,一一解决
% k' P. w, o* ^% r [+ }: k1 n" y: m+ P. G) X4 x
1、编译zlib! M5 _3 Z% P# j
. A K9 V0 t7 ~" j& r n8 ]7 o: P# a( w解压zlib-1.2.5.tar.gz- y( Q8 ]& x7 i5 }' \5 O3 u
4 |$ [& P% T5 M4 u* {7 R#tar -xzvf zlib-1.2.5.tar.gz
. O S6 v; m1 ^) {6 X G+ C) N# Z5 v* t
进入源文件目录
$ H9 ]4 G) Q' a' m7 [* W
4 ~0 v# Y! d+ }#cd zlib-1.2.5
* z1 B+ s! W7 v" a7 w& Q& b% n3 a; b& q. _$ E9 w) X: R
运行configure配置makefile/ W- s1 [) Q; n* B
! v* V& t2 L) K1 t" M6 W4 ^5 o7 k#./configure --prefix=/opt/webcam/ffpeg# ` B3 k5 y, n% f
! _/ }1 a, P/ b8 n( e
--prefix=/opt/webcam/ffpeg的意思是最后执行make install时,将文件安装在/opt/webcam/ffmpeg,不然会默认安装在/usr/local/lib中,其实这里不写这个参数,最后一起在makefile中修改也可以的。
$ M$ m5 Q& ~4 c1 j0 H
% j6 L+ H9 o: M配置后会在当前目录下生成Makefile, @' d: n3 y! ?; ]) N$ m
7 `0 e' ?& v$ E, i9 W4 Z, t
修改Makefile以便能够用arm-linux-gcc编译,其实就是把gcc 改成arm-linux-gcc,ar改成arm-linux-ar等
& w* H: y) h1 w" s* J) ^- ^: n$ F0 T1 \# q: ~$ g. l7 W! i# I+ V: m
下面是改好的makefile部分
# S: a+ X9 k3 x1 X6 q. H3 v/ J+ @4 I: r% h
SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1% @) J0 ^5 G& G! N' N% n% V# a- D7 L
LDFLAGS= -L. libz.a
6 i5 z$ }. g* UTEST_LDFLAGS=-L. libz.a6 q& d/ c5 c2 `4 y! W/ E G1 |& V
LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
! ?8 z- a; W: ]) r" h$ wCPP=arm-linux-gcc -E9 k6 H5 b6 X# J2 B, b' V) U
7 m0 U9 \ [( x/ s8 D
STATICLIB=libz.a
# G/ @9 K7 h% [/ OSHAREDLIB=libz.so1 |- f% p2 Y9 ^1 }( x/ V
SHAREDLIBV=libz.so.1.2.5; V4 ?5 o% P$ T: T7 e8 ?5 X/ x
SHAREDLIBM=libz.so.12 o5 b, {/ T0 u4 f' v
LIBS=$(STATICLIB) $(SHAREDLIBV)
* i* y+ d" _5 h2 K; X9 I1 c# q, O2 n3 Y/ j9 \8 A; v
AR=arm-linux-ar rc
2 h1 B8 O* K4 ]6 [RANLIB=arm-linux-ranlib
) m# H2 _5 R) a8 F$ B( n: C) PLDCONFIG=ldconfig3 F3 X/ Q1 I- B- d) S7 R
LDSHAREDLIBC=-lc; G7 K' y' m. J" H
TAR=tar/ j2 P5 T! |9 p' y0 O
SHELL=/bin/sh0 \7 W; L! u& _3 R' s; _# N6 w' b
EXE=
! l. b" J" v& G! r9 F
( U/ R- E, U) z& W+ v% W' t* k rprefix =/opt/webcam/ffmpeg8 Y+ S! }/ U* C
运行configure是的--prefix 就是最后这个参数,这里修改也行的
( f: I0 e) T1 d f$ j% X然后make,make install
$ p" r5 e q u D+ P$ f0 v
& W5 @( r! y# ^% z#make& w( ~0 d9 k c
( |9 G! d4 i0 U. ~
#make install: D, @$ E+ Y" ~' e$ z' L
- V2 V$ X1 `1 U2 c& g3 [$ D
zlib的编译应该不会出现问题,在/opt/wecam/ffmpeg中是编译好的文件,在子文件夹lib中的.so文件最后要复制到2440里
F& t/ i6 c J4 V+ x# E4 M; |/ _6 Z+ y
# l7 r5 K0 H' Q+ O& \& I* B2、编译x264
8 H- X8 R- x _' p# y4 C- B2 I
1 H: Y" ?! y+ z3 D3 B# _( g. U& q应为编译ffmpeg时需要要添加对x264的支持,所以要先编译好x264,一边让编译ffmpeg时能够找到它
3 h$ ~6 m. ^1 r. @7 O4 ?
% R! }' M" x: s: n* e a解压last_x264.tar.bz2( g/ f' g I1 o! D
6 V& ]* Q/ {, S
#tar -xvzf last_x264.tar.bz25 Q/ k" r1 n* m# d
! Q0 D3 Z: z7 R5 W( @#cd x264-snapshot-20120316-2245
4 C/ x5 `8 T7 g/ l6 j5 K
8 B" ~8 [( x' k6 N, _7 i# ./configure --host=arm-linux --prefix=/opt/wecam/ffmpeg --enable-shared --disable-asm0 t1 B% J: B% {' R9 b& c' F8 _( u) o
9 ]/ U& U$ q$ r3 u
配置选项中已经添加了host的选项,所以makefile就不用再修改了,但是要修改config.mak
2 [% G# n8 h. a. A) o' _! _( I. H+ V: m4 \* \. L' } J; K9 v G
SRCPATH=.( r4 i6 A7 |! G
prefix=/opt/webcam/ffmpeg
- O1 C* o9 m! {6 [% m+ I; ]exec_prefix=${prefix}3 C8 ~/ A( o/ G3 n8 E2 M# X1 i
bindir=${exec_prefix}/bin8 r) H9 D* y" N& |( ^2 N
libdir=${exec_prefix}/lib+ s0 t( E3 r" h# R2 _1 y
includedir=${prefix}/include: P% O: O4 d* S3 z# k8 r! ]* F. p
ARCH=ARM
$ ~+ r$ v( @- B# X3 F( l: CSYS=LINUX
2 G/ y' l% Z2 t/ S1 HCC=arm-linux-gcc) v l3 N' N- |5 `% t) L% ^
CFLAGS=-Wshadow -O3 -fno-fast-math -Wall -I. -I$(SRCPATH) -std=gnu99 -fPIC -fomit-frame-pointer -fno-tree-vectorize& T2 l5 J. ~ }6 Z
DEPMM=-MM -g0/ Z' K8 u5 s5 h/ G1 ~
DEPMT=-MT
: }$ k9 O% P6 T3 r2 L7 T3 ~LD=arm-linux-gcc -o
1 R5 }2 E# A# e7 ?5 t' |8 ?9 rLDFLAGS= -lm -lpthread& {0 q1 \) ?0 w$ Z @! f
LIBX264=libx264.a1 }2 F3 e7 a. z' ?
AR=arm-linux-ar rc
% J3 k5 n8 w; T. Z4 yRANLIB=arm-linux-ranlib
3 A% v/ i" P0 n# O5 J" qSTRIP=arm-linux-strip
9 O2 D; J4 N/ U3 P1 T8 V#make) ]8 \' I6 D6 p7 K
$ a' J0 l3 L3 t
#make install
: p9 g/ l; w1 E
1 u9 w% q' h3 Z3 {6 S3 }; X( kx264编译也不会出现问题的,如果有,把之前安装的pc端的x264全部删掉+ f' m) H- K8 v% U) H
7 D5 X& {" a! f/ Q# Q9 v5 u
: r5 {. ]2 x3 H# g& _, R3、编译ffmpeg
! L, ]5 y9 Y+ _. s. m6 |1 D- W9 T/ V/ J' r. f" @/ n! G" {
解压ffmpeg-0.10.1.tar.gz
$ u: J) H( m% v2 D; v9 h+ k
7 I; t9 N% ]: x#tar -xzvf ffmpeg-0.10.1.tar.gz
% S- F+ Y8 G! K- T' z# R
3 F8 C( h1 E# Z- Y6 ~/ I& u#cd ffmpeg-0.10.1
n5 {4 d4 O7 u) C& ` P
# I9 E- E( k) |5 c( [. N, i7 z0 P0 d#./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/. l6 x$ h: P" f# p
: T/ D+ D7 ]# j2 k8 X, V配置需要注意的是--extra-cflags=-I/opt/webcam/ffmpeg/include --extra-ldflags=-L/opt/webcam/ffmpeg/lib/ 指定x264库的位置
2 X! W) _, I; S! o, W2 v) \1 }; J- P
#make1 N# m" F# \! m0 h' u2 a% B
+ w! p2 i2 B# Y$ v( c- }
#make install
0 `- C* N, P) L+ j8 a- `! i* {3 L9 q5 N% c
以上,所有依赖的库就都编译好了,下面编译webcam应用程序
6 e# i' X% o$ Q5 U5 ^4 s
; ]& F3 e" x# n' i6 V! X5 ]/ c* f/ V6 _) l" w7 d
所有的源文件不做除了修改udp上传用的ip地址和makefile文件外,不做任何修改,源码存放位置/opt/webcam P0 |9 G/ m6 j( f: b3 h+ t
! n$ P9 g" ]% A1、修改server.cpp ip$ {$ v6 X( c: x i7 m
8 z/ F* w- |* b2 F# R0 a
将#define TARGET_IP "192.168.1.220" 后面的ip改成你的pc linux的ip,依旧是客户端webcam_shower所在的pc的ip地址# h5 i4 H- o- W9 @# c# f! W: ]
3 i4 U- |" w+ r" m+ i
2、修改shower.cpp中的
6 {7 u8 c: z @* a1 o3 ^: j9 P% U3 S' p8 f6 Q/ C# G+ U" \
inet_addr("192.168.1.220"); 将ip修改为pc linux的ip,就是自己的ip,socket绑定端口用& S {5 L) v! v+ ~
0 f2 Q. V$ U( s$ ]/ E( g3、修改makefile,以便交叉编译webcam_server,注意,之前编译zlib x264 ffmpeg都在放在webcam/ffmpeg中了
7 S7 A* G* M2 [) h+ A, q: U. S- h; \' A
all: webcam_server" j9 B; }& u; W9 h6 ]/ _# R5 q
#webcam_shower
: J' g, Y7 h% f) ICC=arm-linux-g++& a- Q! T$ K/ b( J
LD=arm-linux-ld
. r9 h2 K. U5 _0 CCXXFLAGS= -c -g -O0 -fPIC -I./ffmpeg/include -L./ffmpeg/lib& |& q0 A% |$ L r- w0 a: K. c
8 X5 b% [8 w. F
OBJS_SERVER= capture.o vcompress.o sender.o server.o
8 |2 X+ j/ X G( a+ |OBJS_SHOWER= vshow.o recver.o shower.o# x2 @8 }: |% H( G) W. b* z5 M
LIBS_SERVER= -lavcodec -lswscale -lavutil -lx264 -lpthread -lz
- J2 U h: R$ A0 m& w* Y; [% ]3 nLIBS_SHOWER= -lavcodec -lswscale -lavutil1 T$ {1 `, w" i1 `; }+ q: s$ Y/ ]# H
% I: I. Y2 s% O/ j7 e2 a4 ?
.cpp.o:4 k, ^ H1 }( l% S2 e! X* [
$(CC) $(CXXFLAGS) $<' ~2 {6 W, R& @
& v* O1 C6 z2 z2 O' r: }webcam_server: $(OBJS_SERVER)
4 M) h( n, k' j1 o c $(CC) -o $@ $^ -L./ffmpeg/lib $(LIBS_SERVER)
& ]0 J% b& `; }/ ]
8 u2 F0 h$ }% e' }5 |webcam_shower: $(OBJS_SHOWER)# F$ R* a; c* I: ^6 g
$(CC) -o $@ $^ $(LIBS_SHOWER)
T& j+ |% `2 P5 u
2 {* G& _% ` R$ ]4 Zclean:
6 i( X c# S9 E; w9 O. C rm -f *.o
( r6 m9 Q, a# p) d. u* V rm -f webcam_server
, ] N6 B; u5 Z! z" I rm -f webcam_shower0 g# _+ I9 `! r. v9 i
! J* P* L# d0 s ?; g) o#make1 a- `& }# [! s$ W% d% y
这一步会出错,报c与c++兼容问题,在include/libavutil/common.h中添加如下,即可
2 {' s+ U* X( M! }, d7 o; r
! M$ H+ i0 H1 l7 G' g0 v$ e7 A/ e. v& ~#ifndef UINT64_C
4 M9 u* |+ K' B8 O8 Z5 [1 D" g! Y#define UINT64_C(value)__CONCAT(value,ULL)4 K8 X% X3 j" ~
#endif
: o; [7 }+ `$ ^$ g0 U; p9 F. X+ \( u7 t9 a) `7 [ T+ d0 O6 U3 S
4 D. Z( s$ x. _5 C9 S最后就得到了编译好的web_server了,将web_server复制到mini2440中,并且将之前编译的第三方编解码库/lib下的所有.so文件复制到mini2440的 /usr/lib中
1 j( C+ b, m3 c$ D3 g% O {, s& U8 w& j( r1 `
插上usb摄像头,webcam_server就可以再mini2440中运行了8 v/ y4 E0 D' H& I& d
( o, a' b0 n2 b* W- m! v' z% u, _2 z7 v" h! b
最后是编译pc端的webcam_shower,这个很简单,按顺序从头编译就好了 |
|