首先找到android拍照的时候所执行的函数代码在:

packages/apps/Camera/src/com/android/camera/Camera.java

[java] view plain copy
  1. mCameraDevice.setParameters(mParameters);
  2. mCameraDevice.takePicture(mShutterCallback,mRawPictureCallback,
  3. mPostViewPictureCallback,newJpegPictureCallback(loc));
  4. mPreviewing=false;


据我理解,这里就是拍照的时候所执行的,而这里应该是调用的camera库里的takepicture下面我们找到库文件:

device/samsung/proprietary/libcamera

库文件就在这里,下面我们进入SeccameraHWInterface.cpp文件查找takepicture如下:

[cpp] view plain copy
  1. status_tCameraHardwareSec::takePicture()
  2. {
  3. LOGV("%s:",__func__);
  4. stopPreview();
  5. Mutex::Autolocklock(mStateLock);
  6. if(mCaptureInProgress){
  7. LOGE("%s:capturealreadyinprogress",__func__);
  8. returnINVALID_OPERATION;
  9. }
  10. if(mPictureThread->run("CameraPictureThread",PRIORITY_DEFAULT)!=NO_ERROR){
  11. LOGE("%s:couldn'trunpicturethread",__func__);
  12. returnINVALID_OPERATION;
  13. }
  14. mCaptureInProgress=true;
  15. returnNO_ERROR;
  16. }


里面的mPictureThread->run就是拍照的东西了,具体我就不分析了。接下来我们找下闪光灯的接口

在SecCamera.h里你会发现下面三个函数接口:

[cpp] view plain copy
  1. boolgetFlashSupport(void);
  2. intsetFlashMode(intflash_mode);
  3. intgetFlashMode(void);

其中setFlashMode即为设置闪光灯的接口,找到这个函数

在SecCamera.cpp里如下:

[cpp] view plain copy
  1. intSecCamera::setFlashMode(intflash_mode)
  2. {
  3. LOGV("%s(flash_mode(%d))",__func__,flash_mode);
  4. if(flash_mode<=FLASH_MODE_BASE||FLASH_MODE_MAX<=flash_mode){
  5. LOGE("ERR(%s):Invalidflash_mode(%d)",__func__,flash_mode);
  6. return-1;
  7. }
  8. if(m_params->flash_mode!=flash_mode){
  9. m_params->flash_mode=flash_mode;
  10. if(m_flag_camera_start){
  11. if(fimc_v4l2_s_ctrl(m_cam_fd,V4L2_CID_CAMERA_FLASH_MODE,flash_mode)<0){
  12. LOGE("ERR(%s):FailonV4L2_CID_CAMERA_FLASH_MODE",__func__);
  13. return-1;
  14. }
  15. }
  16. }
  17. return0;
  18. }

这里又会调用fimc_v4l2_s_ctrl函数代码如下:

[cpp] view plain copy
  1. staticintfimc_v4l2_s_ctrl(intfp,unsignedintid,unsignedintvalue)
  2. {
  3. structv4l2_controlctrl;
  4. intret;
  5. ctrl.id=id;
  6. ctrl.value=value;
  7. //LOGD("%s:--------------------------valueis%d",__func__,value);//adddao
  8. ret=ioctl(fp,VIDIOC_S_CTRL,&ctrl);
  9. if(ret<0){
  10. LOGE("ERR(%s):VIDIOC_S_CTRL(id=%#x(%d),value=%d)failedret=%d\n",
  11. __func__,id,id-V4L2_CID_PRIVATE_BASE,value,ret);
  12. returnret;
  13. }
  14. returnctrl.value;
  15. }


在这里进行了ioctl下面我们到内核里面去看看。
在内核下面的drivers/media/video/v4l2-ioctl.c有如下代码:

[cpp] view plain copy
  1. caseVIDIOC_S_CTRL:
  2. {
  3. structv4l2_control*p=arg;
  4. structv4l2_ext_controlsctrls;
  5. structv4l2_ext_controlctrl;
  6. if(!ops->vidioc_s_ctrl&&!ops->vidioc_s_ext_ctrls)
  7. break;
  8. dbgarg(cmd,"id=0x%x,value=%d\n",p->id,p->value);
  9. if(ops->vidioc_s_ctrl){
  10. ret=ops->vidioc_s_ctrl(file,fh,p);
  11. break;
  12. }
  13. if(!ops->vidioc_s_ext_ctrls)
  14. break;
  15. ctrls.ctrl_class=V4L2_CTRL_ID2CLASS(p->id);
  16. ctrls.count=1;
  17. ctrls.controls=&ctrl;
  18. ctrl.id=p->id;
  19. ctrl.value=p->value;
  20. if(check_ext_ctrls(&ctrls,1))
  21. ret=ops->vidioc_s_ext_ctrls(file,fh,&ctrls);
  22. break;
  23. }


很快我就想到了摄像头驱动里有这样的设置:

代码在drivers/media/video/samsung/ficm/ov2640.c

[cpp] view plain copy
  1. staticconststructv4l2_subdev_core_opsov2640_core_ops={
  2. .init=ov2640_init,/*initializingAPI*/
  3. .s_config=ov2640_s_config,/*Fetchplatformdata*/
  4. .queryctrl=ov2640_queryctrl,
  5. .querymenu=ov2640_querymenu,
  6. .g_ctrl=ov2640_g_ctrl,
  7. .s_ctrl=ov2640_s_ctrl,
  8. };


这里有一个s_ctrl,事实证明确实是执行了ov2640_s_ctrl至于怎么调用过来的没有深入研究。

下面我们看到这个函数开始的部分

[cpp] view plain copy
  1. staticintov2640_s_ctrl(structv4l2_subdev*sd,structv4l2_control*ctrl)
  2. {
  3. structi2c_client*client=v4l2_get_subdevdata(sd);
  4. structov2640_state*state=to_state(sd);
  5. interr=0;
  6. intvalue=ctrl->value;
  7. switch(ctrl->id){
  8. caseV4L2_CID_CAMERA_FLASH_MODE:
  9. caseV4L2_CID_CAMERA_BRIGHTNESS:
  10. break;


第一个就是闪光灯的选项,文件系统里面设置闪光灯的就是传入的这个,可没作任何处理就直接跳出了。下面我在增加闪光灯驱动:

[cpp] view plain copy
  1. staticintflash_ctrl(intmode)
  2. {
  3. interr;
  4. err=gpio_request(S5PV210_GPD0(2),"GPD0");//power
  5. if(err){
  6. printk(KERN_ERR"failedtorequestGPD0for"
  7. "flashlightpowercontrol\n");
  8. returnerr;
  9. }
  10. gpio_direction_output(S5PV210_GPD0(2),1);
  11. err=gpio_request(S5PV210_GPD0(3),"GPD0");//mode
  12. if(err){
  13. printk(KERN_ERR"failedtorequestGPD0for"
  14. "flashlightmodecontrol\n");
  15. returnerr;
  16. }
  17. /*
  18. highisflashmode,lowistorchmode
  19. */
  20. switch(mode){
  21. caseFLASH_MODE_ON:
  22. gpio_direction_output(S5PV210_GPD0(3),1);
  23. break;
  24. caseFLASH_MODE_TORCH:
  25. gpio_direction_output(S5PV210_GPD0(3),0);
  26. break;
  27. default:
  28. break;
  29. }
  30. mdelay(100);
  31. gpio_direction_output(S5PV210_GPD0(2),0);
  32. gpio_free(S5PV210_GPD0(2));
  33. gpio_free(S5PV210_GPD0(3));
  34. returnerr;
  35. }


电路我就不发出来了,流程搞清楚了,大家就好弄了。

修改ov2640_s_ctrl为:

[cpp] view plain copy
  1. caseV4L2_CID_CAMERA_FLASH_MODE:
  2. err=flash_ctrl(value);
  3. break;


只修改相关设置,其它的不变。现在接口已经全部写好,在回到文件系统里。
在拍照之前加上闪光灯设置,这个可以在库里设置也可以在app里设置,我直接在库里设置的,路径我就不在打了,前面的相关函数已经全部给出了,如下:

[cpp] view plain copy
  1. status_tCameraHardwareSec::takePicture()
  2. {
  3. LOGV("%s:",__func__);
  4. stopPreview();
  5. Mutex::Autolocklock(mStateLock);
  6. if(mCaptureInProgress){
  7. LOGE("%s:capturealreadyinprogress",__func__);
  8. returnINVALID_OPERATION;
  9. }
  10. mSecCamera->setFlashMode(FLASH_MODE_ON);//addbydao
  11. if(mPictureThread->run("CameraPictureThread",PRIORITY_DEFAULT)!=NO_ERROR){
  12. LOGE("%s:couldn'trunpicturethread",__func__);
  13. returnINVALID_OPERATION;
  14. }
  15. mCaptureInProgress=true;
  16. returnNO_ERROR;
  17. }


在拍照之前设置FlashMode为FLASH_MODE_ON模式,结果发现这样不行,搞了半天终于发现问题所在,直接把setFlashMode改为如下:

[cpp] view plain copy
  1. intSecCamera::setFlashMode(intflash_mode)
  2. {
  3. LOGV("%s(flash_mode(%d))",__func__,flash_mode);
  4. fimc_v4l2_s_ctrl(m_cam_fd,V4L2_CID_CAMERA_FLASH_MODE,flash_mode);
  5. /*
  6. if(flash_mode<=FLASH_MODE_BASE||FLASH_MODE_MAX<=flash_mode){
  7. LOGE("ERR(%s):Invalidflash_mode(%d)",__func__,flash_mode);
  8. return-1;
  9. }
  10. if(m_params->flash_mode!=flash_mode){
  11. m_params->flash_mode=flash_mode;
  12. if(m_flag_camera_start){
  13. if(fimc_v4l2_s_ctrl(m_cam_fd,V4L2_CID_CAMERA_FLASH_MODE,flash_mode)<0){
  14. LOGE("ERR(%s):FailonV4L2_CID_CAMERA_FLASH_MODE",__func__);
  15. return-1;
  16. }
  17. }
  18. }
  19. */
  20. return0;
  21. }


重新编译库和内核,下载,结果测试成功。

更多相关文章

  1. android上传图片至服务器
  2. Android(安卓)ProgressDialog的使用
  3. android 回调机制
  4. android 页面容器 下一页很上一页view
  5. Android(安卓)uses-permission大全
  6. AndroidManifest.xml - activity 详细说明
  7. LinearLayout布局中layout_weight的用法
  8. Android(安卓)WebRTC
  9. android给listview设置分割线Divider样式

随机推荐

  1. Android 手机端与服务端POST数据交互类
  2. 构建更好的应用--Xamarin平台
  3. Android SQLite 抽象出CRUD操作工具类
  4. Android RectF类的构造函数参数说明
  5. Android5.0以太网流程源码情景分析
  6. Android(安卓)USB\HDMI等事件监听
  7. androidQ 访问SD卡权限问题
  8. Android Stagefright 技术相关网址
  9. Android屏幕点亮(常亮)及屏幕解锁和锁定
  10. Android Studio 日期选择器和时间选择器