|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
" V, k! t1 L. u- f; ~. V( H3 [网络上盛传的基于mini2440的摄像头监控一般是基于 MJPEG-Streamer。
1 F' c. h) O( R% i6 t) h, J0 S' E) H
这种方法利用的是V4L2的底层驱动,然后配合mjpeg这种格式的流传输,然后通过浏览器浏览视频和控制。
4 |7 ]- a/ U5 j
2 Q+ {- J. a& G( x8 L下面用一个更接近真实的IP-camera的方案来实现。5 h5 v7 z" S5 T" h
P4 x+ m4 N/ g
这种方案是用的V4L2的视频驱动,然后配合ffmpeg、x264的软件编解码,通过udp上传至pc显示,视频的编解码真的非常麻烦,幸好有很多开源的编解码库可以使用,几百行的代码就可以实现h.264的流编码与传输。
# ?( w7 K1 }9 T3 g2 ?
" l7 |. m5 h7 @: D' Vusb摄像头得到的数据格式一般是YUV422,如果用的是cmos 摄像头可能是raw原始数据格式,YUV422,是在raw基础上色彩抽点编码,因为人眼对亮度的敏感大于对色彩的敏感,所以并非对所有的色彩编码,这样的数据量会非常的大,视频编解码格式就不讨论了,很多很复杂,当然,你会了,就不会觉得难。
: }: i; N0 N! r) l" _; p+ b) h# t x f$ g5 ~- g
ffmpeg和x264的作用是将YUV422再编码成H.2644 O/ a3 w4 p1 W, L2 b. ?
- c* [5 Y) K2 V
[( P/ u5 d8 u( r' f/ D. W. ?8 i上图看效果,这是在linux中接的图,窗口中显示的是从2440usb摄像头上传上来的视频
$ g4 G/ a+ Z9 X9 C, X. U1 l) P' \
4 n$ n! F5 v- d& k* l
& z z# a) @7 Z这是实物图,手机拍的
' Y1 i& M. I7 D
0 C5 _! M/ Z+ b- [2 _. Z. C/ I/ R
; q" ^+ U0 j" z W* Z. S7 v7 D' c: x
废话少说,一步一步实现+ q+ `# x0 P! A4 p- `
$ {! k* s. R t9 K/ s0 M3 k; o4 r& k1、平台" d! L2 Z4 M# ?) l2 |8 {
' I0 r7 b8 A5 b; c, y7 t硬件:ARM mini2440,usb摄像头
* M0 I1 k# y8 O: p! ?
9 A! L$ V% J7 d8 n0 n) ]9 {0 D" x软件:fedora14,arm-linux-gcc v4.4.3
0 Y2 x( r' n: ]+ L
- @( D: D$ y1 v2、源文件
+ r# b o. q3 c6 o* c# [& x$ q6 E- [; e. i- K" |
ffmpeg-0.10.1.tar.gz+ V6 w* [9 [- {% X6 n2 e
2 p7 t# ?( }4 P! D/ o/ E9 alast_x264.tar.bz2* d. G) g0 j" V8 B
zlib-1.2.5.tar.gz (mini2440中没有libz.so,但是程序运行时需要这个库支持,所以下载源文件交叉编译), G( Z" ]9 j& u5 z2 Z3 `
以上文件只要会搜索的人都能找到
; x8 x t% ?% u* b D! R# ]
- `$ S- t/ t# j0 L下面开始交叉编译,编译过程中会遇到几个小问题,一一解决$ m8 i2 r( X: m8 m8 Z) N
, H. q! q) ~1 i: B& ?
1、编译zlib3 b& T; s( @3 a' j
4 S/ N- {4 K& N9 S( L; a8 B解压zlib-1.2.5.tar.gz
2 o6 Z: U- c f5 D: y6 \4 {5 _; ?: Y0 Q' Q
#tar -xzvf zlib-1.2.5.tar.gz8 G) o I4 |. l0 G' s6 g# E
7 m; E ~6 J9 Y1 J0 x& H8 `
进入源文件目录
& x& Y, s1 ^0 U0 s0 H/ h- M
" e( |% L* b1 O2 B#cd zlib-1.2.5
# x5 W/ f. B& ?7 }& [" }! E+ u6 K' ?. c' t% z# L& x) K" J
运行configure配置makefile/ Y. [0 E) s0 d" _ B* c
?" A0 q8 j8 k. d1 d#./configure --prefix=/opt/webcam/ffpeg( V, ?: u6 V+ r. t9 X$ i! J
/ B" T( v( M9 _, [" Y c+ Q
--prefix=/opt/webcam/ffpeg的意思是最后执行make install时,将文件安装在/opt/webcam/ffmpeg,不然会默认安装在/usr/local/lib中,其实这里不写这个参数,最后一起在makefile中修改也可以的。6 A0 A3 j8 p, x
2 O! _% a5 N: t/ Q1 r配置后会在当前目录下生成Makefile
T* G1 z M8 n- B/ }3 V# E0 C- z3 I3 o6 y6 Z& l
修改Makefile以便能够用arm-linux-gcc编译,其实就是把gcc 改成arm-linux-gcc,ar改成arm-linux-ar等
: X2 u/ E* p4 n
' g; `7 O3 P& W0 H$ n9 k% _下面是改好的makefile部分9 _& R* a+ V$ t% d% p
) k4 p6 N& Z, c3 BSFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1
/ \; d2 ] z* }' ~3 a2 bLDFLAGS= -L. libz.a
5 V0 u& y' u, j' z' E( D' S& aTEST_LDFLAGS=-L. libz.a5 O9 Y0 ~3 d. i6 z* E7 U
LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
) t( x0 Y o. g5 R& ^CPP=arm-linux-gcc -E
; C8 @ H( O3 p, ^8 `* q @1 \
+ m( J" e4 M% J6 E% i# G3 B; i/ V4 n# K; _STATICLIB=libz.a% c( C# z% d! q/ b8 C
SHAREDLIB=libz.so3 y& i; R( c" [0 i- Y
SHAREDLIBV=libz.so.1.2.5
( _; V+ t3 r* U- ?* |SHAREDLIBM=libz.so.1
& G6 |% z9 K. z0 I9 BLIBS=$(STATICLIB) $(SHAREDLIBV)
1 L& v! c! J9 }7 J6 A# [* k& f
6 T0 U% F1 H$ o0 A6 e7 m* `6 k$ UAR=arm-linux-ar rc C% ]2 D* J7 n, i
RANLIB=arm-linux-ranlib% ]: K% _3 w* i6 r
LDCONFIG=ldconfig
u2 I* I1 d! Y5 YLDSHAREDLIBC=-lc
V3 `; v/ p4 h5 n/ k# [" aTAR=tar
, i. W% Q& ?+ C5 R) WSHELL=/bin/sh2 Y! a7 l3 w/ z7 |# g
EXE=$ M4 x. Z+ L; W/ v
3 b% h' I- K$ W. X/ U& y8 eprefix =/opt/webcam/ffmpeg: p- ~& b3 j& @( T8 c- i; S
运行configure是的--prefix 就是最后这个参数,这里修改也行的
& \) M5 E6 Z. P" O( u( Y' ]然后make,make install
5 P/ W9 d/ ]( _! ]
0 J! g4 _ ?7 C- O: \/ ^3 G. @3 ^#make3 H$ ]6 I# _8 v# x! X
4 {4 Y- G. l& ~. m0 D# E
#make install3 |# q) W0 F: H3 h( i$ W
0 ?% u0 l) _ }8 l' t5 I1 @( U
zlib的编译应该不会出现问题,在/opt/wecam/ffmpeg中是编译好的文件,在子文件夹lib中的.so文件最后要复制到2440里
- m- r9 _; r/ Y1 B' @4 G# q- s; f1 Y
. i; s7 ?% B: {) ]# ~
' |0 v: T' N E! S5 D7 {: S) w% F2、编译x264' n, q* z3 D" _0 Y
! ^ h/ h8 [! v; p$ N) A应为编译ffmpeg时需要要添加对x264的支持,所以要先编译好x264,一边让编译ffmpeg时能够找到它# d' S! o5 p2 M$ |
4 i5 x1 U( `. A8 c3 f
解压last_x264.tar.bz2
: `+ X9 h- O$ _- ?- b
! Q- j$ |1 p. T, _, P#tar -xvzf last_x264.tar.bz2
+ P+ p0 `; j4 O# W3 a; A# O* ^4 { y3 t+ d) V
#cd x264-snapshot-20120316-2245
0 x- i! O. K7 U. D' T
. I9 v6 v7 R5 X4 K( F1 p# ./configure --host=arm-linux --prefix=/opt/wecam/ffmpeg --enable-shared --disable-asm
D7 i5 I, `: N7 _# z: t
; x% a5 J8 J) X) ]& U配置选项中已经添加了host的选项,所以makefile就不用再修改了,但是要修改config.mak
6 d7 `; _# _% F* D. H
' w& Z k& K9 f1 y# i8 G- ^% sSRCPATH=.
9 W, S" M, p0 [/ N" a( aprefix=/opt/webcam/ffmpeg5 `# R; v; E4 c# L4 D0 k
exec_prefix=${prefix}" T+ I7 C' t& m7 A1 Y
bindir=${exec_prefix}/bin
6 _$ J. M! e) n, _# olibdir=${exec_prefix}/lib1 m% F0 k' V1 U: P+ N; I0 r
includedir=${prefix}/include c+ F" P' Z3 a, G( Q
ARCH=ARM
: U) o8 x, j$ y" t$ TSYS=LINUX
, B% D2 q6 p. v# `1 h& N! F; ?( tCC=arm-linux-gcc/ ~5 M+ e* c6 @4 O% K; A
CFLAGS=-Wshadow -O3 -fno-fast-math -Wall -I. -I$(SRCPATH) -std=gnu99 -fPIC -fomit-frame-pointer -fno-tree-vectorize$ ]4 A& O; c8 W9 d8 l X
DEPMM=-MM -g0
0 M7 n5 j9 V7 u) v- P+ K# m" \DEPMT=-MT
1 l! a. W. l8 s2 zLD=arm-linux-gcc -o $ M% u& D' [+ T8 J
LDFLAGS= -lm -lpthread
* x" `# Y+ h5 o; Z; M: pLIBX264=libx264.a
& M) R1 A/ Z0 l) L4 jAR=arm-linux-ar rc
$ K2 E3 Y6 g+ f) z, |. N- JRANLIB=arm-linux-ranlib
- l! a. r( A. r; w7 ^ FSTRIP=arm-linux-strip) M" p4 j3 G8 _. S- h5 k
#make+ K3 X0 r6 \9 q0 B* k- x/ d1 t
( }# ^* H/ ^6 M3 l9 n2 n" U#make install5 G! }9 i" h4 e& A+ `2 g
2 Q% @3 j; z% U* ^+ {* \x264编译也不会出现问题的,如果有,把之前安装的pc端的x264全部删掉
- y: J& e8 ?3 ?6 _% E+ V# u1 s" p" M
+ y# f/ D! H) ]* x; Q! Z2 C/ ?& v+ r. r3 w, n. J% G$ ~0 s
3、编译ffmpeg
; F" x; k. R) w* _, A9 S8 J" g( N3 A8 [4 G
解压ffmpeg-0.10.1.tar.gz
9 L( D) H+ r/ t E3 G
* Q- g# [, c2 a* i#tar -xzvf ffmpeg-0.10.1.tar.gz5 I% g( E. H2 i Q# a
: x! |2 C7 }1 ^5 F7 B/ v7 z
#cd ffmpeg-0.10.1
2 X8 f5 G, u8 q, |7 R; m
1 r. d, m9 ]6 V4 z. Q* i- f/ i8 p#./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/* q8 ~$ [. u# p( e3 H; `
! c) p9 n. [6 M5 g配置需要注意的是--extra-cflags=-I/opt/webcam/ffmpeg/include --extra-ldflags=-L/opt/webcam/ffmpeg/lib/ 指定x264库的位置( T& a* ~0 `% e
6 S1 J$ `: f0 q1 T: m#make
5 o+ _$ d0 x3 Y' i5 f2 {: Q! L( S8 y6 X2 d- s! R! }( f4 w: \
#make install% F, i6 l% b9 @" R# N. ~: y% ?
^) Q6 G9 J4 n1 f1 R以上,所有依赖的库就都编译好了,下面编译webcam应用程序. M! E0 l8 o6 E* M- f* q3 I" k9 l
' _6 w8 k" M/ H5 V
) Q8 a8 A3 H: B6 C s. t/ E4 Q: y所有的源文件不做除了修改udp上传用的ip地址和makefile文件外,不做任何修改,源码存放位置/opt/webcam
9 j! k7 p2 Q: X, A# ?% c- ]0 X8 d v, E" q! K) i6 n4 Z
1、修改server.cpp ip
$ v, F+ o. W9 v, W! u+ R3 n) q& j4 E
将#define TARGET_IP "192.168.1.220" 后面的ip改成你的pc linux的ip,依旧是客户端webcam_shower所在的pc的ip地址
' U6 z( J1 t% n8 F: k5 u4 {
+ J" W& t6 _( E9 i2、修改shower.cpp中的7 L) b4 M$ |7 i( ]! a" j! L
5 c& M* h4 `. j. \+ X0 M
inet_addr("192.168.1.220"); 将ip修改为pc linux的ip,就是自己的ip,socket绑定端口用
; z3 k% M& c+ }5 p# L$ h
8 j1 m. X# @. g; H C2 t# j3、修改makefile,以便交叉编译webcam_server,注意,之前编译zlib x264 ffmpeg都在放在webcam/ffmpeg中了: c4 x' c/ ]; }
0 v8 h: d! v/ Ball: webcam_server3 w% Z( y8 \' W) q/ j P9 `$ v$ f
#webcam_shower6 D6 |( M) G2 V5 D8 X- f2 A
CC=arm-linux-g++* `. E' c0 ^( D/ P& m& d3 h
LD=arm-linux-ld; U8 y% B( T+ j& F% m- u
CXXFLAGS= -c -g -O0 -fPIC -I./ffmpeg/include -L./ffmpeg/lib; d3 H; m2 J8 Y; d8 ^! O
8 C8 [5 Q) g! d. G2 y7 J
OBJS_SERVER= capture.o vcompress.o sender.o server.o
6 D9 z+ D4 p& g$ \# p/ r7 P+ OOBJS_SHOWER= vshow.o recver.o shower.o$ j4 G+ J$ q/ n$ q
LIBS_SERVER= -lavcodec -lswscale -lavutil -lx264 -lpthread -lz
6 t2 n# v R8 e: ]LIBS_SHOWER= -lavcodec -lswscale -lavutil
* Z6 b* a9 t; a1 B' g4 I* I. u; |/ `+ U
.cpp.o:
1 g, k7 O2 L# ]/ n* i6 \9 e $(CC) $(CXXFLAGS) $<
: C3 Z! f+ Y1 S# j6 N( K) t4 Y% c8 ~5 G- A: ^5 d
webcam_server: $(OBJS_SERVER)
. W5 o) U+ D' @) A I9 V' |/ ]9 o $(CC) -o $@ $^ -L./ffmpeg/lib $(LIBS_SERVER)
0 X! `! q+ x3 G; d; z5 g2 X
/ X. y/ z9 {- Q2 X7 nwebcam_shower: $(OBJS_SHOWER)' ^$ p# `7 j# }( `+ p0 r
$(CC) -o $@ $^ $(LIBS_SHOWER)* o) {8 f7 A# j' a
9 J- P8 j g3 R; D) p; U& xclean:
: M7 d" }3 Y1 _3 @* ]- h4 l1 L4 U( o rm -f *.o
P" l: T; J" m* y; j- n rm -f webcam_server
$ h3 E/ y3 n0 a2 i rm -f webcam_shower1 N# y- ?3 l# Z3 o8 j
6 S" I$ x2 z7 K! ^: S
#make
9 e0 |; y& r" B/ b# \. d这一步会出错,报c与c++兼容问题,在include/libavutil/common.h中添加如下,即可8 e; M# ^( r$ ~$ W9 P
: V" d- R2 [. O* V#ifndef UINT64_C7 J9 J, M- S! w
#define UINT64_C(value)__CONCAT(value,ULL) C6 U$ v! G! E1 m4 K
#endif- D! @/ ^5 v% w1 }$ \9 K' ]
+ O r& g/ o* s* v, ] Q0 V% n0 H2 {# D7 H2 E# B6 N4 O3 Z9 q0 e" `# g, e
最后就得到了编译好的web_server了,将web_server复制到mini2440中,并且将之前编译的第三方编解码库/lib下的所有.so文件复制到mini2440的 /usr/lib中
$ Y! K& M9 _, d# `/ Y
0 v: ]. _" }! M" L& e, N( ]插上usb摄像头,webcam_server就可以再mini2440中运行了0 ?, p3 P7 X1 M
$ ]# P9 c2 g# _/ y( |2 S/ x- Q$ C
' q' w3 ?. T! T$ s( Y最后是编译pc端的webcam_shower,这个很简单,按顺序从头编译就好了 |
|