AndroidO Camera 分析(一): (API 2)openCamera 流程_but no looper exists in the calling thread

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

        } else { // Camera2 API route
            /\* 我们只分析 Camera2 \*/

            sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                    static\_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
            /\*

* 这个很重要,new CameraDeviceClient()
* 接着分析 CameraDeviceClient() 构造函数
*/
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
}
break;
default:

    }
} else {
    ......
}
return Status::ok();

}

/* CameraDeviceClient.cpp */
CameraDeviceClient::CameraDeviceClient(const sp& cameraService,
const sphardware::camera2::ICameraDeviceCallbacks& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
/* 接着分析 */
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0),
mPrivilegedClient(false) {

char value[PROPERTY_VALUE_MAX];
property_get("persist.camera.privapp.list", value, "");
String16 packagelist(value);
if (packagelist.contains(clientPackageName.string())) {
    mPrivilegedClient = true;
}

ATRACE_CALL();
ALOGI("CameraDeviceClient %s: Opened", cameraId.string());

}

/* Camera2ClientBase.cpp */
template
Camera2ClientBase::Camera2ClientBase(
const sp& cameraService,
const sp& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false)
{
ALOGI(“Camera %s: Opened. Client: %s (PID %d, UID %d)”, cameraId.string(),
String8(clientPackageName).string(), clientPid, clientUid);

mInitialClientPid = clientPid;
/\* 这个对象很重要 \*/
mDevice = new Camera3Device(cameraId);
LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");

}

/* CameraDeviceClient.cpp */
status_t CameraDeviceClient::initialize(sp manager) {
return initializeImpl(manager);
}

/* TProviderPtr = CameraProviderManager */
template
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
ATRACE_CALL();
status_t res;
/* 接着分析 */
res = Camera2ClientBase::initialize(providerPtr);
if (res != OK) {
return res;
}

String8 threadName;
/\* 处理图像帧的实例 \*/
mFrameProcessor = new FrameProcessorBase(mDevice);
threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
/\* 进入一个线程循环处理图像帧 \*/
mFrameProcessor->run(threadName.string());

mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
                                  FRAME_PROCESSOR_LISTENER_MAX_ID,
                                  /\*listener\*/this,
                                  /\*sendPartials\*/true);

return OK;

}

template
status_t Camera2ClientBase::initialize(sp manager) {
/* 接着分析 */
return initializeImpl(manager);
}

template
template
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr) {

/\*

* mDevice 就是 Camera3Device 对象
* 所以就是调用 Camera3Device::initialize()
*/
res = mDevice->initialize(providerPtr);

wp<CameraDeviceBase::NotificationListener> weakThis(this);
res = mDevice->setNotifyCallback(weakThis);

return OK;

}

/* Camera3Device.cpp */
status_t Camera3Device::initialize(sp manager) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);

sp<ICameraDeviceSession> session;
ATRACE_BEGIN("CameraHal::openSession");
/\*

* manager 就是 CameraProviderManager 对象
* 所以就是调用 CameraProviderManager::openSession()
*/
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
ATRACE_END();

res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);

std::shared\_ptr<RequestMetadataQueue> queue;
auto requestQueueRet = session->getCaptureRequestMetadataQueue(
    [&queue](const auto& descriptor) {
        queue = std::make_shared<RequestMetadataQueue>(descriptor);
        if (!queue->isValid() || queue->availableToWrite() <= 0) {
            ALOGE("HAL returns empty request metadata fmq, not use it");
            queue = nullptr;
            // don't use the queue onwards.
        }
    });

std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
auto resultQueueRet = session->getCaptureResultMetadataQueue(
    [&resQueue](const auto& descriptor) {
        resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
        if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
            ALOGE("HAL returns empty result metadata fmq, not use it");
            resQueue = nullptr;
            // Don't use the resQueue onwards.
        }
    });


mInterface = new HalInterface(session, queue);
std::string providerType;
mVendorTagId = manager->getProviderTagIdLocked(mId.string());
/\* 这个函数里面会启动请求队列线程, 后面分析 \*/
return initializeCommonLocked();

}

/* CameraProviderManager.cpp */
status_t CameraProviderManager::openSession(const std::string &id,
const sphardware::camera::device::V3_2::ICameraDeviceCallback& callback,
/*out*/
sphardware::camera::device::V3_2::ICameraDeviceSession *session) {

std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
        /\*minVersion\*/ {3,0}, /\*maxVersion\*/ {4,0});

auto *deviceInfo3 = static\_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);

Status status;
hardware::Return<void> ret;
/\*

* mInterface 它实际上是 CameraDevice 对象
* 所以就是调用 CameraDevice::open()
*/
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const spdevice::V3_2::ICameraDeviceSession& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
return mapToStatusT(status);
}

/* CameraDevice.cpp */
Return CameraDevice::open(const sp& callback, open_cb _hidl_cb) {
Status status = initStatus();
sp session = nullptr;

    /\*\* Open HAL device \*/
    status_t res;
    camera3_device_t *device;

    ATRACE_BEGIN("camera3->open");
    /\*

* mModule 是 CameraModule 对象
* 所以调用 CameraModule::open()
*这里最后会调用 HAL 层的 open() 函数, 后面分析
*/
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();

    struct camera_info info;
    res = mModule->getCameraInfo(mCameraIdInt, &info);

    session = createSession(
            device, info.static_camera_characteristics, callback);

    mSession = session;

    mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();

}

/* CameraModule.cpp */
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN(“camera_module->open”);
/*
* 这里的 mModule 是 hw_get_module 得到的,注意别被名字混淆了
* 最终会调用 HAL 层 open() 得到 device
*/
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}


##### 写到这里发现实在有太多的细节没有办法一一的介绍到,下面我会放上我分析代码的笔记,感兴趣的可以看看


### 3 笔记


#### 3.1 《openCamera 流程》



《openCamera 流程》

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
openCamera()
—>openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);
—>handler = new Handler();
—>openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
—>getCameraCharacteristics(cameraId); //获得camera的一些特征
—>ICameraService cameraService = CameraManagerGlobal.get().getCameraService(); //获得 CameraService binder 服务。参考《CameraService 守护进程分析》
—>CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId); //通过binder调用到 CameraService.cpp 的getCameraCharacteristics函数
—>characteristics = new CameraCharacteristics(info); //构造特征
—>deviceImpl = new android.hardware.camera2.impl.CameraDeviceImpl(cameraId, callback, handler, characteristics, mContext.getApplicationInfo().targetSdkVersion);
—>mCameraId = cameraId;
—>mDeviceCallback = callback; //在 mCallOnOpened.run()中用到
—>mDeviceHandler = handler; //在 setRemoteDevice 中用到
—>mCharacteristics = characteristics;
—>ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks(); //获得回调
—>return mCallbacks = new CameraDeviceCallbacks();
—>ICameraService cameraService = CameraManagerGlobal.get().getCameraService(); //获得 CameraService binder 服务。参考《CameraService 守护进程分析》
—>ICameraDeviceUser cameraUser = cameraService.connectDevice(callbacks, cameraId, mContext.getOpPackageName(), uid); //通过binder调用到 CameraService.cpp 的connectDevice函数
—>connectHelper(…)
—>makeClient(&client, …)
—>*client = new CameraDeviceClient(…)
—>Camera2ClientBase(…)
—>mDevice = new Camera3Device(cameraId);
—>client->initialize(mCameraProviderManager); // mCameraProviderManager 很关键,在CameraService::enumerateProviders()中设置
—>CameraDeviceClient::initialize()
—>initializeImpl(manager);
—>Camera2ClientBase::initialize(providerPtr);
—>initializeImpl(manager);
—>mDevice->initialize(providerPtr); //就是调用 Camera3Device::initialize()
—>manager->openSession(mId.string(), this,/*out*/ &session); // manager 的 类型是 class CameraProviderManager, this = Camera3Device 对象
—>CameraProviderManager::openSession(id, callback, session)
—>auto deviceInfo = findDeviceInfoLocked(id, {3,0}, {4,0});
—>for (auto& provider : mProviders) //轮循 mProviders, 这个很关键,看下面 mProviders 相关
—>for (auto& deviceInfo : provider->mDevices) //mDevices 在 addDevice 中设置
—>return deviceInfo.get();
—>deviceInfo3->mInterface->open(callback, …)//mInterface 它实际上是 CameraDevice 对象,参考下面module 与 CameraDevice 相关
—>CameraDevice::open() //V3_2::implementation::CameraDevice
—>mModule->open(mCameraId.c_str(), reinterpret_cast<hw_device_t**>(&device)); //调用hal的open函数,得到 device 参考《hal 层分析》
—>mModule->getCameraInfo(mCameraIdInt, &info); //调用hal的get_camera_info函数
—>session = createSession(device, info.static_camera_characteristics, callback);
—>new CameraDeviceSession(device, deviceInfo, callback); //注意 CameraDeviceSession::processCaptureRequest() 这个函数。device 由hal层的open()得到
—>mDevice(device)
—>mResultBatcher(callback) // mResultBatcher 在FrameProcessorBase中会使用, callback = Camera3Device 对象
—>mSession = session;
—>_hidl_cb(status, session->getInterface()); //这个回调函数在deviceInfo3->mInterface->open(…)外面套着,在 CameraProviderManager.cpp 文件中
—>*session = cameraSession; //返回session, 这个session由CameraDeviceSession::getInterface() 得到
—>std::shared_ptr queue;
—>auto requestQueueRet = session->getCaptureRequestMetadataQueue([&queue](const auto& descriptor) //CameraDeviceSession::getCaptureRequestMetadataQueue()
—>queue = std::make_shared(descriptor) //这其实是在匿名回调函数里面
—>std::unique_ptr& resQueue = mResultMetadataQueue;
—>auto resultQueueRet = session->getCaptureResultMetadataQueue([&resQueue](const auto& descriptor)
—>resQueue = std::make_unique(descriptor); //这其实是在匿名回调函数里面
—>mInterface = new HalInterface(session, queue);
—>initializeCommonLocked();
—>mBufferManager = new Camera3BufferManager(); //Create buffer manager
—>mRequestThread = new RequestThread(this, mStatusTracker, mInterface); //启动请求队列线程, mInterface = new HalInterface(session, queue); session = CameraDeviceSession
—>mRequestThread->run(String8::format(“C3Dev-%s-ReqQueue”, mId.string()).string()); //参考 《数据流分析》
—>mFrameProcessor = new FrameProcessorBase(mDevice); //处理图像帧的实例
—>mFrameProcessor->run(threadName.string()); //进入一个线程循环处理图像帧
—>FrameProcessorBase::threadLoop()
—>device->waitForNextFrame(kWaitDuration); //等待数据到来
—>processNewFrames(device); //处理数据。参考《FrameProcessorBase 分析》
—>deviceImpl.setRemoteDevice(cameraUser);
—>CameraDeviceImpl::setRemoteDevice(cameraUser) //CameraDeviceImpl.java
—>mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
—>mDeviceHandler.post(mCallOnOpened); //mCallOnOpened 是CameraDeviceImpl的成员变量,直接在本文件搜索即可
—>mCallOnOpened.run()
—>mDeviceCallback.onOpened(CameraDeviceImpl.this); //mDeviceCallback 就是应用程序调用openCamera()时传入的第二个参数,所以这个回调是回调回应用程序,之后应用程序使用 CameraDeviceImpl 操作相机
—>Api2Camera::mCameraStateCallback::onOpened(CameraDevice camera)
—>mCameraDevice = camera; //就是 CameraDeviceImpl 对象
—>tryToStartCaptureSession();
—>startCaptureSession();
—>outputSurfaces.add(mPreviewSurface); //设置预览显示的Surface
—>outputSurfaces.add(mYuv1ImageReader.getSurface());
—>mCameraDevice.createCaptureSession(outputSurfaces, mSessionStateCallback, null); //mCameraDevice 是 CameraDeviceImpl 对象
—>createCaptureSessionInternal(null, outConfigurations, callback, handler, ICameraDeviceUser.NORMAL_MODE);
—>configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations, operatingMode);
—>input = mRemoteDevice.getInputSurface();
—>CameraCaptureSessionCore newSession = null;
—>newSession = new CameraCaptureSessionImpl(mNextSessionId++, input, callback, handler, this, mDeviceHandler, configureSuccess);
—>mStateCallback = createUserStateCallbackProxy(mStateHandler, callback);
—>InvokeDispatcher userCallbackSink = new InvokeDispatcher<>(callback);
—>HandlerDispatcher handlerPassthrough = new HandlerDispatcher<>(userCallbackSink, handler);
—>return new CallbackProxies.SessionStateCallbackProxy(handlerPassthrough);
—>mProxy = new MethodNameInvoker<>(dispatchTarget, CameraCaptureSession.StateCallback.class); //dispatchTarget = new HandlerDispatcher<>
—>mDeviceImpl = checkNotNull(deviceImpl, “deviceImpl must not be null”);
—>mStateCallback.onConfigured(this);
—>SessionStateCallbackProxy::onConfigured() //CallBackProxies.java
—>mProxy.invoke(“onConfigured”, session); //mProxy = new MethodNameInvoker, 调用 SessionStateCallback::onConfigured,回调回应用程序
—>mConfigureSuccess = true;
—>mCurrentSession = newSession;
—>mSessionStateCallback = mCurrentSession.getDeviceStateCallback(); //得到 CallbackProxies.SessionStateCallbackProxy 对象


#### 3.2 《FrameProcessorBase 分析》



《FrameProcessorBase 分析》 参考 《openCamera 流程》

CameraDeviceClient::initializeImpl()
—>mFrameProcessor = new FrameProcessorBase(mDevice);
—>mFrameProcessor->run(threadName.string()); //进入线程
—>FrameProcessorBase::threadLoop()
—>device = mDevice.promote(); //device 就是 Camera3Device 的实例
—>device->waitForNextFrame(kWaitDuration); //等待数据到来
—>while (mResultQueue.empty()) {/* mResultQueue 队列不为空则退出 */}
—>processNewFrames(device); //有数据了就处理
—>CaptureResult result;
—>device->getNextResult(&result) //device 就是 Camera3Device 的实例
—>CaptureResult &result = *(mResultQueue.begin()); //mResultQueue 参考《数据流分析》
—>frame->mResultExtras = result.mResultExtras; //frame 就是传入的 result,别被名字混淆了
—>frame->mMetadata.acquire(result.mMetadata); //得到数据
—>mResultQueue.erase(mResultQueue.begin()); //取出后擦除
—>camera_metadata_entry_t entry;
—>processSingleFrame(result, device)
—>processListeners(result, device) //将数据发给 Listener
—>List<sp > listeners;
—>List::iterator item = mRangeListeners.begin(); //取出迭代器, mRangeListeners 参考 《mRangeListeners 分析》
—>while (item != mRangeListeners.end()) {
sp listener = item->listener.promote(); //listener 就是 CameraDeviceClient 实例
listeners.push_back(listener); //压入
}
—>List<sp >::iterator item = listeners.begin(); //取出迭代器
—>for (; item != listeners.end(); item++)
(*item)->onResultAvailable(result); //调用 CameraDeviceClient::onResultAvailable()
—>CameraDeviceClient::onResultAvailable()
—>sphardware::camera2::ICameraDeviceCallbacks remoteCb = mRemoteCallback; //mRemoteCallback 参考《mRemoteCallback 分析》
—>remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
out/soong/.intermediates/frameworks/av/camera/libcamera_client/android_arm64_armv8-a_kryo300_shared_core/gen/aidl/frameworks/av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.cpp
—>BpCameraDeviceCallbacks::onResultReceived(result, resultExtras)
—>::android::Parcel _aidl_data;
—>_aidl_data.writeInterfaceToken(getInterfaceDescriptor());
—>_aidl_data.writeParcelable(result);
—>_aidl_data.writeParcelable(resultExtras);
—>remote()->transact(ICameraDeviceCallbacks::ONRESULTRECEIVED, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
—>CameraDeviceCallbacks::onResultReceived() //最终会回调回 CameraDeviceCallbacks.java
—>mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, FRAME_PROCESSOR_LISTENER_MAX_ID, /*listener*/this, /*sendPartials*/true);


#### 3.3 《hal 层分析》



《hal 层分析》
mModule->open(mCameraId.c_str(), reinterpret_cast<hw_device_t**>(&device)); //mModule是CameraModule对象
—>mModule->common.methods->open(&mModule->common, id, device) //这里的mModule是hw_get_module得到的,注意别被名字混淆了
—>qcamera::QCamera2Factory::mModuleMethods::camera_device_open(id, device) //使用的是QCamera2Hal.cpp的hal文件
—>QCamera2Factory::camera_device_open(id, hw_device)
—>gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device); //gQCamera2Factory = new gQCamera2Factory()
—>QCamera2Factory::cameraDeviceOpen(id, hw_device)
—>QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId, mCallbacks);
—>mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
—>mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
—>mCameraDevice.common.close = close_camera_device;
—>mCameraDevice.ops = &mCameraOps;
—>mCameraDevice.priv = this;
—>hw->openCamera(hw_device); // QCamera3HardwareInterface 在 QCamera3HWI.cpp
—>rc = openCamera();
—>camera_open((uint8_t)mCameraId, &mCameraHandle);
—>cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
—>cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx);
—>cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
—>cam_obj->vtbl.ops = &mm_camera_ops; // mm_camera_ops 结构体在当前文件下定义
—>mm_camera_open(cam_obj);
—>sscanf(dev_name, “/dev/video%d”, &cam_idx);
—>my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK); //my_obj就是传入的cam_obj
—>mm_camera_get_session_id(my_obj, &my_obj->sessionid);
—>struct v4l2_control control;
—>control.id = MSM_CAMERA_PRIV_G_SESSION_ID;
—>control.value = value;
—>ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control);
—>*sessionid = control.value; //返回sessionid
—>mm_camera_evt_sub(my_obj, TRUE);
—>rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
—>mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread, 0, my_obj->my_hdl, my_obj->ctrl_fd, mm_camera_event_notify,(void*)my_obj, mm_camera_sync_call);
—> g_cam_ctrl.cam_obj[cam_idx] = cam_obj;
—>*camera_vtbl = &cam_obj->vtbl; //返回 mCameraHandle
—>mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle, camEvtHandle, (void *)this); //注册通知回调
—>mm_camera_intf_register_event_notify(mCameraHandle->camera_handle, camEvtHandle, (void *)this) //mm_camera_interface.c
—>*hw_device = &mCameraDevice.common; //返回hw_device


#### 3.4 《数据流分析》



《数据流分析》
Camera3Device::RequestThread::threadLoop()
—>waitForNextRequestBatch(); //等待请求, 之后再分析这里,理清请求是如何生成的
—>submitRequestSuccess = sendRequestsOneByOne(); //发送一个请求
—>mInterface->processCaptureRequest(&nextRequest.halRequest); //mInterface = new HalInterface(session, queue) Camera3Device.cpp
—>std::vector<camera3_capture_request_t*> requests(1); //Camera3Device.cpp
—>requests[0] = request;
—>res = processBatchCaptureRequests(requests, &numRequestProcessed);
—>mRequestMetadataQueue->write(reinterpret_cast<const uint8_t*>(request->settings), settingsSize)
—>mHidlSession->processCaptureRequest(captureRequests, cachesToRemove, [&status, &numRequestProcessed] (auto s, uint32_t n) //mHidlSession = new CameraDeviceSession()
—>processOneCaptureRequest(requests[i])
—>mDevice->ops->process_capture_request(mDevice, &halRequest); //mDevice 由hal层的open()得到, 就是struct camera3_device 结构体
—>QCamera3HardwareInterface::mCameraOps::process_capture_request(device, request) //就是调用这个函数 QCamera3HWI.cpp
—>QCamera3HardwareInterface *hw = reinterpret_cast<QCamera3HardwareInterface *>(device->priv); //device->priv 在 new QCamera3HardwareInterface() 时构造函数中候赋值
—>hw->orchestrateRequest(request);
—>_orchestrationDb.allocStoreInternalFrameNumber(request->frame_number, internalFrameNumber);
—>request->frame_number = internalFrameNumber;
—>processCaptureRequest(request, internallyRequestedStreams);
—>CameraMetadata meta;
—>meta = request->settings;
—>mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters); //mCameraHandle由camera_open((uint8_t)mCameraId, &mCameraHandle)得到。mCameraHandle->ops是 mm_camera_ops 结构体
—>mm_camera_set_parms(my_obj, parms);
—>mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
—>ioctl(fd, VIDIOC_S_CTRL, &control); //最终调用到ioctl
—>mMetadataChannel->start();
—>mStreams[i]->start(); //开启这些Stream的线程
—>mDataQ.init(); // mDataQ 是之后线程需要处理的数据,由其他线程put进来
—>mProcTh.launch(dataProcRoutine, this); //开启线程
—>QCamera3Stream::dataProcRoutine(void *data)
—> QCamera3Stream *pme = (QCamera3Stream *)data;
—>QCameraCmdThread *cmdThread = &pme->mProcTh;
—>cam_sem_wait(&cmdThread->cmd_sem); //等待唤醒 参考第二部分
—>camera_cmd_type_t cmd = cmdThread->getCmd(); //根据cmd选择执行代码 我们分析 CAMERA_CMD_TYPE_DO_NEXT_JOB
—>mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
—>pme->mDataCB(frame, pme, pme->mUserData); //调用回调 就是QCamera3Channel::streamCbRoutine()
—>QCamera3Channel *channel = (QCamera3Channel *)userdata;
—>channel->streamCbRoutine(super_frame, stream);
—>QCamera3ProcessingChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, QCamera3Stream *stream)
—>camera3_stream_buffer_t result;
—>frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
—>resultBuffer = (buffer_handle_t *)mMemory.getBufferHandle(frameIndex);
—>resultFrameNumber = mMemory.getFrameNumber(frameIndex);
—>QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)mUserData;
—>result.stream = mCamera3Stream;
—>result.buffer = resultBuffer;
—>mChannelCB(NULL, &result, (uint32_t)resultFrameNumber, false, mUserData); //回调函数 QCamera3HardwareInterface::captureResultCb()
—>captureResultCb(mm_camera_super_buf_t *metadata_buf, camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer)
—>handleBufferWithLock(buffer, frame_number);
—>camera3_capture_result_t result; //构造camera3_capture_result_t
—>result.result = NULL;
—>result.frame_number = frame_number;
—>result.num_output_buffers = 1;
—>result.output_buffers = buffer;
—>orchestrateResult(&result);
—>mCallbackOps->process_capture_result(mCallbackOps, result); //就是调用 Camera3Device::sProcessCaptureResult()
—>Camera3Device *d = const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
—>d->processCaptureResult(result);
—>uint32_t frameNumber = result->frame_number;
—>CameraMetadata metadata;
—>metadata = result->result;
—>sendCaptureResult(metadata, request.resultExtras, collectedPartialResult, frameNumber, hasInputBufferInRequest);
—>CaptureResult captureResult; //构造 CaptureResult
—>captureResult.mResultExtras = resultExtras;
—>captureResult.mMetadata = pendingMetadata;
—>captureResult.mMetadata.sort();
—>insertResultLocked(&captureResult, frameNumber); //将CaptureResult插入mResultQueue队列
—>List::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(*result));
—>mResultSignal.signal(); //发送信号唤醒 FrameProcessorBase 线程

第二部分:

QCamera3Stream::init()
—>mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
—>stream_config.stream_info = mStreamInfo;
—>stream_config.mem_vtbl = mMemVtbl;
—>stream_config.padding_info = mPaddingInfo;
—>stream_config.userdata = this;
—>stream_config.stream_cb = dataNotifyCB; //回调函数:QCamera3Stream::dataNotifyCB(), 把这个回调函数注册到底层,当有数据是使用这个函数通知
—>stream_config.stream_cb_sync = NULL;
—>rc = mCamOps->config_stream(mCamHandle, mChannelHandle, mHandle, &stream_config);
—>mDataCB = stream_cb; //stream_cb 就是QCamera3Channel::streamCbRoutine()

QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, void *userdata)
—>QCamera3Stream* stream = (QCamera3Stream *)userdata;
—>mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
—>*frame = *recvd_frame;
—>stream->processDataNotify(frame);
—>mDataQ.enqueue((void *)frame) //压入队列
—>mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); //向QCameraCmdThread线程发送命令,表明有数据需要处理

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

);
—>*frame = *recvd_frame;
—>stream->processDataNotify(frame);
—>mDataQ.enqueue((void *)frame) //压入队列
—>mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); //向QCameraCmdThread线程发送命令,表明有数据需要处理

[外链图片转存中…(img-jIPNEWdk-1715840183198)]
[外链图片转存中…(img-xkrAaEz1-1715840183198)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值