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

实例:

  1. #ifndef CAMERA_V4L2CAMERA_H
  2. #define CAMERA_V4L2CAMERA_H
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <getopt.h> /* getopt_long() */
  9. #include <fcntl.h> /* low-level i/o */
  10. #include <unistd.h>
  11. #include <errno.h>
  12. #include <malloc.h>
  13. #include <sys/stat.h>
  14. #include <sys/types.h>
  15. #include <sys/time.h>
  16. #include <sys/mman.h>
  17. #include <sys/ioctl.h>
  18. #include <asm/types.h> /* for videodev2.h */
  19. #include <linux/videodev2.h>
  20.  
  21. #define CONFIG_CAMERA_UVC_INVAL_FRAMECNT 5
  22.  
  23. namespace v4l2
  24. {
  25. /**
  26. * return error code
  27. */
  28. enum _RET_ERROR_CODE
  29. {
  30. RET_ERROR_FAIL = -1,
  31. RET_ERROR_OK = 0,
  32. RET_ERROR_CAPTURE_NULL = -9999,
  33. RET_ERROR_CAPTURE_NAME,
  34. RET_ERROR_CAPTURE_CAPABILITY,
  35. RET_ERROR_CAPTURE_FORMAT,
  36. RET_ERROR_CAPTURE_BUFFER,
  37. RET_ERROR_CAPTURE_OUTMEMORY,
  38. RET_ERROR_CAPTURE_MMAP,
  39. RET_ERROR_CAPTURE_FORM,
  40. RET_ERROR_CAPTURE_MUMAP,
  41. RET_ERROR_CAPTURE_VIDIOC,
  42. };
  43.  
  44. /**
  45. * Name: video_format enum
  46. * Function: Describe formats V4L2 will support
  47. */
  48. typedef enum _pFormat
  49. {
  50. UNKNOWN,
  51. YUYV,
  52. MJPEG,
  53. YV12,
  54. YU12,
  55. NV12,
  56. NV21,
  57. H264,
  58. }pFormat;
  59.  
  60. /**
  61. * frame width and height infomation
  62. */
  63. typedef struct _V4l2Info
  64. {
  65. unsigned int width;
  66. unsigned int height;
  67. unsigned int stepWidth;
  68. unsigned int length;
  69. void* buffer;
  70. }V4l2Info;
  71.  
  72. /**
  73. * caputre properties
  74. */
  75. typedef struct _V4l2Capture
  76. {
  77. pFormat format;
  78. char name[31];//dev_name
  79. int fd;
  80. unsigned int rate;
  81. unsigned int quality;
  82. unsigned int brightness;
  83. V4l2Info v4l2Info;
  84. }V4l2Capture;
  85.  
  86. /**
  87. *
  88. */
  89. class V4l2Camera
  90. {
  91. public:
  92. V4l2Camera();
  93. virtual ~V4l2Camera();
  94.  
  95. public:
  96. /**
  97. * get the number of cameras
  98. *
  99. * @return the number of camera
  100. */
  101. static int getNumberOfCameras();
  102.  
  103. /**
  104. * initialize v4l2 device
  105. * @param capture v4l2 capture handl
  106. * @param width frame width
  107. * @param height fram height
  108. *
  109. * @return 0/other successful or failure
  110. */
  111. int InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height);
  112.  
  113. /**
  114. * initialize v4l2 device
  115. * @param capture v4l2 capture handl
  116. * @param width frame width
  117. * @param height fram height
  118. *
  119. * @return 0/other successful or failure
  120. */
  121. int UninitDevice(V4l2Capture *capture);
  122.  
  123. /**
  124. * Set v4l2 device brightness
  125. * @param capture v4l2 capture handl
  126. * @param value brightness value
  127. *
  128. * @return 0/other successful or failure
  129. */
  130. int SetBrightness(V4l2Capture *capture, unsigned int value);
  131.  
  132. /**
  133. * start v4l2 device
  134. * @param fd v4l2 capture handl
  135. *
  136. * @return 0/other successful or failure
  137. */
  138. int StartDevice(int fd);
  139.  
  140. /**
  141. * stop v4l2 device
  142. * @fd capture v4l2 capture handl
  143. *
  144. * @return 0/other successful or failure
  145. */
  146. int StopDevice(int fd);
  147.  
  148. /**
  149. * Get frame data
  150. * @param capture v4l2 capture handl
  151. *
  152. * @return 0/other successful or failure
  153. */
  154. int GetFrame(V4l2Capture *capture);
  155.  
  156. private:
  157. int InitMmap(int fd);
  158.  
  159. int xioctl(int fd, int request, void *arg);
  160.  
  161. unsigned int GetCameraFormat(pFormat format);
  162.  
  163. int AdjustV4l2Info(unsigned int& width, unsigned int& height);
  164.  
  165. int MSleep(int fd, unsigned int msec);
  166.  
  167. int MatchCameraAuto(int cameraId);
  168.  
  169. private:
  170. typedef struct _Buffers
  171. {
  172. void *start;
  173. size_t length;
  174. }V4l2Buffers;
  175.  
  176. int m_stime;
  177. V4l2Buffers* m_buffers;
  178. unsigned int m_nBuffers;
  179. V4l2Capture* m_capture;
  180.  
  181. static int mNumberOfCameras;
  182. static int mCameraIndex[10];
  183. int mUsbCameraIvalidFrameCnt;
  184. bool m_InitDevice;
  185. };
  186. }//end namespace
  187. #endif //CAMERA_V4L2CAMERA_H

  V4l2Camera.cpp

  1. #include "V4l2Camera.h"
  2.  
  3. namespace v4l2
  4. {
  5. #define BUFFERS_COUNT 4
  6. #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
  7. #define MEMST_VALUE(x) memset(&(x), 0, sizeof (x))
  8.  
  9. const V4l2Info g_v4l2Info[] = {{160, 120}, {320, 240}, {640, 480}, {1024, 768}, {1200, 900}, {1440, 1080}, {1600, 900}, {1600, 1200}};
  10.  
  11. V4l2Camera::V4l2Camera()
  12. {
  13. // TODO Auto-generated constructor stub
  14. m_capture = NULL;
  15. mUsbCameraIvalidFrameCnt = 0;
  16. m_InitDevice = false;
  17. }
  18.  
  19. V4l2Camera::~V4l2Camera()
  20. {
  21. // TODO Auto-generated destructor stub
  22. if(m_capture)
  23. UninitDevice(m_capture);
  24. }
  25.  
  26. int V4l2Camera::xioctl(int fd, int request, void *arg)
  27. {
  28. int r;
  29. int nCount= 0;
  30.  
  31. do
  32. {
  33. r = ioctl (fd, request, arg);
  34. }while (RET_ERROR_FAIL == r && (EINTR == errno) && (++nCount < 100));
  35.  
  36. return r;
  37. }
  38.  
  39. int V4l2Camera::mNumberOfCameras = 0;
  40. int V4l2Camera::mCameraIndex[] = {0};
  41.  
  42. unsigned int V4l2Camera::GetCameraFormat(pFormat format)
  43. {
  44. unsigned int ret = UNKNOWN;
  45. switch(format)
  46. {
  47. case YUYV:
  48. ret = V4L2_PIX_FMT_YUYV;
  49. break;
  50. case MJPEG:
  51. ret = V4L2_PIX_FMT_MJPEG;
  52. break;
  53. case YV12:
  54. ret = V4L2_PIX_FMT_YVU420;
  55. break;
  56. case YU12:
  57. ret = V4L2_PIX_FMT_YUV420;
  58. break;
  59. case NV12:
  60. ret = V4L2_PIX_FMT_NV12;
  61. break;
  62. case NV21:
  63. ret = V4L2_PIX_FMT_NV21;
  64. break;
  65. case H264:
  66. ret = V4L2_PIX_FMT_MPEG;
  67. break;
  68. default:
  69. break;
  70. }
  71. return ret;
  72. }
  73.  
  74. int V4l2Camera::InitMmap(int fd)
  75. {
  76. int ret = RET_ERROR_OK;
  77. struct v4l2_requestbuffers req;
  78. req.count = BUFFERS_COUNT;
  79. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  80. req.memory = V4L2_MEMORY_MMAP;
  81.  
  82. if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_REQBUFS, &req) || req.count < 2)
  83. {
  84. return RET_ERROR_CAPTURE_BUFFER;
  85. }
  86.  
  87. m_buffers = (V4l2Buffers*)calloc(req.count, sizeof(V4l2Buffers));
  88.  
  89. if (!m_buffers)
  90. {
  91. return RET_ERROR_CAPTURE_OUTMEMORY;
  92. }
  93.  
  94. for (m_nBuffers = 0; m_nBuffers < req.count; ++m_nBuffers)
  95. {
  96. struct v4l2_buffer buf;
  97.  
  98. MEMST_VALUE (buf);
  99.  
  100. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  101. buf.memory = V4L2_MEMORY_MMAP;
  102. buf.index = m_nBuffers;
  103.  
  104. if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_QUERYBUF, &buf))
  105. {
  106. ret = RET_ERROR_CAPTURE_BUFFER;
  107. break;
  108. }
  109.  
  110. m_buffers[m_nBuffers].length = buf.length;
  111. m_buffers[m_nBuffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
  112.  
  113. if (MAP_FAILED == m_buffers[m_nBuffers].start)
  114. {
  115. ret = RET_ERROR_CAPTURE_MMAP;
  116. break;
  117. }
  118. }
  119. return ret;
  120. }
  121.  
  122. int V4l2Camera::AdjustV4l2Info(unsigned int& width, unsigned int& height)
  123. {
  124. int ret = RET_ERROR_FAIL;
  125. int index = 0;
  126. for(int nCount = ARRAY_LEN(g_v4l2Info) - 1, i = nCount; i >= 0; --i)
  127. {
  128. if(width <= (g_v4l2Info[i].width + 50))
  129. {
  130. index = i;
  131. ret = RET_ERROR_OK;
  132. }
  133. else if(0 != nCount)
  134. {
  135. width = g_v4l2Info[index].width;
  136. height = g_v4l2Info[index].height;
  137. break;
  138. }
  139. }
  140. return ret;
  141. }
  142.  
  143. int V4l2Camera::getNumberOfCameras()
  144. {
  145. char cam_path[20];
  146. int fd = -1, i=0;
  147. struct v4l2_capability capability;
  148.  
  149. mNumberOfCameras = 0;
  150. memset(mCameraIndex,0x00,sizeof(mCameraIndex));
  151.  
  152. for (i = 0; i < 10; ++i)
  153. {
  154. memset(cam_path,0x00,20);
  155. sprintf(cam_path, "/dev/video%d",i);
  156. fd = open(cam_path, O_RDONLY);
  157. if (fd < 0)
  158. continue;
  159.  
  160. memset(&capability, 0, sizeof(struct v4l2_capability));
  161. if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0)
  162. {
  163. //LOGE("Video device(%s): query capability not supported.\n", cam_path);
  164. goto loop_continue;
  165. }
  166.  
  167. if ((capability.capabilities
  168. & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
  169. != (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
  170. {
  171. }
  172. else
  173. {
  174. mCameraIndex[mNumberOfCameras] = i;
  175. mNumberOfCameras++;
  176. }
  177.  
  178. loop_continue:
  179. if (fd > 0)
  180. {
  181. close(fd);
  182. fd = -1;
  183. }
  184. continue;
  185. }
  186.  
  187. return mNumberOfCameras;
  188. }
  189.  
  190. int V4l2Camera::MatchCameraAuto(int cameraId)
  191. {
  192. if (mNumberOfCameras <= 0 || mNumberOfCameras > 10 || cameraId < 0)
  193. {
  194. return -1;
  195. }
  196.  
  197. // search for camera ID normally
  198. for (int i = 0; i < mNumberOfCameras; ++i)
  199. {
  200. if (cameraId == mCameraIndex[i])
  201. {
  202. return cameraId;
  203. }
  204. }
  205.  
  206. if (mNumberOfCameras == 1)
  207. {
  208. return mCameraIndex[0];
  209. }
  210.  
  211. return cameraId > mCameraIndex[mNumberOfCameras -1] ? mCameraIndex[mNumberOfCameras -1] : mCameraIndex[0];
  212. }
  213.  
  214. int V4l2Camera::InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height)
  215. {
  216. // TODO Auto-generated function stub
  217. struct stat st;
  218. int fd = 0, nRealCameraNameLen = 0, nMinCameraNameLen = 0;
  219. int ret = RET_ERROR_OK;
  220. char szcameraID[4], szCameraName[20];
  221. int cameraId = 0;
  222. struct v4l2_capability cap;
  223. struct v4l2_cropcap cropcap;
  224. struct v4l2_crop crop;
  225.  
  226. if(NULL == capture || NULL == name || 0 == rate || 0 == width || 0 == height) {
  227. ret = RET_ERROR_CAPTURE_NULL;
  228. goto InitDeviceFAILED;
  229. }
  230.  
  231. if ((nRealCameraNameLen = strlen(name)) < (nMinCameraNameLen =strlen("/dev/video0"))) {
  232. ret = RET_ERROR_CAPTURE_NULL;
  233. goto InitDeviceFAILED;
  234. }
  235. // Get camera ID
  236.  
  237. memset(szcameraID,0x00,4);
  238. for (int i=0;i<3;i++) {
  239. if (nRealCameraNameLen >= (nMinCameraNameLen + i))
  240. szcameraID[i] = name[nMinCameraNameLen - 1 + i];
  241. }
  242.  
  243. cameraId = atoi(szcameraID);
  244. mNumberOfCameras = 0;
  245. memset(mCameraIndex, 0x00, sizeof(mCameraIndex));
  246. if (0 == getNumberOfCameras()) {
  247. //LOGE("There is NO camera!");
  248. ret = RET_ERROR_CAPTURE_NAME;
  249. goto InitDeviceFAILED;
  250. }
  251.  
  252. if (-1 == (cameraId = MatchCameraAuto(cameraId))) {
  253. //LOGE("There is NO camera!");
  254. ret = RET_ERROR_CAPTURE_NAME;
  255. goto InitDeviceFAILED;
  256. }
  257.  
  258. memset(szCameraName, 0x00, 20);
  259. sprintf(szCameraName, "/dev/video%d", cameraId);
  260. //LOGI("camera name is %s.", name);
  261. //
  262. if ((RET_ERROR_FAIL == stat (szCameraName, &st)) || (!S_ISCHR (st.st_mode))
  263. || (RET_ERROR_FAIL == (fd = open(szCameraName, O_RDWR | O_NONBLOCK, 0))))
  264. {
  265. ret = RET_ERROR_CAPTURE_NAME;
  266. goto InitDeviceFAILED;
  267. }
  268.  
  269. if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QUERYCAP, &cap) || !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
  270. || !(cap.capabilities & V4L2_CAP_STREAMING))
  271. {
  272. ret = RET_ERROR_CAPTURE_CAPABILITY;
  273. goto InitDeviceFAILED;
  274. }
  275.  
  276. MEMST_VALUE(cropcap);
  277. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  278.  
  279. if(RET_ERROR_OK == xioctl (fd, VIDIOC_CROPCAP, &cropcap))
  280. {
  281. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  282. crop.c = cropcap.defrect; /* reset to default */
  283.  
  284. xioctl(fd, VIDIOC_S_CROP, &crop);
  285. }
  286.  
  287. struct v4l2_format fmt;
  288. MEMST_VALUE (fmt);
  289.  
  290. ret = GetCameraFormat(format);
  291. if(UNKNOWN == ret) {
  292. return RET_ERROR_CAPTURE_FORMAT;
  293. goto InitDeviceFAILED;
  294. }
  295.  
  296. if(RET_ERROR_OK != AdjustV4l2Info(width, height))
  297. {
  298. ret = RET_ERROR_CAPTURE_FORM;
  299. goto InitDeviceFAILED;
  300. }
  301.  
  302. //SetBrightness(capture, capture->brightness);
  303. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  304. fmt.fmt.pix.width = width;
  305. fmt.fmt.pix.height = height;
  306. fmt.fmt.pix.pixelformat = ret;
  307. fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
  308. printf("%s(%d) pixel format is %d\n", __FUNCTION__,__LINE__,ret);
  309.  
  310. if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_S_FMT, &fmt)) {
  311. ret = RET_ERROR_CAPTURE_FORMAT;
  312. goto InitDeviceFAILED;
  313. }
  314.  
  315. if(RET_ERROR_OK != (ret = InitMmap(fd)) ) {// || RET_ERROR_OK != (ret = SetBrightness(capture, capture->brightness)))
  316. goto InitDeviceFAILED;
  317. }
  318.  
  319. // set video frame rate
  320. struct v4l2_streamparm parm;
  321. parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  322. if (RET_ERROR_OK != ioctl(fd, VIDIOC_G_PARM, &parm)) {
  323. //LOGI("VIDIOC_G_PARM fail....");
  324. }
  325.  
  326. parm.parm.capture.timeperframe.numerator = 1;
  327. parm.parm.capture.timeperframe.denominator = rate;
  328. if (RET_ERROR_OK != ioctl(fd, VIDIOC_S_PARM, &parm)) {
  329. //LOGI("VIDIOC_S_PARM Fail....");
  330. }
  331.  
  332. //check setting of frame rate
  333. memset(&parm, 0x00, sizeof(v4l2_streamparm));
  334. parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  335.  
  336. ret = ioctl(fd, VIDIOC_G_PARM, &parm);
  337. if (ret != RET_ERROR_OK) {
  338. //LOGI("VIDIOC_G_PARM fail....");
  339. }
  340.  
  341. capture->fd = fd;
  342. capture->v4l2Info.width = fmt.fmt.pix.width;
  343. capture->v4l2Info.height = fmt.fmt.pix.height;
  344. capture->format = format;
  345. capture->rate = rate;
  346. capture->v4l2Info.length = fmt.fmt.pix.sizeimage;
  347. capture->v4l2Info.stepWidth = fmt.fmt.pix.bytesperline;
  348. capture->v4l2Info.buffer = malloc(fmt.fmt.pix.sizeimage);
  349. strncpy(capture->name, name, sizeof(capture->name));
  350.  
  351. m_stime = 1000 / rate;
  352. m_capture = capture;
  353. m_InitDevice = true;
  354.  
  355. return ret;
  356.  
  357. InitDeviceFAILED:
  358. if (fd >= 0)
  359. {
  360. close(fd);
  361. fd = -1;
  362. }
  363.  
  364. return ret;
  365. }
  366.  
  367. int V4l2Camera::UninitDevice(V4l2Capture *capture)
  368. {
  369. // TODO Auto-generated function stub
  370. printf("%s(%d)...[BEGIN]\n", __FUNCTION__, __LINE__);
  371. int ret = RET_ERROR_OK;
  372. if (!m_InitDevice) {
  373. return ret;
  374. } else {
  375. m_InitDevice = false;
  376. }
  377. if (m_buffers) {
  378. for (unsigned int i = 0; i < m_nBuffers; ++i) {
  379. printf("%s(%d) munmap() i = %d\n", __FUNCTION__, __LINE__, i);
  380. if (RET_ERROR_FAIL == munmap(m_buffers[i].start, m_buffers[i].length)) {
  381. ret = RET_ERROR_CAPTURE_MUMAP;
  382. break;
  383. }
  384. }
  385.  
  386. if (RET_ERROR_OK == ret) {
  387. printf("%s(%d) free(m_buffers)\n", __FUNCTION__, __LINE__);
  388. free(m_buffers);
  389. }
  390. m_buffers = NULL;
  391. if (capture) {
  392. if (capture->v4l2Info.buffer) {
  393. printf("%s(%d) free(capture->v4l2Info.buffer)\n", __FUNCTION__,
  394. __LINE__);
  395. free(capture->v4l2Info.buffer);
  396. capture->v4l2Info.buffer = NULL;
  397. }
  398.  
  399. if (capture->fd >= 0) {
  400. printf("%s(%d) close(capture->fd)\n", __FUNCTION__, __LINE__);
  401. ret = close(capture->fd);
  402. }
  403. }
  404.  
  405. }
  406. printf("%s(%d)...[END]\n", __FUNCTION__, __LINE__);
  407. return ret;
  408. }
  409.  
  410. int V4l2Camera::SetBrightness(V4l2Capture *capture, unsigned int value)
  411. {
  412. // TODO Auto-generated function stub
  413. if(!capture || value > 10000)
  414. return RET_ERROR_FAIL;
  415.  
  416. struct v4l2_control control;
  417. control.id = V4L2_CID_BRIGHTNESS;
  418. control.value = 255;
  419.  
  420. if(RET_ERROR_FAIL == xioctl(capture->fd, VIDIOC_S_CTRL, &control))
  421. {
  422. return RET_ERROR_FAIL;
  423. }
  424. capture->brightness = control.value;
  425.  
  426. return RET_ERROR_OK;
  427. }
  428.  
  429. int V4l2Camera::StartDevice(int fd)
  430. {
  431. // TODO Auto-generated function stub
  432. if(fd < 0)
  433. return RET_ERROR_FAIL;
  434.  
  435. int ret = RET_ERROR_OK;
  436. for (unsigned int i = 0; i < m_nBuffers; ++i)
  437. {
  438. struct v4l2_buffer buf;
  439. MEMST_VALUE(buf);
  440.  
  441. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  442. buf.memory = V4L2_MEMORY_MMAP;
  443. buf.index = i;
  444.  
  445. if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
  446. {
  447. ret = RET_ERROR_CAPTURE_VIDIOC;
  448. break;
  449. }
  450. }
  451.  
  452. enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  453.  
  454. if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMON, &type))
  455. ret = RET_ERROR_CAPTURE_VIDIOC;
  456.  
  457. return ret;
  458. }
  459.  
  460. int V4l2Camera::StopDevice(int fd)
  461. {
  462. // TODO Auto-generated function stub
  463. enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  464. if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMOFF, &type))
  465. {
  466. return RET_ERROR_FAIL;
  467. }
  468. return 0;
  469. }
  470.  
  471. int V4l2Camera::MSleep(int fd, unsigned int msec)
  472. {
  473. fd_set fds;
  474. FD_ZERO (&fds);
  475. FD_SET (fd, &fds);
  476.  
  477. struct timeval tv;
  478. tv.tv_sec = msec;
  479. tv.tv_usec = 0;
  480.  
  481. return select (fd + 1, &fds, NULL, NULL, &tv);
  482. }
  483.  
  484. int V4l2Camera::GetFrame(V4l2Capture *capture)
  485. {
  486. // TODO Auto-generated function stub
  487. if(!capture)
  488. return RET_ERROR_FAIL;
  489.  
  490. int fd = capture->fd;
  491.  
  492. if(RET_ERROR_FAIL == MSleep(capture->fd, m_stime))
  493. return RET_ERROR_FAIL;
  494.  
  495. struct v4l2_buffer buf;
  496.  
  497. MEMST_VALUE(buf);
  498. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  499. buf.memory = V4L2_MEMORY_MMAP;
  500. buf.reserved = 0;
  501.  
  502. // Skip the first CONFIG_CAMERA_UVC_INVAL_FRAMECNT video frames
  503. // because they are possibly invalid
  504. if (mUsbCameraIvalidFrameCnt< CONFIG_CAMERA_UVC_INVAL_FRAMECNT) {
  505. mUsbCameraIvalidFrameCnt++;
  506. if(xioctl(fd, VIDIOC_DQBUF, &buf) >= 0) {
  507. xioctl(fd, VIDIOC_QBUF, &buf);
  508. }
  509. return RET_ERROR_OK;
  510. }
  511.  
  512. if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_DQBUF, &buf) || buf.index >= m_nBuffers)
  513. {
  514. return RET_ERROR_FAIL;
  515. }
  516.  
  517. memcpy(capture->v4l2Info.buffer, m_buffers[buf.index].start, buf.bytesused);
  518.  
  519. if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
  520. return RET_ERROR_FAIL;
  521.  
  522. return RET_ERROR_OK;
  523. }
  524. }//end namespace

  

Linux下实现视频读取的更多相关文章

  1. Linux下实现视频读取(二)---camera參数设定

    Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的使用方法和涵义都是在看videodev2.h中边看边理解.感觉很生涩. 直到写这篇blog时,才发现v4l2有专门的SPEC来 ...

  2. Linux下实现视频读取(三)---Buffer的准备和数据读取

    前面主要介绍的是:V4L2 的一些设置接口,如亮度,饱和度.曝光时间,帧数,增益.白平衡等.今天看看V4L2 得到数据的几个关键ioctl,Buffer的申请和数据的抓取. 1. 初始化 Memory ...

  3. Linux下的视频字幕编辑

    一.Linux下的字幕编辑软件 常用的有subtitleeditor, gnome-subtitles, gaupol 1.gnome-subtitles:不支持多字幕文件批量处理2.gaupol:全 ...

  4. 嵌入式Linux下MP4视频录制库MP4V2移植和简单介绍

    **************************************************************************************************** ...

  5. Linux下从视频提取音频的方法

    Linux下可以利用mencoder将视频里的音频提取出来.方法如下: 1.首先安装mencoder.对于Ubuntu来说,软件仓库里就有mencoder,可直接输入如下命令安装 sudo apt-g ...

  6. Linux 下 Bash配置文件读取

    Linux安装时可能要修改的配置文件:/etc/profile./etc/bashrc(ubuntu没有这个文件,对应地,其有/etc/bash.bashrc文件.我用的是ubuntu系统,所以下面将 ...

  7. Linux下安装视频转换工具ffmpeg

    ffmpeg下载地址:http://ffmpeg.org/releases/ 1.首先需要安装解码器集合(包含安装ffmpeg用到的所有解码器)下载地址: 链接:https://pan.baidu.c ...

  8. Linux下用C读取配置文件。类似ini这样。

    Introduction ccl is the customizable configuration library, a collection of functions for applicatio ...

  9. 基于Linux的v4l2视频架构驱动编写(转载)

    转自:http://www.linuxidc.com/Linux/2011-03/33022.htm 其实,我刚开始一直都不知道怎么写驱动,什么都不懂的,只知道我需要在做项目的过程中学习,所以,我就自 ...

随机推荐

  1. C# 聚合数据借口发短信的使用

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. 简单servlet调用dao层完整步骤

    导入包lib(文件名称) 目录结构:web下:views.web-inf.index.jsp views下各种jsp文件和js(里面放封装好的jquery包) js下:jquery包(js文件后缀) ...

  3. pycharm主题 变量颜色 自定义

    File--Settings--Edtior--Color Schame-- Lanuage Defaults

  4. PAT_A1127#ZigZagging on a Tree

    Source: PAT A1127 ZigZagging on a Tree (30 分) Description: Suppose that all the keys in a binary tre ...

  5. DATEADD()

    定义和用法 DATEADD() 函数在日期中添加或减去指定的时间间隔. 语法 DATEADD(datepart,number,date) date 参数是合法的日期表达式.number 是您希望添加的 ...

  6. 金蝶WAFII

  7. 在 CentOS 7 上设置 grub2

    在 CentOS 7 上设置 grub2 1. 开机选单是自动创建出来的 请勿尝试手动编辑开机选单,因为它是按照 /boot/ 目录内的文件自动创建出来的.然而你可以调整 /etc/default/g ...

  8. 【3】Django创建第一个项目

    天地所以能长且久者,以其不自生,故能长生. --老子<道德经> 写在前面:Django在学习的过程中,我们会参考官方文档,从两部分进行讲解,第一部分主要是一个入门项目的搭建开发,第二部分是 ...

  9. 8.在idea中配置maven

    1.在IntelliJ IDEA中配置maven 打开-File-Settings 2.我们还可以在勾选一些其他选项 3.我们可以更新一下本地仓库和远程仓库,这个样在pom.xml文件中添加依赖jia ...

  10. [GraphQL] Apollo React Mutation Component

    In this lesson I refactor a React component that utilizes a higher-order component for mutations to ...