v4l2程式設計
1.定義 2.
工作流程:
開啟裝置-> 檢查和設定裝置屬性-> 設定幀格式-> 設定一種輸入輸出方法(緩衝區管理)-> 迴圈獲取資料-> 關閉裝置。
3.裝置的開啟和關閉:
#include
int open(const char *device_name, int flags);
#include
int close(int fd); 例:
int fd=open(「/dev/video0」,o_rdwr);//
開啟裝置
close(fd);//
關閉裝置
注意:v4l2
的相關定義包含在標頭檔案中.
4.查詢裝置屬性:
vidioc_querycap
int ioctl(int fd, int request, struct v4l2_capability *argp);
struct v4l2_capability ;
capabilities
常用值:
v4l2_cap_video_capture //
是否支援影象獲取
例:顯示裝置資訊
struct v4l2_capability cap;
ioctl(fd,vidioc_querycap,&cap);
printf(「driver name:%s/ncard name:%s/nbus info:%s/ndriver version:%u.%u.%u/n」,cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0xff, (cap.version>>8)&0xff,cap.version&oxff); 5.
幀格式:
vidioc_enum_fmt // 顯示所有支援的格式
int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);
struct v4l2_fmtdesc ;
例:顯示所有支援的格式
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index=0;
fmtdesc.type=v4l2_buf_type_video_capture;
printf("support format:/n");
while(ioctl(fd,vidioc_enum_fmt,&fmtdesc)!=-1)
// 檢視或設定當前格式
vidioc_g_fmt, vidioc_s_fmt
// 檢查是否支援某種格式
vidioc_try_fmt
int ioctl(int fd, int request, struct v4l2_format *argp);
struct v4l2_format ;
}; struct v4l2_pix_format ;
struct v4l2_format fmt;
fmt.type=v4l2_buf_type_video_capture;
ioctl(fd,vidioc_g_fmt,&fmt);
printf(「current data format information:/n/twidth:%d/n/theight:%d/n」,fmt.fmt.width,fmt.fmt.height);
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index=0;
fmtdesc.type=v4l2_buf_type_video_capture;
while(ioctl(fd,vidioc_enum_fmt,&fmtdesc)!=-1)
fmtdesc.index++; }
例:檢查是否支援某種幀格式
struct v4l2_format fmt;
fmt.type=v4l2_buf_type_video_capture;
fmt.fmt.pix.pixelformat=v4l2_pix_fmt_rgb32;
if(ioctl(fd,vidioc_try_fmt,&fmt)==-1)
if(errno==einval)
printf(「not support
format rgb32!/n」);
6.影象的縮放
vidioc_cropcap
int ioctl(int fd, int request, struct v4l2_cropcap *argp);
struct v4l2_cropcap;//
設定縮放
vidioc_g_crop,vidioc_s_crop
int ioctl(int fd, int request, struct v4l2_crop *argp);
int ioctl(int fd, int request, const struct v4l2_crop *argp);
struct v4l2_crop
7.申請和管理緩衝區,應用程式和裝置有三種交換資料的方法,直接
read/write
,記憶體對映
,使用者指標。這裡只討論
// 向裝置申請緩衝區
vidioc_reqbufs
int ioctl(int fd, int request, struct v4l2_requestbuffers *argp);
struct v4l2_requestbuffers ;
enum v4l2_memoy ;
//count,type,memory 都要應用程式設定
例:申請乙個擁有四個緩衝幀的緩衝區
struct v4l2_requestbuffers req;
req.count=4;
req.type=v4l2_buf_type_video_capture;
req.memory=v4l2_memory_mmap;
ioctl(fd,vidioc_reqbufs,&req);
vidioc_querybuf
int ioctl(int fd, int request, struct v4l2_buffer *argp);
struct v4l2_buffer ;
__u32 length;// 緩衝幀長度
__u32 input;
__u32 reserved; };
mmap ,定義乙個結構體來對映每個緩衝幀。
struct buffer
*buffers;
#include
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
//addr 對映起始位址,一般為null ,讓核心自動選擇
//length 被對映記憶體塊的長度
//prot 標誌對映後能否被讀寫,其值為prot_exec,prot_read,prot_write, prot_none
//flags 確定此記憶體對映能否被其他程序共享,map_shared,map_private
//fd,offset, 確定被對映的記憶體位址
返回成功對映後的位址,不成功返回map_failed ((void*)-1);
int munmap(void *addr, size_t length);// 斷開對映
//addr 為對映後的位址,length 為對映後的記憶體長度
例:將四個已申請到的緩衝幀對映到應用程式,用buffers 指標記錄。
buffers = (buffer*)calloc (req.count, sizeof (*buffers));
if (!buffers)
// 對映
for (unsigned int n_buffers = 0; n_buffers < req.count; ++n_buffers) 8.
緩衝區處理好之後,就可以開始獲取資料了
// 啟動/ 停止資料流
vidioc_streamon,vidioc_streamoff
int ioctl(int fd, int request, const int *argp);
//argp 為流型別指標,如v4l2_buf_type_video_capture.
在開始之前,還應當把緩衝幀放入緩衝佇列:
vidioc_qbuf// 把幀放入佇列
vidioc_dqbuf// 從佇列中取出幀
int ioctl(int fd, int request, struct v4l2_buffer *argp);
例:把四個緩衝幀放入佇列,並啟動資料流
unsigned int i;
enum v4l2_buf_type type;
// 將緩衝幀放入佇列
for (i = 0; i < 4; ++i)
type = v4l2_buf_type_video_capture;
ioctl (fd, vidioc_streamon, &type);
// 這有個問題,這些buf 看起來和前面申請的buf 沒什麼關係,為什麼呢?
例:獲取一幀並處理
struct v4l2_buffer buf;
clear (buf);
buf.type = v4l2_buf_type_video_capture;
buf.memory = v4l2_memory_mmap;
// 從緩衝區取出乙個緩衝幀
ioctl (fd, vidioc_dqbuf, &buf);
// 影象處理
process_image (buffers[buf.index].start);
// 將取出的緩衝幀放回緩衝區
ioctl (fd, vidioc_qbuf, &buf);
V4L2程式設計
include include include include include include include include include include typedef struct buftype buftype user buf int n buffer 0 開啟攝像頭裝置 int ope...
V4L2程式設計 轉
前言 目前正在忙於arm 平台的linux 應用程式的開發 其實是剛剛起步學習啦 底層的東西不用考慮了,開發板子提供了 nand bootloader 和linux 2.6 的原始碼,而且都編譯好了。自己編譯的 bootloader 可以用,但是 linux 編譯後,檔案很大,暫且就用人家編譯的系統...
V4L2程式設計例項
include include include include include include include include include include include include include include define req buf num 4 申請的緩衝區個數,最多5個,緩衝區...