|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
( O, u) F. u. s0 v& f( e
网络上盛传的基于mini2440的摄像头监控一般是基于 MJPEG-Streamer。7 b, p" |( E1 {4 J9 ?) P/ v
l' i, `/ w+ l, U0 m这种方法利用的是V4L2的底层驱动,然后配合mjpeg这种格式的流传输,然后通过浏览器浏览视频和控制。" x7 z. l" ~2 {# L
0 P# d8 ^3 f" y$ y
usb摄像头得到的数据格式一般是YUV422,如果用的是cmos 摄像头可能是raw原始数据格式,YUV422,是在raw基础上色彩抽点编码,因为人眼对亮度的敏感大于对色彩的敏感,所以并非对所有的色彩编码,这样的数据量会非常的大,视频编解码格式就不讨论了,很多很复杂,当然,你会了,就不会觉得难。+ B1 C3 u& ]0 j
* G+ U! i: u4 D
ffmpeg和x264的作用是将YUV422再编码成H.264) U% I# ^* g. b5 Q1 y, P# c6 g: p% N0 t
- l: x+ t$ G/ h
i4 \6 q. m0 z( D% o; _ R2 V9 o7 ~上图看效果,这是在linux中接的图,窗口中显示的是从2440usb摄像头上传上来的视频) S/ n8 T0 F) |% V; b. i( H, D! A
+ b) P# h* e$ l% \ K. J
) v5 \7 v& V8 T/ ^& T1 y L1 P
5 H3 F" q' Q1 W# X) X
这是实物图,手机拍的! i, }3 B* S! }; D* T
# \* f$ A2 |- S4 m3 e
# J( _& _. T2 o K {$ ] C8 r7 z" i! v) Z
废话少说,一步一步实现( Y& X+ |* A- S' R) E
; Z+ Q6 B) v; p! ]% O/ V# V1、平台+ a! b* m7 H! Y( w
/ c0 A+ c0 l) _: n+ ?. I) D
硬件:ARM mini2440,usb摄像头
& r- {) @2 O0 ~2 Q# W3 {, L4 d I) d2 x& ?1 y$ R1 G1 V7 M+ Q/ K
软件:fedora14,arm-linux-gcc v4.4.3
9 [. A5 ]4 A! T# S1 `# z) E8 }. d0 R; A
* M* Z% ~# F2 t* l, k2、源文件
2 o9 T# q1 ]* K# M, W' d) v0 t5 B! s3 q0 A
ffmpeg-0.10.1.tar.gz
- n+ e$ r0 `$ f9 \, W3 g% c, y8 M8 v2 w T
last_x264.tar.bz2
; ?0 i- I5 r8 U: }' q7 ?zlib-1.2.5.tar.gz (mini2440中没有libz.so,但是程序运行时需要这个库支持,所以下载源文件交叉编译)$ l; l; x5 e9 Z* ~) d. E9 ^/ T
以上文件只要会搜索的人都能找到
& ^/ U7 M: e9 g; D# }4 ?# z6 _0 a" S7 k7 S1 G8 | a
下面开始交叉编译,编译过程中会遇到几个小问题,一一解决
! p% V U7 g& H+ v2 ?5 b7 U
* d/ c: F- X& T9 w. }1、编译zlib
# J T- [, Y: u" \7 ^2 ?1 w$ J+ {" k& N' b* u
解压zlib-1.2.5.tar.gz, b2 W5 g/ n8 R$ _) _1 m
7 G. y. F. L7 C4 b. h7 {' [#tar -xzvf zlib-1.2.5.tar.gz
; T% F# |- G: y3 Y- X7 [7 m5 K5 d* ~% s3 o$ C+ ~
进入源文件目录
# a& M' k7 I7 D( k: w+ W" ~, }2 Z" ]4 r3 j8 T: j
#cd zlib-1.2.5
5 H. I1 i0 w7 n G; u
% U& W2 F+ u1 e8 F3 v/ }6 o0 @! i运行configure配置makefile
* ^7 c1 X) D8 s) \) U/ q" p6 c+ T: r Q! `! s; u
#./configure --prefix=/opt/webcam/ffpeg
+ {" i% S9 {) \/ @3 C" J
- X) r$ F# c8 A# J" F--prefix=/opt/webcam/ffpeg的意思是最后执行make install时,将文件安装在/opt/webcam/ffmpeg,不然会默认安装在/usr/local/lib中,其实这里不写这个参数,最后一起在makefile中修改也可以的。
: o) c( V( R7 U8 ?; G& l8 P4 y0 k+ ?7 y9 g! C. G5 F o
配置后会在当前目录下生成Makefile5 r( |+ z9 w& b+ }5 p
g9 h1 k1 M) Y; u
修改Makefile以便能够用arm-linux-gcc编译,其实就是把gcc 改成arm-linux-gcc,ar改成arm-linux-ar等! V+ Q# @* S, v
' r S* b1 i5 F$ x
下面是改好的makefile部分8 K2 s. ]: `* A) I6 | f
; g/ g p* m5 F6 g! gSFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=13 t, o6 I) \* V5 b: b
LDFLAGS= -L. libz.a
+ i* _; }4 n1 STEST_LDFLAGS=-L. libz.a
; w0 n3 l# X ^: }LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map1 |; a3 I, B; k& {9 ]" t+ v( Y
CPP=arm-linux-gcc -E$ K9 y$ C! r! x, _" X/ K* G) C
+ x2 Y% i0 {" V+ A J/ v( K+ SSTATICLIB=libz.a2 ~9 }: Z3 \6 H4 n' y+ J
SHAREDLIB=libz.so
" U V" u% H. V# b% V2 s: ASHAREDLIBV=libz.so.1.2.5
% J q) @, k. N0 Y; U" c* n/ t4 h k, HSHAREDLIBM=libz.so.1; j/ ?9 S* H; U. v6 E/ H( Z
LIBS=$(STATICLIB) $(SHAREDLIBV)
0 P9 _5 Y. k5 w
9 S- k- ?' v/ M7 U# XAR=arm-linux-ar rc
, C' |; i p n1 c7 xRANLIB=arm-linux-ranlib
6 t( ?1 n4 k1 z5 GLDCONFIG=ldconfig
5 _" p" k& |8 x8 A9 r+ YLDSHAREDLIBC=-lc
+ q* n) Y1 U) _+ }TAR=tar' w) t9 G! Y. Q9 U8 |
SHELL=/bin/sh
) e- ~: b* L6 a; BEXE=
3 E4 L& A. U2 _! q( g: R3 P. u. W+ C% W- j( D: e
prefix =/opt/webcam/ffmpeg, x1 }1 a k; t3 O- m
运行configure是的--prefix 就是最后这个参数,这里修改也行的5 F+ J1 }4 r% H
然后make,make install
4 K9 F9 s+ E& x. x) C" z; m
: Y) }: `9 [& e4 u: N) D* U8 `9 B#make
$ }: w8 z: ], }, E/ m
% d1 ^4 N, K4 ?. }' f9 ~9 P6 |#make install
; @3 X6 U% F2 x
, d A3 `, T* s/ Nzlib的编译应该不会出现问题,在/opt/wecam/ffmpeg中是编译好的文件,在子文件夹lib中的.so文件最后要复制到2440里$ w* y$ Y9 m8 b1 z' J9 [7 e7 F
* F( o/ H) K I2 H6 o. ]
+ z* A& Q. R+ |' c0 n
2、编译x264: W8 q$ C. H% D6 I9 c" L. F6 g8 Y
# b* ]0 g2 F) `8 i
应为编译ffmpeg时需要要添加对x264的支持,所以要先编译好x264,一边让编译ffmpeg时能够找到它
2 k% b' l8 N& N X4 Q
4 d; c5 p* u' z2 m5 U l, n解压last_x264.tar.bz2) @6 ? c& |3 q4 r
7 x/ x( C! H- c* r% U! Q#tar -xvzf last_x264.tar.bz2" B% Q: g% P( y# [
1 M Q$ F7 @- q X6 I
#cd x264-snapshot-20120316-2245
& Q7 W0 o. ^, m$ n% w& B
; u: u" h$ j. X! \6 D3 A# ./configure --host=arm-linux --prefix=/opt/wecam/ffmpeg --enable-shared --disable-asm3 L# b0 ^( B9 m4 R
) |; S# N$ t( J* _4 k3 ?配置选项中已经添加了host的选项,所以makefile就不用再修改了,但是要修改config.mak
9 ~; `- t& D1 c' n3 P% f
& ]1 N7 H9 |7 B& YSRCPATH=.
4 Z& [- `, i3 Q. z/ J- M5 Vprefix=/opt/webcam/ffmpeg
5 d8 L" z' I7 y0 z, s* dexec_prefix=${prefix}
% `8 d/ j: g4 Y( {3 Y& Y tbindir=${exec_prefix}/bin
5 w) F- j6 W9 i zlibdir=${exec_prefix}/lib% J E n9 s+ {
includedir=${prefix}/include( T% x/ K( U0 p% l# \
ARCH=ARM, B* J0 C/ n- z. z7 e# x8 C. H* R9 ^
SYS=LINUX0 P$ p- k+ J( y- O. i4 C8 \$ Y1 z
CC=arm-linux-gcc9 C# w& K4 m8 s* N! X
CFLAGS=-Wshadow -O3 -fno-fast-math -Wall -I. -I$(SRCPATH) -std=gnu99 -fPIC -fomit-frame-pointer -fno-tree-vectorize9 T3 l( b) U) B1 j! j
DEPMM=-MM -g06 S- `+ K9 N: j# \) ]2 L; Z
DEPMT=-MT1 X6 [3 |& f3 P3 {
LD=arm-linux-gcc -o
1 j8 k; A! `& e. nLDFLAGS= -lm -lpthread1 R2 ]/ t1 L. K8 O# I
LIBX264=libx264.a$ U C5 o) R! A3 L
AR=arm-linux-ar rc ' S R, J5 X/ X' V! q
RANLIB=arm-linux-ranlib/ S- S: J' @6 S8 s1 z
STRIP=arm-linux-strip8 m# z5 ^0 b3 y0 u1 C4 j( x
#make8 k6 c' W/ N6 Q5 M5 K. ]- n
: a/ s3 ]2 B |) g. C
#make install
0 e5 `0 E2 w% y1 K2 S
$ h- C$ G a# |% \* M5 Cx264编译也不会出现问题的,如果有,把之前安装的pc端的x264全部删掉
/ X- J* G7 j; v1 U2 V* u2 Q4 Z3 M+ f6 E& |8 Y
0 @" U2 W2 D* h* G
3、编译ffmpeg. \" F L; J5 h! g3 Y2 ~
+ C8 I" s0 ? J: c- F7 [解压ffmpeg-0.10.1.tar.gz
9 |, f# l. h9 _) b1 _
$ p0 u3 G( }; x3 ]2 O) Q: q, g#tar -xzvf ffmpeg-0.10.1.tar.gz
& T x. Z% G: }; ?' s1 s% m8 b. t5 Q
#cd ffmpeg-0.10.1
$ N$ V9 ^% u" J$ z* f- M; I* k8 [5 o& B+ F: I; a1 r
#./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/( J. X u# e2 G" X; m V
& C7 Z5 }. w& E) N u5 l6 }5 P
配置需要注意的是--extra-cflags=-I/opt/webcam/ffmpeg/include --extra-ldflags=-L/opt/webcam/ffmpeg/lib/ 指定x264库的位置9 t, q4 f* z7 T K: S% r: }* {
! s# e& b; p+ Y0 F3 c#make
( e) a1 [: `2 c) z" c4 K/ C# o
#make install
2 W& b! U7 c7 X* s2 `5 s8 W6 w/ W- U) f- ?5 g
以上,所有依赖的库就都编译好了,下面编译webcam应用程序
+ F8 L$ H- \9 {* N, n: D! X; h1 }% o @
3 I5 e+ y" b1 @/ A% O8 _, \
所有的源文件不做除了修改udp上传用的ip地址和makefile文件外,不做任何修改,源码存放位置/opt/webcam5 N7 y/ Q7 O \0 P' h
9 x2 c" X( ?, y
1、修改server.cpp ip# G; c6 P& c+ t' s, r ?5 ^* v+ P+ N
% a0 f( j) b( X- E& l& F: @! x将#define TARGET_IP "192.168.1.220" 后面的ip改成你的pc linux的ip,依旧是客户端webcam_shower所在的pc的ip地址
- }. x4 P: A1 P/ {
$ [3 r3 q9 }, N1 q2、修改shower.cpp中的
9 X5 C8 F' Q- }. k& P9 \2 y2 G7 w1 _- U
: Q$ _! ]' |4 p$ Y! Kinet_addr("192.168.1.220"); 将ip修改为pc linux的ip,就是自己的ip,socket绑定端口用
$ s0 l. W3 N, Z- x3 W3 K
$ z& W, r U) U& w# P# u" @3、修改makefile,以便交叉编译webcam_server,注意,之前编译zlib x264 ffmpeg都在放在webcam/ffmpeg中了4 Q" h5 [9 \! o; e4 m2 `- {
) V. x' u( z9 A* v
all: webcam_server- b. Q6 A7 o( a# }
#webcam_shower% m. a( e! j* L. B8 s- [! z% F7 _
CC=arm-linux-g++
* e8 d2 j- B4 t9 nLD=arm-linux-ld2 Z+ F$ x9 r; z$ f+ ~5 l
CXXFLAGS= -c -g -O0 -fPIC -I./ffmpeg/include -L./ffmpeg/lib+ {, U6 q. R |# F) l! h3 `) i7 Q
+ Q s* y3 U" L4 Y. ~& N! }. N
OBJS_SERVER= capture.o vcompress.o sender.o server.o
% v# g: t5 U( I IOBJS_SHOWER= vshow.o recver.o shower.o
& I: T% y6 I% h+ Z' HLIBS_SERVER= -lavcodec -lswscale -lavutil -lx264 -lpthread -lz3 N8 P; U9 d* j) a I6 N: `, S# v
LIBS_SHOWER= -lavcodec -lswscale -lavutil
0 W% h: t# S* K$ T# H3 u+ }+ \6 h
.cpp.o:
) @5 n9 Z* J) x8 F) d $(CC) $(CXXFLAGS) $<
& S% ^) T0 A8 Z# \$ ?& _8 g! t0 E0 _ ~! A; B
webcam_server: $(OBJS_SERVER)
1 Y0 u6 q+ }- Y7 `' x) Q: e $(CC) -o $@ $^ -L./ffmpeg/lib $(LIBS_SERVER) & r% J c/ ^. |8 n& s- R
: d, g* {0 E; mwebcam_shower: $(OBJS_SHOWER)
( x5 _) D% A, _1 h $(CC) -o $@ $^ $(LIBS_SHOWER)2 [8 _* m! y4 t" U( @& q, S' c
0 X) ~1 T/ e$ r" }# \
clean:9 o0 C) g) ~, m4 }( ~2 |
rm -f *.o: G2 w" K# o+ Z, l, Q- U! z a8 a5 I
rm -f webcam_server
6 i& ~! Q, H9 B" U3 B; K rm -f webcam_shower5 z7 c" t. v/ h% x, y x
2 |9 D! `: k& M+ L#make
/ z k% X' t! Z& O% N这一步会出错,报c与c++兼容问题,在include/libavutil/common.h中添加如下,即可0 G3 H5 n. G$ z x, r1 L
2 J7 q1 r! ~/ W% e6 _0 d#ifndef UINT64_C
5 a* Z9 U6 U. p, w) }#define UINT64_C(value)__CONCAT(value,ULL)
. N/ p- j# i- K#endif
$ D3 v2 s- m. @$ ?7 x& f$ }" U( a+ C& I% B. j1 M
' f# T+ t0 B3 E4 [. W
最后就得到了编译好的web_server了,将web_server复制到mini2440中,并且将之前编译的第三方编解码库/lib下的所有.so文件复制到mini2440的 /usr/lib中
; B; X; s0 s9 s: ?5 r+ s
8 U# E3 a( x& B$ [ F插上usb摄像头,webcam_server就可以再mini2440中运行了/ L9 v/ U- h& B
% p; b+ B# E, D9 ^, g+ u( }- K5 {& z
最后是编译pc端的webcam_shower,这个很简单,按顺序从头编译就好了 |
|