视频采集/播放模块设计

视频采集和播放模块实现了通过摄像头采集本端影像视频传输给对话方并接收对方的视频数据还原成影像显示在本端屏幕上的功能,也是本IP电话系统的先进之处,程式中用多的一些Video4Linux支持的专用视频数据结构如下: 

  1)video_capability,包含摄像头的基本信息,如设备名称、支持的最大最小分辨率、信号源信息等,分别对应着结构体中成员变量name[32]、maxwidth、maxheight、minwidth、minheight、channels(信号源个数)、type等; 

  2)video_picture,包含设备采集图像的各种属性,如brightness(亮度)、hue(色调)、contrast(对比度)、whiteness(色度)、depth(深度)等;

  3)video_mmap,用于内存映射; 

  4)video_mbuf,利用mmap进行映射的帧信息,实际上是输入到摄像头存储器缓冲中的帧信息,包括size(帧的大小)、frames(最大支持的帧数)、offsets(每帧相对基址的偏移); 

  5)video_Window,包括设备采集窗口的各种参数。 

  视频采集/播放模块的基本工作流程如图5所示。

系统使用从QWidget继承而来的IPVideo类进行视频数据的处理,在采集和播放之前,必须先对视频设备初始化,正确设置一些工作参数,打开视频设备仍然使用open()函数,设备文件名为/dev/video0,在构造函数中完成并对函数设备初始化,初始化是通过读取摄像头的一些信息来设置设备采集窗口的大小,如下: 

struct video_capability cap; struct video_window win; if(ioctl(video_fd,VIDIOCGCAP,&cap)==-1) //读取摄像头信息 …//错误处理 w=win.width=cap.maxwidth; h=win.height=cap.maxheight; frameSize=w*h; if(ioctl(video_fd,VIDIOCSWIN,&win)==-1) //设置采集窗口大小 …//错误处理 
   进行初始化设备工作后,就能对视频图像进行采集了,通常有两种方法:一种是使用read()直接读取视频数据;另外一种是通过mmap()内存映射来实现,read()通过内核缓冲区来读取数据,而mmap()通过把设备文件映射到内存中,绕过了内核缓冲区,加速了I/O访问,显然比使用read()函数快。所以在系统实现中采用mmap()内存映射方式。

  利用mmap()方式对视频进行采集时,先获得摄像头存储缓冲区的帧信息,之后修改video_mmap中的设置,能重新设置图像帧的重新及水平分辨率、彩色显示格式,接着把摄像头对应的设备文件映射到内存区,代码片断如下:

这样摄像头设备所采集的内容就映射到了内存缓冲区pixBuf中,该映射内容区可读可写并可和其他进程共享。将系统设置为单帧采集模式,当1帧数据采集完毕时,通过vDataSock套接字将视频数据传送给对方,然后发一个canSample()信号给自身再开始下一帧数据的采集,如下: 

在采集视频数据的同时,还要显示对方传输过来的视频数据,当对方的数据被接收到时,系统利用vDataSock的readyRead()信号告诉IPVideo将其显示出来。IPVideo使用QT/Embedded的QImage和QPainter类来实现图像数据的显示,先初始化,为了使图像重画时不闪烁,设置WRepaintNoErase重画不擦除标志,如下: 

p=new QPainter(); image=new QImage((uchar*)buff,w,h,32,0,0,(QImage::Endian)0); setWFlags(getWFlags()|Qt::WRepaintNoErase); 

  重载IPVideo的paintEvent()函数,加载buff中接收过来的视频数据,并在屏幕上画出来,代码如下: 

void paintEvent(QPaintEvent*){ image->loadFromData((uchar*)buff,frameSize); p->begin(this); p->drawImage(0,0,*image); p->end(); } 

  在IPVideo中增加一个槽函数show(),专门接收vDataSock的readyRead()信号,一旦接收到了,就通过vDataSock的ds将视频数据流导入buff缓冲区中,并调用updata()函数,该函数将激活paint事件,调用paintEvent()函数进行视频的更新重画。这样,随着不停地接收到对方的图像数据,就实现了远端视频的播放,双方就能进行语音和视频同步的IP通话了。 

你可能感兴趣的:(嵌入式linux,驱动)