Android Camera 1 使用 Parameters 保存相机的状态, APK下发的命令等信息。
- frameworks/av/services/camera/libcameraservice/api1/client2/Parameters.cpp
Android camera2 很重要的改进是采用 session 方式控制相机。
Camera 2 使用 camera metadata 保存相机的状态, APK下发的命令等信息。
相比而言, camera metadata 更复杂。
文件索引
framework
- frameworks/base/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
- frameworks/base/core/java/android/hardware/camera2/CameraMetadata.java
- frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
- frameworks/base/core/jni/android_hardware_camera2_CameraMetadata.cpp -- 编译出的库 system/lib/libcustom_jni.so
- frameworks/av/include/camera/CameraMetadata.h
- frameworks/av/camera/CameraMetadata.cpp
- frameworks/av/services/camera/libcameraservice/common/FrameProcessorBase.cpp
- frameworks/av/camera/aidl/android/hardware/camera2/impl/CameraMetadataNative.aidl
- frameworks/av/camera/CameraMetadata.cpp
- frameworks/av/camera/include/camera/CameraMetadata.h
hardware
- hardware\libhardware\modules\camera\3_4\capture_request.cpp
重点分析:
分析 JAVA 和 native 的交互, HAL 层暂不分析。
JAVA 和 native 的交互依赖以下两个文件:
- frameworks\base\core\jni\android_hardware_camera2_CameraMetadata.cpp
- frameworks\base\core\java\android\hardware\camera2\impl\CameraMetadataNative.java
分析代码可知:
android_hardware_camera2_CameraMetadata.cpp 中使用 metadata_ptr 维护 CameraMetadata
把 CameraMetadata 类转换成长整形数据(jlong)保存到 CameraMetadataNative.java
java 层维护 CameraMetadata , 加强了 APK 对 camera 的控制, 实现复杂相机场景。
java 保存 CameraMetadata 实例
创建 CameraMetadata 并转换成 jlong 型数据保存到 java 层, 实现 java 维护:
static jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) {ALOGV("%s", __FUNCTION__);return reinterpret_cast<jlong>(new CameraMetadata());
}
CPP 获取 java 维护的 CameraMetadata 实例
获取 CameraMetadata 实例后, 通过 cameraserverHAL 服务转发相机命令和数据到 camera设备:
status_t CameraMetadata_getNativeMetadata(JNIEnv* env, jobject thiz,/*out*/CameraMetadata* metadata) {if (!thiz) {ALOGE("%s: Invalid java metadata object.", __FUNCTION__);return BAD_VALUE;}if (!metadata) {ALOGE("%s: Invalid output metadata object.", __FUNCTION__);return BAD_VALUE;}CameraMetadata* nativePtr = reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz,fields.metadata_ptr));if (nativePtr == NULL) {ALOGE("%s: Invalid native pointer in java metadata object.", __FUNCTION__);return BAD_VALUE;}*metadata = *nativePtr;return OK;
}
核心代码使用关键字 reinterpret_cast 强制转换找到 CameraMetadata 实例:
CameraMetadata* nativePtr = reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz,fields.metadata_ptr));
通过上述两个函数实现 JAVA 维护 CameraMetadata , native 层使用 CameraMetadata 。