问题现象
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且为最高。