Buffer的準備和資料讀取

2021-06-22 20:14:12 字數 4512 閱讀 5901

int ioctl(int fd, int requestbuf, 

struct v4l2_requestbuffers * argp

); 引數一:open()所產生的控制代碼。

引數二:

vidioc_reqbufs

引數三:in/out結構體。

struct v4l2_requestbuffers ;

__u32 count;  

//當memory=

v4l2_memory_mmap時,此處才有效。表明要申請的buffer個數。

enum v4l2_buf_type type;  

//stream 或者buffer的型別。此處肯定為v

4l2_buf_type_video_capture

enum v4l2_memory memory;  

v4l2_memory_mmap

注意:count是個輸入輸出函式。 因為你所申請到的buffer個數不一定就是你所輸入的number。所以在ioctl執行後,driver會將真實申請到的buffer個數填充到此field. 這個數目有可能大於你想要申請的,也可能小與,甚至可能是0個。

應用程式可以再次呼叫ioctl--

vidioc_reqbufs 來修改buffer個數。

但前提是必須先釋放已經

的 buffer

,可以先

munmap

,然後設定引數

count

為 0來釋放所有的

buffer。

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引數)

vidioc_reqbufs

執行時建立後,隨時都可以呼叫此ioctl得到buffer資訊。

我們首先通過v4l2_buffer結構體看看引數三這個輸入輸出引數需要輸入些什麼,以及能夠得到什麼資訊。

struct v4l2_buffer

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_queuedand 

v4l2_buf_flag_done被設定。

2. memory中,v4l2_memory_mmap被設定。

3. 

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

非常簡單的呼叫。就是開始和結束。

資料探索和資料準備的步驟

如我們所知,資料分析工作的70 的時間都用作於資料清洗,資料探索和資料準備當中,這可以說是資料分析的核心所在。資料清洗主要是工具層面上的,這裡先不討論。我們這裡討論資料探索和資料準備的六大步驟。在對資料分析之前,我們需要去識別變數,去了解變數的型別和資料的型別。比如判別變數是分型別變數的還是連續型變...

pandas 資料區域讀取和數字填充

一.資料區域讀取和資料填充 有時候excel檔案資料雜亂 用pandas區域讀取和填充 import pandas as pd from datetime import timedelta,date data pd.read excel c users administrator desktop b...

準備 演算法和資料結構(一 鍊錶及其翻轉)

鍊錶鍊錶應該是面試時被提及的最頻繁的資料結構。鍊錶是由指標把若干個結點連線成鏈狀結構。鍊錶的建立,插入結點,刪除結點等操作都只需要20行左右的 就能實現,比較適合面試。題目 輸入乙個鍊錶的頭結點,從尾到頭 反過來列印出每個結點的值。要求不改變鍊錶的結構。思路 通過遞迴來實現反過來輸出鍊錶,當訪問到乙...