基于ARMLinux的视频采集及无线通信系统源程序.docx
- 文档编号:25113876
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:25
- 大小:21.78KB
基于ARMLinux的视频采集及无线通信系统源程序.docx
《基于ARMLinux的视频采集及无线通信系统源程序.docx》由会员分享,可在线阅读,更多相关《基于ARMLinux的视频采集及无线通信系统源程序.docx(25页珍藏版)》请在冰豆网上搜索。
基于ARMLinux的视频采集及无线通信系统源程序
基于ARM-Linux的视频采集及无线通信系统——源代码
#ifndefQT_V4L_H
#defineQT_V4L_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
classQCheckBox;
classQGridLayout;
classQHBoxLayout;
classQLabel;
classQMovie;
classQSlider;
classQToolButton;
#defineDEBUG_PRINT
#defineMAX_WIDTH176//320
#defineMAX_HEIGHT144//240
#defineDEFAULT_DEVICE"/dev/video0"
#defineBUFLEN255
typedefstructv4l_struct
{
intfd;
/*包含摄像头设备的基本信息(设备名称、支持的最大最小分辨率、信号源信息等),分别对应着结
构体中成员变量name[32],maxwidth,maxheight,minwidth,minheight,channels(信号源个数),type等。
*/
structvideo_capabilitycapability;
/*关于各个信号源的属性,如channel(信号源编号)、name(名称)、tuners(信号源通道)、type(类型)、
Norm(制式)等。
*/
structvideo_channelchannel[8];
/*包含采集到图像的各种属性,如brightness(亮度)、hue(色调)、color(颜色)、
contrast(对比度)、whiteness(色度)、depth(深度)、palette(调色板类型)等。
*/
structvideo_picturepicture;
/*用于内存映射。
*/
structvideo_mmapmmap;
/*利用mmap进行映射的帧信息,即输入到摄像头存储缓冲区中的帧信息,包括size(帧的大小)、
frames(最多支持的帧数)、offsets(每帧相对基址的偏移)。
*/
structvideo_mbufmbuf;
unsignedchar*buffer;
unsignedchar*map;
intframe_current;
intframe_using[2];
boolVisible;
}v4l_device;
classqt_v4l:
publicQWidget
{
Q_OBJECT
public:
structsockaddr_inpeeraddr,localaddr;
intsockfd;
charrecmsg[BUFLEN+1];
intsocklen,n;
char*arg[5];
qt_v4l();
~qt_v4l();
charnum;
charnum1;
inttimerid;
QTimertimer;
QPushButton*btnStart;
QPushButton*btnStop;
QPushButton*btnCapture;
QPushButton*btnSave;
QHBoxLayout*hLayout;
QVBoxLayout*vLayout;
QImageimage;
QLabel*label;
voidcloseEvent(QCloseEvent*);
voidtimerEvent(QTimerEvent*event);
publicslots:
voidstart();
voidstop();
voidsave();
voidsend();
voidmessagebox();
};
intv4l_open(char*dev,v4l_device*vd);
intv4l_close(v4l_device*vd);
intv4l_get_capability(v4l_device*vd);
intv4l_get_picture(v4l_device*vd);
intv4l_set_picture(v4l_device*vd);
intv4l_get_channels(v4l_device*vd);
intv4l_init_mbuf(v4l_device*vd);
intv4l_get_mbuf(v4l_device*vd);
intv4l_mmap_init(v4l_device*vd);
unsignedchar*v4l_get_address(v4l_device*vd);
intv4l_munmap(v4l_device*vd);
intv4l_grab_frame(v4l_device*vd,intframe);
intv4l_grab_sync(v4l_device*vd);
voidv4l_grab_movie(v4l_device*vd);
#endif
//-----------------------------------------------------------------------------
//qt_v4l.cpp
//-----------------------------------------------------------------------------
#include"qt_v4l.h"
v4l_devicev4l_dev;
//声明一个vd变量(v4l_device类型),再调用v4l_open()将设备文件打开
intv4l_open(char*dev,v4l_device*vd)
{
if(!
dev)
{
dev=DEFAULT_DEVICE;
}
//open的返回值是filedescription
if((vd->fd=open(dev,O_RDWR))<0)
{
perror("v4l_open:
");
return-1;
}
#ifdefDEBUG_PRINT
printf("youhaveopendevsuccessfully");
#endif
return0;
}
//利用ioctl()取得设备的相关信息,并且将取得的信息放到structvideo_capability结构里
intv4l_get_capability(v4l_device*vd)
{
//vd->fD是由v4l_open返回值filedescriptor,而传递VIDIOCGCAP给ioctl()则返回设备相关信息,存放在vd->capability
if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability))<0)
{
perror("v4l_get_capability:
");
printf("capa");
return-1;
}
return0;
}
//取得设备采集的影像的各种信息:
就是通过输入到视频采集卡的影像格式
intv4l_get_picture(v4l_device*vd)
{
//传递VIDIOCGPICT给ioctl()则返回影像的属性(imageproperties),放在vd->picture里
if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))<0)
{
perror("v4l_get_picture:
");
return-1;
}
return0;
}
//在采集摄像头视频数据前,可根据需求修改影像参数如分辨率等,具体方法为先给分量赋新值,再调用函数ioctl(vd->fd,//VIDIOCSPICT,&(vd->picture))
intv4l_set_picture(v4l_device*vd)
{
vd->picture.palette=VIDEO_PALETTE_RGB565;//设置调色板RGB565
if(ioctl(vd->fd,VIDIOCSPICT,&(vd->picture))<0)
{
perror("v4l_set_picture:
");
return-1;
}
return0;
}
//用循环来实现channel初始化,取得每个channel的信息
intv4l_get_channels(v4l_device*vd)
{
inti;
//信号源个数储存在vd->capability.channels里,是通过v4l_get_capability()获取的
for(i=0;i
{
vd->channel[i].channel=i;//为每个channel做编号
//传递VIDIOCGCHAN给ioctl(),则返回channel信息,存放在vd->channel中
if(ioctl(vd->fd,VIDIOCGCHAN,&(vd->channel[i]))<0)
{
perror("v4l_get_channel:
");
return-1;
}
}
return0;
}
//同v4l_grab_init():
将vd->mmap结构填入适当的值
intv4l_init_mbuf(v4l_device*vd)
{
//指定mmap大小
vd->mmap.width=MAX_WIDTH;
vd->mmap.height=MAX_HEIGHT;
vd->mmap.format=vd->picture.palette;//存放调色板类型
//会被v4l_grab_frame所使用
vd->frame_current=0;
vd->frame_using[0]=0;
vd->frame_using[1]=0;
#ifdefDEBUG_PRINT
printf("\nbegintoinitdevice:
");
#endif
return0;
}
//getbuffermapinfo
intv4l_get_mbuf(v4l_device*vd)
{
if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf))<0)
{
perror("get_mbuf:
");
return-1;
}
return0;
}
/*
*视频数据的读取与read()方式相比,mmap()方式通过把设备文件映射到内存,绕过了内核缓冲区,加速
*了I/O访问。
完成内存映射之后,就可以用mmap()方式实现对内存映射区域视频数据的单帧采集。
此方式
*下真正做视频截取的为VIDIOCMCAPTURE,调用函数ioctl(_fd,VIDIOCMCAPTURE,&mmap),激活
*设备并真正开始一帧图像的截取,是非阻塞的,接着调用ioctl(_fd,VIDIOCSYNC,&frame)函数等待
*一帧图像截取结束,成功返回表示一帧截取已完成,接着可以做下一次的VIDIOCMCAPTURE操作。
*/
//设备缓冲区到内存空间的映射
intv4l_mmap_init(v4l_device*vd)
{
if(v4l_get_mbuf(vd)<0)
return-1;
if((vd->map=(unsignedchar*)mmap(0,vd->mbuf.size,
PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0))<0)
{
perror("v4l_mmap_init:
mmap");
return-1;
}
return0;
}
//通过mmap的概念与计算frame的offset即刻知道所采集影像的内存存放地址
unsignedchar*v4l_get_address(v4l_device*vd)
{
return(vd->map+vd->mbuf.offsets[vd->frame_current]);
}
//真正将影像放到mmap()所映像内存的函数
intv4l_grab_frame(v4l_device*vd,intframe)
{
//用vd->frame_using[]来记录哪个frame正被使用.如果不为空,则表明正在被使用
if(vd->frame_using[frame])
{
fprintf(stderr,"v4l_grab_frame:
frame%disalreadyused.\n",frame);
return-1;
}
vd->mmap.frame=frame;
//如果没有被使用,就把vd->mmap.frame填入该编号,然后利用VIDIOCAPTURE采集影像
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0)
{
perror("v4l_grab_frame:
");
return-1;
}
//程序结束前,把目前frame的状态标识成使用中,然后把frame_current指定成现在的frame
vd->frame_using[frame]=1;
vd->frame_current=frame;
return0;
}
//用于同步,等待视频采集卡将影像采集完成
intv4l_grab_sync(v4l_device*vd)
{
if(ioctl(vd->fd,VIDIOCSYNC,&(vd->frame_current))<0)
{
perror("v4l_grab_sync:
VIDIOCSYNC");
return-1;
}
//将目前frame的状态改成未被使用
vd->frame_using[vd->frame_current]=0;
return0;
}
intv4l_munmap(v4l_device*vd)
{
if(munmap(vd->map,vd->mbuf.size)<0)
{
perror("v4l_munmap:
munmap");
return-1;
}
return0;
}
intv4l_close(v4l_device*vd)
{
close(vd->fd);
return0;
}
//采集录像
voidv4l_grab_movie(v4l_device*vd)
{
v4l_grab_frame(&v4l_dev,v4l_dev.frame_current);//获取一frame
v4l_grab_sync(&v4l_dev);//等在完成获取工作
v4l_dev.buffer=v4l_get_address(&v4l_dev);//获得映射地址
v4l_dev.frame_current=(v4l_dev.frame_current+1)%2;
}
qt_v4l:
:
qt_v4l()
{
arg[1]="192.168.0.100";
arg[2]="2500";
arg[3]="192.168.0.111";
arg[4]="2500";
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0){
printf("socketcreatingerrorinudptalk\n");
exit
(1);
}
socklen=sizeof(structsockaddr_in);
memset(&peeraddr,0,socklen);
peeraddr.sin_family=AF_INET;
peeraddr.sin_port=htons(atoi(arg[2]));
if(inet_pton(AF_INET,arg[1],&peeraddr.sin_addr)<=0){
printf("WrongdestIPaddress!
\n");
exit
(1);
}
memset(&localaddr,0,socklen);
localaddr.sin_family=AF_INET;
localaddr.sin_port=htons(atoi(arg[4]));
if(inet_pton(AF_INET,arg[3],&localaddr.sin_addr)<=0){
printf("WrongsourceIPaddress!
\n");
exit
(1);
}
if(bind(sockfd,(constsockaddr*)&localaddr,socklen)<0){
printf("bindlocaladdresserrorinudptalk!
\n");
exit
(1);
}
num=0;
num1=50;
setWindowTitle(tr("VedioCapturer"));
label=newQLabel(this);
btnStart=newQPushButton("Start",this);
btnStart->setMaximumSize(55,30);
btnStop=newQPushButton("Stop",this);
btnStop->setMaximumSize(55,30);
btnCapture=newQPushButton("Capture",this);
btnCapture->setMaximumSize(55,30);
timerid=startTimer(20);
timer.start(20);
v4l_dev.Visible=1;
v4l_open(DEFAULT_DEVICE,&v4l_dev);
v4l_get_capability(&v4l_dev);
v4l_set_picture(&v4l_dev);
v4l_get_picture(&v4l_dev);
v4l_init_mbuf(&v4l_dev);
v4l_mmap_init(&v4l_dev);
v4l_dev.picture.contrast=110000;
v4l_set_picture(&v4l_dev);
hLayout=newQHBoxLayout();
hLayout->addWidget(btnStart,0,Qt:
:
AlignCenter);
hLayout->addWidget(btnStop,0,Qt:
:
AlignCenter);
hLayout->addWidget(btnCapture,0,Qt:
:
AlignCenter);
vLayout=newQVBoxLayout(this);
vLayout->addWidget(label,0,Qt:
:
AlignCenter);
vLayout->addLayout(hLayout);
vLayout->setMargin
(2);
setLayout(vLayout);
connect(btnStart,SIGNAL(clicked()),this,SLOT(start()));
connect(btnStop,SIGNAL(clicked()),this,SLOT(stop()));
connect(btnCapture,SIGNAL(clicked()),this,SLOT(save()));
}
qt_v4l:
:
~qt_v4l()
{
}
voidqt_v4l:
:
timerEvent(QTimerEvent*)
{
v4l_grab_movie(&v4l_dev);
unsignedchar*pBuffer=v4l_dev.buffer;
if(v4l_dev.Visible==1){//在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 ARMLinux 视频 采集 无线通信 系统 源程序