MTK Camera Settings分析

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)将其设置为不显示。





一、 手机CAMERA的物理结构: ........................................................................................ - 4 - 二、 CAMERA的成像原理: ................................................................................................. - 4 - 三、 CAMERA常见的数据输出格式:.................................................................................. - 5 - 四、 阅读CAMERA的规格书(以TRULY模组OV5647_RAW为例): ........................... - 6 - 五、 CAMERA的硬件原理图及引脚 ..................................................................................... - 7 - 1、 电源部分:.................................................................................................................... - 7 - 2、 SENSOR INPUT部分: ................................................................................................... - 7 - 3、 SENSOR OUTPUT部分: ............................................................................................... - 7 - 4、 I2C部分:SCL,I2C时钟信号线和SDA,I2C数据信号线。 .................................. - 7 - 六、 MTK平台CAMERA驱动架构: .................................................................................. - 8 - 七、 MTK平台CAMERA相关代码文件(以下代码均为MTK6575平台): .................... - 9 - 1、 CAMERASENSOR驱动相关文件 .................................................................................... - 9 - 2、 SENSOR ID 和一些枚举类型的定义 ............................................................................. - 9 - 3、 SENSOR供电 .................................................................................................................. - 9 - 4、 KERNEL SPACE的SENSORLIST,IMGSENSOR模块注册 ............................................... - 9 - 5、 USER SPACE的SENSORLIST,向用户空间提供支持的SENSORLIST ......................... - 10 - 6、 SENSOR 效果调整的接口 ............................................................................................ - 10 - 八、 CAMERA模块驱动、设备与总线结构: ..................................................................... - 11 - A) 驱动的注册: .................................................................................................................. - 11 - B) 设备的注册: .................................................................................................................. - 11 - C) 总线的匹配: .................................................................................................................. - 12 - 九、 CAMERA驱动工作流程: ............................................................................................- 13 - 十、 CAMERA驱动添加、调试流程:.......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值