Resumen de aprendizaje de la cámara Android

Para comprender la cámara Android de manera más completa, decidí ordenar el flujo de trabajo desde la aplicación de la cámara hasta la capa HAL. La plataforma básica es qcom sdm845. La capa del núcleo no se ha estudiado y encontraré tiempo para estudiarla más tarde.

En primer lugar, puede obtener una comprensión más completa del conocimiento de la cámara de Android en https://source.android.google.cn/devices/camera . Solo hacemos un breve análisis de algunos enlaces.

1.1 El proceso principal de la capa de aplicación

El proceso principal de la capa de aplicación es el siguiente
Inserte la descripción de la imagen aquí

El principal proceso de solicitud es:

  1. Preparación de recursos de superficie
  2. proceso openCamera
  3. proceso createSession
  4. Vista previa y captura del proceso de solicitud
  5. Recepción de datos de cuadros, los principales propósitos son: recepción de datos Jepg, visualización de cuadros de vista previa, actualización de texturas, etc.

Analicemos el flujo del análisis anterior uno por uno.

2.1 Preparación de recursos superficiales

En el sistema de cámara, Surface no solo es un control de pantalla, sino también un portador para recibir y transmitir datos de cuadros.
El primer sistema de cámara necesita surface.dequeueBufferobtener el graphics buffer(padre ANativeWindowBuffer). Luego, pase el búfer al sistema de la cámara. Cuando el sistema de la cámara recibe los datos del cuadro, llena el búfer con surface.queueBufferlos datos del cuadro y luego devuelve los datos del cuadro a la superficie 1 en la llamada .

Hay muchos tipos de superficies, como SurfaceView, TextureVew, SurfaceTexture, ImageReader, etc. No analizaremos el proceso de creación en la aplicación.

2.2 proceso openCamera

El diagrama de flujo breve es el siguiente:
Inserte la descripción de la imagen aquí
openCamera involucra principalmente tres procesos

  1. El proceso de solicitud, FrameworkAPI pertenece al proceso
  2. Proceso de CameraService
  3. Proceso CameraProvider, camx pertenece a este proceso

No analizaremos el proceso detallado paso a paso, nos centraremos en el proceso principal de implementación de openCamera en CamX.

OpenCamera incluye principalmente dos procesos en CamX

  1. Cree un objeto HALDevice e inicialice su variable miembro m_camera3Device, m_camera3Device es un objeto de estructura camera3_device_t (redefine una estructura Camera3Device que sea igual a camera3_device_t en CamX, podemos pensar que es exactamente igual que camera3_device_t).
CamxResult HALDevice::Initialize(
    const HwModule* pHwModule,
    UINT32          cameraId)
{
    
    
    ....
    if (CamxResultSuccess == result)
    {
    
    
    //初始化m_camera3Device结构体对象
        m_camera3Device.hwDevice.tag     = HARDWARE_DEVICE_TAG; 
        m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_3;
        m_camera3Device.hwDevice.close   = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());
        m_camera3Device.pDeviceOps       = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());
        m_camera3Device.pPrivateData     = this;
        // NOWHINE CP036a: Need exception here
        m_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);
    //初始化m_HALCallbacks结构体对象并传递给CHI
        m_HALCallbacks.ProcessCaptureResult = ProcessCaptureResult;
        m_HALCallbacks.NotifyResult         = Notify;
        CamX::ChiOverrideBypass(&m_HALCallbacks);
    }
    return result;
}
  1. Inicialice la variable de miembro HALDevice m_pCamera3CbOps, el tipo m_pCamera3CbOps esCamera3CbOps
int initialize(
    const struct camera3_device*    pCamera3DeviceAPI,
    const camera3_callback_ops_t*   pCamera3CbOpsAPI)
{
    
    
 ...
 if (NULL != pCamera3CbOps)
 {
    
    
     pCamera3CbOps->cbOps.process_capture_result = process_capture_result;
     pCamera3CbOps->cbOps.notify = notify;
     pCamera3CbOps->pCamera3Device = pCamera3DeviceAPI;
     //将CameraProvider传递的指针暂存到pCbOpsAPI 中
     pCamera3CbOps->pCbOpsAPI = pCamera3CbOpsAPI;
     //给pCamera3CbOpsAPI 赋新的指针
     pCamera3CbOpsAPI = &(pCamera3CbOps->cbOps);
 }
 //将新指针设置到HALDevice对象m_pCamera3CbOps成员
 //这样做的目的是在调用CameraProvider的process_capture_result时
 //先打印一些帧信息,可以理解为复写函数
 return pHAL3->initialize(pCamera3DeviceAPI, pCamera3CbOpsAPI);
}

2.3 proceso createSession

Una vez que openCamera tiene éxito, CameraManager devolverá el objeto de la clase CameraDeviceImpl a CameraAPP y luego llamará al
método createCaptureSession para completar la creación de Stream. createCaptureSession finalmente completa la creación de Stream a través de configureStreamsChecked, el código es el siguiente:

//CameraDeviceImpl.java
public boolean configureStreamsChecked(InputConfiguration inputConfig,
        List<OutputConfiguration> outputs, int operatingMode)
                throws CameraAccessException {
    
    
    ....
    synchronized(mInterfaceLock) {
    
    
        ....
        //configStream之前首先需要停预览
        stopRepeating();

        try {
    
    
            //在configStream之前,需要等待Camera为IDLE状态
            waitUntilIdle();
            //mRemoteDevice为BpCameraDeviceUser代理对象
            //与其对应的BnCameraDeviceUser为CameraService中的
            //CameraDeviceClient
            //向CameraService申请开始config
            mRemoteDevice.beginConfigure();
            ....
            // Delete all streams first (to free up HW resources)
            for (Integer streamId : deleteList) {
    
    
                //向CameraService申请删除streamId应用Stream
                mRemoteDevice.deleteStream(streamId);
                mConfiguredOutputs.delete(streamId);
            }
            // Add all new streams
            for (OutputConfiguration outConfig : outputs) {
    
    
                if (addSet.contains(outConfig)) {
    
    
                    //向CameraService申请创建一个新的Stream
                    //outConfig包含了创建Stream必需的Surface
                    //Surface的大小尺寸格式会决定Stream的大小尺寸格式
                    //创建成功后会返回创建的streamId
                    int streamId = mRemoteDevice.createStream(outConfig);
                    mConfiguredOutputs.put(streamId, outConfig);
                }
            }
            operatingMode = (operatingMode | (customOpMode << 16));
            //向CameraService申请完成创建Stream
            //operatingMode?
            //CameraService会根据上边创建的Stream
            //向Camx申请创建HAL层Stream
            mRemoteDevice.endConfigure(operatingMode);
            success = true;
        } catch (IllegalArgumentException e) {
    
    
            .....
        } catch (CameraAccessException e) {
    
    
            ....
        } finally {
    
    
            if (success && outputs.size() > 0) {
    
    
                mDeviceHandler.post(mCallOnIdle);
            }
        }
    }

    return success;
}

Según la función anterior, el flujo de configuración es el siguiente:

  1. beginConfigure
  2. deleteStream / createStream
  3. endConfigure

Analizamos uno a uno, su realización

2.3.1 proceso beginConfigure

CameraService no hace nada para beginConfigure, el código es el siguiente:

binder::Status CameraDeviceClient::beginConfigure() {
    
    
    ALOGV("%s: Not implemented yet.", __FUNCTION__);
    return binder::Status::ok();
}

2.3.2 proceso deleteStream / createStream

Primero presentemos el proceso createStream

2.3.2.1 proceso createStream

Inserte la descripción de la imagen aquí

2.4 Vista previa y captura del proceso de solicitud

continuará. . . . .


  1. Para obtener una introducción más detallada, consulte el proceso de aplicación, entrega y devolución del búfer de gráficos de Android en CameraService, CameraProvider y CameraHAL . ↩︎

Supongo que te gusta

Origin blog.csdn.net/u010116586/article/details/106910001
Recomendado
Clasificación