基于 ARM 的远程视频监控系统 乐橙远程视频监控系统

这些天参考网上的代码,完成了这个嵌入式远程视频监控系统。

系统组成:USB 视频采集模块、数据处理模块、视频播放模块。其中 USB 视频采集模块要解决两个问题,一个是摄像头驱动问题,另一个就是怎么样用 v4l 采集数据的问题。数据处理模块最主要就是把采集到的每一帧图像数据进行压缩,以节省网络带宽。视频播放模块主要就是客户段软件的实现,它通过网络接收数据,解压后进行播放。系统框架图如下:



系统工作流程:实现好摄像头驱动后,用 v4l 接口从摄像头中读取视频数据;调用 H.264 编码库对数据进行编码,然后通过 socket 发给客户端;客户端接收数据,进行解码,最后显示出来。

系统软硬件环境:

宿主机:Lenovo PC, Ubuntu 10.10

FL2440开发板:S3C2440, Linux-2.6.12

摄像头:中星微 ZC0301PH, 驱动为 gspca

编解码库:t264

实现步骤:

1. 编译摄像头驱动:进入摄像头驱动源码目录,修改 Makefile 文件,主要是改动 CC=arm-linux-gcc,KERNELDIR=YourKernelDir,然后 make,就会产生 gspca.ko 这个模块。

2. 交叉编译 H.264 源码:进入源码目录,修改 Makefile 文件:CC=arm-linux-gcc 即可。

3. 编译服务端软件,源码下附,Makefile 中要指明 H.264 的头文件路径还有上一步产生的库文件路径。

4. 测试,insmod gspca.ko,运行 ./camera_server。效果如下:



附 camera_server.c 源码:

view plaincopy to clipboardprint?

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<stdio.h>

#include<sys/ioctl.h>

#include<sys/mman.h>

#include<stdlib.h>

#include<linux/types.h>

#include<linux/videodev.h>

#include<setjmp.h>

#include<string.h>

#include<signal.h>

#include<errno.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include"convert.h"

#include"/paul/Tools/Lib/avc/common/T264.h"

#defineSERVER_PORT8888

T264_t*m_t264;

T264_param_tm_param;

char*m_pSrc;

char*m_pDst;

int*m_lDstSize;

char*m_pPoolData;

#defineUSB_VIDEO"/dev/video0"

intcam_fd;

structvideo_mmapcam_mm;

structvideo_capabilitycam_cap;

structvideo_picturecam_pic;

structvideo_mbufcam_mbuf;

structvideo_windowwin;

char*cam_data=NULL;

intnframe;

staticunsignedcharcam_yuv[2457616];

voidread_video(char*pixels,intw,inth)

{

intret;

intframe=0;

cam_mm.width=w;

cam_mm.height=h;

cam_mm.frame=0;

cam_mm.format=VIDEO_PALETTE_RGB24;//OurcamerasupportRGB24

/*Readdata*/

ret=ioctl(cam_fd,VIDIOCMCAPTURE,&cam_mm);

if(ret<0){

printf("ERROR:VIDIOCMCAPTUREn");

}

/*Waituntilalldataisread.*/

ret=ioctl(cam_fd,VIDIOCSYNC,&frame);

if(ret<0){

printf("ERROR:VIDIOCSYNCn");

}

}

/*Configurepicture*/

voidconfig_vid_pic()

{

charcfpath[100];

FILE*cf;

intret;

if(ioctl(cam_fd,VIDIOCGPICT,&cam_pic)<0){

printf("ERROR:VIDIOCGPICTn");

}

cam_pic.palette=VIDEO_PALETTE_RGB24;

cam_pic.brightness=30464;

cam_pic.hue=111;

cam_pic.colour=555;

cam_pic.contrast=43312;

cam_pic.whiteness=111;

cam_pic.depth=24;

ret=ioctl(cam_fd,VIDIOCSPICT,&cam_pic);

if(ret<0){

close(cam_fd);

printf("ERROR:VIDIOCSPICT,Can'tsetvideo_pictureformatn");

}

return;

}

voidinit_video(intw,inth)

{

intret;

/*Openthedevice*/

cam_fd=open(USB_VIDEO,O_RDWR);

if(cam_fd<0)

printf("Can'topenvideodevicen");

/*Getinfo*/

ret=ioctl(cam_fd,VIDIOCGCAP,&cam_cap);

if(ret<0){

printf("Can'tgetdeviceinformation:VIDIOCGCAPn");

}

printf("Devicename:%snWidth:%d~%dnHeight:%d~%dn",

cam_cap.name,

cam_cap.maxwidth,

cam_cap.minwidth,

cam_cap.maxheight,

cam_cap.minheight);

if(ioctl(cam_fd,VIDIOCGWIN,&win)<0){

printf("ERROR:VIDIOCGWINn");

}

win.x=0;

win.y=0;

win.width=w;

win.height=h;

/*SetWindow*/

if(ioctl(cam_fd,VIDIOCSWIN,&win)<0){

printf("ERROR:VIDIOCSWINn");

}

config_vid_pic();

/*Getdevicebuffer*/

ret=ioctl(cam_fd,VIDIOCGMBUF,&cam_mbuf);

if(ret<0){

printf("ERROR:VIDIOCGMBUF,Can'tgetvideo_mbufn");

}

printf("Frames:%dn",cam_mbuf.frames);

nframe=cam_mbuf.frames;

/*Memorymap*/

cam_data=(char*)mmap(0,cam_mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,cam_fd,0);

if(cam_data==MAP_FAILED){

printf("ERROR:mmapn");

}

printf("Buffersize:%dnOffset:%dn",cam_mbuf.size,cam_mbuf.offsets[0]);

InitLookupTable();

}

/*ThisfunctionisfromtheexampleT264.c.

*Itinitializetheencodewithparametersfromtheconfigurefile.

*Youdon'tneedtoknowthegreatdetail.

*/

voidinit_param(T264_param_t*param,constchar*file)

{

inttotal_no;

FILE*fd;

charline[255];

int32_tb;

if(!(fd=fopen(file,"r")))

{

printf("Couldn'topenparameterfile%s.n",file);

exit(-1);

}

memset(param,0,sizeof(*param));

fgets(line,254,fd);sscanf(line,"%d",&b);

if(b!=4)

{

printf("wrongparamfileversion,expectv4.0n");

exit(-1);

}

fgets(line,254,fd);sscanf(line,"%d",&param->width);

fgets(line,254,fd);sscanf(line,"%d",&param->height);

fgets(line,254,fd);sscanf(line,"%d",&param->search_x);

fgets(line,254,fd);sscanf(line,"%d",&param->search_y);

fgets(line,254,fd);sscanf(line,"%d",&total_no);

fgets(line,254,fd);sscanf(line,"%d",&param->iframe);

fgets(line,254,fd);sscanf(line,"%d",&param->idrframe);

fgets(line,254,fd);sscanf(line,"%d",&param->b_num);

fgets(line,254,fd);sscanf(line,"%d",&param->ref_num);

fgets(line,254,fd);sscanf(line,"%d",&param->enable_rc);

fgets(line,254,fd);sscanf(line,"%d",&param->bitrate);

fgets(line,254,fd);sscanf(line,"%f",&param->framerate);

fgets(line,254,fd);sscanf(line,"%d",&param->qp);

fgets(line,254,fd);sscanf(line,"%d",&param->min_qp);

fgets(line,254,fd);sscanf(line,"%d",&param->max_qp);

fgets(line,254,fd);sscanf(line,"%d",&param->enable_stat);

fgets(line,254,fd);sscanf(line,"%d",&param->disable_filter);

fgets(line,254,fd);sscanf(line,"%d",&param->aspect_ratio);

fgets(line,254,fd);sscanf(line,"%d",&param->video_format);

fgets(line,254,fd);sscanf(line,"%d",&param->luma_coeff_cost);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_INTRA16x16)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_INTRA4x4)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_INTRAININTER)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_HALFPEL)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_QUARTPEL)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_SUBBLOCK)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_FULLSEARCH)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_DIAMONDSEACH)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_FORCEBLOCKSIZE)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_FASTINTERPOLATE)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_SAD)*b;

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_EXTRASUBPELSEARCH)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->flags|=(USE_SCENEDETECT)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_16x16P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_16x8P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_8x16P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_8x8P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_8x4P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_4x8P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_4x4P)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_16x16B)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_16x8B)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_8x16B)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&b);

param->block_size|=(SEARCH_8x8B)*(!!b);

fgets(line,254,fd);sscanf(line,"%d",&param->cpu);

fgets(line,254,fd);sscanf(line,"%d",&param->cabac);

//fgets(line,254,fd);sscanf(line,"%s",src_path);

//fgets(line,254,fd);sscanf(line,"%s",out_path);

//fgets(line,254,fd);sscanf(line,"%s",rec_path);

//param->rec_name=rec_path;

fclose(fd);

}

/*CreateandInitializeanencoder*/

voidinit_encoder()

{

/*Configurefile*/

constchar*paramfile="fastspeed.txt";

/*Readthefileandfilltheparameterstruct*/

init_param(&m_param,paramfile);

m_param.direct_flag=1;

/*Createanencoderwiththeparametersreadfromconfigurefile.*/

m_t264=T264_open(&m_param);

/*allocmemoryfortheencodeddata.*/

m_lDstSize=m_param.height*m_param.width+(m_param.height*m_param.width>>1);

m_pDst=(uint8_t*)T264_malloc(m_lDstSize,CACHE_SIZE);

/*allocmemoryfromdatapackage*/

m_pPoolData=malloc(m_param.width*m_param.height*3/2);

}

/*Thisfunctionisthemainworkingfunction.

*@sockfd:Thesocketweusetosenddata.

*@w:Thewidthofpicture.

*@h:Theheightofpicture.

*/

voidmain_loop(intsockfd,intw,inth)

{

/*Theaddressoftheclient*/

structsockaddr_inaddrdst;

intaddrlen,n;

/*Datasize*/

int32_tiActualLen;

introw_stride=w*3*h/2;

/*Fillclientaddress*/

bzero(&addrdst,sizeof(structsockaddr_in));

addrdst.sin_family=AF_INET;

addrdst.sin_addr.s_addr=inet_addr("125.216.244.49");

addrdst.sin_port=htons(SERVER_PORT);

/*Allisready,comesthisloop,doingtheactuallywork.*/

while(1)

{

/*Readdatafromthecamera*/

read_video(NULL,w,h);

/*WeconvertRGBtoYUV420,sincetheencodeacceptYUV420only*/

ConvertRGB2YUV(w,h,cam_data,cam_yuv);

iActualLen=T264_encode(m_t264,cam_yuv,m_pDst,row_stride);

printf("encoded:%d,%dbytes.n",row_stride,iActualLen);

/*Filladatapackage.

*Hereweputtheframenumberfirst,

*andthetheactualencodeddata.

*Notethatitisnotsafetodoso:

*sendingbinarydatadirectlymaycauseEndianproblem.

*However,ARMandx86areallSmallEndian,soitlooksfine.

*/

memcpy(m_pPoolData,&m_t264->frame_num,1);

memcpy(m_pPoolData+1,m_pDst,iActualLen);

iActualLen++;

/*Weusesockettosendaframe.*/

sendto(sockfd,m_pPoolData,iActualLen,0,

(structsockaddr*)&addrdst,sizeof(structsockaddr_in));

}

}

/*Callbackfunction*/

voidfree_dev()

{

printf("Freedevicen");

close(cam_fd);

}

intmain(void)

{

printf("Startembeddedvideoserver...n");

fflush(stdout);

intsockfd;

/*Actually,theprogramisaclienttechniquely

*thus,wedonthavetobinditaaddress.*/

sockfd=socket(AF_INET,SOCK_DGRAM,0);

if(sockfd<0)

{

printf("0-");

printf("SocketErrorn");

exit(1);

}

/*Initializetheencoder*/

init_encoder();

/*Iguessthisistoregisteracallbackfunction,

*whentheencoderexitunexpectly,thisfunction

*willbecallled.

*/

atexit(&free_dev);

/*InitializeV4l

*Wegetdatafromcamerabythev4lAPI

*/

init_video(m_param.width,m_param.height);

/*Whenworking,wewillbeinaloop.

*Everytimewereaddatafromthecamera,encodeit,

*andsendittotheclient.

*/

main_loop(sockfd,m_param.width,m_param.height);

close(sockfd);

}

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/70676.html

更多阅读

怎样制作自己的游戏视频 游戏视频后期制作软件

看到网上很多人做出自己的视频,其实视频很容易制作怎样制作自己的游戏视频——工具/原料fraps格式工厂怎样制作自己的游戏视频——步骤/方法怎样制作自己的游戏视频 1、首先进入FRAPS设置好快捷键怎样制作自己的游戏视频 2、进入游

如何免费看优酷土豆上的付费视频 优酷付费视频下载

如何免费看优酷土豆上的付费视频——简介我们平时看视频的时候,各大视频网站上有些新电影是收费的,只能看5----10分钟,能不能有一种方法让我们免费看这些视频呢。现在我无意中发现了这么一个方法,经我的验证是对有些视频可以正常使用的,

怎样免费下载高清的mv视频 mv下载网站 免费 高清

怎样免费下载高清的mv视频——简介网络上有很多好看的视频mv,但是只是会员才可以下载观看,普通人只能在线看一下,看完后也就没有了。那么,怎样才能让普通人也能下载下来呢。下面就用“酷我音乐”介绍下怎样免费下载高清的mv视频——工

声明:《基于 ARM 的远程视频监控系统 乐橙远程视频监控系统》为网友孔雀哥哥分享!如侵犯到您的合法权益请联系我们删除