標籤:
資料連結:http://www.cnblogs.com/emouse/archive/2013/03/03/2943243.html
1.開啟網路攝影機的裝置節點檔案。
fd = open (dev_name, O_RDWR | O_NONBLOCK, 0);
2.擷取裝置驅動資訊。
int ioctl(int fd, int request, struct v4l2_capability *argp);
ioctl (fd, VIDIOC_QUERYCAP, &cap);
VIDIOC_QUERYCAP ::查詢裝置屬性。
struct v4l2_capability{ u8 driver[16]; // 驅動名字 u8 card[32]; // 裝置名稱字 u8 bus_info[32]; // 裝置在系統中的位置 u32 version; // 驅動版本號碼 u32 capabilities; // 裝置支援的操作 u32 reserved[4]; // 保留欄位};
3.設定映像格式。
VIDIOC_G_FMT, VIDIOC_S_FMT
檢查是否支援某種格式:VIDIOC_TRY_FMT
My Code:
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 320; fmt.fmt.pix.height = 240; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; ioctl (fd, VIDIOC_S_FMT, &fmt) ;
相關函數:
int ioctl(int fd, int request, struct v4l2_format *argp);
相關結構體:
struct v4l2_format{ enum v4l2_buf_type type; // 框架類型,應用程式設定 union fmt { struct v4l2_pix_format pix; // 視頻裝置使用 struct v4l2_window win; struct v4l2_vbi_format vbi; struct v4l2_sliced_vbi_format sliced; u8 raw_data[200]; };};struct v4l2_pix_format{ u32 width; // 幀寬,單位像素 u32 height; // 幀高,單位像素 u32 pixelformat; // 框架格式 enum v4l2_field field; u32 bytesperline; u32 sizeimage;enum v4l2_colorspace colorspace;u32 priv;};
例:顯示當前幀的相關資訊
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.pix.width,fmt.fmt.pix.height);struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1){if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat){printf(“\tformat:%s\n”,fmtdesc.description);break;}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”);
4.申請幀緩衝
ioctl (fd, VIDIOC_REQBUFS, &req);
My Code:
req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; ioctl (fd, VIDIOC_REQBUFS, &req);
應用程式和裝置有三種交換資料的方法,直接 read/write、記憶體映射(memory mapping)
和使用者指標。這裡只討論記憶體映射(memory mapping)。
向裝置申請緩衝區 VIDIOC_REQBUFS
int ioctl(int fd, int request, struct v4l2_requestbuffers *argp);
相關結構體:
struct v4l2_requestbuffers{u32 count; // 緩衝區內緩衝幀的數目enum v4l2_buf_type type; // 緩衝幀資料格式enum v4l2_memory memory; // 區別是記憶體映射還是使用者指標方式u32 reserved[2];};
V4L2規範編程