基于嵌入式Linux的视频采集系统19-----源程序----v4l_driver.h

2019-07-13 05:16发布

本文来自:
http://blog.chinaunix.net/uid-23093301-id-86408.html

#include "v4l2_driver.h" #include "log.h" #include #include #include #include #include
#define HEADERFRAME1 0xaf

CVideoDriver::CVideoDriver() { logtrace(("CVideoDriver::CVideoDriver begin.... ")); logtrace(("CVideoDriver::CVideoDriver end ok ")); }
CVideoDriver::~CVideoDriver() { logtrace(("CVideoDriver::~CVideoDriver begin.... ")); logtrace(("CVideoDriver::~CVideoDriver end ok ")); } //CVideoDriver* CVideoDriver::globle_ptr = NULL;
//CVideoDriver& CVideoDriver::instance() //{ // if(globle_ptr == NULL) // { // globle_ptr = new CVideoDriver; // } // return *globle_ptr; //}
int CVideoDriver::start(const string& dev,const int& width,const int& height,const int& fps,const int& format) { logtrace(("CVideoDriver::start begin.... ")); usb_video_device_name = dev; m_cap_width  = width; m_cap_height = height; m_cap_fps   = fps; m_cap_fmt    = format;
m_video_input.width = width; m_video_input.height = height; m_video_input.fps    = fps; m_video_input.formatIn = format; m_video_input.framesizeIn = (m_video_input.width * m_video_input.height << 1); //m_video_input.tmpbuffer   = (unsigned char *) calloc(1, (size_t) m_video_input.framesizeIn); //m_video_input.framebuffer = (unsigned char *) calloc(1, (size_t) m_video_input.width * (m_video_input.height + 8) * 2); if(init_device()) { logerror(("CVideoDriver::start failed when init device ")); return -1; } logtrace(("CVideoDriver::open end ok ")); return 0; }
int CVideoDriver::close() { logtrace(("CVideoDriver::close.... ")); int ret = 0; disable(); //free((void*)m_video_input.tmpbuffer); //m_video_input.tmpbuffer = NULL; //ret = close(m_video_input.fd); logtrace(("CVideoDriver::close end ok ret=<%d> ",ret)); return ret; }
int CVideoDriver::capture(unsigned char* pimage) {
logtrace(("CVideoDriver::capture begin.... ")); int ret = 0; size_t var_used =0; if (enalbe()) { logerror(("CVideoDriver::capture faild when enable ")); goto fatal; } memset(&m_video_input.buf, 0, sizeof(struct v4l2_buffer));     m_video_input.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; m_video_input.buf.memory = V4L2_MEMORY_MMAP; //logdebug(("CVideoDriver::capture begin VIDIOC_DQBUF ")); ret = ioctl(m_video_input.fd, VIDIOC_DQBUF, &m_video_input.buf); if (ret < 0) {    logerror(("CVideoDriver::capture faild when VIDIOC_DQBUF "));    m_video_input.isstreaming = false;    disable();    goto fatal; } if (m_video_input.buf.bytesused <= HEADERFRAME1) {    /* Prevent crash                                                 * on empty image */ logdebug(("CVideoDriver::capture,empty buffer ")); ret = ioctl(m_video_input.fd, VIDIOC_QBUF, &m_video_input.buf); return 0; } memcpy((void*)pimage, m_video_input.mem[m_video_input.buf.index], m_video_input.buf.bytesused); //memcpy(m_video_input.tmpbuffer, m_video_input.mem[m_video_input.buf.index], m_video_input.buf.bytesused); var_used = m_video_input.buf.bytesused; //logdebug(("CVideoDriver::capture,buf.bytesused=<%d>. ", m_video_input.buf.bytesused)); ret = ioctl(m_video_input.fd, VIDIOC_QBUF, &m_video_input.buf); if(ret) { logerror(("CVideoDriver::capture,VIDIOC_QBUF failed ")); goto fatal; } logtrace(("CVideoDriver::capture end ok ret=<%d> ",ret)); return var_used; fatal: return -1; }


int CVideoDriver::init_device() { logtrace(("CVideoDriver::init_device.... ")); //int i = 0; int ret = -1; //! set formate  if ((m_video_input.fd = open(usb_video_device_name.c_str(), O_RDWR)) == -1) {    logerror(("CVideoDriver::init_device failed when open=<%s> ",usb_video_device_name.c_str()));    return ret; } ret = set_format(); if(ret < 0) { logerror(("CVideoDriver::init_device failed when set_format ")); return ret; } ret = set_framerate(); if(ret < 0) { logerror(("CVideoDriver::init_device failed when set_framerate ")); return ret; } ret = set_map_buffer(); if(ret < 0) { logerror(("CVideoDriver::init_device failed when set_map_buffer ")); return ret; } logtrace(("CVideoDriver::init_device end ok ")); return ret; }
int CVideoDriver::set_format() { logtrace(("CVideoDriver::set_format.... ")); int ret = 0; memset(&m_video_input.fmt, 0, sizeof(struct v4l2_format)); m_video_input.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; m_video_input.fmt.fmt.pix.width = m_video_input.width; m_video_input.fmt.fmt.pix.height = m_video_input.height; m_video_input.fmt.fmt.pix.pixelformat = m_video_input.formatIn; m_video_input.fmt.fmt.pix.field = V4L2_FIELD_ANY;    ret = ioctl(m_video_input.fd, VIDIOC_S_FMT, &m_video_input.fmt); logtrace(("CVideoDriver::set_format end  ret=<%d> ",ret)); return ret; }

int CVideoDriver::set_framerate() { logtrace(("CVideoDriver::close.... ")); int ret = 0; struct v4l2_streamparm var_fps; struct v4l2_streamparm *setfps = &var_fps;          memset(setfps, 0, sizeof(struct v4l2_streamparm));     setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;     setfps->parm.capture.timeperframe.numerator = 1;     setfps->parm.capture.timeperframe.denominator = m_video_input.fps;     ret = ioctl(m_video_input.fd, VIDIOC_S_PARM, setfps);     if(ret<0){      logerror(("CVideoDriver::set_framerate failed "));      return ret;     } logtrace(("CVideoDriver::set_framerate end ok ret=<%d> ",ret)); return ret; } int CVideoDriver::set_map_buffer() { logtrace(("CVideoDriver::set_map_buffer.... ")); int i,ret = 0; video_input* vd = &m_video_input; /* * request buffers   */  memset(&vd->rb, 0, sizeof(struct v4l2_requestbuffers));  vd->rb.count = NB_BUFFER;  vd->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  vd->rb.memory = V4L2_MEMORY_MMAP;  ret = ioctl(vd->fd, VIDIOC_REQBUFS, &vd->rb);  if (ret < 0) {    perror("CVideoDriver::set_map_buffer when VIDIOC_REQBUFS");    goto fatal;  } /****** begin to map *******/ for (i = 0; i < NB_BUFFER; i++) { memset(&vd->buf, 0, sizeof(struct v4l2_buffer)); vd->buf.index = i; vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vd->buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(vd->fd, VIDIOC_QUERYBUF, &vd->buf); if (ret < 0) {        perror("CVideoDriver::set_map_buffer,VIDIOC_QUERYBUF failed ");        goto fatal;     } logdebug(("CVideoDriver::set_map_buffer,length=<%d>,offset=<%u> ", vd->buf.length, vd->buf.m.offset)); vd->mem[i] = mmap(  0 /* start anywhere */ ,                vd->buf.length,                 PROT_READ, MAP_SHARED,                 vd->fd,                vd->buf.m.offset); if (vd->mem[i] == MAP_FAILED) { logerror(("CVideoDriver::set_map_buffer,map operation failed ")); goto fatal; }//!! end if logdebug(("CVideoDriver::set_map_buffer,mapped address=<%p>", vd->mem[i])); }//! end for //! Queue the buffers. for (i = 0; i < NB_BUFFER; ++i) {    memset(&vd->buf, 0, sizeof(struct v4l2_buffer));    vd->buf.index = i;    vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    vd->buf.memory = V4L2_MEMORY_MMAP;    ret = ioctl(vd->fd, VIDIOC_QBUF, &vd->buf);    if (ret < 0) {     logerror(("CVideoDriver::set_map_buffer,VIDIOC_QBUF failed "));      goto fatal;;    }//! end if }//! end for  logtrace(("CVideoDriver::set_map_buffer end ok ret=<%d> ",ret)); return ret; fatal: return ret; }
int CVideoDriver::enalbe() { logtrace(("CVideoDriver::enalbe.... ")); int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int ret =0; if(m_video_input.isstreaming) { //logdebug(("CVideoDriver::enalbe has enabled ")); return ret; } ret = ioctl(m_video_input.fd, VIDIOC_STREAMON, &type); if (ret < 0) { logerror(("CVideoDriver::enalbe failed when VIDIOC_STREAMON ")); return ret; } m_video_input.isstreaming = true; logtrace(("CVideoDriver::enalbe end ok ret=<%d> ",ret)); return ret; } int CVideoDriver::disable() { logtrace(("CVideoDriver::disable.... ")); int ret = 0; int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
ret = ioctl(m_video_input.fd, VIDIOC_STREAMOFF, &type); if (ret < 0) { logerror(("CVideoDriver::enalbe failed when VIDIOC_STREAMOFF ")); return ret; } m_video_input.isstreaming = false; logtrace(("CVideoDriver::disable end ok ret=<%d> ",ret)); return ret; }
int CVideoDriver::isv4l2Control(const int& control,struct v4l2_queryctrl& queryctrl) { int err =0; struct v4l2_queryctrl var_queryctrl = queryctrl; var_queryctrl.id = control; if ((err= ioctl(m_video_input.fd, VIDIOC_QUERYCTRL, &var_queryctrl)) < 0) { perror("ioctl querycontrol error "); return -1; }
if (var_queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { fprintf(stderr, "control %s disabled ", (char *) var_queryctrl.name); return -1; }
if (var_queryctrl.type & V4L2_CTRL_TYPE_BOOLEAN) { return 1; }
if (var_queryctrl.type & V4L2_CTRL_TYPE_INTEGER) { return 0; }
fprintf(stderr, "contol %s unsupported   ", (char *) var_queryctrl.name); queryctrl = var_queryctrl; return 1; } int CVideoDriver::v4l2GetControl(const int& control)  { struct v4l2_queryctrl queryctrl; struct v4l2_control control_s; int err;
if ((err = isv4l2Control(control, queryctrl)) < 0) {    return -1; }
control_s.id = control; if ((err = ioctl(m_video_input.fd, VIDIOC_G_CTRL, &control_s)) < 0) {    return -1; }
return control_s.value;
} int CVideoDriver::v4l2_up_control(const int& control) { logtrace(("CVideoDriver::v4l2_up_control begin control=<%d>.. ",control)); int ret = 0; struct v4l2_control control_s; struct v4l2_queryctrl queryctrl; int min, max, current, step, val_def; int err;
if (isv4l2Control(control, queryctrl) < 0) { logerror(("CVideoDriver::v4l2_up_control failed when isv4l2Control "));    return -1; } min = queryctrl.minimum; max = queryctrl.maximum; step = queryctrl.step; val_def = queryctrl.default_value; if ( (current = v4l2GetControl(control)) == -1 ) { logerror(("CVideoDriver::v4l2_up_control failed when v4l2GetControl ")); return -1; } logdebug(("CVideoDriver::v4l2_up_control,current=<%d>,step=<%d>,max=<%d> ",current,step,max));    current = 24;//! max invalid = 30 //fprintf(stderr, "max %d, min %d, step %d, default %d ,current %d ",max,min,step,val_def,current); if (current <= max) {    control_s.id = control;    control_s.value = current;    if ((err = ioctl(m_video_input.fd, VIDIOC_S_CTRL, &control_s)) < 0) {     logerror(("CVideoDriver::v4l2_up_control failed when VIDIOC_S_CTRL "));      return -1;    }    //fprintf(stderr, "Control name:%s set to value:%d ", queryctrl.name, control_s.value); } else {    //fprintf(stderr, "Control name:%s already has max value:%d ", queryctrl.name, max);  logerror(("CVideoDriver::v4l2_up_control failed when current > max "));    return -1; }
logtrace(("CVideoDriver::v4l2_up_control end ok ret=<%d> ",ret)); return ret; }