Android4.4之Camera2預覽流程(從APP到Driver)
阿新 • • 發佈:2019-01-28
1.APP呼叫
packages/apps/Camera2/src/com/android/camera/PhotoModule.java
private void startPreview() {
Log.v(TAG, "startPreview");
mCameraDevice.startPreviewAsync();
mFocusManager.onPreviewStarted();
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> 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 <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->startPreview();
}
服務端目錄:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
class BpCamera: public BpInterface<ICamera>
{
public:
BpCamera(const sp<IBinder>& impl)
: BpInterface<ICamera>(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 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<hw_module_t *>(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/usb/uvc/uvc_v4l2.c
const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open= uvc_v4l2_open,
.release = uvc_v4l2_release,
.unlocked_ioctl= uvc_v4l2_ioctl, //對應用層ioctl
}
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> 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 <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->startPreview();
}
6.frameworks/av/include/camera/ICamera.h
class ICamera: public IInterface
{
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
};
frameworks/av/camera/ICamera.cpp //代理端目錄
Binder呼叫,因為BpCamera、IInterface和BBinder都繼承與IBinder類,他們有共同一個父類。在BBinder實現代理端的程式碼,查詢IBinder定義或呼叫,看誰繼承他了,然後在此類裡找到startPreview()方法,就是在BBinder服務端實現的服務,與代理端對應。服務端目錄:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
class BpCamera: public BpInterface<ICamera>
{
public:
BpCamera(const sp<IBinder>& impl)
: BpInterface<ICamera>(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 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<hw_module_t *>(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/usb/uvc/uvc_v4l2.c
const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open= uvc_v4l2_open,
.release = uvc_v4l2_release,
.unlocked_ioctl= uvc_v4l2_ioctl, //對應用層ioctl
}
13.貼一張圖幫助理解