目錄
二、V4L2的应用
首頁 資料庫 mysql教程 V4L2驱动的移植与应用(二)

V4L2驱动的移植与应用(二)

Jun 07, 2016 pm 03:33 PM
下面 介紹 應用 簡單 驅動

二、 V4L2 的应用 下面简单介绍一下 V4L2 驱动的应用流程。 1、 视频采集的基本流程 一般的,视频采集都有如下流程: 2、 打开视频设备 在 V4L2 中,视频设备被看做一个文件。使用 open 函数打开这个设备: // 用非阻塞模式打开摄像头设备 int cameraFd; cam

二、V4L2的应用

    下面简单介绍一下V4L2驱动的应用流程。

1、  视频采集的基本流程

一般的,视频采集都有如下流程:

 

 

2、  打开视频设备

V4L2中,视频设备被看做一个文件。使用open函数打开这个设备:

// 用非阻塞模式打开摄像头设备
int cameraFd;
cameraFd = open("/dev/video0", O_RDWR | O_NONBLOCK, 0);
//
如果用阻塞模式打开摄像头设备,上述代码变为:
//cameraFd = open("/dev/video0", O_RDWR, 0);

关于阻塞模式和非阻塞模式:应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。

3、  设定属性及采集方式

打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理:

extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;

__fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd

__request:具体的命令标志符。

在进行V4L2开发中,一般会用到以下的命令标志符:

VIDIOC_REQBUFS:分配内存

VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址

VIDIOC_QUERYCAP:查询驱动功能

VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式

VIDIOC_S_FMT:设置当前驱动的频捕获格式

VIDIOC_G_FMT:读取当前驱动的频捕获格式

VIDIOC_TRY_FMT:验证当前驱动的显示格式

VIDIOC_CROPCAP:查询驱动的修剪能力

VIDIOC_S_CROP:设置视频信号的边框

VIDIOC_G_CROP:读取视频信号的边框

VIDIOC_QBUF:把数据从缓存中读取出来

VIDIOC_DQBUF:把数据放回缓存队列

VIDIOC_STREAMON:开始视频显示函数

VIDIOC_STREAMOFF:结束视频显示函数

VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PALNTSC

这些IO调用,有些是必须的,有些是可选择的。

4、  检查当前视频设备支持的标准

在亚洲,一般使用PAL720X576)制式的摄像头,而欧洲一般使用NTSC720X480),使用VIDIOC_QUERYSTD来检测:

v4l2_std_id std;
do {
  ret = ioctl(fd, VIDIOC_QUERYSTD, &std);
} while (ret == -1 && errno == EAGAIN);
switch (std) {
    case V4L2_STD_NTSC:
        //……
    case V4L2_STD_PAL:
        //……
}

5、  设置视频捕获格式

当检测完视频设备支持的标准后,还需要设定视频捕获格式:

struct v4l2_format    fmt;
memset ( &fmt, 0, sizeof(fmt) );
fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width       = 720;
fmt.fmt.pix.height      = 576;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
  return -1;
}

v4l2_format结构体定义如下:

struct v4l2_format
{
    enum v4l2_buf_type type;    //
数据流类型,必须永远是
V4L2_BUF_TYPE_VIDEO_CAPTURE
    union
    {
        struct v4l2_pix_format    pix; 
        struct v4l2_window        win; 
        struct v4l2_vbi_format    vbi; 
        __u8    raw_data[200];         
    } fmt;
};
struct v4l2_pix_format
{
    __u32                   width;         //
宽,必须是16的倍数

    __u32                   height;        //
高,必须是16的倍数
    __u32                   pixelformat;   //
视频数据存储类型,例如是YUV422还是RGB
    enum v4l2_field         field;
    __u32                   bytesperline;   
    __u32                   sizeimage;
    enum v4l2_colorspace    colorspace;
    __u32                   priv;      
};

6、  分配内存

接下来可以为视频捕获分配内存:

struct v4l2_requestbuffers  req;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
  return -1;
}

v4l2_requestbuffers定义如下:

struct v4l2_requestbuffers
{
    __u32               count;  //
缓存数量,也就是说在缓存队列里保持多少张照片

    enum v4l2_buf_type  type;   //
数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE
    enum v4l2_memory    memory; // V4L2_MEMORY_MMAP
V4L2_MEMORY_USERPTR
    __u32               reserved[2];
};

7、  获取并记录缓存的物理空间

使用VIDIOC_REQBUFS,我们获取了req.count个缓存,下一步通过调用VIDIOC_QUERYBUF命令来获取这些缓存的地址,然后使用mmap函数转换成应用程序中的绝对地址,最后把这段缓存放入缓存队列:

 

typedef struct VideoBuffer {
    void   *start;
    size_t  length;
} VideoBuffer;

VideoBuffer*          buffers = calloc( req.count, sizeof(*buffers) );
struct v4l2_buffer    buf;

for (numBufs = 0; numBufs     memset( &buf, 0, sizeof(buf) );
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    buf.index = numBufs;
    //
读取缓存

    if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
        return -1;
    }

    buffers[numBufs].length = buf.length;
    //
转换成相对地址
    buffers[numBufs].start = mmap(NULL, buf.length,
        PROT_READ | PROT_WRITE,
        MAP_SHARED,
        fd, buf.m.offset);

    if (buffers[numBufs].start == MAP_FAILED) {
        return -1;
    }

    //
放入缓存队列
    if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
        return -1;
    }
}

8、  关于视频采集方式

操作系统一般把系统使用的内存划分成用户空间和内核空间,分别由应用程序管理和操作系统管理。应用程序可以直接访问内存的地址,而内核空间存放的是供内核访问的代码和数据,用户不能直接访问。v4l2捕获的数据,最初是存放在内核空间的,这意味着用户不能直接访问该段内存,必须通过某些手段来转换地址。

一共有三种视频采集方式:

1)使用readwrite方式:直接使用readwrite函数进行读写。这种方式最简单,但是这种方式会在用户空间和内核空间不断拷贝数据,同时在用户空间和内核空间占用大量内存,效率不高。

2)内存映射方式(mmap):把设备里的内存映射到应用程序中的内存控件,直接处理设备内存,这是一种有效的方式。上面的mmap函数就是使用这种方式。

3)用户指针模式:内存由用户空间的应用程序分配,并把地址传递到内核中的驱动程序,然后由v4l2驱动程序直接将数据填充到用户空间的内存中。这点需要在v4l2_requestbuffers里将memory字段设置成V4L2_MEMORY_USERPTR

第一种方式效率是最低的,后面两种方法都能提高执行的效率,但是对于mmap 方式,文档中有这样一句描述 --Remember the buffers are allocated in physical memory, as opposed to virtual memory which can be swapped out to disk. Applications should free the buffers as soon as possible with the munmap () function .(使用mmap方法的时候,buffers相当于是在内核空间中分配的,这种情况下,这些buffer是不能被交换到虚拟内存中,虽然这种方法不怎么影响读写效率,但是它一直占用着内核空间中的内存,当系统的内存有限的时候,如果同时运行有大量的进程,则对系统的整体性能会有一定的影响。)

       所以,对于三种视频采集方式的选择,推荐的顺序是 userptr mmap read-write 。当使用 mmap userptr 方式的时候,有一个环形缓冲队列的概念,这个队列中,有 n buffer ,驱动程序采集到的视频帧数据,就是存储在每个 buffer 中。在每次用 VIDIOC_DQBUF 取出一个 buffer ,并且处理完数据后,一定要用 VIDIOC_QBUF 将这个 buffer 再次放回到环形缓冲队列中。环形缓冲队列,也使得这两种视频采集方式的效率高于直接 read/write

9、  处理采集数据

V4L2有一个数据缓存,存放req.count数量的缓存数据。数据缓存采用FIFO的方式,当应用程序调用缓存数据时,缓存队列将最先采集到的视频数据缓存送出,并重新采集一张视频数据。这个过程需要用到两个ioctl命令,VIDIOC_DQBUFVIDIOC_QBUF

struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory=V4L2_MEMORY_MMAP;
buf.index=0;

//读取缓存
if (ioctl(cameraFd, VIDIOC_DQBUF, &buf) == -1)
{
    return -1;
}
//…………
视频处理算法
//
重新放入缓存队列
if (ioctl(cameraFd, VIDIOC_QBUF, &buf) == -1) {

    return -1;
}

10、              关闭视频设备

使用close函数关闭一个视频设备

close(cameraFd)

(待续)

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1253
24
羅技ghub驅動不支援win7嗎? -羅技ghub驅動為什麼只能安裝在c盤? 羅技ghub驅動不支援win7嗎? -羅技ghub驅動為什麼只能安裝在c盤? Mar 18, 2024 pm 05:37 PM

羅技ghub驅動是不是不支援win7?不相容。由於Windows7已停止更新且不再是微軟的主要作業系統,許多新軟體不再支援它,如羅技ghub。羅技驅動的主要介面:1.軟體主介面在左邊,三個按鈕依序是燈光,按鍵,靈敏度設定。 2.燈光介面的設置中,一般特效比較常規,音頻視覺效果是亮點,可以根據聲音頻率變色,根據高中低音頻段來進行設置,有不同的顏色和效果。 3.按鍵設定中,使用者可以根據自己有什麼特殊要求的可以在這裡編輯。 4.靈敏度設定裡面有很多用戶會有一些屬於自己的設置,可以自己加DPI速度切換點,但是

如何在iPhone中撤銷從主畫面中刪除 如何在iPhone中撤銷從主畫面中刪除 Apr 17, 2024 pm 07:37 PM

從主畫面中刪除了重要內容並試圖將其取回?您可以透過多種方式將應用程式圖示放回螢幕。我們已經討論了您可以遵循的所有方法,並將應用程式圖示放回主畫面如何在iPhone中撤消從主畫面中刪除正如我們之前提到的,有幾種方法可以在iPhone上恢復此變更。方法1–替換應用程式庫中的應用程式圖示您可以直接從應用程式庫將應用程式圖示放置在主畫面上。步驟1–橫向滑動以尋找應用程式庫中的所有應用程式。步驟2–找到您先前刪除的應用程式圖示。步驟3–只需將應用程式圖示從主庫拖曳到主畫面上的正確位置即可。這是將應用程式圖

PHP中箭頭符號的作用及實作應用 PHP中箭頭符號的作用及實作應用 Mar 22, 2024 am 11:30 AM

PHP中箭頭符號的作用及實踐應用在PHP中,箭頭符號(-&gt;)通常用於存取物件的屬性和方法。物件是PHP中物件導向程式設計(OOP)的基本概念之一,在實際開發中,箭頭符號在操作物件時發揮重要作用。本文將介紹箭頭符號的作用以及實踐應用,並提供具體的程式碼範例來幫助讀者更好地理解。一、箭頭符號的作用存取物件的屬性箭頭符號可以用來存取物件的屬性。當我們實例化一個對

從入門到精通:探索Linux tee命令的各種應用場景 從入門到精通:探索Linux tee命令的各種應用場景 Mar 20, 2024 am 10:00 AM

Linuxtee命令是一個非常有用的命令列工具,它可以在不影響已有輸出的情況下,將輸出寫入檔案或將輸出送到另一個命令。在本文中,我們將深入探索Linuxtee命令的各種應用場景,從入門到精通。 1.基本用法首先,我們來看看tee指令的基本用法。 tee指令的語法如下:tee[OPTION]...[FILE]...該指令會從標準輸入讀取數據,並將數據

win11沒有數位簽章的驅動程式怎麼安裝_Win11驅動沒有數位簽章的處理教學課程 win11沒有數位簽章的驅動程式怎麼安裝_Win11驅動沒有數位簽章的處理教學課程 Mar 20, 2024 pm 04:46 PM

有些用戶在安裝win11電腦的驅動程式時遇到了一些問題,電腦提示無法驗證此文件的數位簽名,導致無法安裝驅動,這該怎麼解決呢?詳細請看下文介紹。 1.按【Win+X】組合鍵,或【右鍵】點選工作列上的【Windows標誌】,在開啟的選單項目中,選擇【執行】;2、執行窗口,輸入【powershell】指令,然後按【Ctrl+Shift+Enter】以管理員權限打開WindowsPowershell窗口;3、用戶帳戶控制窗口,你要允許此應用程式對你的設備進行更改嗎?點擊【是】;4、管理員:WindowsPowers

探索Go語言的優勢及應用場景 探索Go語言的優勢及應用場景 Mar 27, 2024 pm 03:48 PM

Go語言是一種由Google開發的開源程式語言,於2007年首次發布。它被設計成一種簡單易學、高效、並發性強的語言,受到越來越多開發者的青睞。本文將探討Go語言的優勢,並介紹一些適合Go語言的應用場景,同時給出具體的程式碼範例。優勢並發性強:Go語言內建支援輕量級執行緒-goroutine,能夠輕鬆實現並發程式設計。透過使用go關鍵字就可以啟動goroutin

什麼是狗狗幣 什麼是狗狗幣 Apr 01, 2024 pm 04:46 PM

狗狗幣是一種基於網路迷因創建的加密貨幣,沒有固定的供應上限,交易時間快速,交易費用低,擁有龐大的迷因社群。用途包括小額交易、打賞和慈善捐贈。然而,其無限供應量、市場波動和作為笑話幣的地位也帶來風險和擔憂。什麼是狗狗幣?狗狗幣是一種基於網路迷因和笑話創建的加密貨幣。起源與歷史:2013年12月,兩位軟體工程師BillyMarkus和JacksonPalmer創立狗狗幣。靈感來自於當時流行的"Doge"模因,一個以一隻柴犬為特徵的滑稽照片加上破碎英語。特徵與優勢:無限供應量:與比特幣等其他加密貨

網上查成績平台介紹(方便快速的成績查詢工具) 網上查成績平台介紹(方便快速的成績查詢工具) Apr 30, 2024 pm 08:19 PM

快速的成績查詢工具、這為學生和家長提供了更方便,隨著網路的發展,越來越多的教育機構和學校開始提供線上查成績的服務。讓您輕鬆掌握孩子的學業進展,本文將介紹幾個常用的線上查成績平台。一、便捷-透過網路查詢成績平台可以隨時隨地查詢孩子的考試成績家長可以方便地隨時查詢孩子的考試成績,透過在電腦或手機登入對應的網路查詢成績平台。只要有網路連結、無論是在工作中或在外出時、家長都可以及時了解孩子的學習情況,對孩子進行針對性地輔導和幫助。二、多種功能-除了成績查詢,還提供課表、考試安排等資訊許多網路查成

See all articles