fork(1) download
  1. /*
  2.  * V4L2 video stereo capture example with openCV
  3.  * htpp://lowcost-robot.org
  4.  * compile : g++ V4L2_cap.cpp -o V4L2_cap `pkg-config --libs --cflags opencv`
  5.  */
  6. #include "opencv/cv.h"
  7. #include "opencv/highgui.h"
  8. #include "opencv/cvaux.h"
  9. #include "cxmisc.h"
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <assert.h>
  15.  
  16. #include <ctype.h>
  17. #include <vector>
  18. #include <string>
  19. #include <algorithm>
  20. #include <pthread.h>
  21. #include <sys/resource.h>
  22.  
  23. #include <getopt.h> /* getopt_long() */
  24.  
  25. #include <fcntl.h> /* low-level i/o */
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <malloc.h>
  29. #include <sys/stat.h>
  30. #include <sys/types.h>
  31. #include <sys/time.h>
  32. #include <sys/mman.h>
  33. #include <sys/ioctl.h>
  34.  
  35. #include <asm/types.h> /* for videodev2.h */
  36.  
  37.  
  38. #include <linux/videodev2.h>
  39.  
  40. using namespace std;
  41.  
  42. #define CLEAR(x) memset (&(x), 0, sizeof (x))
  43.  
  44.  
  45.  
  46.  
  47. /* This is the critical section object (statically allocated). */
  48. static pthread_mutex_t cs_mutex = PTHREAD_MUTEX_INITIALIZER;
  49.  
  50.  
  51. typedef enum {
  52. IO_METHOD_READ,
  53. IO_METHOD_MMAP,
  54. IO_METHOD_USERPTR,
  55. } io_method;
  56.  
  57. struct buffer {
  58. void * start;
  59. size_t length;
  60. };
  61.  
  62. static char * dev_name = NULL;
  63. static char * dev_name2 = NULL;
  64. int width_cap=352;
  65. int height_cap=288;
  66.  
  67. static io_method io = IO_METHOD_MMAP;
  68.  
  69. static int fd = -1;
  70. static int fd2 = -1;
  71.  
  72. struct buffer * buffers = NULL;
  73. static unsigned int n_buffers = 0;
  74.  
  75. struct buffer * buffers2 = NULL;
  76. static unsigned int n_buffers2 = 0;
  77.  
  78. IplImage* frame=0;
  79. IplImage* frame2=0;
  80. IplImage* grayImg=0;
  81. IplImage* cannyImg=0;
  82.  
  83. bool exit_app=false;
  84.  
  85. static void
  86. errno_exit (const char * s)
  87. {
  88. fprintf (stderr, "%s error %d, %s\n",
  89. s, errno, strerror (errno));
  90.  
  91. exit (EXIT_FAILURE);
  92. }
  93.  
  94. static int
  95. xioctl (int fd,
  96. int request,
  97. void * arg)
  98. {
  99. int r;
  100.  
  101. do r = ioctl (fd, request, arg);
  102. while (-1 == r && (EINTR == errno ));
  103.  
  104. return r;
  105. }
  106.  
  107. #define CLAMP(x) if (x < 0) {x = 0;} if (x > 255) {x = 255;}
  108. static void convert_yuyv_to_rgb(char *raw_buf, char *proc_buf,char *raw_buf2, char *proc_buf2)
  109. {
  110. int x, y;
  111. for(y = 0; y < height_cap; ++y) {
  112. for(x = 0; x < width_cap; x+=2) {
  113. int i = (width_cap * y + x);
  114.  
  115. int y1 = raw_buf[2*i];
  116. int u = raw_buf[2*i+1];
  117. int y2 = raw_buf[2*i+2];
  118. int v = raw_buf[2*i+3];
  119.  
  120. int y1_ = raw_buf2[2*i];
  121. int u_ = raw_buf2[2*i+1];
  122. int y2_ = raw_buf2[2*i+2];
  123. int v_ = raw_buf2[2*i+3];
  124.  
  125. int r1 = (y1-16)*1164/1000 + (v-128)*1596/1000;
  126. int g1 = (y1-16)*1164/1000 - (v-128)*813/1000 - (u-128)*391/1000;
  127. int b1 = (y1-16)*1164/1000 + (u-128)*2018/1000;
  128. int r2 = (y2-16)*1164/1000 + (v-128)*1596/1000;
  129. int g2 = (y2-16)*1164/1000 - (v-128)*813/1000 - (u-128)*391/1000;
  130. int b2 = (y2-16)*1164/1000 + (u-128)*2018/1000;
  131.  
  132. int r1_ = (y1_-16)*1164/1000 + (v_-128)*1596/1000;
  133. int g1_ = (y1_-16)*1164/1000 - (v_-128)*813/1000 - (u_-128)*391/1000;
  134. int b1_ = (y1_-16)*1164/1000 + (u_-128)*2018/1000;
  135. int r2_ = (y2_-16)*1164/1000 + (v_-128)*1596/1000;
  136. int g2_ = (y2_-16)*1164/1000 - (v_-128)*813/1000 - (u_-128)*391/1000;
  137. int b2_ = (y2_-16)*1164/1000 + (u_-128)*2018/1000;
  138.  
  139. CLAMP(r1)
  140. CLAMP(g1)
  141. CLAMP(b1)
  142. CLAMP(r2)
  143. CLAMP(g2)
  144. CLAMP(b2)
  145.  
  146. CLAMP(r1_)
  147. CLAMP(g1_)
  148. CLAMP(b1_)
  149. CLAMP(r2_)
  150. CLAMP(g2_)
  151. CLAMP(b2_)
  152.  
  153. proc_buf[3*i] =b1;
  154. proc_buf[3*i+1]=g1;
  155. proc_buf[3*i+2]=r1;
  156. proc_buf[3*i+3]=b2;
  157. proc_buf[3*i+4]=g2;
  158. proc_buf[3*i+5]=r2;
  159.  
  160. proc_buf2[3*i] =b1_;
  161. proc_buf2[3*i+1]=g1_;
  162. proc_buf2[3*i+2]=r1_;
  163. proc_buf2[3*i+3]=b2_;
  164. proc_buf2[3*i+4]=g2_;
  165. proc_buf2[3*i+5]=r2_;
  166. }
  167. }
  168. }
  169. #undef CLAMP
  170.  
  171.  
  172. static void
  173. process_image(const void * p,const void * p2)
  174. {
  175. /* Enter the critical section -- other threads are locked out */
  176. pthread_mutex_lock( &cs_mutex );
  177.  
  178. convert_yuyv_to_rgb((char*)p,(char*)frame->imageData,(char*)p2,(char*)frame2->imageData);
  179.  
  180.  
  181.  
  182. cvCvtColor( frame, grayImg, CV_BGR2GRAY );
  183.  
  184. // canny edge detection
  185. cvCanny(grayImg, cannyImg, 50, 150, 3);
  186.  
  187.  
  188.  
  189. cvShowImage( "Canny", cannyImg);
  190. cvShowImage( "Cam1", frame);
  191. cvShowImage( "Cam2", frame2);
  192. if( (cvWaitKey(5) & 255) == 27 ) exit_app=true;
  193.  
  194. /*Leave the critical section -- other threads can now pthread_mutex_lock() */
  195. pthread_mutex_unlock( &cs_mutex );
  196.  
  197. }
  198.  
  199. static int
  200. read_frame(void)
  201. {
  202.  
  203. struct v4l2_buffer buf;
  204. struct v4l2_buffer buf2;
  205. unsigned int i;
  206.  
  207. switch (io) {
  208. case IO_METHOD_READ:
  209.  
  210.  
  211. if (-1 == read (fd, buffers[0].start, buffers[0].length)) {
  212. switch (errno) {
  213. case EAGAIN:
  214. return 0;
  215.  
  216. case EIO:
  217. /* Could ignore EIO, see spec. */
  218.  
  219. /* fall through */
  220.  
  221. default:
  222. errno_exit ("read");
  223. }
  224. }
  225.  
  226. if (-1 == read (fd2, buffers2[0].start, buffers2[0].length)) {
  227. switch (errno) {
  228. case EAGAIN:
  229. return 0;
  230.  
  231. case EIO:
  232. /* Could ignore EIO, see spec. */
  233.  
  234. /* fall through */
  235.  
  236. default:
  237. errno_exit ("read2");
  238. }
  239. }
  240. process_image (buffers[0].start,buffers2[0].start);
  241.  
  242.  
  243.  
  244. break;
  245.  
  246. case IO_METHOD_MMAP:
  247.  
  248.  
  249.  
  250. CLEAR (buf);
  251.  
  252. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  253. buf.memory = V4L2_MEMORY_MMAP;
  254.  
  255. if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
  256. switch (errno) {
  257. case EAGAIN:
  258. return 0;
  259.  
  260. case EIO:
  261. /* Could ignore EIO, see spec. */
  262.  
  263. /* fall through */
  264.  
  265. default:
  266. errno_exit ("VIDIOC_DQBUF");
  267. }
  268. }
  269. CLEAR (buf2);
  270.  
  271. buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  272. buf2.memory = V4L2_MEMORY_MMAP;
  273.  
  274. if (-1 == xioctl (fd2, VIDIOC_DQBUF, &buf2)) {
  275. switch (errno) {
  276. case EAGAIN:
  277. return 0;
  278.  
  279. case EIO:
  280. /* Could ignore EIO, see spec. */
  281.  
  282. /* fall through */
  283.  
  284. default:
  285. errno_exit ("VIDIOC_DQBUF2");
  286. }
  287. }
  288.  
  289. assert (buf.index < n_buffers);
  290. assert (buf2.index < n_buffers);
  291.  
  292. process_image (buffers[buf.index].start,buffers2[buf.index].start);
  293.  
  294. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
  295. errno_exit ("VIDIOC_QBUF");
  296. if (-1 == xioctl (fd2, VIDIOC_QBUF, &buf2))
  297. errno_exit ("VIDIOC_QBUF2");
  298.  
  299.  
  300. break;
  301.  
  302. case IO_METHOD_USERPTR:
  303.  
  304.  
  305. CLEAR (buf);
  306.  
  307. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  308. buf.memory = V4L2_MEMORY_USERPTR;
  309.  
  310. if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
  311. switch (errno) {
  312. case EAGAIN:
  313. return 0;
  314.  
  315. case EIO:
  316. /* Could ignore EIO, see spec. */
  317.  
  318. /* fall through */
  319.  
  320. default:
  321. errno_exit ("VIDIOC_DQBUF");
  322. }
  323. }
  324.  
  325. CLEAR (buf2);
  326.  
  327. buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  328. buf2.memory = V4L2_MEMORY_USERPTR;
  329.  
  330. if (-1 == xioctl (fd2, VIDIOC_DQBUF, &buf2)) {
  331. switch (errno) {
  332. case EAGAIN:
  333. return 0;
  334.  
  335. case EIO:
  336. /* Could ignore EIO, see spec. */
  337.  
  338. /* fall through */
  339.  
  340. default:
  341. errno_exit ("VIDIOC_DQBUF2");
  342. }
  343. }
  344.  
  345. for (i = 0; i < n_buffers; ++i)
  346. if (buf.m.userptr == (unsigned long) buffers[i].start
  347. && buf.length == buffers[i].length)
  348. break;
  349.  
  350. assert (i < n_buffers);
  351.  
  352. for (i = 0; i < n_buffers; ++i)
  353. if (buf2.m.userptr == (unsigned long) buffers2[i].start
  354. && buf2.length == buffers2[i].length)
  355. break;
  356.  
  357. assert (i < n_buffers);
  358.  
  359. process_image ((void *) buf.m.userptr,(void *) buf2.m.userptr);
  360.  
  361. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
  362. errno_exit ("VIDIOC_QBUF");
  363. if (-1 == xioctl (fd2, VIDIOC_QBUF, &buf2))
  364. errno_exit ("VIDIOC_QBUF");
  365.  
  366.  
  367.  
  368. break;
  369. }
  370.  
  371.  
  372.  
  373. return 1;
  374. }
  375.  
  376.  
  377.  
  378.  
  379. static void
  380. mainloop (void)
  381. {
  382.  
  383.  
  384. while (!exit_app) {
  385. for (;;) {
  386. fd_set fds;
  387. struct timeval tv;
  388. int r;
  389.  
  390. FD_ZERO (&fds);
  391. FD_SET (fd, &fds);
  392.  
  393. /* Timeout. */
  394. tv.tv_sec = 5;
  395. tv.tv_usec = 1;
  396.  
  397. r = select (fd + 1, &fds, NULL, NULL, &tv);
  398.  
  399. if (-1 == r) {
  400. if (EINTR == errno)
  401. continue;
  402.  
  403. errno_exit ("select");
  404. }
  405.  
  406. if (0 == r) {
  407. fprintf (stderr, "select timeout\n");
  408. exit (EXIT_FAILURE);
  409. }
  410.  
  411. if (read_frame)
  412. break;
  413.  
  414. /* EAGAIN - continue select loop. */
  415. }
  416. }
  417. }
  418.  
  419. static void
  420. stop_capturing (void)
  421. {
  422. enum v4l2_buf_type type;
  423.  
  424. switch (io) {
  425. case IO_METHOD_READ:
  426. /* Nothing to do. */
  427. break;
  428.  
  429. case IO_METHOD_MMAP:
  430. case IO_METHOD_USERPTR:
  431. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  432.  
  433. if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))
  434. errno_exit ("VIDIOC_STREAMOFF");
  435.  
  436. if (-1 == xioctl (fd2, VIDIOC_STREAMOFF, &type))
  437. errno_exit ("VIDIOC_STREAMOFF");
  438.  
  439. break;
  440. }
  441. }
  442.  
  443. static void
  444. start_capturing (void)
  445. {
  446. unsigned int i;
  447. enum v4l2_buf_type type;
  448.  
  449. switch (io) {
  450. case IO_METHOD_READ:
  451. /* Nothing to do. */
  452. break;
  453.  
  454. case IO_METHOD_MMAP:
  455. for (i = 0; i < n_buffers; ++i) {
  456. struct v4l2_buffer buf;
  457.  
  458. CLEAR (buf);
  459.  
  460. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  461. buf.memory = V4L2_MEMORY_MMAP;
  462. buf.index = i;
  463.  
  464. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
  465. errno_exit ("VIDIOC_QBUF");
  466. if (-1 == xioctl (fd2, VIDIOC_QBUF, &buf))
  467. errno_exit ("VIDIOC_QBUF");
  468. }
  469.  
  470. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  471.  
  472. if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
  473. errno_exit ("VIDIOC_STREAMON");
  474. if (-1 == xioctl (fd2, VIDIOC_STREAMON, &type))
  475. errno_exit ("VIDIOC_STREAMON");
  476.  
  477. break;
  478.  
  479. case IO_METHOD_USERPTR:
  480. for (i = 0; i < n_buffers; ++i) {
  481.  
  482. struct v4l2_buffer buf;
  483. struct v4l2_buffer buf2;
  484.  
  485. CLEAR (buf);
  486.  
  487. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  488. buf.memory = V4L2_MEMORY_USERPTR;
  489. buf.index = i;
  490. buf.m.userptr = (unsigned long) buffers[i].start;
  491. buf.length = buffers[i].length;
  492.  
  493. CLEAR (buf2);
  494.  
  495. buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  496. buf2.memory = V4L2_MEMORY_USERPTR;
  497. buf2.index = i;
  498. buf2.m.userptr = (unsigned long) buffers2[i].start;
  499. buf2.length = buffers2[i].length;
  500.  
  501.  
  502. if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
  503. errno_exit ("VIDIOC_QBUF");
  504. if (-1 == xioctl (fd2, VIDIOC_QBUF, &buf2))
  505. errno_exit ("VIDIOC_QBUF");
  506. }
  507.  
  508. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  509.  
  510. if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
  511. errno_exit ("VIDIOC_STREAMON");
  512. if (-1 == xioctl (fd2, VIDIOC_STREAMON, &type))
  513. errno_exit ("VIDIOC_STREAMON");
  514.  
  515. break;
  516. }
  517. }
  518.  
  519. static void
  520. uninit_device (void)
  521. {
  522. unsigned int i;
  523.  
  524. switch (io) {
  525. case IO_METHOD_READ:
  526. free (buffers[0].start);
  527. free (buffers2[0].start);
  528. break;
  529.  
  530. case IO_METHOD_MMAP:
  531. for (i = 0; i < n_buffers; ++i)
  532. {
  533. if (-1 == munmap (buffers[i].start, buffers[i].length))
  534. errno_exit ("munmap");
  535. if (-1 == munmap (buffers2[i].start, buffers2[i].length))
  536. errno_exit ("munmap");
  537. }
  538. break;
  539.  
  540. case IO_METHOD_USERPTR:
  541. for (i = 0; i < n_buffers; ++i)
  542. {
  543. free (buffers[i].start);
  544. free (buffers2[i].start);
  545.  
  546. }
  547. break;
  548. }
  549.  
  550. free (buffers);
  551. free (buffers2);
  552. }
  553.  
  554. static void
  555. init_read (unsigned int buffer_size)
  556. {
  557. char* buff;
  558. buff = (char*) calloc (1, sizeof (*buffers));
  559. buffers = (buffer*) buff;
  560.  
  561.  
  562. if (!buffers) {
  563. fprintf (stderr, "Out of memory\n");
  564. exit (EXIT_FAILURE);
  565. }
  566.  
  567. buffers[0].length = buffer_size;
  568. buffers[0].start = malloc (buffer_size);
  569.  
  570. if (!buffers[0].start) {
  571. fprintf (stderr, "Out of memory\n");
  572. exit (EXIT_FAILURE);
  573. }
  574.  
  575. //===========================================================
  576.  
  577. buff = (char*) calloc (1, sizeof (*buffers));
  578. buffers2 = (buffer*) buff;
  579.  
  580.  
  581. if (!buffers2) {
  582. fprintf (stderr, "Out of memory\n");
  583. exit (EXIT_FAILURE);
  584. }
  585.  
  586. buffers2[0].length = buffer_size;
  587. buffers2[0].start = malloc (buffer_size);
  588.  
  589. if (!buffers2[0].start) {
  590. fprintf (stderr, "Out of memory\n");
  591. exit (EXIT_FAILURE);
  592. }
  593. }
  594.  
  595. static void
  596. init_mmap (void)
  597. {
  598. struct v4l2_requestbuffers req;
  599.  
  600. CLEAR (req);
  601.  
  602. req.count = 4;
  603. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  604. req.memory = V4L2_MEMORY_MMAP;
  605.  
  606. if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
  607. if (EINVAL == errno) {
  608. fprintf (stderr, "%s does not support "
  609. "memory mapping\n", dev_name);
  610. exit (EXIT_FAILURE);
  611. } else {
  612. errno_exit ("VIDIOC_REQBUFS");
  613. }
  614. }
  615.  
  616. if (req.count < 2) {
  617. fprintf (stderr, "Insufficient buffer memory on %s\n",
  618. dev_name);
  619. exit (EXIT_FAILURE);
  620. }
  621.  
  622. char* buff;
  623. buff = (char*) calloc (req.count, sizeof (*buffers));
  624. buffers = (buffer*) buff;
  625.  
  626. if (!buffers) {
  627. fprintf (stderr, "Out of memory\n");
  628. exit (EXIT_FAILURE);
  629. }
  630.  
  631. for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
  632. struct v4l2_buffer buf;
  633.  
  634. CLEAR (buf);
  635.  
  636. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  637. buf.memory = V4L2_MEMORY_MMAP;
  638. buf.index = n_buffers;
  639.  
  640. if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
  641. errno_exit ("VIDIOC_QUERYBUF");
  642.  
  643. buffers[n_buffers].length = buf.length;
  644. buffers[n_buffers].start =
  645. mmap (NULL /* start anywhere */,
  646. buf.length,
  647. PROT_READ | PROT_WRITE /* required */,
  648. MAP_SHARED /* recommended */,
  649. fd, buf.m.offset);
  650.  
  651. if (MAP_FAILED == buffers[n_buffers].start)
  652. errno_exit ("mmap");
  653. }
  654. //========================================================================
  655.  
  656. struct v4l2_requestbuffers req2;
  657.  
  658. CLEAR (req2);
  659.  
  660. req2.count = 4;
  661. req2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  662. req2.memory = V4L2_MEMORY_MMAP;
  663.  
  664. if (-1 == xioctl (fd2, VIDIOC_REQBUFS, &req2)) {
  665. if (EINVAL == errno) {
  666. fprintf (stderr, "%s does not support "
  667. "memory mapping\n", dev_name);
  668. exit (EXIT_FAILURE);
  669. } else {
  670. errno_exit ("VIDIOC_REQBUFS2");
  671. }
  672. }
  673.  
  674. if (req2.count < 2) {
  675. fprintf (stderr, "Insufficient buffer memory on %s\n",
  676. dev_name);
  677. exit (EXIT_FAILURE);
  678. }
  679.  
  680.  
  681. buff = (char*) calloc (req2.count, sizeof (*buffers));
  682. buffers2 = (buffer*) buff;
  683.  
  684. if (!buffers2) {
  685. fprintf (stderr, "Out of memory2\n");
  686. exit (EXIT_FAILURE);
  687. }
  688.  
  689. for (n_buffers = 0; n_buffers < req2.count; ++n_buffers) {
  690. struct v4l2_buffer buf2;
  691.  
  692. CLEAR (buf2);
  693.  
  694. buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  695. buf2.memory = V4L2_MEMORY_MMAP;
  696. buf2.index = n_buffers;
  697.  
  698. if (-1 == xioctl (fd2, VIDIOC_QUERYBUF, &buf2))
  699. errno_exit ("VIDIOC_QUERYBUF");
  700.  
  701. buffers2[n_buffers].length = buf2.length;
  702. buffers2[n_buffers].start =
  703. mmap (NULL /* start anywhere */,
  704. buf2.length,
  705. PROT_READ | PROT_WRITE /* required */,
  706. MAP_SHARED /* recommended */,
  707. fd2, buf2.m.offset);
  708.  
  709. if (MAP_FAILED == buffers2[n_buffers].start)
  710. errno_exit ("mmap2");
  711. }
  712. }
  713.  
  714. static void
  715. init_userp (unsigned int buffer_size)
  716. {
  717. struct v4l2_requestbuffers req;
  718. unsigned int page_size;
  719.  
  720. page_size = getpagesize ();
  721. buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
  722.  
  723. CLEAR (req);
  724.  
  725. req.count = 4;
  726. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  727. req.memory = V4L2_MEMORY_USERPTR;
  728.  
  729. if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
  730. if (EINVAL == errno) {
  731. fprintf (stderr, "%s does not support "
  732. "user pointer i/o\n", dev_name);
  733. exit (EXIT_FAILURE);
  734. } else {
  735. errno_exit ("VIDIOC_REQBUFS");
  736. }
  737. }
  738.  
  739. char* buff;
  740. buff = (char*) calloc (4, sizeof (*buffers));
  741. buffers = (buffer*) buff;
  742.  
  743.  
  744.  
  745.  
  746. if (!buffers) {
  747. fprintf (stderr, "Out of memory\n");
  748. exit (EXIT_FAILURE);
  749. }
  750.  
  751. for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
  752. buffers[n_buffers].length = buffer_size;
  753. buffers[n_buffers].start = memalign (/* boundary */ page_size,
  754. buffer_size);
  755.  
  756. if (!buffers[n_buffers].start) {
  757. fprintf (stderr, "Out of memory\n");
  758. exit (EXIT_FAILURE);
  759. }
  760. }
  761. //===============================================================
  762.  
  763. struct v4l2_requestbuffers req2;
  764. CLEAR (req2);
  765.  
  766. req2.count = 4;
  767. req2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  768. req2.memory = V4L2_MEMORY_MMAP;
  769.  
  770. if (-1 == xioctl (fd2, VIDIOC_REQBUFS, &req2)) {
  771. if (EINVAL == errno) {
  772. fprintf (stderr, "%s does not support "
  773. "memory mapping\n", dev_name2);
  774. exit (EXIT_FAILURE);
  775. } else {
  776. errno_exit ("VIDIOC_REQBUFS2");
  777. }
  778. }
  779.  
  780. if (req.count < 2) {
  781. fprintf (stderr, "Insufficient buffer memory on %s\n",
  782. dev_name2);
  783. exit (EXIT_FAILURE);
  784. }
  785.  
  786.  
  787. buff = (char*) calloc (req.count, sizeof (*buffers));
  788. buffers2 = (buffer*) buff;
  789.  
  790. if (!buffers2) {
  791. fprintf (stderr, "Out of memory\n");
  792. exit (EXIT_FAILURE);
  793. }
  794.  
  795. for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
  796. struct v4l2_buffer buf;
  797.  
  798. CLEAR (buf);
  799.  
  800. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  801. buf.memory = V4L2_MEMORY_MMAP;
  802. buf.index = n_buffers;
  803.  
  804. if (-1 == xioctl (fd2, VIDIOC_QUERYBUF, &buf))
  805. errno_exit ("VIDIOC_QUERYBUF");
  806.  
  807. buffers2[n_buffers].length = buf.length;
  808. buffers2[n_buffers].start =
  809. mmap (NULL /* start anywhere */,
  810. buf.length,
  811. PROT_READ | PROT_WRITE /* required */,
  812. MAP_SHARED /* recommended */,
  813. fd2, buf.m.offset);
  814.  
  815. if (MAP_FAILED == buffers2[n_buffers].start)
  816. errno_exit ("mmap");
  817. }
  818. }
  819.  
  820. static void
  821. init_device (void)
  822. {
  823.  
  824.  
  825.  
  826. struct v4l2_capability cap;
  827. struct v4l2_cropcap cropcap;
  828. struct v4l2_crop crop;
  829. struct v4l2_format fmt;
  830. unsigned int min;
  831.  
  832. if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
  833. if (EINVAL == errno) {
  834. fprintf (stderr, "%s is no V4L2 device\n",
  835. dev_name);
  836. exit (EXIT_FAILURE);
  837. } else {
  838. errno_exit ("VIDIOC_QUERYCAP");
  839. }
  840. }
  841.  
  842. if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
  843. fprintf (stderr, "%s is no video capture device\n",
  844. dev_name);
  845. exit (EXIT_FAILURE);
  846. }
  847.  
  848. switch (io) {
  849. case IO_METHOD_READ:
  850. if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
  851. fprintf (stderr, "%s does not support read i/o\n",
  852. dev_name);
  853. exit (EXIT_FAILURE);
  854. }
  855.  
  856. break;
  857.  
  858. case IO_METHOD_MMAP:
  859. case IO_METHOD_USERPTR:
  860. if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
  861. fprintf (stderr, "%s does not support streaming i/o\n",
  862. dev_name);
  863. exit (EXIT_FAILURE);
  864. }
  865.  
  866. break;
  867. }
  868.  
  869.  
  870. /* Select video input, video standard and tune here. */
  871.  
  872.  
  873. CLEAR (cropcap);
  874.  
  875. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  876.  
  877. if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
  878. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  879. crop.c = cropcap.defrect; /* reset to default */
  880.  
  881. if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
  882. switch (errno) {
  883. case EINVAL:
  884. /* Cropping not supported. */
  885. break;
  886. default:
  887. /* Errors ignored. */
  888. break;
  889. }
  890. }
  891. } else {
  892. /* Errors ignored. */
  893. }
  894.  
  895.  
  896. CLEAR (fmt);
  897.  
  898. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  899. fmt.fmt.pix.width = width_cap;
  900. fmt.fmt.pix.height = height_cap;
  901. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  902. fmt.fmt.pix.field = V4L2_FIELD_NONE;
  903.  
  904.  
  905. if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
  906. errno_exit ("VIDIOC_S_FMT");
  907.  
  908. //=====================================================================
  909.  
  910.  
  911. struct v4l2_capability cap2;
  912. struct v4l2_cropcap cropcap2;
  913. struct v4l2_crop crop2;
  914. struct v4l2_format fmt2;
  915.  
  916.  
  917. if (-1 == xioctl (fd2, VIDIOC_QUERYCAP, &cap2)) {
  918. if (EINVAL == errno) {
  919. fprintf (stderr, "%s is no V4L2 device\n",
  920. dev_name2);
  921. exit (EXIT_FAILURE);
  922. } else {
  923. errno_exit ("VIDIOC_QUERYCAP");
  924. }
  925. }
  926.  
  927. if (!(cap2.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
  928. fprintf (stderr, "%s is no video capture device\n",
  929. dev_name2);
  930. exit (EXIT_FAILURE);
  931. }
  932.  
  933. switch (io) {
  934. case IO_METHOD_READ:
  935. if (!(cap2.capabilities & V4L2_CAP_READWRITE)) {
  936. fprintf (stderr, "%s does not support read i/o\n",
  937. dev_name2);
  938. exit (EXIT_FAILURE);
  939. }
  940.  
  941. break;
  942.  
  943. case IO_METHOD_MMAP:
  944. case IO_METHOD_USERPTR:
  945. if (!(cap2.capabilities & V4L2_CAP_STREAMING)) {
  946. fprintf (stderr, "%s does not support streaming i/o\n",
  947. dev_name2);
  948. exit (EXIT_FAILURE);
  949. }
  950.  
  951. break;
  952. }
  953.  
  954.  
  955. /* Select video input, video standard and tune here. */
  956.  
  957.  
  958. CLEAR (cropcap2);
  959.  
  960. cropcap2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  961.  
  962. if (0 == xioctl (fd2, VIDIOC_CROPCAP, &cropcap2)) {
  963. crop2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  964. crop2.c = cropcap2.defrect; /* reset to default */
  965.  
  966. if (-1 == xioctl (fd2, VIDIOC_S_CROP, &crop2)) {
  967. switch (errno) {
  968. case EINVAL:
  969. /* Cropping not supported. */
  970. break;
  971. default:
  972. /* Errors ignored. */
  973. break;
  974. }
  975. }
  976. } else {
  977. /* Errors ignored. */
  978. }
  979.  
  980.  
  981. CLEAR (fmt2);
  982.  
  983. fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  984. fmt2.fmt.pix.width = width_cap;
  985. fmt2.fmt.pix.height = height_cap;
  986. fmt2.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  987. fmt2.fmt.pix.field = V4L2_FIELD_NONE;
  988.  
  989.  
  990. if (-1 == xioctl (fd2, VIDIOC_S_FMT, &fmt2))
  991. errno_exit ("VIDIOC_S_FMT");
  992.  
  993.  
  994.  
  995.  
  996. /* Note VIDIOC_S_FMT may change width and height. */
  997.  
  998. /* Buggy driver paranoia. */
  999. min = fmt.fmt.pix.width * 2;
  1000. if (fmt.fmt.pix.bytesperline < min)
  1001. fmt.fmt.pix.bytesperline = min;
  1002. min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
  1003. if (fmt.fmt.pix.sizeimage < min)
  1004. fmt.fmt.pix.sizeimage = min;
  1005.  
  1006.  
  1007. switch (io) {
  1008. case IO_METHOD_READ:
  1009.  
  1010. init_read (fmt.fmt.pix.sizeimage);
  1011. break;
  1012.  
  1013. case IO_METHOD_MMAP:
  1014. init_mmap ();
  1015. break;
  1016.  
  1017. case IO_METHOD_USERPTR:
  1018.  
  1019. init_userp (fmt.fmt.pix.sizeimage);
  1020. break;
  1021. }
  1022.  
  1023. }
  1024.  
  1025.  
  1026. static void
  1027. close_device (void)
  1028. {
  1029. if (-1 == close (fd))
  1030. errno_exit ("close");
  1031.  
  1032. fd = -1;
  1033.  
  1034. if (-1 == close (fd2))
  1035. errno_exit ("close2");
  1036.  
  1037. fd2 = -1;
  1038. }
  1039.  
  1040. static void
  1041. open_device (void)
  1042. {
  1043. struct stat st;
  1044.  
  1045. if (-1 == stat (dev_name, &st)) {
  1046. fprintf (stderr, "Cannot identify '%s': %d, %s\n",
  1047. dev_name, errno, strerror (errno));
  1048. exit (EXIT_FAILURE);
  1049. }
  1050.  
  1051. if (!S_ISCHR (st.st_mode)) {
  1052. fprintf (stderr, "%s is no device\n", dev_name);
  1053. exit (EXIT_FAILURE);
  1054. }
  1055.  
  1056. fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
  1057.  
  1058. if (-1 == fd) {
  1059. fprintf (stderr, "Cannot open '%s': %d, %s\n",
  1060. dev_name, errno, strerror (errno));
  1061. exit (EXIT_FAILURE);
  1062. }
  1063.  
  1064. //======================================================================
  1065.  
  1066. struct stat st2;
  1067.  
  1068. if (-1 == stat (dev_name2, &st2)) {
  1069. fprintf (stderr, "Cannot identify '%s': %d, %s\n",
  1070. dev_name2, errno, strerror (errno));
  1071. exit (EXIT_FAILURE);
  1072. }
  1073.  
  1074. if (!S_ISCHR (st2.st_mode)) {
  1075. fprintf (stderr, "%s is no device\n", dev_name2);
  1076. exit (EXIT_FAILURE);
  1077. }
  1078.  
  1079. fd2 = open (dev_name2, O_RDWR /* required */ | O_NONBLOCK, 0);
  1080.  
  1081. if (-1 == fd2) {
  1082. fprintf (stderr, "Cannot open '%s': %d, %s\n",
  1083. dev_name2, errno, strerror (errno));
  1084. exit (EXIT_FAILURE);
  1085. }
  1086.  
  1087. }
  1088.  
  1089. static void
  1090. usage (FILE * fp,
  1091. int argc,
  1092. char ** argv)
  1093. {
  1094. fprintf (fp,
  1095. "Usage: %s [options]\n\n"
  1096. "Options:\n"
  1097. "-x | --width width capture resolution \n"
  1098. "-y | --height height capture resolution \n"
  1099. "-h | --help Print this message\n"
  1100. "-m | --mmap Use memory mapped buffers\n"
  1101. "-r | --read Use read() calls\n"
  1102. "-u | --userp Use application allocated buffers\n"
  1103. "",
  1104. argv[0]);
  1105. }
  1106.  
  1107. static const char short_options [] = "x:y:hmru";
  1108.  
  1109. static const struct option
  1110. long_options [] = {
  1111. { "width", required_argument, NULL, 'x' },
  1112. { "height", required_argument, NULL, 'y' },
  1113. { "help", no_argument, NULL, 'h' },
  1114. { "mmap", no_argument, NULL, 'm' },
  1115. { "read", no_argument, NULL, 'r' },
  1116. { "userp", no_argument, NULL, 'u' },
  1117. { 0, 0, 0, 0 }
  1118. };
  1119.  
  1120. int
  1121. main (int argc,char ** argv)
  1122. {
  1123. dev_name = "/dev/video0";
  1124. dev_name2 = "/dev/video1";
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130. for (;;) {
  1131. int index;
  1132. int c;
  1133.  
  1134. c = getopt_long (argc, argv,
  1135. short_options, long_options,
  1136. &index);
  1137.  
  1138. if (-1 == c)
  1139. break;
  1140.  
  1141. switch (c) {
  1142. case 0: /* getopt_long() flag */
  1143. break;
  1144.  
  1145. case 'x':
  1146. width_cap = atoi(optarg);
  1147. break;
  1148. case 'y':
  1149. height_cap = atoi(optarg);
  1150. break;
  1151.  
  1152. case 'h':
  1153. usage (stdout, argc, argv);
  1154. exit (EXIT_SUCCESS);
  1155.  
  1156. case 'm':
  1157. io = IO_METHOD_MMAP;
  1158. break;
  1159.  
  1160. case 'r':
  1161. io = IO_METHOD_READ;
  1162. break;
  1163.  
  1164. case 'u':
  1165. io = IO_METHOD_USERPTR;
  1166. break;
  1167.  
  1168. default:
  1169. usage (stderr, argc, argv);
  1170. exit (EXIT_FAILURE);
  1171. }
  1172. }
  1173.  
  1174.  
  1175. int which = PRIO_PROCESS;
  1176. id_t pid;
  1177. int priority = 19;
  1178. int ret;
  1179.  
  1180.  
  1181. pid = getpid();
  1182. ret = setpriority(which, pid, priority);
  1183.  
  1184.  
  1185. fprintf (stdout, "begin ...\r\n");
  1186.  
  1187. cvNamedWindow( "Cam1", CV_WINDOW_AUTOSIZE );
  1188. frame = cvCreateImage(cvSize(width_cap,height_cap), IPL_DEPTH_8U, 3);
  1189.  
  1190. cvNamedWindow( "Cam2", CV_WINDOW_AUTOSIZE );
  1191. frame2 = cvCreateImage(cvSize(width_cap,height_cap), IPL_DEPTH_8U, 3);
  1192.  
  1193. cvNamedWindow( "Canny", CV_WINDOW_AUTOSIZE );
  1194. grayImg = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
  1195.  
  1196. cannyImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
  1197.  
  1198. fprintf (stdout, "capture resolution %dx%d \r\n",width_cap,height_cap);
  1199.  
  1200. fprintf (stdout, "open_device\r\n");
  1201. open_device();
  1202. fprintf (stdout, "init_device\r\n");
  1203. init_device ();
  1204.  
  1205.  
  1206. fprintf (stdout, "start_capturing\r\n");
  1207. start_capturing ();
  1208.  
  1209. fprintf (stdout, "mainloop\r\n");
  1210. mainloop ();
  1211.  
  1212.  
  1213. stop_capturing ();
  1214. fprintf (stdout, "stop_capturing\r\n");
  1215.  
  1216. uninit_device ();
  1217. fprintf (stdout, "uninit_device \r\n");
  1218.  
  1219. close_device ();
  1220. fprintf (stdout, " close_device\r\n");
  1221.  
  1222. cvReleaseImage( &grayImg );
  1223. cvReleaseImage( &cannyImg );
  1224. cvDestroyWindow( "Canny" );
  1225.  
  1226. cvReleaseImage( &frame );
  1227. cvDestroyWindow( "Cam1" );
  1228.  
  1229. cvReleaseImage( &frame2 );
  1230. cvDestroyWindow( "Cam2" );
  1231.  
  1232. fprintf (stdout, "...end \r\n");
  1233. exit (EXIT_SUCCESS);
  1234.  
  1235. return 0;
  1236. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:6:23: error: opencv/cv.h: No such file or directory
prog.cpp:7:28: error: opencv/highgui.h: No such file or directory
prog.cpp:8:26: error: opencv/cvaux.h: No such file or directory
prog.cpp:9:20: error: cxmisc.h: No such file or directory
prog.cpp:78: error: expected constructor, destructor, or type conversion before ‘*’ token
prog.cpp:79: error: expected constructor, destructor, or type conversion before ‘*’ token
prog.cpp:80: error: expected constructor, destructor, or type conversion before ‘*’ token
prog.cpp:81: error: expected constructor, destructor, or type conversion before ‘*’ token
prog.cpp: In function ‘void process_image(const void*, const void*)’:
prog.cpp:178: error: ‘frame’ was not declared in this scope
prog.cpp:178: error: ‘frame2’ was not declared in this scope
prog.cpp:182: error: ‘grayImg’ was not declared in this scope
prog.cpp:182: error: ‘CV_BGR2GRAY’ was not declared in this scope
prog.cpp:182: error: ‘cvCvtColor’ was not declared in this scope
prog.cpp:185: error: ‘cannyImg’ was not declared in this scope
prog.cpp:185: error: ‘cvCanny’ was not declared in this scope
prog.cpp:189: error: ‘cvShowImage’ was not declared in this scope
prog.cpp:192: error: ‘cvWaitKey’ was not declared in this scope
prog.cpp: In function ‘void mainloop()’:
prog.cpp:411: warning: the address of ‘int read_frame()’ will always evaluate as ‘true’
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:1123: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:1124: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:1187: error: ‘CV_WINDOW_AUTOSIZE’ was not declared in this scope
prog.cpp:1187: error: ‘cvNamedWindow’ was not declared in this scope
prog.cpp:1188: error: ‘frame’ was not declared in this scope
prog.cpp:1188: error: ‘cvSize’ was not declared in this scope
prog.cpp:1188: error: ‘IPL_DEPTH_8U’ was not declared in this scope
prog.cpp:1188: error: ‘cvCreateImage’ was not declared in this scope
prog.cpp:1191: error: ‘frame2’ was not declared in this scope
prog.cpp:1194: error: ‘grayImg’ was not declared in this scope
prog.cpp:1194: error: ‘cvGetSize’ was not declared in this scope
prog.cpp:1196: error: ‘cannyImg’ was not declared in this scope
prog.cpp:1222: error: ‘cvReleaseImage’ was not declared in this scope
prog.cpp:1224: error: ‘cvDestroyWindow’ was not declared in this scope
prog.cpp: At global scope:
prog.cpp:76: warning: ‘n_buffers2’ defined but not used
stdout
Standard output is empty