【Qt開發】V4L2 API詳解 Buffer的準備和數據讀取

前面主要介紹的是:V4L2 的一些設置接口,如亮度,飽和度,曝光時間,幀數,增益,白平衡等。今天看看V4L2 得到數據的幾個關鍵ioctl,Buffer的申請和數據的抓取。


1. 初始化 Memory Mapping 或 User Pointer I/O.
申請數據Buffer。
int ioctl(int fd, int?requestbuf,?struct v4l2_requestbuffers * argp);
參數一:open()所產生的句柄。
參數二:VIDIOC_REQBUFS
參數三:in/out結構體。
struct v4l2_requestbuffers
{
__u32 count;
enum v4l2_buf_type type;
enum v4l2_memory memory; //Applications set this field to?V4L2_MEMORY_MMAP?or?V4L2_MEMORY_USERPTR
?__u32 reserved[2];
};

注意,有兩種方式的I/O。 Memory Mapping 和User Pointer。
Memory Mapping的Buffer由Driver申請為物理連續的內存空間(Kernel空間)。在此ioctl調用時被分配,需要早于mmap()動作將他們映射到用戶空間。

1.1:Memory Mapping模式詳解:
在使用Memory Mapping模式時,參數三中結構體內每個field都需要設置。


__u32 count; ??//當memory=V4L2_MEMORY_MMAP時,此處才有效。表明要申請的buffer個數。
enum v4l2_buf_type type; ?//Stream 或者Buffer的類型。此處肯定為V4L2_BUF_TYPE_VIDEO_CAPTURE
enum v4l2_memory memory; ?//既然是Memory Mapping模式,則此處設置為:V4L2_MEMORY_MMAP


注意:count是個輸入輸出函數。因為你所申請到的Buffer個數不一定就是你所輸入的Number。所以在ioctl執行后,driver會將真實申請到的buffer個數填充到此field. 這個數目有可能大于你想要申請的,也可能小與,甚至可能是0個。
應用程序可以再次調用ioctl--VIDIOC_REQBUFS 來修改buffer個數。但前提是必須先釋放已經?mapped??buffer?,可以先?munmap?,然后設置參數?count??0?來釋放所有的?buffer


支持Memory ?Mapping ?I/O方式的前提是:v4l2_capability??中支持V4L2_CAP_STREAMING。
在這個模式下,數據本身不會被Copy,只是在Kernel和用戶態之間交換。在應用程序想要訪問到這些數據之前,它必須調用mmap()影射到用戶態。

同時也要注意,通過ioctl申請的內存,是物理內存,無法被交換入Disk,所以一定要釋放:munmap()。



1.2:User Pointer模式:
User Pointer模式時,應用程序實現申請。
只需要填充Type=V4L2_BUF_TYPE_VIDEO_CAPTURE, memory=V4L2_MEMORY_USERPTR




2. 詢問Buffer狀態:
int ioctl(int fd, int request, struct?v4l2_buffer* argp);
參數一:open()所產生的句柄。
參數二:VIDIOC_QUERYBUF
參數三:v4l2_buffer 結構體。(IN/OUT參數)

注意,此ioctl是Memory Mapping的I/O方法之一。User Pointer模式不需要。在Buffer在ioctl-VIDIOC_REQBUFS執行時創建后,隨時都可以調用此Ioctl得到buffer信息。
視頻緩沖區的使用狀態、在內核空間的偏移地址、緩沖區長度等。在應用程序設計中通過調VIDIOC_QUERYBUF來獲取內核空間的視頻緩沖區信息,然后調用函數mmap把內核空間地址映射到用戶空間,這樣應用程序才能夠訪問位于內核空間的視頻緩沖區

我們首先通過v4l2_buffer結構體看看參數三這個輸入輸出參數需要輸入些什么,以及能夠得到什么信息。

struct v4l2_buffer
{
__u32 index;
enum v4l2_buf_type type;
__u32 bytesused;
__u32 flags;
enum v4l2_field field;
struct timeval timestamp;
struct v4l2_timecode timecode;
__u32 sequence;

enum v4l2_memory memory;
union {
__u32 offset;
unsigned long userptr;
} m;
__u32 length;
__u32 input;
__u32 reserved;
};

在調用ioctl--VIDIOC_QUERYBUF時,需要寫入的項目有:
enum v4l2_buf_type type; //V4L2_BUF_TYPE_VIDEO_CAPTURE
__u32 index; ?// 這里需要解釋一下,因為在調用ioctl-VIDIOC_REQBUFS時,建立了count個Buffer。所以,這里index的有效范圍是:0到count-1.


在調用ioctl-VIDIOC_QUERYBUF后,Driver會填充v4l2_buffer 結構體內所有信息供用戶使用。
如果一些正常:
1. flags 中:V4L2_BUF_FLAG_MAPPED,?V4L2_BUF_FLAG_QUEUED?and?V4L2_BUF_FLAG_DONE被設置。
2. memory中,V4L2_MEMORY_MMAP被設置。
3.?m.offset中,從將要mapping 的device memory頭到數據頭的offset.
4.?length?中,填充當前Buffer長度。
5。其它的Field有可能設置,也有可能不被設置。


這樣,mmap()想要有的信息就全了。而mmap()之后,Device Driver 申請的或者Device Memory就能映射到用戶空間。數據就可以被應用程序使用了。這才是ioctl-VIDIOC_QUERYBUF的關鍵作用。



3.和Driver交換buffer:?
對Camera這樣的捕獲設備來說,Device將數據放到Buffer中,用戶得到數據。Device再次將數據放到Buffer中。
那么Device Driver 怎樣知道哪個Buffer是可以存放數據的呢?這就用到當前這兩個ioctl-VIDIOC_QBUF, ioctl-VIDIOC_DQBUF.

ioctl-VIDIOC_QBUF: 將指定的Buffer放到輸入隊列中,即向Device表明這個Buffer可以存放東西。
ioctl-VIDIOC_DQBUF: 將輸出隊列中的數據 buffer取出。

?driver?內部管理著兩個?buffer queues?,一個輸入隊列,一個輸出隊列。對于?capture device?來說,當輸入隊列中的?buffer?被塞滿數據以后會自動變為輸出隊列,等待調用?VIDIOC_DQBUF?將數據進行處理以后重新調用?VIDIOC_QBUF??buffer?重新放進輸入隊列.


用法:
ioctl--VIDIOC_QBUF:
int ioctl(int fd, int request, struct?v4l2_buffer* argp);
參數一:open()所產生的句柄。
參數二:VIDIOC_QBUF
參數三:v4l2_buffer 結構體。(IN/OUT參數)

參數三是IN/OUT 參數。需要填充
enum v4l2_buf_type type; //V4L2_BUF_TYPE_VIDEO_CAPTURE
__u32 index; ?// 這里需要解釋一下,因為在調用ioctl-VIDIOC_REQBUFS時,建立了count個Buffer。所以,這里index的有效范圍是:0到count-1.?
memory:?V4L2_MEMORY_MMAP.

則這個結構體指明的buffer被送入輸出隊列,表明此Buffer可以被device 填充數據。

用法:
ioctl--VIDIOC_DQBUF:
int ioctl(int fd, int request, struct?v4l2_buffer* argp);
參數一:open()所產生的句柄。
參數二:VIDIOC_DQBUF
參數三:v4l2_buffer 結構體。(IN/OUT參數)

從輸出隊列中取出一個有數據的Buffer。這個Buffer中的數據被處理后,此Buffer可以通過ioctl-VIDIOC_QBUF再次放入輸入隊列中去。




4. 開始和結束捕獲:
ioctl--VIDIOC_STREAMON. ioctl--VIDIOC_STREAMOFF

非常簡單的調用。就是開始和結束。

轉載于:https://www.cnblogs.com/huty/p/8518249.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254585.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254585.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254585.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

halcon File文件算子,持續更新

目錄File文件Images圖像read_imageread_sequencewrite_imagedeserialize_imageserialize_imagelist_image_fileparse_filenameMisc混合體copy_filedelete_filefile_existsget_current_dirlist_filesmake_dirread_world_fileremove_dirset_current_dirObject對象deserialize_obj…

Nginx 之一:編譯安裝nginx 1.8.1 及配置

轉http://www.cnblogs.com/zhang-shijie/p/5294162.html 一:基介紹 官網地址www.nginx.org,nginx是由1994年畢業于俄羅斯國立莫斯科鮑曼科技大學的同學為俄羅斯rambler.ru公司開發的,開發工作最早從2002年開始,第一次公開發布時間…

PI校正環節的程序實現推導過程

PI校正環節在經典控制論中非常有用,特別是對負反饋控制系統,基本上都有PI校正環節。1.下面分別說明比例環節和積分環節的作用,以階躍信號為例。①比例環節單獨作用以上分析說明,若只有比例環節的控制系統,階躍響應也是…

XML文檔注釋(C#)

目錄XML文檔編譯器識別的標記添加XLM注釋的方法添加XLM注釋的例子XML文檔 C#可以根據特定的注釋自動創建XML格式的文檔說明。 這些注釋都是單行注釋&#xff0c;但都以三條斜杠開頭 編譯器識別的標記 標記說明<C>把行中的文本標記為代碼&#xff0c;例如<c>int …

vs里根據json快速創建對應類的方法

有時候,我們在調用別人接口的時候,服務端返回了一個json格式的字符串,我們要獲取json里面的數據的話一般有兩種方式: 1.通過正則 2.反序列化成一個對象 第一種方式這里不再多說,主要說一下第二種,(為什么呢&#xff0c;你看到后面 你也會喜歡上第二種) 有人肯定會說, json字符串…

德魯克的《卓有成效的管理者》

是一本很好的書&#xff0c;對我有諸多的啟發&#xff0c;這本書我在短期內連看兩遍呢。 現將一些我覺得有啟發性的句子發給大家分享。 1. 一個人的有效性&#xff0c;與他的智力、想象力或知識之間&#xff0c;幾乎沒有太大的關聯。有才能的人往往最為無效&#xff0c;因為他們…

人工智能之基于face_recognition的人臉檢測與識別

不久乘高鐵出行&#xff0c;看見高鐵火車站已經實現了“刷臉進站”&#xff0c;而且效率很高&#xff0c;很感興趣&#xff0c;今天抽時間研究一下&#xff0c;其實沒那么復雜。 我基本上是基于https://github.com/ageitgey/face_recognition上的資料和源碼做一些嘗試和試驗。 …

iOS 升級https的方案選擇

我的選擇是將UIWebView統一替換為WKWebView WKWebView AFN SDWebImage https的支持之前的博客都有涉及轉載于:https://www.cnblogs.com/Jusive/p/6867531.html

預處理指令(C#)

目錄預處理指令簡介#define、#undef#if、#elif、#else、#endif#warning、#error#region、#endregion#line、#line default#pragma預處理指令簡介 微軟對預處理指令解釋鏈接 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/preprocessor-directives/index…

NSWindowController的初始化創建代碼

-(PRAboutWindowController*)aboutCtrl{ if(_aboutCtrl nil){ _aboutCtrl [[PRAboutWindowController alloc]initWithWindowNibName:"PRAboutWindowController"]; } return _aboutCtrl ; } 轉載于:https://www.cnblogs.com/PJXWang/p/5816675.html

對CMMI3的學習和思考

原文出處&#xff1a; http://tech.it168.com/m/2007-08-02/200708020957750.shtml本文請勿轉載。近來筆者所在公司正在為過CMMI3做各種準備&#xff0c;對公司的員工進行了一些相關的培訓&#xff0c;作為項目管理人員的我&#xff0c;在學習CMMI3的過程中&#xff0c;也有了自…

Python3抓取糗百、不得姐

?點擊關注 異步圖書&#xff0c;置頂公眾號 每天與你分享 IT好書 技術干貨 職場知識 重要提示1:本文所列程序均基于Python3.6,低于Python3.6的Python版本可能無法運行.重要提示2:因所抓取的網站可能隨時更改展示內容,因此程序也需及時跟進.重要提示3:本程序僅供學習,不能拿去做…

halcon邊緣檢測的方法及各種方法的適用范圍

目錄一、邊緣提取二、BLOB分析檢測三、贓物檢測一、邊緣提取 1、設置ROI興趣區域 2、快速二值化&#xff0c;并連接相鄰區域。 這樣做的目的是進一步減少目標區域&#xff0c;通過二值化將目標區域大概輪廓提取出來 3、提取最接近目標區域的輪廓 常用函數有boundary&#xff0…

Oracle優化-表設計

前言  絕大多數的Oracle數據庫性能問題都是由于數據庫設計不合理造成的&#xff0c;只有少部分問題根植于Database Buffer、Share Pool、Redo Log Buffer等內存模塊配置不合理&#xff0c;I/O爭用&#xff0c;CPU爭用等DBA職責范圍上。所以除非是面對一個業已完成不可變更的系…

Win10遠程桌面 出現 身份驗證錯誤,要求的函數不受支持,這可能是由于CredSSP加密Oracle修正 解決方法...

升級至win10 最新版本10.0.17134&#xff0c;遠程桌面連接Window Server時報錯信息如下&#xff1a; 出現身份驗證錯誤&#xff0c;要求的函數不正確&#xff0c;這可能是由于CredSSP加密Oracle修正。 解決方法&#xff1a; 運行 gpedit.msc 本地組策略&#xff1a; 計算機配置…

CMM2

原文出處&#xff1a;http://hi.baidu.com/seaweaver/blog/item/e80e7af427f674d9f2d3854a.html CMM2的六個KPA 1、需求管理 &#xff08;RM&#xff0c;Requirement Management&#xff09; 2、軟件項目計劃 &#xff08;SPP&#xff0c;Software Project Planning&#…

查看linux系統核數

查看linux系統核數&#xff1a; grep ^processor /proc/cpuinfo | wc -l轉載于:https://www.cnblogs.com/myyan/p/5822368.html

Rsyslog 日志相關內容

[rootserver vusers_home]# rpm -ql rsyslog|more ###.so結尾為模塊&#xff0c;模塊有分im為輸入模塊&#xff0c;om 為輸出模塊/etc/logrotate.d/syslog/etc/pki/rsyslog/etc/rc.d/init.d/rsyslog/etc/rsyslog.conf/etc/rsyslog.d/etc/sysconfig/rsyslog/lib64/rsyslog…

MFC導出對話框類DLL的實現

1.新建基于對話框的應用程序 2.新建MFC DLL工程 3.選擇MFC DLL 4.選擇擴展Dll選項&#xff08;重要&#xff01;&#xff01;&#xff01;&#xff09; 5.為Dll工程添加一個MFC類&#xff0c;基類為CDialogEx 6.Dll新建的MFC 類中添加resource.h防止編譯出錯…

中國如何引進CMM評估,促進軟件產業發展

北京軟件行業協會 &#xff08;本文轉載自軟件工程專家網www.21cmm.com&#xff09; 一、CMM的含義及作用   CMM&#xff08;軟件能力成熟度模型&#xff1a;Capability Maturity Model For Software&#xff09;是由美國卡內基梅 隆大學的軟件工程研究所&#xff08;SEI&a…