文章目录

  • 文件路径:src\main\java\net\sourceforge\opencamera\CameraXActivity.java
  • src\main\java\net\sourceforge\opencamera\preview\Preview.java
  • src\main\java\net\sourceforge\opencamera\cameracontroller\CameraController2.java
  • 通过Android SDK接口继续往下调用:

参考连接:
Android Camera模块解析之拍照
Android P Camera2相机简单解析

在学习Camera的过程中发现如果没有直观感受的界面供我们调试,不管是熟悉接口还是流程都会变得非常缓慢,学过去就忘了,下面我给大家剖析一个三方库 OpenCameraX大家可以直接下载导入AndroidStudio工程中运行,可以从App直接到Hal梳理拍照流程。

文件路径:src\main\java\net\sourceforge\opencamera\CameraXActivity.java

/ **用户已经按下了拍照按钮,或执行了相同的操作来请求拍照(例如,音量按钮,音频触发)。
* @param photo_snapshot如果为真,则用户请求在拍摄视频时拍照录音。如果为false,则拍照或启动/停止视频视情况而定当前模式。
* /
public void takePicture(boolean photo_snapshot) {if( applicationInterface.getPhotoMode() == CameraXApplicationInterface.PhotoMode.Panorama ) {if( preview.isTakingPhoto() ) {if( CameraXDebug.LOG )Log.d(TAG, "ignore whilst taking panorama photo");}else if( applicationInterface.getGyroSensor().isRecording() ) {if( CameraXDebug.LOG )Log.d(TAG, "panorama complete");applicationInterface.finishPanorama();return;}else if( !applicationInterface.canTakeNewPhoto() ) {if( CameraXDebug.LOG )Log.d(TAG, "can't start new panoroma, still saving in background");// we need to test here, otherwise the Preview won't take a new photo - but we'll think we've// started the panorama!}else {if( CameraXDebug.LOG )Log.d(TAG, "start panorama");applicationInterface.startPanorama();}}this.takePicturePressed(photo_snapshot, false);
}
/ * *
* @param photo_snapshot如果为真,则用户请求在拍摄视频时拍照录音。如果为false,则拍照或启动/停止视频视情况而定当前模式。
* @param continuous_fast_burst如果为真,那么开始一个连续的快速爆发。
* /
void takePicturePressed(boolean photo_snapshot, boolean continuous_fast_burst) {closePopup();this.last_continuous_fast_burst = continuous_fast_burst;this.preview.takePicturePressed(photo_snapshot, continuous_fast_burst);
}

src\main\java\net\sourceforge\opencamera\preview\Preview.java

/ **用户已点击“拍照”按钮(或等效的GUI操作)。
* @param photo_snapshot如果为真,则用户请求在拍摄视频时拍照录音。如果为false,则拍照或启动/停止视频视情况而定当前模式。
* @param continuous_fast_burst如果为真,那么开始一个连续的快速爆发。
* /
public void takePicturePressed(boolean photo_snapshot, boolean continuous_fast_burst) {if( camera_controller == null ) {if( CameraXDebug.LOG )Log.d(TAG, "camera not opened!");this.phase = PHASE_NORMAL;return;}if( !this.has_surface ) {if( CameraXDebug.LOG )Log.d(TAG, "preview surface not yet available");this.phase = PHASE_NORMAL;return;}if( is_video && continuous_fast_burst ) {Log.e(TAG, "continuous_fast_burst not supported for video mode");this.phase = PHASE_NORMAL;return;}if( is_video && isVideoRecording() && !photo_snapshot ) {// user requested stop videoif( !video_start_time_set || System.currentTimeMillis() - video_start_time < 500 ) {// if user presses to stop too quickly, we ignore// firstly to reduce risk of corrupt video files when stopping too quickly (see RuntimeException we have to catch in stopVideo),// secondly, to reduce a backlog of events which slows things down, if user presses start/stop repeatedly too quicklyif( CameraXDebug.LOG )Log.d(TAG, "ignore pressing stop video too quickly after start");}else {stopVideo(false);}return;}else if( ( !is_video || photo_snapshot ) && this.phase == PHASE_TAKING_PHOTO ) {// user requested take photo while already taking photoif( CameraXDebug.LOG )Log.d(TAG, "already taking a photo");if( remaining_repeat_photos != 0 ) {cancelRepeat();showToast(take_photo_toast, R.string.cancelled_repeat_mode);}else if( !is_video && camera_controller.getBurstType() == CameraController.BurstType.BURSTTYPE_FOCUS && camera_controller.isCapturingBurst() ) {camera_controller.stopFocusBracketingBurst();showToast(take_photo_toast, R.string.cancelled_focus_bracketing);}return;}if( !is_video || photo_snapshot ) {// check it's okay to take a photoif( !applicationInterface.canTakeNewPhoto() ) {if( CameraXDebug.LOG )Log.d(TAG, "don't take another photo, queue is full");return;}}// make sure that preview running (also needed to hide trash/share icons)this.startCameraPreview();if( photo_snapshot || continuous_fast_burst ) {// go straight to taking a photo, ignore timer or repeat optionstakePicture(false, photo_snapshot, continuous_fast_burst);return;}long timer_delay = applicationInterface.getTimerPref();String repeat_mode_value = applicationInterface.getRepeatPref();if( repeat_mode_value.equals("unlimited") ) {if( CameraXDebug.LOG )Log.d(TAG, "unlimited repeat");remaining_repeat_photos = -1;}else {int n_repeat;try {n_repeat = Integer.parseInt(repeat_mode_value);if( CameraXDebug.LOG )Log.d(TAG, "n_repeat: " + n_repeat);}catch(NumberFormatException e) {if( CameraXDebug.LOG )Log.e(TAG, "failed to parse repeat_mode value: " + repeat_mode_value);e.printStackTrace();n_repeat = 1;}remaining_repeat_photos = n_repeat-1;}if( timer_delay == 0 ) {takePicture(false, photo_snapshot, continuous_fast_burst);}else {takePictureOnTimer(timer_delay, false);}if( CameraXDebug.LOG )Log.d(TAG, "takePicturePressed exit");
}
/ **启动“拍照”命令。在视频模式下,启动视频命令。在拍照模式下,这可能首先涉及到自动对焦。
* @param photo_snapshot如果为真,则用户请求在拍摄视频时拍照录音。如果为false,则拍照或启动/停止视频视情况而定当前模式。
* @param continuous_fast_burst如果为真,那么开始一个连续的快速爆发。
* /
private void takePicture(boolean max_filesize_restart, boolean photo_snapshot, boolean continuous_fast_burst) {if( !is_video || photo_snapshot )this.phase = PHASE_TAKING_PHOTO;else {if( phase == PHASE_TIMER )this.phase = PHASE_NORMAL; // in case we were previously on timer for starting the video}synchronized( this ) {// synchronise for consistency (keep FindBugs happy)take_photo_after_autofocus = false;}if( camera_controller == null ) {if( CameraXDebug.LOG )Log.d(TAG, "camera not opened!");this.phase = PHASE_NORMAL;applicationInterface.cameraInOperation(false, false);if( is_video )applicationInterface.cameraInOperation(false, true);return;}if( !this.has_surface ) {if( CameraXDebug.LOG )Log.d(TAG, "preview surface not yet available");this.phase = PHASE_NORMAL;applicationInterface.cameraInOperation(false, false);if( is_video )applicationInterface.cameraInOperation(false, true);return;}boolean store_location = applicationInterface.getGeotaggingPref();if( store_location ) {boolean require_location = applicationInterface.getRequireLocationPref();if( require_location ) {if( applicationInterface.getLocation() != null ) {// fine, we have location}else {if( CameraXDebug.LOG )Log.d(TAG, "location data required, but not available");showToast(null, R.string.location_not_available);if( !is_video || photo_snapshot )this.phase = PHASE_NORMAL;applicationInterface.cameraInOperation(false, false);if( is_video )applicationInterface.cameraInOperation(false, true);return;}}}if( is_video && !photo_snapshot ) {if( CameraXDebug.LOG )Log.d(TAG, "start video recording");startVideoRecording(max_filesize_restart);return;}takePhoto(false, continuous_fast_burst);if( CameraXDebug.LOG )Log.d(TAG, "takePicture exit");
}

takePhoto()调用takePhotoWhenFocused()

    /** Take photo, assumes any autofocus has already been taken care of, and that applicationInterface.cameraInOperation(true, false) has*  already been called.*  Note that even if a caller wants to take a photo without focusing, you probably want to call takePhoto() with skip_autofocus*  set to true (so that things work okay in continuous picture focus mode).*/private void takePhotoWhenFocused(boolean continuous_fast_burst) {camera_controller.takePicture(pictureCallback, errorCallback);

调用CameraController2的takePicture()将CameraController.PictureCallback传达过去

public abstract void takePicture(final CameraController.PictureCallback picture, final ErrorCallback error);

src\main\java\net\sourceforge\opencamera\cameracontroller\CameraController2.java

@Override
public void takePicture(final PictureCallback picture, final ErrorCallback error) {boolean call_takePictureAfterPrecapture = false;boolean call_runFakePrecapture = false;boolean call_runPrecapture = false;synchronized( background_camera_lock ) {if( camera == null || captureSession == null ) {if( CameraXDebug.LOG )Log.d(TAG, "no camera or capture session");error.onError();return;}this.picture_cb = picture;this.jpeg_todo = true;this.raw_todo = imageReaderRaw != null;this.done_all_captures = false;this.take_picture_error_cb = error;this.fake_precapture_torch_performed = false; // just in case still on?if( !ready_for_capture ) {if( CameraXDebug.LOG )Log.e(TAG, "takePicture: not ready for capture!");//throw new RuntimeException(); // debugging}{if( CameraXDebug.LOG ) {Log.d(TAG, "current flash value: " + camera_settings.flash_value);Log.d(TAG, "use_fake_precapture_mode: " + use_fake_precapture_mode);}// Don't need precapture if flash off or torchif( camera_settings.flash_value.equals("flash_off") || camera_settings.flash_value.equals("flash_torch") || camera_settings.flash_value.equals("flash_frontscreen_torch") ) {call_takePictureAfterPrecapture = true;}else if( use_fake_precapture_mode ) {// fake flash auto/on mode// fake precapture works by turning on torch (or using a "front screen flash"), so we can't use the camera's own decision for flash auto// instead we check the current ISO valueboolean auto_flash = camera_settings.flash_value.equals("flash_auto") || camera_settings.flash_value.equals("flash_frontscreen_auto");Integer flash_mode = previewBuilder.get(CaptureRequest.FLASH_MODE);if( CameraXDebug.LOG )Log.d(TAG, "flash_mode: " + flash_mode);if( auto_flash && !fireAutoFlash() ) {if( CameraXDebug.LOG )Log.d(TAG, "fake precapture flash auto: seems bright enough to not need flash");call_takePictureAfterPrecapture = true;}else if( flash_mode != null && flash_mode == CameraMetadata.FLASH_MODE_TORCH ) {if( CameraXDebug.LOG )Log.d(TAG, "fake precapture flash: torch already on (presumably from autofocus)");// On some devices (e.g., OnePlus 3T), if we've already turned on torch for an autofocus immediately before// taking the photo, ae convergence may have already occurred - so if we called runFakePrecapture(), we'd just get// stuck waiting for CONTROL_AE_STATE_SEARCHING which will never happen, until we hit the timeout - it works,// but it means taking photos is slower as we have to wait until the timeout// Instead we assume that ae scanning has already started, so go straight to STATE_WAITING_FAKE_PRECAPTURE_DONE,// which means wait until we're no longer CONTROL_AE_STATE_SEARCHING.// (Note, we don't want to go straight to takePictureAfterPrecapture(), as it might be that ae scanning is still// taking place.)// An alternative solution would be to switch torch off and back on again to cause ae scanning to start - but// at worst this is tricky to get working, and at best, taking photos would be slower.fake_precapture_torch_performed = true; // so we know to fire the torch when capturingtest_fake_flash_precapture++; // for testing, should treat this same as if we did do the precapturestate = STATE_WAITING_FAKE_PRECAPTURE_DONE;precapture_state_change_time_ms = System.currentTimeMillis();}else {call_runFakePrecapture = true;}}else {// standard flash, flash auto or on// note that we don't call needsFlash() (or use is_flash_required) - as if ae state is neither CONVERGED nor FLASH_REQUIRED, we err on the side// of caution and don't skip the precapture//boolean needs_flash = capture_result_ae != null && capture_result_ae == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED;boolean needs_flash = capture_result_ae != null && capture_result_ae != CaptureResult.CONTROL_AE_STATE_CONVERGED;if( camera_settings.flash_value.equals("flash_auto") && !needs_flash ) {// if we call precapture anyway, flash wouldn't fire - but we tend to have a pause// so skipping the precapture if flash isn't going to fire makes this fasterif( CameraXDebug.LOG )Log.d(TAG, "flash auto, but we don't need flash");call_takePictureAfterPrecapture = true;}else {call_runPrecapture = true;}}}}// important to call functions outside of locks, so that they can in turn call callbacks without a lockif( call_takePictureAfterPrecapture ) {takePictureAfterPrecapture();}else if( call_runFakePrecapture ) {runFakePrecapture();}else if( call_runPrecapture ) {runPrecapture();}
}

takePictureAfterPrecapture(); runFakePrecapture(); runPrecapture();三个方法都会调用capture()

CameraController2.java

private void capture() throws CameraAccessException {capture(previewBuilder.build());
}private void capture(CaptureRequest request) throws CameraAccessException {synchronized( background_camera_lock ) {if( camera == null || captureSession == null ) {if( CameraXDebug.LOG )Log.d(TAG, "no camera or capture session");return;}captureSession.capture(request, previewCaptureCallback, handler);}
}

通过Android SDK接口继续往下调用:

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));}}

在当前文件下,我们看一下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<CaptureRequest> requestList = new ArrayList<CaptureRequest>();requestList.add(request);return submitCaptureRequest(requestList, callback, executor, /*streaming*/false);}...private int submitCaptureRequest(List<CaptureRequest> requestList, CaptureCallback callback,Executor executor, boolean repeating) throws CameraAccessException {// Need a valid executor, or current thread needs to have a looper, if// callback is validexecutor = 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 requestfor (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 surfaceIdxfor (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();}}

mRemoteDevice 又需要找一下在哪里进行初始化的了

    public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {synchronized(mInterfaceLock) {// TODO: Move from decorator to direct binder-mediated exceptions// If setRemoteFailure already called, do nothingif (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+ devicesICameraService 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 devicesint 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 statedeviceImpl.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 throwthrowAsPublicException(e);}} else {// Unexpected failure - rethrowthrowAsPublicException(e);}} catch (RemoteException e) {// Camera service died - act as if it's a CAMERA_DISCONNECTED caseServiceSpecificException 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;}

对之前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<hardware::camera2::CaptureRequest> requestList = { request };return submitRequestList(requestList, streaming, submitInfo);...binder::Status CameraDeviceClient::submitRequestList(const std::vector<hardware::camera2::CaptureRequest>& 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<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;std::list<const SurfaceMap> 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 idString8 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<int32_t> outputStreamIds;std::vector<std::string> requestedPhysicalIds;if (request.mSurfaceList.size() > 0) {for (sp<Surface> surface : request.mSurfaceList) {if (surface == 0) continue;int32_t streamId;sp<IGraphicBufferProducer> 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<camera_metadata_t *>(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 logsreturn 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 1ALOGV("%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<CameraProviderManager> 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<ICameraDeviceSession> 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<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.}});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<ResultMetadataQueue>& resQueue = mResultMetadataQueue;//获得结果队列,最终保存在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.}});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<const PhysicalCameraSettingsList> &requestsList,const std::list<const SurfaceMap> &surfaceMaps,int64_t *lastFrameNumber) {ATRACE_CALL();return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);
}
...
status_t Camera3Device::submitRequestsHelper(const List<const PhysicalCameraSettingsList> &requests,const std::list<const SurfaceMap> &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 callreturn res;}RequestList requestList;res = convertMetadataListToRequestListLocked(requests, surfaceMaps, repeating, /*out*/&requestList); //提交if (res != OK) {// error logged by previous callreturn 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<sp<CaptureRequest> > &requests,/*out*/int64_t *lastFrameNumber) {ATRACE_CALL();Mutex::Autolock l(mRequestLock);for (List<sp<CaptureRequest> >::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 waitUntilPausedmRequestSignal.signal();Mutex::Autolock p(mPauseLock);if (!mDoPause) {ALOGV("%s: RequestThread: Going active", __FUNCTION__);if (mPaused) {sp<StatusTracker> 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 anyint 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> statusTracker = mStatusTracker.promote();if (statusTracker != 0) {sp<Camera3Device> 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<camera3_capture_request_t*> 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 HALif (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchangedMutex::Autolock al(mLatestRequestMutex);camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);mLatestRequest.acquire(cloned);sp<Camera3Device> 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 oneATRACE_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 HALif (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchangedMutex::Autolock al(mLatestRequestMutex);camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);mLatestRequest.acquire(cloned);sp<Camera3Device> 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<camera3_capture_request_t*> requests(1);requests[0] = request;res = processBatchCaptureRequests(requests, &numRequestProcessed);//好吧,还是走Batchreturn res;
}
...
status_t Camera3Device::HalInterface::processBatchCaptureRequests(std::vector<camera3_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {ATRACE_NAME("CameraHal::processBatchCaptureRequests");if (!valid()) return INVALID_OPERATION;sp<device::V3_4::ICameraDeviceSession> 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<device::V3_2::CaptureRequest> captureRequests;hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;size_t batchSize = requests.size();if (hidlSession_3_4 != nullptr) {captureRequests_3_4.resize(batchSize);} else {captureRequests.resize(batchSize);}std::vector<native_handle_t*> 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<device::V3_2::BufferCache> cachesToRemove;{std::lock_guard<std::mutex> lock(mBufferIdMapLock);for (auto& pair : mFreedBuffers) {// The stream might have been removed since onBufferFreedif (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<const uint8_t*>(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<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),get_camera_metadata_size(request->settings));captureRequest->fmqSettingsSize = 0u;}} else {// A null request settings maps to a size-0 CameraMetadatacaptureRequest->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<const uint8_t*>(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<uint8_t*>(const_cast<camera_metadata_t*>(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

Return<void>
ThisNamespace::
processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests, const hidl_vec<BufferCache>& cachesToRemove, processCaptureRequest_cb _hidl_cb)
{uint32_t numRequestProcessed = 0;hidl_vec<V3_4::CaptureRequest> 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();
}
...
Return<void>
ThisNamespace::
processCaptureRequest_3_4(const hidl_vec<V3_4::CaptureRequest>& requests, const hidl_vec<BufferCache>& 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();
}
...
auto
ThisNamespace::
onProcessCaptureRequest(const hidl_vec<V3_4::CaptureRequest>& requests,const hidl_vec<BufferCache>& 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<IPipelineModelManager::AppRequest> pipelineRequests;
#endifauto pPipelineModel = getSafePipelineModel();::android::Vector<IAppStreamManager::Request> 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<std::shared_ptr<UserRequestParams>> vPipelineRequests(appRequests.size());for ( size_t i=0; i<appRequests.size(); ++i ) {auto& pItem = vPipelineRequests[i];pItem = std::make_shared<UserRequestParams>();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;}
#elsepipelineRequests.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;
}

Camera2 TakePicture流程相关推荐

  1. android camera(6)---camera2 拍照流程

    android camera2 拍照流程 正文 camera2 API 的加入是从AndroidV5.0(21)开始的,因此我们使用Camera2应该是在Android 5.0(含5.0)之后.同时, ...

  2. android camera2 API流程分析

    Android camera2 API流程分析 Android5.0之后,新推出来了一个类,android.hardware.camera2,与原来的camera的类实现照相和拍视频的流程有所不同,原 ...

  3. Camera1 源码解析系列(五)—— Camera1 takePicture() 流程解析

    前言 前面几篇文章已经把 Camera 控制流的部分梳理得比较清楚了.在 Camera 流程中,还有一个重要的部分,即数据流. Camera API 1 中,数据流主要是通过函数回调的方式,依照从下往 ...

  4. Android Camera 流程学习记录(五)—— Camera.takePicture() 流程解析

    简介 在前面的几篇笔记中,我已经把 Camera 控制流的部分梳理得比较清楚了.在 Camera 流程中,还有一个重要的部分,即数据流. Camera API 1 中,数据流主要是通过函数回调的方式, ...

  5. Camera2 openCamera 流程分析

    文章目录 一.相机架构 二.应用框架 1.Camera APP 2.AIDL 3.原生框架 4.binder IPC 接口 5.相机服务 6.HAL 三.open流程分析 1. CameraManag ...

  6. Camera2 OpenCamera流程

    和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 1.1.APP层传递摄像头id来打开摄像头 这里的callback是回调给APP的摄像头打开的结果 ha ...

  7. Camera1、Camera2 API的使用

    Camera1 使用流程: 检查相机权限(android.permission.CAMERA) Camera.getNumberOfCameras():获取相机硬件数量: Camera.getCame ...

  8. 展锐camera 调用流程

    本文将要为您介绍的是[Camera专题]Sprd-深入浅出Camera驱动框架1(HAL层-Kernel层),具体完成步骤: 一.前言 本文主要研究展讯平台Camera驱动和HAL层代码架构,熟悉展讯 ...

  9. Android Camera2 使用指北

    目录 Camera2 API使用 Camera2 使用流程简述 上面两幅图是camera硬件层面成像的基本流程,感觉图非常好,所以以此为开端! Camera2 API使用 1. 监听和枚举相机设备. ...

最新文章

  1. MySQL5.7在Ubuntu上的安装、配置与使用
  2. 借钱,一定要有还钱的素质
  3. 网易云音乐喊话酷狗称其“耍猴”:专利文件与“跟听”毫无关系
  4. 福利 | 闷骚的程序员是如何讲冷笑话的?
  5. android用户头像保存,Android的登陆注册(sharedpreferences和SQLite保存以及头像上传显示...
  6. 业务请求量膨胀的扩容技术实践
  7. 卧槽!火爆GitHub的算法电子书开放下载了!
  8. 雅虎开源色情图片检测神经网络
  9. Picture exceed the maximum allowable rotation range
  10. Verilog测试:TestBench结构
  11. MagicDraw 18.5 SP4
  12. WESTCAR系列的液力偶合器rotofluid、rotomec、kda
  13. 排球-五一跑位(转)
  14. python代码画玫瑰花
  15. Windows 常用dos命令大全
  16. linux系统读取plc状态,Linux系统下上位机通讯协议及PLC冗余系统组态-工业支持中心-西门子中国...
  17. python抓取免费ip存入redis
  18. java查看附近门店_微信公众号获取用户地理位置并列出附近的门店的示例代码...
  19. 网页html5播放器,一个强大的开源HTML5视频播放器,字节出品
  20. CAD中 OLE不能旋转_CAD制图初学入门教程:阵列功能的使用技巧

热门文章

  1. C#数据库编程入门:病人管理系统
  2. c#位图转换未矢量图_C#中如何生成矢量图
  3. 红旗linux如何联wifi,8089B开启Wifi的方法(默认的红旗linux系统)
  4. div.html attach html,attach.html
  5. 趋高智能机器视觉在机械手臂运动控制系统中的运用
  6. CSDN周赛第30期题目解析(天然气定单、小艺读书、买苹果、圆桌)
  7. 计算机软件测试技术 pdf,[计算机软件及应用]软件测试技术.pdf
  8. 交换机出现发送端无法连接接收端问题解决
  9. 软件著作权多久能申请下来
  10. mac shell创建文件/文件夹添加内容