由之前的章节可知,Camera.cpp中的mCamera对象实际上是BpCamera的实例,因此,Camera类的startPreview()函数会调用
BpCamera的startPreview()函数,如下:
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);
return reply.readInt32();
}
省略...
};
其中remote()的值是上述interface_cast()函数注入的IBinder对象,它实际上是由MediaServer进程通过ipc传过来的
CameraService::Client对象(这点我们会在后续章节中论证),而CameraService::Client又是BnCamera的派生类,因此,remote()->transact()函数
实际上会调用到BnCamera的onTransact()函数中.
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;
省略...
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
CameraClient是CameraServcie::Client的派生类,CameraService::Client是BnCamera的实现类,即startPreview()函数在CameraClient中定义.
/ start preview mode
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
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();
case CAMERA_RECORDING_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
status_t CameraClient::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// 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;
}
mHardware是CameraHardwareInterface对象,因此下一步会调用CameraHardwareInterface的startPreview()函数:
/**
* Start preview mode.
*/
status_t startPreview()
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->start_preview)
return mDevice->ops->start_preview(mDevice);
return INVALID_OPERATION;
}
mDevice是camera_device_t类型的指针
typedef struct camera_device {
/**
* camera_device.common.version must be in the range
* HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is
* recommended.
*/
hw_device_t common;
camera_device_ops_t *ops;
void *priv;
} camera_device_t;
而mDevice->ops是camera_device_ops_t类型的指针
typedef struct camera_device_ops {
省略...
/**
* Start preview mode.
*/
int (*start_preview)(struct camera_device *);
省略...
} camera_device_ops_t;
camera_device_t指针和camera_device_ops_t又是在哪初始化的呢?
这里我们以lge的mako平台为例进行分析,mako平台也是使用高通的芯片,先看看hal层的相关实现:
在QualcommCamera.cpp中,
camera_device_ops_t camera_ops = {
省略...
start_preview: android::start_preview,
stop_preview: android::stop_preview,
省略...
};
extern "C" int camera_device_open(
const struct hw_module_t* module, const char* id,
struct hw_device_t** hw_device)
{
省略...
if(module && id && hw_device) {
省略...
if (!strcmp(module->name, camera_common.name)) {
省略...
if (camHal->hardware && camHal->hardware->isCameraReady()) {
camHal->cameraId = cameraId;
device = &camHal->hw_dev;
device->common.close = close_camera_device;
device->ops = &camera_ops;
device->priv = (void *)camHal;
rc = 0;
} else {
省略...
}
}
}
/* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */
*hw_device = (hw_device_t*)&device->common;
LOGE("%s: end rc %d", __func__, rc);
return rc;
}
static hw_module_methods_t camera_module_methods = {
open: camera_device_open,
};
static hw_module_t camera_common = {
tag: HARDWARE_MODULE_TAG,
version_major: 0,
version_minor: 01,
id: CAMERA_HARDWARE_MODULE_ID,
name: "Qcamera",
author:"Qcom",
methods: &camera_module_methods,
dso: NULL,
//reserved[0]: 0,
};
camera_module_t HAL_MODULE_INFO_SYM = {
common: camera_common,
get_number_of_cameras: get_number_of_cameras,
get_camera_info: get_camera_info,
};
从上诉代码可得知,camera_device_open()函数在hal层camera模块初始化的时候会被调用,CameraHardwareInterface中的
mDevice和mDevice->ops就是在这时候初始化的.
好,我们回到QualcommCamera.cpp中继续看start_preview()函数:
int start_preview(struct camera_device * device)
{
ALOGV("Q%s: E", __func__);
int rc = -1;
QualcommCameraHardware * hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->startPreview( );
}
ALOGV("Q%s: X", __func__);
return rc;
}
status_t QualcommCameraHardware::startPreview()
{
status_t result;
ALOGV("startPreview E");
Mutex::Autolock l(&mLock);
if( mPreviewWindow == NULL) {
/* startPreview has been called before setting the preview
* window. Start the camera with initial buffers because the
* CameraService expects the preview to be enabled while
* setting a valid preview window */
ALOGV(" %s : Starting preview with initial buffers ", __FUNCTION__);
result = startInitialPreview();
} else {
/* startPreview has been issued after a valid preview window
* is set. Get the preview buffers from gralloc and start
* preview normally */
ALOGV(" %s : Starting normal preview ", __FUNCTION__);
result = getBuffersAndStartPreview();
}
ALOGV("startPreview X");
return result;
}
status_t QualcommCameraHardware::getBuffersAndStartPreview() {
省略...
mFrameThreadWaitLock.lock();
while (mFrameThreadRunning) {
ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
mFrameThreadWait.wait(mFrameThreadWaitLock);
ALOGV("%s: old frame thread completed.",__FUNCTION__);
}
mFrameThreadWaitLock.unlock();
省略...
//Starting preview now as the preview buffers are allocated
// if(!mPreviewInitialized && !mCameraRunning) { // TODO just for testing
ALOGI("setPreviewWindow: Starting preview after buffer allocation");
startPreviewInternal();
// }
ALOGV(" %s : X ",__FUNCTION__);
return NO_ERROR;
}
status_t QualcommCameraHardware::startPreviewInternal()
{
省略...
if (!mPreviewInitialized) {
mLastQueuedFrame = NULL;
mPreviewInitialized = initPreview();
if (!mPreviewInitialized) {
ALOGE("startPreview X initPreview failed. Not starting preview.");
mPreviewBusyQueue.deinit();
return UNKNOWN_ERROR;
}
}
省略...
}
bool QualcommCameraHardware::initPreview()
{
省略...
// See comments in deinitPreview() for why we have to wait for the frame
// thread here, and why we can't use pthread_join().
mFrameThreadWaitLock.lock();
while (mFrameThreadRunning) {
mFrameThreadWait.wait(mFrameThreadWaitLock);
}
mFrameThreadWaitLock.unlock();
省略...
if (ret) {
if(mIs3DModeOn != true) {
省略...
mPreviewThreadWaitLock.lock();
pthread_attr_t pattr;
pthread_attr_init(&pattr);
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
mPreviewThreadRunning = !pthread_create(&mPreviewThread,
&pattr,
preview_thread,
(void*)NULL);
ret = mPreviewThreadRunning;
mPreviewThreadWaitLock.unlock();
省略...
}
mFrameThreadWaitLock.lock();
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
省略...
mFrameThreadRunning = !pthread_create(&mFrameThread,
&attr,
frame_thread,
&camframeParams);
ret = mFrameThreadRunning;
mFrameThreadWaitLock.unlock();
LINK_wait_cam_frame_thread_ready();
}
mFirstFrame = true;
ALOGV("initPreview X: %d", ret);
return ret;
}
BpCamera的startPreview()函数,如下:
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);
return reply.readInt32();
}
省略...
};
其中remote()的值是上述interface_cast()函数注入的IBinder对象,它实际上是由MediaServer进程通过ipc传过来的
CameraService::Client对象(这点我们会在后续章节中论证),而CameraService::Client又是BnCamera的派生类,因此,remote()->transact()函数
实际上会调用到BnCamera的onTransact()函数中.
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;
省略...
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
CameraClient是CameraServcie::Client的派生类,CameraService::Client是BnCamera的实现类,即startPreview()函数在CameraClient中定义.
/ start preview mode
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
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();
case CAMERA_RECORDING_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
status_t CameraClient::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// 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;
}
mHardware是CameraHardwareInterface对象,因此下一步会调用CameraHardwareInterface的startPreview()函数:
/**
* Start preview mode.
*/
status_t startPreview()
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->start_preview)
return mDevice->ops->start_preview(mDevice);
return INVALID_OPERATION;
}
mDevice是camera_device_t类型的指针
typedef struct camera_device {
/**
* camera_device.common.version must be in the range
* HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is
* recommended.
*/
hw_device_t common;
camera_device_ops_t *ops;
void *priv;
} camera_device_t;
而mDevice->ops是camera_device_ops_t类型的指针
typedef struct camera_device_ops {
省略...
/**
* Start preview mode.
*/
int (*start_preview)(struct camera_device *);
省略...
} camera_device_ops_t;
camera_device_t指针和camera_device_ops_t又是在哪初始化的呢?
这里我们以lge的mako平台为例进行分析,mako平台也是使用高通的芯片,先看看hal层的相关实现:
在QualcommCamera.cpp中,
camera_device_ops_t camera_ops = {
省略...
start_preview: android::start_preview,
stop_preview: android::stop_preview,
省略...
};
extern "C" int camera_device_open(
const struct hw_module_t* module, const char* id,
struct hw_device_t** hw_device)
{
省略...
if(module && id && hw_device) {
省略...
if (!strcmp(module->name, camera_common.name)) {
省略...
if (camHal->hardware && camHal->hardware->isCameraReady()) {
camHal->cameraId = cameraId;
device = &camHal->hw_dev;
device->common.close = close_camera_device;
device->ops = &camera_ops;
device->priv = (void *)camHal;
rc = 0;
} else {
省略...
}
}
}
/* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */
*hw_device = (hw_device_t*)&device->common;
LOGE("%s: end rc %d", __func__, rc);
return rc;
}
static hw_module_methods_t camera_module_methods = {
open: camera_device_open,
};
static hw_module_t camera_common = {
tag: HARDWARE_MODULE_TAG,
version_major: 0,
version_minor: 01,
id: CAMERA_HARDWARE_MODULE_ID,
name: "Qcamera",
author:"Qcom",
methods: &camera_module_methods,
dso: NULL,
//reserved[0]: 0,
};
camera_module_t HAL_MODULE_INFO_SYM = {
common: camera_common,
get_number_of_cameras: get_number_of_cameras,
get_camera_info: get_camera_info,
};
从上诉代码可得知,camera_device_open()函数在hal层camera模块初始化的时候会被调用,CameraHardwareInterface中的
mDevice和mDevice->ops就是在这时候初始化的.
好,我们回到QualcommCamera.cpp中继续看start_preview()函数:
int start_preview(struct camera_device * device)
{
ALOGV("Q%s: E", __func__);
int rc = -1;
QualcommCameraHardware * hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->startPreview( );
}
ALOGV("Q%s: X", __func__);
return rc;
}
status_t QualcommCameraHardware::startPreview()
{
status_t result;
ALOGV("startPreview E");
Mutex::Autolock l(&mLock);
if( mPreviewWindow == NULL) {
/* startPreview has been called before setting the preview
* window. Start the camera with initial buffers because the
* CameraService expects the preview to be enabled while
* setting a valid preview window */
ALOGV(" %s : Starting preview with initial buffers ", __FUNCTION__);
result = startInitialPreview();
} else {
/* startPreview has been issued after a valid preview window
* is set. Get the preview buffers from gralloc and start
* preview normally */
ALOGV(" %s : Starting normal preview ", __FUNCTION__);
result = getBuffersAndStartPreview();
}
ALOGV("startPreview X");
return result;
}
status_t QualcommCameraHardware::getBuffersAndStartPreview() {
省略...
mFrameThreadWaitLock.lock();
while (mFrameThreadRunning) {
ALOGV("%s: waiting for old frame thread to complete.", __FUNCTION__);
mFrameThreadWait.wait(mFrameThreadWaitLock);
ALOGV("%s: old frame thread completed.",__FUNCTION__);
}
mFrameThreadWaitLock.unlock();
省略...
//Starting preview now as the preview buffers are allocated
// if(!mPreviewInitialized && !mCameraRunning) { // TODO just for testing
ALOGI("setPreviewWindow: Starting preview after buffer allocation");
startPreviewInternal();
// }
ALOGV(" %s : X ",__FUNCTION__);
return NO_ERROR;
}
status_t QualcommCameraHardware::startPreviewInternal()
{
省略...
if (!mPreviewInitialized) {
mLastQueuedFrame = NULL;
mPreviewInitialized = initPreview();
if (!mPreviewInitialized) {
ALOGE("startPreview X initPreview failed. Not starting preview.");
mPreviewBusyQueue.deinit();
return UNKNOWN_ERROR;
}
}
省略...
}
bool QualcommCameraHardware::initPreview()
{
省略...
// See comments in deinitPreview() for why we have to wait for the frame
// thread here, and why we can't use pthread_join().
mFrameThreadWaitLock.lock();
while (mFrameThreadRunning) {
mFrameThreadWait.wait(mFrameThreadWaitLock);
}
mFrameThreadWaitLock.unlock();
省略...
if (ret) {
if(mIs3DModeOn != true) {
省略...
mPreviewThreadWaitLock.lock();
pthread_attr_t pattr;
pthread_attr_init(&pattr);
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
mPreviewThreadRunning = !pthread_create(&mPreviewThread,
&pattr,
preview_thread,
(void*)NULL);
ret = mPreviewThreadRunning;
mPreviewThreadWaitLock.unlock();
省略...
}
mFrameThreadWaitLock.lock();
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
省略...
mFrameThreadRunning = !pthread_create(&mFrameThread,
&attr,
frame_thread,
&camframeParams);
ret = mFrameThreadRunning;
mFrameThreadWaitLock.unlock();
LINK_wait_cam_frame_thread_ready();
}
mFirstFrame = true;
ALOGV("initPreview X: %d", ret);
return ret;
}