• Linux下实现视频读取


      V4L(video4linux是一些视频系统,视频软件、音频软件的基础,经常时候在需要采集图像的场合,如视频监控,webcam,可视电话,经常
    使用在embedded linux中是linux嵌入式开发中经常使用的系统接口。它是linux内核提供给用户空间的编程接口,各种的视频和音频设备开
    发相应的驱动程序后,就可以通过v4l提供的系统API来控制视频和音频设备,也就是说v4l分为两层,底层为音视频设备在内核中的驱动,上
    层为系统提供的API,而对于我们来说需要的就是使用这些系统API。
    V4L2是V4L的升级版本,为linux下视频设备程序提供了一套接口规范。包括一套数据结构和底层V4L2驱动接口。V4L2采用流水线的方式,
    操作更简单直观,基本遵循打开视频设备、设置格式、处理数据、关闭设备,更多的具体操作通过ioctl函数来实现。

    1、打开设备
      int open(const char *device_name, int flags);
      int fd = open("/dev/video0", O_RDONLY); //O_NONBLOCK --非阻塞(不推荐使用)
    2、关闭设备 int close(int fd)
      int ret = close(fd);
    3、v4l2_capability 查看属性
      int ioctl(int fd, int request, struct v4l2_capability *argp);
      struct v4l2_capability
      {
        u8 driver[16]; // 驱动名字
        u8 card[32]; // 设备名字
        u8 bus_info[32]; // 设备在系统中的位置
        u32 version; // 驱动版本号
        u32 capabilities; // 设备支持的操作
        u32 reserved[4]; // 保留字段
      };

    4、设置视频格式与制式
    相关函数:
    int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);
    int ioctl(int fd, int request, struct v4l2_format *argp);

    相关结构体:
    v4l2_cropcap 结构体用来设置摄像头的捕捉能力,在捕捉上视频时应先先设置
    v4l2_cropcap 的 type 域,再通过 VIDIO_CROPCAP 操作命令获取设备捕捉能力的参数,保存于 v4l2_cropcap 结构体中,包括 bounds
    (最大捕捉方框的左上角坐标和宽高),defrect(默认捕捉方框的左上角坐标和宽高)等。
    v4l2_format 结构体用来设置摄像头的视频制式、帧格式等,在设置这个参数时应先填 好 v4l2_format 的各个域,如 type(传输流类型),
    fmt.pix.width(宽),fmt.pix.heigth(高),fmt.pix.field(采样区域,如隔行采样),fmt.pix.pixelformat(采样类型,如 YUV4:2:2),
    然后通过 VIDIO_S_FMT 操作命令设置视频捕捉格式。
    struct v4l2_fmtdesc
    {
    u32 index; // 要查询的格式序号,应用程序设置
    enum v4l2_buf_type type; // 帧类型,应用程序设置
    u32 flags; // 是否为压缩格式
    u8 description[32]; // 格式名称
    u32 pixelformat; // 格式
    u32 reserved[4]; // 保留
    };
    所有的视频格式可以能下面的方法查看
    #define v4l2_fourcc(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
    All format : VIDIOC_ENUM_FMT, v4l2_fmtdesc

    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;
    };

    5、查看视频的帧率
    int ioctl(int fd, int request, struct v4l2_streamparm parm* argp);
    struct v4l2_streamparm parm;
    parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    其中VIDIOC_G_PARM是用取帧率的,VIDIOC_S_PARM是用来设定帧率

    6、定制ioctl函数
    在内核目录下找到kernel/include/linux/videodev2.h头文件,你可查看所有的io控制的命令
    /*
    * Experimental, third param 0--video, 1--tracking
    */
    #define VIDIOC_POCCESS_NOTIFY _IOW('V', 99, int) //add by Henry.Wen 20131126

    实例:

    #ifndef CAMERA_V4L2CAMERA_H
    #define CAMERA_V4L2CAMERA_H
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <getopt.h>             /* getopt_long() */
    #include <fcntl.h>              /* low-level i/o */
    #include <unistd.h>
    #include <errno.h>
    #include <malloc.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/mman.h>
    #include <sys/ioctl.h>
    #include <asm/types.h>          /* for videodev2.h */
    #include <linux/videodev2.h>
    
    #define CONFIG_CAMERA_UVC_INVAL_FRAMECNT    5
    
    namespace v4l2
    {
    	/**
    	 * return error code
    	 */
    	enum _RET_ERROR_CODE
    	{
    		RET_ERROR_FAIL = -1,
    		RET_ERROR_OK = 0,
    		RET_ERROR_CAPTURE_NULL = -9999,
    		RET_ERROR_CAPTURE_NAME,
    		RET_ERROR_CAPTURE_CAPABILITY,
    		RET_ERROR_CAPTURE_FORMAT,
    		RET_ERROR_CAPTURE_BUFFER,
    		RET_ERROR_CAPTURE_OUTMEMORY,
    		RET_ERROR_CAPTURE_MMAP,
    		RET_ERROR_CAPTURE_FORM,
    		RET_ERROR_CAPTURE_MUMAP,
    		RET_ERROR_CAPTURE_VIDIOC,
    	};
    
    	/**
    	 *  Name: video_format enum
    	 *  Function: Describe formats V4L2 will support
    	 */
    	typedef enum _pFormat
    	{
    		UNKNOWN,
    		YUYV,
    		MJPEG,
    		YV12,
    		YU12,
    		NV12,
    		NV21,
    		H264,
    	}pFormat;
    
    	/**
    	 * frame width and height infomation
    	 */
    	typedef struct _V4l2Info
    	{
    		unsigned int width;
    		unsigned int height;
    		unsigned int stepWidth;
    		unsigned int length;
    		void*        buffer;
    	}V4l2Info;
    
    	/**
    	 * caputre properties
    	 */
    	typedef struct _V4l2Capture
    	{
    		pFormat      format;
    		char         name[31];//dev_name
    		int          fd;
    		unsigned int rate;
    		unsigned int quality;
    		unsigned int brightness;
    		V4l2Info     v4l2Info;
    	}V4l2Capture;
    
    	/**
    	 *
    	 */
    	class V4l2Camera
    	{
    	public:
    		V4l2Camera();
    		virtual ~V4l2Camera();
    
    	public:
    		/**
    		 * get the number of cameras
    		 *
    		 * @return the number of camera
    		 */
    		static int getNumberOfCameras();
    		
    		/**
    		 * initialize v4l2 device
    		 * @param capture v4l2 capture handl
    		 * @param width frame width
    		 * @param height fram height
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height);
    
    		/**
    		 * initialize v4l2 device
    		 * @param capture v4l2 capture handl
    		 * @param width frame width
    		 * @param height fram height
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int UninitDevice(V4l2Capture *capture);
    
    		/**
    		 * Set v4l2 device brightness
    		 * @param capture v4l2 capture handl
    		 * @param value brightness value
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int SetBrightness(V4l2Capture *capture, unsigned int value);
    
    		/**
    		 * start v4l2 device
    		 * @param fd v4l2 capture handl
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int StartDevice(int fd);
    
    		/**
    		 * stop v4l2 device
    		 * @fd capture v4l2 capture handl
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int StopDevice(int fd);
    
    		/**
    		 * Get frame data
    		 * @param capture v4l2 capture handl
    		 *
    		 * @return 0/other successful or failure
    		 */
    		int GetFrame(V4l2Capture *capture);
    
    	private:
    		int InitMmap(int fd);
    
    		int xioctl(int fd, int request, void *arg);
    
    		unsigned int GetCameraFormat(pFormat format);
    
    		int AdjustV4l2Info(unsigned int& width, unsigned int& height);
    
    		int MSleep(int fd, unsigned int msec);
    		
    		int MatchCameraAuto(int cameraId);
    
    	private:
    		typedef struct _Buffers
    		{
    			void *start;
    			size_t length;
    		}V4l2Buffers;
    
    		int                    m_stime;
    		V4l2Buffers*           m_buffers;
    		unsigned int           m_nBuffers;
    		V4l2Capture*           m_capture;
    		
    		static int mNumberOfCameras;
    		static int mCameraIndex[10];
    		int mUsbCameraIvalidFrameCnt;
    		bool m_InitDevice;
    	};
    }//end namespace
    #endif //CAMERA_V4L2CAMERA_H
    

      V4l2Camera.cpp

    #include "V4l2Camera.h"
    
    namespace v4l2
    {
    	#define BUFFERS_COUNT  4
    	#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
    	#define MEMST_VALUE(x) memset(&(x), 0, sizeof (x))
    
    	const V4l2Info g_v4l2Info[] = {{160, 120}, {320, 240}, {640, 480}, {1024, 768}, {1200, 900}, {1440, 1080}, {1600, 900}, {1600, 1200}};
    
    	V4l2Camera::V4l2Camera()
    	{
    		// TODO Auto-generated constructor stub
    		m_capture = NULL;
    		mUsbCameraIvalidFrameCnt = 0;
    		m_InitDevice = false;
    	}
    
    	V4l2Camera::~V4l2Camera()
    	{
    		// TODO Auto-generated destructor stub
    		if(m_capture)
    			UninitDevice(m_capture);
    	}
    
    	int V4l2Camera::xioctl(int fd, int request, void *arg)
    	{
    		int r;
    		int nCount= 0;
    
    		do
    		{
    			r = ioctl (fd, request, arg);
    		}while (RET_ERROR_FAIL == r && (EINTR == errno) && (++nCount < 100));
    
    		return r;
    	}
    
    	int V4l2Camera::mNumberOfCameras = 0;
    	int V4l2Camera::mCameraIndex[] = {0};
    
    	unsigned int V4l2Camera::GetCameraFormat(pFormat format)
    	{
    		unsigned int ret = UNKNOWN;
    		switch(format)
    		{
    		case YUYV:
    			ret = V4L2_PIX_FMT_YUYV;
    			break;
    		case MJPEG:
    			ret = V4L2_PIX_FMT_MJPEG;
    			break;
    		case YV12:
    			ret = V4L2_PIX_FMT_YVU420;
    			break;
    		case YU12:
    			ret = V4L2_PIX_FMT_YUV420;
    			break;
    		case NV12:
    			ret = V4L2_PIX_FMT_NV12;
    			break;
    		case NV21:
    			ret = V4L2_PIX_FMT_NV21;
    			break;
    		case H264:
    			ret = V4L2_PIX_FMT_MPEG;
    			break;
    		default:
    			break;
    		}
    		return ret;
    	}
    
    	int V4l2Camera::InitMmap(int fd)
    	{
    		int ret = RET_ERROR_OK;
    		struct v4l2_requestbuffers req;
    		req.count = BUFFERS_COUNT;
    		req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		req.memory = V4L2_MEMORY_MMAP;
    
    		if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_REQBUFS, &req) || req.count < 2)
    		{
    			return RET_ERROR_CAPTURE_BUFFER;
    		}
    
    		m_buffers = (V4l2Buffers*)calloc(req.count, sizeof(V4l2Buffers));
    
    		if (!m_buffers)
    		{
    			return RET_ERROR_CAPTURE_OUTMEMORY;
    		}
    
    		for (m_nBuffers = 0; m_nBuffers < req.count; ++m_nBuffers)
    		{
    			struct v4l2_buffer buf;
    
    			MEMST_VALUE (buf);
    
    			buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    			buf.memory = V4L2_MEMORY_MMAP;
    			buf.index = m_nBuffers;
    
    			if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_QUERYBUF, &buf))
    			{
    				ret = RET_ERROR_CAPTURE_BUFFER;
    				break;
    			}
    
    			m_buffers[m_nBuffers].length = buf.length;
    			m_buffers[m_nBuffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
    
    			if (MAP_FAILED == m_buffers[m_nBuffers].start)
    			{
    				ret = RET_ERROR_CAPTURE_MMAP;
    				break;
    			}
    		}
    		return ret;
    	}
    
    	int V4l2Camera::AdjustV4l2Info(unsigned int& width, unsigned int& height)
    	{
    		int ret = RET_ERROR_FAIL;
    		int index = 0;
    		for(int nCount = ARRAY_LEN(g_v4l2Info) - 1, i = nCount; i >= 0; --i)
    		{
    			if(width <= (g_v4l2Info[i].width + 50))
    			{
    				index = i;
    				ret = RET_ERROR_OK;
    			}
    			else if(0 != nCount)
    			{
    				width  = g_v4l2Info[index].width;
    				height = g_v4l2Info[index].height;
    				break;
    			}
    		}
    		return ret;
    	}
    
    	int V4l2Camera::getNumberOfCameras()
    	{
    		char cam_path[20];
    		int fd = -1, i=0;
    		struct v4l2_capability capability;
    
    		mNumberOfCameras = 0;
    		memset(mCameraIndex,0x00,sizeof(mCameraIndex));
    
    		for (i = 0; i < 10; ++i)
    		{
    			memset(cam_path,0x00,20);
    			sprintf(cam_path, "/dev/video%d",i);
    			fd = open(cam_path, O_RDONLY);
    			if (fd < 0)
    				continue;
    
    			memset(&capability, 0, sizeof(struct v4l2_capability));
    			if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0)
    			{
    				//LOGE("Video device(%s): query capability not supported.
    ", cam_path);
    				goto loop_continue;
    			}
    
    			if ((capability.capabilities
    					& (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
    					!= (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
    			{
    			}
    			else
    			{
    				mCameraIndex[mNumberOfCameras] = i;
    				mNumberOfCameras++;
    			}
    
    	loop_continue:
    			if (fd > 0)
    			{
    				close(fd);
    				fd = -1;
    			}
    			continue;
    		}
    
    		return mNumberOfCameras;
    	}
    	
    	int V4l2Camera::MatchCameraAuto(int cameraId)
    	{
    		if (mNumberOfCameras <= 0 || mNumberOfCameras > 10 || cameraId < 0)
    		{
    			return -1;
    		}
    
    		// search for camera ID normally
    		for (int i = 0; i < mNumberOfCameras; ++i)
    		{
    			if (cameraId == mCameraIndex[i])
    			{
    				return cameraId;
    			}
    		}
    
    		if (mNumberOfCameras == 1)
    		{
    			return mCameraIndex[0];
    		}
    
    		return cameraId > mCameraIndex[mNumberOfCameras -1] ? mCameraIndex[mNumberOfCameras -1] : mCameraIndex[0];
    	}
    	
    	int V4l2Camera::InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height)
    	{
    		// TODO Auto-generated function stub
    		struct stat st;
    		int fd = 0, nRealCameraNameLen = 0, nMinCameraNameLen = 0;
    		int ret = RET_ERROR_OK;
    		char szcameraID[4], szCameraName[20];
    		int cameraId = 0;
    		struct v4l2_capability cap;
    		struct v4l2_cropcap cropcap;
    		struct v4l2_crop crop;
    		
    		if(NULL == capture || NULL == name || 0 == rate || 0 == width || 0 == height) {
    			ret = RET_ERROR_CAPTURE_NULL;
    			goto InitDeviceFAILED;
    		}
    	
    		if ((nRealCameraNameLen = strlen(name)) < (nMinCameraNameLen =strlen("/dev/video0"))) {
    			ret = RET_ERROR_CAPTURE_NULL;
    			goto InitDeviceFAILED;
    		}
    		// Get camera ID
    
    		memset(szcameraID,0x00,4);
    		for (int i=0;i<3;i++) {
    			if (nRealCameraNameLen >= (nMinCameraNameLen + i))
    				szcameraID[i] = name[nMinCameraNameLen - 1 + i];
    		}
    		
    		cameraId = atoi(szcameraID);
    		mNumberOfCameras = 0;
    		memset(mCameraIndex, 0x00, sizeof(mCameraIndex));
    		if (0 == getNumberOfCameras()) {
    			//LOGE("There is NO camera!");
    			ret = RET_ERROR_CAPTURE_NAME;
    			goto InitDeviceFAILED;
    		}
    	
    		if (-1 == (cameraId = MatchCameraAuto(cameraId))) {
    			//LOGE("There is NO camera!");
    			ret = RET_ERROR_CAPTURE_NAME;
    			goto InitDeviceFAILED;
    		}
    	
    		memset(szCameraName, 0x00, 20);
    		sprintf(szCameraName, "/dev/video%d", cameraId);
    		//LOGI("camera name is %s.", name);
    		//
    		if ((RET_ERROR_FAIL == stat (szCameraName, &st)) || (!S_ISCHR (st.st_mode))
    				|| (RET_ERROR_FAIL == (fd = open(szCameraName, O_RDWR | O_NONBLOCK, 0))))
    		{
    			ret = RET_ERROR_CAPTURE_NAME;
    			goto InitDeviceFAILED;
    		}
    
    		if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QUERYCAP, &cap) || !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
    				|| !(cap.capabilities & V4L2_CAP_STREAMING))
    		{
    			ret = RET_ERROR_CAPTURE_CAPABILITY;
    			goto InitDeviceFAILED;
    		}
    
    		MEMST_VALUE(cropcap);
    		cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    		if(RET_ERROR_OK == xioctl (fd, VIDIOC_CROPCAP, &cropcap))
    		{
    			crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    			crop.c = cropcap.defrect; /* reset to default */
    
    			xioctl(fd, VIDIOC_S_CROP, &crop);
    		}
    
    		struct v4l2_format fmt;
    		MEMST_VALUE (fmt);
    
    		ret = GetCameraFormat(format);
    		if(UNKNOWN == ret) {
    			return RET_ERROR_CAPTURE_FORMAT;
    			goto InitDeviceFAILED;
    		}
    
    		if(RET_ERROR_OK != AdjustV4l2Info(width, height))
    		{
    			ret = RET_ERROR_CAPTURE_FORM;
    			goto InitDeviceFAILED;
    		}
    
    		//SetBrightness(capture, capture->brightness);
    		fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		fmt.fmt.pix.width       = width;
    		fmt.fmt.pix.height      = height;
    		fmt.fmt.pix.pixelformat = ret;
    		fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    		printf("%s(%d) pixel format is %d
    ", __FUNCTION__,__LINE__,ret);
    
    		if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_S_FMT, &fmt)) {
    			ret = RET_ERROR_CAPTURE_FORMAT;
    			goto InitDeviceFAILED;
    		}
    
    		if(RET_ERROR_OK != (ret = InitMmap(fd)) ) {// || RET_ERROR_OK != (ret = SetBrightness(capture, capture->brightness)))
    			goto InitDeviceFAILED;
    		}
    	
    		// set video frame rate
    		struct v4l2_streamparm parm;
    		parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		if (RET_ERROR_OK != ioctl(fd, VIDIOC_G_PARM, &parm)) {
    			//LOGI("VIDIOC_G_PARM fail....");
    		}
    	
    		parm.parm.capture.timeperframe.numerator = 1;
    		parm.parm.capture.timeperframe.denominator = rate;
    		if (RET_ERROR_OK != ioctl(fd, VIDIOC_S_PARM, &parm)) {
    			//LOGI("VIDIOC_S_PARM  Fail....");
    		}
    	
    		//check setting of frame rate
    		memset(&parm, 0x00, sizeof(v4l2_streamparm));
    		parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	
    		ret = ioctl(fd, VIDIOC_G_PARM, &parm);
    		if (ret != RET_ERROR_OK) {
    			//LOGI("VIDIOC_G_PARM fail....");
    		}
    		
    		capture->fd = fd;
    		capture->v4l2Info.width = fmt.fmt.pix.width;
    		capture->v4l2Info.height = fmt.fmt.pix.height;
    		capture->format = format;
    		capture->rate = rate;
    		capture->v4l2Info.length = fmt.fmt.pix.sizeimage;
    		capture->v4l2Info.stepWidth = fmt.fmt.pix.bytesperline;
    		capture->v4l2Info.buffer = malloc(fmt.fmt.pix.sizeimage);
    		strncpy(capture->name, name, sizeof(capture->name));
    
    		m_stime = 1000 / rate;
    		m_capture = capture;
    		m_InitDevice = true;
    
    		return ret;
    		
    InitDeviceFAILED:
    		if (fd >= 0)
    		{
    			close(fd);
    			fd = -1;
    		}
    
    	return ret;
    	}
    
    	int V4l2Camera::UninitDevice(V4l2Capture *capture)
    	{
    		// TODO Auto-generated function stub
    		printf("%s(%d)...[BEGIN]
    ", __FUNCTION__, __LINE__);
    		int ret = RET_ERROR_OK;
    		if (!m_InitDevice) {
    			return ret;
    		} else {
    			m_InitDevice = false;
    		}
    		if (m_buffers) {
    			for (unsigned int i = 0; i < m_nBuffers; ++i) {
    				printf("%s(%d) munmap() i = %d
    ", __FUNCTION__, __LINE__, i);
    				if (RET_ERROR_FAIL == munmap(m_buffers[i].start, m_buffers[i].length)) {
    					ret = RET_ERROR_CAPTURE_MUMAP;
    					break;
    				}
    			}
    
    			if (RET_ERROR_OK == ret) {
    				printf("%s(%d) free(m_buffers)
    ", __FUNCTION__, __LINE__);
    				free(m_buffers);
    			}
    			m_buffers = NULL;
    			if (capture) {
    				if (capture->v4l2Info.buffer) {
    					printf("%s(%d) free(capture->v4l2Info.buffer)
    ", __FUNCTION__,
    							__LINE__);
    					free(capture->v4l2Info.buffer);
    					capture->v4l2Info.buffer = NULL;
    				}
    
    				if (capture->fd >= 0) {
    					printf("%s(%d) close(capture->fd)
    ", __FUNCTION__, __LINE__);
    					ret = close(capture->fd);
    				}
    			}
    
    		}
    		printf("%s(%d)...[END]
    ", __FUNCTION__, __LINE__);
    		return ret;
    	}
    
    	int V4l2Camera::SetBrightness(V4l2Capture *capture, unsigned int value)
    	{
    		// TODO Auto-generated function stub
    		if(!capture || value > 10000)
    			return RET_ERROR_FAIL;
    
    		struct v4l2_control control;
    		control.id = V4L2_CID_BRIGHTNESS;
    		control.value = 255;
    
    		if(RET_ERROR_FAIL == xioctl(capture->fd, VIDIOC_S_CTRL, &control))
    		{
    			return RET_ERROR_FAIL;
    		}
    		capture->brightness = control.value;
    
    		return RET_ERROR_OK;
    	}
    
    	int V4l2Camera::StartDevice(int fd)
    	{
    		// TODO Auto-generated function stub
    		if(fd < 0)
    			return RET_ERROR_FAIL;
    
    		int ret = RET_ERROR_OK;
    		for (unsigned int i = 0; i < m_nBuffers; ++i)
    		{
    			struct v4l2_buffer buf;
    			MEMST_VALUE(buf);
    
    			buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    			buf.memory      = V4L2_MEMORY_MMAP;
    			buf.index       = i;
    
    			if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
    			{
    				ret = RET_ERROR_CAPTURE_VIDIOC;
    				break;
    			}
    		}
    
    		enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    		if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMON, &type))
    			ret = RET_ERROR_CAPTURE_VIDIOC;
    
    		return ret;
    	}
    
    	int V4l2Camera::StopDevice(int fd)
    	{
    		// TODO Auto-generated function stub
    		enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMOFF, &type))
    		{
    			return RET_ERROR_FAIL;
    		}
    		return 0;
    	}
    
    	int V4l2Camera::MSleep(int fd, unsigned int msec)
    	{
    		fd_set fds;
    		FD_ZERO (&fds);
    		FD_SET (fd, &fds);
    
    		struct timeval tv;
    		tv.tv_sec = msec;
    		tv.tv_usec = 0;
    
    		return select (fd + 1, &fds, NULL, NULL, &tv);
    	}
    
    	int V4l2Camera::GetFrame(V4l2Capture *capture)
    	{
    		// TODO Auto-generated function stub
    		if(!capture)
    			return RET_ERROR_FAIL;
    
    		int fd = capture->fd;
    
    		if(RET_ERROR_FAIL == MSleep(capture->fd, m_stime))
    			return RET_ERROR_FAIL;
    
    		struct v4l2_buffer buf;
    
    		MEMST_VALUE(buf);
    		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    		buf.memory = V4L2_MEMORY_MMAP;
    		buf.reserved = 0;
    
    		// Skip the first CONFIG_CAMERA_UVC_INVAL_FRAMECNT video frames
    		// because they are possibly invalid
    		if (mUsbCameraIvalidFrameCnt< CONFIG_CAMERA_UVC_INVAL_FRAMECNT) {
    			mUsbCameraIvalidFrameCnt++;
    			if(xioctl(fd, VIDIOC_DQBUF, &buf) >= 0) {
    				xioctl(fd, VIDIOC_QBUF, &buf);
    			}
    			return RET_ERROR_OK;
    		}
    		
    		if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_DQBUF, &buf) || buf.index >=  m_nBuffers)
    		{
    			return RET_ERROR_FAIL;
    		}
    
    		memcpy(capture->v4l2Info.buffer, m_buffers[buf.index].start, buf.bytesused);
    
    		if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
    			return RET_ERROR_FAIL;
    
    		return RET_ERROR_OK;
    	}
    }//end namespace
    

      

  • 相关阅读:
    PLSQL游标
    SqlHelper助手
    机房重构前奏——三层转七层
    应用运筹管理经济
    C++——宏观把控
    操作系统——宏观把控
    .NET总结一
    深复制与浅复制
    设计模式之结构型
    设计模式之一对多
  • 原文地址:https://www.cnblogs.com/wenrenhua08/p/3937736.html
Copyright © 2020-2023  润新知