前言
每次对硬件Camera打开后,都需要下发参数。
本文对下发参数全过程及其他设计到参数下发的地方都进行分析。
看这边文章前建议先了解之前的《MTK camera 4.2 app PreferenceGroup生成过程》
SettingChecker
在《MTK camera 4.2 app PreferenceGroup生成过程》中,提到建议使用SettingChecker作为访问preference的接口。
其实SettingChecker的作用不只与此,这一节作深入了解.
SettingChecker设计为表驱动,就让我们先来认识这些表(过程枯燥),再了解围绕这些表设计的方法。
索引与mListPrefs[]
public static final int ROW_SETTING_FLASH = 0;//common public static final int ROW_SETTING_DUAL_CAMERA = 1;//common public static final int ROW_SETTING_EXPOSURE = 2;//common public static final int ROW_SETTING_SCENCE_MODE = 3;//common public static final int ROW_SETTING_WHITE_BALANCE = 4;//common public static final int ROW_SETTING_IMAGE_PROPERTIES = 5;//common public static final int ROW_SETTING_COLOR_EFFECT = 6;//common public static final int ROW_SETTING_SELF_TIMER = 7;//camera …… …… …… //not in preference or not same as preference, but should be set in parameter public static final int ROW_SETTING_CAMERA_MODE = 40;//camera mode public static final int ROW_SETTING_CAPTURE_MODE = 41;//not in preference public static final int ROW_SETTING_CONTINUOUS_NUM = 42;//different from preference public static final int ROW_SETTING_RECORDING_HINT = 43;//not in preference public static final int ROW_SETTING_JPEG_QUALITY = 44;//not in preference //not in preference and not in parameter public static final int ROW_SETTING_STEREO_MODE = 45; public static final int ROW_SETTING_FACEBEAUTY_PROPERTIES = 46;//camera // facebeauty adjustment public static final int ROW_SETTING_FACEBEAUTY_SMOOTH = 47;//camera public static final int ROW_SETTING_FACEBEAUTY_SKIN_COLOR = 48;//camera public static final int ROW_SETTING_FACEBEAUTY_SHARP = 49;//camera public static final int ROW_SETTING_CAMERA_FACE_DETECT = 50;//camera
打开SettingChecker,首先引入眼帘的是一大块常量定义,以ROW_SETTING_作为前缀(如上图)。
在《MTK camera 4.2 app PreferenceGroup生成过程》中我们已经知道,这些常量被当做索引,让ListPreference的引用保存到mListPrefs中。(mListPrefs定义如下:)
private ListPreference[] mListPrefs = new ListPreference[SETTING_ROW_COUNT];
- 使用SettingChecker作为访问preference的接口,就是通过这个表来访问。
- 通过查看每项后面的注释,我们可以了解到,索引不只包含preference。
索引分组
根据的需求,把索引放入不同的数组中
RESET_SETTING_ITEMS
程序退出时需要ComboPreference中清除的项。
SETTING_GROUP_XXX_FOR_TAB
SETTING_GROUP_COMMON_FOR_TAB SETTING_GROUP_CAMERA_FOR_TAB SETTING_GROUP_VIDEO_FOR_TAB SETTING_GROUP_COMMON_FOR_TAB_PREVIEW SETTING_GROUP_CAMERA_FOR_TAB_NO_PREVIEW SETTING_GROUP_VIDEO_FOR_TAB_NO_PREVIEW SETTING_GROUP_IMAGE_FOR_TAB
以上几个数组都是用于Setting界面中选项的显示。根据需求选择
SETTING_GROUP_CAMERA_FOR_PARAMETERS
用于下发拍照参数的setting项 //Camera setting items can be set in Parameters.
SETTING_GROUP_VIDEO_FOR_PARAMETERS
用于下发录像参数的setting项 //Video setting items can be set in parameters
SETTING_GROUP_CAMERA_FOR_UI
setting界面中所有与相机相关的项 //Camera all setting items for final user.
SETTING_GROUP_VIDEO_FOR_UI
setting界面中所有与录像相关的项 //Video all setting items for final user.
SETTING_GROUP_ALL_IN_SCREEN
在预览界面展示的preference ,可以参考(applyParametersToUIImmediately() 的注释)
SETTING_GROUP_ALL_IN_SETTING
SETTING_GROUP_NOT_IN_PREFERENCE
暂时不清楚。在camera_preference.xml中有相关项。部分在CameraSettings中有build方法。
Restriction
在findSupported()过程中,会先检查mMappingFinder是否存在;如果存在,则先用mMappingFinder过滤一次。
主要的表
没有说明,都指一维数组。二维数组在数组名后面加[][]
与PreferenceGroup生成过程,默认值相关
MATRIX_SETTING_VISIBLE[][]
在MTK camera 4.2 app PreferenceGroup生成过程已经提到。(前后摄像头各一个维度),决定该pref是否显示出来。
在PreferenceGroup生成过程的filterUnsuportedPreference()中使用.
DEFAULT_VALUE_FOR_SETTING
默认值。在PreferenceGroup生成过程的filterUnsuportedPreference()中被全部设置为null;在getDefaultValueFromXml()中被重新赋值。
DEFAULT_VALUE_FOR_SETTING_ID
默认值。引用资源文件中的值.string.pref_camera_XXX。
对DEFAULT_VALUE_FOR_SETTING[]的补充。用在getDefaultValueFromXml()
KEYS_FOR_SETTING
每一个索引(ROW_SETTING_XXX)都对应一个key。如果索引对应的pref是从Camera_preferences.xml读入,则该key与Camera_preferences.xml中的key相同。
与重置相关
RESET_STATE_VALUE[][]
不规则二维数组。配合下标STATE_R0,STATE_R1,……,STATE_R6,STATE_R7使用。
PS:关于STATE_XX
STATE_D0 = 100;//disable STATE_E0 = 200;//enable STATE_R0 = 300;//reset value 0 STATE_R1 = 301;//reset value 1 STATE_R2 = 302;//reset value 2 STATE_R3 = 303;//reset value 3 STATE_R4 = 304;//reset value 4 STATE_R5 = 305;//reset value 5 STATE_R6 = 306;//reset value 6 STATE_R7 = 307;//reset value 7
mOverrideSettingValues
进入特定场景,模式(ASD)下派参数时会覆盖一些setting值,为了从这些场景,模式恢复时能取得正确的场景,则在进入前进行保存。
PS:提供的两个方法getOverrideSettingValue(),getOverrideValues()参数,实现,返回值都一样。。难道为多人开发?
与mode(模式)相关
MATRIX_MODE_STATE[][]
定义了setting在各种mode下的状态:disable,enable,reset value.用STATE_XX表示
方法getMatrixValue()可以检索二维表。
与secne(场景)相关
MATRIX_SCENE_STATE[][]
定义了setting在各种secne下的状态:disable,enable,reset value.用STATE_XX表示。
方法getMatrixValue()可以检索二维表。
下派参数入口
public void applyPreferenceToParameters()
- 找到camera/video对应参数索引分组,确定哪些setting应该下派。getModeSettingGroupForParameters()。
- 再按照preference,mode,scene,restriction,other limitation的顺序调用命名方式为applyXXXxxxToParameters()的函数。
可以理解为一个模板流程。
基本的调用位置:
CameraStartUpThread.run() applyParameters(true); mSettingChecker.applyPreferenceToParameters();
private static int[] getModeSettingGroupForParameters()
isVideoMode()
- 1.根据mode判断当前为camera/video。取得MATRIX_MODE_STATE[ROW_SETTING_RECORDING_HINT][mode]中的值STATE_XX
- 2.定义STATE_OFFSET = 100;用于与STATE_XX求余得到RESET_STATE_VALUE[ROW_SETTING_RECORDING_HINT]中的下标,进而取得RESET_STATE_VALUE[ROW_SETTING_RECORDING_HINT]中的值(true/false)。
- 3.true:SETTING_GROUP_VIDEO_FOR_PARAMETERS; false: SETTING_GROUP_CAMERA_FOR_PARAMETERS;
getModeSettingGroupForParameters()
根据isVideoMode()选择索引分组 SETTING_GROUP_VIDEO_FOR_PARAMETERS 或者 SETTING_GROUP_CAMERA_FOR_PARAMETERS
private static void applyPreferenceToParameters()
根据上图我们可以看到为了逐个保存preference值到parameter中做了许多操作。
大概可以分为两步:
- 取值
- 检查值
取值
- 过滤掉索引分组SETTING_GROUP_NOT_IN_PREFERENCE中的setting项
- 检查是否有override value
- 如果上一步不成立,检查是否有mode状态对应的值
- 如果上一步不成立,取得preference(如果为空就用默认值)
检查值
- parameters是否支持 isParametersSupportedValue()
- 检查Capability getCapabilitySupportedValue() ???
private static void applyModeTableToParameters()
方法getMatrixValue()可以检索二维表,函数作者又在代码中重新做了个实现。。。。O__O"…
private static void applySceneTableToParameters()
保存场景的参数到Parameters.
过程与applyModeTableToParameters()类似
- 找到索引对应的参数
- 从自定义的参数值数组KEYS_FOR_SCENE[]中找到上一步获得的参数的index
- 根据index从二维数组MATRIX_SCENE_STATE[][]找到状态值
- 根据状态值从RESET_STATE_VALUE[][]找到值
- 保存值到parameters中
private static void applyRestrictionsToParameters()
正常启动,函数中的内容没有被执行。至于为何如此设计需要进一步研究。
public void applyLimitToParameters()
public void applyFocusCapabilities()
设置ae,awb,focus area, metering area,continous callback