CAMERA的数据流总体涉及到几个层面:1)APP层 , 2)Framework层,3)HAL层,4)驱动层。下面主要分析2和3之间的数据流。安卓引入HAL3后,采用一个新的通讯方式HIDL,和以前的AIDL相似,都是用于进程间通信,只是HIDL是用硬件框架的通讯。Framework层正是使用这种新的方式与HAL层进行通信的。
- 1) Framework层的Camera3Device.cpp中有个camera3_callback_ops,有2个方法,HAL层数据通过它的2个方法回调回来。
typedef struct camera3_callback_ops {
void (*process_capture_result)(const struct camera3_callback_ops *, const camera3_capture_result_t *result);
void (*notify)(const struct camera3_callback_ops *, const camera3_notify_msg_t *msg);
} camera3_callback_ops_t;
- 2) QCamera3HardwareInterface::initialize中传入camera3_callback_ops
QCamera3HWI.cpp
int QCamera3HardwareInterface::initialize(
const struct camera3_callback_ops *callback_ops)
{
ATRACE_CALL();
int rc;
......
rc = initParameters();
if (rc < 0) {
LOGE("initParamters failed %d", rc);
goto err1;
}
mCallbackOps = callback_ops;
在QCamera3HardwareInterface::orchestrateResult 和 void QCamera3HardwareInterface::orchestrateNotify会用到上面的mCallbackOps ,后面的QCamera3Channel最终会将得到的数据通过QCamera3HardwareInterface::captureResultCb回调到这2个函数。
void QCamera3HardwareInterface::orchestrateResult(
camera3_capture_result_t *result)
{
uint32_t frameworkFrameNumber;
int32_t rc = _orchestrationDb.getFrameworkFrameNumber(result->frame_number,
frameworkFrameNumber);
if (rc != NO_ERROR) {
LOGE("Cannot find translated frameworkFrameNumber");
assert(0);
} else {
if (frameworkFrameNumber == EMPTY_FRAMEWORK_FRAME_NUMBER) {
LOGD("CAM_DEBUG Internal Request drop the result");
} else {
result->frame_number = frameworkFrameNumber;
mCallbackOps->process_capture_result(mCallbackOps, result);
}
}
}
void QCamera3HardwareInterface::orchestrateNotify(camera3_notify_msg_t *notify_msg)
{
uint32_t frameworkFrameNumber;
uint32_t internalFrameNumber = notify_msg->message.shutter.frame_number;
int32_t rc = _orchestrationDb.getFrameworkFrameNumber(internalFrameNumber,
frameworkFrameNumber);
if (rc != NO_ERROR) {
LOGE("Cannot find translated frameworkFrameNumber");
assert(0);
} else {
if (frameworkFrameNumber == EMPTY_FRAMEWORK_FRAME_NUMBER) {
LOGE("CAM_DEBUG Internal Request drop the notifyCb");
} else {
notify_msg->message.shutter.frame_number = frameworkFrameNumber;
mCallbackOps->notify(mCallbackOps, notify_msg);
}
}
}
- 3) 在QCamera3HWI.cpp中会建立QCamera3Channel,QCamera3Channel的构造函数将QCamera3HardwareInterface::captureResultCb做为参数传入Channel。
QCamera3Channel.cpp
QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
cam_feature_mask_t postprocess_mask,
void *userData, uint32_t numBuffers)
- 4) QCamera3Channel::addStream 中会调用QCamera3Stream::init方法,将QCamera3Channel::streamCbRoutine传入QCamera3Stream中。
QCamera3Channel.cpp
rc = pStream->init(streamType, streamFormat, streamDim, streamRotation,
NULL, minStreamBufNum, postprocessMask, isType, batchSize,
streamCbRoutine, this);
- 5) QCamera3Stream::init 中有个stream_config.stream_cb = dataNotifyCB; 将这个回调注册到底层的mm-camera-interface操作接 ,这样MM层接收到数据后,就可以回调到stream里
int32_t QCamera3Stream::init(
...
stream_config.stream_cb = dataNotifyCB;
rc = mCamOps->config_stream(mCamHandle,
mChannelHandle, mHandle, &stream_config);
至此,数据回调流程基本完成,还剩下从驱动层读取数据过程。
总体流程:mm-camera-interface-->stream ---> channel ---> HWI ---> framework