午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

(轉載)基于ZedBoard的Webcam設計(三):視頻的采集和動態(tài)顯示

 enchen008 2013-11-05

(原創(chuàng))基于ZedBoard的Webcam設計(一):USB攝像頭(V4L2接口)的圖片采集(原創(chuàng))基于ZedBoard的Webcam設計(二):USB攝像頭圖片采集+QT顯示兩篇博客中,我們完成了ZedBoard上USB攝像頭的圖片采集,以及將圖片顯示到Qt界面上??墒钱吘共杉惋@示到只是一幀圖像,并非動態(tài)的視頻數(shù)據(jù)。本小節(jié)將在介紹V4L2更新視頻緩沖的方式、Qt paintEvent更新控件的基礎上,實現(xiàn)如何實現(xiàn)視頻的動態(tài)顯示。

更多更新請關注我的博客:@超群天晴 http://www.cnblogs.com/surpassal/ 

 

相關閱讀 :

(原創(chuàng))基于ZedBoard的Webcam設計(一):USB攝像頭(V4L2接口)的圖片采集

(原創(chuàng))基于ZedBoard的Webcam設計(二):USB攝像頭圖片采集+QT顯示

(原創(chuàng))基于ZedBoard的Webcam設計(三):視頻的采集和動態(tài)顯示

(原創(chuàng))基于ZedBoard的Webcam設計(四):MJPG編碼和AVI封裝

(原創(chuàng))基于ZedBoard的Webcam設計(五):x264編碼在zedboard上的實現(xiàn)(軟編碼)

 

硬件平臺:Digilent ZedBoard

開發(fā)環(huán)境:Windows XP 32 bit + Wmare 8.0 + Ubuntu 10.04 +Qt+ arm-linux-xilinx-gnueabi交叉編譯環(huán)境 

Zedboard linux: Digilent OOB Design  

 

一、V4l2更新緩沖Buffer的方法

 回顧上一節(jié)中,我們使用v4l2控制usb 攝像頭,對攝像頭的靜態(tài)圖片采集流程操作過程可以歸納為圖1:

圖1 靜態(tài)圖片采集流程圖

所用到的函數(shù)和參數(shù)都在旁邊標注出。可以看到使用命令VIDIOC_DQBUF將緩存中的圖像幀取出,然后攝像頭設備是一直在采集圖像,如果沒有更新緩存區(qū)命令,采集到的新數(shù)據(jù)是不會被更新到緩存中的。v4l2提供了與VIDIOC_DQBUF命令相對的命令VIDIOC_QBUF,我對這個命令的理解就是允許攝像頭設備將采集圖像更新到緩存區(qū)。假設開辟的緩存FIFO大小為4幀,如圖2(a),當使用VIDIOC_DQBUF命令后,當前幀n從FIFO中取走,F(xiàn)IFO留下一個空缺,如圖2(b),這種情況下如果使用VIDIOC_QBUF命令,新一幀n+4將被寫入緩存,如圖2(c)。

圖2 緩存FIFO與VIDIOC_DQBUF命令、VIDIOC_QBUF命令

所以為了實現(xiàn)緩存區(qū)圖像數(shù)據(jù)的動態(tài)更新,需要在每一次處理完數(shù)據(jù)后使用VIDIOC_QBUF更新緩存區(qū),以便下一次VIDIOC_DQBUF獲取到新的一幀數(shù)據(jù)。因而動態(tài)更新緩存的視頻采集流程應該如圖3所示:

 

圖3 動態(tài)視頻采集流程

 為此,需要重新定義兩個函數(shù),一個我們定義為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釋放視頻幀,讓出緩存空間準備新的視頻幀數(shù)據(jù):

復制代碼
 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事件

在上篇博客里面,我們對采集的的視頻幀數(shù)據(jù)的顯示,采用的方法是使用了一個QLabel和QPixmap,并使用loadfromdata函數(shù)將采集的數(shù)據(jù)轉為QPixmap中的數(shù)據(jù),并顯示到QLabel上。這樣的做法導致的結果是QLabel和QPixmap數(shù)據(jù)只能被更新一次,所以只能顯示靜態(tài)圖片。

在完成了視頻緩存數(shù)據(jù)更新后,我們所面臨的問題就是怎么樣才能把這個數(shù)據(jù)動態(tài)顯示出來。好在Qt提供了窗口刷新事件paintEvent,在這里,我們可以使用兩種方式觸發(fā)paintEvent事件:

1、使用定時器QTimer,定時為33ms(因為攝像頭的幀頻為30pfs);

2、不使用定時器,由QLabel自身內容改變產生。這里采用這種方式。paintEvent函數(shù)內容:

復制代碼
 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 }
復制代碼

 

三、測試效果

在ubuntu上測試通過后,移植到Zedboard上進行測試,測試視頻:

 

 

==================================

工程:zed_YUV_camera.zip

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多