Android S5PV210 camera驱动测试程序

来源:互联网 发布:vb请假管理 编辑:程序博客网 时间:2024/05/17 05:01

分类: Android Samsung S5PV210 480人阅读 评论(13) 收藏 举报

最近在调试S5PV210上的camera驱动,因为对Android的samsung camera hal 不太了解,自己写了个测试程序方便调试

因为camera驱动都是遵守V4L2标准,所以测试程序是通用的,在MX51平台也能工作。

[html] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <assert.h>  
  5. #include <getopt.h>    
  6. #include <fcntl.h>    
  7. #include <unistd.h>  
  8. #include <errno.h>  
  9. #include <sys/stat.h>  
  10. #include <sys/types.h>  
  11. #include <sys/time.h>  
  12. #include <sys/mman.h>  
  13. #include <sys/ioctl.h>  
  14. #include <asm/types.h>  
  15. #include <linux/videodev2.h>  
  16. #include <linux/fb.h>  
  17.   
  18. #define CLEAR(x) memset (&(x), 0, sizeof (x))  
  19.   
  20. int PAL_WIDTH = 720;  
  21. int PAL_HEIGHT = 576;  
  22.   
  23. enum {  
  24.     RGB565,  
  25.     RGB888,  
  26.     RGB32,  
  27. };  
  28.   
  29. struct buffer {  
  30.     void *start;  
  31.     size_t length;  
  32. };  
  33.   
  34. static char *dev_name = NULL;  
  35. static int fd = -1;  
  36. static unsigned int n_buffers = 0;  
  37. static int g_width;  
  38. static int g_height;  
  39. static unsigned  g_pixelformat;  
  40. static struct fb_var_screeninfo vinfo;  
  41. static struct fb_fix_screeninfo finfo;  
  42. struct buffer *buffers = NULL;  
  43. static int file_index = 1;  
  44. static int g_count = 9;  
  45.   
  46.    
  47. static void errno_exit (const char * s)  
  48. {  
  49.     fprintf (stderr, "%s error %d, %s\n",s, errno, strerror (errno));  
  50.     exit (EXIT_FAILURE);  
  51. }  
  52.    
  53. static int xioctl (int fd,int request,void * arg)  
  54. {  
  55.     int r;  
  56.     do r = ioctl (fd, request, arg);  
  57.     while (-1 == r && EINTR == errno);  
  58.     return r;  
  59. }  
  60.    
  61. static void write_yuv(const void *p, int index)  
  62. {  
  63.     int write_fd = 0;  
  64.     int ret;  
  65.     int length;  
  66.     char tmp[20];  
  67.   
  68.     sprintf(tmp, "/data/file/yuvfile%d", index);  
  69.   
  70.     write_fd = open(tmp, O_RDWR|O_CREAT);  
  71.     if (write_fd == -1) {  
  72.         printf("%s: open yuvfile failed, errno(%d)\n", __func__, errno);  
  73.     }  
  74.   
  75.     length = g_width * g_height * 2;  
  76.     ret = write(write_fd, p, length);  
  77.     if (ret != length) {  
  78.         printf("%s: write yuvfile failed, ret(%d), errno(%d)\n", __func__, ret, errno);  
  79.     }  
  80. }  
  81.   
  82. static void process_image(const void *p)  
  83. {  
  84.     if (file_index < g_count) {  
  85.         write_yuv(p, file_index);  
  86.         file_index = file_index + 1;  
  87.     }  
  88. }  
  89.   
  90. static int read_frame(void)  
  91. {  
  92.     int ret = 0;  
  93.     struct timeval timer;  
  94.     struct v4l2_buffer buf;  
  95.   
  96.     CLEAR (buf);  
  97.     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  98.     buf.memory = V4L2_MEMORY_MMAP;  
  99.   
  100.     if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {  
  101.         switch (errno) {  
  102.         case EAGAIN:  
  103.             printf("VIDIOC_DQBUF return EAGAIN\n");  
  104.             return 0;  
  105.         default:  
  106.             printf("VIDIOC_DQBUF failed, errno(%d):\n", errno, strerror(errno));  
  107.             ret = -errno;  
  108.             return ret;  
  109.         }  
  110.     }  
  111.   
  112.     assert (buf.index < n_buffers);  
  113.     printf("%s: buf.bytesused(%d), buf.index(%d)\n",   
  114.             __func__, buf.index);  
  115.     process_image(buffers[buf.index].start);  
  116.     if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {  
  117.         printf("VIDIOC_BUF failed, errno(%d)\n", errno);  
  118.         ret = -errno;  
  119.     }  
  120.   
  121.     gettimeofday(&timer, NULL);  
  122.     printf("(%d)th capture, tv_sec(%d), tv_usec\n",   
  123.             file_index, timer.tv_sec, timer.tv_usec);  
  124.   
  125.     return ret;  
  126. }  
  127.    
  128. static void run(void)  
  129. {  
  130.     int ret;  
  131.   
  132.     printf("%s: enter\n", __func__);  
  133.   
  134.     while (1) {  
  135.         fd_set fds;  
  136.         struct timeval tv;  
  137.         FD_ZERO (&fds);  
  138.         FD_SET(fd, &fds);  
  139.           
  140.         if (file_index == g_count) {  
  141.             break;  
  142.         }  
  143.   
  144.         tv.tv_sec = 5;  
  145.         tv.tv_usec = 0;  
  146.   
  147.         ret = select(fd + 1, &fds, NULL, NULL, &tv);  
  148.         if (-1 == ret) {  
  149.             if (EINTR == errno) {  
  150.                 printf("errno == EINTR\n");  
  151.                 continue;  
  152.             }  
  153.             errno_exit("select");  
  154.         }  
  155.   
  156.         if (0 == ret) {  
  157.             printf("select timeout\n");  
  158.             exit(EXIT_FAILURE);  
  159.         }  
  160.   
  161.         if (read_frame())  
  162.             continue;  
  163.         sleep(1);  
  164.     }  
  165.   
  166.     printf("%s: end run\n", __func__);  
  167. }  
  168.   
  169. static void stop_capturing (void)  
  170. {  
  171.     enum v4l2_buf_type type;  
  172.   
  173.     printf("%s: enter\n", __func__);  
  174.   
  175.     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  176.     if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))  
  177.         errno_exit ("VIDIOC_STREAMOFF");  
  178. }  
  179.    
  180. static void start_capturing(void)  
  181. {  
  182.     unsigned int i;  
  183.     enum v4l2_buf_type type;  
  184.   
  185.     printf("%s: enter\n", __func__);  
  186.    
  187.     for (i = 0; i < n_buffers; ++i) {  
  188.         struct v4l2_buffer buf;  
  189.         CLEAR (buf);  
  190.   
  191.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  192.         buf.memory = V4L2_MEMORY_MMAP;  
  193.         buf.index = i;  
  194.   
  195.         if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))  
  196.             errno_exit ("VIDIOC_QBUF");  
  197.     }  
  198.   
  199.     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  200.   
  201.     if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))  
  202.         errno_exit ("VIDIOC_STREAMON");  
  203.   
  204. }  
  205.   
  206. static void uninit_device (void)  
  207. {  
  208.     unsigned int i;  
  209.    
  210.     for (i = 0; i < n_buffers; ++i)  
  211.         if (-1 == munmap(buffers[i].start, buffers[i].length))  
  212.             errno_exit ("munmap");  
  213.       
  214.     free (buffers);  
  215. }  
  216.   
  217.   
  218. static void init_mmap (void)  
  219. {  
  220.     struct v4l2_requestbuffers req;  
  221.   
  222.     CLEAR (req);   
  223.     req.count = 4;  
  224.     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  225.     req.memory = V4L2_MEMORY_MMAP;  
  226.     if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {  
  227.         if (EINVAL == errno) {  
  228.             fprintf (stderr, "%s does not support memory mapping\n", dev_name);  
  229.             exit (EXIT_FAILURE);  
  230.         } else {  
  231.             errno_exit ("VIDIOC_REQBUFS");  
  232.         }  
  233.     }  
  234.    
  235.     if (req.count < 2) {    //if (req.count < 2)  
  236.         fprintf (stderr, "Insufficient buffer memory on %s\n",dev_name);  
  237.         exit (EXIT_FAILURE);  
  238.     }  
  239.    
  240.     buffers = calloc(req.count, sizeof(*buffers));  
  241.     if (!buffers) {  
  242.         fprintf (stderr, "Out of memory\n");  
  243.         exit (EXIT_FAILURE);  
  244.     }  
  245.     printf("request buffer count(%d)\n", req.count);  
  246.    
  247.     for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {  
  248.         struct v4l2_buffer buf;  
  249.    
  250.         CLEAR (buf);  
  251.    
  252.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  253.         buf.memory = V4L2_MEMORY_MMAP;  
  254.         buf.index = n_buffers;  
  255.    
  256.         if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))  
  257.             errno_exit ("VIDIOC_QUERYBUF");  
  258.    
  259.         buffers[n_buffers].length = buf.length;  
  260.         buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);  
  261.         printf("buf.start(%p), buf.length(%d)\n", buffers[n_buffers].start, buf.length);  
  262.         if (MAP_FAILED == buffers[n_buffers].start)  
  263.             errno_exit ("mmap");  
  264.     }  
  265.    
  266. }  
  267.   
  268. static void init_device (void)  
  269. {  
  270.     struct v4l2_capability cap;  
  271.     struct v4l2_cropcap cropcap;  
  272.     struct v4l2_crop crop;  
  273.     struct v4l2_format fmt;  
  274.   
  275.     if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {  
  276.         printf("%s: VIDIOC_QUERYCAP\n", __func__, errno);  
  277.         exit (EXIT_FAILURE);  
  278.     }  
  279.   
  280.     printf("support overlay cap.capabilities(0x%x)\n", cap.capabilities);  
  281.     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {  
  282.         fprintf (stderr, "%s is no video capture device\n",dev_name);  
  283.         exit (EXIT_FAILURE);  
  284.     }  
  285.    
  286.     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {  
  287.         fprintf (stderr, "%s does not support streaming i/o\n",dev_name);  
  288.         exit (EXIT_FAILURE);  
  289.     }  
  290.    
  291.     CLEAR (cropcap);   
  292.     cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  293.     if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {  
  294.         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  295.         crop.c = cropcap.defrect;  
  296.   
  297.         if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {  
  298.             printf("VIDIOC_S_CROP failed(%d), %s\n", errno, strerror(errno));  
  299.         }  
  300.     }  
  301.   
  302.     CLEAR (fmt);  
  303.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  304.     fmt.fmt.pix.width = PAL_WIDTH;  
  305.     fmt.fmt.pix.height = PAL_HEIGHT;  
  306.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;  
  307.     fmt.fmt.pix.field = V4L2_FIELD_NONE;  
  308.     if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) {  
  309.         errno_exit ("VIDIOC_S_FMT");  
  310.     }  
  311.   
  312.     printf("width(%d), height(%d), pixelformat(0x%x), field(%d)\n",   
  313.             fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.pixelformat,   
  314.             fmt.fmt.pix.field);  
  315.   
  316.     g_width = fmt.fmt.pix.width;  
  317.     g_height = fmt.fmt.pix.height;  
  318.   
  319.     init_mmap ();  
  320. }  
  321.    
  322. static void close_device(void)  
  323. {  
  324.     close(fd);  
  325. }  
  326.   
  327. static void open_device(void)  
  328. {  
  329.     struct stat st;    
  330.   
  331.   
  332.     fd = open(dev_name, O_RDWR| O_NONBLOCK, 0);  
  333.     if (-1 == fd) {  
  334.         fprintf (stderr, "Cannot open '%s': %d, %s\n",   
  335.                 dev_name, errno, strerror (errno));  
  336.         exit (EXIT_FAILURE);  
  337.     }  
  338. }  
  339.   
  340. static void usage (FILE * fp,int argc,char ** argv)  
  341. {  
  342.     fprintf (fp,  
  343.             "Usage: %s [options]\n\n"  
  344.             "Options:\n"  
  345.             "-d | --device name Video device name [/dev/video]\n"  
  346.             "-h | --help Print this message\n"  
  347.             "-t | --how long will display in seconds\n"  
  348.             "",  
  349.             argv[0]);  
  350. }  
  351.   
  352. static const char short_options [] = "d:w:h:f:p:c:";  
  353. static const struct option long_options [] = {  
  354.     { "device", required_argument, NULL, 'd' },  
  355.     { "help", no_argument, NULL, 'h' },  
  356.     { "time", no_argument, NULL, 't' },  
  357.     { 0, 0, 0, 0 }  
  358. };  
  359.   
  360. int select_input(int input)  
  361. {  
  362.     int ret;  
  363.     ret = xioctl(fd, VIDIOC_S_INPUT, &input);  
  364.     if (ret) {  
  365.         printf("xioctl VIDIOC_S_INPUT failed errno(%d)\n", errno);  
  366.     }     
  367.   
  368.     return ret;  
  369. }     
  370.   
  371.   
  372. int main (int argc,char ** argv)  
  373. {  
  374.     dev_name = "/dev/video0";  
  375.   
  376.     for (;;) {  
  377.         int index;  
  378.         int c;  
  379.         int tmp;  
  380.   
  381.         c = getopt_long(argc, argv, short_options, long_options, &index);  
  382.         if (-1 == c)  
  383.             break;  
  384.   
  385.         switch (c) {  
  386.             case 0:  
  387.                 break;  
  388.             case 'd':  
  389.                 dev_name = optarg;  
  390.                 break;  
  391.             case 'c':  
  392.                 g_count = strtol(optarg, NULL, 10);  
  393.                 break;  
  394.             case 'p':  
  395.                 tmp = strtol(optarg, NULL, 10);  
  396.                 if (tmp == 0) {  
  397.                     g_pixelformat = V4L2_PIX_FMT_UYVY;  
  398.                 }  
  399.                 else if (tmp == 1) {  
  400.                     g_pixelformat = V4L2_PIX_FMT_YUYV;  
  401.                 }  
  402.                 break;  
  403.             case 'w':  
  404.                 PAL_WIDTH = strtol(optarg, NULL, 10);  
  405.                 printf("PAL_WIDTH(%d)\n", PAL_WIDTH);  
  406.                 break;  
  407.             case 'h':  
  408.                 PAL_HEIGHT = strtol(optarg, NULL, 10);  
  409.                 printf("PAL_HEIGHT(%d)\n", PAL_HEIGHT);  
  410.                 break;  
  411.             default:  
  412.                 usage (stderr, argc, argv);  
  413.                 exit (EXIT_FAILURE);  
  414.         }  
  415.     }  
  416.   
  417.     open_device();  
  418.     select_input(0);  
  419.     init_device();  
  420.     start_capturing ();  
  421.     run();  
  422.     stop_capturing();  
  423.     uninit_device();  
  424.     close_device();  
  425.   
  426.     return 0;  
  427. }  
原创粉丝点击