《【高通SDM660平台】(1) — Camera 驱动 Bringup Guide》
《【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析》
《【高通SDM660平台】(3) — Camera V4L2 驱动层分析 》
《【高通SDM660平台】(4) — Camera Init 初始化流程 》
《【高通SDM660平台】(5) — Camera Open 流程》
《【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程》
《【高通SDM660平台】(7) — Camera onPreview 代码流程》
《【高通SDM660平台】(8) — Camera MetaData介绍》
《【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析》
《【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析》
《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》
前面分析了 open camera 流程,在preview 前,我们要做 getParameters 及 setParameters 操作,因此,我们先来看下 getParameters 及 setParameters 的调用流程。
网上从大神那看到一张图,画的挺好,先贴上来:
在分析代码前,我们先来看下Camera.java 的代码注释:
To make camera parameters take effect, applications have to call {@link Camera#setParameters(Camera.Parameters)}.
Camera APP 需要调用setParameters()
方法来让参数设置生效。
For example, after {@link Camera.Parameters#setWhiteBalance} is called, white balance is not actually changed until {@link Camera#setParameters(Camera.Parameters)} is called with the changed parameters object.
例如,当调用setWhiteBalance()
方法后,白平衡实际上并没有生效,需要在调用 setParameters()
后才会实际生效。
Different devices may have different camera capabilities, such as picture size or flash modes.
不同的Camera 硬件设备的支持的功能及能力也不同,比如 图片尺寸、闪光灯模式等。
For example, the application should call {@link Camera.Parameters#getSupportedColorEffects()} before calling {@link Camera.Parameters#setColorEffect(String)}.
例如,app 应该先调用 getSupportedColorEffects()
,然后再调用 setColorEffect(string)
方法。
If the camera does not support color effects, {@link Camera.Parameters#getSupportedColorEffects()} will return null.
如果Camera
硬件不支持 color effects
,调和 getSupportedColorEffects()
函数时会返回 NULL。
Camera 有特别多参数,主要包括如下:
@ frameworks/base/core/java/android/hardware/Camera.java public class Camera { private static final String TAG = "Camera"; /* Camera service settings. * @deprecated We recommend using the new {@link android.hardware.camera2} API for new applications. */ @Deprecated public class Parameters { // Parameter keys to communicate with the camera driver. // 1. Preview 尺寸、格式、帧率、支持的fps范围 private static final String KEY_PREVIEW_SIZE = "preview-size"; private static final String KEY_PREVIEW_FORMAT = "preview-format"; private static final String KEY_PREVIEW_FRAME_RATE = "preview-frame-rate"; private static final String KEY_PREVIEW_FPS_RANGE = "preview-fps-range"; // 2. Picture 尺寸、格式 private static final String KEY_PICTURE_SIZE = "picture-size"; private static final String KEY_PICTURE_FORMAT = "picture-format"; // 3. Jpeg 缩略图的 尺寸、宽高、质量, Jpeg的能力 private static final String KEY_JPEG_THUMBNAIL_SIZE = "jpeg-thumbnail-size"; private static final String KEY_JPEG_THUMBNAIL_WIDTH = "jpeg-thumbnail-width"; private static final String KEY_JPEG_THUMBNAIL_HEIGHT = "jpeg-thumbnail-height"; private static final String KEY_JPEG_THUMBNAIL_QUALITY = "jpeg-thumbnail-quality"; private static final String KEY_JPEG_QUALITY = "jpeg-quality"; // 4. 旋转角度 private static final String KEY_ROTATION = "rotation"; // 5. GPS 经纬度、时间戳等信息 private static final String KEY_GPS_LATITUDE = "gps-latitude"; private static final String KEY_GPS_LONGITUDE = "gps-longitude"; private static final String KEY_GPS_ALTITUDE = "gps-altitude"; private static final String KEY_GPS_TIMESTAMP = "gps-timestamp"; private static final String KEY_GPS_PROCESSING_METHOD = "gps-processing-method"; // 6. 白平衡、效果、场景模式、闪光灯模式、对焦模式、对焦范围、对焦长度 private static final String KEY_WHITE_BALANCE = "whitebalance"; private static final String KEY_EFFECT = "effect"; private static final String KEY_ANTIBANDING = "antibanding"; private static final String KEY_SCENE_MODE = "scene-mode"; private static final String KEY_FLASH_MODE = "flash-mode"; private static final String KEY_FOCUS_MODE = "focus-mode"; private static final String KEY_FOCUS_AREAS = "focus-areas"; private static final String KEY_MAX_NUM_FOCUS_AREAS = "max-num-focus-areas"; private static final String KEY_FOCAL_LENGTH = "focal-length"; // 7. 水平视角、垂直视角、曝光补偿、自动曝光、自动白平衡 private static final String KEY_HORIZONTAL_VIEW_ANGLE = "horizontal-view-angle"; private static final String KEY_VERTICAL_VIEW_ANGLE = "vertical-view-angle"; private static final String KEY_EXPOSURE_COMPENSATION = "exposure-compensation"; private static final String KEY_MAX_EXPOSURE_COMPENSATION = "max-exposure-compensation"; private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation"; private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step"; private static final String KEY_AUTO_EXPOSURE_LOCK = "auto-exposure-lock"; private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported"; private static final String KEY_AUTO_WHITEBALANCE_LOCK = "auto-whitebalance-lock"; private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED = "auto-whitebalance-lock-supported"; // 8. 放大缩放功能,焦距 private static final String KEY_METERING_AREAS = "metering-areas"; private static final String KEY_MAX_NUM_METERING_AREAS = "max-num-metering-areas"; private static final String KEY_ZOOM = "zoom"; private static final String KEY_MAX_ZOOM = "max-zoom"; private static final String KEY_ZOOM_RATIOS = "zoom-ratios"; private static final String KEY_ZOOM_SUPPORTED = "zoom-supported"; private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported"; private static final String KEY_FOCUS_DISTANCES = "focus-distances"; // 9. video size、视频预览大小、最大人脸检测数量、VIDEO 质量 private static final String KEY_VIDEO_SIZE = "video-size"; private static final String KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO = "preferred-preview-size-for-video"; private static final String KEY_MAX_NUM_DETECTED_FACES_HW = "max-num-detected-faces-hw"; private static final String KEY_MAX_NUM_DETECTED_FACES_SW = "max-num-detected-faces-sw";
private static final String KEY_RECORDING_HINT = "recording-hint"; private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported"; private static final String KEY_VIDEO_STABILIZATION = "video-stabilization"; private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported"; // Parameter key suffix for supported values. private static final String SUPPORTED_VALUES_SUFFIX = "-values"; private static final String TRUE = "true"; private static final String FALSE = "false"; // 10. 自动白平衡、白炽光、荧光灯、暖荧光灯、日光、阴天、晚上、阴影效果 // Values for white balance settings. public static final String WHITE_BALANCE_AUTO = "auto"; public static final String WHITE_BALANCE_INCANDESCENT = "incandescent"; public static final String WHITE_BALANCE_FLUORESCENT = "fluorescent"; public static final String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent"; public static final String WHITE_BALANCE_DAYLIGHT = "daylight"; public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight"; public static final String WHITE_BALANCE_TWILIGHT = "twilight"; public static final String WHITE_BALANCE_SHADE = "shade"; /** @hide * wb manual cct mode. */ public static final String WHITE_BALANCE_MANUAL_CCT = "manual-cct"; // 11. 颜色效果 // Values for color effect settings. public static final String EFFECT_NONE = "none"; public static final String EFFECT_MONO = "mono"; public static final String EFFECT_NEGATIVE = "negative"; public static final String EFFECT_SOLARIZE = "solarize"; public static final String EFFECT_SEPIA = "sepia"; public static final String EFFECT_POSTERIZE = "posterize"; public static final String EFFECT_WHITEBOARD = "whiteboard"; public static final String EFFECT_BLACKBOARD = "blackboard"; public static final String EFFECT_AQUA = "aqua"; // Values for antibanding settings. public static final String ANTIBANDING_AUTO = "auto"; public static final String ANTIBANDING_50HZ = "50hz"; public static final String ANTIBANDING_60HZ = "60hz"; public static final String ANTIBANDING_OFF = "off"; // 12、闪光灯模式,关闭,自动,常开,手电筒模式、消除红眼 // Values for flash mode settings. /** Flash will not be fired. */ public static final String FLASH_MODE_OFF = "off"; /** * Flash will be fired automatically when required. The flash may be fired * during preview, auto-focus, or snapshot depending on the driver. */ public static final String FLASH_MODE_AUTO = "auto"; /** * Flash will always be fired during snapshot. The flash may also be * fired during preview or auto-focus depending on the driver. */ public static final String FLASH_MODE_ON = "on"; /** Flash will be fired in red-eye reduction mode. */ public static final String FLASH_MODE_RED_EYE = "red-eye"; /** Constant emission of light during preview, auto-focus and snapshot. * This can also be used for video recording.*/ public static final String FLASH_MODE_TORCH = "torch"; // 13、场景模式: 移动、消像、风景、夜晚、夜晚肖像、海滩、雪天、日落,抖动消除、烟火、运动,晚会、烛光、条形码、高清等 /** @hide * Scene mode is off.*/ public static final String SCENE_MODE_ASD = "asd"; public static final String SCENE_MODE_AUTO = "auto"; /** * Take photos of fast moving objects. Same as {@link #SCENE_MODE_SPORTS}.*/ public static final String SCENE_MODE_ACTION = "action"; /*** Take people pictures. */ public static final String SCENE_MODE_PORTRAIT = "portrait"; /*** Take pictures on distant objects. */ public static final String SCENE_MODE_LANDSCAPE = "landscape"; /** * Take photos at night. */ public static final String SCENE_MODE_NIGHT = "night"; /*** Take people pictures at night.*/ public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait"; /*** Take photos in a theater. Flash light is off.*/ public static final String SCENE_MODE_THEATRE = "theatre"; /*** Take pictures on the beach.*/ public static final String SCENE_MODE_BEACH = "beach"; /*** Take pictures on the snow. */ public static final String SCENE_MODE_SNOW = "snow"; /*** Take sunset photos.*/ public static final String SCENE_MODE_SUNSET = "sunset"; /** * Avoid blurry pictures (for example, due to hand shake).*/ public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto"; /** * For shooting firework displays.*/ public static final String SCENE_MODE_FIREWORKS = "fireworks"; /*** Take photos of fast moving objects. Same as {@link #SCENE_MODE_ACTION}.*/ public static final String SCENE_MODE_SPORTS = "sports"; /*** Take indoor low-light shot. */ public static final String SCENE_MODE_PARTY = "party"; /*** Capture the naturally warm color of scenes lit by candles.*/ public static final String SCENE_MODE_CANDLELIGHT = "candlelight"; /** @hide* SCENE_MODE_BACKLIGHT**/ public static final String SCENE_MODE_BACKLIGHT = "backlight"; /** @hide* SCENE_MODE_FLOWERS**/ public static final String SCENE_MODE_FLOWERS = "flowers"; /** * Applications are looking for a barcode. Camera driver will be * optimized for barcode reading. */ public static final String SCENE_MODE_BARCODE = "barcode"; /** * Capture a scene using high dynamic range imaging techniques. The * camera will return an image that has an extended dynamic range * compared to a regular capture. Capturing such an image may take * longer than a regular capture. */ public static final String SCENE_MODE_HDR = "hdr"; /** * Auto-focus mode. Applications should call {@link * #autoFocus(AutoFocusCallback)} to start the focus in this mode. */ public static final String FOCUS_MODE_AUTO = "auto"; /** * Focus is set at infinity. Applications should not call * {@link #autoFocus(AutoFocusCallback)} in this mode. */ public static final String FOCUS_MODE_INFINITY = "infinity"; /** * Macro (close-up) focus mode. Applications should call * {@link #autoFocus(AutoFocusCallback)} to start the focus in this * mode. */ public static final String FOCUS_MODE_MACRO = "macro"; /** * Focus is fixed. The camera is always in this mode if the focus is not * adjustable. If the camera has auto-focus, this mode can fix the * focus, which is usually at hyperfocal distance. Applications should * not call {@link #autoFocus(AutoFocusCallback)} in this mode. */ public static final String FOCUS_MODE_FIXED = "fixed"; /** @hide * Normal focus mode. Applications should call * {@link #autoFocus(AutoFocusCallback)} to start the focus in this * mode. */ public static final String FOCUS_MODE_NORMAL = "normal"; /** * Extended depth of field (EDOF). Focusing is done digitally and * continuously. Applications should not call {@link * #autoFocus(AutoFocusCallback)} in this mode. */ public static final String FOCUS_MODE_EDOF = "edof"; /** * Continuous auto focus mode intended for video recording. The camera * continuously tries to focus. This is the best choice for video * recording because the focus changes smoothly . Applications still can * call {@link #takePicture(Camera.ShutterCallback, * Camera.PictureCallback, Camera.PictureCallback)} in this mode but the * subject may not be in focus. Auto focus starts when the parameter is * set. * * <p>Since API level 14, applications can call {@link * #autoFocus(AutoFocusCallback)} in this mode. The focus callback will * immediately return with a boolean that indicates whether the focus is * sharp or not. The focus position is locked after autoFocus call. If * applications want to resume the continuous focus, cancelAutoFocus * must be called. Restarting the preview will not resume the continuous * autofocus. To stop continuous focus, applications should change the * focus mode to other modes. * * @see #FOCUS_MODE_CONTINUOUS_PICTURE */ public static final String FOCUS_MODE_CONTINUOUS_VIDEO = "continuous-video"; /** * Continuous auto focus mode intended for taking pictures. The camera * continuously tries to focus. The speed of focus change is more * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus * starts when the parameter is set. * * <p>Applications can call {@link #autoFocus(AutoFocusCallback)} in * this mode. If the autofocus is in the middle of scanning, the focus * callback will return when it completes. If the autofocus is not * scanning, the focus callback will immediately return with a boolean * that indicates whether the focus is sharp or not. The apps can then * decide if they want to take a picture immediately or to change the * focus mode to auto, and run a full autofocus cycle. The focus * position is locked after autoFocus call. If applications want to * resume the continuous focus, cancelAutoFocus must be called. * Restarting the preview will not resume the continuous autofocus. To * stop continuous focus, applications should change the focus mode to * other modes. * * @see #FOCUS_MODE_CONTINUOUS_VIDEO */ public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture"; /** @hide * manual focus mode */ public static final String FOCUS_MODE_MANUAL_POSITION = "manual"; // Indices for focus distance array. /** * The array index of near focus distance for use with * {@link #getFocusDistances(float[])}. */ public static final int FOCUS_DISTANCE_NEAR_INDEX = 0; /** * The array index of optimal focus distance for use with * {@link #getFocusDistances(float[])}. */ public static final int FOCUS_DISTANCE_OPTIMAL_INDEX = 1; /** * The array index of far focus distance for use with * {@link #getFocusDistances(float[])}. */ public static final int FOCUS_DISTANCE_FAR_INDEX = 2; /** * The array index of minimum preview fps for use with {@link * #getPreviewFpsRange(int[])} or {@link * #getSupportedPreviewFpsRange()}. */ public static final int PREVIEW_FPS_MIN_INDEX = 0; /** * The array index of maximum preview fps for use with {@link * #getPreviewFpsRange(int[])} or {@link * #getSupportedPreviewFpsRange()}. */ public static final int PREVIEW_FPS_MAX_INDEX = 1; // 14、像素格式:yuv、rgb、jpeg、bayer-rggb、raw、yv12、nv12 // Formats for setPreviewFormat and setPictureFormat. private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp"; private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp"; private static final String PIXEL_FORMAT_YUV420SP_ADRENO = "yuv420sp-adreno"; private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv"; private static final String PIXEL_FORMAT_YUV420P = "yuv420p"; private static final String PIXEL_FORMAT_RGB565 = "rgb565"; private static final String PIXEL_FORMAT_JPEG = "jpeg"; private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb"; private static final String PIXEL_FORMAT_RAW = "raw"; private static final String PIXEL_FORMAT_YV12 = "yv12"; private static final String PIXEL_FORMAT_NV12 = "nv12"; private final LinkedHashMap<String, String> mMap; // 1.初始化 camera 参数的hash map private Parameters() { mMap = new LinkedHashMap<String, String>(/*initialCapacity*/64); } // 2. 将所所参数 dump到 log中 @Deprecated public void dump() { Log.e(TAG, "dump: size=" + mMap.size()); for (String k : mMap.keySet()) { Log.e(TAG, "dump: " + k + "=" + mMap.get(k)); } } public void set(String key, String value) { if (key.indexOf('=') != -1 || key.indexOf(';') != -1 || key.indexOf(0) != -1) { Log.e(TAG, "Key \"" + key + "\" contains invalid character (= or ; or \\0)"); return; } if (value.indexOf('=') != -1 || value.indexOf(';') != -1 || value.indexOf(0) != -1) { Log.e(TAG, "Value \"" + value + "\" contains invalid character (= or ; or \\0)"); return; } put(key, value); } // 3. 设置 preview size public void setPreviewSize(int width, int height) { String v = Integer.toString(width) + "x" + Integer.toString(height); set(KEY_PREVIEW_SIZE, v); } // 4. 获取 preview size public Size getPreviewSize() { String pair = get(KEY_PREVIEW_SIZE); return strToSize(pair); } // 5. 设置缩略图大小 public void setJpegThumbnailSize(int width, int height) { set(KEY_JPEG_THUMBNAIL_WIDTH, width); set(KEY_JPEG_THUMBNAIL_HEIGHT, height); } ......
此外,高通自已也新增了一些 key
@ frameworks/base/core/java/android/hardware/Camera.java /* ### QC ADDED PARAMETER KEYS*/ private static final String KEY_QC_HFR_SIZE = "hfr-size"; private static final String KEY_QC_PREVIEW_FRAME_RATE_MODE = "preview-frame-rate-mode"; private static final String KEY_QC_PREVIEW_FRAME_RATE_AUTO_MODE = "frame-rate-auto"; private static final String KEY_QC_PREVIEW_FRAME_RATE_FIXED_MODE = "frame-rate-fixed"; private static final String KEY_QC_GPS_LATITUDE_REF = "gps-latitude-ref"; private static final String KEY_QC_GPS_LONGITUDE_REF = "gps-longitude-ref"; private static final String KEY_QC_GPS_ALTITUDE_REF = "gps-altitude-ref"; private static final String KEY_QC_GPS_STATUS = "gps-status"; private static final String KEY_QC_EXIF_DATETIME = "exif-datetime"; private static final String KEY_QC_TOUCH_AF_AEC = "touch-af-aec"; private static final String KEY_QC_TOUCH_INDEX_AEC = "touch-index-aec"; private static final String KEY_QC_TOUCH_INDEX_AF = "touch-index-af"; private static final String KEY_QC_MANUAL_FOCUS_POSITION = "manual-focus-position"; private static final String KEY_QC_MANUAL_FOCUS_POS_TYPE = "manual-focus-pos-type"; private static final String KEY_QC_SCENE_DETECT = "scene-detect"; private static final String KEY_QC_ISO_MODE = "iso"; private static final String KEY_QC_EXPOSURE_TIME = "exposure-time"; private static final String KEY_QC_MIN_EXPOSURE_TIME = "min-exposure-time"; private static final String KEY_QC_MAX_EXPOSURE_TIME = "max-exposure-time"; private static final String KEY_QC_LENSSHADE = "lensshade"; private static final String KEY_QC_HISTOGRAM = "histogram"; private static final String KEY_QC_SKIN_TONE_ENHANCEMENT = "skinToneEnhancement"; private static final String KEY_QC_AUTO_EXPOSURE = "auto-exposure"; private static final String KEY_QC_SHARPNESS = "sharpness"; private static final String KEY_QC_MAX_SHARPNESS = "max-sharpness"; private static final String KEY_QC_CONTRAST = "contrast"; private static final String KEY_QC_MAX_CONTRAST = "max-contrast"; private static final String KEY_QC_SATURATION = "saturation"; private static final String KEY_QC_MAX_SATURATION = "max-saturation"; private static final String KEY_QC_DENOISE = "denoise"; private static final String KEY_QC_CONTINUOUS_AF = "continuous-af"; private static final String KEY_QC_SELECTABLE_ZONE_AF = "selectable-zone-af"; private static final String KEY_QC_FACE_DETECTION = "face-detection"; private static final String KEY_QC_MEMORY_COLOR_ENHANCEMENT = "mce"; private static final String KEY_QC_REDEYE_REDUCTION = "redeye-reduction"; private static final String KEY_QC_ZSL = "zsl"; private static final String KEY_QC_CAMERA_MODE = "camera-mode"; private static final String KEY_QC_VIDEO_HIGH_FRAME_RATE = "video-hfr"; private static final String KEY_QC_VIDEO_HDR = "video-hdr"; private static final String KEY_QC_POWER_MODE = "power-mode"; private static final String KEY_QC_POWER_MODE_SUPPORTED = "power-mode-supported"; private static final String KEY_QC_WB_MANUAL_CCT = "wb-manual-cct"; private static final String KEY_QC_MIN_WB_CCT = "min-wb-cct"; private static final String KEY_QC_MAX_WB_CCT = "max-wb-cct"; private static final String KEY_QC_AUTO_HDR_ENABLE = "auto-hdr-enable"; private static final String KEY_QC_VIDEO_ROTATION = "video-rotation";
public String getSceneDetectMode() { return get(KEY_QC_SCENE_DETECT); } ......
getParameters
中,主要是new Parameters()
对象 用来保存 native_getParameters()
返回的参数。setParameters
中,如果正在预览,是不能动态修改preview size 的,所以在设置参数前会先检测preview size是否一致,接着调用 native_setParameters()
.params.flatten()
和 params.unflatten()
分别是将所有Camera 参数以;
的格式区分保存String中,以及,从String 解析所有参数。private native final void native_setParameters(String params); private native final String native_getParameters();
/** * Changes the settings for this Camera service. * * @param params the Parameters to use for this Camera service * @throws RuntimeException if any parameter is invalid or not supported. * @see #getParameters() */ public void setParameters(Parameters params) { // If using preview allocations, don't allow preview size changes if (mUsingPreviewAllocation) { Size newPreviewSize = params.getPreviewSize(); Size currentPreviewSize = getParameters().getPreviewSize(); if (newPreviewSize.width != currentPreviewSize.width || newPreviewSize.height != currentPreviewSize.height) { throw new IllegalStateException("Cannot change preview size" +" while a preview allocation is configured."); } } native_setParameters(params.flatten()); } /** * Returns the current settings for this Camera service. * If modifications are made to the returned Parameters, they must be passed * to {@link #setParameters(Camera.Parameters)} to take effect. * * @see #setParameters(Camera.Parameters) */ public Parameters getParameters() { Parameters p = new Parameters(); String s = native_getParameters(); p.unflatten(s); return p; }
native 层代码位于
@ frameworks/base/core/jni/android_hardware_Camera.cpp
static const JNINativeMethod camMethods[] = {
{ “native_setParameters”, “(Ljava/lang/String;)V”, (void )android_hardware_Camera_setParameters },
{ “native_getParameters”, “()Ljava/lang/String;”, (void )android_hardware_Camera_getParameters },
}
可知,对应的函数分别为: android_hardware_Camera_setParameters()
和 android_hardware_Camera_getParameters()
在 android_hardware_Camera_setParameters()
中:
在 android_hardware_Camera_getParameters
中,主要是调用 camera->getParameters()
。
static void android_hardware_Camera_setParameters(JNIEnv *env, jobject thiz, jstring params) { ALOGV("setParameters"); // 1. 获取 native 层 Camera 对象, 对应代码为 frameworks/av/camera/Camera.cpp sp<Camera> camera = get_native_camera(env, thiz, NULL);
// 2. 将JAVA 层 String 对象,保存在 jchar * str 中 const jchar* str = env->GetStringCritical(params, 0); String8 params8; if (params) { params8 = String8(reinterpret_cast<const char16_t*>(str), env->GetStringLength(params)); env->ReleaseStringCritical(params, str); } // 3. 调用camera->setParameters() if (camera->setParameters(params8) != NO_ERROR) { jniThrowRuntimeException(env, "setParameters failed"); return; }
}
static jstring android_hardware_Camera_getParameters(JNIEnv *env, jobject thiz)
{
ALOGV(“getParameters”);
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return 0;
String8 params8 = camera->getParameters();
if (params8.isEmpty()) {
jniThrowRuntimeException(env, "getParameters failed (empty parameters)");
return 0;
}
return env->NewStringUTF(params8.string());
}
此处的 mCamera
是 Camera Client 对象,
而 sp <::android::hardware::ICamera> c = mCamera
则是将 Camera Client 对象强制转换为 ICamera
对象,
然后,调用 ICamera
对象中的 setParameters()
.
frameworks/av/camera/Camera.cpp
// set preview/capture parameters - key/value pairs
status_t Camera::setParameters(const String8& params)
{
ALOGV("setParameters");
sp <::android::hardware::ICamera> c = mCamera;
return c->setParameters(params);
}
// get preview/capture parameters - key/value pairs
String8 Camera::getParameters() const
{
ALOGV(“getParameters”);
String8 params;
sp <::android::hardware::ICamera> c = mCamera;
params = mCamera->getParameters();
return params;
}
ICamera
类是个接口类,没有任何实现,其定义在 frameworks/av/include/camera/android/hardware/ICamera.h
因为 ICamera
中的 setParameters
和 getParameters
都是虚函数,
所以,
我们要去找ICamera
的子类,这些方法是在它们的子类中实现的。
namespace hardware {
class ICameraClient;
// ICamera 继承自 IInterface
class ICamera: public IInterface
{
public:
// set preview/capture parameters - key/value pairs
virtual status_t setParameters(const String8& params) = 0;
// get preview/capture parameters - key/value pairs
virtual String8 getParameters() const = 0;
}
// BnCamera 继承自 BnInterface ,也就是继承于 ICamera
class BnCamera: public BnInterface<ICamera>
{
public:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};
我们来看下 IInterface
和 BnInterface
各自的定义:
@frameworks/native/include/binder/IInterface.h
class IInterface : public virtual RefBase
{
public:
IInterface();
static sp<IBinder> asBinder(const IInterface*);
static sp<IBinder> asBinder(const sp<IInterface>&);
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
在前面代码中:class BnCamera: public BnInterface
相当于是 class BnCamera: public ICamera
。
也就是说 BnCamera
继承自 ICamera
。
我们再来看看 谁承继了 BnCamera
在 frameworks/av/services/camera/libcameraservice/CameraService.h
中看到
class CameraService
的内部类 class Client
继承自 BnCamera
。
class CameraService : public BinderService<CameraService>, public ::android::hardware::BnCameraService, public IBinder::DeathRecipient, public camera_module_callbacks_t { friend class BinderService<CameraService>; public: class Client; class BasicClient;
class Client : public hardware::BnCamera, public BasicClient { public: typedef hardware::ICameraClient TCamCallbacks; // ICamera interface (see ICamera for details) virtual status_t connect(const sp<hardware::ICameraClient>& client) = 0; virtual status_t startPreview() = 0; virtual void stopPreview() = 0; virtual status_t setParameters(const String8& params) = 0; virtual String8 getParameters() const = 0;
再来看下class CameraService
的内部类 class Client
被谁继承。
找下代码,发现如下:
但实际上,这个是 API1 的代码,我们现在 Camera 走的是 API2,所以CameraClient 这个继承关系是走不到的。
@ frameworks/av/services/camera/libcameraservice/api1/CameraClient.h
class CameraClient : public CameraService::Client
{
public:
// ICamera interface (see ICamera for details)
virtual status_t connect(const sp<hardware::ICameraClient>& client);
virtual status_t startPreview();
virtual void stopPreview();
virtual status_t setParameters(const String8& params);
virtual String8 getParameters() const;
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
virtual status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);
}
从frameworks/av/services/camera/libcameraservice/Android.mk
中可以看出,CameraClient.cpp 不会编译进来。
继续找代码,在 Camera2Client
中,frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h
看到,
class Camera2Client
继承自 CameraService::Client
class Camera2Client :
public Camera2ClientBase<CameraService::Client>
{
public:
virtual status_t connect(const sp<hardware::ICameraClient>& client);
virtual status_t startPreview();
virtual void stopPreview();
virtual status_t setParameters(const String8& params);
virtual String8 getParameters() const;
最终,setParameters()
函数经过 class ICamera ---> class BnCamera ---> class CameraService::Client ---> class Camera2Client
这一系列继承。
最终实现在 frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
中。
@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
status_t Camera2Client::setParameters(const String8& params) {
ALOGV("%s: Camera %d", FUNCTION, mCameraId);
Parameters::focusMode_t focusModeBefore = l.mParameters.focusMode;
res = l.mParameters.set(params);
Parameters::focusMode_t focusModeAfter = l.mParameters.focusMode;
if (l.mParameters.allowZslMode && focusModeAfter != focusModeBefore) {
mZslProcessor->clearZslQueue();
}
res = updateRequests(l.mParameters);
return res;
}
String8 Camera2Client::getParameters() const {
ATRACE_CALL();
ALOGV("%s: Camera %d", FUNCTION, mCameraId);
Mutex::Autolock icl(mBinderSerializationLock);
// The camera service can unconditionally get the parameters at all times
if (getCallingPid() != mServicePid && checkPid(FUNCTION) != OK) return String8();
SharedParameters::ReadLock l(mParameters);
return l.mParameters.get();
}
我们来看下 l.mParameters
实际上是 Class SharedParameters
对象的私有变量 Parameters mParameters;
,
定义如下
@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.h
// Current camera device configuration
camera2::SharedParameters mParameters;
struct Parameters {
// Validate and update camera parameters based on new settings
status_t set(const String8 ¶mString);
// Retrieve the current settings
String8 get() const;
};
class SharedParameters {
private:
Parameters mParameters;
mutable Mutex mLock;
};
因此,l.mParameters.set(params)
和 l.mParameters.get()
分别对应着前面的
Camera2Client::setParameters()
和 Camera2Client::getParameters()
。
l.mParameters.get()
具体实现如下:
@ frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp
String8 Parameters::get() const {
return paramsFlattened;
}
代码中,直接返回 paramsFlattened
,分别是在 Parameters::initialize() 和 Parameters::set() 时更新的。
@ frameworks/av/services/came ra/libcameraservice/api1/client2/Parameters.cpp
status_t Parameters::set(const String8& paramString) {
// 1. 根据上层传递下来的 Parameters 字符串,生成 CameraParameters2 对象
CameraParameters2 newParams(paramString);
=>
+ @ frameworks/av/include/camera/CameraParameters2.h
+ class CameraParameters2
+ {
+ public:
+ CameraParameters2(const String8 ¶ms) { unflatten(params); }
<=
// 2. 解析上层设置的参数,且检查参数的正确性
validatedParams.jpegRotation = newParams.getInt(CameraParameters::KEY_ROTATION);
.... 省略一大段代码
// AUTO_EXPOSURE_LOCK (always supported)
validatedParams.autoExposureLock = boolFromString( newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
// AUTO_WHITEBALANCE_LOCK (always supported)
validatedParams.autoWhiteBalanceLock = boolFromString(newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS), &validatedParams.meteringAreas);
// ZOOM
validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
// VIDEO_SIZE
newParams.getVideoSize(&validatedParams.videoWidth,&validatedParams.videoHeight);
// VIDEO_STABILIZATION
validatedParams.videoStabilization = boolFromString( newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
camera_metadata_ro_entry_t availableVideoStabilizationModes =
staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 0, 0, false);
/** Update internal parameters */
*this = validatedParams;
updateOverriddenJpegSize();
res = calculatePictureFovs(&horizFov, &vertFov);
newParams.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,horizFov);
newParams.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
ALOGV("Current still picture FOV: %f x %f deg", horizFov, vertFov);
// 3. 参数更新和检测成功后,重新生成字符串,更新在 paramsFlattened 中,及保存在 params 对象中。
// Need to flatten again in case of overrides
paramsFlattened = newParams.flatten();
params = newParams;
return OK;
}
BpCamera
@ frameworks/av/camera/ICamera.cpp class BpCamera: public BpInterface<ICamera> { public: // set preview/capture parameters - key/value pairs status_t setParameters(const String8& params) { ALOGV("setParameters"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeString8(params); remote()->transact(SET_PARAMETERS, data, &reply); return reply.readInt32(); }
// get preview/capture parameters - key/value pairs String8 getParameters() const { ALOGV("getParameters"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(GET_PARAMETERS, data, &reply); return reply.readString8(); }
BnCamera
@ frameworks/av/camera/ICamera.cpp
status_t BnCamera::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case SET_PARAMETERS: {
ALOGV(“SET_PARAMETERS”);
CHECK_INTERFACE(ICamera, data, reply);
String8 params(data.readString8());
reply->writeInt32(setParameters(params));
return NO_ERROR;
} break;
case GET_PARAMETERS: {
ALOGV(“GET_PARAMETERS”);
CHECK_INTERFACE(ICamera, data, reply);
reply->writeString8(getParameters());
return NO_ERROR;
} break;
}
}
在处理preview和录像 stream的线程mStreamingProcessor
中,
status_t Camera2Client::updateRequests(Parameters ¶ms) { status_t res; ALOGV("%s: Camera %d: state = %d", __FUNCTION__, getCameraId(), params.state);
res = mStreamingProcessor->incrementStreamingIds(); // 更新 preview 参数 res = mStreamingProcessor->updatePreviewRequest(params); ============> @ frameworks/av/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { sp<CameraDeviceBase> device = mDevice.promote(); // 如果当前 mBuffer==NULL if (mPreviewRequest.entryCount() == 0) { sp<Camera2Client> client = mClient.promote(); // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case. if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) { if (params.useZeroShutterLag() && !params.recordingHint) { res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, &mPreviewRequest); } else { res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW, &mPreviewRequest); } } } // 向 android.hardware.Camera 下发更新参数 @ frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp res = params.updateRequest(&mPreviewRequest); } <============ // 更新 Recording 参数 res = mStreamingProcessor->updateRecordingRequest(params); // 根椐参数判断是否要开始 Preview 还是 Recording if (params.state == Parameters::PREVIEW) { res = startPreviewL(params, true); } else if (params.state == Parameters::RECORD || params.state == Parameters::VIDEO_SNAPSHOT) { res = startRecordingL(params, true); } return res;
}
在 Parameters::updateRequest()
函数中,主要是调用 request->update()
方法来对hardware 层更新参数
@ frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp
status_t Parameters::updateRequest(CameraMetadata *request) const {
uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
res = request->update(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);
if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fastInfo.bestStillCaptureFpsRange, 2);
} else {
res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, previewFpsRange, 2);
}
uint8_t reqWbLock = autoWhiteBalanceLock ? ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
res = request->update(ANDROID_CONTROL_AWB_LOCK, &reqWbLock, 1);
res = request->update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibandingMode, 1);
uint8_t reqControlMode = ANDROID_CONTROL_MODE_AUTO;
if (enableFaceDetect || sceneModeActive) {
reqControlMode = ANDROID_CONTROL_MODE_USE_SCENE_MODE;
}
res = request->update(ANDROID_CONTROL_MODE, &reqControlMode, 1);
res = request->update(ANDROID_FLASH_MODE,&reqFlashMode, 1);
.........
}
request->update 定义在 frameworks/av/include/camera/CameraMetadata.h
中
class CameraMetadata: public Parcelable { public: /** Update metadata entry. Will create entry if it doesn't exist already, and * will reallocate the buffer if insufficient space exists. Overloaded for * the various types of valid data. */ status_t update(uint32_t tag, const uint8_t *data, size_t data_count); status_t update(uint32_t tag, const int32_t *data, size_t data_count); status_t update(uint32_t tag, const float *data, size_t data_count); status_t update(uint32_t tag, const int64_t *data, size_t data_count); status_t update(uint32_t tag, const double *data, size_t data_count); status_t update(uint32_t tag, const camera_metadata_rational_t *data, size_t data_count); status_t update(uint32_t tag, const String8 &string); status_t update(const camera_metadata_ro_entry &entry);
template<typename T> status_t update(uint32_t tag, Vector<T> data) { return update(tag, data.array(), data.size()); }
}
实际定义如下:
// frameworks/av/camera/CameraMetadata.cpp
status_t CameraMetadata::update(uint32_t tag,const int32_t *data, size_t data_count) {
return updateImpl(tag, (const void*)data, data_count);
}
待更新中。。。。。。。。。。。
《camera api1 和api2》
《Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互》
参考:
《【定制Android系统】Android O Camera(1)——简单梳理 Camera1 的 setParameters 通路.1》