Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1639852
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: 嵌入式

2011-06-16 01:33:45

Andrew Huang 转载请注明作者及网址

1.设备性能查询

v4l设备里中,使用ioctl的VIDIOCGCAP来查询设备的,这里v4l规定必须实现的操作.

struct video_capability  cap; 
 memset(&cap,0,sizeof(cap));
ret = ioctl(fd, VIDIOCGCAP, &cap);

其中struct video_capability定义在linux/videodevice.h.定义如下

struct video_capability
{
    char name[32];
    int type;
    int channels;    /* Num channels */
    int audios;    /* Num audio devices */
    int maxwidth;    /* Supported width */
    int maxheight;    /* And height */
    int minwidth;    /* Supported width */
    int minheight;    /* And height */
};


另外查询设备输入/输出通道,也是基本要求,用VIDIOCGCHAN命令


struct video_channel channel;
   int i;

   PRINT_V4L("channels\n");
       

   for(i=0; i<count;i++)
       {
        memset(&channel,0,sizeof(channel));
        channel.channel = i;
        if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) {
            
            continue;
        }
}

其中数据结构定义如下:
  

struct video_channel
{
    int channel;
    char name[32];
    int tuners;
    __u32 flags;
#define VIDEO_VC_TUNER        1    /* Channel has a tuner */
#define VIDEO_VC_AUDIO        2    /* Channel has audio */
    __u16 type;
#define VIDEO_TYPE_TV        1
#define VIDEO_TYPE_CAMERA    2
    __u16 norm;            /* Norm set by channel */
};


2.实现代码
  v4l设备里中,使用ioctlVIDIOCGPICT来查询设备的支持视频格式
   struct video_picture pic;
   memset(&pic,0,sizeof(pic));
 
   ret = ioctl(fd, VIDIOCGPICT, &pic);

 
其中video_picture的定义如下,plalette定义就是视频格式。
  1. struct video_picture
  2. {
  3.     __u16    brightness;
  4.     __u16    hue;
  5.     __u16    colour;
  6.     __u16    contrast;
  7.     __u16    whiteness;    /* Black and white only */
  8.     __u16    depth;        /* Capture depth */
  9.     __u16 palette;    /* Palette in use */
  10. #define VIDEO_PALETTE_GREY    1    /* Linear greyscale */
  11. #define VIDEO_PALETTE_HI240    2    /* High 240 cube (BT848) */
  12. #define VIDEO_PALETTE_RGB565    3    /* 565 16 bit RGB */
  13. #define VIDEO_PALETTE_RGB24    4    /* 24bit RGB */
  14. #define VIDEO_PALETTE_RGB32    5    /* 32bit RGB */
  15. #define VIDEO_PALETTE_RGB555    6    /* 555 15bit RGB */
  16. #define VIDEO_PALETTE_YUV422    7    /* YUV422 capture */
  17. #define VIDEO_PALETTE_YUYV    8
  18. #define VIDEO_PALETTE_UYVY    9    /* The great thing about standards is ... */
  19. #define VIDEO_PALETTE_YUV420    10
  20. #define VIDEO_PALETTE_YUV411    11    /* YUV411 capture */
  21. #define VIDEO_PALETTE_RAW    12    /* RAW capture (BT848) */
  22. #define VIDEO_PALETTE_YUV422P    13    /* YUV 4:2:2 Planar */
  23. #define VIDEO_PALETTE_YUV411P    14    /* YUV 4:1:1 Planar */
  24. #define VIDEO_PALETTE_YUV420P    15    /* YUV 4:2:0 Planar */
  25. #define VIDEO_PALETTE_YUV410P    16    /* YUV 4:1:0 Planar */
  26. #define VIDEO_PALETTE_PLANAR    13    /* start of planar entries */
  27. #define VIDEO_PALETTE_COMPONENT 7    /* start of component entries */
  28. };



3.实现代码
  1. /*
  2.  * Author: Andrew Huang <bluedrum@163.com>
  3.  * query v4l1 device capabilities
  4.  * date: 2010/06/16
  5.  */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <errno.h>

  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>

  12. #include <linux/videodev.h>

  13. #define PRINT_V4L printf

  14. #define PRINT_IOCTL_CMD(cmd) printf(" %15s = (0x%x)\n",#cmd,cmd)
  15. #define PRINT_IOCTL_CMD2(cmd,n) printf(" %-20s(%d) = (0x%x)\n",#cmd,n,cmd)

  16. #define PRINT_V4L_MEMBER(m) printf(" %-20s:",#m);
  17. #define PRINT_V4L_STRING(m) printf(" %-20s:\"%s\"\n",#m,m)
  18. #define PRINT_V4L_INT(m) printf(" %-20s:%d\n",#m,m)
  19. #define PRINT_V4L_INTX(m) printf(" %-20s:0x%x\n",#m,m)

  20. /* 显示enum 值的之一*/
  21. #define TEST_V4L_FLAG0(m,f) printf("%s",((m & f)==f)?#f:"")

  22. /* 显示一个组合值的所有内容 */
  23. #define PRINT_V4L_FLAGS(m) printf(" %-20s:0x%x [",#m,m) /* 组合值开始*/
  24. #define TEST_V4L_FLAG(m,f) printf("%s",((m & f)==f)?#f",":"") /* 组合值中间值,可以有多个*/
  25. #define PRINT_V4L_FLAGS2(m) printf("]\n") /* 组合值结束*/


  26. #define PRINT_INT(e) printf("%s=%d\n",#e,e)


  27. int v4l_get_channels(int fd,int count)
  28. {
  29.    struct video_channel channel;
  30.    int i;

  31.    PRINT_V4L("channels\n");
  32.        

  33.    for(i=0; i<count;i++)
  34.        {
  35.         memset(&channel,0,sizeof(channel));
  36.         channel.channel = i;
  37.         if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) {
  38.             
  39.             continue;
  40.         }

  41.          PRINT_IOCTL_CMD2(VIDIOCGCAP,i);
  42.   
  43.      PRINT_V4L_INT(channel.channel);    
  44.         PRINT_V4L_STRING(channel.name);
  45.          PRINT_V4L_INT(channel.tuners);
  46.         

  47.          PRINT_V4L_FLAGS(channel.flags);    
  48.         TEST_V4L_FLAG(channel.flags,VIDEO_VC_TUNER);
  49.         TEST_V4L_FLAG(channel.flags,VIDEO_VC_AUDIO);        
  50.         PRINT_V4L_FLAGS2(channel.flags);


  51.          PRINT_V4L_FLAGS(channel.type);    
  52.         TEST_V4L_FLAG(channel.type,VIDEO_TYPE_TV);
  53.         TEST_V4L_FLAG(channel.type,VIDEO_TYPE_CAMERA);        
  54.         PRINT_V4L_FLAGS2(channel.type);

  55.         PRINT_V4L_INT(channel.norm);
  56.         
  57.        }
  58.     
  59.    
  60.    
  61. }

  62. int v4l_query_video_cap(int fd)
  63. {
  64.  int ret;
  65. struct video_capability cap;
  66.  memset(&cap,0,sizeof(cap));
  67. ret = ioctl(fd, VIDIOCGCAP, &cap);
  68. if(ret < 0)
  69.     {
  70.      printf("get vidieo capability error,error code: %d \n", errno);
  71.      return ret;
  72.     }
  73.     PRINT_V4L("general info\n");
  74.     PRINT_IOCTL_CMD(VIDIOCGCAP);

  75.     PRINT_V4L_STRING(cap.name);
  76.     PRINT_V4L_INT(cap.channels);
  77.     PRINT_V4L_INT(cap.audios);
  78.     PRINT_V4L_INT(cap.maxwidth);
  79.     PRINT_V4L_INT(cap.maxheight);
  80.     PRINT_V4L_INT(cap.minwidth);
  81.     PRINT_V4L_INT(cap.minheight);
  82.     
  83.     
  84.     
  85.     PRINT_V4L_FLAGS(cap.type);    
  86.     TEST_V4L_FLAG(cap.type,VID_TYPE_CAPTURE);
  87.     TEST_V4L_FLAG(cap.type,VID_TYPE_TUNER);
  88.     TEST_V4L_FLAG(cap.type,VID_TYPE_TELETEXT);
  89.     TEST_V4L_FLAG(cap.type,VID_TYPE_OVERLAY);
  90.     TEST_V4L_FLAG(cap.type,VID_TYPE_CHROMAKEY);
  91.     TEST_V4L_FLAG(cap.type,VID_TYPE_CLIPPING);
  92.     TEST_V4L_FLAG(cap.type,VID_TYPE_FRAMERAM);
  93.     TEST_V4L_FLAG(cap.type,VID_TYPE_SCALES);
  94.     TEST_V4L_FLAG(cap.type,VID_TYPE_MONOCHROME);
  95.     TEST_V4L_FLAG(cap.type,VID_TYPE_SUBCAPTURE);
  96.     TEST_V4L_FLAG(cap.type,VID_TYPE_MPEG_DECODER);
  97.     TEST_V4L_FLAG(cap.type,VID_TYPE_MPEG_ENCODER);
  98.     TEST_V4L_FLAG(cap.type,VID_TYPE_MJPEG_DECODER);
  99.     TEST_V4L_FLAG(cap.type,VID_TYPE_MJPEG_ENCODER);


  100.     PRINT_V4L_FLAGS2(cap.type);

  101.     v4l_get_channels(fd,cap.channels);
  102.    return 0;

  103. }



  104. int v4l_query_video_picture(int fd)
  105. {

  106.  int ret;
  107.  struct video_picture pic;
  108.  memset(&pic,0,sizeof(pic));
  109.  
  110. ret = ioctl(fd, VIDIOCGPICT, &pic);
  111. if(ret < 0)
  112.     {
  113.      printf("get vidieo picture error,error code: %d \n", errno);
  114.      return ret;
  115.     }

  116.    
  117.     PRINT_IOCTL_CMD(VIDIOCGPICT);
  118.     PRINT_V4L_INT(pic.brightness);
  119.     PRINT_V4L_INT(pic.hue);
  120.     PRINT_V4L_INT(pic.colour);
  121.     PRINT_V4L_INT(pic.contrast);
  122.     PRINT_V4L_INT(pic.whiteness);
  123.     PRINT_V4L_INT(pic.depth);

  124.      PRINT_V4L_MEMBER(pic.palette);
  125.       TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_GREY);
  126.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_HI240);
  127.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_RGB565);
  128.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_RGB24);
  129.     TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_RGB32);
  130.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_RGB555);
  131.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV422);;
  132.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUYV);
  133.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_UYVY);
  134.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV420);
  135.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV411);
  136.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_RAW);
  137.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV422P);
  138.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV411P);
  139.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV420P);
  140.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_YUV410P);
  141.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_PLANAR);
  142.      TEST_V4L_FLAG0(pic.palette,VIDEO_PALETTE_COMPONENT);
  143.     
  144.      PRINT_V4L("\n");

  145.     return 0;
  146. }
  147. int main(int argc,char * argv[])
  148. {
  149.    char dev_name[64] = "/dev/video2";
  150.    int cam_fd =-1;

  151.    if(argc>1)
  152.        {
  153.         strncpy(dev_name,argv[1],sizeof(dev_name)-1);
  154.        }

  155.    
  156.     cam_fd = open(dev_name,O_RDWR|O_NONBLOCK);

  157.     if(cam_fd == -1)
  158.         {
  159.          printf("open failure \n");
  160.          return -1;
  161.         }


  162.     printf("### v4l device info [%s] ###\n",dev_name);

  163.     
  164.    v4l_query_video_cap(cam_fd);
  165.    
  166.    v4l_query_video_picture(cam_fd);
  167.    // get_supported_video_formats(cam_fd);
  168.     close(cam_fd);

  169.    return 0;
  170.     
  171. }





4.测试结果
   使用mini6410,Linux 2.6.28.6,注意这里/dev/video0 ,/dev/video1,CMOS摄像头,它们的驱动对于 V4l1,并且一运行某些V4L1ioctl命令的就产生oops.
 
关于修正这一些BUG,可以参见我的博文
     <信息的分析>>

     http://blog.chinaunix.net/space.php?uid=20587912&do=blog&id=2163944

使用用USB摄像头,我使用的是ZC301摄像头.设备结点是/dev/video2
 
三种测试结果如下:
 

./test_v4l /dev/video2
### v4l device info [/dev/video2] ###
general info
      VIDIOCGCAP = (0x803c7601)
  cap.name            :"PC Camera"
  cap.channels        :1
  cap.audios          :0
  cap.maxwidth        :640
  cap.maxheight       :480
  cap.minwidth        :48
  cap.minheight       :32
  cap.type            :0x1 [VID_TYPE_CAPTURE,]
channels
 VIDIOCGCAP          (0) = (0x803c7601)
  channel.channel     :0
  channel.name        :"zc3xx"
  channel.tuners      :0
  channel.flags       :0x0 []
  channel.type        :0x2 [VIDEO_TYPE_CAMERA,]
  channel.norm        :0
     VIDIOCGPICT = (0x800e7606)
  pic.brightness      :32896
  pic.hue             :0
  pic.colour          :0
  pic.contrast        :32768
  pic.whiteness       :39321
  pic.depth           :8
  pic.palette         :
-----------------------------------------------------------------------

./test_v4l /dev/video0
### v4l device info [/dev/video0] ###

general info
      VIDIOCGCAP = (0x803c7601)
  cap.name            :"s3c-fimc0"
  cap.channels        :2
  cap.audios          :0
  cap.maxwidth        :0
  cap.maxheight       :0
  cap.minwidth        :48
  cap.minheight       :32
  cap.type            :0x29 [VID_TYPE_CAPTURE,VID_TYPE_OVERLAY,VID_TYPE_CLIPPING,]
channels
 VIDIOCGCAP          (0) = (0x803c7601)
  channel.channel     :0
  channel.name        :"External Camera Input"
  channel.tuners      :0
  channel.flags       :0x0 []
  channel.type        :0x2 [VIDEO_TYPE_CAMERA,]
  channel.norm        :0
 VIDIOCGCAP          (1) = (0x803c7601)
  channel.channel     :1
  channel.name        :"Memory Input"
  channel.tuners      :0
  channel.flags       :0x0 []
  channel.type        :0x2 [VIDEO_TYPE_CAMERA,]
  channel.norm        :0
     VIDIOCGPICT = (0x800e7606)
  pic.brightness      :0
  pic.hue             :0
  pic.colour          :0
  pic.contrast        :0
  pic.whiteness       :0
  pic.depth           :32
  pic.palette         :
[root@FriendlyARM 2]#

--------------------------------------------------------------------------------------------------------------------------

./test_v4l /dev/video1
### v4l device info [/dev/video1] ###

general info
      VIDIOCGCAP = (0x803c7601)
  cap.name            :"s3c-fimc1"
  cap.channels        :2
  cap.audios          :0
  cap.maxwidth        :0
  cap.maxheight       :0
  cap.minwidth        :48
  cap.minheight       :32
  cap.type            :0x29 [VID_TYPE_CAPTURE,VID_TYPE_OVERLAY,VID_TYPE_CLIPPING,]
channels
 VIDIOCGCAP          (0) = (0x803c7601)
  channel.channel     :0
  channel.name        :"External Camera Input"
  channel.tuners      :0
  channel.flags       :0x0 []
  channel.type        :0x2 [VIDEO_TYPE_CAMERA,]
  channel.norm        :0
 VIDIOCGCAP          (1) = (0x803c7601)
  channel.channel     :1
  channel.name        :"Memory Input"
  channel.tuners      :0
  channel.flags       :0x0 []
  channel.type        :0x2 [VIDEO_TYPE_CAMERA,]
  channel.norm        :0
     VIDIOCGPICT = (0x800e7606)
  pic.brightness      :0
  pic.hue             :0
  pic.colour          :0
  pic.contrast        :0
  pic.whiteness       :0
  pic.depth           :32
  pic.palette         :
[root@FriendlyARM 2]#



阅读(3173) | 评论(0) | 转发(7) |
给主人留下些什么吧!~~