Android P Camera2相机简单解析(二、拍照)
还是老样子,从API开始梳理。
CameraCaptureSession.java
文件路径:/frameworks/base/core/java/android/hardware/camera2/CameraCaptureSession.java
public abstract int capture(@NonNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler) throws CameraAccessException;
不难发现这里实际上什么都没做,那么需要找一下继承于CameraCaptureSession.java文件的子类了,对应文件为
CameraCaptureSessionImpl.java
文件路径:/frameworks/base/core/java/android/hardware/camera2/imp/CameraCaptureSessionImpl.java
public int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { checkCaptureRequest(request); synchronized (mDeviceImpl.mInterfaceLock) { checkNotClosed(); handler = checkHandler(handler, callback); if (DEBUG) { Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback + " handler " + handler); } return addPendingSequence(mDeviceImpl.capture(request, createCaptureCallbackProxy(handler, callback), mDeviceExecutor)); } }
这里第15-16行又告诉我们需要去其他地方了,在当前文件下,我们看一下mDeviceImpl的初始化,
private final android.hardware.camera2.impl.CameraDeviceImpl mDeviceImpl;
这里告诉我们需要去CameraDeviceImpl.java了
CameraDeviceImpl.java
文件路径:/frameworks/base/core/java/android/hardware/camera2/imp/CameraDeviceImpl.java
public int capture(CaptureRequest request, CaptureCallback callback, Executor executor) throws CameraAccessException { if (DEBUG) { Log.d(TAG, "calling capture"); } List requestList = new ArrayList(); requestList.add(request); return submitCaptureRequest(requestList, callback, executor, /*streaming*/false); } ... private int submitCaptureRequest(List requestList, CaptureCallback callback, Executor executor, boolean repeating) throws CameraAccessException { // Need a valid executor, or current thread needs to have a looper, if // callback is valid executor = checkExecutor(executor, callback); // Make sure that there all requests have at least 1 surface; all surfaces are non-null; // the surface isn't a physical stream surface for reprocessing request for (CaptureRequest request : requestList) { if (request.getTargets().isEmpty()) { throw new IllegalArgumentException( "Each request must have at least one Surface target"); } for (Surface surface : request.getTargets()) { if (surface == null) { throw new IllegalArgumentException("Null Surface targets are not allowed"); } for (int i = 0; i < mConfiguredOutputs.size(); i++) { OutputConfiguration configuration = mConfiguredOutputs.valueAt(i); if (configuration.isForPhysicalCamera() && configuration.getSurfaces().contains(surface)) { if (request.isReprocess()) { throw new IllegalArgumentException( "Reprocess request on physical stream is not allowed"); } } } } } synchronized(mInterfaceLock) { checkIfCameraClosedOrInError(); if (repeating) { stopRepeating(); } SubmitInfo requestInfo; CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]); // Convert Surface to streamIdx and surfaceIdx for (CaptureRequest request : requestArray) { request.convertSurfaceToStreamId(mConfiguredOutputs); } requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating); if (DEBUG) { Log.v(TAG, "last frame number " + requestInfo.getLastFrameNumber()); } for (CaptureRequest request : requestArray) { request.recoverStreamIdToSurface(); } if (callback != null) { mCaptureCallbackMap.put(requestInfo.getRequestId(), new CaptureCallbackHolder( callback, requestList, executor, repeating, mNextSessionId - 1)); } else { if (DEBUG) { Log.d(TAG, "Listen for request " + requestInfo.getRequestId() + " is null"); } } if (repeating) { if (mRepeatingRequestId != REQUEST_ID_NONE) { checkEarlyTriggerSequenceComplete(mRepeatingRequestId, requestInfo.getLastFrameNumber()); } mRepeatingRequestId = requestInfo.getRequestId(); } else { mRequestLastFrameNumbersList.add( new RequestLastFrameNumbersHolder(requestList, requestInfo)); } if (mIdle) { mDeviceExecutor.execute(mCallOnActive); } mIdle = false; return requestInfo.getRequestId(); } }
这里第58行中的mRemoteDevice 又需要找一下在哪里进行初始化的了,
public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException { synchronized(mInterfaceLock) { // TODO: Move from decorator to direct binder-mediated exceptions // If setRemoteFailure already called, do nothing if (mInError) return; mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice); IBinder remoteDeviceBinder = remoteDevice.asBinder(); // For legacy camera device, remoteDevice is in the same process, and // asBinder returns NULL. if (remoteDeviceBinder != null) { try { remoteDeviceBinder.linkToDeath(this, /*flag*/ 0); } catch (RemoteException e) { CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected); throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED, "The camera device has encountered a serious error"); } } mDeviceExecutor.execute(mCallOnOpened); mDeviceExecutor.execute(mCallOnUnconfigured); } }
在这里我们不仅需要关注mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice),好需要关注setRemoteDevice这个方法是谁调用的,因为remoteDevice是由其他地方传入的,在第一篇open中开始opencamera的相关接口就调用了这个接口。我们先继续跟进CameraDeviceImpl.java中的mRemoteDevice.submitRequestList(requestArray, repeating)到下一个文件
ICameraDeviceUserWrapper.java
文件路径:/frameworks/base/core/java/android/hardware/camera2/imp/ICameraDeviceUserWrapper.java
public ICameraDeviceUserWrapper(ICameraDeviceUser remoteDevice) { if (remoteDevice == null) { throw new NullPointerException("Remote device may not be null"); } mRemoteDevice = remoteDevice; } ... public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean streaming) throws CameraAccessException { try { return mRemoteDevice.submitRequestList(requestList, streaming); } catch (Throwable t) { CameraManager.throwAsPublicException(t); throw new UnsupportedOperationException("Unexpected exception", t); } }
这里又实际上指向了remoteDevice,通过上面不难发现是通过setRemoteDevice这个接口来设置的,这个接口又是CameraManager.java调用的。
CameraManager.java
文件路径:/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
private CameraDevice openCameraDeviceUserAsync(String cameraId, CameraDevice.StateCallback callback, Executor executor, final int uid) throws CameraAccessException { CameraCharacteristics characteristics = getCameraCharacteristics(cameraId); CameraDevice device = null; synchronized (mLock) { ICameraDeviceUser cameraUser = null; android.hardware.camera2.impl.CameraDeviceImpl deviceImpl = new android.hardware.camera2.impl.CameraDeviceImpl( cameraId, callback, executor, characteristics, mContext.getApplicationInfo().targetSdkVersion); ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks(); try { if (supportsCamera2ApiLocked(cameraId)) { // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices ICameraService cameraService = CameraManagerGlobal.get().getCameraService(); if (cameraService == null) { throw new ServiceSpecificException( ICameraService.ERROR_DISCONNECTED, "Camera service is currently unavailable"); } cameraUser = cameraService.connectDevice(callbacks, cameraId, mContext.getOpPackageName(), uid); } else { // Use legacy camera implementation for HAL1 devices int id; try { id = Integer.parseInt(cameraId); } catch (NumberFormatException e) { throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: " + cameraId); } Log.i(TAG, "Using legacy camera HAL."); cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id); } } catch (ServiceSpecificException e) { if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) { throw new AssertionError("Should've gone down the shim path"); } else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE || e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE || e.errorCode == ICameraService.ERROR_DISABLED || e.errorCode == ICameraService.ERROR_DISCONNECTED || e.errorCode == ICameraService.ERROR_INVALID_OPERATION) { // Received one of the known connection errors // The remote camera device cannot be connected to, so // set the local camera to the startup error state deviceImpl.setRemoteFailure(e); if (e.errorCode == ICameraService.ERROR_DISABLED || e.errorCode == ICameraService.ERROR_DISCONNECTED || e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) { // Per API docs, these failures call onError and throw throwAsPublicException(e); } } else { // Unexpected failure - rethrow throwAsPublicException(e); } } catch (RemoteException e) { // Camera service died - act as if it's a CAMERA_DISCONNECTED case ServiceSpecificException sse = new ServiceSpecificException( ICameraService.ERROR_DISCONNECTED, "Camera service is currently unavailable"); deviceImpl.setRemoteFailure(sse); throwAsPublicException(sse); } // TODO: factor out callback to be non-nested, then move setter to constructor // For now, calling setRemoteDevice will fire initial // onOpened/onUnconfigured callbacks. // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if // cameraUser dies during setup. deviceImpl.setRemoteDevice(cameraUser); device = deviceImpl; } return device; }
其中第30和82行即对之前remoteDevice进行了初始化和设置,至此java层已经结束了。在上一篇中已经有梳理30和31行了,我们直接到CameraDeviceClient.cpp
CameraDeviceClient.cpp
文件路径:/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
binder::Status CameraDeviceClient::submitRequest( const hardware::camera2::CaptureRequest& request, bool streaming, /*out*/ hardware::camera2::utils::SubmitInfo *submitInfo) { std::vector requestList = { request }; return submitRequestList(requestList, streaming, submitInfo); ... binder::Status CameraDeviceClient::submitRequestList( const std::vector& requests, bool streaming, /*out*/ hardware::camera2::utils::SubmitInfo *submitInfo) { ATRACE_CALL(); ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size()); binder::Status res = binder::Status::ok(); status_t err; if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) { return res; } Mutex::Autolock icl(mBinderSerializationLock); if (!mDevice.get()) { return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive"); } if (requests.empty()) { ALOGE("%s: Camera %s: Sent null request. Rejecting request.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list"); } List metadataRequestList; std::list surfaceMapList; submitInfo->mRequestId = mRequestIdCounter; uint32_t loopCounter = 0; for (auto&& request: requests) { if (request.mIsReprocess) { if (!mInputStream.configured) { ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT, "No input configured for camera %s but request is for reprocessing", mCameraIdStr.string()); } else if (streaming) { ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Repeating reprocess requests not supported"); } else if (request.mPhysicalCameraSettings.size() > 1) { ALOGE("%s: Camera %s: reprocess requests not supported for " "multiple physical cameras.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Reprocess requests not supported for multiple cameras"); } } if (request.mPhysicalCameraSettings.empty()) { ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Request doesn't contain any settings"); } //The first capture settings should always match the logical camera id String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str()); if (mDevice->getId() != logicalId) { ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Invalid camera request settings"); } if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) { ALOGE("%s: Camera %s: Requests must have at least one surface target. " "Rejecting request.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Request has no output targets"); } /** * Write in the output stream IDs and map from stream ID to surface ID * which we calculate from the capture request's list of surface target */ SurfaceMap surfaceMap; Vector outputStreamIds; std::vector requestedPhysicalIds; if (request.mSurfaceList.size() > 0) { for (sp surface : request.mSurfaceList) { if (surface == 0) continue; int32_t streamId; sp gbp = surface->getIGraphicBufferProducer(); res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId); if (!res.isOk()) { return res; } ssize_t index = mConfiguredOutputs.indexOfKey(streamId); if (index >= 0) { String8 requestedPhysicalId( mConfiguredOutputs.valueAt(index).getPhysicalCameraId()); requestedPhysicalIds.push_back(requestedPhysicalId.string()); } else { ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__); } } } else { for (size_t i = 0; i < request.mStreamIdxList.size(); i++) { int streamId = request.mStreamIdxList.itemAt(i); int surfaceIdx = request.mSurfaceIdxList.itemAt(i); ssize_t index = mConfiguredOutputs.indexOfKey(streamId); if (index < 0) { ALOGE("%s: Camera %s: Tried to submit a request with a surface that" " we have not called createStream on: stream %d", __FUNCTION__, mCameraIdStr.string(), streamId); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Request targets Surface that is not part of current capture session"); } const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers(); if ((size_t)surfaceIdx >= gbps.size()) { ALOGE("%s: Camera %s: Tried to submit a request with a surface that" " we have not called createStream on: stream %d, surfaceIdx %d", __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Request targets Surface has invalid surface index"); } res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr); if (!res.isOk()) { return res; } String8 requestedPhysicalId( mConfiguredOutputs.valueAt(index).getPhysicalCameraId()); requestedPhysicalIds.push_back(requestedPhysicalId.string()); } } CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList; for (const auto& it : request.mPhysicalCameraSettings) { if (it.settings.isEmpty()) { ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.", __FUNCTION__, mCameraIdStr.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Request settings are empty"); } String8 physicalId(it.id.c_str()); if (physicalId != mDevice->getId()) { auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(), it.id); if (found == requestedPhysicalIds.end()) { ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.", __FUNCTION__, mCameraIdStr.string(), physicalId.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Invalid physical camera id"); } if (!mSupportedPhysicalRequestKeys.empty()) { // Filter out any unsupported physical request keys. CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size()); camera_metadata_t *meta = const_cast( filteredParams.getAndLock()); set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId()); filteredParams.unlock(meta); for (const auto& keyIt : mSupportedPhysicalRequestKeys) { camera_metadata_ro_entry entry = it.settings.find(keyIt); if (entry.count > 0) { filteredParams.update(entry); } } physicalSettingsList.push_back({it.id, filteredParams}); } } else { physicalSettingsList.push_back({it.id, it.settings}); } } if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) { // Callee logs return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED, "Caller does not have permission to change restricted controls"); } physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0], outputStreamIds.size()); if (request.mIsReprocess) { physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, 1); } physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_ID, &(submitInfo->mRequestId), /*size*/1); loopCounter++; // loopCounter starts from 1 ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)", __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId, loopCounter, requests.size()); metadataRequestList.push_back(physicalSettingsList); surfaceMapList.push_back(surfaceMap); } mRequestIdCounter++; if (streaming) { err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList, &(submitInfo->mLastFrameNumber)); if (err != OK) { String8 msg = String8::format( "Camera %s: Got error %s (%d) after trying to set streaming request", mCameraIdStr.string(), strerror(-err), err); ALOGE("%s: %s", __FUNCTION__, msg.string()); res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string()); } else { Mutex::Autolock idLock(mStreamingRequestIdLock); mStreamingRequestId = submitInfo->mRequestId; } } else { err = mDevice->captureList(metadataRequestList, surfaceMapList, &(submitInfo->mLastFrameNumber)); if (err != OK) { String8 msg = String8::format( "Camera %s: Got error %s (%d) after trying to submit capture request", mCameraIdStr.string(), strerror(-err), err); ALOGE("%s: %s", __FUNCTION__, msg.string()); res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string()); } ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId); } ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string()); return res;}}
通过阅读此处代码不难知道第215行是视频录制接下来的处理,而229行才是拍照处理的。之前在分析open的流程时应该知道这里的mDevice指的是Camera3Device.cpp
Camera3Device.cpp
文件路径:/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::initialize(sp manager, const String8& monitorTags) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string()); if (mStatus != STATUS_UNINITIALIZED) { CLOGE("Already initialized!"); return INVALID_OPERATION; } if (manager == nullptr) return INVALID_OPERATION; sp session; ATRACE_BEGIN("CameraHal::openSession"); status_t res = manager->openSession(mId.string(), this, /*out*/ &session); ATRACE_END(); if (res != OK) { SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res); return res; } res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo); if (res != OK) { SET_ERR_L("Could not retrive camera characteristics: %s (%d)", strerror(-res), res); session->close(); return res; } std::shared_ptr queue; auto requestQueueRet = session->getCaptureRequestMetadataQueue( //获取请求队列 [&queue](const auto& descriptor) { queue = std::make_shared(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. } }); if (!requestQueueRet.isOk()) { ALOGE("Transaction error when getting request metadata fmq: %s, not use it", requestQueueRet.description().c_str()); return DEAD_OBJECT; } std::unique_ptr& resQueue = mResultMetadataQueue; //获得结果队列,最终保存在mResultMetadataQueue对象中 auto resultQueueRet = session->getCaptureResultMetadataQueue( [&resQueue](const auto& descriptor) { resQueue = std::make_unique(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. } }); if (!resultQueueRet.isOk()) { ALOGE("Transaction error when getting result metadata queue from camera session: %s", resultQueueRet.description().c_str()); return DEAD_OBJECT; } IF_ALOGV() { session->interfaceChain([]( ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) { ALOGV("Session interface chain:"); for (auto iface : interfaceChain) { ALOGV(" %s", iface.c_str()); } }); } mInterface = new HalInterface(session, queue); std::string providerType; mVendorTagId = manager->getProviderTagIdLocked(mId.string()); mTagMonitor.initialize(mVendorTagId); if (!monitorTags.isEmpty()) { mTagMonitor.parseTagsToMonitor(String8(monitorTags)); } return initializeCommonLocked();}...status_t Camera3Device::captureList(const List &requestsList, const std::list &surfaceMaps, int64_t *lastFrameNumber) { ATRACE_CALL(); return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);}...status_t Camera3Device::submitRequestsHelper( const List &requests, const std::list &surfaceMaps, bool repeating, /*out*/ int64_t *lastFrameNumber) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); status_t res = checkStatusOkToCaptureLocked(); // 检查 if (res != OK) { // error logged by previous call return res; } RequestList requestList; res = convertMetadataListToRequestListLocked(requests, surfaceMaps, repeating, /*out*/&requestList); //提交 if (res != OK) { // error logged by previous call return res; } if (repeating) { res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber); //连续拍照request插入mRequestThread } else { res = mRequestThread->queueRequestList(requestList, lastFrameNumber);//拍照request插入mRequestThread } else { } if (res == OK) { waitUntilStateThenRelock(/*active*/true, kActiveTimeout); if (res != OK) { SET_ERR_L("Can't transition to active in %f seconds!", kActiveTimeout/1e9); } ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(), (*(requestList.begin()))->mResultExtras.requestId); } else { CLOGE("Cannot queue request. Impossible."); return BAD_VALUE; } return res;}...status_t Camera3Device::RequestThread::queueRequestList( List > &requests, /*out*/ int64_t *lastFrameNumber) { ATRACE_CALL(); Mutex::Autolock l(mRequestLock); for (List >::iterator it = requests.begin(); it != requests.end(); ++it) { mRequestQueue.push_back(*it); } if (lastFrameNumber != NULL) { *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1; ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".", __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber, *lastFrameNumber); } unpauseForNewRequests(); return OK;}...void Camera3Device::RequestThread::unpauseForNewRequests() { ATRACE_CALL(); // With work to do, mark thread as unpaused. // If paused by request (setPaused), don't resume, to avoid // extra signaling/waiting overhead to waitUntilPaused mRequestSignal.signal(); Mutex::Autolock p(mPauseLock); if (!mDoPause) { ALOGV("%s: RequestThread: Going active", __FUNCTION__); if (mPaused) { sp statusTracker = mStatusTracker.promote(); if (statusTracker != 0) { statusTracker->markComponentActive(mStatusId); } } mPaused = false; }}.../*处理RequestThread 中的request*/bool Camera3Device::RequestThread::threadLoop() { ATRACE_CALL(); status_t res; // Handle paused state. if (waitIfPaused()) { return true; } // Wait for the next batch of requests. waitForNextRequestBatch(); if (mNextRequests.size() == 0) { return true; } // Get the latest request ID, if any int latestRequestId; camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1]. captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID); if (requestIdEntry.count > 0) { latestRequestId = requestIdEntry.data.i32[0]; } else { ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__); latestRequestId = NAME_NOT_FOUND; } // 'mNextRequests' will at this point contain either a set of HFR batched requests // or a single request from streaming or burst. In either case the first element // should contain the latest camera settings that we need to check for any session // parameter updates. if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) { res = OK; //Input stream buffers are already acquired at this point so an input stream //will not be able to move to idle state unless we force it. if (mNextRequests[0].captureRequest->mInputStream != nullptr) { res = mNextRequests[0].captureRequest->mInputStream->forceToIdle(); if (res != OK) { ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } } if (res == OK) { sp statusTracker = mStatusTracker.promote(); if (statusTracker != 0) { sp parent = mParent.promote(); if (parent != nullptr) { parent->pauseStateNotify(true); } statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE); if (parent != nullptr) { mReconfigured |= parent->reconfigureCamera(mLatestSessionParams); } statusTracker->markComponentActive(mStatusId); setPaused(false); } if (mNextRequests[0].captureRequest->mInputStream != nullptr) { mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState(); if (res != OK) { ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } } } } // Prepare a batch of HAL requests and output buffers. res = prepareHalRequests(); if (res == TIMED_OUT) { // Not a fatal error if getting output buffers time out. cleanUpFailedRequests(/*sendRequestError*/ true); // Check if any stream is abandoned. checkAndStopRepeatingRequest(); return true; } else if (res != OK) { cleanUpFailedRequests(/*sendRequestError*/ false); return false; } // Inform waitUntilRequestProcessed thread of a new request ID { Mutex::Autolock al(mLatestRequestMutex); mLatestRequestId = latestRequestId; mLatestRequestSignal.signal(); } // Submit a batch of requests to HAL. // Use flush lock only when submitting multilple requests in a batch. // TODO: The problem with flush lock is flush() will be blocked by process_capture_request() // which may take a long time to finish so synchronizing flush() and // process_capture_request() defeats the purpose of cancelling requests ASAP with flush(). // For now, only synchronize for high speed recording and we should figure something out for // removing the synchronization. bool useFlushLock = mNextRequests.size() > 1; if (useFlushLock) { mFlushLock.lock(); } ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__, mNextRequests.size()); bool submitRequestSuccess = false; nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC); if (mInterface->supportBatchRequest()) { submitRequestSuccess = sendRequestsBatch();//批量处理? } else { submitRequestSuccess = sendRequestsOneByOne();//一条一条的处理 } nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC); mRequestLatency.add(tRequestStart, tRequestEnd); if (useFlushLock) { mFlushLock.unlock(); } // Unset as current request { Mutex::Autolock l(mRequestLock); mNextRequests.clear(); } return submitRequestSuccess;}...bool Camera3Device::RequestThread::sendRequestsBatch() { ATRACE_CALL(); status_t res; size_t batchSize = mNextRequests.size(); std::vector requests(batchSize); uint32_t numRequestProcessed = 0; for (size_t i = 0; i < batchSize; i++) { requests[i] = &mNextRequests.editItemAt(i).halRequest; ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number); } res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);//到下一处 bool triggerRemoveFailed = false; NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0); for (size_t i = 0; i < numRequestProcessed; i++) { NextRequest& nextRequest = mNextRequests.editItemAt(i); nextRequest.submitted = true; // Update the latest request sent to HAL if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged Mutex::Autolock al(mLatestRequestMutex); camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings); mLatestRequest.acquire(cloned); sp parent = mParent.promote(); if (parent != NULL) { parent->monitorMetadata(TagMonitor::REQUEST, nextRequest.halRequest.frame_number, 0, mLatestRequest); } } if (nextRequest.halRequest.settings != NULL) { nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock( nextRequest.halRequest.settings); } cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest); if (!triggerRemoveFailed) { // Remove any previously queued triggers (after unlock) status_t removeTriggerRes = removeTriggers(mPrevRequest); if (removeTriggerRes != OK) { triggerRemoveFailed = true; triggerFailedRequest = nextRequest; } } } if (triggerRemoveFailed) { SET_ERR("RequestThread: Unable to remove triggers " "(capture request %d, HAL device: %s (%d)", triggerFailedRequest.halRequest.frame_number, strerror(-res), res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } if (res != OK) { // Should only get a failure here for malformed requests or device-level // errors, so consider all errors fatal. Bad metadata failures should // come through notify. SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)", mNextRequests[numRequestProcessed].halRequest.frame_number, strerror(-res), res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } return true;}bool Camera3Device::RequestThread::sendRequestsOneByOne() { status_t res; for (auto& nextRequest : mNextRequests) { // Submit request and block until ready for next one ATRACE_ASYNC_BEGIN("frame capture", nextRequest.halRequest.frame_number); res = mInterface->processCaptureRequest(&nextRequest.halRequest);//到下一处 if (res != OK) { // Should only get a failure here for malformed requests or device-level // errors, so consider all errors fatal. Bad metadata failures should // come through notify. SET_ERR("RequestThread: Unable to submit capture request %d to HAL" " device: %s (%d)", nextRequest.halRequest.frame_number, strerror(-res), res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } // Mark that the request has be submitted successfully. nextRequest.submitted = true; // Update the latest request sent to HAL if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged Mutex::Autolock al(mLatestRequestMutex); camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings); mLatestRequest.acquire(cloned); sp parent = mParent.promote(); if (parent != NULL) { parent->monitorMetadata(TagMonitor::REQUEST, nextRequest.halRequest.frame_number, 0, mLatestRequest); } } if (nextRequest.halRequest.settings != NULL) { nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock( nextRequest.halRequest.settings); } cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest); // Remove any previously queued triggers (after unlock) res = removeTriggers(mPrevRequest); if (res != OK) { SET_ERR("RequestThread: Unable to remove triggers " "(capture request %d, HAL device: %s (%d)", nextRequest.halRequest.frame_number, strerror(-res), res); cleanUpFailedRequests(/*sendRequestError*/ false); return false; } } return true;}...status_t Camera3Device::HalInterface::processCaptureRequest( camera3_capture_request_t *request) { ATRACE_NAME("CameraHal::processCaptureRequest"); if (!valid()) return INVALID_OPERATION; status_t res = OK; uint32_t numRequestProcessed = 0; std::vector requests(1); requests[0] = request; res = processBatchCaptureRequests(requests, &numRequestProcessed);//好吧,还是走Batch return res;}...status_t Camera3Device::HalInterface::processBatchCaptureRequests( std::vector& requests,/*out*/uint32_t* numRequestProcessed) { ATRACE_NAME("CameraHal::processBatchCaptureRequests"); if (!valid()) return INVALID_OPERATION; sp hidlSession_3_4; auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession); if (castResult_3_4.isOk()) { hidlSession_3_4 = castResult_3_4; } hardware::hidl_vec captureRequests; hardware::hidl_vec captureRequests_3_4; size_t batchSize = requests.size(); if (hidlSession_3_4 != nullptr) { captureRequests_3_4.resize(batchSize); } else { captureRequests.resize(batchSize); } std::vector handlesCreated; for (size_t i = 0; i < batchSize; i++) { if (hidlSession_3_4 != nullptr) { wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2, /*out*/&handlesCreated); } else { wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i], /*out*/&handlesCreated); } } std::vector cachesToRemove; { std::lock_guard lock(mBufferIdMapLock); for (auto& pair : mFreedBuffers) { // The stream might have been removed since onBufferFreed if (mBufferIdMaps.find(pair.first) != mBufferIdMaps.end()) { cachesToRemove.push_back({pair.first, pair.second}); } } mFreedBuffers.clear(); } common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR; *numRequestProcessed = 0; // Write metadata to FMQ. for (size_t i = 0; i < batchSize; i++) { camera3_capture_request_t* request = requests[i]; device::V3_2::CaptureRequest* captureRequest; if (hidlSession_3_4 != nullptr) { captureRequest = &captureRequests_3_4[i].v3_2; } else { captureRequest = &captureRequests[i]; } if (request->settings != nullptr) { size_t settingsSize = get_camera_metadata_size(request->settings); if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write( reinterpret_cast(request->settings), settingsSize)) { captureRequest->settings.resize(0); captureRequest->fmqSettingsSize = settingsSize; } else { if (mRequestMetadataQueue != nullptr) { ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__); } captureRequest->settings.setToExternal( reinterpret_cast(const_cast(request->settings)), get_camera_metadata_size(request->settings)); captureRequest->fmqSettingsSize = 0u; } } else { // A null request settings maps to a size-0 CameraMetadata captureRequest->settings.resize(0); captureRequest->fmqSettingsSize = 0u; } if (hidlSession_3_4 != nullptr) { captureRequests_3_4[i].physicalCameraSettings.resize(request->num_physcam_settings); for (size_t j = 0; j < request->num_physcam_settings; j++) { if (request->physcam_settings != nullptr) { size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]); if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write( reinterpret_cast(request->physcam_settings[j]), settingsSize)) { captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0); captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = settingsSize; } else { if (mRequestMetadataQueue != nullptr) { ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__); } captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal( reinterpret_cast(const_cast( request->physcam_settings[j])), get_camera_metadata_size(request->physcam_settings[j])); captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u; } } else { captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u; captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0); } captureRequests_3_4[i].physicalCameraSettings[j].physicalCameraId = request->physcam_id[j]; } } } /*指向了CameraDeviceSession,接下来就是HAL厂家的了*/ hardware::details::return_status err; if (hidlSession_3_4 != nullptr) { err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove, [&status, &numRequestProcessed] (auto s, uint32_t n) { status = s; *numRequestProcessed = n; }); } else { err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove, [&status, &numRequestProcessed] (auto s, uint32_t n) { status = s; *numRequestProcessed = n; }); } if (!err.isOk()) { ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); return DEAD_OBJECT; } if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) { ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests", __FUNCTION__, *numRequestProcessed, batchSize); status = common::V1_0::Status::INTERNAL_ERROR; } for (auto& handle : handlesCreated) { native_handle_delete(handle); } return CameraProviderManager::mapToStatusT(status);}
不难发现上层的request在这里经过层层调用最后还是到了每个厂家的HAL层,对于MTK平台而言是调用了CameraDevice3SessionImpl.cpp文件
CameraDevice3SessionImpl.cpp
文件路径:/vendor/mediatek/proprietary/hardware/mtkcam/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp
ReturnThisNamespace::processCaptureRequest(const hidl_vec& requests, const hidl_vec& cachesToRemove, processCaptureRequest_cb _hidl_cb){ uint32_t numRequestProcessed = 0; hidl_vec v34Requests(requests.size()); int i = 0; for(auto &r : requests) { v34Requests[i++] = (V3_4::CaptureRequest &)WrappedCaptureRequest(r); } auto status = onProcessCaptureRequest(v34Requests, cachesToRemove, numRequestProcessed); MY_LOGD_IF(getLogLevel() >= 2, "- requestNo_1st:%u #:%zu numRequestProcessed:%u", requests[0].frameNumber, requests.size(), numRequestProcessed); if ( m1stRequestNotSent ) { if (OK == status) { m1stRequestNotSent = false; mStateLog.add("-> 1st request - OK"); MY_LOGD("-> 1st request - OK"); } else { mStateLog.add("-> 1st request - failure"); MY_LOGE("-> 1st request - failure"); } } _hidl_cb(mapToHidlCameraStatus(status), numRequestProcessed); return Void();}...ReturnThisNamespace::processCaptureRequest_3_4(const hidl_vec& requests, const hidl_vec& cachesToRemove, processCaptureRequest_3_4_cb _hidl_cb){ uint32_t numRequestProcessed = 0; auto status = onProcessCaptureRequest(requests, cachesToRemove, numRequestProcessed); MY_LOGD_IF(getLogLevel() >= 2, "- requestNo_1st:%u #:%zu numRequestProcessed:%u", requests[0].v3_2.frameNumber, requests.size(), numRequestProcessed); if ( m1stRequestNotSent ) { if (OK == status) { m1stRequestNotSent = false; mStateLog.add("-> 1st request - OK"); MY_LOGD("-> 1st request - OK"); } else { mStateLog.add("-> 1st request - failure"); MY_LOGE("-> 1st request - failure"); } } _hidl_cb(mapToHidlCameraStatus(status), numRequestProcessed); return Void();}...autoThisNamespace::onProcessCaptureRequest( const hidl_vec& requests, const hidl_vec& cachesToRemove, uint32_t& numRequestProcessed) -> ::android::status_t{ size_t const requestNum = requests.size(); uint32_t const requestNo_1st = requests[0].v3_2.frameNumber; ::android::status_t err = OK;#if ! PIPELINE_NEW_ARCH ::android::Vector pipelineRequests;#endif auto pPipelineModel = getSafePipelineModel(); ::android::Vector appRequests; auto pAppStreamManager = getSafeAppStreamManager(); if ( pAppStreamManager == 0 ) { MY_LOGE("Bad AppStreamManager"); return DEAD_OBJECT; } // { Mutex::Autolock _lRequesting(mRequestingLock); // pAppStreamManager->removeBufferCache(cachesToRemove); // if ( 0 == ::android_atomic_acquire_load(&mRequestingAllowed) ) { MY_LOGW("submitting requests during flushing - requestNo_1st:%u #:%zu", requestNo_1st, requestNum); pAppStreamManager->flushRequest(requests); numRequestProcessed = requests.size(); return OK; } // if ( pPipelineModel == 0 ) { MY_LOGE("Bad PipelineModel"); return NO_INIT; } // err = pAppStreamManager->submitRequest(requests, appRequests); if ( OK != err ) { return err; } } //#if PIPELINE_NEW_ARCH#define _CLONE_(dst, src) \ do { \ dst.clear(); \ for (size_t j = 0; j < src.size(); j++) { \ dst.emplace( std::make_pair(src.keyAt(j), src.valueAt(j) ) ); \ } \ } while (0) \ std::vector> vPipelineRequests(appRequests.size()); for ( size_t i=0; i(); if ( !pItem ) { MY_LOGE("Bad UserRequestParams"); return NO_INIT; } pItem->requestNo = appRequests[i].frameNo; _CLONE_(pItem->vIImageBuffers, appRequests[i].vInputImageBuffers); _CLONE_(pItem->vOImageBuffers, appRequests[i].vOutputImageBuffers); _CLONE_(pItem->vIMetaBuffers, appRequests[i].vInputMetaBuffers); }#undef _CLONE_ // // Since this call may block, it should be performed out of locking. err = pPipelineModel->submitRequest(vPipelineRequests, numRequestProcessed); if ( OK != err || requests.size() != numRequestProcessed ) { MY_LOGE("%u/%zu requests submitted sucessfully - err:%d(%s)", numRequestProcessed, vPipelineRequests.size(), -err, ::strerror(-err)); return err; }#else pipelineRequests.resize(appRequests.size()); for (size_t i = 0; i < appRequests.size(); i++) {#define _CLONE_(dst, src) \ do { \ dst.setCapacity(src.size()); \ dst.clear(); \ for (size_t j = 0; j < src.size(); j++) { \ dst.add(src.keyAt(j), src.valueAt(j)); \ } \ } while (0) \ auto& item = pipelineRequests.editItemAt(i); item.requestNo = appRequests[i].frameNo; _CLONE_(item.vIImageBuffers, appRequests[i].vInputImageBuffers); _CLONE_(item.vOImageBuffers, appRequests[i].vOutputImageBuffers); _CLONE_(item.vIMetaBuffers, appRequests[i].vInputMetaBuffers);#undef _CLONE_ } // // Since this call may block, it should be performed out of locking. err = pPipelineModel->submitRequest(pipelineRequests, numRequestProcessed); if ( OK != err || requests.size() != numRequestProcessed ) { MY_LOGE("%u/%zu requests submitted sucessfully - err:%d(%s)", numRequestProcessed, pipelineRequests.size(), -err, ::strerror(-err)); return err; }#endif // return OK;}
更多相关文章
- android 获取配置文件 相对路径
- Android关于读取临时文件
- Android下载并打开pdf文件
- Android HTTP GET 小文件下载
- Android中播放mp3文件
- Android 文件的下载
- android获取sd卡路径方法
- android选取照片并以其uri取得绝对路径