Camera功耗偏高 :
一般优化为:
1. 降低CPUloading
2. 在不造成卡顿的情况下降低CPU的频率
另外,请确认测试使用的是user版本,userdebug版本的camera默认全程高频
下面分别介绍
> 1.降低CPU Loading
先抓到 Camera 进程的各线程占用,找出消耗最大的几个线程,看能否优化。
一般来说会看到几个算法的线程,此时可以内部确认是否可以关闭一些不需要的算法node,比如如果不需要人脸识别就可以关闭FD。
如果项目上要求算法不能关闭,那就看能否进行隔帧处理。
top查看各进程、各线程cpu占用
查看进程:top
查看线程:top -H -p
top输出某个特定进程
> 2.在不造成卡顿的情况下降低CPU的频率
平台camera预览的 power 逻辑是 :
刚进入camera,使用high_perf高频, 出约35帧后,进入lowpower低频 , 关相机时进入high_perf高频
平台Camera Capture 的power逻辑是:
拍照时进入high_perf提频 , 在拍照完成,大图返回后,进入perview的频点(lowpower)
camera的power策略总体逻辑为:
在相机对性能要求高的场景(如打开、关闭相机,拍照等)进行提频,以减少卡顿情况的发生;
在预览等对性能要求没那么高的场景使用低频,以控制整体功耗。
一般录像时4k60fps时才就会进入高频策略,详情可查阅基线 adjustprviewperformance() 函数(A11~A14不同安卓版本的位置可能不同,但都查这个函数即可)。
即一般预览、录像使用的是camera_lowpower策略,修改camera_lowpower 的各核频率范围即可
power_scene_config.xml小核最小频率 小核最大频率 大核最小频率(9863等平台为policy4) 大核最大频率 大核提频幅度 小核提频幅度
freq_margin 指提频,例如调频时,计算目标频率的方式是max_freq * cpu使用率,引入freq_margin 后,假设freq_margin是30,计算方式变成了max_freq * ( 1 + 30% ) * cpu使用率, freq_margin 的取值范围是[-100, 100]。
> 3.针对某个三方应用设置cpu策略 :
A14示例:
① vendor/sprd/modules/libcamera/idispatch/android/Camera3Adapter.cpp
48 static TopAppS topAppList[] = {
49 { TOP_APP_NONE, "com.android.camera2" },
50 { TOP_APP_WECHAT, "com.tencent.mm" },
51 // { TOP_APP_WTFACTORY, ""},
52 { TOP_APP_QQ, "com.tencent.mobileqq"},
53 { TOP_APP_FACEBOOK, "com.facebook.katana"},
54 { TOP_APP_INSTAGRAM, "com.instagram.android"},
55 { TOP_APP_MESSENGER, "com.facebook.orca"},
56 { TOP_APP_SNAPCHAT, "com.snapchat.android"},
57 { TOP_APP_WHATSAPP, "com.whatsapp"},
> ++++++ { TOP_APP_GPULUMERA, "com.joeware.android.gpulumera"},
② vendor/sprd/modules/libcamera/common/inc/cmr_common.h
2233 //for some thirdparty camera apps
2234 TOP_APP_MTXX = 30,
2235 TOP_APP_MEIYAN,
2236 TOP_APP_FACEU,
2237 TOP_APP_LITE,
2238 TOP_APP_WUTA,
2239 TOP_APP_DOUBTNUT,
2240 TOP_APP_CALI,
2241 TOP_APP_TWITTER,
>++++++ TOP_APP_GPULUMERA
③ vendor/sprd/modules/libcamera/hal3_2v7/SprdCamera3Setting.cpp
9916 int SprdCamera3Setting::get3rdAppSceneLevel(SessionParam mSessionParam) {
9917 int level = 0;
9918 char macro_3rd[16] = "false";
9919 char macro_9863t_3rd[16] = "false";
9920 lwp::ConfigurationManager::getTarget("CONFIG_CAMERA_3RDAPP_SATISFYPERF", macro_3rd);
9921 lwp::ConfigurationManager::getTarget("CONFIG_CAMERA_9863T_POWERHINT", macro_9863t_3rd);
9922 if (mSessionParam.mTopAppId == TOP_APP_WECHAT) {
9923 level = CAM_PERFORMANCE_LEVEL_7;
9924 } else if (mSessionParam.mTopAppId != 0 || mSessionParam.sceneMode == CAM_SCENE_MODE_THIRDPARTY) {
9925 if (!(strcmp("true", macro_3rd))) {
9926 level = CAM_PERFORMANCE_LEVEL_4;
9927 } else {
9928 if (!(strcmp("true", macro_9863t_3rd)) && mSessionParam.mTopAppId > 0) {
9929 level = CAM_PERFORMANCE_LEVEL_14;
9930 } else if (!(strcmp("true", macro_9863t_3rd)) && mSessionParam.mTopAppId < 0) {
9931 level = CAM_PERFORMANCE_LEVEL_4;
9932 } else {
9933 level = CAM_PERFORMANCE_LEVEL_6;
9934 }
9935 }
9936 }
//++++++++++++++++参考添加以下code
if(mSessionParam.mTopAppId ==TOP_APP_GPULUMERA){
level = CAM_PERFORMANCE_LEVEL_3;
HAL_LOGD("3RD_APP CAM_PERFORMANCE_LEVEL_3");
}
//++++++++++++++++
9937 return level;
9938 }
A13示例:
① vendor/sprd/modules/libcamera/hal3_2v6/SprdCamera3Setting.cpp
162 static TopAppS topAppList[] = {
163 { TOP_APP_NONE, "com.android.camera2" },
164 { TOP_APP_WECHAT, "com.tencent.mm" },
165 // { TOP_APP_WTFACTORY, ""},
166 { TOP_APP_QQ, "com.tencent.mobileqq"},
167 { TOP_APP_FACEBOOK, "com.facebook.katana"},
168 { TOP_APP_INSTAGRAM, "com.instagram.android"},
169 { TOP_APP_MESSENGER, "com.facebook.orca"},
170 { TOP_APP_SNAPCHAT, "com.snapchat.android"},
171 { TOP_APP_WHATSAPP, "com.whatsapp"},
172 { TOP_APP_QQINT, "com.tencent.mobileqqi"},
173 { TOP_APP_READYAPP, "com.google.android.apps.tachyon.readyapp"},
174 { TOP_APP_CAMERAGO, "com.google.android.apps.cameralite"},
>+++ { TOP_APP_VOLTE, "xxxxxxx"},
② vendor/sprd/modules/libcamera/common/inc/cmr_common.h
1833 enum top_app_id {
1834 //set other thirdparty apps besides the list to -1
1835 TOP_APP_NONE = 0,
1836 TOP_APP_WECHAT = (1 << 0),
1837 TOP_APP_WTFACTORY = (1 << 1),
1838 TOP_APP_QQ = (1 << 2),
1839 TOP_APP_FACEBOOK = (1 << 3),
1840 TOP_APP_INSTAGRAM = (1 << 4),
1841 TOP_APP_MESSENGER = (1 << 5),
1842 TOP_APP_SNAPCHAT = (1 << 6),
1843 TOP_APP_WHATSAPP = (1 << 7),
1844 TOP_APP_QQINT = (1 << 8),
1845 TOP_APP_READYAPP = (1 << 9),
1846 TOP_APP_CAMERAGO = (1 << 10),
>+++ TOP_APP_VOLTE = (1 << 11),
③ vendor/sprd/modules/libcamera / hal3_2v6/SprdCamera3OEMIf.cpp
void SprdCamera3OEMIf::adjustPreviewPerformance(uint32_t frame_num,
const SPRD_DEF_Tag *sprddefInfo) {
if (!isCapturing() && mIsPowerhintWait && !mIsAutoFocus) {
if ((int)(frame_num - mStartFrameNum) > CAM_POWERHINT_WAIT_COUNT) {
if (sprddefInfo->top_app_id == -2)
goto exit;
if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_4 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_4) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_4);
} else if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_5 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_5) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_5);
} else if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_6 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_6) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_6);
} else if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_7 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_7) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_7);
} else if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_3 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_3) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_3);
} else if (getAppSceneLevel(mSprdAppmodeId) == CAM_PERFORMANCE_LEVEL_1 ||
getScenePerfLevel() == CAM_PERFORMANCE_LEVEL_1) {
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_1);
}
mIsPowerhintWait = 0;
}
}
>+++ if(mTopAppId == TOP_APP_VOLTE) {
>+++ setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_1);
>+++ HAL_LOGD("TOP_APP_VOLTE,SET CAM_PERFORMANCE_LEVEL_1");
>+++ }
return;
exit:
setCamPreformaceScene(CAM_PERFORMANCE_LEVEL_6);
mIsPowerhintWait = 0;
return;
}
> 4.常用功耗优化方案:
① FD隔帧(Face Detect)
② PD隔帧(PDAF)
③ AWB隔帧
④ LSC隔帧
①FD隔帧(Face Detect)
A13\A14:
--- a/ips/swpool/facedetection/facedetection2.0/FaceDetectSDKNode.cpp +++ b/ips/swpool/facedetection/facedetection2.0/FaceDetectSDKNode.cpp
@@ -418,11 +418,13 @@ void FaceDetectSDKNode::process(const std::string &port, data_type job) {
}
/* scaler end */
ratio = (float)src.size.width / (float)dst.size.width;
-
- if (fd_process(param, request, dst, ratio)) {
- LOGE("fd_process fail");
+ if (mFDhandle.frame_id % 2 == 0)
+ {
+ if (fd_process(param, request, dst, ratio))
+ {
+ LOGE("fd_process fail");
+ }
}
②PD隔帧(PDAF)
分为V3和V4两个算法版本,可通过log确认算法版本,例如:
PDAF_Algo_new_version: CAM_ALGO_3A_PD_4.0.0.202211280940
V14 版本修改:
vendor/sprd/modules/libcamera/ispalg/pdaf/sprd/pd4.x/pdaf_sprd_adpt_v2.c
static cmr_s32 sprd_pd_adpt_v2_process(cmr_handle adpt_handle, void *in, void *out)
{
.......
void *pInPhaseBuf_left = NULL;
void *pInPhaseBuf_right = NULL;
cmr_u16 *pInPhaseBuf_Type2 = NULL;
cmr_u8 *pInPhaseBuf_Dual_PD = NULL;
struct af_pd2hybrid_info2 pd_result2;
+++ cxt->frame_id = proc_in->frame_id;
+++ //for pd type2 skip
+++ if ((0 == cxt->frame_id % 2)
+++ && (cxt->pd_type == PDAF_SENSOR_TYPE2))
+++ {
+++ return ISP_SUCCESS;
+++ }
memset(&callback_in, 0, sizeof(callback_in));
memset(&calc_out, 0, sizeof(struct pd_calc_out));
cxt->is_busy = 1;
---- cxt->frame_id = proc_in->frame_id;
pd_sprd_adpt_get_af_info(cxt);
V3版本修改:
diff --git a/camdrv/isp2.6/middleware/isp_alg_fw.c b/camdrv/isp2.6/middleware/isp_alg_fw.c index 61f1834..f7f85cd 100755 --- a/camdrv/isp2.6/middleware/isp_alg_fw.c +++ b/camdrv/isp2.6/middleware/isp_alg_fw.c
@@ -5920,6 +5920,7 @@
u_addr = statis_info->uaddr;
pdaf_param_in.u_addr = statis_info->uaddr;
pdaf_param_in.u_addr_right = statis_info->uaddr + offset;
+ pdaf_param_in.frame_id = statis_info->frame_id;
ISP_LOGV("addr 0x%lx, addr1 0x%lx, offset %x\n", statis_info->uaddr, pdaf_param_in.u_addr_right, offset);
switch (cxt->pdaf_cxt.pdaf_support) {
diff --git a/ispalg/pdaf/inc/pdaf_ctrl.h b/ispalg/pdaf/inc/pdaf_ctrl.h
index 869c61c..eb50390 100755
--- a/ispalg/pdaf/inc/pdaf_ctrl.h
+++ b/ispalg/pdaf/inc/pdaf_ctrl.h
@@ -117,6 +117,7 @@
cmr_uint u_addr;
cmr_uint u_addr_right;
cmr_uint datasize;
+ cmr_uint frame_id;
};
struct pdaf_ctrl_process_out {
diff --git a/ispalg/pdaf/sprd/pdaf_sprd_adpt.c b/ispalg/pdaf/sprd/pdaf_sprd_adpt.c
index 122b1b9..d89d38a 100755
--- a/ispalg/pdaf/sprd/pdaf_sprd_adpt.c
+++ b/ispalg/pdaf/sprd/pdaf_sprd_adpt.c
@@ -585,6 +585,13 @@
ret = ISP_PARAM_NULL;
return ret;
}
+ cxt->frame_id = proc_in->frame_id;
+ //for pd type2 skip
+ if ((0 == cxt->frame_id % 2)
+ && (cxt->pdaf_type == PDAF_SENSOR_TYPE2))
+ {
+ return ISP_SUCCESS;
+ }
ISP_CHECK_HANDLE_VALID(adpt_handle);
memset(&callback_in, 0, sizeof(callback_in));
③ AWB隔帧
Awb隔帧:将tunning参数中awb项的calculation interval改为2,即每两帧计算一次。
将tunning参数中awb项的calculation interval改为2,即每两帧计算一次
④ LSC隔帧
lsc隔帧:需要修改tuning参数alsc模块的calc_freq 为3。