android6.0源码分析之Camera API2.0下的初始化流程分析

2023-11-14

在文章android源码分析之Camera API2.0简介中,对Camera API2.0的框架以及代码做了简单介绍,本文将基于android6.0源码,分析Camera API2.0下的Camera2内置应用中,对Camera的初始化的流程分析,主要涉及Camera HAL3.0,Java 层的IPC Binder,Native层的CameraService的C/S服务架构等关键点。 
Camera2相关分析文章目录: 
android6.0源码分析之Camera API2.0简介 
android6.0源码分析之Camera2 HAL分析 
android6.0源码分析之Camera API2.0下的初始化流程分析 
android6.0源码分析之Camera API2.0下的Preview(预览)流程分析 
android6.0源码分析之Camera API2.0下的Capture流程分析 
android6.0源码分析之Camera API2.0下的video流程分析 
Camera API2.0的应用


1、Camera2初始化的应用层流程分析

Camera2的初始化流程与Camera1.0有所区别,本文将就Camera2的内置应用来分析Camera2.0的初始化过程。Camera2.0首先启动的是CameraActivity,而它继承自QuickActivity,在代码中你会发现没有重写OnCreate等生命周期方法,因为此处采用的是模板方法的设计模式,在QuickActivity中的onCreate方法调用的是onCreateTasks等方法,所以要看onCreate方法就只须看onCreateTasks方法即可:

//CameraActivity.java
@Override
public void onCreateTasks(Bundle state) {
    Profile profile = mProfiler.create("CameraActivity.onCreateTasks")
                            .start();
    ...
    mOnCreateTime = System.currentTimeMillis();
    mAppContext = getApplicationContext();
    mMainHandler = new MainHandler(this, getMainLooper());
    …
    try {
        //初始化OneCameraOpener对象
        ①mOneCameraOpener = OneCameraModule.provideOneCameraOpener(
                mFeatureConfig, mAppContext,mActiveCameraDeviceTracker,
                ResolutionUtil.getDisplayMetrics(this));
        mOneCameraManager = OneCameraModule.provideOneCameraManager();
    } catch (OneCameraException e) {...}
    …
    //建立模块信息
    ②ModulesInfo.setupModules(mAppContext, mModuleManager, mFeatureConfig);
    …
    //进行初始化
    ③mCurrentModule.init(this, isSecureCamera(), isCaptureIntent());
    …
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

如代码所示,重要的有以上三点,先看第一点:

//OneCameraModule.java
public static OneCameraOpener provideOneCameraOpener(OneCameraFeatureConfig     
            featureConfig, Context context, ActiveCameraDeviceTracker 
            activeCameraDeviceTracker,DisplayMetrics displayMetrics) 
            throws OneCameraException {
    //创建OneCameraOpener对象
    Optional<OneCameraOpener> manager = Camera2OneCameraOpenerImpl.create(
              featureConfig, context, activeCameraDeviceTracker, displayMetrics);
    if (!manager.isPresent()) {
        manager = LegacyOneCameraOpenerImpl.create();
    }
    ...
    return manager.get();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

它调用Camera2OneCameraOpenerImpl的create方法来获得一个OneCameraOpener对象,以供CameraActivity之后的操作使用,继续看create方法:

//Camera2OneCameraOpenerImpl.java
public static Optional<OneCameraOpener> create(OneCameraFeatureConfig 
            featureConfig, Context context, ActiveCameraDeviceTracker 
            activeCameraDeviceTracker, DisplayMetrics displayMetrics) {
    ...
    CameraManager cameraManager;
    try {
        cameraManager = AndroidServices.instance().provideCameraManager();
    } catch (IllegalStateException ex) {...}
    //新建一个Camera2OneCameraOpenerImpl对象
    OneCameraOpener oneCameraOpener = new Camera2OneCameraOpenerImpl(
                featureConfig, context, cameraManager,
                activeCameraDeviceTracker, displayMetrics);
    return Optional.of(oneCameraOpener);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

很明显,它首先获取一个cameraManger对象,然后根据这个cameraManager对象来新创建了一个Camera2OneCameraOpenerImpl对象,所以第一步主要是为了获取一个OneCameraOpener对象,它的实现为Camera2OneCameraOpenerImpl类。 
继续看第二步,ModulesInfo.setupModules:

// ModulesInfo.java
public static void setupModules(Context context, ModuleManager moduleManager,
            OneCameraFeatureConfig config) {
        Resources res = context.getResources();
        int photoModuleId = context.getResources().getInteger(
            R.integer.camera_mode_photo);
        //注册Photo模块
        registerPhotoModule(moduleManager, photoModuleId, 
            SettingsScopeNamespaces.PHOTO,config.isUsingCaptureModule());
        //计算你还Photo模块设置为默认的模块
        moduleManager.setDefaultModuleIndex(photoModuleId);
        //注册Videa模块
        registerVideoModule(moduleManager, res.getInteger(
            R.integer.camera_mode_video),SettingsScopeNamespaces.VIDEO);
        if (PhotoSphereHelper.hasLightCycleCapture(context)) {//开启闪光
            //注册广角镜头
            registerWideAngleModule(moduleManager, res.getInteger(
                R.integer.camera_mode_panorama),SettingsScopeNamespaces
                .PANORAMA);
            //注册光球模块
            registerPhotoSphereModule(moduleManager,res.getInteger(
                R.integer.camera_mode_photosphere),
                SettingsScopeNamespaces.PANORAMA);
        }
        //若需重新聚焦
        if (RefocusHelper.hasRefocusCapture(context)) {
            //注册重聚焦模块
            registerRefocusModule(moduleManager, res.getInteger(
                R.integer.camera_mode_refocus),
                SettingsScopeNamespaces.REFOCUS);
        }
        //如果有色分离模块
        if (GcamHelper.hasGcamAsSeparateModule(config)) {
            //注册色分离模块
            registerGcamModule(moduleManager, res.getInteger(
                R.integer.camera_mode_gcam),SettingsScopeNamespaces.PHOTO,
                config.getHdrPlusSupportLevel(OneCamera.Facing.BACK));
        }
        int imageCaptureIntentModuleId = res.getInteger(
            R.integer.camera_mode_capture_intent);
        registerCaptureIntentModule(moduleManager, 
            imageCaptureIntentModuleId,SettingsScopeNamespaces.PHOTO,
            config.isUsingCaptureModule());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

代码根据配置信息,进行一系列模块的注册,其中PhotoModule和VideoModule被注册,而其他的module则是根据配置来进行的,因为打开Camera应用,既可以拍照片也可以拍视频,此处,只分析PhoneModule的注册:

// ModulesInfo.java
private static void registerPhotoModule(ModuleManager moduleManager, final 
            int moduleId, final String namespace, 
            final boolean enableCaptureModule) {
        //向ModuleManager注册PhotoModule模块
        moduleManager.registerModule(new ModuleManager.ModuleAgent() {

            @Override
            public int getModuleId() {
                return moduleId;
            }

            @Override
            public boolean requestAppForCamera() {
                return !enableCaptureModule;
            }

            @Override
            public String getScopeNamespace() {
                return namespace;
            }

            @Override
            public ModuleController createModule(AppController app, Intent 
                    intent) {
                Log.v(TAG, "EnableCaptureModule = " + enableCaptureModule);
                //创建ModuleController
                return enableCaptureModule ? new CaptureModule(app) 
                        : new PhotoModule(app);
            }
        });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

由代码可知,它最终是由ModuleManager来新建一个CaptureModule实例,而CaptureModule其实实现了ModuleController ,即创建了一个CaptureModule模式下的ModuleController对象,而真正的CaptureModule的具体实现为ModuleManagerImpl。 
至此,前两步已经获得了OneCameraOpener以及新建了ModuleController,并进行了注册,接下来分析第三步,mCurrentModule.init(this, isSecureCamera(), isCaptureIntent()):

//CaptureModule.java
public void init(CameraActivity activity, boolean isSecureCamera, boolean 
            isCaptureIntent) {
        ...
        HandlerThread thread = new HandlerThread("CaptureModule.mCameraHandler");
        thread.start();
        mCameraHandler = new Handler(thread.getLooper());
        //获取第一步中创建的OneCameraOpener对象
        mOneCameraOpener = mAppController.getCameraOpener();

        try {
            //获取前面创建的OneCameraManager对象
            mOneCameraManager = OneCameraModule.provideOneCameraManager();
        } catch (OneCameraException e) {
            Log.e(TAG, "Unable to provide a OneCameraManager. ", e);
        }
       `...
        //新建CaptureModule的UI
        mUI = new CaptureModuleUI(activity, mAppController.
                getModuleLayoutRoot(), mUIListener);
        //设置预览状态的监听
        mAppController.setPreviewStatusListener(mPreviewStatusListener);
        synchronized (mSurfaceTextureLock) {
            //获取SurfaceTexture
            mPreviewSurfaceTexture = mAppController.getCameraAppUI()
                .getSurfaceTexture();
        }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

首先获取前面创建的OneCameraOpener对象以及OneCameraManager对象,然后再设置预览状态监听,这里主要分析预览状态的监听:

//CaptureModule.java
private final PreviewStatusListener mPreviewStatusListener = new 
    PreviewStatusListener() {
        ...

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, 
            int width, int height) {
            updatePreviewTransform(width, height, true);
            synchronized (mSurfaceTextureLock) {
                mPreviewSurfaceTexture = surface;
            }
            //打开Camera
            reopenCamera();
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.d(TAG, "onSurfaceTextureDestroyed");
            synchronized (mSurfaceTextureLock) {
                mPreviewSurfaceTexture = null;
            }
            //关闭Camera
            closeCamera();
            return true;
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, 
            int width, int height) {
            //更新预览尺寸
            updatePreviewBufferSize();
        }
        ...
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

由代码可知,当SurfaceTexture的状态变成可用的时候,会调用reopenCamera()方法来打开Camera,所以继续分析reopenCamera()方法:

//CaptureModule.java
private void reopenCamera() {
    if (mPaused) {
        return;
    }
    AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
        @Override
        public void run() {
            closeCamera();
            if(!mAppController.isPaused()) {
                //开启Camera并开始预览
                openCameraAndStartPreview();
            }
        }
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

它采用异步任务的方法,开启一个异步线程来进行启动操作,首先关闭打开的Camera,然后如果AppController不处于暂停状态,则打开Camera并启动Preview操作,所以继续分析openCameraAndStartPreview方法:

//CaptureModule.java
private void openCameraAndStartPreview() {
    ...
    if (mOneCameraOpener == null) {
        Log.e(TAG, "no available OneCameraManager, showing error dialog");
        //释放CameraOpenCloseLock锁
        mCameraOpenCloseLock.release();
        mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
        guard.stop("No OneCameraManager");
        return;
    }
    // Derive objects necessary for camera creation.
    MainThread mainThread = MainThread.create();

    //查找需要打开的CameraId
    CameraId cameraId = mOneCameraManager.findFirstCameraFacing(
        mCameraFacing);
    ...
    //打开Camera
    mOneCameraOpener.open(cameraId, captureSetting, mCameraHandler,
        mainThread, imageRotationCalculator, mBurstController, 
        mSoundPlayer,new OpenCallback() {

            @Override
            public void onFailure() {
                //进行失败的处理
                ...
            }

            @Override
            public void onCameraClosed() {
                ...
            }

            @Override
            public void onCameraOpened(@Nonnull final OneCamera camera) {
                Log.d(TAG, "onCameraOpened: " + camera);
                mCamera = camera;

                if (mAppController.isPaused()) {
                    onFailure();
                    return;
                }
                ...
                mMainThread.execute(new Runnable() {
                    @Override
                    public void run() {
                        //通知UI,Camera状态变化
                        mAppController.getCameraAppUI().onChangeCamera();
                        //使能拍照按钮
                        mAppController.getButtonManager().enableCameraButton();
                    }
                });
                //至此,Camera打开成功,开始预览                    
                camera.startPreview(new Surface(getPreviewSurfaceTexture()), 
                    new CaptureReadyCallback() {
                        @Override
                        public void onSetupFailed() {
                            ...
                        }

                        @Override
                        public void onReadyForCapture() {
                            //释放锁
                            mCameraOpenCloseLock.release();
                            mMainThread.execute(new Runnable() {
                                @Override
                                public void run() {
                                    ...
                                    onPreviewStarted();
                                    ...
                                    onReadyStateChanged(true);
                                    //设置CaptureModule为Capture准备的状态监听
                                    mCamera.setReadyStateChangedListener(
                                        CaptureModule.this);
                                        mUI.initializeZoom(mCamera.getMaxZoom());                                 
                                        mCamera.setFocusStateListener(
                                            CaptureModule.this);
                                    }
                                });
                            }
                        });
                    } 
              }, mAppController.getFatalErrorHandler());
        guard.stop("mOneCameraOpener.open()");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

首先,它主要会调用Camera2OneCameraOpenerImpl的open方法来打开Camera,并定义了开启的回调函数,对开启结束后的结果进行处理,如失败则释放mCameraOpenCloseLock,并暂停mAppController,如果打开成功,通知UI成功,并开启Camera的Preview,并且定义了Preview的各种回调操作,这里主要分析Open过程,所以继续分析:

//Camera2OneCameraOpenerImpl.java
@Override
public void open(
    ...
    mActiveCameraDeviceTracker.onCameraOpening(cameraKey);
    //打开Camera,此处调用框架层的CameraManager类的openCamera,进入frameworks层
    mCameraManager.openCamera(cameraKey.getValue(), 
        new CameraDevice.StateCallback() {
        private boolean isFirstCallback = true;
        @Override
        ...

        @Override
        public void onOpened(CameraDevice device) {
            //第一次调用此回调
            if (isFirstCallback) {
                isFirstCallback = false;
                try {
                    CameraCharacteristics characteristics = mCameraManager
                        .getCameraCharacteristics(device.getId());
                    ...
                    //创建OneCamera对象
                    OneCamera oneCamera = OneCameraCreator.create(device,
                        characteristics, mFeatureConfig, captureSetting,
                        mDisplayMetrics, mContext, mainThread,
                        imageRotationCalculator, burstController, soundPlayer,
                        fatalErrorHandler);

                    if (oneCamera != null) {
                        //如果oneCamera不为空,则回调onCameraOpened,后面将做分析
                        openCallback.onCameraOpened(oneCamera);
                    } else {
                        ...
                        openCallback.onFailure();
                    }
                } catch (CameraAccessException e) {
                    openCallback.onFailure();
                } catch (OneCameraAccessException e) {
                    Log.d(TAG, "Could not create OneCamera", e);
                    openCallback.onFailure();
                }
            }
        }
    }, handler);
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

至此,Camera的初始化流程中应用层的分析就差不多了,下一步将会调用CameraManager的openCamera方法来进入框架层,并进行Camera的初始化,下面将应用层的初始化时序图: 
这里写图片描述


2、Camera2初始化的框架层流程分析

由上面的分析可知,将由应用层进入到框架层处理,将会调用CameraManager的openCamera方法,并且定义了CameraDevice的状态回调函数,具体的回调操作此处不做分析,继续跟踪openCamera()方法:

//CameraManager.java(frameworks/base/core/java/android/hardware/camera2)
@RequiresPermission(android.Manifest.permission.CAMERA)
public void openCamera(@NonNull String cameraId,@NonNull final 
        CameraDevice.StateCallback callback, @Nullable Handler handler)
        throws CameraAccessException {
    ...
    openCameraDeviceUserAsync(cameraId, callback, handler);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

由代码可知,此处与Camera1.0有明显不同,Camera1.0是通过一个异步的线程以及JNI来调用android_hardware_camera.java里面的native_setup方法来连接Camera,其使用的是C++的Binder来与CameraService进行通信的,而此处则不一样,它直接使用的是Java层的Binder来进行通信,先看openCameraDeviceUserAsync代码:

//CameraManager.java(frameworks/base/core/java/android/hardware/camera2)
private CameraDevice openCameraDeviceUserAsync(String cameraId,
        CameraDevice.StateCallback callback, Handler handler)
        throws CameraAccessException {
    CameraCharacteristics characteristics = getCameraCharacteristics(
        cameraId);
    CameraDevice device = null;
    try {
        synchronized (mLock) {
            ICameraDeviceUser cameraUser = null;
            //初始化一个CameraDevice对象
            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                new android.hardware.camera2.impl.CameraDeviceImpl(cameraId,
                callback, handler, characteristics);
            BinderHolder holder = new BinderHolder();
            //获取回调
            ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
            int id = Integer.parseInt(cameraId);
            try {
                if (supportsCamera2ApiLocked(cameraId)) {
                    //通过Java层的Binder获取CameraService                        
                    ICameraService cameraService = CameraManagerGlobal.get()
                        .getCameraService();
                    ...
                    //通过CameraService连接Camera设备
                    cameraService.connectDevice(callbacks, id, mContext
                        .getOpPackageName(), USE_CALLING_UID, holder);
                    //获取连接成功的CameraUser对象,它用来与CameraService通信
                    cameraUser = ICameraDeviceUser.Stub.asInterface(
                        holder.getBinder());
                } else {
                    //使用遗留的API
                    cameraUser = CameraDeviceUserShim.connectBinderShim(
                        callbacks, id);
                }
            } catch (CameraRuntimeException e) {
                ...
        } catch (RemoteException e) {
            ...
            //将其包装成DeviceImpl对象,供应用层使用
            deviceImpl.setRemoteDevice(cameraUser);
            device = deviceImpl;
        }
    } catch (NumberFormatException e) {
        ...
    } catch (CameraRuntimeException e) {
        throw e.asChecked();
    }
    return device;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

此方法的目的是通过CameraService来连接并获取CameraDevice对象,该对象用来与Camera进行通信操作。代码首先通过Java层的Binder机制获取CameraService,然后调用其connectDevice方法来连接CaneraDevice,最后Camera返回的是CameraDeviceUser对象,而接着将其封装成Jav层CameraDevice对象,而之后所有与Camera的通信都通过CameraDevice的接口来进行。接下来分析一下Native层下的CameraDevice的初始化过程:

//CameraService.cpp,其中device为输出对象
status_t CameraService::connectDevice(const sp<ICameraDeviceCallbacks>& cameraCb,int cameraId,
        const String16& clientPackageName,int clientUid,/*out*/sp<ICameraDeviceUser>& device) {

    status_t ret = NO_ERROR;
    String8 id = String8::format("%d", cameraId);
    sp<CameraDeviceClient> client = nullptr;
    ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
            /*out*/client);//client为输出对象
    ...
    device = client;
    return NO_ERROR;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Native层的connectDevice方法就是调用了connectHelper方法,所以继续分析connectHelper:

//CameraService.h
template<class CALLBACK, class CLIENT>
status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int halVersion, const String16& clientPackageName, int clientUid,
        apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
    status_t ret = NO_ERROR;
    String8 clientName8(clientPackageName);
    int clientPid = getCallingPid();
    ...
    sp<CLIENT> client = nullptr;
    {
        ...

        //如果有必要,给FlashLight关闭设备的机会
        mFlashlight->prepareDeviceOpen(cameraId);
        //获取CameraId
        int id = cameraIdToInt(cameraId);
        ...
        //获取Device的版本,此处为Device3
        int deviceVersion = getDeviceVersion(id, /*out*/&facing);
        sp<BasicClient> tmp = nullptr;
        //获取client对象
        if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)) != NO_ERROR) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());
        //调用client的初始化函数来初始化模块
        if ((ret = client->initialize(mModule)) != OK) {
            ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
            return ret;
        }

        sp<IBinder> remoteCallback = client->getRemote();
        if (remoteCallback != nullptr) {
            remoteCallback->linkToDeath(this);
        }
    } // lock is destroyed, allow further connect calls
    //将client赋值给输出Device
    device = client;
    return NO_ERROR;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

CameraService根据Camera的相关参数来获取一个client,如makeClient方法,然后再调用client的initialize来进行初始化,首先看makeClient:

//CameraService.cpp
status_t CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp<BasicClient>* client) {

    //将字符串的CameraId转换成整形
    int id = cameraIdToInt(cameraId);
    ...
    if (halVersion < 0 || halVersion == deviceVersion) {//判断Camera HAL版本是否和Device的版本相同
        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
            if (effectiveApiLevel == API_1) {  // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new CameraClient(cameraService, tmp, packageName, id, facing,
                        clientPid, clientUid, getpid(), legacyMode);
            } else { // Camera2 API route
                ALOGW("Camera using old HAL version: %d", deviceVersion);
                return -EOPNOTSUPP;
            }
            break;
          case CAMERA_DEVICE_API_VERSION_2_0:
          case CAMERA_DEVICE_API_VERSION_2_1:
          case CAMERA_DEVICE_API_VERSION_3_0:
          case CAMERA_DEVICE_API_VERSION_3_1:
          case CAMERA_DEVICE_API_VERSION_3_2:
          case CAMERA_DEVICE_API_VERSION_3_3:
            if (effectiveApiLevel == API_1) { // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName, id, facing,
                        clientPid, clientUid, servicePid, legacyMode);
            } else { // Camera2 API route
                sp<ICameraDeviceCallbacks> tmp =
                        static_cast<ICameraDeviceCallbacks*>(cameraCb.get());
                *client = new CameraDeviceClient(cameraService, tmp, packageName, id,
                        facing, clientPid, clientUid, servicePid);
            }
            break;
          default:
            // Should not be reachable
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return INVALID_OPERATION;
        }
    } else {
        // A particular HAL version is requested by caller. Create CameraClient
        // based on the requested HAL version.
        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
            // Only support higher HAL version device opened as HAL1.0 device.
            sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
            *client = new CameraClient(cameraService, tmp, packageName, id, facing,
                    clientPid, clientUid, servicePid, legacyMode);
        } else {
            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
                    " opened as HAL %x device", halVersion, deviceVersion,
                    CAMERA_DEVICE_API_VERSION_1_0);
            return INVALID_OPERATION;
        }
    }
    return NO_ERROR;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

其中就是创建一个Client对象,由于此处分析的是Camera API2.0,其HAL的版本是3.0+,而Device的版本则其Device的版本即为3.0+,所以会创建一个CameraDeviceClient对象,至此,makeClient已经创建了client对象,并返回了,接着看它的初始化:

//CameraDeviceClient.cpp
status_t CameraDeviceClient::initialize(CameraModule *module)
{
    ATRACE_CALL();
    status_t res;
    //调用Camera2ClientBase的初始化函数来初始化CameraModule模块
    res = Camera2ClientBase::initialize(module);
    if (res != OK) {
        return res;
    }

    String8 threadName;
    //初始化FrameProcessor
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%d-FrameProc", mCameraId);
    mFrameProcessor->run(threadName.string());
    //并注册监听,监听的实现就在CameraDeviceClient类中
    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
            FRAME_PROCESSOR_LISTENER_MAX_ID, /*listener*/this,/*sendPartials*/true);
    return OK;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

它会调用Camera2ClientBase的initialize方法来初始化,并且会初始化一个FrameProcessor来进行帧处理,主要是回调每一帧的ExtraResult到应用中,也就是3A相关的数据信息。而Camera1.0中各种Processor模块,即将数据打包处理后再返回到应用的模块都已经不存在,而Camera2.0中将由MediaRecorder、SurfaceView、ImageReader等来直接处理,总体来说效率更好。继续看initialize:

// Camera2ClientBase.cpp
template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(CameraModule *module) {
    ...
    //调用Device的initialie方法
    res = mDevice->initialize(module);
    ...
    res = mDevice->setNotifyCallback(this);
    return OK;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

代码就是调用了Device的initialize方法,此处的Device是在Camera2ClientBase的构造函数中创建的:

// Camera2ClientBase.cpp
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(const sp<CameraService>& cameraService,
        const sp<TCamCallbacks>& remoteCallback,const String16& clientPackageName,
        int cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid):
        TClientBase(cameraService, remoteCallback, clientPackageName,cameraId, cameraFacing, 
        clientPid, clientUid, servicePid),mSharedCameraCallbacks(remoteCallback),
        mDeviceVersion(cameraService->getDeviceVersion(cameraId))
{
    ...
    mInitialClientPid = clientPid;
    mDevice = CameraDeviceFactory::createDevice(cameraId);
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

目前Camera API是2.0,而Device的API已经是3.0+了,继续看CameraDeviceFactory的createDevice方法:

// CameraDeviceFactory.cpp
sp<CameraDeviceBase> CameraDeviceFactory::createDevice(int cameraId) {

    sp<CameraService> svc = sService.promote();
    ...
    int deviceVersion = svc->getDeviceVersion(cameraId, /*facing*/NULL);

    sp<CameraDeviceBase> device;

    switch (deviceVersion) {
        case CAMERA_DEVICE_API_VERSION_2_0:
        case CAMERA_DEVICE_API_VERSION_2_1:
            device = new Camera2Device(cameraId);
            break;
        case CAMERA_DEVICE_API_VERSION_3_0:
        case CAMERA_DEVICE_API_VERSION_3_1:
        case CAMERA_DEVICE_API_VERSION_3_2:
        case CAMERA_DEVICE_API_VERSION_3_3:
            device = new Camera3Device(cameraId);
            break;
        default:
            ALOGE("%s: Camera %d: Unknown HAL device version %d",
                  __FUNCTION__, cameraId, deviceVersion);
            device = NULL;
            break;
    }
    return device;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

很显然,它将会创建一个Camera3Device对象,所以,Device的initialize就是调用了Camera3Device的initialize方法:

// Camera3Device.cpp
status_t Camera3Device::initialize(CameraModule *module)
{
    ...
    camera3_device_t *device;
    //打开Camera HAL层的Deivce
    res = module->open(deviceName.string(),
            reinterpret_cast<hw_device_t**>(&device));
    ...

    //交叉检查Device的版本
    if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
        SET_ERR_L("Could not open camera: "
                "Camera device should be at least %x, reports %x instead",
                CAMERA_DEVICE_API_VERSION_3_0,
                device->common.version);
        device->common.close(&device->common);
        return BAD_VALUE;
    }
    ...

    //调用回调函数来进行初始化,即调用打开Device的initialize方法来进行初始化
    res = device->ops->initialize(device, this);
    ...

    //启动请求队列线程
    mRequestThread = new RequestThread(this, mStatusTracker, device, aeLockAvailable);
    res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
    if (res != OK) {
        SET_ERR_L("Unable to start request queue thread: %s (%d)",
                strerror(-res), res);
        device->common.close(&device->common);
        mRequestThread.clear();
        return res;
    }
    ...
    //返回初始成功
    return OK;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

首先,会依赖HAL框架打开并获得相应的Device对象,具体的流程请参考android6.0源码分析之Camera2 HAL分析,然后再回调此对象的initialize方法进行初始化,最后再启动RequestThread等线程,并返回initialize成功。至此Camera API2.0下的初始化过程就分析结束了。框架层的初始化时序图如下: 
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android6.0源码分析之Camera API2.0下的初始化流程分析 的相关文章

  • 解释来自 Android 相机 onPictureTaken(byte[] data) 的原始图像数据

    我正在使用 Camera 类来拍照 并希望对 onPictureTaken 中的图像进行一些处理 如何解释字节数组 是RGB格式还是其他格式 参考文献说这取决于 Camera Parameters 相机参数 http developer a
  • 保存的图像方向错误

    我正在使用这段代码 https github com commonsguy cw advandroid blob master Camera Picture src com commonsware android picture Pictu
  • 相机插件 flutter web

    你好我想知道是否有一个用于 flutter web 的相机插件 以便拍摄照片并将其存储在临时路径中 然后将其上传到 firestorage 如果我理解正确 我希望您已经尝试过这些软件包 image picker 和 image picker
  • 如何使用flex4使用前置摄像头

    我使用 Flex 4 为 Android 移动设备开发了简单的相机应用程序 问题是 当我运行该应用程序时 它使用后置摄像头 它没有使用前置摄像头 怎么换相机啊 我需要使用前置摄像头来实现此应用程序 请帮助我 var camera Camer
  • 将预览帧转换为位图

    我知道这个主题已经在黑板上出现过很多次了 但无论如何我都无法让它发挥作用 我想将预览中的视图帧保存为 jpeg 文件 它看起来或多或少 代码被简化 没有额外的逻辑 异常等 像这样 public void onPreviewFrame byt
  • 使用 Android 相机进行图像处理

    我想使用 onPreviewFrame 在将图像显示给用户之前对其进行后处理 即应用色调 棕褐色等 据我了解 返回给回调的 byte 数据以 YUV420sp 编码 人们是否已经在 J ava 中或使用 NDK 本机代码 将其解码为 RGB
  • android 11 上 imageCapture 用例的camerax“未绑定到有效相机”

    我一直收到错误 未绑定到有效相机 当尝试实现 imageCapture 用例时 我正在按照camerax教程在Java中实现该功能here https codelabs developers google com codelabs came
  • 如何从里程计/tf数据获取投影矩阵?

    我想将视觉里程计的结果与 KITTI 数据集提供的事实进行比较 对于地面中的每一帧 我都有一个投影矩阵 例如 1 000000e 00 9 043683e 12 2 326809e 11 1 110223e 16 9 043683e 12
  • 适用于图片和视频的 Android 相机

    我想在我的 Android 应用程序中启动相机活动 并且我知道该怎么做 我想问当相机活动结束时 如何检查是否是用户拍摄的照片或视频 UPDATED 我有一个对话框 它询问两件事 新照片或视频 现有照片或视频 如果没有的话 1 这意味着相机将
  • Android 致命信号 11 (SIGSEGV) at 0x00000040 (code=1) 错误

    我正在开发一个 Android 应用程序 我正在其中获取用户照片图像 5张图像 使用opencv2 4 2具有面部检测功能的相机 并使用 Web 服务保存到服务器中的数据库中 为此 我使用 Opencv2 4 2 人脸检测示例 Ksoap2
  • OpenCV 从相机捕获 YUYV,无需 RGB 转换

    我尝试使用 openCV c 从 LI USB30 V024 立体相机捕获左右图像 而不自动将其转换为 RGB 相机输出 YUYV 格式的图像 我尝试使用 videoCapture set CV CAP PROP CONVERT RGB f
  • 3D 图形矩阵 4x4 中最后一行的 magic 4 的用途是什么?

    当我阅读有关WebGL的书时 我看到了下一个矩阵描述 有关于书中最后一行的信息 WebGL 初学者指南 初学者指南 Diego Cantor Brandon Jones 神秘的第四排 第四排没有任何特殊之处 意义 元素 m4 m8 m12
  • 上传前压缩相机图像

    我正在使用这段代码 来自www internetria com http www internetria com blog 2013 04 12 android enviar imagenes por webservice 拍照并上传到服务
  • 在 OpenGL 中移动相机时出现故障

    我正在为 iPhone 编写一个基于图块的游戏引擎 除了以下故障之外 它基本上可以正常工作 基本上 相机将始终将玩家保持在屏幕中央 并且它会移动以正确跟随玩家并在静止时正确绘制所有内容 然而 当玩家移动时 玩家行走的表面瓷砖会出现故障 如下
  • ipad 2相机支持检测

    我有一个使用以下宏的应用程序 define IS IPAD UIDevice currentDevice respondsToSelector selector userInterfaceIdiom UIDevice currentDevi
  • 使用畸变从图像平面计算相机矢量

    我正在尝试使用相机模型来重建可以使用某些相机及其 外部 内部 参数拍摄的图像 这一点我没有任何问题 现在我想添加扭曲 正如它们中所描述的那样OpenCV https docs opencv org 4 x dc dbb tutorial p
  • iOS 所需的设备功能自动对焦相机

    我有一个 iOS 应用程序 我在其中设置Required Device Capabilities配置设置需要两者still camera and auto focus camera因为它需要在具有更好的自动对焦相机传感器的新一代设备上运行
  • Three.js 设置并读取相机外观向量

    而不是使用camera rotation或lookAt 函数旋转相机 我想将外观矢量直接传递给相机 是否可以直接设置相机外观矢量以及是否可以从相机读取外观矢量 相机没有 外观矢量 因此无法设置它 但是 您可以构造一个point通过将您的外观
  • java.lang.RuntimeException:release()后调用的方法

    If i am 不使用 相机 release in 表面被破坏 then 无法从另一个 Activity 再次启动 CameraActivity 简而言之 得到不幸的是应用程序已停止 错误 即使不释放相机 但如果我确实点击了 主页 按钮 来
  • cameraOverlayView 防止使用 allowedEditing 进行编辑

    在我的应用程序中 使用以下行在拍摄照片后对其进行编辑 移动和缩放 效果很好 imagePicker setAllowsEditing YES 但如果我还使用cameraOverlayView 则编辑模式将不再起作用 屏幕出现 但平移和捏合手

随机推荐

  • https 是如何保护数据传输的

    为什么需要 https https 是 http ssl 也就是加密的 http 数据传输 我们都知道 https 的最主要的作用在于保证数据的安全 但具体来说 https 的安全性主要体现在以下两点 保证数据传输不被中间人盗用和信息的泄漏
  • GitHub开源协议

    开源协议 有名开源许可证 很多 经过Open Source Initiative组织 OSI批准 通过批准的开源协议目前有58种 常见的开源许可证包括 MIT MIT License GPL GNU General Public Licen
  • 预览word文件,支持下载(微软提供)

    预览打印 file 文件对象 url 接口地址 filepath 文件路径 filetype 文件类型 PS 兼容docx pdf后缀文件 export const filePreview file gt if file filepath
  • 三层架构:软件设计架构

    1 界面层 表示层 用户看的得界面 用户可以通过界面上的组件和服务器进行交互 2 业务逻辑层 处理业务逻辑的 3 数据访问层 操作数据存储文件
  • ---复位现象---GD32 MCU插入SD卡MCU立刻复位

    问题描述 程序运行正常 但是在插入SD卡的瞬间 单片机硬件复位 程序重新运行 之后状态一切正常 可以读取到SD卡 如果上电前插入SD卡 则一切正常 原因 使用示波器测试MCU电源 在SD卡插入瞬间 MCU电源电压跌落到2 5V以下 正常GD
  • 重载输入<<,输出>>,前置和后置++,--运算符

    由于系统给定的输入 lt lt 输出 gt gt 前置和后置 运算符只能处理类似于int float等系统已经定义好的类型的变量 为了能对我们自己定义的类的对象也能进行这些操作 我们就要重载这些运算符 定义一个复数类的对象 class Co
  • 基于OPENCV4的火焰烟雾检测

    现在目标检测主要采用深度学习训练模型 然后采用OPENCV4调用 烟雾火焰检测 采用CAFFE训练一个模型 采用OPENCV4调用 C PYTHON都可以调用 可以加Q 2830025146进行讨论 效果测试在 https download
  • 前端安全

    有哪些可能引起前端安全的问题 跨站脚本攻击 Cross Site Scripting XSS 一种代码注入方式 为了与 CSS 区分所以被称为 XSS 早期常见于网络论坛 起因是网站没有对用户的输入进行严格的限制 使得攻击者可以将脚本上传到
  • 行人重识别数据集汇总

    最近一段时间在做行人重识别方向的研究 行人重识别 Person Re Identification 作为图像识别领域的一个分支 在实际生活中具有极其重要的意义 目前 城市里的用于公共治安领域的摄像头已经大量部署 几乎到了几十米到几百米一个覆
  • Android 11(targetSdkVersion 30)不能获得存储权限的问题和适配指南

    虽然原文说的比较详细了 但我补充一两点 也为了方便自己总结和避坑 Android权限大致可分为三类 普通权限 只需要在清单文件中注册即可 危险权限 需要在代码中动态申请 以弹系统 Dialog 的形式进行请求 特殊权限 需要在代码中动态申请
  • 苹果新iPad创新乏力,中国发售遇冷失宠

    7月20日清晨 北京三里屯苹果店外有点冷清 十几个顾客在门口安静地排着队 曾经活跃的黄牛党没了踪影 守候在一旁的工作人员正在拆除原本打算维持秩序的护栏 如果不是店面上巨大的苹果标志 你恐怕很难把这个场景和苹果新品首发联系在一起 要知道在半年
  • 测试用例入门(三)-使用边界值分析法编写测试用例

    在 软件测试 一书中是这样描述边界值分析法的作用 如果在悬崖峭壁边可以自信 安全的行走而不掉下去 平地就不在话下了 本篇文章中的演示代码均由Python编写 目录 一 边界值分析法概述 二 边界条件的判断 三 边界两侧的判断 四 次边界条件
  • 输入华氏温度输出摄氏温度

    华氏温度转化为摄氏温度 c 5 9 f 32 数据 输入华氏温度 f 输出摄氏温度 c f int input 请输入华氏度 c f 32 5 9 print 6 2f华氏度对应的摄氏度为 6 2f f c 中间出过一点小问题 比如第一行双
  • input标签的类型

    今天学习突然想着input有哪些类型呢 然后就查了下资料 记录一下 1 文本框 type text 2 密码框 type password 3 单选框 type radio 4 复选框 type checkbox 5 图片上传 type f
  • linux切换用户时报错 this account is currently not available

    linux切换用户时报错 this account is currently not available 在安装完redis之后系统创建了一个名叫redis用户 但切换到这个用户的时候却报了错 this account is current
  • 网站怎么创建?

    网站怎么创建 现在很多公司企业都会有自己的网站 即使是没有网站的公司也抓紧时间纷纷入局 希望能在互联网的流量中分到一杯羹 那么网站怎么创建呢 下面给大家简单说一说 网站怎么创建步骤1 首先我们准备好一个域名 一个网站需要有域名才能访问 我们
  • 论文笔记:DEEP DECLARATIVE DYNAMIC TIME WARPING FOREND-TO-END LEARNING OF ALIGNMENT PATHS

    个人感觉 可微DTW的主要优点作为一个损失函数 可以进行梯度反向传播 如果目标只是两个时间序列的相似度 可能不太需要 1 Intro 1 1 背景 DTW 笔记 Dynamic Time Warping 动态时间规整 DTW的python实
  • 寒假训练 第一节 时空复杂度分析

    算法是由若干条指令所组成的的有穷序列 其中每一条指令表示计算机的一个或多个操作 一个好的算法首先要具备正确性 可读性和健壮性 在具备这三个条件后 就应该考虑算法的效率问题 即算法的时间效率和空间效率两方面 时间复杂度 一个算法所需要的运算时
  • windows 搭建ssh服务

    1 官网下载安装包 mls software com 2 点击安装 一直默认即可 3 配置 opensshServer 4 成功登录
  • android6.0源码分析之Camera API2.0下的初始化流程分析

    在文章android源码分析之Camera API2 0简介中 对Camera API2 0的框架以及代码做了简单介绍 本文将基于android6 0源码 分析Camera API2 0下的Camera2内置应用中 对Camera的初始化的