mx53 camera s5k5bbgx驱动分析

一: linux驱动层

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

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

/*

声明s5k5bbgx的IIC 资源

*/

  1. <spanstyle="font-size:16px;">staticintmxc_camera2_pwdn(intpwdn)
  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. return0;
  8. }
  9. staticstructmxc_camera_platform_datacamera2_data={
  10. .mclk=24000000,
  11. .csi=0,
  12. .pwdn=mxc_camera2_pwdn,
  13. };
  14. staticstructi2c_board_infomxc_i2c0_board_info[]__initdata={
  15. {
  16. .type="s5k5bbgx",
  17. .addr=0x2d,
  18. //IIC地址为7位,最后一位是读写位,mx53的驱动内部会把地址左移一位,所以这里要右移一位
  19. .platform_data=(void*)&camera2_data,
  20. },
  21. }
  22. </span>
  1. <spanstyle="font-size:16px;">/*!
  2. *Boardspecificinitialization.
  3. */
  4. staticvoid__initmxc_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驱动

*/

  1. <spanstyle="font-size:16px;">staticstructi2c_client*s5k5bbgx_i2c_client=NULL;
  2. staticconststructi2c_device_ids5k5bbgx_id[]={
  3. {"s5k5bbgx",0},
  4. {},
  5. };
  6. MODULE_DEVICE_TABLE(i2c,s5k5bbgx_id);
  7. staticstruct2055_i2c_drvier{
  8. .driver={
  9. .owner=THIS_MODULE,
  10. .name="s5k5bbgx",
  11. },
  12. .probe=s5k5bbgx_probe,
  13. .remove=s5k5bbgx_remove,
  14. .id_table=s5k5bbgx_id,
  15. };
  16. /*!
  17. *s5k5bbgxinitfunction
  18. *Calledbyinsmods5k5bbgx_camera.ko.
  19. *
  20. *@returnErrorcodeindicatingsuccessorfailure
  21. */
  22. static__initints5k5bbgx_init(void)
  23. {
  24. U8err;
  25. err=i2c_add_driver(s5k5bbgx_i2c_driver);
  26. returnerr;
  27. }
  28. staticints5k5bbgx_probe(structi2c_client*client,
  29. conststructi2c_device_id*id)
  30. {
  31. s5k5bbgx_i2c_client=client;
  32. return0;
  33. }
  34. /*
  35. IIC读写
  36. */
  37. statics32s5k5bbgx_read_reg(u16reg,u16*val)
  38. {
  39. u8au8RegBuf[2]={0};
  40. u8data[2]={0};
  41. au8RegBuf[0]=reg>>8;
  42. au8RegBuf[1]=reg&0xff;
  43. if(2!=i2c_master_send(s5k5bbgx_i2c_client,au8RegBuf,2)){
  44. pr_err("%s:writeregerror:reg=%x\n",
  45. __func__,reg);
  46. return-1;
  47. }
  48. if(2!=i2c_master_recv(s5k5bbgx_i2c_client,data,2)){
  49. pr_err("%s:readregerror:reg=0x%04x\n",
  50. __func__,reg);
  51. return-2;
  52. }
  53. *val=(data[0]<<8)|data[1];
  54. return0;
  55. }
  56. statics32s5k5bbgx_write_reg(u16cammand,u16val)
  57. {
  58. u8au8Buf[4]={0};
  59. au8Buf[0]=cammand>>8;
  60. au8Buf[1]=cammand&0xff;
  61. au8Buf[2]=val>>8;
  62. au8Buf[3]=val&0xff;
  63. if(4!=i2c_master_send(s5k5bbgx_i2c_client,au8Buf,4)){
  64. pr_err("%s:writecammanderror:cammand=0x%04x,val=0x%04x\n",
  65. __func__,cammand,val);
  66. return-1;
  67. }
  68. return0;
  69. }
  70. <strong>
  71. </strong></span>
至此IIC注册完毕

b: 注册 v4l2 slave device:

  1. <spanstyle="font-size:16px;">/*!
  2. *Maintainstheinformationonthecurrentstateofthesesor.
  3. */
  4. structsensor{
  5. conststructmxc_camera_platform_data*platform_data;
  6. structv4l2_int_device*v4l2_int_device;
  7. structi2c_client*i2c_client;
  8. structv4l2_pix_formatpix;
  9. structv4l2_captureparmstreamcap;
  10. boolon;
  11. /*controlsettings*/
  12. intbrightness;
  13. inthue;
  14. intcontrast;
  15. intsaturation;
  16. intred;
  17. intgreen;
  18. intblue;
  19. intae_mode;
  20. u32mclk;
  21. intcsi;
  22. }s5k5bbgx_data;
  23. /*!
  24. *Thisstructuredefinesalltheioctlsforthismoduleandlinksthemtothe
  25. *enumeration.
  26. */
  27. staticstructv4l2_int_ioctl_descs5k5bbgx_ioctl_desc[]={
  28. {vidioc_int_s_parm_num,(v4l2_int_ioctl_func*)ioctl_s_parm},
  29. {vidioc_int_s_ctrl_num,(v4l2_int_ioctl_func*)ioctl_s_ctrl},
  30. };
  31. staticstructv4l2_int_slaves5k5bbgx_slave={
  32. .ioctls=s5k5bbgx_ioctl_desc,
  33. .num_ioctls=ARRAY_SIZE(s5k5bbgx_ioctl_desc),
  34. };
  35. staticstructv4l2_int_devices5k5bbgx_int_device={
  36. .module=THIS_MODULE,
  37. .name="s5k5bbgx",
  38. .type=v4l2_int_type_slave,
  39. .u={
  40. .slave=&s5k5bbgx_slave,
  41. },
  42. };
  43. /*!
  44. *ioctl_s_parm-V4L2sensorinterfacehandlerforVIDIOC_S_PARMioctl
  45. *@s:pointertostandardV4L2devicestructure
  46. *@a:pointertostandardV4L2VIDIOC_S_PARMioctlstructure
  47. *
  48. *Configuresthesensortousetheinputparameters,ifpossible.If
  49. *notpossible,revertstotheoldparametersandreturnsthe
  50. *appropriateerrorcode.
  51. */
  52. staticintioctl_s_parm(structv4l2_int_device*s,structv4l2_streamparm*a)
  53. {
  54. structsensor*sensor=s->priv;
  55. structv4l2_fract*timeperframe=&a->parm.capture.timeperframe;
  56. u32tgt_fps;/*targetframespersecound*/
  57. enums5k5bbgx_frame_rateframe_rate;
  58. intret=0;
  59. /*Makesurepoweron*/
  60. if(camera_plat->pwdn)
  61. camera_plat->pwdn(0);
  62. switch(a->type){
  63. /*Thisistheonlycasecurrentlyhandled.*/
  64. caseV4L2_BUF_TYPE_VIDEO_CAPTURE:
  65. /*Theseareallthepossiblecases.*/
  66. caseV4L2_BUF_TYPE_VIDEO_OUTPUT:
  67. caseV4L2_BUF_TYPE_VIDEO_OVERLAY:
  68. caseV4L2_BUF_TYPE_VBI_CAPTURE:
  69. caseV4L2_BUF_TYPE_VBI_OUTPUT:
  70. caseV4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  71. caseV4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  72. pr_debug("typeisnot"\
  73. "V4L2_BUF_TYPE_VIDEO_CAPTUREbut%d\n",
  74. a->type);
  75. ret=-EINVAL;
  76. break;
  77. default:
  78. pr_debug("typeisunknown-%d\n",a->type);
  79. ret=-EINVAL;
  80. break;
  81. }
  82. returnret;
  83. }
  84. /*!
  85. *ioctl_s_ctrl-V4L2sensorinterfacehandlerforVIDIOC_S_CTRLioctl
  86. *@s:pointertostandardV4L2devicestructure
  87. *@vc:standardV4L2VIDIOC_S_CTRLioctlstructure
  88. *
  89. *Iftherequestedcontrolissupported,setsthecontrol'scurrent
  90. *valueinHW(andupdatesthevideo_control[]array).Otherwise,
  91. *returns-EINVALifthecontrolisnotsupported.
  92. */
  93. staticintioctl_s_ctrl(structv4l2_int_device*s,structv4l2_control*vc)
  94. {
  95. intretval=0;
  96. pr_debug("Ins5k5bbgx:ioctl_s_ctrl%d\n",
  97. vc->id);
  98. switch(vc->id){
  99. caseV4L2_CID_BRIGHTNESS:
  100. break;
  101. caseV4L2_CID_CONTRAST:
  102. break;
  103. caseV4L2_CID_SATURATION:
  104. break;
  105. caseV4L2_CID_HUE:
  106. break;
  107. caseV4L2_CID_AUTO_WHITE_BALANCE:
  108. break;
  109. caseV4L2_CID_DO_WHITE_BALANCE:
  110. break;
  111. default:
  112. retval=-EPERM;
  113. break;
  114. }
  115. returnretval;
  116. }
  117. staticints5k5bbgx_probe(strcti2c_client*client,conststructi2c_device_id*id)
  118. {
  119. s5k5bbgx_int_device.priv=&s5k5bbgx_data;
  120. retval=v4l2_int_device_register(&s5k5bbgx_int_device);
  121. }
  122. </span>
v4l2 slave device 注册完毕

c: s5k5bbgx 初始化和操作

  1. <spanstyle="font-size:16px;">staticints5k5bbgx_probe(structi2c_client*client,
  2. conststructi2c_device_id*id)
  3. {
  4. /*
  5. *默认的参数:yuv模式,像素,帧速等。这些参数会在s_paramioctl中重新设置
  6. */
  7. s5k5bbgx_data.pix.pixelformat=V4L2_PIX_FMT_YUYV;
  8. s5k5bbgx_data.pix.width=800;
  9. s5k5bbgx_data.pix.height=600;
  10. s5k5bbgx_data.streamcap.capability=V4L2_MODE_HIGHQUALITY|
  11. V4L2_CAP_TIMEPERFRAME;
  12. s5k5bbgx.streamcap.capturemode=0;
  13. s5k5bbgx_data.streamcap.timeperframe.denominator=DEFAULT_FPS;
  14. s5k5bbgx_data.streamcap.timeperframe.numerator=1;
  15. }
  16. staticints5k5bbgx_init_mode(enums5k5bbgx_frame_rateframe_rate,
  17. enums5k5bbgx_modemode)
  18. {
  19. structreg_value*pModeSetting=NULL;
  20. s32i=0;
  21. s32iModeSettingArySize=0;
  22. registeru32Delay_ms=0;
  23. registeru16RegAddr=0;
  24. registeru8Mask=0;
  25. registeru16Val=0;
  26. registeru8u8Val=0;
  27. u8RegVal=0;
  28. intretval=0;
  29. pModeSetting=s5k5bbgx_mode_info_data[frame_rate][mode].init_data_ptr;
  30. iModeSettingArySize=s5k5bbgx_mode_info_data[frame_rate][mode].init_data_size;
  31. s5k5bbgx_data.pix.width=s5k5bbgx_mode_info_data[frame_rate][mode].width;
  32. s5k5bbgx_data.pix.height=s5k5bbgx_mode_info_data[frame_rate][mode].height;
  33. /*
  34. *设置camera的参数,如fps,像素等
  35. */
  36. for(i=0;i<iModeSettingArySize;++i,++pModeSetting){
  37. Delay_ms=pModeSetting->u32Delay_ms;
  38. RegAddr=pModeSetting->u16RegAddr;
  39. Val=pModeSetting->u16Val;
  40. Mask=pModeSetting->u8Mask;
  41. if(Mask){
  42. RegVal&=~(u8)Mask;
  43. Val&=Mask;
  44. Val|=RegVal;
  45. }
  46. retval=s5k5bbgx_write_reg(RegAddr,Val);
  47. if(retval<0)
  48. gotoerr;
  49. if(Delay_ms)
  50. msleep(Delay_ms);
  51. }
  52. }
  53. structs5k5ggbx_sets5k5ggbx_set_data[12]={
  54. {preview,ARRAY_SIZE(preview)},//screenmode:auto
  55. {record,ARRAY_SIZE(record)},
  56. {night,ARRAY_SIZE(night)},
  57. {capture,ARRAY_SIZE(capture)},//capture
  58. {normal,ARRAY_SIZE(normal)},//coloreffect
  59. {mono,ARRAY_SIZE(mono)},
  60. {negative,ARRAY_SIZE(negative)},
  61. {sepia,ARRAY_SIZE(sepia)},
  62. {Auto,ARRAY_SIZE(Auto)},//whitebalance
  63. {incandescent,ARRAY_SIZE(incandescent)},
  64. {daylight,ARRAY_SIZE(daylight)},
  65. {flourescent,ARRAY_SIZE(flourescent)}
  66. };
  67. /*
  68. 设置白平衡等参数
  69. */
  70. staticints5k5ggbx_set_code(intindex)
  71. {
  72. structreg_value*p=NULL;
  73. s32i=0;
  74. s32size=0;
  75. intretval;
  76. registeru32Delay_ms=0;
  77. registeru16RegAddr=0;
  78. registeru16Val=0;
  79. p=s5k5ggbx_set_data[index].init_data_ptr;
  80. size=s5k5ggbx_set_data[index].init_data_size;
  81. for(i=0;i<size;++i,++p){
  82. Delay_ms=p->u32Delay_ms;
  83. RegAddr=p->u16RegAddr;
  84. Val=p->u16Val;
  85. retval=s5k5bbgx_write_reg(RegAddr,Val);
  86. if(retval<0)
  87. returnretval;
  88. if(Delay_ms)
  89. msleep(Delay_ms);
  90. }
  91. return0;
  92. }
  93. staticintioctl_s_parm(structv4l2_int_device*s,structv4l2_streamparm*a)
  94. {
  95. switch(a->type){
  96. /*Thisistheonlycasecurrentlyhandled.*/
  97. caseV4L2_BUF_TYPE_VIDEO_CAPTURE:
  98. /*Checkthatthenewframerateisallowed.*/
  99. if((timeperframe->numerator==0)||
  100. (timeperframe->denominator==0)){
  101. timeperframe->denominator=DEFAULT_FPS;
  102. timeperframe->numerator=1;
  103. }
  104. tgt_fps=timeperframe->denominator/
  105. timeperframe->numerator;
  106. if(tgt_fps>MAX_FPS){
  107. timeperframe->denominator=MAX_FPS;
  108. timeperframe->numerator=1;
  109. }elseif(tgt_fps<MIN_FPS){
  110. timeperframe->denominator=MIN_FPS;
  111. timeperframe->numerator=1;
  112. }
  113. /*Actualframerateweuse*/
  114. tgt_fps=timeperframe->denominator/
  115. timeperframe->numerator;
  116. /*Actualframerateweuse*/
  117. tgt_fps=timeperframe->denominator/
  118. timeperframe->numerator;
  119. if(tgt_fps==15)
  120. frame_rate=ov2655_15_fps;
  121. elseif(tgt_fps==30)
  122. frame_rate=ov2655_30_fps;
  123. elseif(tgt_fps==7)
  124. frame_rate=ov2655_7p5_fps;
  125. else{
  126. pr_err("Thecameraframerateisnotsupported!\n");
  127. return-EINVAL;
  128. }
  129. sensor->streamcap.timeperframe=*timeperframe;
  130. sensor->streamcap.capturemode=(u32)a->parm.capture.capturemode;
  131. printk("\n%s,frame_rate=%d,sensor->streamcap.capturemode=%d\n",__func__,frame_rate,sensor->streamcap.capturemode);
  132. if(sensor->streamcap.capturemode==2)//preview:normal
  133. {
  134. s5k5ggbx_init_mode(frame_rate,sensor->streamcap.capturemode);
  135. s5k5ggbx_set_code(0);
  136. }
  137. elseif(sensor->streamcap.capturemode==4)//capture
  138. {
  139. s5k5ggbx_init_mode(frame_rate,sensor->streamcap.capturemode);
  140. s5k5ggbx_set_code(3);
  141. }
  142. elseif(sensor->streamcap.capturemode==1)//preview:recording
  143. {
  144. s5k5ggbx_init_mode(frame_rate,sensor->streamcap.capturemode);
  145. s5k5ggbx_set_code(1);
  146. }
  147. break;
  148. }
  149. }
  150. </span>

二,V4L2 capture应用

1.接口

  1. <spanstyle="font-size:16px;">namespaceandroid{
  2. classV4l2CapDeviceBase:publicCaptureDeviceInterface{
  3. public:
  4. virtualCAPTURE_DEVICE_ERR_RETSetDevName(char*deviceName);
  5. virtualCAPTURE_DEVICE_ERR_RETGetDevName(char*deviceName);
  6. virtualCAPTURE_DEVICE_ERR_RETDevOpen();
  7. virtualCAPTURE_DEVICE_ERR_RETEnumDevParam(DevParamTypedevParamType,void*retParam);
  8. virtualCAPTURE_DEVICE_ERR_RETDevSetCtrl(intid,intvalue);
  9. virtualCAPTURE_DEVICE_ERR_RETDevSetConfig(structcapture_config_t*pCapcfg);
  10. virtualCAPTURE_DEVICE_ERR_RETDevAllocateBuf(DMA_BUFFER*DevBufQue,unsignedint*pBufQueNum);
  11. virtualCAPTURE_DEVICE_ERR_RETDevPrepare();
  12. virtualCAPTURE_DEVICE_ERR_RETDevStart();
  13. virtualCAPTURE_DEVICE_ERR_RETDevDequeue(unsignedint*pBufQueIdx);
  14. virtualCAPTURE_DEVICE_ERR_RETDevStop();
  15. virtualCAPTURE_DEVICE_ERR_RETDevDeAllocate();
  16. virtualCAPTURE_DEVICE_ERR_RETDevClose();
  17. protected:
  18. V4l2CapDeviceBase();
  19. virtual~V4l2CapDeviceBase();
  20. virtualCAPTURE_DEVICE_ERR_RETV4l2Open();
  21. virtualCAPTURE_DEVICE_ERR_RETV4l2EnumParam(DevParamTypedevParamType,void*retParam);
  22. virtualCAPTURE_DEVICE_ERR_RETV4l2EnumFmt(void*retParam);
  23. virtualCAPTURE_DEVICE_ERR_RETV4l2EnumSizeFps(void*retParam);
  24. virtualCAPTURE_DEVICE_ERR_RETV4l2SetConfig(structcapture_config_t*pCapcfg);
  25. virtualCAPTURE_DEVICE_ERR_RETV4l2AllocateBuf(DMA_BUFFER*DevBufQue,unsignedint*pBufQueNum);
  26. virtualCAPTURE_DEVICE_ERR_RETV4l2Prepare();
  27. virtualCAPTURE_DEVICE_ERR_RETV4l2Start();
  28. virtualCAPTURE_DEVICE_ERR_RETV4l2Dequeue(unsignedint*pBufQueIdx);
  29. virtualCAPTURE_DEVICE_ERR_RETV4l2Queue(unsignedintBufQueIdx);
  30. virtualCAPTURE_DEVICE_ERR_RETV4l2Stop();
  31. virtualCAPTURE_DEVICE_ERR_RETV4l2DeAlloc();
  32. virtualCAPTURE_DEVICE_ERR_RETV4l2Close();
  33. virtualCAPTURE_DEVICE_ERR_RETV4l2ConfigInput(structcapture_config_t*pCapcfg);
  34. virtualCAPTURE_DEVICE_ERR_RETV4l2GetCaptureMode(structcapture_config_t*pCapcfg,unsignedint*pMode);
  35. virtualCAPTURE_DEVICE_ERR_RETV4l2SetRot(structcapture_config_t*pCapcfg);
  36. charmCaptureDeviceName[CAMAERA_FILENAME_LENGTH];
  37. charmInitalDeviceName[CAMAERA_SENSOR_LENGTH];
  38. intmCameraDevice;
  39. unsignedintmFmtParamIdx;
  40. unsignedintmSizeFPSParamIdx;
  41. unsignedintmRequiredFmt;
  42. unsignedintmBufQueNum;
  43. intmQueuedBufNum;
  44. DMA_BUFFERmCaptureBuffers[MAX_CAPTURE_BUF_QUE_NUM];
  45. structcapture_config_tmCapCfg;
  46. };
  47. };
  48. </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 上的实际实现:

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

  1. CAPTURE_DEVICE_ERR_RETV4l2CapDeviceBase::V4l2Open(){
  2. CAMERA_HAL_LOG_FUNC;
  3. intfd=0,i,j,is_found=0;
  4. constchar*flags[]={"uncompressed","compressed"};
  5. chardev_node[CAMAERA_FILENAME_LENGTH];
  6. DIR*v4l_dir=NULL;
  7. structdirent*dir_entry;
  8. structv4l2_capabilityv4l2_cap;
  9. structv4l2_fmtdescvid_fmtdesc;
  10. structv4l2_frmsizeenumvid_frmsize;
  11. CAPTURE_DEVICE_ERR_RETret=CAPTURE_DEVICE_ERR_NONE;
  12. if(mCameraDevice>0)
  13. returnCAPTURE_DEVICE_ERR_ALRADY_OPENED;
  14. elseif(mCaptureDeviceName[0]!='#'){
  15. CAMERA_HAL_LOG_RUNTIME("alreadygetthedevicename%s",mCaptureDeviceName);
  16. mCameraDevice=open(mCaptureDeviceName,O_RDWR,O_NONBLOCK);
  17. if(mCameraDevice<0)
  18. returnCAPTURE_DEVICE_ERR_OPEN;
  19. }
  20. else{
  21. CAMERA_HAL_LOG_RUNTIME("deviceNameis%s",mInitalDeviceName);
  22. v4l_dir=opendir("/sys/class/video4linux");
  23. if(v4l_dir){
  24. while((dir_entry=readdir(v4l_dir))){
  25. memset((void*)dev_node,0,CAMAERA_FILENAME_LENGTH);
  26. if(strncmp(dir_entry->d_name,"video",5))
  27. continue;
  28. sprintf(dev_node,"/dev/%s",dir_entry->d_name);
  29. if((fd=open(dev_node,O_RDWR,O_NONBLOCK))<0)
  30. continue;
  31. CAMERA_HAL_LOG_RUNTIME("dev_nodeis%s",dev_node);
  32. if(ioctl(fd,VIDIOC_QUERYCAP,&v4l2_cap)<0){
  33. close(fd);
  34. continue;
  35. }elseif((strstr((char*)v4l2_cap.driver,mInitalDeviceName)!=0)&&
  36. (v4l2_cap.capabilities&V4L2_CAP_VIDEO_CAPTURE)){
  37. is_found=1;
  38. strcpy(mCaptureDeviceName,dev_node);
  39. CAMERA_HAL_LOG_RUNTIME("devicenameis%s",mCaptureDeviceName);
  40. break;
  41. }else
  42. close(fd);
  43. }
  44. }
  45. if(fd>0)
  46. mCameraDevice=fd;
  47. else{
  48. CAMERA_HAL_ERR("Thedevicenameisnotcorrectorthedeviceiserror");
  49. returnCAPTURE_DEVICE_ERR_OPEN;
  50. }
  51. }
  52. returnret;
  53. }
  1. CAPTURE_DEVICE_ERR_RETV4l2CapDeviceBase::V4l2AllocateBuf(DMA_BUFFER*DevBufQue,unsignedint*pBufQueNum){
  2. unsignedinti;
  3. structv4l2_bufferbuf;
  4. enumv4l2_buf_typetype;
  5. structv4l2_requestbuffersreq;
  6. intBufQueNum;
  7. CAMERA_HAL_LOG_FUNC;
  8. if(mCameraDevice<=0||DevBufQue==NULL||pBufQueNum==NULL||*pBufQueNum==0){
  9. returnCAPTURE_DEVICE_ERR_BAD_PARAM;
  10. }
  11. mBufQueNum=*pBufQueNum;
  12. memset(&req,0,sizeof(req));
  13. req.count=mBufQueNum;
  14. req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  15. req.memory=V4L2_MEMORY_MMAP;
  16. if(ioctl(mCameraDevice,VIDIOC_REQBUFS,&req)<0){
  17. CAMERA_HAL_ERR("v4l_capture_setup:VIDIOC_REQBUFSfailed\n");
  18. returnCAPTURE_DEVICE_ERR_SYS_CALL;
  19. }
  20. /*thedrivermaycan'tmeettherequest,andreturnthebufnumitcanhandle*/
  21. *pBufQueNum=mBufQueNum=req.count;
  22. for(i=0;i<mBufQueNum;i++){
  23. memset(&buf,0,sizeof(buf));
  24. buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  25. buf.index=i;
  26. if(ioctl(mCameraDevice,VIDIOC_QUERYBUF,&buf)<0){
  27. CAMERA_HAL_ERR("VIDIOC_QUERYBUFerror\n");
  28. returnCAPTURE_DEVICE_ERR_SYS_CALL;
  29. }else{
  30. CAMERA_HAL_LOG_RUNTIME("VIDIOC_QUERYBUFok\n");
  31. }
  32. mCaptureBuffers[i].length=DevBufQue[i].length=buf.length;
  33. mCaptureBuffers[i].phy_offset=DevBufQue[i].phy_offset=(size_t)buf.m.offset;
  34. mCaptureBuffers[i].virt_start=DevBufQue[i].virt_start=(unsignedchar*)mmap(NULL,mCaptureBuffers[i].length,
  35. PROT_READ|PROT_WRITE,MAP_SHARED,mCameraDevice,mCaptureBuffers[i].phy_offset);
  36. memset(mCaptureBuffers[i].virt_start,0xFF,mCaptureBuffers[i].length);
  37. CAMERA_HAL_LOG_RUNTIME("capturebuffers[%d].length=%d\n",i,mCaptureBuffers[i].length);
  38. CAMERA_HAL_LOG_RUNTIME("capturebuffers[%d].phy_offset=0x%x\n",i,mCaptureBuffers[i].phy_offset);
  39. CAMERA_HAL_LOG_RUNTIME("capturebuffers[%d].virt_start=0x%x\n",i,(unsignedint)(mCaptureBuffers[i].virt_start));
  40. }
  41. returnCAPTURE_DEVICE_ERR_NONE;
  42. }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值