Advertisement
Guest User

Untitled

a guest
Oct 26th, 2012
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.55 KB | None | 0 0
  1.  
  2. /*
  3. * ALEXEEV (c) 2012 compilated from mxc_fb_test and some other source (don't remember now)
  4. *
  5. * This program can be used and distributed without restrictions.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <assert.h>
  12.  
  13. #include <fcntl.h> /* low-level i/o */
  14. #include <unistd.h>
  15. #include <errno.h>
  16. #include <malloc.h>
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. #include <sys/time.h>
  20. #include <sys/mman.h>
  21. #include <sys/ioctl.h>
  22.  
  23. #include <asm/types.h> /* for videodev2.h */
  24.  
  25. #include <linux/videodev2.h>
  26.  
  27. #include <linux/fb.h>
  28.  
  29. /* Standard Include Files */
  30. #include <unistd.h>
  31. #include <linux/mxcfb.h>
  32. #include <math.h>
  33.  
  34. #define TFAIL -1
  35. #define TPASS 0
  36.  
  37. int fd_fb = 0;
  38. unsigned short * fb;
  39. int g_fb_size;
  40.  
  41. char *dev_name = "/dev/video0";
  42.  
  43.  
  44. #define CLEAR(x) memset (&(x), 0, sizeof (x))
  45.  
  46. struct buffer {
  47. void *start;
  48. size_t length;
  49. };
  50.  
  51. static int fd = -1;
  52. struct buffer *buffers = NULL;
  53. static unsigned int n_buffers = 0;
  54.  
  55. static void errno_exit(const char *s) {
  56. fprintf (stderr, "%s error %d, %s\n", s, errno, strerror (errno));
  57.  
  58. exit (EXIT_FAILURE);
  59. }
  60.  
  61. static int xioctl(int fd, int request, void * arg) {
  62. int r;
  63.  
  64. do r = ioctl (fd, request, arg);
  65. while (-1 == r && EINTR == errno);
  66.  
  67. return r;
  68. }
  69.  
  70. //---------------------------------------------------------------
  71. void saveToFile(const void *p, size_t length) {
  72. //fputc ('.', stdout);
  73.  
  74. printf ("saving image to file, length=%d\n", length);
  75. char s[4096];
  76. int i;
  77. sprintf (s,"");
  78. FILE *f;
  79.  
  80. f = fopen ("output.bin", "wb");
  81. fwrite (p, sizeof(char), length, f);
  82. fclose(f);
  83.  
  84. /*
  85. char *t = (char *)p;
  86. char w[10];
  87. for (i=0; i<64; i++)
  88. {
  89. sprintf (w, "%02X ", *t);
  90. strcat(s,w);
  91. t++;
  92. }
  93. strcat(s,"\n");
  94. fprintf (stderr, s);
  95. */
  96.  
  97. }
  98. //---------------------------------------------------------------
  99.  
  100. void YUV444toRGB888 (char y, char u, char v, char *r, char *g, char *b)
  101. {
  102. *r = 1.164*(y - 16) + 1.596*(v - 128);
  103. *g = 1.164*(y - 16) - 0.813*(v - 128) - 0.391*(u - 128);
  104. *b = 1.164*(y - 16) + 2.018*(u - 128);
  105. }
  106.  
  107. //---------------------------------------------------------------
  108.  
  109. char clamp (int x)
  110. {
  111. if (x>255) return 255;
  112. if (x<0) return 0;
  113. return x;
  114. }
  115.  
  116.  
  117. void showFrame(const void *p, size_t length)
  118. {
  119. printf ("show frame called\n");
  120.  
  121. // -------- working with display --------------------
  122.  
  123.  
  124.  
  125. printf ("image received, length=%d\n", length);
  126. char s[4096];
  127. sprintf (s,"");
  128.  
  129.  
  130. /* saving to file
  131. FILE *f;
  132. f = fopen ("output.bin", "wb");
  133. fwrite (p, sizeof(char), length, f);
  134. fclose(f);
  135. */
  136.  
  137. printf ("now displaying...\n");
  138.  
  139.  
  140. int width=640;
  141. int height=480;
  142. long size = width*height;
  143.  
  144. // pixel format = 24bit
  145. char i420[length];
  146.  
  147. typedef struct {
  148. char y, u, v;
  149. } Tyuv ;
  150. typedef struct {
  151. char r;
  152. char g;
  153. char b;
  154. } Trgb;
  155. Tyuv yuv[size];
  156. Trgb rgb[size];
  157. //int i;
  158. printf ("copying buffer to i420 array\n");
  159. int i;
  160.  
  161. for(i = 0; i < length; i++ )
  162. {
  163. i420[i] = *(char *)p++;
  164. }
  165.  
  166.  
  167. // Переписали все компоненты яркости, в данном формате их по каждой на пиксел
  168. printf ("copying Y\n");
  169.  
  170. for(i = 0; i < width*height; i++ )
  171. {
  172. yuv[i].y = i420[i];
  173. }
  174.  
  175. //saveToFile(i420, length);
  176.  
  177. int Counter = 0;
  178.  
  179. // Теперь компоненты цветоразностей, они одинаковы в каждом макропикселе, который представляет собой квадрат размером 2х2 пиксела
  180. printf ("copying U and V\n");
  181. for(i = 0; i < width*height/4; i++ )
  182. {
  183. //printf ("counter=%d\n", Counter);
  184. yuv[Counter].u =
  185. yuv[Counter + 1].u =
  186. yuv[Counter + width].u =
  187. yuv[Counter + width + 1].u = i420[width*height + i];
  188.  
  189. yuv[Counter].v =
  190. yuv[Counter + 1].v =
  191. yuv[Counter + width].v =
  192. yuv[Counter + width + 1].v = i420[width*height + i + width*height/4];
  193.  
  194. Counter += 2;
  195. if( Counter%width == 0 )
  196. if( (Counter/width)%2 != 0 )
  197. Counter += width;
  198. }
  199.  
  200. //saveToFile(&yuv[0], size*3);// -- OK WORK!
  201.  
  202.  
  203.  
  204. printf ("converting yuv to rgb\n");
  205.  
  206.  
  207. // теперь конфертнем из YUV в RGB
  208. for( i = 0; i < size; i++ )
  209. {
  210. //printf ("i=%d\n", i);
  211. /*
  212. rgb[i].b = 1.164*(yuv[i].y - 16) + 2.018*(yuv[i].u - 128);
  213. rgb[i].g = 1.164*(yuv[i].y - 16) - 0.813*(yuv[i].v - 128) - 0.391*(yuv[i].u - 128);
  214. rgb[i].r = 1.164*(yuv[i].y- 16) + 1.596*(yuv[i].v - 128);
  215. */
  216. int C,D,E;
  217. int Y= yuv[i].y;
  218. int U= yuv[i].u;
  219. int V= yuv[i].v;
  220. C = Y - 16;
  221. D = U - 128;
  222. E = V - 128;
  223.  
  224.  
  225. char R = clamp((int) ( 298 * C + 409 * E + 128) >> 8);
  226. char G = clamp((int) ( 298 * C - 100 * D - 208 * E + 128) >> 8);
  227. char B = clamp((int) ( 298 * C + 516 * D + 128) >> 8);
  228. rgb[i].r = R;
  229. rgb[i].g = G;
  230. rgb[i].b = B;
  231.  
  232. }
  233.  
  234. //saveToFile(&rgb[0], size*3);
  235.  
  236.  
  237.  
  238. int c=0;
  239. int x,y;
  240. printf ("displaying rgb to screen\n");
  241.  
  242. int screenwidth=800;
  243. int screenheight = 480;
  244.  
  245. for( y = 0; y < screenheight; y++ )
  246. {
  247. for(x = 0; x < screenwidth; x++)
  248. {
  249. if ( (x<width) && (y<height) )
  250. {
  251. ((__u8*)fb)[c++] = rgb[y*width + x].b; // Blue
  252. ((__u8*)fb)[c++] = rgb[y*width + x].g; // Green
  253. ((__u8*)fb)[c++] = rgb[y*width + x].r; // Red
  254. }
  255. else c+=3;
  256. }
  257. }
  258.  
  259.  
  260. return ;
  261.  
  262. }
  263.  
  264.  
  265.  
  266. //-----------------------------------------------------------------------------
  267. static int read_frame(void) {
  268. struct v4l2_buffer buf;
  269. unsigned int i;
  270.  
  271. fprintf (stderr, "VERSION 2.1 --- read frame called\n");
  272.  
  273. if (-1 == read (fd, buffers[0].start, buffers[0].length))
  274. {
  275. printf ("ERROR!\n");
  276.  
  277. switch (errno) {
  278. case EAGAIN:
  279. {
  280. printf ("EAGAIN\n");
  281. return 0;
  282. }
  283.  
  284. case EIO:
  285. /* Could ignore EIO, see spec. */
  286. /* fall through */
  287. printf ("EIO\n");
  288.  
  289. default:
  290. printf ("default\n");
  291. errno_exit ("read");
  292. }
  293.  
  294. }
  295. printf ("OK passed reading!\n");
  296. showFrame (buffers[0].start, buffers[0].length);
  297.  
  298. return 1;
  299. }
  300.  
  301. //-----------------------------------------------------------------------------
  302.  
  303. int InitFrameBuffer()
  304. {
  305. int retval = TPASS;
  306. struct fb_var_screeninfo screen_info;
  307. struct fb_fix_screeninfo fb_fix;
  308. u_int32_t screensize = 0;
  309.  
  310. if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0)
  311. {
  312. printf("Unable to open /dev/fb0\n");
  313. retval = TFAIL;
  314. return 1;
  315. }
  316.  
  317. retval = ioctl(fd_fb, FBIOGET_VSCREENINFO, &screen_info);
  318. if (retval < 0)
  319. {
  320. return 1;
  321. }
  322. printf("Set the background to 16-bpp\n");
  323. screen_info.bits_per_pixel = 16;
  324. screen_info.yoffset = 0;
  325. retval = ioctl(fd_fb, FBIOPUT_VSCREENINFO, &screen_info);
  326. if (retval < 0)
  327. {
  328. return 1;
  329. }
  330. printf ("screen info xres=%d, yres=%d, bits per pixel =%d\n", screen_info.xres , screen_info.yres , screen_info.bits_per_pixel );
  331. screensize = screen_info.xres * screen_info.yres * screen_info.bits_per_pixel / 8;
  332. g_fb_size = screen_info.xres * screen_info.yres_virtual * screen_info.bits_per_pixel / 8;
  333.  
  334. printf("\n Screen size = %u \n", screensize);
  335.  
  336. /* Map the device to memory*/
  337. fb = (unsigned short *)mmap(0, g_fb_size,PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
  338. if ((int)fb <= 0)
  339. {
  340. printf("\nError: failed to map framebuffer device 0 to memory.\n");
  341. return 1;
  342. }
  343.  
  344.  
  345. //__u32 screensize;
  346. //int retval;
  347. //struct fb_var_screeninfo screen_info;
  348.  
  349. retval = ioctl(fd_fb, FBIOGET_VSCREENINFO, &screen_info);
  350. if (retval < 0)
  351. {
  352. printf ("FBIOGET_VSCREENINFO failed\n");
  353. return;
  354. }
  355.  
  356. printf("Set the BG to 24-bpp\n");
  357. screen_info.bits_per_pixel = 24;
  358. retval = ioctl(fd_fb, FBIOPUT_VSCREENINFO, &screen_info);
  359. if (retval < 0)
  360. {
  361. return;
  362. }
  363. printf("fb_test: xres_virtual = %d\n", screen_info.xres_virtual);
  364. screensize = screen_info.xres * screen_info.yres * screen_info.bits_per_pixel / 8;
  365.  
  366.  
  367. return 0;
  368. }
  369.  
  370.  
  371.  
  372. //-------------------------------------------------------------------------
  373. static void singleloop(void) {
  374. unsigned int count;
  375.  
  376. //fprintf (stderr, "main loop started\n");
  377. count = 10000;
  378.  
  379. while (count-- > 0) {
  380. for (;;) {
  381. fd_set fds;
  382. struct timeval tv;
  383. int r;
  384.  
  385. FD_ZERO (&fds);
  386. FD_SET (fd, &fds);
  387.  
  388. /* Timeout. */
  389. tv.tv_sec = 2;
  390. tv.tv_usec = 0;
  391.  
  392. r = select (fd + 1, &fds, NULL, NULL, &tv);
  393.  
  394. if (-1 == r) {
  395. if (EINTR == errno)
  396. continue;
  397.  
  398. errno_exit ("select");
  399. }
  400.  
  401. if (0 == r) {
  402. fprintf (stderr, "select timeout\n");
  403. exit (EXIT_FAILURE);
  404. }
  405. /*
  406. if (read_frame ())
  407. break;
  408. */
  409. read_frame ();
  410.  
  411.  
  412. //fprintf (stderr, "main loop finished. \n");
  413. return;
  414.  
  415.  
  416. /* EAGAIN - continue select loop. */
  417. }
  418. }
  419. }
  420.  
  421. static void uninit_device(void) {
  422. unsigned int i;
  423.  
  424. free (buffers[0].start);
  425. free (buffers);
  426. }
  427.  
  428. static void init_read(unsigned int buffer_size) {
  429. buffers = calloc (1, sizeof (*buffers));
  430.  
  431. if (!buffers) {
  432. fprintf (stderr, "Out of memory\n");
  433. exit (EXIT_FAILURE);
  434. }
  435.  
  436. buffers[0].length = buffer_size;
  437. buffers[0].start = malloc (buffer_size);
  438.  
  439. if (!buffers[0].start) {
  440. fprintf (stderr, "Out of memory\n");
  441. exit (EXIT_FAILURE);
  442. }
  443. }
  444.  
  445. //-----------------------------------------------------------------------
  446.  
  447. static void init_device(char *dev_name) {
  448. struct v4l2_capability cap;
  449. struct v4l2_cropcap cropcap;
  450. struct v4l2_crop crop;
  451. struct v4l2_format fmt;
  452. unsigned int min;
  453.  
  454. //---- inserted by Alexeev -----------
  455.  
  456. //struct v4l2_format fmt;
  457. //struct v4l2_crop crop;
  458. struct v4l2_control ctrl;
  459. struct v4l2_streamparm parm;
  460. //int fd = 0;
  461. //struct v4l2_mxc_offset off;
  462. struct v4l2_dbg_chip_ident chip;
  463. struct v4l2_frmsizeenum fsize;
  464. struct v4l2_fmtdesc ffmt;
  465. //-----------end of paste-----------------
  466.  
  467.  
  468. if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
  469. if (EINVAL == errno) {
  470. fprintf (stderr, "%s is no V4L2 device\n",
  471. dev_name);
  472. exit (EXIT_FAILURE);
  473. } else {
  474. errno_exit ("VIDIOC_QUERYCAP");
  475. }
  476. }
  477.  
  478. if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
  479. fprintf (stderr, "%s is no video capture device\n",
  480. dev_name);
  481. exit (EXIT_FAILURE);
  482. }
  483.  
  484. if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
  485. fprintf (stderr, "%s does not support read i/o\n",
  486. dev_name);
  487. exit (EXIT_FAILURE);
  488. }
  489.  
  490. /* Select video input, video standard and tune here. */
  491.  
  492. CLEAR (cropcap);
  493.  
  494. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  495.  
  496. if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
  497. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  498. crop.c = cropcap.defrect; /* reset to default */
  499.  
  500. if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
  501. switch (errno) {
  502. case EINVAL:
  503. /* Cropping not supported. */
  504. break;
  505. default:
  506. /* Errors ignored. */
  507. break;
  508. }
  509. }
  510. } else {
  511. /* Errors ignored. */
  512. }
  513.  
  514.  
  515. CLEAR (fmt);
  516.  
  517. fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  518. fmt.fmt.pix.width = 640; //640;//1280; //2592;//640;
  519. fmt.fmt.pix.height = 480; //480; //720; // 1944; //480
  520.  
  521. // This worked with my capture card, but bombed with
  522. // "VIDIOC_S_FMT error 22, Invalid argument" on my Logitech QuickCam Pro 4000
  523. // fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  524. // This worked on the logitech:
  525. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
  526. fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
  527.  
  528. if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
  529. errno_exit("VIDIOC_S_FMT");
  530.  
  531.  
  532. //---------------------Inserted by Alexeev -----------------------------
  533.  
  534. //// ov5642_mode_QSXGA_2592_1944 = 6,
  535. int g_capture_mode=0;//2; //high resolution
  536.  
  537. /*
  538. ov5642_mode_MIN = 0,
  539. ov5642_mode_VGA_640_480 = 0,
  540. ov5642_mode_QVGA_320_240 = 1,
  541. ov5642_mode_NTSC_720_480 = 2,
  542. ov5642_mode_PAL_720_576 = 3,
  543. ov5642_mode_720P_1280_720 = 4,
  544. ov5642_mode_1080P_1920_1080 = 5,
  545. ov5642_mode_QSXGA_2592_1944 = 6,
  546. ov5642_mode_QCIF_176_144 = 7,
  547. ov5642_mode_MAX = 7
  548. */
  549.  
  550.  
  551. fsize.index = g_capture_mode;
  552. if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize) < 0)
  553. {
  554. printf("VIDIOC_ENUM_FRAMESIZES failed\n");
  555. return;
  556. }
  557.  
  558. printf("sensor frame size is %dx%d\n", fsize.discrete.width,
  559. fsize.discrete.height);
  560. ffmt.index = g_capture_mode;
  561. if (ioctl(fd, VIDIOC_ENUM_FMT, &ffmt) < 0)
  562. {
  563. printf("VIDIOC_ENUM_FMT failed\n");
  564. return;
  565. }
  566. if (ffmt.pixelformat == V4L2_PIX_FMT_YUYV)
  567. printf("sensor frame format is YUYV\n");
  568. else if (ffmt.pixelformat == V4L2_PIX_FMT_UYVY)
  569. printf("sensor frame format is UYVY\n");
  570.  
  571. parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // even if we make G_PARM the type of parm we must set
  572. if (ioctl(fd, VIDIOC_G_PARM, &parm) < 0)
  573. {
  574. printf("VIDIOC_G_PARM failed (parm type was %d) \n", parm.type);
  575. //return;
  576. }
  577. /*
  578. printf ("G_PARM:\n");
  579. printf ("capability = %d\n", parm.parm.capture.capability);
  580. printf ("time per frame: denom=%d, numer=%d\n", parm.parm.capture.timeperframe.denominator, parm.parm.capture.timeperframe.numerator);
  581. printf ("capturemode = %d\n", parm.parm.capture.capturemode);
  582. */
  583.  
  584. parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  585. parm.parm.capture.timeperframe.numerator = 1; //tgt_fps = timeperframe->denominator / timeperframe->numerator;
  586. parm.parm.capture.timeperframe.denominator = 30;
  587. parm.parm.capture.capturemode = g_capture_mode;
  588.  
  589. /*
  590. printf ("S_PARM:\n");
  591. printf ("capability = %d\n", parm.parm.capture.capability);
  592. printf ("time per frame: denom=%d, numer=%d\n", parm.parm.capture.timeperframe.denominator, parm.parm.capture.timeperframe.numerator);
  593. printf ("capturemode = %d\n", parm.parm.capture.capturemode);
  594. */
  595.  
  596.  
  597. /* CANCELLED
  598.  
  599. if (ioctl(fd, VIDIOC_S_PARM, &parm) < 0)
  600. {
  601. printf("VIDIOC_S_PARM failed\n");
  602. return;
  603. }
  604.  
  605. printf ("VIDIOC_S_PARM succeeded\n");
  606. */
  607.  
  608.  
  609. // --------------------- end of paste---------------------------
  610.  
  611.  
  612.  
  613. /* Note VIDIOC_S_FMT may change width and height. */
  614.  
  615. /* Buggy driver paranoia. */
  616. min = fmt.fmt.pix.width * 2;
  617. if (fmt.fmt.pix.bytesperline < min)
  618. fmt.fmt.pix.bytesperline = min;
  619. min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
  620. if (fmt.fmt.pix.sizeimage < min)
  621. fmt.fmt.pix.sizeimage = min;
  622.  
  623. init_read (fmt.fmt.pix.sizeimage);
  624. }
  625.  
  626. static void close_device(void) {
  627. if (-1 == close (fd))
  628. errno_exit ("close");
  629.  
  630. fd = -1;
  631. }
  632.  
  633. static void open_device(char *dev_name) {
  634. struct stat st;
  635.  
  636. if (-1 == stat (dev_name, &st)) {
  637. fprintf (stderr, "Cannot identify '%s': %d, %s\n",
  638. dev_name, errno, strerror (errno));
  639. exit (EXIT_FAILURE);
  640. }
  641.  
  642. if (!S_ISCHR (st.st_mode)) {
  643. fprintf (stderr, "%s is no device\n", dev_name);
  644. exit (EXIT_FAILURE);
  645. }
  646.  
  647. fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
  648.  
  649. if (-1 == fd) {
  650. fprintf (stderr, "Cannot open '%s': %d, %s\n",
  651. dev_name, errno, strerror (errno));
  652. exit (EXIT_FAILURE);
  653. }
  654. }
  655.  
  656.  
  657. int main(int argc, char **argv) {
  658.  
  659.  
  660. if (InitFrameBuffer())
  661. {
  662. printf ("Error. Failed\n");
  663. return;
  664. }
  665.  
  666. while (1)
  667. {
  668. open_device(dev_name);
  669. init_device(dev_name);
  670.  
  671.  
  672. singleloop();
  673.  
  674. uninit_device();
  675. close_device();
  676.  
  677. //break;
  678. }
  679.  
  680. close(fd_fb);
  681.  
  682.  
  683. exit(EXIT_SUCCESS);
  684. return 0;
  685. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement