MTK Camera Settings分析
来源:互联网 发布:淘宝直播赚钱吗 编辑:程序博客网 时间:2024/05/17 07:28
MTK的camera实现settings的方式比较复杂,先贴出Camera的settings实现涉及的主要类与其关系图:
下面先初略了解整个setting建立的大致流程:
1.settings数据存储表格.
Settings使用SharedPreferences来存储设置项,分为Global和Local,Global一张表,存储全局的设置项,如位置信息。Local根据cameraId的数量建表,即每个camera都对应一张Local表,对应的表中的设置信息只对对应的camera生效。
这些表的建立和对象的获取是在CameraActivity的onCreate中通过
mPreferences = new ComboPreferences(this,isSecureCamera());得到的。其中CameraDeciveCtrl持有mPreferences对象。
2. settings初始化
在camera打开时,CameraDeciveCtrl里的CameraStartUpThread将被启动,其run方法里将会调用initializeSettingController()方法:
private void initializeSettingController() { Log.d(TAG, "[initializeSettingController]"); if (!mISettingCtrl.isSettingsInitialized()) { mISettingCtrl.initializeSettings(R.xml.camera_preferences, mPreferences.getGlobal(),mPreferences.getLocal()); } mISettingCtrl.updateSetting(mPreferences.getLocal()); •••}
CameraDeciveCtrl持有ISettingCtrl接口对象,而SettingCtrl实现了ISettingCtrl接口。SettingCtrl是Settings实现的核心类,主要负责设置项的初始化、设置项之间的规则执行、设置项的修改等功能。initializeSettings方法如下:
@Override public void initializeSettings(int preferenceRes, SharedPreferences globalPref, SharedPreferences localPref) { Log.i(TAG, "[initializeSettings]..."); mGlobalPref = globalPref; mLocalPrefs.put(mICameraDeviceManager.getCurrentCameraId(), localPref); mPrefTransfer = new SharedPreferencesTransfer(globalPref, localPref); mSettingGenerator = new SettingGenerator(mICameraContext, mPrefTransfer); mSettingGenerator.createSettings(preferenceRes); createRules(); mIsInitializedSettings = true; }
首先将preference对象保存,再新建一个SettingGenerator对象,最后调用createRules()创建setting项之间的规则(后面介绍)。
先来看看SettingGenerator的createSettings方法
public void createSettings(int preferenceRes) { mPreferenceRes = preferenceRes; mInflater = new PreferenceInflater(mContext, mPrefTransfer); int currentCameraId = mICameraDeviceManager.getCurrentCameraId(); PreferenceGroup group = (PreferenceGroup) mInflater.inflate(preferenceRes); mPreferencesGroupMap.put(currentCameraId, group); createSettingItems(); createPreferences(group, currentCameraId);}
这里将R.xml.camera_preferences这个xml表的内容加载进来(Inflater的同时会将对应的item保存进preference中),并保存在mPreferencesGroupMap中,然后创建所有setting项对应的SettingItems实例,再创建每个设置项的ListPreference对象并保存到mPreferencesMap,最后还有调用filterPreferences方法来过滤setting项(后面详细介绍)。
至此,初始化工作基本完成,总结起来有几点:
1.获取preference;
2.将R.xml.camera_preferences这个xml表加载进preference里;
3.创建规则;
4.创建Preferences对象集,并过滤。
另外,这里还有一个类SettingConstants,里面是所有settings项的preference字段名和编号,还定义了很多数组,用于各种情况下使用的settings项,如 :
UN_SUPPORT_BY_3RDPARTY——三方进入camera是不支持的setting项
RESET_SETTING_ITEMS——重置setting时需要重置的项等----------------------------------------------------------------------------------------------------------------------------------------------------------
下面详细分析settings规则:
规则的实体类是CommonRule,它实现了ISettingRule接口,主要包含execute和addLimitation两个方法,根据方法名就知道其用来运行规则和添加限制条件。CommonRule主要有以下成员:
private String mConditionKey;//受限项的key private String mResultKey;//受影响项的key private SettingItem mConditionSetting; private SettingItem mResultSetting; private List<String> mConditions =new ArrayList<String>();//受限项的值 private List<List<String>>mResults = new ArrayList<List<String>>();//受影响项的值
SettingCtrl的createRules方法如下:
private void createRules() { createRuleFromResctrictionMatrix(); createRuleFromRestrictions(); createRuleFromScene(); RuleContainer container = newRuleContainer(this, mICameraContext); container.addRule(); }
这里有四种创建规则的方法:
1. createRuleFromResctrictionMatrix()
这种规则的来源是SettingDataBase中的MATRIX_RESTRICTION_STATE数组
例如:
MATRIX_RESTRICTION_STATE[SettingConstants.ROW_SETTING_FLASH]= new int[]{ STATE_E0, STATE_R0, STATE_R0,STATE_R0, STATE_E0, STATE_E0, STATE_E0, STATE_R0, STATE_R0,STATE_R0};
这个数组表示不同模式下,FLASH的设置情况,模式的顺序有RESTRCTION_SETTING_INDEX数组决定,如第二个是SettingConstants.ROW_SETTING_HDR,则当FLASH设置为”on”的时候,HDR设置为R0所代表的值,而R0所代表的值为RESET_STATE_VALUE这个数组中的第1个元素,HDR的是”off”。2. createRuleFromRestrictions()
这种规则的来源是SettingDataBase中的RESTRICTIOINS数组:
例如:
new Restriction(SettingConstants.ROW_SETTING_MICROPHONE)//should be checked. .setValues("off") .setRestrictions( newRestriction(SettingConstants.ROW_SETTING_AUDIO_MODE) .setEnable(false) .setValues("normal"))
代表当MICROPHONE为”off”时,AUDIO_MODE设为"normal"。
3. createRuleFromScene();
与createRuleFromResctrictionMatrix 类似,只是来源数组变为MATRIX_SCENE_STATE
4.container.addRule();
手动添加规则,如:
HDRZSDRulehdrzsdRule = new HDRZSDRule(); mISettingCtrl.addRule(SettingConstants.KEY_HDR, SettingConstants.KEY_CAMERA_ZSD, hdrzsdRule);
通过HDRZSDRule中设定HDR与ZSD之间的规则。
----------------------------------------------------------------------------------------------------------------------------------------------------------
下面来看filterPreferences这个方法。
前面说的SettingGenerator中在createPreferences时候,会调用filterPreferences来过滤设置项,这也是为什么不同的模式或者不同的进入方式等,settings会表现不同的原因。下面就详细分析过滤了哪些的东西。
先看filterPreferences这个函数:
private voidfilterPreferences(ArrayList<ListPreference> preferences, int cameraId) { ArrayList<SettingItem>settingItems = mSettingItemsMap.get(cameraId); limitPreferencesByIntent(); for (int i = 0; i <preferences.size(); i++) { // filter list preference. ListPreference preference =preferences.get(i); boolean isRemove =filterPreference(preference); if (isRemove) { preference = null; preferences.set(i, null); } // update setting's value anddefault value. SettingItem settingItem =settingItems.get(i); updateSettingItem(settingItem,preference); } overrideSettingByIntent(); }
主要有三个方法起到过滤的作用,limitPreferencesByIntent()、filterPreference(preference)、和overrideSettingByIntent():
limitPreferencesByIntent()方法如下,主要就是将两个数组SettingConstants.UN_SUPPORT_BY_3RDPARTY和SettingConstants.UN_SUPPORT_BY_FRONT_CAMERA中的setting项的preference置空,从数组名可以看出,是过滤三方Intent进入camera和前置摄像头这两种情况下不支持的setting项。
private void limitPreferencesByIntent() { boolean isNonePickIntent =mIModuleCtrl.isNonePickIntent(); if (!isNonePickIntent) { int currentCameraId =mICameraDeviceManager.getCurrentCameraId(); ArrayList<ListPreference> preferences= mPreferencesMap.get(currentCameraId); int[]unSupportedBy3rdParty = SettingConstants.UN_SUPPORT_BY_3RDPARTY; for (int i = 0; i <unSupportedBy3rdParty.length; i++) { preferences.set(unSupportedBy3rdParty[i],null); } } int currentCameraId =mICameraDeviceManager.getCurrentCameraId(); if (currentCameraId ==mICameraDeviceManager.getFrontCameraId()) { ArrayList<ListPreference>preferences = mPreferencesMap.get(currentCameraId); int[] unSupportedByFrontCamera =SettingConstants.UN_SUPPORT_BY_FRONT_CAMERA; for (int i = 0; i <unSupportedByFrontCamera.length; i++) { preferences.set(unSupportedByFrontCamera[i], null); } } }
再来看看filterPreference(preference),这个方法的内容较多,不贴代码,主要看看其做了什么。这个方法是被遍历调用的,有多少个settings项,就调用多少次,通过switch (settingId) 判断此次调用需要过滤的setting项是什么,然后调用对应setting项的具体过滤方法,比如
caseSettingConstants.ROW_SETTING_DUAL_CAMERA: removePreference =buildCameraId(preference, settingId); break;
ROW_SETTING_DUAL_CAMERA这个设置项,buildCameraId方法中判断摄像头的个数,小于两个这返回ture,即移除该项,否则说明是支持双摄的,则不移除该项。
很多时候莫名其妙的那个setting项不见了,很可能就是在这里将其移除了。
最后overrideSettingByIntent():
privatevoid overrideSettingByIntent() { if (!mIModuleCtrl.isNonePickIntent()) { int[]supportedBy3rdButHidden = SettingConstants.SUPPORT_BY_3RDPARTY_BUT_HIDDEN; for (int i = 0; i <supportedBy3rdButHidden.length; i++) { int settingIndex =supportedBy3rdButHidden[i]; SettingItem item =getSettingItem(settingIndex); ListPreference pref =item.getListPreference(); if (pref != null) { pref.setVisibled(false); } //Override its value as defaultvalue except GPS and video quality. if(SettingConstants.ROW_SETTING_RECORD_LOCATION != settingIndex &&SettingConstants.ROW_SETTING_VIDEO_QUALITY != settingIndex) { item.setValue(SettingDataBase.getDefaultValue(settingIndex)); } } } }
这里是对数组SettingConstants.SUPPORT_BY_3RDPARTY_BUT_HIDDEN里的设置项进行过滤,即三方进入camera时,支持的setting项但不显示的,如ROW_SETTING_VIDEO_QUALITY,通过pref.setVisibled(false)将其设置为不显示。
- MTK Camera Settings分析
- MTK Camera上电流程分析
- mtk平台Camera应用的全屏分析
- MTK-CAMERA
- MTK平台camera AF马达驱动调试流程分析
- MTK平台camera AF马达驱动调试流程分析
- Android5.0 MTk Camera HAL层代码分析
- mtk android settings
- mtk android settings
- mtk camera isp
- mtk camera isp
- MTK Camera Power
- MTK Android Driver :camera
- MTK Android Driver :camera
- MTK Android Driver :camera
- MTK之camera框架
- mtk camera 移植步骤
- MTK 移植camera说明
- 单例模式 六种写法
- 级联人脸检测--Detecting Faces Using Inside Cascaded Contextual CNN
- 设计模式----装饰模式
- 拷贝构造和赋值运算符函数的重载
- require 和 include 用法区别
- MTK Camera Settings分析
- 10分钟搞懂Tensorflow 逻辑回归实现手写识别
- 【P2024】食物链 (扩展域并查集)
- SpringBoot配置属性之NOSQL(四)
- [Leetcode] 415. Add Strings 解题报告
- List、set以及map的遍历方式的整理
- 跑通 MobileNet in Tensorflow
- C#DynamicXml动态读取操作XML(XML到Object的通用实现)
- 传感器数据融合