Cámara Qualcomm HAL3: CAMX, explicación detallada de CHI-CDK

No hay muchos documentos introductorios sobre Qualcomm CameraHAL3 en Internet. He hecho un resumen y organización de Qualcomm CameraHAL3 antes. Es un poco complicado, así que me conformaré con ello.

1. Comprensión preliminar

Qualcomm CameraHAL3 tiene una arquitectura enorme y una gran cantidad de código.

Primero, tenga una comprensión preliminar de los términos y catálogos clave de CAMX y Chi-CDK.

1.1 Varios conceptos clave en el sistema CAMX CHI-CDK:

(1).Caso de uso: como sugiere el nombre, un "caso de uso" es un requisito funcional.
Por ejemplo, la función ZSL es un caso de uso, HDR es un caso de uso, multicámara es un caso de uso y
un caso de uso puede contener múltiples canalizaciones y múltiples funciones Característica, múltiples módulos isp, múltiples nodos.
Todo chi-cdk es un sistema construido en torno a la implementación de casos de uso.

(2)Pipeline: Se crea un canal de flujo de datos, por ejemplo, un flujo de vista previa o un canal de transmisión de video, estos flujos de datos circulan en forma de canales de canalización.

(3).Nodo: nodo de función. El algoritmo de la cámara que analizaremos más adelante es un nodo anidado en el flujo de la tubería. Este nodo es equivalente a realizar el contenido del algoritmo. Por ejemplo, el nodo dummyrtb
realiza el procesamiento de fusión de la cámara dual. data,
remosaic El nodo implementa la reordenación de datos y
el nodo staticaecalgo implementa el acceso a algoritmos AEC de terceros, etc.

(4) Objetivo: objeto de destino, utilizado para definir alguna información de parámetro utilizada

(5).Topología: todo el caso de uso, la canalización y la nota presentan una estructura de enlace topológico. Estas topologías se describen en forma de xml. Este xml describe la topología del caso de uso, el flujo de la canalización y la red en la función de cámara de todo el proyecto. .Parámetros de configuración de relaciones y sus parámetros, etc.

El proyecto SM7450 utiliza chi-cdk/oem/qcom/topology/titan/fillmore/fillmore_usecase.xml de forma predeterminada

1.2 Terminología

  • ABF: filtro automático de Bayer, algoritmo de reducción de ruido de dominio de Bayer
  • ACE: Mejora de croma avanzada Mejora de croma avanzada
  • ADRC: compresión automática del rango dinámico compresión automática del rango dinámico
  • AFD: Detección automática de parpadeo, detección automática de parpadeo
  • ASD: Detección automática de escena
  • ASF: filtro espacial adaptativo, filtrado espacial adaptativo
  • BDS: Escalador de descargas de Bayer
  • BPC: Corrección de píxeles incorrecta, corrección de píxeles incorrecta
  • BPS: segmento de procesamiento de Bayer (para instantáneas)
  • CDS:Chroma DownSampler
  • CDK: kit de desarrollo de cámara kit de desarrollo de cámara
  • CHI: Interfaz de hardware de cámara Interfaz de hardware de cámara
  • CS: Supresión de croma, supresión de croma
  • CSID: módulo decodificador de interfaz serie de cámara
  • CV:Mejora de croma Mejora de croma
  • DPU: unidad de procesamiento de visualización
  • GTM: Mapeo de tonos globales, mapeo de tonos globales
  • IFE: Image Front End, los datos emitidos por el sensor llegarán primero a IFE
  • IPE: motor de procesamiento de imágenes
  • KMD: Controlador de modo Kernal
  • LPM: administrador de bajo consumo (funciona con bajo consumo de energía)
  • LTM: Mapeo de tonos locales, mapeo de tonos locales
  • MCTF: Filtrado temporal de compensación de movimiento Reducción de ruido de fotogramas múltiples durante la grabación
  • MCE: mejora del color de la memoria
  • MFNR: Reducción de ruido de varios fotogramas Reducción de ruido de varios fotogramas al tomar fotografías
  • OPE: motor de procesamiento fuera de línea
  • PDAF: enfoque automático de diferencia de fase, enfoque de fase
  • QCFA: Disposición/matriz de filtros de color cuádruples (codificación Bayer)
  • RDI: Interfaz de volcado sin formato
  • RTB: Bokeh en tiempo real
  • SCE: mejora del color de la piel, mejora del color de la piel
  • TNR: reducción de ruido temporal, reducción de ruido en el dominio del tiempo
  • TFE: extremo frontal delgado
  • UMD: controlador de modo de usuario
  • VPU: Unidad de procesamiento de vídeo (códec)
  • WNR: reducción de ruido wavelet, reducción de ruido wavelet, algoritmo de reducción de ruido en el dominio Yuv

1.3 Directorio principal

1.3.1 Existen los siguientes directorios principales en CAMX:

  • core/: se utiliza para almacenar el módulo de implementación principal de camx, que también incluye el directorio hal/ utilizado principalmente para implementar la interfaz hal3 y el directorio chi/ responsable de interactuar con CHI.
  • csl/: se utiliza para almacenar el módulo de comunicación responsable principalmente de camx y el controlador de la cámara, proporcionando una interfaz de control del controlador de la cámara unificada para camx
  • hwl/: se utiliza para almacenar nodos de hardware con capacidades informáticas independientes. Esta parte del nodo es administrada por csl
  • swl/: se utiliza para almacenar nodos que no tienen capacidades informáticas independientes y deben depender de la CPU para implementarse

1.3.2 Existen los siguientes directorios principales en Chi-Cdk:

  • chioverride/: se utiliza para almacenar el módulo central de la implementación de CHI, responsable de interactuar con camx e implementar el marco general de CHI y el procesamiento comercial específico.
  • bin/: utilizado para almacenar elementos de configuración relacionados con la plataforma
  • topología/: se utiliza para almacenar archivos de configuración xml de Usecase definidos por el usuario
  • nodo/: nodo utilizado para almacenar funciones definidas por el usuario
  • módulo/: se utiliza para almacenar archivos de configuración de diferentes sensores.Esta parte es necesaria al inicializar el sensor.
  • tuning/: Archivos de configuración utilizados para almacenar parámetros de efectos en diferentes escenarios
  • sensor/: utilizado para almacenar información privada y registrar parámetros de configuración de diferentes sensores
  • actuador/: utilizado para almacenar información de configuración de diferentes módulos de enfoque
  • ois/: utilizado para almacenar la información de configuración del módulo anti-vibración
  • flash/: almacena la información de configuración del módulo flash
  • eeprom/: almacena la información de configuración del módulo de almacenamiento externo eeprom
  • fd/: almacena la información de configuración del módulo de reconocimiento facial

2. Arquitectura general de CAMX

2.1 Diagrama de arquitectura general de CAMX:

2.2 Mecanismo de comunicación CAMX CHI-CDK

CAMX y CHI-CDK obtuvieron el método de entrada de cada uno al abrir la biblioteca So de cada uno:

2.3 Dirección del flujo de datos de CameraHAL3

Diagrama de flujo de datos de CamraHAL3:

Cuando los datos de la cámara salen del sensor, primero pasarán por IFE y luego se dividirán en dos situaciones: vista previa/vídeo y toma de fotografías.

Si se trata de una vista previa o una grabación, IPE la procesa primero y finalmente la envía a la pantalla.

Si está tomando fotografías, primero son procesadas por BSP, luego pasan por el codificador JPEG y finalmente se guardan como salida de imagen.

IFE, IPE, BPS y JPEG representan respectivamente las unidades de procesamiento de hardware dentro del chip.

El procesamiento de datos dentro de estas unidades todavía es relativamente complicado. En diferentes unidades de procesamiento, se realizará algún procesamiento de algoritmos complejos. Aquí primero tenemos una comprensión y un concepto básico.

3. Componentes básicos de CAMX CHI-CDK

3.1 Caso de uso

UseCase, significado literal: caso de uso

Nota oficial:

Un conjunto de transmisiones configuradas por el cliente combinado con un conjunto de propiedades estáticas que especifican el procesamiento de esas transmisiones.

Un conjunto de flujos configurados por el cliente. Este conjunto de flujos es un flujo descrito por una serie de atributos estáticos.


Consulte createCaptureSession en la documentación de Android CameraDevice

Entendámoslo mejor con el siguiente código:

//UseCase: 预览+录像
List<Surface> surfaces = new ArrayList<>();

if(previewSurface != null && previewSurface.isValid()){
  surfaces.add(previewSurface);
  mPreviewBuilder.addTarget(previewSurface);
}

if(mMediaRecorder != null && mMediaRecorderSurface != null 
      && mMediaRecorderSurface.isValid()){
  surfaces.add(mMediaRecorderSurface);
  mPreviewBuilder.addTarget(mMediaRecorderSurface);
}

mCameraDevice.createCaptureSession(surfaces,...,...);

Este código establece tanto la superficie de vista previa como la superficie de grabación y luego crea una sesión.

Esto significa que necesito obtener los datos de la cámara tanto para la vista previa como para la grabación.

Supongamos que el tamaño de mi configuración de vista previa es 1080 x 720 y el video es 1080p, entonces esta vista previa de 1080 x 720 + video de 1080p

es un caso de uso

Otras analogías.

UsecaseId: \chi-cdk\core\chiutils\chxdefs.h

/// @brief Usecase identifying enums
enum class UsecaseId
{
    NoMatch             = 0,
    Default             = 1,
    Preview             = 2,
    PreviewZSL          = 3,
    MFNR                = 4,
    MFSR                = 5,
    MultiCamera         = 6,
    QuadCFA             = 7,
    RawJPEG             = 8,
    MultiCameraVR       = 9,
    Torch               = 10,
    YUVInBlobOut        = 11,
    VideoLiveShot       = 12,
    SuperSlowMotionFRC  = 13,
    Feature2            = 14,
    Depth               = 15,
    AON                 = 16,
    MaxUsecases         = 17,
};

chi-cdk/oem/qcom/topology/titan/fillmore/fillmore_usecase.xml

Este archivo xml describe 82 casos de uso, pero es posible que nuestras cámaras no necesariamente ejecuten todos estos casos de uso.

Estos xml solo describen configuraciones. La implementación de los casos de uso descritos depende de si se implementan en el código y habilitan estos casos de uso.

Por ejemplo, a menudo entramos en contacto con UsecaseTorch, UsecasePreview, UsecaseVideo, UsecaseSnapshot, UsecaseZSL, UsecaseQuadCFA, UsecaseRTB, UsecaseSAT, etc.

Seleccione ID de caso de uso

Diferentes UsecaseIds corresponden a diferentes "casos de uso".

Esta etapa se logra llamando al método UsecaseSelector::GetMatchingUsecase().

En esta función, el UsecaseId correspondiente se selecciona a través del modo de operación entrante, el flujo de datos de configuración num_streams, la cantidad y el número de sensores utilizados actualmente.

Por ejemplo, cuando el valor de numPhysicalCameras es mayor que 1 y el número de flujos de datos configurados al mismo tiempo, num_streams, es mayor que 1, se selecciona UsecaseId::MultiCamera, lo que indica que actualmente se utiliza una escena de doble cámara.

chi-cdk\core\chiusecase\Chxusecaseutils.cpp

UsecaseId UsecaseSelector::GetMatchingUsecase(
    const LogicalCameraInfo*        pCamInfo,
    camera3_stream_configuration_t* pStreamConfig)
{
    UsecaseId usecaseId = UsecaseId::Default; //第一行代码
    ......
    CHX_LOG_INFO("usecase ID:%d",usecaseId);
    return usecaseId;                         //最后一行代码
}

chi-cdk\core\chiframework\Chxextensionmodule.h

UsecaseSelector*        m_pUsecaseSelector;                     ///< Usecase selector
UsecaseFactory*         m_pUsecaseFactory;                      ///< Usecase factory
Usecase*                m_pSelectedUsecase[MaxNumImageSensors]; ///< Selected usecase

Crear caso de uso:

Cree el caso de uso correspondiente a través de UsecaseFactory según el UsecaseId seleccionado previamente.

Class Usecase es la clase base de todos los casos de uso, que define e implementa algunas interfaces comunes.

CameraUsecaseBase hereda de Usecase y amplía algunas funciones.

AdvancedCameraUsecase hereda de CameraUsecaseBase y es la clase de implementación de Usecase principal responsable de la mayoría de los escenarios.

Además, para escenarios multicámara, ahora se proporciona UsecaseMultiCamera, que se hereda de AdvancedCameraUsecase, para implementarlo.

Como puede ver en este código, a excepción de la escena de doble cámara, la mayoría de las demás escenas usan la clase AdvancedCameraUsecase para crear Usecase.

chi-cdk\core\chiframework\Chxextensionmodule.cpp

CDKResult ExtensionModule::InitializeOverrideSession(
            uint32_t                        logicalCameraId,
            const camera3_device_t*         pCamera3Device,
            const chi_hal_ops_t*            chiHalOps,
            camera3_stream_configuration_t* pStreamConfig,
            int*                            pIsOverrideEnabled,
            VOID**                          pPrivate)
{
    ...
    selectedUsecaseId = m_pUsecaseSelector->GetMatchingUsecase(&m_logicalCameraInfo[logicalCameraId],
pStreamConfig);
    ...
    m_pSelectedUsecase[logicalCameraId] =
 m_pUsecaseFactory->CreateUsecaseObject(&m_logicalCameraInfo[logicalCameraId],
                                               selectedUsecaseId, m_pStreamConfig[logicalCameraId],
                                               m_multiCameraResources.hDescriptorConfig);                                                           
}

chi-cdk\core\chiusecase\Chxusecaseutils.cpp

Usecase* UsecaseFactory::CreateUsecaseObject(
LogicalCameraInfo*              pLogicalCameraInfo,     ///< camera info
UsecaseId                       usecaseId,              ///< Usecase Id
camera3_stream_configuration_t* pStreamConfig,          ///< Stream config
ChiMcxConfigHandle              hDescriptorConfig)      ///< mcx config
{
    Usecase* pUsecase  = NULL;
    UINT     camera0Id = pLogicalCameraInfo->ppDeviceInfo[0]->cameraId;
    switch (usecaseId)
    {
        case UsecaseId::PreviewZSL:
        case UsecaseId::VideoLiveShot:
            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
            break;
        case UsecaseId::MultiCamera:
            if ((LogicalCameraType::LogicalCameraType_Default == pLogicalCameraInfo->logicalCameraType) &&
                (pLogicalCameraInfo->numPhysicalCameras > 1))
            {
                pUsecase = ChiMulticameraBase::Create(pLogicalCameraInfo, pStreamConfig, hDescriptorConfig);
            }
            break;
        case UsecaseId::MultiCameraVR:
            //pUsecase = UsecaseMultiVRCamera::Create(pLogicalCameraInfo, pStreamConfig);
            break;
        case UsecaseId::QuadCFA:
            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
            break;
        case UsecaseId::Torch:
            pUsecase = UsecaseTorch::Create(pLogicalCameraInfo, pStreamConfig);
            break;
        case UsecaseId::Depth:
            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
            break;
        case UsecaseId::AON:
            pUsecase = CHXUsecaseAON::Create(pLogicalCameraInfo);
            break;
        default:
            pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
            break;
    }
    
    return pUsecase;
}

Muchas operaciones de inicialización se realizan en el método AdvancedCameraUsecase::Create, incluidas las siguientes etapas:

  • Obtener información de configuración de casos de uso en un archivo XML
  • Crear característica
  • Guarde el flujo de datos y reconstruya la información de configuración del caso de uso.
  • Llame al método de inicialización de la clase principal CameraUsecaseBase para realizar algún trabajo de inicialización general.

Chi-cdk\core\chiusecase\Chxadvancedcamerausecase.cpp

Obtener información de configuración de casos de uso en un archivo XML

Esta parte se implementa principalmente llamando al método CameraUsecaseBase::GetXMLUsecaseByName.

La operación principal de este método es encontrar el caso de uso que coincida con el nombre de uso dado de la matriz PerNumTargetUsecases y devolverlo a la persona que llama como valor de retorno.

En la función, se comparará con el "UsecaseZSL" predeterminado pasado, se actualizará y devolverá pUsecase.

La definición de PerNumTargetUsecases está en g_pipeline.h. Este archivo se convierte a g_pipeline.h mediante el script \chi-cdk\tools\usecaseconverter\usecaseconverter.pl durante el proceso de compilación.


/// AdvancedCameraUsecase::Create

AdvancedCameraUsecase* AdvancedCameraUsecase::Create(
            LogicalCameraInfo*              pCameraInfo,   ///< Camera info
            camera3_stream_configuration_t* pStreamConfig, ///< Stream configuration
            UsecaseId                       usecaseId)     ///< Identifier for usecase function
{
    AdvancedCameraUsecase* pAdvancedCameraUsecase = CHX_NEW AdvancedCameraUsecase;
    
    if ((NULL != pAdvancedCameraUsecase) && (NULL != pStreamConfig))
    {
        result = pAdvancedCameraUsecase->Initialize(pCameraInfo, pStreamConfig, usecaseId);
    }

    return pAdvancedCameraUsecase;
}


/// AdvancedCameraUsecase::Initialize
/// 这个函数后面会反复查看

static const CHAR*  ZSL_USECASE_NAME   = "UsecaseZSL";
CDKResult AdvancedCameraUsecase::Initialize(
    LogicalCameraInfo*              pCameraInfo,   ///< Camera info
    camera3_stream_configuration_t* pStreamConfig, ///< Stream configuration
    UsecaseId                       usecaseId)     ///< Identifier for the usecase function
{
    ...
    m_pAdvancedUsecase = GetXMLUsecaseByName(ZSL_USECASE_NAME);
    ...
    if (CDKResultSuccess == result)
    {
        if ((UsecaseId::PreviewZSL    == m_usecaseId) ||
            (UsecaseId::YUVInBlobOut  == m_usecaseId) ||
            (UsecaseId::VideoLiveShot == m_usecaseId) ||
            (UsecaseId::QuadCFA       == m_usecaseId) ||
            (UsecaseId::RawJPEG       == m_usecaseId) ||
            (UsecaseId::Feature2      == m_usecaseId) ||
            (UsecaseId::MultiCamera   == m_usecaseId))
            {
                SelectFeatures(pStreamConfig);
            }
        result = SelectUsecaseConfig(pCameraInfo, pStreamConfig);
    }
     ...
 }


/// CameraUsecaseBase::GetXMLUsecaseByName

/// @brief Collection of usecases with matching properties (target count at this point)
struct ChiTargetUsecases
{
    UINT        numUsecases;  ///< The number of Usecases in this collection
    ChiUsecase* pChiUsecases; ///< An array of Usecases of size numUsecases
};

ChiUsecase* CameraUsecaseBase::GetXMLUsecaseByName(const CHAR* usecaseName)
{
    ChiUsecase* pUsecase   = NULL;
    UINT32      numTargets = 0;

    CHX_LOG("E. usecaseName:%s", usecaseName);

    struct ChiTargetUsecases* pPerNumTargetUsecases = UsecaseSelector::GetValueFromUsecasepChiTargetUsecases().at(
                                                      "PerNumTargetUsecases");


    numTargets = UsecaseSelector::GetValueFromUsecaseEnum().at("PerNumTargetUsecasesSize");
  

    for (UINT32 i = 0; i < numTargets; i++)
    {
        if (0 < pPerNumTargetUsecases[i].numUsecases)
        {
            ChiUsecase* pUsecasePerTarget = pPerNumTargetUsecases[i].pChiUsecases;

            for (UINT32 index = 0; index < pPerNumTargetUsecases[i].numUsecases; index++)
            {
                if (0 == strcmp(usecaseName, pUsecasePerTarget[index].pUsecaseName))
                {
                    //传入的默认"UsecaseZSL"和挑选出来的不一致,就用挑选出来的
                    pUsecase = &pUsecasePerTarget[index];
                    break;
                }
            }
        }
    }

    CHX_LOG("pUsecase:%p", pUsecase);
    return pUsecase;
}

UseCase tiene muchas clases derivadas en camx. Camx crea diferentes objetos de casos de uso para diferentes flujos, que se utilizan para administrar la selección de funciones y crear canalizaciones y sesiones.

3.2 Característica

La característica representa una función específica.

Las características de Qualcomm Camera HAL3 incluyen HDR (alto rango dinámico), SuperNight (súper escena nocturna), MFNR (reducción de ruido de cuadros múltiples), etc.

Usecase selecciona la característica correspondiente y luego asocia un conjunto de tuberías. La capa superior emite una solicitud y la capa hal seleccionará la característica correspondiente de acuerdo con la solicitud.

3.3 Nodo

Node es un módulo abstracto único con funciones de procesamiento independientes, que puede ser una unidad de software o una unidad de hardware.

El nodo es una clase principal muy importante en camx: es un nodo intermedio para procesar solicitudes de cámara y se utiliza para procesar solicitudes emitidas por la canalización.

Estructura de nodo:

Crear proceso de nodo:

Los nodos de nodo son cruciales en la arquitectura camx chi y el procesamiento de datos se realiza a través de nodos de nodo encapsulados.

Proceso de inicialización del nodo: 

3.4 Tubería

Una colección de nodos. La canalización proporciona una colección de todos los recursos para una única función específica y mantiene el flujo de todos los recursos y datos del hardware.

3.5 Sesión

Una colección de varias canalizaciones asociadas, una unidad de control abstracta utilizada para gestionar canalizaciones, que contiene al menos una canalización y controla todos los recursos de hardware, así como el flujo de solicitudes y la entrada y salida de datos dentro de cada canalización.

3.6 Enlace

Definir diferentes puertos de conexión de puertos (puerto de entrada y puerto de salida)

3.7 Puerto

Como puerto de entrada y salida de Node, utilice las estructuras SrcPort y DstPort para definir archivos XML.

3.8 Topologías

3.9 Casos de uso, canalizaciones y sus relaciones correspondientes de uso común

El propósito de crear componentes en Camx y Chi-Cdk es:

Los diferentes modelos, el rendimiento del producto y el posicionamiento son diferentes, incluso si la línea de base es la misma, el caso de uso, etc., puede ser diferente.

Proporciona a los fabricantes de teléfonos móviles mucho espacio para la personalización: UseCase se puede reutilizar en escenarios y la canalización correspondiente también se puede utilizar o reutilizar.

Correspondencia entre casos de uso y canalizaciones de uso común:

 

4. Relación entre componentes

4.1 Relación entre componentes básicos:

  • De acuerdo con los requisitos de la capa superior, la configuración correspondiente se transmite hacia abajo.
  • A continuación, se seleccionará el caso de uso correspondiente en función de la secuencia aplicada.
  • Una vez completada la selección del caso de uso, se seleccionarán las funciones requeridas.
  • Se asociarán diferentes características con la tubería correspondiente.
  • El oleoducto se compone de una serie de nodos.
  • Finalmente, el flujo de la configuración de la capa superior se entregará a cada nodo para su procesamiento.

Diagrama de componentes: 

En la actualidad, la arquitectura de Qualcomm Camera HAL3 ha cambiado gradualmente a centrada en funciones, abandonando el modelo de arquitectura anterior centrado en casos de uso.

5. Interacción entre componentes básicos y capas superiores.

5.1 Proceso de renderizado general de la aplicación Camera y diagrama de flujo de interacción con CAMX:

Figura 1:

 Figura 2:

5.2 Flujo de solicitudes

Cada Solicitud emitida por la Sesión en la capa superior corresponde a tres Resultados:

  • metadatos parciales
  • metadatos
  • datos de imagen

Para cada resultado, el proceso de carga se puede dividir aproximadamente en las dos etapas siguientes:

  • Complete el procesamiento de datos de imágenes dentro de la sesión y envíe los resultados a Usecase
  • Usecase recibe datos de la sesión y los carga al proveedor

5.3 La realización de la función de devolución de llamada de sesión en CAMX

5.3.1 Sesión::Transmitir()

Este método se utiliza principalmente para iniciar la salida de datos del hardware.

El punto específico es configurar el registro del Sensor, dejar que comience a dibujar e informar a cada Nodo del estado de la Sesión actual, para que también puedan estar preparados para procesar datos internamente, por lo que el flujo posterior de Solicitudes relacionadas se basará en este método. se basa en la premisa, por lo que la importancia de este método es evidente.

El método StreamOn de Session realiza principalmente las dos tareas siguientes:

  1. Llame al método FinalizeDeferPipeline()
    . Si la canalización actual no se ha inicializado, se llamará al método FinalizePipeline() de la canalización. En este método, las operaciones FinalizeInitialization, CreateBufferManager, NotifyPipelineCreated y PrepareNodeStreamOn se realizarán para cada nodo que pertenece a la canalización actual. FinalizeInitialization se usa para

    completar la acción de inicialización de Node, NotifyPipelineCreated se usa para notificar a Node sobre el estado actual de Pipeline. En este momento, Node puede realizar las operaciones correspondientes de acuerdo con sus propias necesidades. El método PrepareNodeStreamOn() se usa principalmente para completar

    la controlar los módulos de hardware de Node, como Sensor e IFE, antes de dibujar. Configuración, incluida la configuración de los parámetros expuestos.

    El método CreateBufferManagers() implica un mecanismo de gestión de búfer muy importante en CAMX CHI-CDK, que se utiliza para la creación del ImageBufferManager de Node. y esta clase se utiliza para administrar el puerto de salida en Node.Aplicación/transferencia/liberación de búfer y otras operaciones.

  2. Llamar al método StreamOn () de Pipeline
    notificará aún más a la parte CSL para iniciar el flujo de datos y llamará al método OnNodeStreamOn () de cada nodo. Este método llamará a Activate () de ImageBufferManager, que en realidad asignará los datos para Después de cargar el búfer de datos de imagen , se llamará al método Nod pOnStreamOn() definido por el usuario implementado en la parte CHI. El usuario puede realizar algunas operaciones personalizadas en este método.

5.3.2 Sesión::ProcessCaptureRequest()

Cada transferencia de solicitud comienza con este método como punto de entrada. El proceso específico se muestra en la siguiente figura:

La canalización se agrega a DRQ por primera vez llamando al método AddDeferredNode para cada nodo.

En este momento, todos los nodos se agregarán a m_readyNodes y luego, al llamar al método DispatReadyNodes, se activará DRQ para iniciar todo el proceso de procesamiento interno.

El proceso básico se puede ver en la siguiente figura:

Cómo se envía el resultado a Usecase después de que los datos de la imagen se procesan dentro de la sesión:

¿Cómo recibe Usecase los datos de la sesión y los envía al proveedor?

Tome el AdvancedCameraUsecase de uso común como ejemplo para ordenar el código:

6. ETIQUETA de registro:

6.1 Encienda el controlador de la cámara:

Registro de encendido del controlador: cam_sensor_driver_cmd | Sonda exitosa

6.2 Apague el controlador de la cámara:

Registro de apagado del controlador:

cam_sensor_driver_cmd: CAM_STOP_DEV Éxito para productname_ofilm_s5khm2_wide sensor_id:0x1ad2,sensor_slave_addr:0x20

cam_sensor_driver_cmd:  CAM_RELEASE_DEV Éxito para productname_ofilm_s5khm2_wide sensor_id:0x1ad2, Slave_addr:0x20

6.3 Antes de encender la cámara y comenzar a transmitir el primer fotograma:

CAM_START_DEV

6.4 Recorrido de la capa inferior de las cámaras:

  • CHIUSECASE: [INFO] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 4, conjunto 54
  • CHIUSECASE: [INFO] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 0, conjunto 50
  • CHIUSECASE: [INFO] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 1, conjunto 50
  • CHIUSECASE: [INFO] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 2, conjunto 50
  • CHIUSECASE: [INFO] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 3, conjunto 50

6.5 Abrir la cámara:

CameraService:  CameraService::connect|primer cuadro llegó|CameraService: desconectar: ​​Desconectado|CAM_ACQUIRE_DEV|CAM_START_DEV|CAM_STOP_DEV|CAM_RELEASE_DEV

"configure_streams": Configurar transmisiones

"pipelineName": nombre de la tubería

CAMX   : |CHIUSECASE:|STREAM_ONSelectFeatureGraphforRequestFromTable|Nodo::|CamX:|CHIUSECASE:|Camera3|CameraDevice

7. Otros

7.1 Defina la dirección xml del nodo en la tubería:

proveedor/qcom/proprietary/chi-cdk/oem/qcom/topology/titan/usecase-components/usecases/UsecaseZSL/pipelines

7.2 Definición del modo de enlace de nodo:

Los métodos de nodo y conexión en Pipeline se definen en XML, que incluye principalmente las siguientes definiciones de etiquetas:

  • PipelineName: se utiliza para definir el nombre del Pipeline
  • NodeList: Esta etiqueta define todos los Nodos de este Pipeline.
  • PortLinkages: esta etiqueta define la relación de conexión entre diferentes puertos en el Nodo.

7.3 archivo de definición de etiqueta de proveedor:

/vendor/qcom/proprietary/chi-cdk/api/common/chioemvendortagdefines.h 

7.4  directorio del controlador del sensor:

Un proyecto llamado nombre de producto, el directorio de archivos del controlador de una cámara:

proveedor\qcom\proprietary\chi-cdk\oem\qcom\sensor\productname_sensor\productname_ofilm_ov16a1q_front_sensor

8. Fin

Supongo que te gusta

Origin blog.csdn.net/geyichongchujianghu/article/details/131029549
Recomendado
Clasificación