SA8650 camera UsecaseId UsecaseAuto

目录

UsecaseAuto create

 UsecaseAuto::Initialize

1)、获取输入输出流

2)、ChiUsecase 获取usecase 的数组

3)、判断是否具有裁剪属性 打印裁剪后的分辨率

4)、解析UsecaseAuto_pipelines 的数组UsecaseAuto_AutoOfflineIFE_sink_TargetDescriptors数组配置,

5)、初始化pipeline信息

6)、初始化pipelineCreateData m_pipelineDescriptor 解析node支持的模式 配置output buffer的分辨率

6)、创建session

pipelineCreateDesc ChiPipelineCreateDescriptor 的结构体信息 

 Chi node info 结构体信息

1、pNodeProperties[i].pValues中保存的是支持的node 节点支持的算法信息com.qti.stats.pdlibwrapper com.qti.hvx.addconstant 

2、获取HDR 模式信息 m_HDRInfo[logicalCameraId]

3、如果usecases(torch widget, AON),那么 IsNoBufferUsecase=true

4、当前场景中没使用torch widget, AON, auto usecase的 IsNoBufferUsecase = FALSE

5、获取帧率,判断是否支持HDR 模式

6、获取pLogicalCameraInfo 的m_cameraCaps.numSensorModes pSensorModeInfo

7、根据pLogicalCameraInfo判断支持那种模式的HDR

8、判断是否支持裁剪 根据设置传感器模式 设置分辨率

HDR科普


UsecaseAuto create


/// UsecaseAuto::Create

UsecaseAuto* UsecaseAuto::Create(
    LogicalCameraInfo*              pCameraInfo,    ///< Camera info
    camera3_stream_configuration_t* pStreamConfig)  ///< Stream configuration
{
    CDKResult  result     = CDKResultSuccess;
    UsecaseAuto* pUsecaseAuto = CHX_NEW UsecaseAuto;

    if (NULL != pUsecaseAuto)
    {
        result = pUsecaseAuto->Initialize(pCameraInfo, pStreamConfig);

        if (CDKResultSuccess != result)
        {
            pUsecaseAuto->Destroy(FALSE);
            pUsecaseAuto = NULL;
            CHX_LOG_ERROR("pUsecaseAuto Initialize failed with error %s", CdkUtils::CDKResultToString(result));
        }
    }
    else
    {
        result = CDKResultEFailed;
    }

    return pUsecaseAuto;
}

 UsecaseAuto::Initialize

1)、获取输入输出流

2)、ChiUsecase 获取usecase 的数组

3)、判断是否具有裁剪属性 打印裁剪后的分辨率

4)、解析UsecaseAuto_pipelines 的数组UsecaseAuto_AutoOfflineIFE_sink_TargetDescriptors数组配置,

5)、初始化pipeline信息

6)、初始化pipelineCreateData m_pipelineDescriptor 解析node支持的模式 配置output buffer的分辨率

6)、创建session


/// UsecaseAuto::Initialize

CDKResult UsecaseAuto::Initialize(
    LogicalCameraInfo*              pCameraInfo,    ///< Camera info
    camera3_stream_configuration_t* pStreamConfig)  ///< Stream configuration
{
    CDKResult  result        = CDKResultSuccess;
    BOOL       isMultiCamera = (pCameraInfo->numPhysicalCameras > 1);
    std::map> cameraIdToStreamMap;
    std::map> cameraIdToCamera3StreamMap;

    m_pFrameNumCounter = 1;

    m_logicalCameraId        = pCameraInfo->cameraId;
    m_pAppResultMutex        = Mutex::Create();
    m_availableResultTags    = getResultVendorTags();
    m_availableResultTagsOEM = ChiVendorTagUtilOEM::getResultVendorTags();

    if (NULL == m_pAppResultMutex)
    {
        CHX_LOG_ERROR("Mutex Create failed");
        result = CDKResultENoMemory;
    }

    if (CDKResultSuccess == result)
    {
        // 1. Initialize metadata Manager and initialize input client
        m_pMetadataManager = ChiMetadataManager::Create(m_logicalCameraId);

        if (NULL != m_pMetadataManager)
        {
            result = m_pMetadataManager->InitializeFrameworkInputClient(DefaultNumMetadataBuffers);
        }
        else
        {
            result = CDKResultENoMemory;
        }
    }

    // allocate memory for the local streamconfiguration
    camera3_stream_configuration_t* pStreamConfigPerPipeline = static_cast(
                                        CHX_CALLOC(sizeof(camera3_stream_configuration_t)));

    if (NULL == pStreamConfigPerPipeline)
    {
        result = CDKResultENoMemory;
    }

    // 2. Get the default matching usecase for the stream combination.
    if (CDKResultSuccess == result)
    {
        // @todo Currently only one pipeline is returned for Auto usecase with RAW streams, handle for more?
        // Create and clone the realtime pipelines for each physical camera.
        for (UINT streamIdx = 0; streamIdx < pStreamConfig->num_streams; streamIdx++)
        {
           //获取输入输出流
            camera3_stream_t* pFwkStream       = pStreamConfig->streams[streamIdx];
            UINT32            cameraIndex      = 0;

            UINT32 physicalCameraId = InvalidCameraId;
            if ((NULL != pFwkStream) &&
                (NULL != pFwkStream->physical_camera_id) &&
                (0 < CdkUtils::StrLen(pFwkStream->physical_camera_id)))
            {
                physicalCameraId = static_cast(atoi(pFwkStream->physical_camera_id));
            }
            if (TRUE == isMultiCamera)
            {
                for (UINT32 index = 0; index < pCameraInfo->numPhysicalCameras; ++index)
                {
                    if (pCameraInfo->ppDeviceInfo[index]->frameworkId == physicalCameraId)
                    {
                        cameraIndex = index;
                        break;
                    }
                }
            }

            cameraIdToStreamMap[cameraIndex].push_back(reinterpret_cast(pFwkStream));
            cameraIdToCamera3StreamMap[cameraIndex].push_back(pFwkStream);

            m_StreamToCameraIdMap[reinterpret_cast(pFwkStream)] = physicalCameraId;

            CHX_LOG_INFO("camera index %d stream %p camera ID %d", cameraIndex, pFwkStream, physicalCameraId);
            // @todo Should return failure if logical stream is present. Add validation check.
        }

        m_numRTPipelines = cameraIdToStreamMap.size();

        auto camera3StreamItr = cameraIdToCamera3StreamMap.begin();
        for (UINT index = 0; index < m_numRTPipelines; index++)
        {
            std::vector pCamera3Streams            = camera3StreamItr->second;
            pStreamConfigPerPipeline->num_streams                     = pCamera3Streams.size();
            pStreamConfigPerPipeline->streams                         = &pCamera3Streams[0];
            pStreamConfigPerPipeline->session_parameters              = pStreamConfig->session_parameters;
            //ChiUsecase 获取usecase 的数组
            m_pChiUsecase[index] = UsecaseSelector::DefaultMatchingUsecase(pStreamConfigPerPipeline, 0);
            camera3StreamItr++;
        }

        //判断是否具有裁剪属性 打印裁剪后的分辨率
        camera_metadata_entry_t entry = {};
        ChxUtils::QuerySessionParam(pStreamConfig, "ScalerCropRegion", entry);

        m_isScalerCropRegionEnabled = FALSE;

        if (NULL != entry.data.i32)
        {
            CHX_LOG_INFO("m_scalerCropRegion set from session param successfully");
            m_scalerCropRegion = *(reinterpret_cast(entry.data.i32));
            m_isScalerCropRegionEnabled = TRUE;
        }
        else
        {
            CHX_LOG_INFO("session param not found: m_scalerCropRegion values will be 0");
        }

        CHX_LOG_INFO("m_scalerCropRegion {left, top, width, height} = {%d,%d,%d,%d}",
                     m_scalerCropRegion.left,
                     m_scalerCropRegion.top,
                     m_scalerCropRegion.width,
                     m_scalerCropRegion.height);


        m_pChiPipelineRecRequest = static_cast(
                                            CHX_CALLOC(sizeof(CHIPIPELINERECURRENTREQUEST) * m_numRTPipelines));

        m_pChiPipelineRecSetting = static_cast(
                                            CHX_CALLOC(sizeof(CHIPIPELINERECURRENTSETTING) * m_numRTPipelines));

        // 3. Create pipeline and assign all pipeline parameters.
        // Handling only realtime pipelines for Auto
        auto itr = cameraIdToStreamMap.begin();//pStreamConfig->streams
        for (UINT index = 0; index < m_numRTPipelines; index++)
        {
            UINT32 cameraIndex      = itr->first;
            UINT32 cameraId         = pCameraInfo->ppDeviceInfo[cameraIndex]->cameraId;
            UINT32 fwkCameraId      = pCameraInfo->ppDeviceInfo[cameraIndex]->frameworkId;

            m_cameraIdToPipelineIndexMap[fwkCameraId] = index;
            std::vector pChiStreams    = itr->second;
            UINT32                  numStreams     = pChiStreams.size();

            CHX_LOG_INFO("Creating Pipeline %s index:%d camera Id %d numStreams %d",
                 m_pChiUsecase[index]->pPipelineTargetCreateDesc[0].pPipelineName, index, cameraId, numStreams);
                  //UsecaseAuto_pipelines
             //AutoOfflineIFE AutoYUVROI  Auto AutoYUV
            ChiPipelineTargetCreateDescriptor* pPipelineDesc = &m_pChiUsecase[index]->pPipelineTargetCreateDesc[0];

            if (NULL != pPipelineDesc)
            {
                //pSinkTarget={5,UsecaseAuto_AutoOfflineIFE_sink_TargetDescriptors}
                ChiTargetPortDescriptorInfo*   pSinkTarget   = &pPipelineDesc->sinkTarget;

                ChiPortBufferDescriptor pipelineOutputBuffer[MaxChiStreams];
                ChxUtils::Memset(pipelineOutputBuffer, 0, sizeof(pipelineOutputBuffer));

                // Create an output buffer for every stream and its matching target
                for (UINT streamIdx = 0; streamIdx < numStreams; streamIdx++)
                {
                    for (UINT sinkIdx = 0; sinkIdx < pSinkTarget->numTargets; sinkIdx++)
                    {   //解析UsecaseAuto_AutoOfflineIFE_sink_TargetDescriptors数组配置
                        ChiTargetPortDescriptor* pSinkTargetDesc = &pSinkTarget->pTargetPortDesc[sinkIdx];

                        if (pSinkTargetDesc->pTarget->pChiStream  == pChiStreams[streamIdx])
                        { 
                           //pStream = UsecaseAuto_TARGET_BUFFER_RAW2_target
                            pipelineOutputBuffer[streamIdx].pStream      = pSinkTargetDesc->pTarget->pChiStream;
                            //pNodePort=s_69_TARGET_BUFFER_RAW2_Link_NodeDescriptors
                            pipelineOutputBuffer[streamIdx].pNodePort    = pSinkTargetDesc->pNodePort;
                            //numNodePorts=1
                            pipelineOutputBuffer[streamIdx].numNodePorts = pSinkTargetDesc->numNodePorts;

                            CHX_LOG_INFO("Creating output buffer for stream: %p, idx: %d, format: %d and matching target idx: %d",
                                pChiStreams[streamIdx], streamIdx, pChiStreams[streamIdx]->format, sinkIdx);
                        }
                    }
                }

                m_pPipelines[index] = Pipeline::Create(cameraId, PipelineType::Default);

                if (NULL != m_pPipelines[index])
                {
                //初始化pipeline信息
                    m_pPipelines[index]->SetOutputBuf
                    //配置node信息 UsecaseAuto_pipelines[0]的pipelineCreateDesc信息
                    // pipelineCreateDesc={ 0, 3, UsecaseAuto_AutoOfflineIFENodes, 7, UsecaseAuto_AutoOfflineIFELinks, 1, 0, { 0 }, { 0 }}
                    m_pPipelines[index]->SetPipelineNodePorts(&pPipelineDesc->pipelineCreateDesc);
                    m_pPipelines[index]->SetPipelineName(pPipelineDesc->pPipelineName);
                    m_pPipelines[index]->SetPipelineLogicalCameraId(m_logicalCameraId);
                    m_pPipelines[index]->SetPipelineContext(ChiMultiContextType::DefaultContext);

                    m_privData[index].streamIndex = index;
                    m_physFwkCameraIds[index]     = std::to_string(fwkCameraId);

                    m_requiredResultVendorTag.tagIds.insert(
                        end(m_requiredResultVendorTag.tagIds), begin(m_availableResultTagsOEM), end(m_availableResultTagsOEM));
                    m_requiredResultVendorTag.tagIds.insert(
                        end(m_requiredResultVendorTag.tagIds), begin(m_availableResultTags), end(m_availableResultTags));

                    ChiMetadata* pMetadata = m_pPipelines[index]->GetDescriptorMetadata();

                    result                 = pMetadata->SetTag("com.qti.chi.availableResults",
                                               "RequiredResultVendorTags",
                                               &m_requiredResultVendorTag,
                                               sizeof(RequiredResultVendorTags));

                    if (CDKResultSuccess != result)
                    {
                        CHX_LOG_WARN("SetTag failed to setavailableResults");
                        result = CDKResultSuccess;
                    }
                    //初始化pipelineCreateData m_pipelineDescriptor
                    //解析node支持的模式 配置output buffer的分辨率
                    result = m_pPipelines[index]->CreateDescriptor();
                }
                else
                {
                    result = CDKResultEFailed;
                    CHX_LOG_ERROR("Pipeline creation failed for pipeline with index: %d", index);
                }

                if (CDKResultSuccess != result)
                {
                    CHX_LOG_ERROR("CreateDescriptor of pipeline %s failed with error %s",
                        pPipelineDesc->pPipelineName, CdkUtils::CDKResultToString(result));
                }

                itr++;
            }
        }

        // 4. Create session
        if (CDKResultSuccess == result)
        {
            auto itr = cameraIdToStreamMap.begin();
            for (UINT index = 0; index < m_numRTPipelines; index++)
            {
                UINT32 cameraIndex      = itr->first;
                UINT32 fwkCameraId      = pCameraInfo->ppDeviceInfo[cameraIndex]->frameworkId;
                UINT32 pipelineIndex    = m_cameraIdToPipelineIndexMap[fwkCameraId];
                UINT32 numPipelines     = DefaultNumAutoPipeline;
                ChiCallBacks callbacks  = { 0 };

                callbacks.ChiNotify                         = SessionCbNotifyMessage;
                callbacks.ChiProcessCaptureResult           = SessionCbCaptureResult;
                callbacks.ChiProcessRecurrentCaptureResult  = SessionCbRecurrentCaptureResult;

                m_RTSessionPvtData.sessionId = index;
                m_RTSessionPvtData.pUsecase  = this;
               //创建session 
                m_pRTSession[index] = Session::Create(&m_pPipelines[index], numPipelines, &callbacks, &m_RTSessionPvtData);

                if (NULL == m_pRTSession[index])
                {
                    result = CDKResultEFailed;
                    CHX_LOG_ERROR("Session creation failed");
                }

                m_pipelineIdxToSessionMap[pipelineIndex] = m_pRTSession[index];
                CHX_LOG_VERBOSE("Mapping Pipeline idx %d to stream %p", pipelineIndex, m_pRTSession[index]);
                itr++;
            }
        }
    }

    if (CDKResultSuccess == result)
    {
        result = AllocateRecurrentRequest();
    }

    // 5. Register metadata clients.
    if (CDKResultSuccess == result)
    {
        for (UINT index = 0; index < m_numRTPipelines; index++)
        {
            Pipeline* pPipeline = m_pPipelines[index];
            m_metadataClients[index] =
                 m_pMetadataManager->RegisterClient(
                    pPipeline->IsRealTime(),
                    pPipeline->GetTagList(),
                    pPipeline->GetTagCount(),
                    pPipeline->GetPartialTagCount(),
                    pPipeline->GetMetadataBufferCount() + BufferQueueDepth,
                    ChiMetadataUsage::RealtimeOutput);

            CHX_LOG_ERROR("Register Client Id: %d", m_metadataClients[index]);
            pPipeline->SetMetadataClientId(m_metadataClients[index]);
        }
    }

    // get extension module instance for pipeline activation
    ExtensionModule * pExtensionModuleInstance = ExtensionModule::GetInstance();

    if (NULL == pExtensionModuleInstance)
    {
        result = CDKResultEFailed;
        CHX_LOG_ERROR("Extension module is NULL");
    }

    // 6. Activate the pipelines.
    // @todo Add resource manager checks before activating
    if (CDKResultSuccess == result)
    {
        for (UINT index = 0; index < m_numRTPipelines; index++)
        {
            CHX_LOG_CORE_CFG("ActivatePipeline %s", m_pPipelines[index]->GetPipelineName());
            result = pExtensionModuleInstance->ActivatePipeline(m_pRTSession[index]->GetSessionHandle(),
                                                                      m_pRTSession[index]->GetPipelineHandle(0));
            if (CDKResultSuccess == result)
            {
                m_pPipelines[index]->SetPipelineActivateFlag();
            }
            else
            {
                CHX_LOG_ERROR("Activate %s failed! result: %s", m_pPipelines[index]->GetPipelineName(),
                    CdkUtils::CDKResultToString(result));
                break;
            }
        }

        // If any of activate failed, then deactivate all the pipelines and report error.
        if (CDKResultSuccess != result)
        {
            for (UINT index = 0; index < m_numRTPipelines; index++)
            {
                Pipeline* pPipeline = m_pPipelines[index];
                if (TRUE == pPipeline->IsPipelineActive())
                {
                    CHX_LOG_CORE_CFG("DeActivatePipeline %s", pPipeline->GetPipelineName());
                    result = pExtensionModuleInstance->DeactivatePipeline(m_pRTSession[index]->GetSessionHandle(),
                                                                          m_pRTSession[index]->GetPipelineHandle(index),
                                                                          CHIDeactivateModeDefault);

                    if (CDKResultSuccess == result)
                    {
                        pPipeline->SetPipelineDeactivate();
                    }
                    else
                    {
                        CHX_LOG_ERROR("Deactivate %s failed! result: %s", pPipeline->GetPipelineName(),
                            CdkUtils::CDKResultToString(result));
                    }
                }
            }
        }
    }

    // release local stream configuration
    if (NULL != pStreamConfigPerPipeline)
    {
        CHX_FREE(pStreamConfigPerPipeline);
    }

    return result;
}

pipelineCreateDesc ChiPipelineCreateDescriptor 的结构体信息 

/// @brief Structure that contains all information required to create a pipeline
1127typedef struct ChiPipelineCreateDescriptor
1128{
1129    UINT32              size;                                ///< Size of this structure
1130    UINT32              numNodes;                            ///< Number of pipeline nodes
1131    CHINODE*            pNodes;                              ///< Pipeline nodes
1132    UINT32              numLinks;                            ///< Number of links
1133    CHINODELINK*        pLinks;                              ///< Each link descriptor
1134    UINT32              isRealTime;                          ///< Is this a realtime pipeline
1135    UINT                numPipelineModes;                    ///< Number of pipeline modes (transition modes)
1136    UINT                pipelineModeIds[MaxNumberOfModes];   ///< Array of transition mode ids
1137    const CHAR*         pipelineModeNames[MaxNumberOfModes]; ///< Array of transition mode names
1138    UINT                numBatchedFrames;                    ///< Number of framework frames batched
1139    UINT                maxFPSValue;                         ///< maxFPSValue info of batched frames
1140    UINT32              cameraId;                            ///< Camera Id of pipeline
1141    CHIMETAHANDLE       hPipelineMetadata;                   ///< Valid Metadata buffer handle containing tags init tags
1142    BOOL                HALOutputBufferCombined;             ///< Is the HAL output buffer combined for batch mode
1143    UINT32              logicalCameraId;                     
///< Logical Camera Id of pipeline
1144} CHIPIPELINECREATEDESCRIPTOR;

pipelineCreateDesc=
{ 
0, 
3, 
UsecaseAuto_AutoOfflineIFENodes,
 7, 
 UsecaseAuto_AutoOfflineIFELinks,
 1,
 0,
 { 0 }, 
 { 0 }
 }

 Chi node info 结构体信息

/// @brief Chi node info
1086typedef struct ChiNode
1087{
1088    CHINODEPROPERTY* pNodeProperties;                     ///< Properties associated with the node
1089    UINT32           nodeId;                              ///< Node identifier
1090    UINT32           nodeInstanceId;                      ///< Node instance identifier
1091    CHINODEPORTS     nodeAllPorts;                        ///< Information about all ports
1092    UINT32           numProperties;                       ///< Count of NodeProperty instances in pNodeProperties
1093    PruneSettings    pruneProperties;                     ///< A list of prune properties
1094    UINT32           preferredMode;                       ///< Preferred mode to be used for sensor initialization
1095    UINT32           numTransitionModes;                  ///< Number of transition modes
1096    UINT32           transitionModeIds[MaxNumberOfModes]; ///< Transition mode Ids
1097} CHINODE;
static ChiNodeProperty UsecaseAuto_AutoOfflineIFE_node0_0_properties[] =
{
    {1, "com.qti.stats.pdlibwrapper"},
};

static ChiNodeProperty UsecaseAuto_AutoOfflineIFE_node65536_1_properties[] =
{
    {2, "1"},
    {37, "0"},
};

static ChiNodeProperty UsecaseAuto_AutoOfflineIFE_node65636_0_properties[] =
{
    {1, "com.qti.hvx.addconstant"},
    {6, "1"},
};
static ChiNode UsecaseAuto_AutoOfflineIFENodes[] =
{
    {UsecaseAuto_AutoOfflineIFE_node0_0_properties, 0, 0, {0, { 0 }, NULL, 1, { 0 }, UsecaseAuto_AutoOfflineIFENode0_0OutputPortDescriptors}, 1, {0, NULL}, 0, 0, { 0 }},
    {UsecaseAuto_AutoOfflineIFE_node65536_1_properties, 65536, 1, {1, { 0 }, UsecaseAuto_AutoOfflineIFENode65536_1InputPortDescriptors, 2, { 0 }, UsecaseAuto_AutoOfflineIFENode65536_1OutputPortDescriptors}, 2, {0, NULL}, 0, 0, { 0 }},
    {UsecaseAuto_AutoOfflineIFE_node65636_0_properties, 65636, 0, {1, { 0 }, UsecaseAuto_AutoOfflineIFENode65636_0InputPortDescriptors, 4, { 0 }, UsecaseAuto_AutoOfflineIFENode65636_0OutputPortDescriptors}, 2, {0, NULL}, 0, 0, { 0 }},
};
typedef UINT32 NodeProperty;
static const NodeProperty NodePropertyCustomLib                  = 1;     ///< Custom lib
static const NodeProperty NodePropertyProfileId                  = 2;     ///< IPE/BPS Instance Property Profile
static const NodeProperty NodePropertyStabilizationType          = 3;     ///< IPE Instance Property Stabilization Type
static const NodeProperty NodePropertyProcessingType             = 4;     ///< IPE Instance Property Processing Type
static const NodeProperty NodePropertyIPEDownscale               = 5;     ///< IPE Instance IPE downscale
139static const NodeProperty NodePropertyStatsSkipPattern           = 6;
static const NodeProperty NodePropertyIFECSIDHeight              = 7;
static const NodeProperty NodePropertyIFECSIDWidth               = 8;
static const NodeProperty NodePropertyIFECSIDLeft                = 9;
static const NodeProperty NodePropertyIFECSIDTop                 = 10;
static const NodeProperty NodePropertyNodeClass                  = 11;    ///< Node class -

解析ChiNode 中的node info 信息

1、pNodeProperties[i].pValues中保存的是支持的node 节点支持的算法信息com.qti.stats.pdlibwrapper com.qti.hvx.addconstant 

2、获取HDR 模式信息 m_HDRInfo[logicalCameraId]

3、如果usecases(torch widget, AON),那么 IsNoBufferUsecase=true

4、当前场景中没使用torch widget, AON, auto usecase的 IsNoBufferUsecase = FALSE

5、获取帧率,判断是否支持HDR 模式

6、获取pLogicalCameraInfo 的m_cameraCaps.numSensorModes pSensorModeInfo

     modeCount:

     pLogicalCameraInfo->m_cameraCaps.numSensorModes

     pAllModes:

     pLogicalCameraInfo->pSensorModeInfo

7、根据pLogicalCameraInfo判断支持那种模式的HDR

  1)、采用三曝光实现实时HDR预览

  2)、Staggered HDR 行交织 HD

  3)、MFHDR 多帧 HDR

  4)、QHDR(Quad HDR,四像素HDR)

8、判断是否支持裁剪 根据设置传感器模式 设置分辨率



// Pipeline::CreateDescriptor

CDKResult Pipeline::CreateDescriptor()
{
    CDKResult          result                    = CDKResultSuccess;
    PipelineCreateData pipelineCreateData        = {};

    m_pipelineDescriptor.isRealTime              = HasSensorNode(&m_pipelineDescriptor);

    // m_cameraId from usecase side must be correct, even for pipelines without sensor Node
    m_pipelineDescriptor.cameraId                = m_cameraId;
    m_pipelineDescriptor.logicalCameraId         = m_logicalCameraId;
    m_pipelineDescriptor.context                 = m_context;

    pipelineCreateData.pPipelineName             = m_pPipelineName;
    pipelineCreateData.numOutputs                = m_numOutputBuffers;
    pipelineCreateData.pOutputDescriptors        = &m_pipelineOutputBuffer[0];
    pipelineCreateData.numInputs                 = m_numInputBuffers;
    pipelineCreateData.pInputOptions             = &m_pipelineInputOptions[0];
    pipelineCreateData.pPipelineCreateDescriptor = &m_pipelineDescriptor;

    CHIPIPELINECREATEDESCRIPTOR* pCreateDesc = pipelineCreateData.pPipelineCreateDescriptor;

    pCreateDesc->numBatchedFrames        = ExtensionModule::GetInstance()->GetNumBatchedFrames(m_logicalCameraId);
    pCreateDesc->HALOutputBufferCombined = ExtensionModule::GetInstance()->GetHALOutputBufferCombined();
    pCreateDesc->maxFPSValue             = ExtensionModule::GetInstance()->GetUsecaseMaxFPS(m_logicalCameraId);

    const CHAR* pClientName = "Chi::Pipeline::CreateDescriptor";
    SetTuningUsecase();

    m_pPipelineDescriptorMetadata->AddReference(pClientName);
    m_pipelineDescriptor.hPipelineMetadata = m_pPipelineDescriptorMetadata->GetHandle();

    CHX_LOG_CORE_CFG("Pipeline[%s] pipeline pointer %p numInputs=%d, numOutputs=%d stream w x h: %d x %d "
        "format: %d, numBatchedFrames: %d, HALOutputBufferCombined: %d maxFPSValue: %d cameraId: %d logicalCameraId:%d",
        m_pPipelineName,
        this,
        pipelineCreateData.numInputs,
        pipelineCreateData.numOutputs,
        (NULL != pipelineCreateData.pOutputDescriptors->pStream) ? pipelineCreateData.pOutputDescriptors->pStream->width : 0,
        (NULL != pipelineCreateData.pOutputDescriptors->pStream) ? pipelineCreateData.pOutputDescriptors->pStream->height : 0,
        (NULL != pipelineCreateData.pOutputDescriptors->pStream) ? pipelineCreateData.pOutputDescriptors->pStream->format : 0,
        pCreateDesc->numBatchedFrames,
        pCreateDesc->HALOutputBufferCombined,
        pCreateDesc->maxFPSValue,
        pipelineCreateData.pPipelineCreateDescriptor->cameraId,
        pipelineCreateData.pPipelineCreateDescriptor->logicalCameraId);

    UINT32 enableSWMCTFwithReferenceFrame = ExtensionModule::GetInstance()->GetMCTFwithReferenceFrameStatus(m_logicalCameraId);
    ChxUtils::SetVendorTagValue(m_pPipelineDescriptorMetadata,
        VendorTag::SWMCTFEnableWithRef,
        1,
        &enableSWMCTFwithReferenceFrame);

    UINT32 facialContourVersion = ExtensionModule::GetInstance()->GetFacialContourVersion(m_logicalCameraId);
    ChxUtils::SetVendorTagValue(m_pPipelineDescriptorMetadata,
        VendorTag::FacialContourVersion,
        1,
        &facialContourVersion);

    // Update stats skip pattern in node property with value from override
    //m_pipelineDescriptor.numNodes=3
    for (UINT node = 0; node < m_pipelineDescriptor.numNodes; node++)
    {
       //pNodes[node]=UsecaseAuto_AutoOfflineIFENodes[node]
        const ChiNode* const pChiNode = &m_pipelineDescriptor.pNodes[node];
        
       //pChiNode->numProperties=1 2 4
       //pChiNode->pNodeProperties=UsecaseAuto_AutoOfflineIFE_node0_0_properties
       //                            UsecaseAuto_AutoOfflineIFE_node65536_1_properties
       //                            UsecaseAuto_AutoOfflineIFE_node65536_0_properties
        for (UINT i = 0; i < pChiNode->numProperties; i++)
        {
           //pChiNode->pNodeProperties[i].id=1
            switch(pChiNode->pNodeProperties[i].id)
            { //解析node的算法
            //pNodeProperties[i].pValues = com.qti.stats.pdlibwrapper  com.qti.hvx.addconstant
                case NodePropertyStatsSkipPattern://6
                    m_statsSkipPattern = ExtensionModule::GetInstance()->GetStatsSkipPattern();
                    pChiNode->pNodeProperties[i].pValue = &m_statsSkipPattern;
                    break;
                case NodePropertyEnableFOVC://16
                    m_enableFOVC = ExtensionModule::GetInstance()->EnableFOVCUseCase();
                    pChiNode->pNodeProperties[i].pValue = &m_enableFOVC;
                    break;
                case NodePropertyNISInternalTrigger://21 
                    m_isNISInternalTrigger = ExtensionModule::GetInstance()->IsInternalTriggered(m_logicalCameraId);
                    pChiNode->pNodeProperties[i].pValue = &m_isNISInternalTrigger;
                    break;
                default:
                    break;
            }
        }
    }
    //初始化pCreatePipelineDescriptor m_hPipelineHandle
    m_hPipelineHandle = ExtensionModule::GetInstance()->CreatePipelineDescriptor(&pipelineCreateData);

    m_pPipelineDescriptorMetadata->ReleaseReference(pClientName);

    if (NULL == m_hPipelineHandle)
    {
        result = CDKResultEFailed;
        CHX_LOG_ERROR("Fail due to NULL pipeline handle");
    }
    else
    {//获取HDR 模式信息  m_HDRInfo[logicalCameraId]
        const HDRInfo&    rHDRInfo              = ExtensionModule::GetInstance()->GetHDRInfo(m_logicalCameraId);
        HDRDeviceInfo*    pLogicalHDRDeviceInfo = rHDRInfo.pLogicalHDRDeviceInfo;
        ChiHDRModeInfo    physicalHDRModeInfo   =
                ExtensionModule::GetInstance()->GetPhysicalDeviceHDRModeInfo(m_logicalCameraId, m_cameraId);
        ChiHDRFeatureMode physicalHDRMode       = physicalHDRModeInfo.HDRMode;
        //usecases(torch widget, AON). IsNoBufferUsecase=true
        //auto usecase  IsNoBufferUsecase = FALSE
        if ((FALSE == ExtensionModule::GetInstance()->IsNoBufferUsecase()))
        {
            // sensor mode selection not required for no buffer usecases(torch widget, AON).
            DesiredSensorMode desiredSensorMode = {};
            //获取帧率
            desiredSensorMode.frameRate = ExtensionModule::GetInstance()->GetUsecaseMaxFPS(m_logicalCameraId);
            //判断是否支持HDR 模式
            if (ExtensionModule::GetInstance()->IsVideoHDRMode())
            {
                const auto sensorModes = [&]() -> ChiPtrView
                {
                    UINT32             modeCount = 0;
                    CHISENSORMODEINFO* pAllModes = NULL;
                    //获取pLogicalCameraInfo  modeCount pAllModes
                    //pLogicalCameraInfo->m_cameraCaps.numSensorModes
                    //pLogicalCameraInfo->pSensorModeInfo;
                    if (CDKResultSuccess == ExtensionModule::GetInstance()->GetPhysicalCameraSensorModes(m_cameraId,
                                                                                                         &modeCount,
                                                                                                         &pAllModes))
                    {
                        return ChiPtrView{static_cast(modeCount), pAllModes};
                    }
                    return ChiPtrView(static_cast(0), NULL);
                }();

                auto SupportsZZHDR = [&](const ChiSensorModeInfo& rSensorModeInfo)
                {
                    return rSensorModeInfo.sensorModeCaps.u.ZZHDR;
                };
                desiredSensorMode.sensorModeCaps.u.ZZHDR = std::any_of(sensorModes.begin(), sensorModes.end(), SupportsZZHDR);
            }//采用三曝光实现实时HDR预览
            else if (SelectInSensorHDR3ExpUsecase::InSensorHDR3ExpPreview ==
                     ExtensionModule::GetInstance()->SelectInSensorHDR3ExpUsecase())
            {
                desiredSensorMode.sensorModeCaps.u.IHDR = 1;
            }//Staggered HDR 行交织 HDR
            else if (HDRFeatureModeSHDR == physicalHDRMode)
            {
                desiredSensorMode.sensorModeCaps.u.SHDR = 1;
                desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::TwoExposure;
                if (FALSE == rHDRInfo.isAutoHDREnabled)
                {
                    switch (rHDRInfo.appReqNumHDRExposure)
                    {
                        case SingleHDRExposure:
                            desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::OneExposure;
                            break;
                        case TwoHDRExposure:
                            desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::TwoExposure;
                            break;
                        case ThreeHDRExposure:
                            desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::ThreeExposure;
                            break;
                        default:
                            desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::TwoExposure;
                            break;
                    }
                }
            }//MFHDR 多帧 HDR
            else if (HDRFeatureModeMFHDR == physicalHDRMode)
            {
                desiredSensorMode.sensorModeCaps.u.Normal = TRUE;
                // For MFHDR case, we will run sensor @ twice the desired output framerate
                desiredSensorMode.frameRate *= 2;
            }//QHDR(Quad HDR,四像素HDR)
            else if (HDRFeatureModeQHDR == physicalHDRMode)
            {
                if (TRUE == rHDRInfo.appEnabledQHDR)
                {
                    desiredSensorMode.sensorModeCaps.u.QHDR = 1;
                    desiredSensorMode.sensorHDRExposureType = ChiHDRExposureType::ThreeExposure;
                }
            }

            UINT index = FindHighestWidthInputIndex(m_pipelineInputOptions, m_numInputOptions);
            // @todo Select the highest width/height from all the input buffer requirements
            desiredSensorMode.optimalWidth  = m_pipelineInputOptions[index].bufferOptions.optimalDimension.width;
            desiredSensorMode.optimalHeight = m_pipelineInputOptions[index].bufferOptions.optimalDimension.height;
            desiredSensorMode.maxWidth      = m_pipelineInputOptions[index].bufferOptions.maxDimension.width;
            desiredSensorMode.maxHeight     = m_pipelineInputOptions[index].bufferOptions.maxDimension.height;
            desiredSensorMode.minWidth      = m_pipelineInputOptions[index].bufferOptions.minDimension.width;
            desiredSensorMode.minHeight     = m_pipelineInputOptions[index].bufferOptions.minDimension.height;
            desiredSensorMode.forceMode     = ExtensionModule::GetInstance()->GetForceSensorMode(m_cameraId);

            if (TRUE == m_isSensorModeHintSet)
            {
                CHX_LOG("input option:%dx%d, upscale:%d, override optimal size:%dx%d, sensor mode caps:%x",
                    desiredSensorMode.optimalWidth, desiredSensorMode.optimalHeight,
                    m_SensorModePickhint.postSensorUpscale,
                    m_SensorModePickhint.sensorOutputSize.width,
                    m_SensorModePickhint.sensorOutputSize.height,
                    m_SensorModePickhint.sensorModeCaps.value);
                
                 //判断是否支持裁剪 根据设置传感器模式 设置分辨率
                if ((TRUE == m_SensorModePickhint.postSensorUpscale) &&
                    (m_SensorModePickhint.sensorOutputSize.width  < desiredSensorMode.optimalWidth) &&
                    (m_SensorModePickhint.sensorOutputSize.height < desiredSensorMode.optimalHeight))
                {
                    desiredSensorMode.optimalWidth  = m_SensorModePickhint.sensorOutputSize.width;
                    desiredSensorMode.optimalHeight = m_SensorModePickhint.sensorOutputSize.height;
                    desiredSensorMode.maxWidth      = desiredSensorMode.optimalWidth;
                    desiredSensorMode.maxHeight     = desiredSensorMode.optimalHeight;
                    desiredSensorMode.minWidth      = desiredSensorMode.optimalWidth;
                    desiredSensorMode.minHeight     = desiredSensorMode.optimalHeight;
                }

                if (0 != m_SensorModePickhint.sensorModeCaps.value)
                {
                    desiredSensorMode.sensorModeCaps.value = m_SensorModePickhint.sensorModeCaps.value;
                }
                if (0 != m_SensorModePickhint.frameRateMultiplier)
                {
                    desiredSensorMode.frameRate *= m_SensorModePickhint.frameRateMultiplier;
                }

                if (TRUE == m_SensorModePickhint.sensorModeCaps.u.QuadCFA)
                {
                    desiredSensorMode.sensorRemosaicType = ExtensionModule::GetInstance()->GetRemosaicType();
                }
            }
            if (StreamConfigModeFastShutter == ExtensionModule::GetInstance()->GetOpMode(m_cameraId))
            {
                desiredSensorMode.sensorModeCaps.u.FS = 1;
            }

            if (HDRFeatureModeQHDR == physicalHDRMode)
            {
                // QCFA binning mode
                if (FALSE == rHDRInfo.appEnabledQHDR)
                {
                    desiredSensorMode.optimalWidth  = m_pipelineInputOptions[index].bufferOptions.optimalDimension.width >> 1;
                    desiredSensorMode.optimalHeight = m_pipelineInputOptions[index].bufferOptions.optimalDimension.height >> 1;
                }
            }

            m_pSelectedSensorMode                   = ChxSensorModeSelect::FindBestSensorMode(m_cameraId, &desiredSensorMode);
            m_pSelectedSensorMode->batchedFrames    = ExtensionModule::GetInstance()->GetNumBatchedFrames(m_logicalCameraId);
            m_pSelectedSensorMode->HALOutputBufferCombined = ExtensionModule::GetInstance()->GetHALOutputBufferCombined();
        }


        if (TRUE == m_pipelineDescriptor.isRealTime)
        {
            if ((NULL               != pLogicalHDRDeviceInfo) &&
                (HDRFeatureModeSHDR == pLogicalHDRDeviceInfo->HDRModeInfo.HDRMode) &&
                (InvalidMode        != ExtensionModule::GetInstance()->GetForceSensorMode(m_cameraId)))
            {
                // This is to handle the case wherre overridesensor mode is used
                pLogicalHDRDeviceInfo->numHDRExposure = static_cast(m_pSelectedSensorMode->HDRExposureType) + 1;
            }

            m_pipelineInfo.pipelineInputInfo.isInputSensor              = TRUE;
            m_pipelineInfo.pipelineInputInfo.sensorInfo.cameraId        = m_cameraId;
            m_pipelineInfo.pipelineInputInfo.sensorInfo.pSensorModeInfo = m_pSelectedSensorMode;
            CHX_LOG_CORE_CFG("Pipeline[%s] Pipeline pointer %p Selected sensor Mode W=%d, H=%d Mode=%d",
                m_pPipelineName,
                this,
                m_pipelineInfo.pipelineInputInfo.sensorInfo.pSensorModeInfo->frameDimension.width,
                m_pipelineInfo.pipelineInputInfo.sensorInfo.pSensorModeInfo->frameDimension.height,
                m_pipelineInfo.pipelineInputInfo.sensorInfo.pSensorModeInfo->modeIndex);

                std::vector transition_modes = {1, 2, 3};
                std::copy(transition_modes.begin(), transition_modes.end(), std::back_inserter(m_transitionModesList));
            // add changes to get the list of seamless mode transitions possible for this sensor mode
        }
        else
        {
            m_pipelineInfo.pipelineInputInfo.isInputSensor                           = FALSE;
            m_pipelineInfo.pipelineInputInfo.inputBufferInfo.numInputBuffers         = m_numInputBuffers;
            m_pipelineInfo.pipelineInputInfo.inputBufferInfo.pInputBufferDescriptors = GetInputBufferDescriptors();

            if ((FALSE == ExtensionModule::GetInstance()->IsNoBufferUsecase()))
            {
                CHIBUFFERDIMENSION sensorOutDim = {};
                sensorOutDim.width              = m_pSelectedSensorMode->frameDimension.width;
                sensorOutDim.height             = m_pSelectedSensorMode->frameDimension.height;

                for (UINT32 i = 0; i < m_numInputOptions; i++)
                {
                    CHIBUFFEROPTIONS& rBufferOptions = m_pipelineInputOptions[i].bufferOptions;

                    if ((rBufferOptions.minDimension.width  > sensorOutDim.width) ||
                        (rBufferOptions.minDimension.height > sensorOutDim.height))
                    {
                        CHX_LOG_INFO("override min requirement to sensor output size. %dx%d -> %dx%d",
                            rBufferOptions.minDimension.width, rBufferOptions.minDimension.height,
                            sensorOutDim.width, sensorOutDim.height);

                        rBufferOptions.minDimension = sensorOutDim;
                    }

                    if ((rBufferOptions.minDimension.width  > rBufferOptions.optimalDimension.width) ||
                        (rBufferOptions.minDimension.height > rBufferOptions.optimalDimension.height))
                    {
                        rBufferOptions.optimalDimension = rBufferOptions.minDimension;
                    }
                }
            }
        }

        m_pipelineInfo.hPipelineDescriptor                = reinterpret_cast(m_hPipelineHandle);
        m_pipelineInfo.pipelineOutputInfo.hPipelineHandle = NULL;
        m_pipelineInfo.pipelineResourcePolicy             = m_resourcePolicy;
        m_pipelineInfo.isDeferFinalizeNeeded              = m_isDeferFinalizeNeeded;
    }

    return result;
}

HDR科普

https://deepinout.com/hdr/img-sensor-hdr-mode-intro.html

https://sspai.com/post/62228#!

https://deepinout.com/hdr/understand-the-various-types-of-hdr.html

你可能感兴趣的:(camera,c++,qnx)