camera拍摄视频耗电过快的问题分析

问题:【相机】33%电量开启闪光灯录制视频,大约6分钟左右,手机自动关机,再开机,电量为4%

分析过程:

开闪光灯录制视频的情况下导致掉电,手机关机。经过跟测试沟通之后,发现正常模式下录制视频的话,没有这个问题,那么我们就把问题点定位到闪光灯上了,由于闪光灯有Flash模式和Torch模式,在拍照时,我们用的是Flash模式,该模式瞬间曝光,一般电压在300mV ~ 75mV 之间,这个是跟连接的RSET有关,我们电路接的是139kΩ,那么根据公式VFB = (1.26V/ RSET) ×10.2kΩ (Flash Mode),算出VFB=92.5mV。而Torch模式的话就只有VFB = 47mV (Torch Mode)。然后看了一下拍视频时闪光灯的亮度,跟拍照时的亮度是一样的,那么就肯定是我们拍视频的时候闪光灯的模式错误的设置为Flash模式了;

问题定位后就是代码分析了。首先分析的是驱动leds_strobe.c文件

[cpp] view plain copy print ?
  1. 129 ssize_t gpio_FL_Enable(void)  
  2. 130 {  
  3. 131     /*Enable*/  
  4. 132     printk("FlashLight: %s:%d: called g_torch_mode:%d\n",__func__,__LINE__,g_torch_mode);  
  5. 133     if(0 == g_torch_mode){  
  6. 134         if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENM_PIN,GPIO_OUT_ONE)){PK_DBG("[constant_flashlight] enable flashlight failed!!     \n");}  
  7. 135     if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENF_PIN,GPIO_OUT_ONE)){PK_DBG("[constant_flashlight] open flashlight failed!    ! \n");}  
  8. 136     }else{  
  9. 137         if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENM_PIN,GPIO_OUT_ONE)){PK_DBG("[constant_flashlight] set gpio failed!! \n");    }  
  10. 138     }  
  11. 139     return 0;  
  12. 140 }    
  13. 141      
  14. 142 ssize_t gpio_FL_Disable(void)  
  15. 143 {    
  16. 144     /*Disable*/  
  17. 145     printk("FlashLight: %s:%d: called g_torch_mode:%d\n",__func__,__LINE__,g_torch_mode);  
  18. 146     if(0 == g_torch_mode){  
  19. 147     if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENF_PIN,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] close flashlight failed!!     \n");}  
  20. 148         if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENM_PIN,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] enable flashlight fail    ed!! \n");}  
  21. 149     }else{                  
  22. 150         if(mt_set_gpio_out(GPIO_CAMERA_FLASH_ENM_PIN,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] set gpio failed!! \n")    ;}  
  23. 151     }  
  24. 152     return 0;  
  25. 153 }  

然后我们再查看torch模式和flash模式是什么情况下设置的:

[cpp] view plain copy print ?
  1. 155 ssize_t gpio_FL_dim_duty(kal_uint8 duty)  
  2. 156 {  
  3. 157     if (duty == 0)  
  4. 158         g_torch_mode = 1;  
  5. 159     else  
  6. 160         g_torch_mode = 0;  
  7. 161     printk("FlashLight: %s:%d: called duty:%d\n",__func__,__LINE__,duty);  
  8. 162     return 0;  
  9. 163 }  

170 #define FL_dim_duty gpio_FL_dim_duty

继续看看调用FL_dim_duty的地方:

[cpp] view plain copy print ?
  1. 201 static int constant_flashlight_ioctl(MUINT32 cmd, MUINT32 arg)  
  2. 202 {  
  3. 203     int i4RetValue = 0;  
  4. 204     int ior_shift;  
  5. 205     int iow_shift;  
  6. 206     int iowr_shift;  
  7. 207     ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));  
  8. 208     iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));  
  9. 209     iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));  
  10. 210     PK_DBG("constant_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, i  
  11.     ow_shift, iowr_shift, arg);  
  12. 211     switch(cmd)  
  13. 212     {  
  14. 213         case FLASH_IOC_SET_TIME_OUT_TIME_MS:  
  15. 214             PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",arg);  
  16. 215             g_timeOutTimeMs=arg;  
  17. 216         break;  
  18. 217   
  19. 218         case FLASH_IOC_SET_DUTY :  
  20. 219             PK_DBG("FLASHLIGHT_DUTY: %d\n",arg);  
  21. 220             FL_dim_duty(arg);  
  22. 221             break;  

好吧,那么就是跟到Ioctl,我们继续查看哪里有调用FLASH_IOC_SET_DUTY,搜索了一下,发现在

mediatek/platform/mt6592/hardware/mtkcam/core/featureio/drv/strobe/flashlight_drv.cpp中

[cpp] view plain copy print ?
  1. 284 int FlashlightDrv::setDuty(int duty)  
  2. 285 {  
  3. 286     DRV_DBG("setDuty() duty = %d\n",duty);  
  4. 287     int err = 0;  
  5. 288     if (m_fdSTROBE < 0)  
  6. 289     {  
  7. 290         DRV_DBG("setDuty() m_fdSTROBE < 0\n");  
  8. 291         return StrobeDrv::STROBE_UNKNOWN_ERROR;  
  9. 292     }  
  10. 293     err = ioctl(m_fdSTROBE,FLASH_IOC_SET_DUTY,duty);  
  11. 294     if (err < 0)  
  12. 295     {  
  13. 296         DRV_ERR("setDuty() err=%d\n", err);  
  14. 297         return err;  
  15. 298     }  
  16. 299     m_duty = duty;  
  17. 300     return err;  
  18. 301 }  

m_duty的值初始化时为0,SetDuty对duty 进行设置,讲duty的值传给m_duty,而getDuty则进行获取直接获取m_duty的值
[cpp] view plain copy print ?
  1. 1021 int FlashlightDrv::getDuty(int* duty)  
  2. 1022 {  
  3. 1023     DRV_DBG("getDuty()\n");  
  4. 1024     int err = 0;  
  5. 1025     if (m_fdSTROBE < 0)  
  6. 1026     {  
  7. 1027         DRV_DBG("getDuty() m_fdSTROBE < 0\n");  
  8. 1028         return StrobeDrv::STROBE_UNKNOWN_ERROR;  
  9. 1029     }  
  10. 1030     *duty = m_duty;  
  11. 1031     return err;  
  12. 1032   
  13. 1033 }  

最后setDuty被文件mediatek /hardware/mtkcam/core/featureio/pipe/aaa/flash_mgr/flash_mgr.cpp调用:

[cpp] view plain copy print ?
  1. 210 void turnOnTorch()  
  2. 211 {  
  3. 212     int bOn;  
  4. 213     int step;  
  5. 214     int duty;  
  6. 215     g_pStrobe->isOn(&bOn);  
  7. 216     g_pStrobe->getDuty(&duty);  
  8. 217     g_pStrobe->getStep(&step);  
  9. 218   
  10. 219     FLASH_PROJECT_PARA prjPara;  
  11. 220     int aeMode;  
  12. 221     aeMode = AeMgr::getInstance().getAEMode();  
  13. 222     prjPara = FlashMgr::getInstance()->getFlashProjectPara(aeMode);  
  14. 223     LogInfo("turnOnTorch line=%d isOn=%d",__LINE__,bOn);  
  15. 224     if(bOn==0 || prjPara.engLevel.torchDuty!=duty || prjPara.engLevel.torchStep!=step)  
  16. 225     {  
  17. 226         LogInfo("turnOnTorch duty,step=%d %d",prjPara.engLevel.torchDuty, prjPara.engLevel.torchStep);  
  18. 227         g_pStrobe->setDuty(prjPara.engLevel.torchDuty);  
  19. 228         g_pStrobe->setStep(prjPara.engLevel.torchStep);  
  20. 229         g_pStrobe->setTimeOutTime(0);  
  21. 230         hwSetFlashOn();  
  22. 231     }  
  23. 232 }  

其中:prjPara= FlashMgr::getInstance()->getFlashProjectPara(aeMode);调用:

[cpp] view plain copy print ?
  1. 297 FLASH_PROJECT_PARA&FlashMgr::getFlashProjectPara(int aeMode)  
  2.  298{  
  3.  299    NVRAM_CAMERA_STROBE_STRUCT* pNv;  
  4.  300    int err;  
  5.  301    err = nvGetBuf(pNv);  
  6.  302    if(err!=0)  
  7.  303        LogError("nvGetBuf err");  
  8.  304    //loadNvram();  
  9.  305    FLASH_PROJECT_PARA para;  
  10.  306if(m_sensorType==DUAL_CAMERA_MAIN_SENSOR)  
  11.  307     return cust_getFlashProjectPara(aeMode, pNv);  
  12.  308else  
  13.  309    return cust_getFlashProjectPara_sub(aeMode, pNv);  
  14.  310}  

接着是cust_getFlashProjectPara(aeMode,pNv);代用下面文件,

mediatek/custom/out/huaqin92_wet_b2a_tdd/hal/camera/flash_tuning_custom.cpp中的
[cpp] view plain copy print ?
  1. 118 FLASH_PROJECT_PARA& cust_getFlashProjectPara(int aeMode, NVRAM_CAMERA_STROBE_STRUCT* nvrame)  
  2. 119 {  
  3. 120     static FLASH_PROJECT_PARA para;  
  4. 121   
  5. 122     para.dutyNum = 10;  
  6. 123     para.stepNum = 1;  
  7. 124       
  8. 125     if(nvrame!=0)  
  9. 126     {  
  10. 127         XLOGD("cust_getFlashProjectPara nvrame->tuningPara[0].yTar=%d", nvrame->tuningPara[0].yTar);  
  11. 128         switch(aeMode)  
  12. 129         {  
  13. 130             case LIB3A_AE_MODE_OFF:  
  14. 131             case LIB3A_AE_MODE_AUTO:  
  15. 132                 copyTuningPara(¶.tuningPara, &nvrame->tuningPara[0]);  
  16. 133             break;  
  17. 134             case LIB3A_AE_MODE_NIGHT:  
  18. 135             case LIB3A_AE_MODE_CANDLELIGHT:  
  19. 136             case LIB3A_AE_MODE_FIREWORKS:  
  20. 137             case LIB3A_AE_MODE_NIGHT_PORTRAIT:  
  21. 138                 copyTuningPara(¶.tuningPara, &nvrame->tuningPara[1]);  
  22. 139             break;  
  23. 140             case LIB3A_AE_MODE_ACTION:  
  24. 141             case LIB3A_AE_MODE_SPORTS:  
  25. 142             case LIB3A_AE_MODE_ISO_ANTI_SHAKE:  
  26. 143                 copyTuningPara(¶.tuningPara, &nvrame->tuningPara[2]);  
  27. 144             break;  
  28. 145             case LIB3A_AE_MODE_PORTRAIT:  
  29. 146                 copyTuningPara(¶.tuningPara, &nvrame->tuningPara[3]);  
  30. 147             break;  
  31. 148             default:  
  32. 149                 copyTuningPara(¶.tuningPara, &nvrame->tuningPara[0]);  
  33. 150             break;  
  34. 151         }  
  35. 152     }  
  36. 153     //--------------------  
  37. 154     //eng level  
  38. 155     //index mode  
  39. 156     //torch  
  40. 157     para.engLevel.torchEngMode = ENUM_FLASH_ENG_INDEX_MODE;  
  41. 158     para.engLevel.torchDuty = 0;  
  42. 159     para.engLevel.torchStep = 0;  

这个函数的160-162行可以看到:

160    para.engLevel.torchEngMode = ENUM_FLASH_ENG_INDEX_MODE;

161    para.engLevel.torchDuty= 1;

162    para.engLevel.torchStep = 0;

好了,所以我们的duty就被设置为1了,导致走的驱动层的Flash模式。

修改完成编译后,将libcameracustom.so 文件push到/system/lib/

reboot后就搞定了!

你可能感兴趣的:(camera拍摄视频耗电过快的问题分析)