Ov5640.c (drivers\media\video)
83087
2013-5-31
两个地方使用到夜景,但都是关闭:
ov5640_config_preview
ov5640_set_night_mode(sd, 0);//关闭夜景
ov5640_config_capture
ov5640_set_night_mode(sd, 0);//关闭夜景
HAL层代码:
Broadcom21664/src/hardware/broadcom/rhea_hawaii/v4l2_camerahal/
App:
一、资源文件:
1.apps\camera\res\xml\Camera_preferences.xml
<IconListPreference
camera:key="pref_camera_scenemode_key"
camera:defaultValue="@string/pref_camera_scenemode_default"
camera:title="@string/pref_camera_scenemode_title"
camera:singleIcon="@drawable/ic_scn_holo_light"
camera:entries="@array/pref_camera_scenemode_entries"
camera:entryValues="@array/pref_camera_scenemode_entryvalues" />
2.apps\camera\res\values-en-rgb\Strings.xml
<string name="pref_camera_scenemode_title" msgid="1420535844292504016">"Scene mode"</string>
3.apps\camera\res\values\Arrays.xml
<string-array name="pref_camera_scenemode_entries" translatable="false">
<item>@string/pref_camera_scenemode_entry_auto</item>
<item>@string/pref_camera_scenemode_entry_landscape</item>
<item>@string/pref_camera_scenemode_entry_portrait</item>
<item>@string/pref_camera_scenemode_entry_night</item>
<item>@string/pref_camera_scenemode_entry_night_portrait</item>
<item>@string/pref_camera_scenemode_entry_action</item>
<item>@string/pref_camera_scenemode_entry_theatre</item>
<item>@string/pref_camera_scenemode_entry_beach</item>
<item>@string/pref_camera_scenemode_entry_snow</item>
<item>@string/pref_camera_scenemode_entry_sunset</item>
<item>@string/pref_camera_scenemode_entry_steadyphoto</item>
<item>@string/pref_camera_scenemode_entry_fireworks</item>
<item>@string/pref_camera_scenemode_entry_sports</item>
<item>@string/pref_camera_scenemode_entry_party</item>
<item>@string/pref_camera_scenemode_entry_candlelight</item>
</string-array>
和
<string-array name="pref_camera_scenemode_entryvalues" translatable="false">
<item>auto</item>
<item>landscape</item>
<item>portrait</item>
<item>night</item>
<item>night-portrait</item>
<item>action</item>
<item>theatre</item>
<item>beach</item>
<item>snow</item>
<item>sunset</item>
<item>steadyphoto</item>
<item>fireworks</item>
<item>sports</item>
<item>party</item>
<item>candlelight</item>
</string-array>
由这些定义,我们可以看出,Android的Camera应用程序支持15种场景模式。但是硬件并非都支持这些模式的。所以最终的菜单中只会显示这15种场景模式当中底层硬件所支持的,如果硬件支持的场景模式与其中任何一种都不匹配,则不会显示出“Scene mode”菜单。
二、菜单的创建:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
if (mIsImageCaptureIntent) {
// No options menu for attach mode.
return false;
} else {
addBaseMenuItems(menu);
}
return true;
}
//这段代码没有看明白,以后分析。
在非Video Camera模式下,mIsImageCaptureIntent为true,此处将不做任何处理。当mIsImageCaptureIntent为false时,即Video Camera模式下,将调用函数addBaseMenuItems()来创建Video Camera的菜单。Picture大小的菜单不会出现在Video Camera模式下,所以就不对addBaseMenuItems()函数分析了。
既然这里没有创建Camera模式下的菜单,那Camera模式下的菜单在哪里创建的了?我们接着分析。在Camera.java文件中定义了类MainHandler,它里面只有一个成员函数handleMessage(),它用来处理Camera应用程序中的message。
代码:
private class MainHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case RESTART_PREVIEW: {
restartPreview();
if (mJpegPictureCallbackTime != 0) {
long now = System.currentTimeMillis();
mJpegCallbackFinishTime = now - mJpegPictureCallbackTime;
Log.v(TAG, "mJpegCallbackFinishTime = "
+ mJpegCallbackFinishTime + "ms");
mJpegPictureCallbackTime = 0;
}
break;
}
case CLEAR_SCREEN_DELAY: {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
break;
}
case FIRST_TIME_INIT: {
initializeFirstTime();
break;
}
case SET_CAMERA_PARAMETERS_WHEN_IDLE: {
setCameraParametersWhenIdle(0);
break;
}
}
}
}
Message FIRST_TIME_INIT应该在类Camera初始化时就会被处理,我是这样猜的,只是还没有找到具体的code。initializeFirstTime()的实现如下所示:
private void initializeFirstTime() {
。。。
mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
initializeHeadUpDisplay();//里面会对xml进行加载
mFirstTimeInitialized = true;//前面初始化好之后将标志设置为true
changeHeadUpDisplayState();
。。。
}
上面有两个函数很重要:
1.加载监听器MyHeadUpDisplayListener
2.加载xml文件initializeHeadUpDisplay
private void initializeHeadUpDisplay() {
CameraSettings settings = new CameraSettings(this, mInitialParams,
CameraHolder.instance().getCameraInfo());
mHeadUpDisplay.initialize(this,
settings.getPreferenceGroup(R.xml.camera_preferences),
getZoomRatios(), mOrientationCompensation);
//其中R.xml.camera_preferences指的就是camera_preference.xml资源文件。
。。。
updateSceneModeInHud();
}
接下来我们将对settings.getPreferenceGroup()--->获取配置,mHeadUpDisplay.initialize()和MyHeadUpDisplayListener做以介绍。
函数settings.getPreferenceGroup()定义在文件Packages/apps/camera/src/com/android/camera/CameraSetting.java中。其具体定义为:
public PreferenceGroup getPreferenceGroup(int preferenceRes) {
PreferenceInflater inflater = new PreferenceInflater(mContext);
PreferenceGroup group =
(PreferenceGroup) inflater.inflate(preferenceRes);
if (mParameters != null) initPreference(group);
return group;
}
函数inflater.inflate(preferenceRes)将camera_preference.xml文件中的菜单信息存储到PreferenceGroup中。接着函数initPreference()对这些信息做了处理
private void initPreference(PreferenceGroup group) {
。。。
ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);
。。。
if (sceneMode != null) {
filterUnsupportedOptions(group,
sceneMode, mParameters.getSupportedSceneModes());
}
。。。
}
其中,宏定义KEY_SCENE_MODE定义在文件
Packages/apps/camera/src/com/android/camera/CameraSetting.java中,具体定义为:
public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
该值与camera_preference.xml中的KEY值匹配。语句ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);将sceneMode的信息存储在了结构体ListPreference sceneMode中。
语句
if (sceneMode != null) {
filterUnsupportedOptions(group,
sceneMode, mParameters.getSupportedSceneModes());
}
mParameters.getSupportedSceneModes()获取了硬件Camera所支持的sceneMode信息,我在Camera HAL层(broadcom\rhea_hawaii\v4l2_camerahal\brcm\CameraHAL.cpp)的实现中,在函数initDefaultParameters()中设置了硬件所支持的sceneMode。CODE如下:
str8 = pCamDev->querySceneModes(defScene);//在这里需要进一步查看
if (str8.length() > 0) {//查询支持的scene mode
ALOGI("initDefaultParameters(): camera device supports %s scene modes", str8.string());
mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, str8.string());
mParameters.set(CameraParameters::KEY_SCENE_MODE, defScene.string());
}
函数filterUnsupportedOptions()会将Camera应用和硬件支持的Scence中两者匹配的mode存储在group中。
函数mHeadUpDisplay.initialize()定义在文件
broadcom_test_apps\brcmcamera\src\com\broadcom\camera\ui\CameraHeadUpDisplay.java中,其具体定义为:
public void initialize(Context context, PreferenceGroup group,
float[] initialZoomRatios, int initialOrientation) {
mInitialZoomRatios = initialZoomRatios;
mInitialOrientation = initialOrientation;
super.initialize(context, group);
}
调用父类的initialize
public void initialize(Context context, PreferenceGroup preferenceGroup) {
mPreferenceGroup = preferenceGroup;
mSharedPrefs = ComboPreferences.get(context);
mPopupWindow = null;
clearComponents();
initializeIndicatorBar(context, preferenceGroup);
requestLayout();
}
其中函数initializeIndicatorBar()定义如下:
protected void initializeIndicatorBar(
Context context, PreferenceGroup group) {
mIndicatorBar = new IndicatorBar();
mIndicatorBar.setBackground(new NinePatchTexture(
context, R.drawable.ic_viewfinder_iconbar));
mIndicatorBar.setHighlight(new ColorTexture(COLOR_ICONBAR_HIGHLIGHT));
addComponent(mIndicatorBar);
mIndicatorBar.setOnItemSelectedListener(new IndicatorBarListener());
}
函数addComponent()将group中的picture大小添加到了菜单中。至此,菜单的创建就告一段落。