Linux環境應用程式設計(九) Camera

2021-10-08 11:26:02 字數 4731 閱讀 3006

1、概念

可以支援多種裝置,它可以有以下幾種介面:

(5)收音機介面(radio inte***ce):可用來處理從am或fm高頻頭裝置接收來的音訊流.

v4l2在linux系統中的結構圖:

2、程式設計模式

v4l2是針對uvc免驅usb裝置的程式設計框架,主要用於採集usb攝像頭等,程式設計模式如下:

(2)申請影象幀緩衝,並進行記憶體對映,將這些幀緩衝區從核心空間對映到使用者空間,便於應用程式讀取、處理影象資料;

(5)釋放資源,停止採集工作。

從結構圖中可以看出v4l2是乙個字元裝置,而v4l2的大部分功能都是通過裝置檔案的ioctl匯出的。

1、ioctl常用指令分類:

query capability:查詢裝置支援的功能,只有vidioc_querycap乙個。

優先順序相關:包括vidioc_g_priority,vidioc_s_priority,設定優先順序。

id描述vidioc_enum_fmt

列舉裝置所支援的所有資料格式

vidioc_s_fmt

設定資料格式

vidioc_g_fmt

獲取資料格式

vidioc_try_fmt

與vidioc_s_fmt一樣,但不會改變裝置的狀態

vidioc_reqbufs

vidioc_querybuf

查詢緩衝區的狀態

vidioc_qbuf

vidioc_dqbuf

vidioc_overlay

開始或者停止overlay

vidioc_g_fbuf

獲取video overlay裝置或osd裝置的framebuffer引數

vidioc_s_fbuf

設定framebuffer引數

vidioc_streamon

開始流i/o操作,capture or output device

vidioc_streamoff

關閉流i/o操作

id描述vidioc_enumstd

列舉裝置支援的所有標準

vidioc_g_std

獲取當前正在使用的標準

vidioc_s_std

vidioc_querystd

2、具體流程圖

1、開啟裝置檢視屬性

struct v4l2_capability ;

struct v4l2_capability tv4l2cap;

ifd = open(strdevname, o_rdwr);

if (ifd < 0)

ptvideodevice->ifd = ifd;

ierror = ioctl(ifd, vidioc_querycap, &tv4l2cap);

memset(&tv4l2cap, 0, sizeof(struct v4l2_capability));

ierror = ioctl(ifd, vidioc_querycap, &tv4l2cap);

if (ierror)

if (!(tv4l2cap.capabilities & v4l2_cap_video_capture))

if (tv4l2cap.capabilities & v4l2_cap_streaming)

if (tv4l2cap.capabilities & v4l2_cap_readwrite)

2、顯示所有支援的格式v4l2_fmtdesc 結構體描述當前camera支援的格式資訊,使用命令vidioc_enum_fmt查詢, v4l2_fmtdesc結構體中index要設定,從0開始;v4l2_buf_type type也要設定,如果使用的是camera裝置,則v4l2_buf_type type要設定為v4l2_buf_type_video_capture,因為camera是capture裝置。結構體中的其他內容driver會填充。

struct v4l2_fmtdesc ;

struct v4l2_fmtdesc tfmtdesc;

memset(&tfmtdesc, 0, sizeof(tfmtdesc));

tfmtdesc.index = 0;

tfmtdesc.type = v4l2_buf_type_video_capture;

while ((ierror = ioctl(ifd, vidioc_enum_fmt, &tfmtdesc)) == 0)

tfmtdesc.index++;

}

3、設定影象幀格式struct v4l2_format結構體需要設定enum v4l2_buf_type type和union fmt中的struct v4l2_pix_format pix。enum v4l2_buf_type type因為使用的是camera裝置,camera是capture裝置,所以設定成v4l2_buf_type_video_capture。struct v4l2_pix_format pix設定一幀影象的長、寬和格式等,由於要適配lcd輸出,所以長、寬設定為lcd支援的長、寬。

struct v4l2_format  fmt;

};struct v4l2_format tv4l2fmt;

/* set format in */

getdispresolution(&ilcdwidth, &ilcdheigt, &ilcdbpp);

memset(&tv4l2fmt, 0, sizeof(struct v4l2_format));

tv4l2fmt.type = v4l2_buf_type_video_capture;

tv4l2fmt.fmt.pix.pixelformat = ptvideodevice->ipixelformat;

tv4l2fmt.fmt.pix.width = ilcdwidth;

tv4l2fmt.fmt.pix.height = ilcdheigt;

tv4l2fmt.fmt.pix.field = v4l2_field_any;

ierror = ioctl(ifd, vidioc_s_fmt, &tv4l2fmt);

4、申請緩衝區申請乙個擁有nb_buffer個緩衝幀的緩衝區,__u32 count為緩衝幀的數目;enum v4l2_buf_type type和前文一樣,同樣設定成v4l2_buf_type_video_capture;enum v4l2_memorymemory用來區分是記憶體對映還是使用者指標,我們使用記憶體對映的方式,所以設定成v4l2_memory_mmap。

struct v4l2_requestbuffers ;

struct v4l2_requestbuffers tv4l2reqbuffs;

/* request buffers */

memset(&tv4l2reqbuffs, 0, sizeof(struct v4l2_requestbuffers));

tv4l2reqbuffs.count = nb_buffer;

tv4l2reqbuffs.type = v4l2_buf_type_video_capture;

tv4l2reqbuffs.memory = v4l2_memory_mmap;

ierror = ioctl(ifd, vidioc_reqbufs, &tv4l2reqbuffs);

if (ierror)

5、將申請的緩衝幀從核心空間對映到使用者空間並將緩衝幀放如佇列

struct v4l2_buffer  m;

__u32 length;

__u32 reserved2;

__u32 reserved;

};struct v4l2_buffer tv4l2buf;

if (tv4l2cap.capabilities & v4l2_cap_streaming)

ptvideodevice->ivideobufmaxlen = tv4l2buf.length;

ptvideodevice->pucvidebuf[i] = mmap(0 /* start anywhere */ ,

tv4l2buf.length, prot_read, map_shared, ifd,

tv4l2buf.m.offset);

if (ptvideodevice->pucvidebuf[i] == map_failed)

}

/* queue the buffers. */

for (i = 0; i < ptvideodevice->ivideobufcnt; i++) }}

Linux串列埠應用程式設計

常見的資料通訊的基本方式可分為並行通訊與序列通訊兩種。1.並行通訊是指利用多條資料傳輸線將乙個字資料的各位元位同時傳送。它的特點是傳輸速度快,適用於傳輸距離短且傳輸速度較高的通訊。2.序列通訊是指利用一條傳輸線將資料以位元位為單位順序傳送。特點是通訊 線路簡單,利用簡單的線纜就可實現通訊,降低成本,...

Linux應用程式設計 mmap

二話不說,上來就問下那個man name mmap,munmap map or unmap files or devices into memory synopsis include void mmap void addr,size t length,int prot,int flags,int f...

Linux環境應用程式設計(二) 記憶體分配

許多系統程式需要為動態資料結構 鍊錶和二叉樹 分配額外記憶體,此類資料結構的大小由執行時獲取的資訊決定。程序可以通過增加堆的大小來分配記憶體,所謂堆是一段長度可變的連續虛擬記憶體,始於程序的未初始化資料段末尾,隨著記憶體的分配和釋放而增減,通常將堆的當前記憶體邊界稱為 program break 1...