Android4.4之Camera2预览流程(从APP到Driver)
1.APP调用
packages/apps/Camera2/src/com/android/camera/PhotoModule.java
private void startPreview() {
Log.v(TAG, "startPreview");
mCameraDevice.startPreviewAsync();
mFocusManager.onPreviewStarted();
}
2.Java层
packages/apps/Camera/src/com/android/camera/CameraManager.java
public void startPreviewAsync() {
mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);//发消息:START_PREVIEW_ASYNC
}
public void handleMessage(final Message msg) {
try {
switch (msg.what) {
case START_PREVIEW_ASYNC:
mCamera.startPreview();
return; // no need to call mSig.open()
}
}
3.定义JNI层
frameworks/base/core/java/android/hardware/Camera.java
public native final void startPreview();
4.JNI层
frameworks/base/core/jni/android_hardware_Camera.cpp、
static JNINativeMethod camMethods[] = {
{
"startPreview", "()V", (void *)android_hardware_Camera_startPreview },
};
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
ALOGV("startPreview");
sp camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
if (camera->startPreview() != NO_ERROR) {
jniThrowRuntimeException(env, "startPreview failed");
return;
}
}
5.C++层
frameworks/av/camera/Camera.cpp
status_t Camera::startPreview()
{
ALOGV("startPreview");
sp c = mCamera;
if (c == 0) return NO_INIT;
return c->startPreview();
}
6.frameworks/av/camera/ICamera.cpp //代理端目录
Binder调用,因为BpCamera和BBinder都继承与IBinder类,在BBinder实现代理端的代码,查找IBinder定义或调用,看谁继承他了,然后在此类里找到startPreview()方法,就是在BBinder服务端实现的服务,与代理端对应。
服务端目录:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
class BpCamera: public BpInterface
{
public:
BpCamera(const sp& impl)
: BpInterface(impl)
{
}
// start preview mode, must call setPreviewTarget first
status_t startPreview()
{
ALOGV("startPreview");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(START_PREVIEW, data, &reply);//根据START_PREVIEW跳到对应的Case
return reply.readInt32();
}
};
对应START_PREVIEW的Case
IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
// ----------------------------------------------------------------------
status_t BnCamera::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case DISCONNECT: {
case START_PREVIEW: {
ALOGV("START_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startPreview());
return NO_ERROR;
} break;
}
7.frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp //服务端目录
<1> CAMERA_PREVIEW_MODE
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
<2>对应CAMERA_PREVIEW_MODE的Case
status_t CameraClient::startCameraMode(camera_mode mode) {
switch(mode) {
case CAMERA_PREVIEW_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
LOG1("mSurface is not set yet.");
// still able to start preview in this case.
}
return startPreviewMode();
}
<3>startPreviewMode()函数调用mHardware->startPreview();
status_t CameraClient::startPreviewMode() {
// if preview has been enabled, nothing needs to be done
if (mHardware->previewEnabled()) {
return NO_ERROR;
}
if (mPreviewWindow != 0) {
native_window_set_scaling_mode(mPreviewWindow.get(),
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
native_window_set_buffers_transform(mPreviewWindow.get(),
mOrientation);
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
return result;
}
8.frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
status_t startPreview()
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->start_preview)
return mDevice->ops->start_preview(mDevice);
return INVALID_OPERATION;
}
9.HAL头文件
<1>start_preview头文件位置
hardware/libhardware/include/hardware/camera.h
<2>结构体:camera_device mDevice;
typedef struct camera_device {
hw_device_t common;
camera_device_ops_t *ops;//ops
void *priv;
} camera_device_t;//mDevice
<3>结构体:camera_device_ops ops;
typedef struct camera_device_ops {
int (*start_preview)(struct camera_device *);
} camera_device_ops_t;
10.HAL层源码位置:
hardware/leadcore/libcamera/ComipCameraHWInterface.cpp
<1> extern "C" {
struct camera_module HAL_MODULE_INFO_SYM = {
common : {
tag : HARDWARE_MODULE_TAG,
module_api_version : CAMERA_MODULE_API_VERSION_1_0,//0x0100, add by zgs 2012.12.28 ,to choose HAL version
hal_api_version : HARDWARE_HAL_API_VERSION,//0x00
id : CAMERA_HARDWARE_MODULE_ID,//硬件标识的ID
name : "Leadcore camera HAL",
author : "Leadcore Corporation",
methods : &camera_module_methods,//HAL操作方法集
dso: NULL,
reserved: {0},
},
get_number_of_cameras : HAL_getNumberOfCameras,
get_camera_info : HAL_getCameraInfo,
set_callbacks : HAL_setCallbacks,
get_vendor_tag_ops : HAL_getVendorTagOps,
reserved : {0}
};
}
<2>HAL操作方法集
static hw_module_methods_t camera_module_methods = {
open : HAL_camera_device_open
};
<3>HAL_camera_device_open()函数
static int HAL_camera_device_open(const struct hw_module_t* module,
const char *id,
struct hw_device_t** device)
{
LOG2("HAL_camera_device_open");
int cameraId = atoi(id);
if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) {
ALOGE("invalid camera ID %s", id);
return -EINVAL;
}
if (g_cam_device) {
if (obj(g_cam_device)->getCameraId() == cameraId) {
LOG2("returning existing camera ID %s", id);
goto done;
} else {
ALOGE("cannot open camera %d. camera %d is already running!",
cameraId, obj(g_cam_device)->getCameraId());
return -ENOSYS;
}
}
g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t));
if (!g_cam_device)
return -ENOMEM;
g_cam_device->common.tag = HARDWARE_DEVICE_TAG;
g_cam_device->common.version = 1;
g_cam_device->common.module = const_cast(module);
g_cam_device->common.close = HAL_camera_device_close;
g_cam_device->ops = &camera_device_ops; //HAL功能操作集
g_cam_device->priv = new CameraHardwareComip(cameraId, g_cam_device);
done:
*device = (hw_device_t *)g_cam_device;
LOG2("opened camera %s (%p)", id, *device);
return 0;
}
<4>camera_device_ops();//HAL功能操作集函数
#define SET_METHOD(m) m : HAL_camera_device_##m
static camera_device_ops_t camera_device_ops = {
SET_METHOD(stop_preview),//SET_METHOD()函数的功能即,把start_preview()变为HAL_camera_device_start_preview()的功能。
};
<5>把start_preview()变为HAL_camera_device_start_preview()函数
static int HAL_camera_device_start_preview(struct camera_device *dev)
{
LOG2("HAL_camera_device_start_preview");
return obj(dev)->startPreview();
}
<6>startPreview()函数
status_t CameraHardwareComip::startPreview()
{
int ret = startPreviewInternal();
}
<7>startPreviewInternal()函数
status_t CameraHardwareComip::startPreviewInternal()
{
ret = mComipCamera->startPreview();
}
11.HAL调用V4L2操作
<1>startPreview()函数调用
hardware/leadcore/libcamera/ComipCamera.cpp
int ComipCamera::startPreview(void)
{
int ret = v4l2_streamon(m_cam_fd, m_preview_buf_type);
}
<2>v4l2_streamon()函数
static int v4l2_streamon(int fp, enum v4l2_buf_type type)
{
ret = ioctl(fp, VIDIOC_STREAMON, &type);
}
12.Kernel层调用V4L2驱动
kernel/linux-3.10/drivers/media/v4l2-core/v4l2-dev.c
static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
if(vdev->fops->unlocked_ioctl) {
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
}