Linux下的V4L2程式設計

2021-05-24 21:26:14 字數 4534 閱讀 4452

一.設定採集方式,格式 常用命令標誌

extern int ioctl (int __fd, unsigned long int __request, …) __throw;

__request:具體的命令標誌符。

在進行v4l2開發中,一般會用到以下的命令標誌符:

vidioc_reqbufs:分配記憶體

vidioc_querycap:查詢驅動功能

vidioc_s_fmt:設定當前驅動的頻捕獲格式

vidioc_g_fmt:讀取當前驅動的頻捕獲格式

vidioc_try_fmt:驗證當前驅動的顯示格式

vidioc_cropcap:查詢驅動的修剪能力

vidioc_qbuf:把資料從快取中讀取出來

vidioc_dqbuf:把資料放回快取佇列

這些io呼叫,有些是必須的,有些是可選擇的。

1. 開啟裝置檔案。

int fd=open(」/dev/video0″,o_rdwr);

v4l2_std_id std;

do while (ret == -1 && errno == eagain);

switch (std) fmt;

struct v4l2_pix_format

__u32                   width;         // 寬,必須是16 的倍數

__u32                   height;        // 高,必須是16 的倍數

enum v4l2_field         field;

__u32                   bytesperline;   

__u32                   sizeimage;

enum v4l2_colorspace    colorspace;

__u32                   priv;      

樣例:memset ( &fmt, 0, sizeof(fmt) );

fmt.type = v4l2_buf_type_video_capture;

fmt.fmt.pix.width = 320;

fmt.fmt.pix.height = 240;

fmt.fmt.pix.pixelformat = v4l2_pix_fmt_jpeg;

if (ioctl(fd, vidioc_s_fmt, &fmt) < 0)

printf("set format failed/n");

//return 0;

5. 向驅動申請幀緩衝,一般不超過5個。struct 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];

樣例:struct v4l2_requestbuffers req;

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

req.count = 4;

req.type = v4l2_buf_type_video_capture;

req.memory = v4l2_memory_mmap;

if (ioctl(fd,vidioc_reqbufs,&req) == -1)

perror("vidioc_reqbufs error /n");

//return -1;

6.申請物理記憶體 ,並將申請到的幀緩衝對映到使用者空間,這樣就可以直接操作採集到的幀了,而不必去複製。將申請到的幀緩衝全部入佇列,以便存放採集到的資料.vidioc_qbuf,struct v4l2_buffer

videobuffer*          buffers = calloc( req.count, sizeof(videobuffer) );

printf("sizeof(videobuffer) is %d/n",sizeof(videobuffer));

struct v4l2_buffer    buf;

for (numbufs = 0; numbufs < req.count; 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) < 0)

printf("vidioc_querybuf error/n");

//return -1;

printf("buf len is %d/n",sizeof(buf));

//記憶體對映

buffers[numbufs].length = buf.length;

buffers[numbufs].offset = (size_t) buf.m.offset;

buffers[numbufs].start = mmap (null, buf.length,prot_read | prot_write, map_shared, fd, buf.m.offset);

printf("buffers.length = %d,buffers.offset = %d ,buffers.start[0] = %d/n",buffers[numbufs].length,buffers[numbufs].offset,buffers[numbufs].start[0]);

printf("buf2 len is %d/n",sizeof(buffers[numbufs].start));

if (buffers[numbufs].start == map_failed)

perror("buffers error/n");

//return -1;

if (ioctl (fd, vidioc_qbuf, &buf) < 0)

printf("vidioc_qbuf error/n");

//return -1;

enum v4l2_buf_type type;

type = v4l2_buf_type_video_capture;  

if (ioctl (fd, vidioc_streamon, &type) < 0)

printf("vidioc_streamon error/n");

// return -1;

8. 出佇列以取得已採集資料的幀緩衝,取得原始採集資料。vidioc_dqbuf, 將緩衝重新入佇列尾,這樣可以迴圈採集。vidioc_qbuf

if (ioctl(fd, vidioc_dqbuf, &buf) < 0)

perror("vidioc_dqbuf failed./n");

//return -1;

buf.type = v4l2_buf_type_video_capture;

buf.memory = v4l2_memory_mmap;

unsigned char *ptcur = buffers[numbufs].start;

debug("buf.bytesused = %d /n",buf.bytesused);

int i1;

for(i1=0; i1if((buffers[numbufs].start[i1] == 0x000000ff) && (buffers[numbufs].start[i1+1] == 0x000000c4))

debug("huffman table finded! /nbuf.bytesused = %d/nffc4 = %d /n",buf.bytesused,i1);

break;     

if(i1 == buf.bytesused)printf("huffman table don't exist! /n"); 

int i;

for(i=0; iif((buffers[numbufs].start[i] == 0x000000ff) && (buffers[numbufs].start[i+1] == 0x000000d8)) break;       

ptcur++;

debug("i=%d,ff=%02x,d8=%02x/n",i,buffers[numbufs].start[i],buffers[numbufs].start[i+1]);

int imagesize =buf.bytesused - i;

debug("buf.bytesused = %d /n",buf.bytesused);

debug ("imagesize = %d /n",imagesize);

V4L2程式設計

include include include include include include include include include include typedef struct buftype buftype user buf int n buffer 0 開啟攝像頭裝置 int ope...

V4L2 程式設計

v4l2程式設計 1.定義 2.工作流程 開啟裝置 檢查和設定裝置屬性 設定幀格式 設定一種輸入輸出方法 緩衝區管理 迴圈獲取資料 關閉裝置。3.裝置的開啟和關閉 include int open const char device name,int flags include int close ...

V4L2程式設計 轉

前言 目前正在忙於arm 平台的linux 應用程式的開發 其實是剛剛起步學習啦 底層的東西不用考慮了,開發板子提供了 nand bootloader 和linux 2.6 的原始碼,而且都編譯好了。自己編譯的 bootloader 可以用,但是 linux 編譯後,檔案很大,暫且就用人家編譯的系統...