之前在手机系统开发的工作中,碰到一个问题,用系统camera进行录像,在录制界面,切换预览场景,预览画面不会进行自动对焦(也就是连续对焦),而只能手动点击对焦,导致移动手机,可能出现因为没有对焦导致的预览模糊。
通过摸索代码发现,原来mtk code中camera2里边,在录像对焦逻辑这一块有一点特殊,video preview和video recording是做了不同的Restriction的,而他们设置的对焦方式也不一致。
出现这种现象的原因就是,video preview时对焦方式为continuous-video(即连续对焦),video recording时对焦方式为auto。
解决此问题的方案,就是将video recording时的对焦方式改为continuous-video(即连续对焦)。
代码如下,在Camera2的VideoRestriction.java中:
1.先看video preview的对焦设定,key_focus是"continuous-video"。
static {
sPreviewRelationGroup.setHeaderKey(VIDEO_MODE_KEY);
if (SystemProperties.getInt("mtk.camera.app.fd.video", 0) == 0) {
sPreviewRelationGroup.setBodyKeys("key_focus,key_scene_mode,key_face_detection");
sPreviewRelationGroup.addRelation(
new Relation.Builder(VIDEO_MODE_KEY, "preview")
.addBody("key_focus", "continuous-video", "continuous-video,auto")
.addBody("key_scene_mode", "off", getVideoSceneRestriction())
.addBody("key_face_detection", "off", "off")
.build());
} else {
sPreviewRelationGroup.setBodyKeys("key_focus,key_scene_mode");
sPreviewRelationGroup.addRelation(
new Relation.Builder(VIDEO_MODE_KEY, "preview")
.addBody("key_focus", "continuous-video", "continuous-video,auto")
.addBody("key_scene_mode", "off", getVideoSceneRestriction())
.build());
}
}
2.再看video recording的对焦设定,key_focus是"auto"。
static {
sRecordingRelationGroupForMode.setHeaderKey(VIDEO_MODE_KEY);
sRecordingRelationGroupForMode.setBodyKeys("key_focus");
if (SystemProperties.getInt("mtk.camera.app.fd.video", 0) == 0) {
sRecordingRelationGroupForMode.addRelation(
new Relation.Builder(VIDEO_MODE_KEY, "recording")
/*ljr modify for PRODUCTION-10648*/
//.addBody("key_focus", "auto", "auto")
.addBody("key_focus", "continuous-video", "continuous-video,auto")
.build());
}
sRecordingRelationGroupForMode.addRelation(
new Relation.Builder(VIDEO_MODE_KEY, "stop-recording")
.addBody("key_focus", "continuous-video", "continuous-video,auto")
.build());
}
修改之处:
//.addBody("key_focus", "auto", "auto")
.addBody("key_focus", "continuous-video", "continuous-video,auto")
3.看他们的逻辑调用。
protected List<Relation> getRecordedRestriction(boolean isRecording) {
List<Relation> relationList = new ArrayList<>();
if (isRecording) {
if (!mVideoHelper.isPDAFSupported(mCameraApi)) {
relationList.add(VideoRestriction.getRecordingRelationForMode()
.getRelation(KEY_RECORDING, true));
}
} else {
relationList.add(VideoRestriction.getRecordingRelationForMode()
.getRelation(KEY_STOP_RECORDING, true));
}
return relationList;
}
通过boolean isRecording来标识是否在录像,而正常调用之处是再startRecording和stopRecording函数中。KEY_RECORDING表示的"recording",KEY_STOP_RECORDING表示的"stop-recording",通过put也就对应到了VideoRestriction中sRecordingRelationGroupForMode的设置,也就是第二点。
4.带来的问题
这样修改是会起作用的,也能解决bug了。但是测试小姐姐们又用敏锐的眼光发现了另一个问题,即在使用手机相机进行录像拍摄时,手机保持不动(但其实可能手出现轻微抖动),然后拍摄的场景是动态的,比如电影打斗片段,架子鼓片段,预览界面也会出现对焦,而且次数比较多,所拍摄的视频也会有镜头对焦拉近的现象。所以测试小姐姐们就提bug啦,经过自己的复现,才发现,这不就是录像改为continue-video之后才出现的问题吗,预览场景切换或拍摄动态的画面,都被识别成了需要进行连续对焦的情况。
这个就是一个疑问了,难道mtk code将进入video recording之后focus设置为auto,理由之一是为了避免此类现象?还是说底层在recording时对识别需要连续对焦的场景判断条件有问题?我理解的,设置为continue对焦方式后,预览场景改变进行自动对焦就是正常的。
最后当然是找对比机对比,发现也有类型现象,再找产品经理说明,问题才算沟通解决掉了。呼。。。