C語言高階應用---操作linux下V4L2攝像頭應用程式
阿新 • • 發佈:2019-01-23
#include "CameralOpt.h" int video_fd ; int length ; char *yuv[COUNT] ; struct v4l2_buffer enqueue , dequeue ; //定義出入隊的操作結構體成員 int Init_Cameral(int Width , int Hight) { //引數檢查 char *videodevname = NULL ; videodevname = "/dev/video0" ; //開啟裝置 video_fd = open(videodevname , O_RDWR); if(-1 == video_fd ) { perror("open video device fail"); return -1 ; } int i ; int ret ; struct v4l2_format format ; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; format.fmt.pix.width = Width; format.fmt.pix.height = Hight; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV ; //我支援的格式是這個 ret = ioctl(video_fd , VIDIOC_S_FMT , &format); if(ret != 0) { perror("set video format fail"); return -2 ; } //申請buffer,切割成幾個部分 //3 struct v4l2_requestbuffers requestbuffer ; requestbuffer.count = COUNT ; requestbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; requestbuffer.memory = V4L2_MEMORY_MMAP ; ret = ioctl(video_fd , VIDIOC_REQBUFS , &requestbuffer); if(ret != 0) { perror("request buffer fail "); return -3 ; } //querybuffer struct v4l2_buffer querybuffer ; querybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; querybuffer.memory = V4L2_MEMORY_MMAP ; for(i = 0 ; i < COUNT ; i++) { querybuffer.index = i ; ret = ioctl(video_fd , VIDIOC_QUERYBUF , &querybuffer); if(ret != 0) { perror("query buffer fail"); return -4 ; } // printf("index:%d length:%d offset:%d \n" , // querybuffer.index , querybuffer.length , querybuffer.m.offset); length = querybuffer.length ; //將攝像頭記憶體印射到程序的記憶體地址 yuv[i] = mmap(0,querybuffer.length , PROT_READ | PROT_WRITE , MAP_SHARED , video_fd , querybuffer.m.offset ); //列隊 struct v4l2_buffer queuebuffer ; queuebuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; queuebuffer.memory = V4L2_MEMORY_MMAP ; queuebuffer.index = i ; ret = ioctl(video_fd , VIDIOC_QBUF , &queuebuffer); if(ret != 0) { perror("queuebuffer fail"); return -5 ; } } //初始化入隊出隊 enqueue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; dequeue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; enqueue.memory = V4L2_MEMORY_MMAP ; dequeue.memory = V4L2_MEMORY_MMAP ; return 0 ; } int Exit_Cameral(void) { int i ; for(i = 0 ; i < COUNT ; i++) munmap(yuv+i , length); close(video_fd); return 0 ; } int Start_Cameral(void) { //開啟攝像頭 int ret ; int on = 1 ; ret = ioctl(video_fd , VIDIOC_STREAMON , &on); if(ret != 0) { perror("start Cameral fail"); return -1 ; } return 0 ; } int Stop_Cameral(void) { //停止攝像頭 int ret ; int off= 1 ; ret = ioctl(video_fd , VIDIOC_STREAMOFF, &off); if(ret != 0) { perror("stop Cameral fail"); return -1 ; } return 0 ; } int Get_Picture(char *buffer) { int ret ; //出隊 ret = ioctl(video_fd , VIDIOC_DQBUF , &dequeue); if(ret != 0) { perror("dequeue fail"); return -1 ; } //獲取圖片資料 YUV yuv[dequeue.index] memcpy(buffer , yuv[dequeue.index] , dequeue.length); // write(yuyv_fd , yuv[dequeue.index] , dequeue.length); enqueue.index = dequeue.index ; ret = ioctl(video_fd , VIDIOC_QBUF , &enqueue); if(ret != 0) { perror("enqueue fail"); return -2 ; } return 0 ; }
執行結果:樓主本人,長得醜別噴。