一.設定採集方式,格式 常用命令標誌
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 編譯後,檔案很大,暫且就用人家編譯的系統...