Camera Preview the overall flow 预览整体流程

查看 81|回复 9
作者:djdgf4   
Preview the overall flow 预览整体流程



image.png (168.06 KB, 下载次数: 0)
下载附件
调用过程概览
2024-8-17 22:53 上传

[ol]

  • App在MainActivity 中使用一些预览控件,它们都包含一个surface作为取相机数据的容器。在openCamera之前:
    [ol]
  • 首先需要获取系统的 CameraManager实例,通过getSystemService(Context.CAMERA_SERVICE)方法获取。
  • 选择相机设备:使用  CameraManager 的  getCameraIdList()方法获取可用的相机设备列表,选择需要的相机设备的 ID
    [/ol]

  • 对于MainActivity 在onCreat的时候,调用API通知Framework Native Service-- CameraServer去 connect HAL ,打开硬件sensor

  • 相关函数、方法
    CameraManager.openCamera(String cameraId,  CameraDevice.StateCallback callback, @Nullable Handler handler)
    /*
    接口打开相机设备。
    @ String  cameraId:相机设备编号
    @ CameraDevice.StateCallback  callback:相机设备打开状态监听(判断相机打开是否成功)的回调对象(调用openCamera()时必须传入该回调对象,才能打开相机设备)
    @ Handler handler:指定执行回调方法的线程(可以是主线程,也可以后台线程)。
    */
            --> ...
                    --> private CameraDevice openCameraDeviceUserAsync(String cameraId,
                CameraDevice.StateCallback callback, Executor executor, final int uid)
                throws CameraAccessException
    对于 CameraDevice.StateCallback 须实现方法:
  • onOpened:相机设备打开完成时调用的方法(相机设备已就绪,可以调用 CameraDevice.createCaptureSession()来创建 CameraCaptureSession对象)。
  • onClosed:关闭相机设备时调用。
  • onDisconnected:相机设备不可再调用时调用(该回调内可调用 CameraDevice.close方法关闭相机设备)。
  • onError:相机设备不可再调用时调用(该回调内可调用 CameraDevice.close方法关闭相机设备)。

    对于 openCameraDeviceUserAsync 方法,主要做了下面几件事:
  • 获取当前cameraId指定相机的设备信息。(获取ICameraService代{过}{滤}理,调用其getCameraInfo方法获取当前设备的属性)
  • 利用获取相机的设备信息创建CameraDeviceImpl实例。(并将来自App的CameraDevice.StateCallback接口存入该实例中)
  • 调用远程CameraService获取当前相机的远程服务。(再将CameraDeviceImpl中的内部类CameraDeviceCallback作为参数通过ICameraService的connectDevice方法传入Camera Service去打开并获取一个ICameraDeviceUser代{过}{滤}理)
  • 将获取的远程服务设置到CameraDeviceImpl实例中(并将该代{过}{滤}理存入CameraDeviceImpl中进行管理。)
  • 返回CameraDeviceImpl实例

  • 流程概览图


  • OpenCamera成功的话,回调从CameraServer 通知到APP,在onOpened() 中调用preview的操作,在此时创建会话CameraCaptureSession 。创建过程中调用configStream(p)--参数中包含Surface的引用,也就是说,cameraServer包装了来自App的sureface容器为stream,再通过HIDL传给HAL,再由HAL继续configStream

  • 相关函数、方法
    CameraDevice.StateCallback.onOpened()// 回调方法,
            --> CameraDevice.createCaptureSession(SessionConfiguration config)
            /* @ SessionConfiguration  config: 会话配置参数(聚合类参数,包含创建CameraCaptureSession的所有参数)
                    在打开相机设备之后便需要去创建一个相机会话,用于传输图像请求,其最终实现是调用该方法来进行实现的,
                    而该方法会去调用到Camera Framework中的createCaptureSessionInternal方法,该方法主要做了两件事:
                    首先调用configureStreamsChecked方法来配置数据流。
                    其次实例化了一个CameraCaptureImpl对象,并通过传入CameraCaptureSession.StateCallback回调类将该对象发送至至App中。        
                            --> 而在configureStreamsChecked方法中会去调用ICameraDeviceUser代{过}{滤}理的一系列方法进行数据流配置,
                                            其中调用cancelRequest方法停掉当前的的预览流程,调用deleteStream方法删除之前的数据流,调用createStream创建新的数据流,
                                            最后调用endConfigure来进行数据流的配置工作,针对性的配置便在最后这个endConfigure方法中。
            */
            --> CameraCaptureSession.setRepeatingRequest(CaptureRequest request,  CameraCaptureSession.CaptureCallback callback,Handler handler)
                    /*
                     @ CaptureRequest request:无限期重复的CaptureRequest。
                        向Camera底层送一个CaptureRequest,底层不停重复送这一个CaptureRequest,不能为null
                     @ CameraCaptureSession.CaptureCallback callback:  CaptureRequest处理状态监听的回调。
                        当一个CaptureRequest发送给相机设备,使用这个监听器跟踪该CaptureRequest的处理进度,CaptureRequest完成处理时会通知该回调对象。
                        该回调对象的所有方法都有默认的空实现,也可根据需求重写相应方法。
                     @ Handler handler:
                        CaptureRequest回调方法执行的线程。如果为null,表示使用当前线程的looper
                     */
                             --> submitCaptureRequest
                             // Framework 层的方法。将此次Request下发到CameraService中。

  • SessionConfiguration 需配置参数:
    [ol]
  • session type:会话类型。
    常用普通预览使用 SessionConfiguration.SESSION_REGULAR,高速预览使用 SessionConfiguration.SESSION_HIGH_SPEED
  • List outputs:CameraCaptureSession的输出配置列表。
    根据不同的场景选择需要的surface,创建 OutputConfiguration列表,以拍照模式为例,选择相机预览、拍照所需的surface作为相机图像数据最终输出对象,创建 OutputConfiguration列表参数。
  • Executor executor:指定回调执行的线程。
    通常,建议不要在主(UI)线程上执行相机操作。
  • CameraCaptureSession.StateCallback cb:监听 CameraCaptureSession创建状态的回调对象。
    onConfigured和 onConfigureFailed两个抽象方法必须重写。
  • CaptureRequest参数: SessionConfiguration类对象实例化后,调用该类 setSessionParameters接口,设置创建 CameraCaptureSession时所需要的 CaptureRequest参数。根据场景,利用 CaptureRequest.Builder创建所需的 CaptureRequest参数,例如,预览时,创建 CameraDevice.TEMPLATE_PREVIEW类型的 CaptureRequest,并将预览用的surface添加到该 CaptureRequest,作为预览输出目标; 拍照时,创建 CameraDevice.TEMPLATE_STILL_CAPTURE类型CaptureRequest,并将拍照用的surface添加到该 CaptureRequest,作为拍照输出目标
    [/ol]

  • 而对于 CameraCaptureSession.StateCallback回调对象需实现方法:
    [ol]
  • onConfigured:会话配置完成, CameraCaptureSession创建成功(在该回调方法中可获取到 CameraCaptureSession实例,然后调用 CameraCaptureSession.setRepeatingRequest方法发送重复 CaptureRequest,开启预览)。
  • onConfigureFailed: CameraCaptureSession创建失败时调用,可能配置的Surface size不支持,或者Surface数量配置太多。
  • onActive:在 onConfigured后执行,即开始真的处理 CaptureRequest。
  • onReady:当 CameraCaptureSession没有 CaptureRequest可处理时调用。
  • onCaptureQueueEmpty:相机设备的输入CaptureRequest队列为空时回调。
  • onClosed: CameraCaptureSession关闭时调用。
    [/ol]
    以上 onConfigured 和  onConfigureFailed两个抽象方法必须实现,其余的可以空实现

  • CameraCaptureSession
    https://developer.android.google.cn/reference/android/hardware/camera2/CameraCaptureSession
    [table]
    [tr]
    [td]Nested classes[/td]
    [td][/td]
    [/tr]
    [tr]
    [td]class

    方法, 相机

  • heheluo   

    分享的知识很有用。
    qisangmo   

    谢谢分享
    coolcalf   

    图画得不错,你用什么工具画?
    business1   

    虽然看不懂,觉得很好👌🏻
    Lty20000423   


    coolcalf 发表于 2024-8-18 09:34
    图画得不错,你用什么工具画?

    应该是ROSE
    Maiz1888   

    大佬,第一张图用什么画的
    justwz   

    收藏了  虽然看不懂 但是看着是好东西
    djdgf4
    OP
      


    Maiz1888 发表于 2024-8-19 11:05
    大佬,第一张图用什么画的

    不是我画的,是谷歌官方的图,应该是Google的画布吧
    djdgf4
    OP
      


    coolcalf 发表于 2024-8-18 09:34
    图画得不错,你用什么工具画?

    不是我画的,是谷歌官方的图,应该是Google的画布吧
    您需要登录后才可以回帖 登录 | 立即注册