SnapdragonCamera骁龙相机源码解析

骁龙相机是高通开发的一个测试系统摄像头的demo,代码完善,功能强大。可以配合Camera驱动进行功能联调。

很多逻辑代码在CaptureModule.java里。

CaptureModule有8000多行,包罗万象。

涉及到界面显示要结合CaptureUI.java 一起来实现。

CaptureActivity持有了 CaptureModule 和 CaptureUI 。

以上是主要的引用关系。

CameraActivity 中调用了以下代码

复制代码
            case ModuleSwitcher.CAPTURE_MODULE_INDEX:
                if(mCaptureModule == null) {
                    mCaptureModule = new CaptureModule();
                    //核心代码!!!
                    mCaptureModule.init(this, mCameraCaptureModuleRootView);
                } else {
                    mCaptureModule.reinit();
                }
                mCurrentModule = mCaptureModule;
                mCameraCaptureModuleRootView.setVisibility(View.VISIBLE);
                Log.e("CameraActity"," setModuleFromIndex =================== CAPTURE_MODULE_INDEX");
                break;

CaptureModule 里初始化代码:

复制代码
@Override
    public void init(CameraActivity activity, View parent) {
        mActivity = activity;
        mRootView = parent;
        mSettingsManager = SettingsManager.getInstance();
        mSettingsManager.createCaptureModule(this);
        mSettingsManager.registerListener(this);
        if (mSettingsManager.mIsHasOneCamera) {
            CURRENT_ID = 0;
        } else {
            if (isBackCameraId()) {
                CURRENT_ID = BACK_MODE;
            } else {
                CURRENT_ID = FRONT_MODE;
            }
        }
        mSettingsManager.init();
        mFirstPreviewLoaded = false;
        Log.d(TAG, "init");
        for (int i = 0; i < MAX_NUM_CAM; i++) {
            mCameraOpened[i] = false;
            mTakingPicture[i] = false;
        }
        for (int i = 0; i < MAX_NUM_CAM; i++) {
            mState[i] = STATE_PREVIEW;
        }
        SceneModule module;
        for (int i = 0; i < mSelectableModes.length + 2; i++) {
            module = new SceneModule();
            module.mode = CameraMode.values()[i];
            mSceneCameraIds.add(module);
        }
        mPostProcessor = new PostProcessor(mActivity, this);
        mFrameProcessor = new FrameProcessor(mActivity, this);

        mContentResolver = mActivity.getContentResolver();
        initModeByIntent();
        initCameraIds();
        mUI = new CaptureUI(activity, this, parent);
        mUI.initializeControlByIntent();

        mFocusStateListener = new FocusStateListener(mUI);
        mLocationManager = new LocationManager(mActivity, this);
    }

通过以下代码初始化CaptureUI

复制代码
 mUI = new CaptureUI(activity, this, parent);
        mUI.initializeControlByIntent();

介绍一个核心操作来,了解是如何切换拍照模式的。

首先,通过CaptureUI ,来对组件赋予监听回调。

复制代码
mFlashButton = (FlashToggleButton) mRootView.findViewById(R.id.flash_button);
        mModeSelectLayout = (RecyclerView) mRootView.findViewById(R.id.mode_select_layout);
        mModeSelectLayout.setLayoutManager(new LinearLayoutManager(mActivity,
                LinearLayoutManager.HORIZONTAL, false));
        mCameraModeAdapter = new Camera2ModeAdapter(mModule.getCameraModeList());

   //设置单击回调 
       mCameraModeAdapter.setOnItemClickListener(mModule.getModeItemClickListener());
        mModeSelectLayout.setAdapter(mCameraModeAdapter);
        mSettingsIcon = (ImageView) mRootView.findViewById(R.id.settings);
        mSettingsIcon.setImageResource(R.drawable.settings);
        mSettingsIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openSettingsMenu();
            }
        });

对应CaptureModule的处理。

复制代码
 public OnItemClickListener getModeItemClickListener() {
        return new OnItemClickListener() {
            @Override
            public int onItemClick(int mode) {
                if (showLog) Log.e(TAG, "mode >>> " + mode);
                if (!getCameraModeSwitcherAllowed()) {
                    return -1;
                }
                if (mode == CameraMode.VIDEO.ordinal()) {
                    videoCameraId = -1;
                    videoType = VIDEO_DEFAULT;
                } else {
                    if (mode == CameraMode.MACRO.ordinal() || mode == CameraMode.NIGHT.ordinal()) {
                        videoCameraId = -1;
                        videoType = -1;
                    }
                }
                return selectCameraMode(mode);
            }
        };
    }

CaptureModule 核心代码处理:

复制代码
public int selectCameraMode(int mode) {
        if (showLog) Log.e("CaptureModule", "  mode:: ============== " + mode);
        if (showLog)
            Log.e("CaptureModule", "  mCurrentSceneMode.mode:: =================== " + mCurrentSceneMode.mode);

        for (SceneModule sceneModule : mSceneCameraIds) {
            if (showLog) Log.e(TAG, " secenmode:: >> " + sceneModule.mode);
        }

        if (showLog)
            Log.e("CaptureModule", "  mSceneCameraIds.get(mode).mode:: =================== " + mSceneCameraIds.get(mode).mode);
        if (showLog) Log.e("CaptureModule", "  videoType:: =================== " + videoType);
        if (showLog)
            Log.e("CaptureModule", "  videoCameraId:: =================== " + videoCameraId);
        showCameraDevice();

        String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);
        boolean post = false;
        if (mode == CameraMode.VIDEO.ordinal()) {
            videoType = VIDEO_DEFAULT;
            videoCameraId = 0;
        } else if (mode == CameraMode.MACRO.ordinal()) {
            if (value != null && value.equals("front")) {
                post = true;
                if (!isBackCamera()) {
                    mUI.performCameraSwitchClick();
                }
            }
        } else if (mode == CameraMode.DEFAULT.ordinal()) {
            videoType = -1;
            videoCameraId = -1;
        } else if (mode == CameraMode.NIGHT.ordinal()) {
            if (value != null && value.equals("front")) {
                if (!isBackCamera()) {
                    post = true;
                    mUI.performCameraSwitchClick();
                }
            }
            if (showLog)
                Log.e("xxx", " mPreviewRequestBuilder.length ===========> " + mPreviewRequestBuilder.length);
            if (showLog)
                Log.e("xxx", " mPreviewRequestBuilder.length ===========> " + mPreviewRequestBuilder.length);
        } else if (mode == CameraMode.PRO_MODE.ordinal()) {
//            if (value != null && value.equals("front")) {
//                if (!isBackCamera()) {
//                    post = true;
//                    mUI.performCameraSwitchClick();
//                }
//            }
        } else if (mode == CameraMode.HFR.ordinal()) {
            if (value != null && value.equals("front")) {
                if (!isBackCamera()) {
                    post = true;
                    mUI.performCameraSwitchClick();
                }
            }
        }


        if (showLog)
            Log.e("CaptureModule", "  mode2:: ============== " + mode);
        if (showLog)
            Log.e("CaptureModule", "  mCurrentSceneMode.mode2 :: =================== " + mCurrentSceneMode.mode);
        if (showLog)
            Log.e("CaptureModule", "  mSceneCameraIds.get(mode).mode2 :: =================== " + mSceneCameraIds.get(mode).mode);
        showCameraDevice();

        nmode = mode;
        if (post) {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    selectModle(nmode);
                }
            }, 1000);
        } else {
            selectModle(mode);
        }
        return 1;
    }

以上经过定制后的代码。代码逻辑更加复杂。因为要支持,夜视和微距摄像头效果。还要支持前摄。

再调用selectModle方法

复制代码
selectModle(int mode) 
复制代码
private int selectModle(int mode) {
//        if (!isVideoModel) {
//            if (mCurrentSceneMode.mode == mSceneCameraIds.get(mode).mode) {
//                return -1;
//            }
//        }
        showCameraDevice();
        setCameraModeSwitcherAllowed(false);
        setNextSceneMode(mode);
        SceneModule nextSceneMode = mSceneCameraIds.get(mode);
        String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);
        if (showLog)
            Log.e(TAG, " =============== current Mode is :::  " + mCurrentSceneMode.mode.ordinal());
        if (value != null && value.equals("front") &&
                (nextSceneMode.mode == CameraMode.RTB
                        || nextSceneMode.mode == CameraMode.SAT
                        || nextSceneMode.mode == CameraMode.PRO_MODE
                )) {
            if (showLog)
                Log.e(TAG, " selectModle begin set value KEY_FRONT_REAR_SWITCHER_VALUE  rear ==========   mode:: " + mode);
            mSettingsManager.setValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE, "rear");
        } else {
            if (showLog) Log.e(TAG, " restartAll ==========   mode:: " + mode);
            restartAll();

        }
        updateZoomSeekBarVisible();
        return 1;
    }

再调用 restartAll方法

复制代码
 public void restartAll() {
        showCameraDevice();
        int nextCameraId = getNextScreneModeId(mNextModeIndex);
        CURRENT_ID = getMainCameraId();
        Log.d(TAG, "restart all CURRENT_ID :" + CURRENT_ID + " nextCameraId :" + nextCameraId);


        if (CURRENT_ID == nextCameraId && mCameraDevice[nextCameraId] != null) {
            mIsCloseCamera = false;
        } else {
            mIsCloseCamera = true;
        }
        SceneModule nextSceneModule = mSceneCameraIds.get(mNextModeIndex);
        if (nextSceneModule.mode == CameraMode.DEFAULT
                || nextSceneModule.mode == CameraMode.PRO_MODE
                || nextSceneModule.mode == CameraMode.HFR
        ) {
            mIsCloseCamera = true;
        }
        if (mCameraDevice[nextCameraId] == null) {
            if (showLog) Log.e(TAG, "  mCameraDevice[nextCameraId] is null " + nextCameraId);
        } else {
            if (showLog) Log.e(TAG, "  mCameraDevice[nextCameraId] is not null " + nextCameraId);
        }

在restartAll中执行各种Camera的初始化操作。首先要关闭原来的摄像头资源,再打开新的摄像头资源。各种操作都封装在以下几个方法。

复制代码
onPauseBeforeSuper();
if (showLog) Log.e(TAG, " do onPauseBeforeSuper");
onPauseAfterSuper(false);
if (showLog) Log.e(TAG, " do onPauseAfterSuper false");
reinitSceneMode();
if (showLog) Log.e(TAG, " do reinitSceneMode ");
onResumeBeforeSuper(true);
if (showLog) Log.e(TAG, " do onResumeBeforeSuper ");
onResumeAfterSuper(true);
if (showLog) Log.e(TAG, " do onResumeAfterSuper ");
setRefocusLastTaken(false);
if (showLog) Log.e(TAG, " do setRefocusLastTaken ");

打开摄像头的操作。

复制代码
onResumeAfterSuper 方法里的
复制代码
 if (mIsCloseCamera) {
            Message msg = Message.obtain();
            msg.what = OPEN_CAMERA;
            msg.arg1 = mCurrentSceneMode.getCurrentId();
            Log.d(TAG, "open is " + msg.arg1);
            if (mCameraHandler != null) {
                mCameraHandler.sendMessage(msg);
            }
        }

对应Handle的操作

复制代码
private class MyCameraHandler extends Handler {

        public MyCameraHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            int id = msg.arg1;
            switch (msg.what) {
                case OPEN_CAMERA:
                    openCamera(id);
                    break;
                case CANCEL_TOUCH_FOCUS:
                    cancelTouchFocus(id);
                    break;
            }
        }
    }

执行openCamra操作:

复制代码
private void openCamera(int id) {
        if (mPaused) {
            return;
        }
        if (showLog) Log.e(TAG, "openCamera  1111 " + id);
        CameraManager manager;
        try {
            manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
            mCameraId[id] = manager.getCameraIdList()[id];
            if (!mCameraOpenCloseLock.tryAcquire(5000, TimeUnit.MILLISECONDS)) {
                Log.d(TAG, "Time out waiting to lock camera opening.");
                throw new RuntimeException("Time out waiting to lock camera opening");
            }
            manager.openCamera(mCameraId[id], mStateCallback, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            if (showLog) Log.d(TAG, "openCamera CameraAccessException  2222" + id);
        } catch (InterruptedException e) {
            e.printStackTrace();
            if (showLog) Log.d(TAG, "openCamera InterruptedException  3333 " + id);
        } catch (Exception e) {
            e.printStackTrace();
            if (showLog) Log.d(TAG, "openCamera Exception  44444 " + id);
        }
        if (showLog) Log.d(TAG, "openCamera  end  55555 " + id);
    }

回调mStateCallback 操作。

复制代码
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(CameraDevice cameraDevice) {
            int id = Integer.parseInt(cameraDevice.getId());
            Log.d(TAG, "onOpened " + id);
            mCameraOpenCloseLock.release();
            if (mPaused) {
                return;
            }
            showCameraDevice();
            if (showLog)
                Log.e(TAG, "mStateCallback  onOpened  ========== id:: " + id);
            mCameraDevice[id] = cameraDevice;
            mCameraOpened[id] = true;

            if (isBackCamera() && getCameraMode() == DUAL_MODE && id == BAYER_ID) {
                Message msg = mCameraHandler.obtainMessage(OPEN_CAMERA, MONO_ID, 0);
                mCameraHandler.sendMessage(msg);
            } else {
                mCamerasOpened = true;
                if (showLog)
                    Log.e(TAG, "mStateCallback  onOpened  ========== mCamerasOpened:: " + mCamerasOpened);
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (showLog)
                            Log.e(TAG, "mStateCallback  onOpened  ========== mUI.onCameraOpened:: ");
                        mUI.onCameraOpened(mCurrentSceneMode.getCurrentId());
                        if (showLog)
                            Log.e(TAG, "mStateCallback  onOpened  ========== mUI.onCameraOpened:: end ");
                    }
                });
                showCameraDevice();
                createSessions();
            }
        }

注意 mCameraDevice[id] = cameraDevice; 和 mCameraOpened[id] = true; 有几个摄像头就有几个mCameraDevice。id就是CameraId,一般就是其下标。

同样会有一个非常重要的函数 createSessions() ,有了 CameraDevice就要创建 CaptureSeesion。

复制代码
private void createSessions() {
        if (PersistUtil.isTraceEnable())
            Trace.beginSection("createSessions");
        if (mPaused || !mCamerasOpened || mTempHoldVideoInVideoIntent) return;
        int cameraId = mCurrentSceneMode.getCurrentId();
        if (showLog)
            Log.e(TAG, "createSessions : Current SceneMode is ==== " + mCurrentSceneMode.mode);
        Log.e(TAG, "createSessions : Current cameraId is ===== " + cameraId);
        showCameraDevice();
        switch (mCurrentSceneMode.mode) {
            case VIDEO:
            case VIDEO_NIGHT:
            case VIDEO_MACRO:
            case NIGHT:
                createSessionForVideo
                        (cameraId);
                break;
            case HFR:
                if (!HFR_RATE.equals("")) {
                    mSettingsManager.setValue(SettingsManager.KEY_VIDEO_HIGH_FRAME_RATE, HFR_RATE);
                }
                createSessionForVideo(cameraId);
                break;
            default:
                createSession(cameraId);
        }
        if (PersistUtil.isTraceEnable())
            Trace.endSection();
    }

对应的会执行2个方法,一个是创建Camera的Session createSession(cameraId) 一个是创建Video的Session createSessionForVideo(cameraId)

createSession()

复制代码
if (mChosenImageFormat == ImageFormat.YUV_420_888 || mChosenImageFormat == ImageFormat.PRIVATE) {
                    if (mPostProcessor.isZSLEnabled()) {
                        mPreviewRequestBuilder[id].addTarget(mImageReader[id].getSurface());
                        list.add(mPostProcessor.getZSLReprocessImageReader().getSurface());
                        if (mSaveRaw) {
                            mPreviewRequestBuilder[id].addTarget(mRawImageReader[id].getSurface());
                        }
                        mCameraDevice[id].createReprocessableCaptureSession(new InputConfiguration(mImageReader[id].getWidth(),
                                mImageReader[id].getHeight(), mImageReader[id].getImageFormat()), list, captureSessionCallback, mCameraHandler);
                    } else {
                        if (mSettingsManager.isHeifWriterEncoding() && outputConfigurations != null) {
                            mCameraDevice[id].createCaptureSessionByOutputConfigurations(outputConfigurations,
                                    captureSessionCallback, mCameraHandler);
                        } else {
                            mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);
                        }
                    }
                } else {
                    outputConfigurations = null;
                    if (ApiHelper.isAndroidPOrHigher() && outputConfigurations != null) {
                        Log.i(TAG, "list size:" + list.size());
                        Log.i(TAG, "create session 111 ");

                        createCameraSessionWithSessionConfiguration(id, outputConfigurations,
                                captureSessionCallback, mCameraHandler, mPreviewRequestBuilder[id]);

//                        mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);
                    } else {
                        Log.i(TAG, "create session 222 ");

                        mCameraDevice[id].createCaptureSession(list, captureSessionCallback, mCameraHandler);

                    }

captureSessionCallback 的操作

复制代码
CameraCaptureSession.StateCallback captureSessionCallback =
                    new CameraCaptureSession.StateCallback() {

                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                            if (mPaused || null == mCameraDevice[id] ||
                                    cameraCaptureSession == null) {
                                return;
                            }
                            Log.i(TAG, "cameracapturesession - onConfigured " + id);
                            setCameraModeSwitcherAllowed(true);
                            // When the session is ready, we start displaying the preview.
                            mCaptureSession[id] = cameraCaptureSession;
                            if (id == getMainCameraId()) {
                                mCurrentSession = cameraCaptureSession;
                            }
                            initializePreviewConfiguration(id);
                            setDisplayOrientation();
                            updateFaceDetection();
                            mFirstPreviewLoaded = false;
                            try {
                                if (isBackCamera() && getCameraMode() == DUAL_MODE) {
                                    linkBayerMono(id);
                                    mIsLinked = true;
                                }
                                // Finally, we start displaying the camera preview.
                                // for cases where we are in dual mode with mono preview off,
                                // don't set repeating request for mono
                                if (mCaptureSession[id] == null) {
                                    return;
                                }
//                                if (id == NIGHT_CAMRA_ID) { //Night模式
//                                    mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
//                                }
                                if (id == MONO_ID && !canStartMonoPreview()
                                        && getCameraMode() == DUAL_MODE) {
                                    mCaptureSession[id].capture(mPreviewRequestBuilder[id]
                                            .build(), mCaptureCallback, mCameraHandler);
                                } else {
                                    if (id == NIGHT_CAMRA_ID) { //Night模式
                                        mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
//                                        mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                                        Log.d(TAG, "createSession : mPreviewRequestBuilder FLASH_MODE_TORCH ===== ");
                                    }
                                    mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
                                            .build(), mCaptureCallback, mCameraHandler);
                                }
                                if (mIntentMode == INTENT_MODE_STILL_IMAGE_CAMERA &&
                                        mIsVoiceTakePhote) {
                                    mHandler.sendEmptyMessageDelayed(VOICE_INTERACTION_CAPTURE, 500);
                                }
                                if (isClearSightOn()) {
                                    ClearSightImageProcessor.getInstance().onCaptureSessionConfigured(id == BAYER_ID, cameraCaptureSession);
                                } else if (mChosenImageFormat == ImageFormat.PRIVATE && id == getMainCameraId()) {
                                    mPostProcessor.onSessionConfigured(mCameraDevice[id], mCaptureSession[id]);
                                }

                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            } catch (IllegalStateException e) {
                                e.printStackTrace();
                            } catch (IllegalArgumentException e) {
                                e.printStackTrace();
                            }
                            mCurrentSessionClosed = false;

                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                            if (showLog)
                                Log.e(TAG, "cameracapturesession - onConfigureFailed " + id);
                            setCameraModeSwitcherAllowed(true);
                            if (mActivity.isFinishing()) {
                                return;
                            }
//                            Toast.makeText(mActivity, "Camera Initialization Failed",
//                                    Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onClosed(CameraCaptureSession session) {
                            Log.d(TAG, "cameracapturesession - onClosed");
                            setCameraModeSwitcherAllowed(true);
                        }
                    };

createSessionForVideo()

复制代码
 if (showLog)
                Log.e(TAG, "createSessionForVideo   66666666666666 ");
            if (isHighSpeedRateCapture()) {
                int optionMode = isSSMEnabled() ? STREAM_CONFIG_SSM : SESSION_HIGH_SPEED;
                if (showLog)
                    Log.e("TAG", " buildConstrainedCameraSession in ");
                buildConstrainedCameraSession(mCameraDevice[cameraId], optionMode,
                        surfaces, mSessionListener, mCameraHandler, mVideoRecordRequestBuilder);
                if (showLog)
                    Log.e(TAG, "createSessionForVideo    77777777777777777");
            } else {
                if (showLog)
                    Log.e("TAG", " configureCameraSessionWithParameters in  cameraId :: " + cameraId);
                configureCameraSessionWithParameters(cameraId, surfaces,
                        mSessionListener, mCameraHandler, mVideoRecordRequestBuilder);
                if (showLog)
                    Log.e(TAG, "createSessionForVideo    888888888888");
            }

创建CameraSession和VideoSession的主要区别。

复制代码
CameraSession 使用了 mVideoRecordRequestBuilder 和  mPreviewRequestBuilder。
VideoSession 使用了 mVideoPreviewSurface 和 mMediaRecorderSurface。

CameraSession 通过拍照操作,来使用ImageReader获取图片数据。对应CameraSession有ImageReader实现的地方。

复制代码
 mCurrentSession.setRepeatingRequest(mVideoRecordRequestBuilder.build(),
                                mCaptureCallback, mCameraHandler);

执行以上操作后,就可以预览看到的内容了。

对应的,还有关闭Camera的操作。

复制代码
closeCamera()
复制代码
/**
     * Closes the current {@link CameraDevice}.
     */
    private void closeCamera() {
        Log.d(TAG, "closeCamera ============== begin");

        closeProcessors();

        /* no need to set this in the callback and handle asynchronously. This is the same
        reason as why we release the semaphore here, not in camera close callback function
        as we don't have to protect the case where camera open() gets called during camera
        close(). The low level framework/HAL handles the synchronization for open()
        happens after close() */

        try {
            // Close camera starting with AUX first
            for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
                if (null != mCameraDevice[i]) {
                    try {
                        if (!mCameraOpenCloseLock.tryAcquire(2000, TimeUnit.MILLISECONDS)) {
                            Log.d(TAG, "Time out waiting to lock camera closing.");
//                            throw new RuntimeException("Time out waiting to lock camera closing");
                        }
                    } catch (Exception e) {
                        mCameraOpenCloseLock.release();
                        e.printStackTrace();
                    }

                    Log.d(TAG, "Closing camera: " + mCameraDevice[i].getId());

                    // session was closed here if intentMode is INTENT_MODE_VIDEO
                    if (mIntentMode != INTENT_MODE_VIDEO) {
                        try {
                            if (isAbortCapturesEnable() && mCaptureSession[i] != null) {
                                mCaptureSession[i].abortCaptures();
                                Log.d(TAG, "Closing camera call abortCaptures ");
                            }
                            if (isSendRequestAfterFlushEnable() && mCaptureSession[i] != null) {
                                Log.v(TAG, "Closing camera call setRepeatingRequest");
                                mCaptureSession[i].setRepeatingRequest(mPreviewRequestBuilder[i].build(),
                                        mCaptureCallback, mCameraHandler);
                            }
                        } catch (IllegalStateException | CameraAccessException e) {
                            e.printStackTrace();
                        }
                    }
                    mCameraDevice[i].close();
                    mCameraDevice[i] = null;
                    mCameraOpened[i] = false;
                    mCaptureSession[i] = null;
                }
            }

            mIsLinked = false;

            if (null != mMediaRecorder) {
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
        } catch (RuntimeException e) {
            mCameraOpenCloseLock.release();
//            throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mCurrentSessionClosed = true;
            mCameraOpenCloseLock.release();
        }
        Log.d(TAG, "closeCamera ============== end");
    }
复制代码
closeImageReader()的操作
复制代码
private void closeImageReader() {
        for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
            if (null != mImageReader[i]) {
                mImageReader[i].close();
                mImageReader[i] = null;
            }
            if (null != mRawImageReader[i]) {
                mRawImageReader[i].close();
                mRawImageReader[i] = null;
            }
        }
        for (int i = mYUVCount - 1; i >= 0; i--) {
            if (null != mYUVImageReader[i]) {
                mYUVImageReader[i].close();
                mYUVImageReader[i] = null;
            }
        }
        if (null != mVideoSnapshotImageReader) {
            mVideoSnapshotImageReader.close();
            mVideoSnapshotImageReader = null;
        }
    }

closeProcessors()

复制代码
private void closeProcessors() {
        if (mPostProcessor != null) {
            mPostProcessor.onClose();
        }

        if (mFrameProcessor != null) {
            mFrameProcessor.onClose();
        }
    }

closeSessions()

复制代码
private void closeSessions() {
        for (int i = MAX_NUM_CAM - 1; i >= 0; i--) {
            if (null != mCaptureSession[i]) {
                if (mCamerasOpened) {
                    try {
                        if (mCurrentSession instanceof CameraConstrainedHighSpeedCaptureSession) {
                            List requestList = ((CameraConstrainedHighSpeedCaptureSession)
                                    mCurrentSession).createHighSpeedRequestList(
                                    mVideoRecordRequestBuilder.build());
                            mCurrentSession.captureBurst(requestList, null, mCameraHandler);
                        } else {
                            mCaptureSession[i].capture(mPreviewRequestBuilder[i].build(), null,
                                    mCameraHandler);
                        }
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    }
                }
                mCaptureSession[i].close();
                mCaptureSession[i] = null;
            }
        }
    }

以上是Camera的初始化流程,很复杂。这里单纯的是CaptureModule的逻辑。其中还要涉及到

复制代码
CaptureUI的逻辑交互。

其中主要调用 showRelatedIcons(CaptureModule.CameraMode mode),根据显示模式显示不同的界面。

复制代码
public void showRelatedIcons(CaptureModule.CameraMode mode) {
        //common settings
        mShutterButton.setVisibility(View.VISIBLE);
        mFrontBackSwitcher.setVisibility(View.VISIBLE);
        photoVideoSwitcher.setVisibility(View.INVISIBLE);
        txt_macro_advice.setVisibility(View.INVISIBLE);
        mMakeupButton.setVisibility(View.INVISIBLE);
        mSceneModeSwitcher.setVisibility(View.INVISIBLE);
        //settings for each mode
        switch (mode) {
            case DEFAULT:
                mFilterModeSwitcher.setVisibility(View.VISIBLE);
                mSceneModeSwitcher.setVisibility(View.VISIBLE);
                mVideoButton.setVisibility(View.INVISIBLE);
                mMuteButton.setVisibility(View.INVISIBLE);
                mPauseButton.setVisibility(View.INVISIBLE);
                break;
            case RTB:
            case SAT:
                mFilterModeSwitcher.setVisibility(View.VISIBLE);
                mSceneModeSwitcher.setVisibility(View.VISIBLE);
                mVideoButton.setVisibility(View.INVISIBLE);
                mFlashButton.setVisibility(View.INVISIBLE);
                mMuteButton.setVisibility(View.INVISIBLE);
                mPauseButton.setVisibility(View.INVISIBLE);
                if (!DEV_LEVEL_ALL) {
                    mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                }
                break;
            case VIDEO:
            case HFR:
                mFrontBackSwitcher.setVisibility(View.VISIBLE);
                photoVideoSwitcher.setVisibility(View.INVISIBLE);
                mVideoButton.setVisibility(View.VISIBLE);
                mFilterModeSwitcher.setVisibility(View.VISIBLE);
                if (mModule.isBackCamera()) {
                    mFlashButton.setVisibility(View.INVISIBLE);
                } else {
                    mFlashButton.setVisibility(View.VISIBLE);
                }
                mShutterButton.setVisibility(View.INVISIBLE);

                break;
            case PRO_MODE:
                mFilterModeSwitcher.setVisibility(View.INVISIBLE);
                mVideoButton.setVisibility(View.INVISIBLE);
                mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                mMuteButton.setVisibility(View.INVISIBLE);
                mPauseButton.setVisibility(View.INVISIBLE);
//                if (mModule.isBackCamera()) {
//                    mFlashButton.setVisibility(View.VISIBLE);
//                } else {
                mFlashButton.setVisibility(View.INVISIBLE);
//                }
                break;
            case MACRO:
                mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                photoVideoSwitcher.setVisibility(View.VISIBLE);
                ((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.video_switch);
                mVideoButton.setVisibility(View.INVISIBLE);
                mFilterModeSwitcher.setVisibility(View.INVISIBLE);
                txt_macro_advice.setVisibility(View.VISIBLE);
                break;
            case VIDEO_MACRO:
                mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                photoVideoSwitcher.setVisibility(View.VISIBLE);
                ((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.photo_switch);
                mVideoButton.setVisibility(View.VISIBLE);
                mFilterModeSwitcher.setVisibility(View.INVISIBLE);
                mShutterButton.setVisibility(View.INVISIBLE);
                txt_macro_advice.setVisibility(View.VISIBLE);
                break;
            case VIDEO_NIGHT:
                mFlashButton.setVisibility(View.VISIBLE);
                mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                photoVideoSwitcher.setVisibility(View.VISIBLE);
                ((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.photo_switch);
                mFilterModeSwitcher.setVisibility(View.INVISIBLE);
                mShutterButton.setVisibility(View.INVISIBLE);
                mVideoButton.setVisibility(View.VISIBLE);
                break;
            case NIGHT:
                mFlashButton.setVisibility(View.INVISIBLE);
                mFrontBackSwitcher.setVisibility(View.INVISIBLE);
                photoVideoSwitcher.setVisibility(View.VISIBLE);
                ((RotateImageView) photoVideoSwitcher).setImageResource(R.drawable.video_switch);
                mVideoButton.setVisibility(View.INVISIBLE);
                mFilterModeSwitcher.setVisibility(View.INVISIBLE);
                break;
            default:
                break;
        }

        String value = mSettingsManager.getValue(SettingsManager.KEY_FRONT_REAR_SWITCHER_VALUE);

        if (value == null) {
            mFrontBackSwitcher.setVisibility(View.INVISIBLE);
        }
        if (mModule.getVideoType() == CaptureModule.VIDEO_DEFAULT || mModule.getCurrenCameraMode() == CaptureModule.CameraMode.HFR) {
            photoVideoSwitcher.setVisibility(View.INVISIBLE);
            if (mModule.getCurrenCameraMode() == CaptureModule.CameraMode.HFR) {
                if (mModule.isBackCamera()) {
                    mFlashButton.setVisibility(View.VISIBLE);
                } else {
                    mFlashButton.setVisibility(View.INVISIBLE);
                }
            }
        }

        if (mModule.mMFNREnable && mModule.getMainCameraId() == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) {
            mFilterModeSwitcher.setVisibility(View.INVISIBLE);
        }
    }

源码多读,多多比较思考和跟踪代码的流程。

如何编译 在SnapdragonCamera工程呢?

执行

source ./build/envsetup.sh

执行

lunch

选择正确的配置

在SnapdragonCamera工程下,执行 ,

mm

编译即可。

执行

adb install -r ../../../../SnapdragonCamera.apk

安装即可。

相关推荐
鸿蒙布道师22 分钟前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
Harrison_zhu1 小时前
Ubuntu18.04 编译 Android7.1代码报错
android
CYRUS STUDIO3 小时前
Unidbg Trace 反 OLLVM 控制流平坦化(fla)
android·汇编·算法·网络安全·逆向·ollvm
扫地的小何尚4 小时前
NVIDIA工业设施数字孪生中的机器人模拟
android·java·c++·链表·语言模型·机器人·gpu
顾林海6 小时前
深度解析ArrayList工作原理
android·java·面试
安静的海岸_AI6 小时前
Android端WIFI/流量共存技术方案
android
_一条咸鱼_6 小时前
Android Compose 框架进度指示器深入剖析(五十二)
android
张风捷特烈6 小时前
Flutter 伪 3D 绘制#02 | 地平面与透视
android·flutter
每次的天空6 小时前
Kotlin 作用域函数:apply、let、run、with、also
android·开发语言·kotlin
重生之我在写代码6 小时前
如何进行apk反编译
android·程序员·编译器