linux下V4l2编程步骤
int init()
{
struct v4l2_cropcap cropcap; struct v4l2_capability capability; struct v4l2_fmtdesc fmtdesc; struct v4l2_format fmt; struct v4l2_format g_fmt; struct v4l2_streamparm fps; struct v4l2_requestbuffers reqbuf; struct v4l2_buffer querybuf; struct v4l2_crop crop; //VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) //#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) struct v4l2_frmsizeenum frm_sizes; struct v4l2_frmivalenum frm_ivalenum; uint32_t stream_on = V4L2_BUF_TYPE_VIDEO_CAPTURE; int32_t ret = 0; m_fd = open("/dev/video0", O_RDWR); qDebug("fd is :%d\n", m_fd); #if 1 memset(&cropcap, 0, sizeof(cropcap)); ret = ioctl(m_fd, VIDIOC_CROPCAP, &cropcap); qDebug("cropcap bounds:%d %d %d %d\n",cropcap.bounds.height, cropcap.bounds.width, cropcap.bounds.top, cropcap.bounds.left); qDebug("cropcap defrect:%d %d %d %d\n",cropcap.defrect.height, cropcap.defrect.width, cropcap.defrect.top, cropcap.defrect.left); #endif #if 1 fmtdesc.index = 0; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while(ioctl(m_fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) { qDebug("--:index:%d, %s %d\n", fmtdesc.index, fmtdesc.description, fmtdesc.pixelformat); fmtdesc.index++; } #endif #if 1 frm_sizes.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; frm_sizes.pixel_format = V4L2_PIX_FMT_YUYV; frm_sizes.index = 0; while(ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &frm_sizes) != -1) { qDebug("support frm size:index:%d h:%d w:%d\n", frm_sizes.index, frm_sizes.discrete.height, frm_sizes.discrete.width); frm_sizes.index++; } #endif #if 1 frm_ivalenum.pixel_format = V4L2_PIX_FMT_YUYV; frm_ivalenum.index = 0; frm_ivalenum.height = CAM_HEIGHT; frm_ivalenum.width = CAM_WIDTH; while(ioctl(m_fd, VIDIOC_ENUM_FRAMEINTERVALS, &frm_ivalenum) != -1) { qDebug("support frame interval:%d %d %d\n",frm_ivalenum.index, frm_ivalenum.discrete.denominator, frm_ivalenum.discrete.numerator); frm_ivalenum.index++; } #endif #if 1 struct v4l2_control control; /*亮度(V4L2_CID_BRIGHTNESS)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_BRIGHTNESS; control.value = 60;//默认值50 (0~100) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("BRIGHTNESS failed \n"); } /*饱和度(V4L2_CID_SATURATION)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_SATURATION; control.value = 50;//默认值32(0~100) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("SATURATION failed \n"); } /*对比度(V4L2_CID_CONTRAST)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_CONTRAST; control.value = 32;//默认值32 (0~100) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("CONTRAST failed \n"); } /*色调(HUE)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_HUE; control.value = 0;//默认值0(-180~180) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("HUE failed \n"); } /*自动白平衡(AUTO_WHITE_BALANCE)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_AUTO_WHITE_BALANCE; control.value = 1;//默认值1(0~1) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("WHITE_BALANCE failed \n"); } /*伽马(V4L2_CID_GAMMA)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_GAMMA; control.value = 8;//默认值8(0~16) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("GAMMA failed \n"); } /*低亮度补偿(V4L2_CID_BACKLIGHT_COMPENSATION)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_BACKLIGHT_COMPENSATION; control.value = 1;//默认值0(0~1) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("test failed \n"); } /*清晰度(V4L2_CID_SHARPNESS)*/ memset(&control, 0, sizeof(control)); control.id = V4L2_CID_SHARPNESS; control.value = 1;//默认值4(0~20) if(ioctl(m_fd, VIDIOC_S_CTRL, &control) < 0) { qDebug("V4L2_CID_SHARPNESS failed \n"); } #endif #if 1 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = CAM_WIDTH; fmt.fmt.pix.height = CAM_HEIGHT; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//V4L2_PIX_FMT_YUV422P;//V4L2_PIX_FMT_MJPEG fmt.fmt.pix.field = V4L2_FIELD_ANY; ret = ioctl(m_fd, VIDIOC_S_FMT, &fmt); g_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; g_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; ret = ioctl(m_fd, VIDIOC_G_FMT, &g_fmt); qDebug("--:%d %d %d\n", ret, g_fmt.fmt.pix.width, g_fmt.fmt.pix.height); #endif #if 0 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c.top = 80; crop.c.left = 0; crop.c.width = CAM_WIDTH; crop.c.height = CAM_HEIGHT; ret = ioctl(m_fd_framebuffer, VIDIOC_S_CROP, &crop); qDebug("-------VIDIOC_S_CROP:%d\n", ret); #endif #if 1 fps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fps.parm.capture.timeperframe.numerator = 1; fps.parm.capture.timeperframe.denominator = 10; ret = ioctl(m_fd, VIDIOC_S_PARM, &fps); #endif reqbuf.count = CAM_BUFF_COUNT; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; ret = ioctl(m_fd, VIDIOC_REQBUFS, &reqbuf); #if 1 for(int i = 0; i < CAM_BUFF_COUNT; i++) { memset(&querybuf, 0, sizeof(querybuf)); querybuf.index = i; querybuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; querybuf.memory = V4L2_MEMORY_MMAP; ret = ioctl(m_fd, VIDIOC_QUERYBUF, &querybuf); camera_buff[i] = (uint8_t *)mmap(0, querybuf.length, PROT_READ, MAP_SHARED, m_fd, querybuf.m.offset); } for(int i = 0; i < CAM_BUFF_COUNT; i++) { memset(&querybuf, 0, sizeof(querybuf)); querybuf.index = i; querybuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; querybuf.memory = V4L2_MEMORY_MMAP; ret = ioctl(m_fd, VIDIOC_QBUF, &querybuf); } ret = ioctl(m_fd, VIDIOC_STREAMON, &stream_on); #endif } void VideoThread::main_loop() { struct timeval tv; struct v4l2_buffer deqbuf; fd_set fds_set; FD_ZERO(&fds_set); FD_SET(m_fd, &fds_set); while(1) { tv.tv_sec = 1; tv.tv_usec = 0; int32_t ret = 0; ret = select(m_fd + 1, &fds_set,NULL,NULL, &tv); if(ret < 0) { qDebug("select)error\n"); } else if(ret == 0) { qDebug("time out\n"); } if(FD_ISSET(m_fd, &fds_set)) { memset(&deqbuf, 0, sizeof(deqbuf)); deqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; deqbuf.memory = V4L2_MEMORY_MMAP; ioctl(m_fd, VIDIOC_DQBUF, &deqbuf); //qDebug("get buffer index:%d size:%d\n", deqbuf.index, deqbuf.bytesused); //memcpy(camera_buf, camera_buff[deqbuf.index], deqbuf.bytesused); //emit camera_capture_picture(camera_buf, deqbuf.bytesused); framebuffer_display(deqbuf.index, deqbuf.bytesused); //hdmi_framebuffer_display(deqbuf.index, deqbuf.bytesused); //m_h264_decoder->push_encode(camera_buff[deqbuf.index], (int)deqbuf.bytesused); //m_vpu_encoder.push_encode(camera_buff[deqbuf.index], (int)deqbuf.bytesused); //void h264decoder::push_encode(uint8_t *buf, int size); deqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; deqbuf.memory = V4L2_MEMORY_MMAP; ioctl(m_fd, VIDIOC_QBUF, &deqbuf); } } }
linux下V4l2编程步骤,查看摄像头支持分辨率和帧率

图片来自https://www.cnblogs.com/emouse/archive/2013/03/04/2943243.html这个图片描述cropcap和format关系比较形象
https://www.cnblogs.com/emouse/archive/2013/03/04/2943243.html

浙公网安备 33010602011771号