Qt---Linux平臺Qt5用V4L2讀取攝像頭,實現實時畫面和拍照

平臺:ubuntu14.04

工具:qt5.7_opensource版本

Desktop

 

1. V4L2的介紹:

摘自http://www.cnblogs.com/silence-hust/p/4464291.html

大部分都一樣的流程,多看幾遍再結合代碼就可以看懂的。

 

一、Video for Linux two

  v4l2爲linux下視頻設備程序提供了一套接口規範。包括一套數據結構和底層V4L2驅動接口。只能在linux下使用。它使程序有發現設備和操作設備的能力。它主要是用一系列的回調函數來實現這些功能。像設置攝像頭的頻率、幀頻、視頻壓縮格式和圖像參數等等。當然也可以用於其他多媒體的開發,如音頻等。

  在Linux下,所有外設都被看成一種特殊的文件,成爲“設備文件”,可以象訪問普通文件一樣對其進行讀寫。一般來說,採用V4L2驅動的攝像頭設備文是/dev/v4l/video0。爲了通用,可以建立一個到/dev/video0的鏈接。V4L2支持兩種方式來採集圖像:內存映射方式(mmap)和直接讀取方式(read)。V4L2在include/linux/videodev.h文件中定義了一些重要的數據結構,在採集圖像的過程中,就是通過對這些數據的操作來獲得最終的圖像數據。Linux系統V4L2的能力可在Linux內核編譯階段配置,默認情況下都有此開發接口。V4L2從Linux 2.5.x版本的內核中開始出現。

  V4L2規範中不僅定義了通用API元素(Common API Elements),圖像的格式(Image Formats),輸入/輸出方法(Input/Output),還定義了Linux內核驅動處理視頻信息的一系列接口(Interfaces),這些接口主要有:

  視頻採集接口——Video Capture Interface;

  視頻輸出接口—— Video Output Interface;

  視頻覆蓋/預覽接口——Video Overlay Interface;

  視頻輸出覆蓋接口——Video Output Overlay Interface;

  編解碼接口——Codec Interface。

二、v4l2結構體介紹

1、常用的結構體在內核目錄include/linux/videodev2.h中定義

        struct v4l2_requestbuffers        //申請幀緩衝,對應命令VIDIOC_REQBUFS 
        struct v4l2_capability        //視頻設備的功能,對應命令VIDIOC_QUERYCAP 
        struct v4l2_input        //視頻輸入信息,對應命令VIDIOC_ENUMINPUT
        struct v4l2_standard        //視頻的制式,比如PAL,NTSC,對應命令VIDIOC_ENUMSTD 
        struct v4l2_format        //幀的格式,對應命令VIDIOC_G_FMT、VIDIOC_S_FMT等
        struct v4l2_buffer        //驅動中的一幀圖像緩存,對應命令VIDIOC_QUERYBUF 
        struct v4l2_crop        //視頻信號矩形邊框

        v4l2_std_id        //視頻制式

 

 

常用結構體的內容:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

struct v4l2_capability

 

{

 

u8 driver[16]; // 驅動名字

 

u8 card[32]; // 設備名字

 

u8 bus_info[32]; // 設備在系統中的位置

 

u32 version; // 驅動版本號

 

u32 capabilities; // 設備支持的操作

 

u32 reserved[4]; // 保留字段

 

};

  其中域 capabilities 代表設備支持的操作模式,常見的值有 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING 表示是一個視頻捕捉設備並且具有數據流控制模式;另外 driver 域需要和 struct video_device 中的 name 匹配。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

struct v4l2_format { 

    enum v4l2_buf_type type; 

    union 

        struct v4l2_pix_format         pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 

        struct v4l2_window             win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ 

        struct v4l2_vbi_format         vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */ 

        struct v4l2_sliced_vbi_format  sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ 

        __u8   raw_data[200];                   /* user-defined */ 

    } fmt; 

}; 

 

enum v4l2_buf_type { 

    V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1, 

    V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2, 

    V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3, 

    ... 

    V4L2_BUF_TYPE_PRIVATE              = 0x80, 

}; 

   

struct v4l2_pix_format { 

    __u32                   width; 

    __u32                   height; 

    __u32                   pixelformat; 

    enum v4l2_field         field; 

    __u32                   bytesperline;   /* for padding, zero if unused */ 

    __u32                   sizeimage; 

    enum v4l2_colorspace    colorspace; 

    __u32                   priv;           /* private data, depends on pixelformat */ 

};

  常見的捕獲模式爲 V4L2_BUF_TYPE_VIDEO_CAPTURE 即視頻捕捉模式,在此模式下 fmt 聯合體採用域 v4l2_pix_format:其中 width 爲視頻的寬、height 爲視頻的高、pixelformat 爲視頻數據格式(常見的值有 V4L2_PIX_FMT_YUV422P | V4L2_PIX_FMT_RGB565)、bytesperline 爲一行圖像佔用的字節數、sizeimage 則爲圖像佔用的總字節數、colorspace 指定設備的顏色空間。

 

struct v4l2_requestbuffers 與 VIDIOC_REQBUFS ,VIDIOC_REQBUFS 命令通過結構 v4l2_requestbuffers 請求驅動申請一片連續的內存用於緩存視頻信息:

1

2

3

4

5

6

7

8

9

10

11

struct v4l2_requestbuffers {

    __u32                   count;

    enum v4l2_buf_type      type;

    enum v4l2_memory        memory;

    __u32                   reserved[2];

};

enum v4l2_memory {

    V4L2_MEMORY_MMAP             = 1,

    V4L2_MEMORY_USERPTR          = 2,

    V4L2_MEMORY_OVERLAY          = 3,

};

count 指定根據圖像佔用空間大小申請的緩存區個數,type 爲視頻捕獲模式,memory 爲內存區的使用方式。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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;

  

    /* memory location */

    enum v4l2_memory    memory;

    union {

            __u32   offset;

            unsigned long   userptr;

    } m;

    __u32    length;

    __u32    input;

    __u32    reserved;

};

  index 爲緩存編號

  type 爲視頻捕獲模式

  bytesused 爲緩存已使用空間大小

  flags 爲緩存當前狀態(常見值有 V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE,分別代表當前緩存已經映射、緩存可以採集數據、緩存可以提取數據)

  timestamp 爲時間戳

  sequence爲緩存序號

  memory 爲緩存使用方式

  offset 爲當前緩存與內存區起始地址的偏移

  length 爲緩存大小

  reserved 一般用於傳遞物理地址值。

  另外 VIDIOC_QBUF 和 VIDIOC_DQBUF 命令都採用結構 v4l2_buffer 與驅動通信:VIDIOC_QBUF 命令向驅動傳遞應用程序已經處理完的緩存,即將緩存加入空閒可捕獲視頻的隊列,傳遞的主要參數爲 index;VIDIOC_DQBUF 命令向驅動獲取已經存放有視頻數據的緩存,v4l2_buffer 的各個域幾乎都會被更新,但主要的參數也是 index,應用程序會根據 index 確定可用數據的起始地址和範圍。

 

2、常用的IOCTL接口命令也在include/linux/videodev2.h中定義

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         //檢查當前視頻設備支持的標準,例如PAL或NTSC。

三、調用v4l2的工作流程

  打開設備-> 檢查和設置設備屬性-> 設置幀格式-> 設置一種輸入輸出方法(緩衝 區管理)-> 循環獲取數據-> 關閉設備。

2. qt代碼實現

https://download.csdn.net/download/sunny_hu92/10356887

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章