视频的采集和动态显示(三)
来源:互联网 发布:华为手机解锁软件 编辑:程序博客网 时间:2024/06/15 01:31
硬件平台:Digilent ZedBoard
开发环境:Windows XP 32 bit + Wmare 8.0 + Ubuntu 10.04 +Qt+ arm-linux-xilinx-gnueabi交叉编译环境
Zedboard linux: Digilent OOB Design
一、V4l2更新缓冲Buffer的方法
回顾上一节中,我们使用v4l2控制usb 摄像头,对摄像头的静态图片采集流程操作过程可以归纳为图1:
图1 静态图片采集流程图
所用到的函数和参数都在旁边标注出。可以看到使用命令VIDIOC_DQBUF将缓存中的图像帧取出,然后摄像头设备是一直在采集图像,如果没有更新缓存区命令,采集到的新数据是不会被更新到缓存中的。v4l2提供了与VIDIOC_DQBUF命令相对的命令VIDIOC_QBUF,我对这个命令的理解就是允许摄像头设备将采集图像更新到缓存区。假设开辟的缓存FIFO大小为4帧,如图2(a),当使用VIDIOC_DQBUF命令后,当前帧n从FIFO中取走,FIFO留下一个空缺,如图2(b),这种情况下如果使用VIDIOC_QBUF命令,新一帧n+4将被写入缓存,如图2(c)。
图2 缓存FIFO与VIDIOC_DQBUF命令、VIDIOC_QBUF命令
所以为了实现缓存区图像数据的动态更新,需要在每一次处理完数据后使用VIDIOC_QBUF更新缓存区,以便下一次VIDIOC_DQBUF获取到新的一帧数据。因而动态更新缓存的视频采集流程应该如图3所示:
图3 动态视频采集流程
为此,需要重新定义两个函数,一个我们定义为get_frame获取视频帧:
1 int VideoDevice::get_frame(void **frame_buf, size_t* len) 2 { 3 v4l2_buffer queue_buf; 4 5 queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 6 queue_buf.memory = V4L2_MEMORY_MMAP; 7 8 if(ioctl(fd, VIDIOC_DQBUF, &queue_buf) == -1) 9 {10 return FALSE;11 }12 13 *frame_buf = buffers[queue_buf.index].start;14 *len = buffers[queue_buf.index].length;15 index = queue_buf.index;16 17 return TRUE;18 }
再定义free_frame释放视频帧,让出缓存空间准备新的视频帧数据:
1 int VideoDevice::free_frame() 2 { 3 if(index != -1) 4 { 5 v4l2_buffer queue_buf; 6 queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 7 queue_buf.memory = V4L2_MEMORY_MMAP; 8 queue_buf.index = index; 9 10 if(ioctl(fd, VIDIOC_QBUF, &queue_buf) == -1)11 {12 return FALSE;13 }14 return TRUE;15 }16 return FALSE;17 }
二、Qt的paintEvent事件
在上篇博客里面,我们对采集的的视频帧数据的显示,采用的方法是使用了一个QLabel和QPixmap,并使用loadfromdata函数将采集的数据转为QPixmap中的数据,并显示到QLabel上。这样的做法导致的结果是QLabel和QPixmap数据只能被更新一次,所以只能显示静态图片。
在完成了视频缓存数据更新后,我们所面临的问题就是怎么样才能把这个数据动态显示出来。好在Qt提供了窗口刷新事件paintEvent,在这里,我们可以使用两种方式触发paintEvent事件:
1、使用定时器QTimer,定时为33ms(因为摄像头的帧频为30pfs);
2、不使用定时器,由QLabel自身内容改变产生。这里采用这种方式。paintEvent函数内容:
1 void Widget::paintEvent(QPaintEvent *) 2 { 3 rs = vd->get_frame((void **)&yuv_buffer,&len); 4 convert_yuv_to_rgb_buffer(yuv_buffer,rgb_buffer,640,480); 5 6 frame->loadFromData((uchar *)rgb_buffer,640 * 480 * 3); 7 8 ui->label->setPixmap(QPixmap::fromImage(*frame,Qt::AutoColor)); 9 10 rs = vd->unget_frame();11 }
工程:zed_YUV_camera.zip
- 视频的采集和动态显示(三)
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示
- 基于ZedBoard的Webcam设计(三):视频的采集和动态显示-----学习心得---zed上用v4l2做cam显示视频
- zedboard--zedboard的qt测试和usb视频采集和显示(十六)
- iOS视频采集(三)
- 视频采集显示分辨率
- WebRTC之本地视频采集(三)
- dsp下基于双循环缓冲队列的视频采集和显示记录
- 采集视频,并在PC上显示出采集到的视频的程序
- Windows远程桌面实现之三(电脑内部声音采集,录音采集,摄像头视频采集)
- 视频采集和处理
- 基于Video4linux的视频采集,用SDL显示
- 基于Video4linux的视频采集,用SDL显示
- 基于Video4linux的视频采集,用SDL显示
- win音视频--Dshow视频采集显示
- 入门视频采集与处理(显示YUV数据)
- 入门视频采集与处理(显示YUV数据)
- extjs.4.1,4.2,结合 jquery 遮罩层,ajax 请求时 数据遮罩,动态加载 contral
- do...while(0) do...while(false)的妙用
- HTML DOM setTimeout
- Python数学与随机数 (math包,random包)
- iphone5 适配
- 视频的采集和动态显示(三)
- MyEclipse中svn无法个更新文件
- hdu4607
- chinaunix 内核源码分析精贴
- ROS探索总结(十四)——move_base(路径规划)
- ArcGIS for android 离线地图 案例
- 从两个例子分析C语言的声明
- Asp.net循环遍历服务器文件夹及文件
- Java中Integer和String浅谈