您好,欢迎来到欧得旅游网。
搜索
您的当前位置:首页V4L2camera驱动capture测试程序

V4L2camera驱动capture测试程序

来源:欧得旅游网
V4L2camera驱动capture测试程序

在网上找了一个测试程序, 看了看,是根据capture.c修改的。测试步骤如下

1. gcc -o capture_image capture_image.c

2. ctrl+alt+f1 切换到ubuntu的控制台,切换到控制台模式是因为在图形模式下看不到测试图形,这可能和framebuffer的设置有关

3. sudo modprobe vivi

4. sudo ./capture_image -d /dev/video0

这时可以看到在屏幕左上角有一个640x480大小窗口,内容是彩色条格,彩色条格不停的移动,持续时间5秒

在ubuntu下还可以使用cheese测试 1. sudo apt-get install cheese 2. sudo modprobe vivi

2. 启动 cheese后,就可以看到滚动的彩色条格

附上测试程序

[c-sharp] view plaincopy 1. #include 2. #include 3. #include 4. #include 5. #include 6. #include 7. #include 8. #include 9. #include 10. #include

11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. rno));

38. 39. #include #include #include #include #include #include

#define CLEAR(x) memset (&(x), 0, sizeof (x))

struct buffer { void * start; size_t length; };

static char * dev_name = NULL; static int fd = -1;

struct buffer * buffers = NULL; static unsigned int n_buffers = 0; static int time_in_sec_capture=5; static int fbfd = -1;

static struct fb_var_screeninfo vinfo; static struct fb_fix_screeninfo finfo; static char *fbp=NULL; static long screensize=0;

static void errno_exit (const char * s) {

fprintf (stderr, \"%s error %d, %s/n\exit (EXIT_FAILURE); }

40.

41. static int xioctl (int fd,int request,void * arg) 42. { 43. int r;

44. do r = ioctl (fd, request, arg); 45. while (-1 == r && EINTR == errno); 46. return r; 47. } 48.

49. inline int clip(int value, int min, int max) {

50. return (value > max ? max : value < min ? min : value);

51. } 52.

53. static void process_image (const void * p){ 54. 55.

56. //ConvertYUVToRGB32 57. 1;

58. unsigned char* in=(char*)p; 59. int width=640; 60. int height=480; 61. int istride=1280; 62. int x,y,j;

63. int y0,u,y1,v,r,g,b; 64. long location=0; 65.

66. for ( y = 100; y < height + 100; ++y) {

67. for (j = 0, x=100; j < width * 2 ; j += 4,x +=2) { 68. location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +

69. (y+vinfo.yoffset) * finfo.line_length; 70.

71. y0 = in[j];

72. u = in[j + 1] - 128; 73. y1 = in[j + 2]; 74. v = in[j + 3] - 128; 75.

76. r = (298 * y0 + 409 * v + 128) >> 8;

77. g = (298 * y0 - 100 * u - 208 * v + 128) >> 8; 78. b = (298 * y0 + 516 * u + 128) >> 8; 79.

80. fbp[ location + 0] = clip(b, 0, 255); 81. fbp[ location + 1] = clip(g, 0, 255); 82. fbp[ location + 2] = clip(r, 0, 255); 83. fbp[ location + 3] = 255; 84.

85. r = (298 * y1 + 409 * v + 128) >> 8;

86. g = (298 * y1 - 100 * u - 208 * v + 128) >> 8; 87. b = (298 * y1 + 516 * u + 128) >> 8; 88.

89. fbp[ location + 4] = clip(b, 0, 255); 90. fbp[ location + 5] = clip(g, 0, 255); 91. fbp[ location + 6] = clip(r, 0, 255); 92. fbp[ location + 7] = 255; 93. }

94. in +=istride; 95. } 96. } 97.

98. static int read_frame (void) 99. {

100. struct v4l2_buffer buf; 101. unsigned int i; 102.

103. CLEAR (buf);

104. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 105. buf.memory = V4L2_MEMORY_MMAP; 106.

107. if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { 108. switch (errno) { 109. case EAGAIN: 110. return 0; 111. case EIO: 112. 113. 114.

115. default:

116. errno_exit (\"VIDIOC_DQBUF\"); 117. } 118. } 119.

120. assert (buf.index < n_buffers);

121. printf(\"v4l2_pix_format->field(%d)/n\122. //assert (buf.field ==V4L2_FIELD_NONE); 123. process_image (buffers[buf.index].start); 124. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) 125. errno_exit (\"VIDIOC_QBUF\"); 126.

127. return 1;

128. } 129.

130. static void run (void) 131. {

132. unsigned int count; 133. int frames;

134. frames = 30 * time_in_sec_capture; 135.

136. while (frames-- > 0) { 137. for (;;) { 138. fd_set fds; 139. struct timeval tv; 140. int r;

141. FD_ZERO (&fds); 142. FD_SET (fd, &fds); 143. 144.

145. tv.tv_sec = 2; 146. tv.tv_usec = 0; 147.

148. r = select (fd + 1, &fds, NULL, NULL, &tv); 149.

150. if (-1 == r) { 151. if (EINTR == errno) 152. continue;

153. errno_exit (\"select\"); 154. } 155.

156. if (0 == r) {

157. fprintf (stderr, \"select timeout/n\");

158. exit (EXIT_FAILURE); 159. } 160.

161. if (read_frame ()) 162. break; 163. 164. } 165. } 166. } 167.

168. static void stop_capturing (void) 169. {

170. enum v4l2_buf_type type; 171.

172. type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 173. if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type)) 174. errno_exit (\"VIDIOC_STREAMOFF\"); 175. } 176.

177. static void start_capturing (void) 178. {

179. unsigned int i;

180. enum v4l2_buf_type type; 181.

182. for (i = 0; i < n_buffers; ++i) { 183. struct v4l2_buffer buf; 184. CLEAR (buf); 185.

186. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 187. buf.memory = V4L2_MEMORY_MMAP;

188. buf.index = i; 189.

190. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) 191. errno_exit (\"VIDIOC_QBUF\"); 192. } 193.

194. type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 195.

196. if (-1 == xioctl (fd, VIDIOC_STREAMON, &type)) 197. errno_exit (\"VIDIOC_STREAMON\"); 198. 199. } 200.

201. static void uninit_device (void) 202. {

203. unsigned int i; 204.

205. for (i = 0; i < n_buffers; ++i)

206. if (-1 == munmap (buffers[i].start, buffers[i].length)) 207. errno_exit (\"munmap\"); 208.

209. if (-1 == munmap(fbp, screensize)) {

210. printf(\" Error: framebuffer device munmap() failed./n\");

211. exit (EXIT_FAILURE) ; 212. }

213. free (buffers); 214. } 215. 216.

217. static void init_mmap (void) 218. {

219. struct v4l2_requestbuffers req; 220.

221. //mmap framebuffer

222. fbp = (char *)mmap(NULL,screensize,PROT_READ | PROT_WRITE,MAP_SHARED ,fbfd, 0);

223. if ((int)fbp == -1) {

224. printf(\"Error: failed to map framebuffer device to memory./n\");

225. exit (EXIT_FAILURE) ; 226. }

227. memset(fbp, 0, screensize); 228. CLEAR (req); 229.

230. req.count = 4;

231. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 232. req.memory = V4L2_MEMORY_MMAP; 233.

234. if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) { 235. if (EINVAL == errno) {

236. fprintf (stderr, \"%s does not support memory mapping/n\

237. exit (EXIT_FAILURE); 238. } else {

239. errno_exit (\"VIDIOC_REQBUFS\"); 240. } 241. } 242.

243. if (req.count < 4) { //if (req.count < 2)

244. fprintf (stderr, \"Insufficient buffer memory on %s/n\ev_name);

245. exit (EXIT_FAILURE); 246. } 247.

248. buffers = calloc (req.count, sizeof (*buffers)); 249.

250. if (!buffers) {

251. fprintf (stderr, \"Out of memory/n\"); 252. exit (EXIT_FAILURE); 253. } 254.

255. for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {

256. struct v4l2_buffer buf; 257.

258. CLEAR (buf); 259.

260. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 261. buf.memory = V4L2_MEMORY_MMAP; 262. buf.index = n_buffers; 263.

264. if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf)) 265. errno_exit (\"VIDIOC_QUERYBUF\"); 266.

267. buffers[n_buffers].length = buf.length;

268. buffers[n_buffers].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);

269.

270. if (MAP_FAILED == buffers[n_buffers].start)

271. errno_exit (\"mmap\"); 272. } 273. 274. } 275. 276. 277.

278. static void init_device (void) 279. {

280. struct v4l2_capability cap; 281. struct v4l2_cropcap cropcap; 282. struct v4l2_crop crop; 283. struct v4l2_format fmt; 284. unsigned int min; 285. 286.

287. // Get fixed screen information

288. if (-1==xioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { 289. printf(\"Error reading fixed information./n\"); 290. exit (EXIT_FAILURE); 291. } 292.

293. // Get variable screen information 294. if (-1==xioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {

295. printf(\"Error reading variable information./n\"); 296. exit (EXIT_FAILURE); 297. }

298. screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

299. 300.

301. if (-1 == xioctl (fd, VIDIOC_QUERYCAP, ∩)) { 302. if (EINVAL == errno) {

303. fprintf (stderr, \"%s is no V4L2 device/n\304. exit (EXIT_FAILURE); 305. } else {

306. errno_exit (\"VIDIOC_QUERYCAP\"); 307. } 308. } 309.

310. if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { 311. fprintf (stderr, \"%s is no video capture device/n\ame);

312. exit (EXIT_FAILURE); 313. } 314.

315. if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 316. fprintf (stderr, \"%s does not support streaming i/o/n\dev_name);

317. exit (EXIT_FAILURE); 318. } 319. 320. 321.

322. CLEAR (cropcap); 323.

324. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 325.

326. if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {

327. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 328. crop.c = cropcap.defrect; 329.

330. if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) { 331. switch (errno) { 332. case EINVAL: 333. break; 334. default: 335. break; 336. } 337. }

338. }else { } 339.

340. CLEAR (fmt); 341.

342. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 343. fmt.fmt.pix.width = 640; 344. fmt.fmt.pix.height = 480;

345. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 346. fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 347.

348. if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) 349. errno_exit (\"VIDIOC_S_FMT\"); 350.

351. init_mmap (); 352. 353. } 354.

355. static void close_device (void) 356. {

357. if (-1 == close (fd)) 358. errno_exit (\"close\"); 359. fd = -1; 360. close(fbfd); 361. } 362.

363. static void open_device (void) 364. {

365. struct stat st; 366.

367. if (-1 == stat (dev_name, &st)) {

368. fprintf (stderr, \"Cannot identify '%s': %d, %s/n\me, errno, strerror (errno));

369. exit (EXIT_FAILURE); 370. } 371.

372. if (!S_ISCHR (st.st_mode)) {

373. fprintf (stderr, \"%s is no device/n\374. exit (EXIT_FAILURE); 375. } 376.

377. //open framebuffer

378. fbfd = open(\"/dev/fb0\379. if (fbfd==-1) {

380. printf(\"Error: cannot open framebuffer device./n\"); 381. exit (EXIT_FAILURE); 382. } 383.

384. //open camera

385. fd = open (dev_name, O_RDWR| O_NONBLOCK, 0);

386.

387. if (-1 == fd) {

388. fprintf (stderr, \"Cannot open '%s': %d, %s/n\e, errno, strerror (errno));

389. exit (EXIT_FAILURE); 390. } 391. } 392.

393. static void usage (FILE * fp,int argc,char ** argv) 394. {

395. fprintf (fp,

396. \"Usage: %s [options]/n/n\" 397. \"Options:/n\" 398. \"-d | --device name Video device name [/dev/video]/n\"

399. \"-h | --help Print this message/n\" 400. \"-t | --how long will display in seconds/n\" 401. \"\402. argv[0]); 403. } 404.

405. static const char short_options [] = \"d:ht:\"; 406. static const struct option long_options [] = { 407. { \"device\408. { \"help\409. { \"time\410. { 0, 0, 0, 0 } 411. }; 412.

413. int main (int argc,char ** argv)

414. {

415. dev_name = \"/dev/video0\"; 416. 417. for (;;) 418. {

419. int index; 420. int c; 421.

422. c = getopt_long (argc, argv,short_options, long_options,&index);

423. if (-1 == c) 424. break; 425.

426. switch (c) { 427. case 0: 428. break; 429.

430. case 'd':

431. dev_name = optarg; 432. break; 433.

434. case 'h':

435. usage (stdout, argc, argv); 436. exit (EXIT_SUCCESS); 437. case 't':

438. time_in_sec_capture = atoi(optarg); 439. break; 440.

441. default:

442. usage (stderr, argc, argv);

443. exit (EXIT_FAILURE); 444. } 445. } 446.

447. open_device (); 448.

449. init_device (); 450.

451. start_capturing (); 452. 453. run (); 454.

455. stop_capturing (); 456.

457. uninit_device (); 458.

459. close_device (); 460.

461. exit (EXIT_SUCCESS); 462.

463. return 0; 464. }

这个测试程序是根据vivi驱动hard code的, 并不一定适合其他的camera驱动

比如,我手头上的logitech stv06xx usb camera, 因为不支持640x480模式,参见代码59 60行,

代码348行 if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) 应该是个协商的过程,

343 fmt.fmt.pix.width = 640;

344 fmt.fmt.pix.height = 480;

345 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 346 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

这几行只是应用的期望格式,驱动会根据这个格式选择一个相近的格式返回,应用最后的显示处理要根据返回的格式进行处理,即process_image要做相应修改

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- ovod.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务