问题现象
camera录像中拍照,录出来的视频帧率为29.3fps,未达到30fps。
问题分析
这个场景相当于跑了previe+vedio+capture,极其损耗性能。
当前场景CPU频率已处于最高。
抓取systrace分析。
1,分析掉帧直接原因
SinkNode存在大量一帧耗时超过33.3ms,造成帧率无法达到30fps。
2,对比查看线程优先级
SinkNode大部分处于Runnable状态,async_FaceDetec处于Running状态,很明显两者优先级不一样,从systrace上看确实如此。
3,提升SinkNode线程优先级
#include <sys/resource.h>
void set_current_max_priority()
{auto current_tid = gettid();auto origin_priority = getpriority(PRIO_PROCESS, current_tid);if (-1 == origin_priority) {LOGE("licq getpriority error");return;}auto set_perf_ret = setpriority(PRIO_PROCESS, current_tid, -20);
}void set_current_max_rt()
{struct sched_param param;int policy;int ret;ret = pthread_getschedparam(pthread_self(), &policy, ¶m);if (ret != 0) {LOGE("licq Error: pthread_getschedparam failed");return;}param.sched_priority = 99;pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
}
两种方式提升线程优先级,选用set_current_max_rt,将SinkNode设置为RT线程并达到最高级别。
systrace确定改动是否生效:
帧率达标,抓取systrace查看SinkNode耗时,已在33.3ms之内完成。同时发现一段很长sleep时间,是processCaptureResult,systrace如下:
根据binder通信原理,很快找到了最终元凶,是com.android.camera 处理慢了。
解决方案
提升SinkNode线程优先级为RT且为最高。