概况:
kernel层 vb2_queue 队列操作
下图是给上层的回调流程,这里以视频预览帧数据为例
- CameraClient作为上层和HAl层的中转站,持有HAl层的引用(以后简称mHardware)和Camera客户端的引用(以后简称mRemoteCallback),在初始化的时候将本类的函数指针实现全部传给Hal层。
- 所以当AppMsgNotifier.cpp 向上发送通知的时候,就可找到该函数指针发起调用mDataCb
void AppMsgNotifier::callbackThread()
{
bool loop = true;
Message_cam msg;
int index,err = 0;
camera_memory_t *frame = NULL;
LOG_FUNCTION_NAME
while (loop) {
memset(&msg,0,sizeof(msg));
callbackThreadCommandQ.get(&msg);
switch (msg.command)
{
case CameraAppCallbackThread::CMD_MSG_PREVIEW_FRAME:
{
LOG2("datacb: send preview frame (CAMERA_MSG_PREVIEW_FRAME).");
frame = (camera_memory_t*)msg.arg2;
if (mMsgTypeEnabled & CAMERA_MSG_PREVIEW_FRAME)
// mDataCb 就是中间层传来的函数
mDataCb(CAMERA_MSG_PREVIEW_FRAME, frame, 0,NULL,mCallbackCookie);
//release buffer
frame->release(frame);
}
break;
/**
* ........................................
*/
}
3.回到CameraClient里,使用ICameraClient回调至上层。
// preview callback - frame buffer update
void CameraClient::handlePreviewData(int32_t msgType,
const sp<IMemory>& mem,
camera_frame_metadata_t *metadata) {
// 拿到远程客户端的引用
sp<hardware::ICameraClient> c = mRemoteCallback;
// 最后都会调用 c->dataCallback();
if (c != 0) {
ALOGD("--- CameraClient c != 0");
// Is the received frame copied out or not?
if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
LOG2("frame is copied");
copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
} else {
LOG2("frame is forwarded");
mLock.unlock();
c->dataCallback(msgType, mem, metadata);
}
} else {
mLock.unlock();
}
}
关键是mRemoteCallback就是 Camera.cpp 的创建的时候何时包装成一个ICameraClient对象,
在CameraService.cpp的makeClient函数里,观察第二个参数就能得到答案
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
// Default path: HAL version is unspecified by caller, create CameraClient
// based on device version reported by the HAL.
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new CameraClient(cameraService, tmp, packageName, cameraId, facing,
clientPid, clientUid, getpid(), legacyMode);
} else { // Camera2 API route
ALOGW("Camera using old HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
"Camera device \"%d\" HAL version %d does not support camera2 API",
cameraId, deviceVersion);
}
break;
}
4.在Camera里直接看对应的地方,这个listener 就是JNI层的指针
// callback from camera service when frame or image is ready
void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata)
{
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
listener = mListener;
}
if (listener != NULL) {
listener->postData(msgType, dataPtr, metadata);
}
}
5.最终进入JNI层的 postData,通知JAVA层帧数据发生的改变
void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)
{
// 用反射直接调用JAVA层的静态方法
env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
mCameraJObjectWeak, msgType, 0, 0, obj);
if (obj) {
env->DeleteLocalRef(obj);
}
}