mx53 camera s5k5bbgx驱动分析

mx53 camera s5k5bbgx驱动分析

一: linux驱动层

1.  通讯方式I2C驱动注册:

a: arch/arm/mach-mx5/mx53_xx.c

/*

声明s5k5bbgx的IIC 资源

*/

[cpp]  view plain copy
  1. <span style="font-size:16px;">static int mxc_camera2_pwdn(int pwdn)  
  2. {  
  3.     if (pwdn)  
  4.         gpio_direction_output(MX53_HMS_CAMERA2_PWN, 1);  
  5.     else  
  6.         gpio_direction_output(MX53_HMS_CAMERA2_PWN, 0);  
  7.     return 0;  
  8. }      
  9.    
  10. static struct mxc_camera_platform_data camera2_data = {  
  11.     .mclk = 24000000,  
  12.     .csi = 0,  
  13.     .pwdn = mxc_camera2_pwdn,  
  14. };   
  15.   
  16. static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {  
  17.   
  18.    {  
  19.     .type = "s5k5bbgx",  
  20.     .addr = 0x2d,   
  21.       // IIC 地址为7位,最后一位是读写位,mx53的驱动内部会把地址左移一位,所以这里要右移一位  
  22.       .platform_data = (void *)&camera2_data,  
  23.      },  
  24.   
  25. }  
  26.   
  27. </span>  
[cpp]  view plain copy
  1. <span style="font-size:16px;">/*! 
  2.  * Board specific initialization. 
  3.  */  
  4. static void __init mxc_board_init(void)  
  5. {  
  6. i2c_register_board_info(0, mxc_i2c0_board_info,  
  7.                 ARRAY_SIZE(mxc_i2c0_board_info));  
  8. }</span>  

b: driver/media/video/capture/xx_cam_2M.c

/*

*  注册IIC驱动

*/

[cpp]  view plain copy
  1. <span style="font-size:16px;">static struct i2c_client *s5k5bbgx_i2c_client = NULL;  
  2.   
  3.   
  4. static const struct i2c_device_id s5k5bbgx_id[] = {  
  5.     {"s5k5bbgx", 0},  
  6.     {},  
  7. };  
  8.   
  9. MODULE_DEVICE_TABLE(i2c, s5k5bbgx_id);  
  10.   
  11. static struct 2055_i2c_drvier {  
  12.      .driver = {  
  13.           .owner = THIS_MODULE,  
  14.           .name  = "s5k5bbgx",  
  15.           },  
  16.     .probe  = s5k5bbgx_probe,  
  17.     .remove = s5k5bbgx_remove,  
  18.     .id_table = s5k5bbgx_id,  
  19.   
  20.   
  21. };  
  22. /*! 
  23.  * s5k5bbgx init function 
  24.  * Called by insmod s5k5bbgx_camera.ko. 
  25.  * 
  26.  * @return  Error code indicating success or failure 
  27.  */  
  28. static __init int s5k5bbgx_init(void)  
  29. {  
  30.     U8 err;  
  31.     err = i2c_add_driver(s5k5bbgx_i2c_driver);  
  32.     return err;  
  33. }  
  34. static int s5k5bbgx_probe(struct i2c_client *client,  
  35.             const struct i2c_device_id *id)  
  36. {  
  37.     s5k5bbgx_i2c_client = client;  
  38.   
  39.     return 0;  
  40. }  
  41. /* 
  42.  IIC 读写 
  43. */  
  44. static s32 s5k5bbgx_read_reg(u16 reg, u16 *val)  
  45. {  
  46.         u8 au8RegBuf[2] = {0};  
  47.     u8 data[2] = {0};  
  48.   
  49.         au8RegBuf[0] = reg >> 8;  
  50.         au8RegBuf[1] = reg & 0xff;  
  51.   
  52.     if (2 != i2c_master_send(s5k5bbgx_i2c_client, au8RegBuf, 2)) {  
  53.                 pr_err("%s:write reg error:reg=%x\n",  
  54.                                 __func__, reg);  
  55.                 return -1;  
  56.         }  
  57.   
  58.     if (2 != i2c_master_recv(s5k5bbgx_i2c_client, data, 2)) {  
  59.                 pr_err("%s:read reg error:reg=0x%04x\n",  
  60.                                 __func__, reg);  
  61.                 return -2;  
  62.         }  
  63.   
  64.         *val = (data[0] << 8) | data[1];  
  65.   
  66.         return 0;  
  67. }  
  68.   
  69.   
  70. static s32 s5k5bbgx_write_reg(u16 cammand, u16 val)  
  71. {  
  72.         u8 au8Buf[4] = {0};  
  73.   
  74.     au8Buf[0] = cammand >> 8;  
  75.         au8Buf[1] = cammand & 0xff;  
  76.         au8Buf[2] = val >> 8;  
  77.         au8Buf[3] = val & 0xff;  
  78.   
  79.     if (4 != i2c_master_send(s5k5bbgx_i2c_client, au8Buf, 4)) {  
  80.         pr_err("%s:write cammand error:cammand=0x%04x,val=0x%04x\n",  
  81.                 __func__, cammand, val);  
  82.         return -1;  
  83.     }  
  84.   
  85.     return 0;  
  86. }  
  87. <strong>  
  88. </strong></span>  
至此IIC注册完毕

b: 注册 v4l2 slave device:

[cpp]  view plain copy
  1. <span style="font-size:16px;">/*! 
  2.  * Maintains the information on the current state of the sesor. 
  3.  */  
  4. struct sensor {  
  5.     const struct mxc_camera_platform_data *platform_data;  
  6.     struct v4l2_int_device *v4l2_int_device;  
  7.     struct i2c_client *i2c_client;  
  8.     struct v4l2_pix_format pix;  
  9.     struct v4l2_captureparm streamcap;  
  10.     bool on;  
  11.   
  12.     /* control settings */  
  13.     int brightness;  
  14.     int hue;  
  15.     int contrast;  
  16.     int saturation;  
  17.     int red;  
  18.     int green;  
  19.     int blue;  
  20.     int ae_mode;  
  21.   
  22.     u32 mclk;  
  23.     int csi;  
  24. }s5k5bbgx_data;  
  25. /*! 
  26.  * This structure defines all the ioctls for this module and links them to the 
  27.  * enumeration. 
  28.  */  
  29. static struct v4l2_int_ioctl_desc s5k5bbgx_ioctl_desc[] = {  
  30.      
  31.     {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},  
  32.     {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},  
  33.      
  34. };  
  35.   
  36.   
  37. static struct v4l2_int_slave s5k5bbgx_slave = {  
  38.     .ioctls = s5k5bbgx_ioctl_desc,  
  39.     .num_ioctls = ARRAY_SIZE(s5k5bbgx_ioctl_desc),  
  40. };  
  41.   
  42.   
  43. static struct v4l2_int_device s5k5bbgx_int_device = {  
  44.     .module = THIS_MODULE,  
  45.     .name = "s5k5bbgx",  
  46.     .type = v4l2_int_type_slave,  
  47.     .u = {  
  48.         .slave = &s5k5bbgx_slave,  
  49.     },  
  50. };  
  51. /*! 
  52.  * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl 
  53.  * @s: pointer to standard V4L2 device structure 
  54.  * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure 
  55.  * 
  56.  * Configures the sensor to use the input parameters, if possible.  If 
  57.  * not possible, reverts to the old parameters and returns the 
  58.  * appropriate error code. 
  59.  */  
  60. static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)  
  61. {  
  62.     struct sensor *sensor = s->priv;  
  63.     struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;  
  64.     u32 tgt_fps;    /* target frames per secound */  
  65.     enum s5k5bbgx_frame_rate frame_rate;  
  66.     int ret = 0;  
  67.   
  68.     /* Make sure power on */  
  69.     if (camera_plat->pwdn)  
  70.         camera_plat->pwdn(0);  
  71.   
  72.     switch (a->type) {  
  73.     /* This is the only case currently handled. */  
  74.     case V4L2_BUF_TYPE_VIDEO_CAPTURE:  
  75.   
  76.   
  77.     /* These are all the possible cases. */  
  78.     case V4L2_BUF_TYPE_VIDEO_OUTPUT:  
  79.     case V4L2_BUF_TYPE_VIDEO_OVERLAY:  
  80.     case V4L2_BUF_TYPE_VBI_CAPTURE:  
  81.     case V4L2_BUF_TYPE_VBI_OUTPUT:  
  82.     case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:  
  83.     case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:  
  84.         pr_debug("   type is not " \  
  85.             "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",  
  86.             a->type);  
  87.         ret = -EINVAL;  
  88.         break;  
  89.   
  90.     default:  
  91.         pr_debug("   type is unknown - %d\n", a->type);  
  92.         ret = -EINVAL;  
  93.         break;  
  94.     }  
  95.   
  96.     return ret;  
  97. }  
  98. /*! 
  99.  * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl 
  100.  * @s: pointer to standard V4L2 device structure 
  101.  * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure 
  102.  * 
  103.  * If the requested control is supported, sets the control's current 
  104.  * value in HW (and updates the video_control[] array).  Otherwise, 
  105.  * returns -EINVAL if the control is not supported. 
  106.  */  
  107. static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)  
  108. {  
  109.     int retval = 0;  
  110.   
  111.     pr_debug("In s5k5bbgx:ioctl_s_ctrl %d\n",  
  112.          vc->id);  
  113.   
  114.     switch (vc->id) {  
  115.     case V4L2_CID_BRIGHTNESS:  
  116.         break;  
  117.     case V4L2_CID_CONTRAST:  
  118.         break;  
  119.     case V4L2_CID_SATURATION:  
  120.         break;  
  121.     case V4L2_CID_HUE:  
  122.         break;  
  123.     case V4L2_CID_AUTO_WHITE_BALANCE:  
  124.         break;  
  125.     case V4L2_CID_DO_WHITE_BALANCE:  
  126.         break;  
  127.   default:  
  128.         retval = -EPERM;  
  129.         break;  
  130.     }  
  131.   
  132.     return retval;  
  133. }  
  134.   
  135.   
  136.   
  137. static int s5k5bbgx_probe(strct i2c_client *client, const struct i2c_device_id *id)  
  138. {  
  139.     s5k5bbgx_int_device.priv = &s5k5bbgx_data;  
  140.     retval = v4l2_int_device_register(&s5k5bbgx_int_device);  
  141. }  
  142. </span>  
v4l2 slave device 注册完毕

c: s5k5bbgx 初始化和操作

[cpp]  view plain copy
  1. <span style="font-size:16px;">static int s5k5bbgx_probe(struct i2c_client *client,  
  2.             const struct i2c_device_id *id)  
  3. {  
  4.   
  5.     /* 
  6.      * 默认的参数: yuv模式,像素,帧速等。这些参数会在s_param ioctl中重新设置 
  7.     */  
  8.     s5k5bbgx_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;  
  9.   
  10.     s5k5bbgx_data.pix.width = 800;  
  11.     s5k5bbgx_data.pix.height = 600;  
  12.     s5k5bbgx_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |  
  13.                        V4L2_CAP_TIMEPERFRAME;  
  14.     s5k5bbgx.streamcap.capturemode = 0;  
  15.     s5k5bbgx_data.streamcap.timeperframe.denominator = DEFAULT_FPS;  
  16.     s5k5bbgx_data.streamcap.timeperframe.numerator = 1;  
  17.   
  18. }  
  19. static int s5k5bbgx_init_mode(enum s5k5bbgx_frame_rate frame_rate,  
  20.                 enum s5k5bbgx_mode mode)  
  21. {  
  22.   struct reg_value *pModeSetting = NULL;  
  23.     s32 i = 0;  
  24.     s32 iModeSettingArySize = 0;  
  25.     register u32 Delay_ms = 0;  
  26.     register u16 RegAddr = 0;  
  27.     register u8 Mask = 0;  
  28.     register u16 Val = 0;  
  29.     register u8 u8Val = 0;  
  30.     u8 RegVal = 0;  
  31.     int retval = 0;  
  32.   
  33.   
  34.      pModeSetting = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_ptr;  
  35.      iModeSettingArySize = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_size;                  
  36.      s5k5bbgx_data.pix.width = s5k5bbgx_mode_info_data[frame_rate][mode].width;  
  37.      s5k5bbgx_data.pix.height = s5k5bbgx_mode_info_data[frame_rate][mode].height;  
  38.      /* 
  39.      *  设置camera的参数,如fps,像素等 
  40.      */  
  41.     for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {  
  42.         Delay_ms = pModeSetting->u32Delay_ms;  
  43.         RegAddr = pModeSetting->u16RegAddr;  
  44.         Val = pModeSetting->u16Val;  
  45.         Mask = pModeSetting->u8Mask;  
  46.         if (Mask) {  
  47.             RegVal &= ~(u8)Mask;  
  48.             Val &= Mask;  
  49.             Val |= RegVal;  
  50.         }  
  51.         retval = s5k5bbgx_write_reg(RegAddr, Val);  
  52.         if (retval < 0)  
  53.             goto err;  
  54.   
  55.         if (Delay_ms)  
  56.             msleep(Delay_ms);  
  57.     }  
  58. }  
  59.   
  60. struct s5k5ggbx_set s5k5ggbx_set_data[12] = {  
  61.     {preview, ARRAY_SIZE(preview)}, //screen mode: auto  
  62.     {record, ARRAY_SIZE(record)},  
  63.     {night, ARRAY_SIZE(night)},  
  64.     {capture, ARRAY_SIZE(capture)}, //capture  
  65.     {normal, ARRAY_SIZE(normal)},   //color effect  
  66.     {mono, ARRAY_SIZE(mono)},  
  67.     {negative, ARRAY_SIZE(negative)},  
  68.     {sepia, ARRAY_SIZE(sepia)},  
  69.     {Auto, ARRAY_SIZE(Auto)},   //white balance  
  70.     {incandescent, ARRAY_SIZE(incandescent)},  
  71.     {daylight, ARRAY_SIZE(daylight)},  
  72.     {flourescent, ARRAY_SIZE(flourescent)}  
  73. };  
  74.   
  75. /* 
  76. 设置白平衡等参数 
  77. */  
  78. static int s5k5ggbx_set_code(int index)  
  79. {  
  80.         struct reg_value *p = NULL;  
  81.         s32 i = 0;  
  82.         s32 size = 0;  
  83.         int retval;  
  84.         register u32 Delay_ms = 0;  
  85.         register u16 RegAddr = 0;  
  86.         register u16 Val = 0;  
  87.   
  88.     p = s5k5ggbx_set_data[index].init_data_ptr;  
  89.     size = s5k5ggbx_set_data[index].init_data_size;  
  90.   
  91.     for (i = 0; i < size; ++i, ++p) {  
  92.                 Delay_ms = p->u32Delay_ms;  
  93.                 RegAddr = p->u16RegAddr;  
  94.                 Val = p->u16Val;  
  95.   
  96.                 retval = s5k5bbgx_write_reg(RegAddr, Val);  
  97.                 if (retval < 0)  
  98.                     return retval;  
  99.   
  100.                 if (Delay_ms)  
  101.                         msleep(Delay_ms);  
  102.   
  103.         }  
  104.   
  105.         return 0;  
  106. }  
  107.   
  108.   
  109. static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)  
  110. {  
  111.  switch (a->type) {  
  112.     /* This is the only case currently handled. */  
  113.     case V4L2_BUF_TYPE_VIDEO_CAPTURE:  
  114.         /* Check that the new frame rate is allowed. */  
  115.         if ((timeperframe->numerator == 0) ||  
  116.             (timeperframe->denominator == 0)) {  
  117.             timeperframe->denominator = DEFAULT_FPS;  
  118.             timeperframe->numerator = 1;  
  119.         }  
  120.   
  121.         tgt_fps = timeperframe->denominator /  
  122.               timeperframe->numerator;  
  123.   
  124.         if (tgt_fps > MAX_FPS) {  
  125.             timeperframe->denominator = MAX_FPS;  
  126.             timeperframe->numerator = 1;  
  127.         } else if (tgt_fps < MIN_FPS) {  
  128.             timeperframe->denominator = MIN_FPS;  
  129.             timeperframe->numerator = 1;  
  130.         }  
  131.   
  132.         /* Actual frame rate we use */  
  133.         tgt_fps = timeperframe->denominator /  
  134.               timeperframe->numerator;  
  135.   
  136.         /* Actual frame rate we use */  
  137.         tgt_fps = timeperframe->denominator /  
  138.               timeperframe->numerator;  
  139.   
  140.         if (tgt_fps == 15)  
  141.             frame_rate = ov2655_15_fps;  
  142.         else if (tgt_fps == 30)  
  143.             frame_rate = ov2655_30_fps;  
  144.         else if (tgt_fps == 7)  
  145.             frame_rate = ov2655_7p5_fps;  
  146.         else {  
  147.             pr_err(" The camera frame rate is not supported!\n");  
  148.             return -EINVAL;  
  149.         }  
  150.   
  151.  sensor->streamcap.timeperframe = *timeperframe;  
  152.         sensor->streamcap.capturemode = (u32)a->parm.capture.capturemode;  
  153. printk("\n%s, frame_rate = %d, sensor->streamcap.capturemode = %d\n", __func__, frame_rate, sensor->streamcap.capturemode);  
  154.         if (sensor->streamcap.capturemode == 2) //preview: normal  
  155.          {  
  156.                s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  157.                s5k5ggbx_set_code(0);  
  158.          }  
  159.          else if (sensor->streamcap.capturemode == 4)    //capture  
  160.          {  
  161.                  s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  162.                 s5k5ggbx_set_code(3);  
  163.          }  
  164.          else if (sensor->streamcap.capturemode == 1)    //preview: recording  
  165.          {  
  166.                 s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  167.                 s5k5ggbx_set_code(1);  
  168.          }  
  169.   
  170.   
  171.         break;  
  172.   
  173.    }  
  174.   
  175. }  
  176.   
  177.   
  178. </span>  

二,V4L2 capture应用

1.接口

[cpp]  view plain copy
  1. <span style="font-size:16px;">namespace android{  
  2.   
  3.     class V4l2CapDeviceBase : public CaptureDeviceInterface{  
  4.     public:  
  5.   
  6.         virtual CAPTURE_DEVICE_ERR_RET SetDevName(char * deviceName);  
  7.         virtual CAPTURE_DEVICE_ERR_RET GetDevName(char * deviceName);  
  8.         virtual CAPTURE_DEVICE_ERR_RET DevOpen();  
  9.         virtual CAPTURE_DEVICE_ERR_RET EnumDevParam(DevParamType devParamType, void *retParam);  
  10.         virtual CAPTURE_DEVICE_ERR_RET DevSetCtrl(int id,int value);  
  11.         virtual CAPTURE_DEVICE_ERR_RET DevSetConfig(struct capture_config_t *pCapcfg);  
  12.         virtual CAPTURE_DEVICE_ERR_RET DevAllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);  
  13.         virtual CAPTURE_DEVICE_ERR_RET DevPrepare();  
  14.         virtual CAPTURE_DEVICE_ERR_RET DevStart();  
  15.         virtual CAPTURE_DEVICE_ERR_RET DevDequeue(unsigned int *pBufQueIdx);  
  16.  virtual CAPTURE_DEVICE_ERR_RET DevStop();  
  17.         virtual CAPTURE_DEVICE_ERR_RET DevDeAllocate();  
  18.         virtual CAPTURE_DEVICE_ERR_RET DevClose();  
  19.   
  20.     protected:  
  21.   
  22.         V4l2CapDeviceBase();  
  23.         virtual ~V4l2CapDeviceBase();  
  24.         virtual CAPTURE_DEVICE_ERR_RET V4l2Open();  
  25.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumParam(DevParamType devParamType, void *retParam);  
  26.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumFmt(void *retParam);  
  27.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumSizeFps(void *retParam);  
  28.         virtual CAPTURE_DEVICE_ERR_RET V4l2SetConfig(struct capture_config_t *pCapcfg);  
  29.         virtual CAPTURE_DEVICE_ERR_RET V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);  
  30. virtual CAPTURE_DEVICE_ERR_RET V4l2Prepare();  
  31.         virtual CAPTURE_DEVICE_ERR_RET V4l2Start();  
  32.         virtual CAPTURE_DEVICE_ERR_RET V4l2Dequeue(unsigned int *pBufQueIdx);  
  33.         virtual CAPTURE_DEVICE_ERR_RET V4l2Queue(unsigned int BufQueIdx);  
  34.         virtual CAPTURE_DEVICE_ERR_RET V4l2Stop();  
  35.         virtual CAPTURE_DEVICE_ERR_RET V4l2DeAlloc();  
  36.         virtual CAPTURE_DEVICE_ERR_RET V4l2Close();  
  37.         virtual CAPTURE_DEVICE_ERR_RET V4l2ConfigInput(struct capture_config_t *pCapcfg);  
  38.         virtual CAPTURE_DEVICE_ERR_RET V4l2GetCaptureMode(struct capture_config_t *pCapcfg, unsigned int *pMode);  
  39.         virtual CAPTURE_DEVICE_ERR_RET V4l2SetRot(struct capture_config_t *pCapcfg);  
  40.   
  41.         char         mCaptureDeviceName[CAMAERA_FILENAME_LENGTH];  
  42.         char         mInitalDeviceName[CAMAERA_SENSOR_LENGTH];  
  43.         int          mCameraDevice;  
  44. unsigned int mFmtParamIdx;  
  45.         unsigned int mSizeFPSParamIdx;  
  46.         unsigned int mRequiredFmt;  
  47.         unsigned int mBufQueNum;  
  48.         int          mQueuedBufNum;  
  49.         DMA_BUFFER mCaptureBuffers[MAX_CAPTURE_BUF_QUE_NUM];  
  50.         struct   capture_config_t mCapCfg;  
  51.   
  52.     };  
  53. };  
  54. </span>  

2.  经典的调用流程。

具体解析可以看 http://www.linuxidc.com/Linux/2011-03/33022.htm

a. open device  /dev/video16

b . VIDIOC_ENUM_FMT : get video capture supported format

struct v4l2_fmtdesc fmt;

ioctl(dev, VIDIOC_ENUM_FMT, &fmt))

c. VIDIOC_QUERYCAP , get the capture ability

struct v4l2_capability cap; 

iret = ioctl(fd_usbcam, VIDIOC_QUERYCAP, &cap);

d. VIDIOC_S_FMT    , set parameter


   struct v4l2_format tv4l2_format; 

   tv4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

   tv4l2_format.fmt.pix.width = img_width; 

   tv4l2_format.fmt.pix.height = img_height; 

   tv4l2_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 

   tv4l2_format.fmt.pix.field = V4L2_FIELD_INTERLACED; 

   iret = ioctl(fd_usbcam, VIDIOC_S_FMT, &tv4l2_format);

e. VIDIOC_REQBUFS  : get buffer

// Request buffers 
struct v4l2_requestbuffers reqbuf; 
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
reqbuf.memory = V4L2_MEMORY_MMAP; 
reqbuf.count = BUFFER_COUNT; 
ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf); 
if(ret < 0) { 
LOG("VIDIOC_REQBUFS failed (%d)\n", ret); 
return ret; 
}

f. VIDIOC_QUERYBUF

struct v4l2_buffer buf; 
for(i=0; i // Query buffer 
buf.index = i; 
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
buf.memory = V4L2_MEMORY_MMAP; 
ret = ioctl(fd , VIDIOC_QUERYBUF, &buf); 
if(ret < 0) { 
LOG("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret); 
return ret; 
}

// mmap buffer 
framebuf[i].length = buf.length; 
framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset); 
if (framebuf[i].start == MAP_FAILED) { 
LOG("mmap (%d) failed: %s\n", i, strerror(errno)); 
return -1; 
}

g. VIDIOC_QBUF

struct v4l2_buffer tV4L2buf; 

memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));

 

tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

tV4L2buf.memory = V4L2_MEMORY_MMAP; 

tV4L2buf.index = i; //(指定)要投放到视频输入队列中的内核空间视频缓冲区的编号;

 

iret = ioctl(fd_usbcam, VIDIOC_QBUF, &tV4L2buf);

H. VIDIOC_STREAMON

enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

fd_set    fds ; 

struct timeval   tv; 

iret = ioctl(fd_usbcam, VIDIOC_STREAMON, &v4l2type);


i. VIDIOC_DQBUF 

struct v4l2_buffer tV4L2buf; 

memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));

 

tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

tV4L2buf.memory = V4L2_MEMORY_MMAP; 

 

iret = ioctl(fd_usbcam, VIDIOC_DQBUF, &tV4L2buf);


j. VIDIOC_QBUF  VIDIOC_DQBUF  VIDIOC_QBUF ...... (read data)
k. VIDIOC_STREAMOFF

enum v4l2_buf_type  v4l2type; 

v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  

iret = ioctl(fd_usbcam, VIDIOC_STREAMOFF, &v4l2type);

3. android 上的实际实现:

与上面的大同小异,贴出两个函数

[cpp]  view plain copy
  1. CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2Open(){  
  2.         CAMERA_HAL_LOG_FUNC;  
  3.         int fd = 0, i, j, is_found = 0;  
  4.         const char *flags[] = {"uncompressed""compressed"};  
  5.   
  6.         char   dev_node[CAMAERA_FILENAME_LENGTH];  
  7.         DIR *v4l_dir = NULL;  
  8.         struct dirent *dir_entry;  
  9.         struct v4l2_capability v4l2_cap;  
  10.         struct v4l2_fmtdesc vid_fmtdesc;  
  11.         struct v4l2_frmsizeenum vid_frmsize;  
  12.         CAPTURE_DEVICE_ERR_RET ret = CAPTURE_DEVICE_ERR_NONE;  
  13.   
  14.         if(mCameraDevice > 0)  
  15.             return CAPTURE_DEVICE_ERR_ALRADY_OPENED;  
  16.         else if (mCaptureDeviceName[0] != '#'){  
  17.             CAMERA_HAL_LOG_RUNTIME("already get the device name %s", mCaptureDeviceName);  
  18.             mCameraDevice = open(mCaptureDeviceName, O_RDWR, O_NONBLOCK);  
  19.             if (mCameraDevice < 0)  
  20.                 return CAPTURE_DEVICE_ERR_OPEN;  
  21.         }  
  22.         else{  
  23.             CAMERA_HAL_LOG_RUNTIME("deviceName is %s", mInitalDeviceName);  
  24.             v4l_dir = opendir("/sys/class/video4linux");  
  25.             if (v4l_dir){  
  26.                 while((dir_entry = readdir(v4l_dir))) {  
  27.                     memset((void *)dev_node, 0, CAMAERA_FILENAME_LENGTH);  
  28.                     if(strncmp(dir_entry->d_name, "video", 5))  
  29.                         continue;  
  30.                     sprintf(dev_node, "/dev/%s", dir_entry->d_name);  
  31.                     if ((fd = open(dev_node, O_RDWR, O_NONBLOCK)) < 0)  
  32. continue;  
  33.                     CAMERA_HAL_LOG_RUNTIME("dev_node is %s", dev_node);  
  34.                     if(ioctl(fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0 ) {  
  35.                         close(fd);  
  36.                         continue;  
  37.                     } else if ((strstr((char *)v4l2_cap.driver, mInitalDeviceName) != 0) &&  
  38.                             (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {  
  39.                         is_found = 1;  
  40.                         strcpy(mCaptureDeviceName, dev_node);  
  41.                         CAMERA_HAL_LOG_RUNTIME("device name is %s", mCaptureDeviceName);  
  42.                         break;  
  43.                     } else  
  44.                         close(fd);  
  45.                 }  
  46.             }  
  47.             if (fd > 0)  
  48.                 mCameraDevice = fd;  
  49.             else{  
  50.                 CAMERA_HAL_ERR("The device name is not correct or the device is error");  
  51.                 return CAPTURE_DEVICE_ERR_OPEN;  
  52.             }  
  53.         }  
  54.         return ret;  
  55.     }  
[cpp]  view plain copy
  1. CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum){  
  2.         unsigned int i;  
  3.         struct v4l2_buffer buf;  
  4.         enum v4l2_buf_type type;  
  5.         struct v4l2_requestbuffers req;  
  6.         int BufQueNum;  
  7.   
  8.         CAMERA_HAL_LOG_FUNC;  
  9.         if (mCameraDevice <= 0 || DevBufQue == NULL || pBufQueNum == NULL || *pBufQueNum == 0){  
  10.             return CAPTURE_DEVICE_ERR_BAD_PARAM;  
  11.         }  
  12.   
  13.         mBufQueNum = *pBufQueNum;  
  14.   
  15.         memset(&req, 0, sizeof (req));  
  16.         req.count = mBufQueNum;  
  17.         req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  18.         req.memory = V4L2_MEMORY_MMAP;  
  19.         if (ioctl(mCameraDevice, VIDIOC_REQBUFS, &req) < 0) {  
  20.             CAMERA_HAL_ERR("v4l_capture_setup: VIDIOC_REQBUFS failed\n");  
  21.             return CAPTURE_DEVICE_ERR_SYS_CALL;  
  22.         }  
  23.  /*the driver may can't meet the request, and return the buf num it can handle*/  
  24.         *pBufQueNum = mBufQueNum = req.count;  
  25.   
  26.         for (i = 0; i < mBufQueNum; i++) {  
  27.             memset(&buf, 0, sizeof (buf));  
  28.             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  29.             buf.index = i;  
  30.             if (ioctl(mCameraDevice, VIDIOC_QUERYBUF, &buf) < 0) {  
  31.                 CAMERA_HAL_ERR("VIDIOC_QUERYBUF error\n");  
  32.                 return CAPTURE_DEVICE_ERR_SYS_CALL;  
  33.             } else {  
  34.                 CAMERA_HAL_LOG_RUNTIME("VIDIOC_QUERYBUF ok\n");  
  35.             }  
  36.   
  37.             mCaptureBuffers[i].length = DevBufQue[i].length= buf.length;  
  38.             mCaptureBuffers[i].phy_offset = DevBufQue[i].phy_offset = (size_t) buf.m.offset;  
  39.             mCaptureBuffers[i].virt_start = DevBufQue[i].virt_start = (unsigned char *)mmap (NULL, mCaptureBuffers[i].length,  
  40.                     PROT_READ | PROT_WRITE, MAP_SHARED, mCameraDevice, mCaptureBuffers[i].phy_offset);  
  41.             memset(mCaptureBuffers[i].virt_start, 0xFF, mCaptureBuffers[i].length);  
  42.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].length = %d\n", i, mCaptureBuffers[i].length);  
  43.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].phy_offset = 0x%x\n", i, mCaptureBuffers[i].phy_offset);  
  44.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].virt_start = 0x%x\n", i, (unsigned int)(mCaptureBuffers[i].virt_start));  
  45.         }  
  46.   
  47.         return CAPTURE_DEVICE_ERR_NONE;  
  48.     }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值