<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          高通 Camx 架構(gòu)了解下(一)

          共 25558字,需瀏覽 52分鐘

           ·

          2020-08-24 17:36

          和你一起終身學習,這里是程序員Android

          通過閱讀本文您將收獲以下知識點:

          一、camx 代碼結(jié)構(gòu)
          二、camx 編譯
          三、camx 代碼流程分析
          四、camx 調(diào)試

          一、camx 代碼結(jié)構(gòu)

          目前主流的機型都使用camx架構(gòu),這個架構(gòu)和之前架構(gòu)的主要區(qū)別就是 芯片接口層的代碼從hardware/qcom 遷移到?vendor/qcom/proprietary/下面,我們主要關(guān)注的camera hal層的源碼也是放在vendor/qcom/proprietary/camx/下面。

          二、camx 編譯

          camx的核心目錄是?vendor/qcom/proprietary/camx/src/目錄下面:

          total 40
          drwxrwxr-x 10 lxl lxl 4096 4月 4 10:52 ./
          drwxrwxr-x 4 lxl lxl 4096 4月 4 10:52 ../
          drwxrwxr-x 3 lxl lxl 4096 4月 4 10:52 chiiqutils/
          drwxrwxr-x 7 lxl lxl 4096 4月 4 10:56 core/
          drwxrwxr-x 7 lxl lxl 4096 4月 4 10:52 csl/
          drwxrwxr-x 14 lxl lxl 4096 4月 4 10:52 hwl/
          drwxrwxr-x 3 lxl lx 4096 4月 4 10:52 lib/
          drwxrwxr-x 3 lxl lxl 4096 4月 4 10:52 osutils/
          drwxrwxr-x 11 lxl lxl 4096 4月 4 10:52 swl/
          drwxrwxr-x 3 lxl lxl 4096 4月 4 10:52 utils/

          核心的Android.mk在?./lib/build/android/Android.mk?中。
          其中包括的靜態(tài)庫如下:

          # Libraries to link
          LOCAL_STATIC_LIBRARIES := \
          libcamxcore \
          libcamxchi \
          libcamxcsl \
          libcamxofflinestats \
          libnc \
          libcamxncs \
          libifestriping \
          libstriping

          LOCAL_WHOLE_STATIC_LIBRARIES := \
          libcamxdspstreamer \
          libcamxhwlbps \
          libcamxgenerated \
          libcamxhal \
          libcamxhalutils \
          libcamxhwlfd \
          libcamxhwlife \
          libcamxhwlipe \
          libcamxhwliqmodule \
          libcamxswlfdmanager \
          libcamxswljpeg \
          libcamxhwljpeg \
          libcamxhwllrme \
          libcamxswlransac \
          libcamxhwltitan17x \
          libcamxiqsetting \
          libcamxosutils \
          libcamxstats \
          libcamxsensor \
          libcamxutils

          這些靜態(tài)庫都是camx或者其他的目錄下編譯的,編譯工程的時候,我們要先編譯這些靜態(tài)庫,然后編譯camx的動態(tài)庫(/vendor/lib/hw/camera.qcom.so)。

          三、camx 代碼流程分析

          camera.provider中如何實現(xiàn)到camera hal層的跳躍,camera service調(diào)用到camera provider中的接口方法,現(xiàn)在調(diào)用到 camera provider中的?hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp中的processCaptureRequest(...)方法,最終會調(diào)用到:

           status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);

          這個mDevice->ops 就是?hardware/libhardware/include/hardware/camera3.h中的 camera3_device_ops 結(jié)構(gòu)體:(參考:https://www.jianshu.com/p/099cc3b0ab25)

          typedef struct camera3_device_ops {
          int (*initialize)(const struct camera3_device *,
          const camera3_callback_ops_t *callback_ops);
          int (*configure_streams)(const struct camera3_device *,
          camera3_stream_configuration_t *stream_list);
          int (*register_stream_buffers)(const struct camera3_device *,
          const camera3_stream_buffer_set_t *buffer_set);
          const camera_metadata_t* (*construct_default_request_settings)(
          const struct camera3_device *,
          int type);
          int (*process_capture_request)(const struct camera3_device *,
          camera3_capture_request_t *request);
          void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,
          vendor_tag_query_ops_t* ops);
          void (*dump)(const struct camera3_device *, int fd);
          int (*flush)(const struct camera3_device *);

          /* reserved for future use */
          void *reserved[8];
          } camera3_device_ops_t;

          camera3_device_ops_t 映射函數(shù)指針操作:?hardware/libhardware/modules/camera/3_0/Camera.cpp

          const camera3_device_ops_t Camera::sOps = {
          .initialize = default_camera_hal::initialize,
          .configure_streams = default_camera_hal::configure_streams,
          .register_stream_buffers = default_camera_hal::register_stream_buffers,
          .construct_default_request_settings
          = default_camera_hal::construct_default_request_settings,
          .process_capture_request = default_camera_hal::process_capture_request,
          .get_metadata_vendor_tag_ops = NULL,
          .dump = default_camera_hal::dump,
          .flush = default_camera_hal::flush,
          .reserved = {0},
          };

          這樣找到在camera hal層的函數(shù)指針的映射關(guān)系。
            映射到:vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp中的static Dispatch g_dispatchHAL3(&g_jumpTableHAL3);

          /// Array containing camera3_device_ops_t methods
          static camera3_device_ops_t g_camera3DeviceOps =
          {
          CamX::initialize,
          CamX::configure_streams,
          NULL,
          CamX::construct_default_request_settings,
          CamX::process_capture_request,
          NULL,
          CamX::dump,
          CamX::flush,
          {0},
          };

          定義了g_camera3DeviceOps變量:

          /// Array containing camera3_device_ops_t methods
          static camera3_device_ops_t g_camera3DeviceOps =
          {
          CamX::initialize,
          CamX::configure_streams,
          NULL,
          CamX::construct_default_request_settings,
          CamX::process_capture_request,
          NULL,
          CamX::dump,
          CamX::flush,
          {0},
          };

          并在\vendor\qcom\proprietary\camx\src\core\hal\camxhaldevice.cpp的Initialize方法中通過GetCamera3DeviceOps獲取,建立聯(lián)系:

          CamxResult HALDevice::Initialize(
          const HwModule* pHwModule,
          UINT32 cameraId)
          {
          CamxResult result = CamxResultSuccess;

          m_cameraId = cameraId;

          if (CamxResultSuccess == result)
          {
          m_camera3Device.hwDevice.tag = HARDWARE_DEVICE_TAG; /// @todo (CAMX-351) Get from local macro
          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.ProcessCaptureResult = ProcessCaptureResult;
          m_HALCallbacks.NotifyResult = Notify;
          CamX::ChiOverrideBypass(&m_HALCallbacks);
          }

          m_pHALSession = NULL;
          Utils::Memset(m_flushRequest, 0, sizeof(m_flushRequest));

          return result;
          }

          看一下g_jumpTableHAL3 變量:在?vendor/qcom/proprietary/camx/src/core/hal/camxhal3.cpp?中定義的:

          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          // Jump table for HAL3
          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          JumpTableHAL3 g_jumpTableHAL3 =
          {
          open,
          get_number_of_cameras,
          get_camera_info,
          set_callbacks,
          get_vendor_tag_ops,
          open_legacy,
          set_torch_mode,
          init,
          parallelQuery,
          setCallBack,
          get_tag_count,
          get_all_tags,
          get_section_name,
          get_tag_name,
          get_tag_type,
          close,
          initialize,
          configure_streams,
          construct_default_request_settings,
          process_capture_request,
          dump,
          flush,
          camera_device_status_change,
          torch_mode_status_change,
          process_capture_result,
          notify
          };

          這兒直接構(gòu)成了指針函數(shù)的映射關(guān)系(對應(yīng)camxhaldevice.cpp中的函數(shù))。vendor/qcom/proprietary/camx/src/core/chi/camxchitypes.h中定義了CHIAppCallbacks結(jié)構(gòu)體,如下:

          struct CHIAppCallbacks
          {
          /// @brief Called by the driver to get number of cameras
          INT(*CHIGetNumCameras)(
          UINT32* pNumFwCameras,
          UINT32* pNumLogicalCameras);

          /// @brief Called by the driver to get the camera info for the camera id
          CamxResult (*CHIGetCameraInfo)(
          UINT32 cameraId,
          CameraInfo* pCameraInfo);

          /// @brief Defines the prototype for the device status change callback method from to the framework. Please refer to
          /// the camera_device_status_change documentation in hardware/camera_common.h.
          VOID (*CHIInitializeOverrideSession)(
          UINT32 cameraId,
          const Camera3Device* pCamera3Device,
          const HALCallbacks* pHALCallbacks,
          Camera3StreamConfig* pStreamConfig,
          BOOL* isOverrideEnabled,
          VOID** ppPrivate);

          /// @brief Defines the prototype for the torch mode status change callback method from to the framework. Please refer to
          /// the torch_mode_status_change documentation in hardware/camera_common.h.
          VOID (*CHIFinalizeOverrideSession)(
          const Camera3Device* pCamera3Device,
          UINT64* pSession,
          VOID** ppPrivate);

          /// @brief Called by the driver to inform about session closing
          VOID (*CHITeardownOverrideSession)(
          const Camera3Device* pCamera3Device,
          UINT64* pSession,
          VOID* pPrivate);

          /// @brief Called by the driver to pass on capture request call to CHI
          INT (*CHIOverrideProcessRequest)(
          const Camera3Device* pCamera3Device,
          Camera3CaptureRequest* pCaptureRequest,
          VOID* pPrivate);

          /// @brief Called by the driver to allow for additional override processing during open()
          INT(*CHIExtendOpen)(
          UINT32 cameraId,
          VOID* pPrivateData);

          /// @brief Called by the driver to allow for additional override processing during close()
          INT(*CHIExtendClose)(
          UINT32 cameraId,
          VOID* pPrivateData);

          /// @brief Called by the driver to allow override to remap special camera IDs into logical camera IDs
          UINT32(*CHIRemapCameraId)(
          UINT32 frameworkCameraId,
          CameraIdRemapMode mode);

          /// @brief Interface to allow various override-specific settings to be toggled.
          UINT32(*CHIModifySettings)(
          VOID* pPrivateData);

          /// @brief Get any vendor tag specific request settings the override wants to get added to the default settings
          VOID (*CHIGetDefaultRequestSettings)(
          UINT32 frameworkCameraId,
          INT requestTemplate,
          const Metadata** pAdditionalMetadata);

          /// @brief Called by the driver to allow for flush()
          INT(*CHIOverrideFlush)(
          const Camera3Device* pCamera3Device);
          INT(*CHIParallelQuery) (INT num, char* list[]);
          INT(*CHISetCallback) (void*);

          };

          typedef VOID(*CHIHALOverrideEntry)(CHIAppCallbacks* pCHIAppCallbacks);

          這個結(jié)構(gòu)體是函數(shù)指針,映射關(guān)系:vendor/qcom/proprietary/camx/src/core/hal/camxhal3module.h中定義了 CHIAppCallbacks m_ChiAppCallbacks;

             CHIAppCallbacks       m_ChiAppCallbacks;                    ///< CHI HAL override entry

          vendor/qcom/proprietary/camx/src/core/hal/camxhal3module.cpp中的 HAL3Module構(gòu)造函數(shù)中,存在下面的執(zhí)行語句:

          CHIHALOverrideEntry funcCHIHALOverrideEntry =
          reinterpret_cast<CHIHALOverrideEntry>(
          CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry"));

          if (NULL != funcCHIHALOverrideEntry)
          {
          funcCHIHALOverrideEntry(&m_ChiAppCallbacks); //對應(yīng)到 chxextensioninterface.cpp 中的chi_hal_override_entry函數(shù)

          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetNumCameras);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetCameraInfo);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideFlush);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHITeardownOverrideSession);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendOpen);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendClose);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIRemapCameraId);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIModifySettings);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIParallelQuery);
          CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHISetCallback);

          if ((NULL != m_ChiAppCallbacks.CHIGetNumCameras) &&
          (NULL != m_ChiAppCallbacks.CHIGetCameraInfo) &&
          (NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession) &&
          (NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession) &&
          (NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest) &&
          (NULL != m_ChiAppCallbacks.CHIOverrideFlush) &&
          (NULL != m_ChiAppCallbacks.CHITeardownOverrideSession) &&
          (NULL != m_ChiAppCallbacks.CHIExtendOpen) &&
          (NULL != m_ChiAppCallbacks.CHIExtendClose) &&
          (NULL != m_ChiAppCallbacks.CHIRemapCameraId) &&
          (NULL != m_ChiAppCallbacks.CHIModifySettings) &&
          (NULL != m_ChiAppCallbacks.CHIParallelQuery) &&
          (NULL != m_ChiAppCallbacks.CHISetCallback))
          {
          CAMX_LOG_WARN(CamxLogGroupHAL, "CHI Module library function pointers exchanged");
          }
          }

          m_ChiAppCallbacks 通過 funcCHIHALOverrideEntry 映射到 chi_hal_override_entry這個 chi_hal_override_entry 就是指vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensioninterface.cpp中的 chi_hal_override_entry 函數(shù),如下:

          void chi_hal_override_entry(
          chi_hal_callback_ops_t* callbacks)
          {
          ExtensionModule* pExtensionModule = ExtensionModule::GetInstance();

          CHX_ASSERT(NULL != callbacks);

          if (NULL != pExtensionModule)
          {
          callbacks->chi_get_num_cameras = chi_get_num_cameras;
          callbacks->chi_get_camera_info = chi_get_camera_info;
          callbacks->chi_initialize_override_session = chi_initialize_override_session;
          callbacks->chi_finalize_override_session = chi_finalize_override_session;
          callbacks->chi_override_process_request = chi_override_process_request;
          callbacks->chi_teardown_override_session = chi_teardown_override_session;
          callbacks->chi_extend_open = chi_extend_open;
          callbacks->chi_extend_close = chi_extend_close;
          callbacks->chi_remap_camera_id = chi_remap_camera_id;
          callbacks->chi_modify_settings = chi_modify_settings;
          callbacks->chi_get_default_request_settings = chi_get_default_request_settings;
          callbacks->chi_override_flush = chi_override_flush;
          callbacks->chi_parallelquery = chi_parallelquery;
          callbacks->chi_setcallback = chi_setcallback;
          }
          }

          這樣就建立了 CHIAppCallbacks 中函數(shù)指針的一一映射關(guān)系。

          vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp 中的 ExtensionModule::OverrideProcessRequest?函數(shù)中執(zhí)行了?m_pUsecaseFactory->CreateUsecaseObject,如下:

          m_pSelectedUsecase[logicalCameraId] =
          m_pUsecaseFactory->CreateUsecaseObject(&m_logicalCameraInfo[logicalCameraId],
          static_cast<UsecaseId>(m_SelectedUsecaseId[logicalCameraId]),
          m_pStreamConfig[logicalCameraId]);

          直接調(diào)用到:vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecaseutils.cpp中的 UsecaseFactory::CreateUsecaseObject 函數(shù):

          Usecase* UsecaseFactory::CreateUsecaseObject(
          LogicalCameraInfo* pLogicalCameraInfo, ///< camera info
          UsecaseId usecaseId, ///< Usecase Id
          camera3_stream_configuration_t* pStreamConfig) ///< Stream config
          {
          Usecase* pUsecase = NULL;
          UINT camera0Id = pLogicalCameraInfo->ppDeviceInfo[0]->cameraId;
          CHX_LOG_ERROR("UsecaseFactory::CreateUsecaseObject id = %d", usecaseId);
          switch (usecaseId)
          {
          case UsecaseId::PreviewZSL:
          pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
          break;
          case UsecaseId::MultiCamera:
          pUsecase = UsecaseMultiCamera::Create(pLogicalCameraInfo, pStreamConfig);
          break;
          case UsecaseId::MultiCameraVR:
          pUsecase = UsecaseMultiVRCamera::Create(pLogicalCameraInfo, pStreamConfig);
          break;
          case UsecaseId::MFNR:
          pUsecase = UsecaseMFNR::Create(camera0Id, pStreamConfig);
          break;
          case UsecaseId::QuadCFA:
          pUsecase = UsecaseQuadCFA::Create(pLogicalCameraInfo, pStreamConfig);
          break;
          case UsecaseId::Torch:
          pUsecase = UsecaseTorch::Create(camera0Id, pStreamConfig);
          break;
          default:
          pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
          break;
          }

          return pUsecase;
          }

          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,
          MaxUsecases = 12,
          };

          前置攝像頭的UsecaseId是 PreviewZSL,是單攝,后置攝像頭的UsecaseId是 MultiCamera,是多攝。

          camx-usecase


          vendor/qcom/proprietary/camx/src/core/chi/camxchi.cpp中的 ChiEntry函數(shù)如下:

          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          /// ChiEntry
          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          CAMX_VISIBILITY_PUBLIC VOID ChiEntry(
          ChiContextOps* pChiContextOps)
          {
          if (NULL != pChiContextOps)
          {
          pChiContextOps->size = sizeof(ChiContextOps);

          pChiContextOps->majorVersion = CHI_API_MAJOR_VERSION;
          pChiContextOps->minorVersion = CHI_API_MINOR_VERSION;
          pChiContextOps->pOpenContext = CamX::ChiOpenContext;
          pChiContextOps->pCloseContext = CamX::ChiCloseContext;
          pChiContextOps->pGetNumCameras = CamX::ChiGetNumCameras;
          pChiContextOps->pGetCameraInfo = CamX::ChiGetCameraInfo;
          pChiContextOps->pEnumerateSensorModes = CamX::ChiEnumerateSensorModes;
          pChiContextOps->pCreatePipelineDescriptor = CamX::ChiCreatePipelineDescriptor;
          pChiContextOps->pDestroyPipelineDescriptor = CamX::ChiDestroyPipelineDescriptor;
          pChiContextOps->pCreateSession = CamX::ChiCreateSession;
          pChiContextOps->pDestroySession = CamX::ChiDestroySession;
          pChiContextOps->pFlushSession = CamX::ChiFlushSession;
          pChiContextOps->pActivatePipeline = CamX::ChiActivatePipeline;
          pChiContextOps->pDeactivatePipeline = CamX::ChiDeactivatePipeline;
          pChiContextOps->pSubmitPipelineRequest = CamX::ChiSubmitPipelineRequest;
          pChiContextOps->pTagOps = CamX::ChiGetTagOps;
          }

          // This is the workaround for presil HAL3test on Windows
          // On Device, set_camera_metadata_vendor_ops will be call the set the
          // static vendor tag operation in camera_metadata.c
          //
          // On Windows side, theoretically hal3test should mimic what Android framework
          // does and call the set_camera_metadata_vendor_ops function in libcamxext library
          // However, in Windows, if both hal3test.exe and hal.dll link to libcamxext library,
          // there are two different instance of static varibles sit in different memory location.
          // Even if set_camera_metadata_vendor_ops is called in hal3test, when hal try to
          // access to vendor tag ops, it is still not set.
          //
          // This is also a workaround to call vendor tag ops in Chi at GetNumCameras which happens to get called before
          // GetVendorTagOps
          CamX::g_vendorTagOps.get_all_tags = CamX::ChiGetAllTags;
          CamX::g_vendorTagOps.get_section_name = CamX::ChiGetSectionName;
          CamX::g_vendorTagOps.get_tag_count = CamX::ChiGetTagCount;
          CamX::g_vendorTagOps.get_tag_name = CamX::ChiGetTagName;
          CamX::g_vendorTagOps.get_tag_type = CamX::ChiGetTagType;

          set_camera_metadata_vendor_ops(&(CamX::g_vendorTagOps));
          }

          這個函數(shù)映射關(guān)系很重要,也在camx chi中比較常見,直接映射在此文件的CamxChi類中。都是從?vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp中調(diào)用過來的。

          下面是預(yù)覽時capture request 處理流程圖:



           check這段流程的時候我們最關(guān)注應(yīng)該是5個重要的處理類型:

          • 1.UseCase
            vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.h上面有介紹類圖。UseCase在camx中很有很多衍生類,這是camx針對不同的stream來建立不同的usecase對象,用來管理選擇feature,并且創(chuàng)建 pipeline以及session。

          • 2.ChiFeature
            vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxfeature.h, usecase選擇相應(yīng)的feature,關(guān)聯(lián)一組pipeline,收到request請求,根據(jù)request選擇對應(yīng)的feature。

          • 3.Node
            vendro/qcom/propriatary/camx/src/core/camxnode.h,下面有類圖。Node是camx中非常重要的一個父類,是camx中處理camera 請求的一個中間節(jié)點,用于處理pipeline下發(fā)的請求,下面有類圖介紹,比較重要**的Node子類已經(jīng)標出來了。

          • 4.pipeline
            一連串node的集合,通過pipeline下發(fā)給各個node處理。

          • 5.session
            若干個有關(guān)聯(lián)的pipeline的集合,用來管理pipeline,使用pipeline處理請求。

          注:Node 節(jié)點在camx chi架構(gòu)中至關(guān)重要,數(shù)據(jù)的處理都是通過封裝好的Node節(jié)點來進行的。


            camxnode結(jié)構(gòu)圖:


          node節(jié)點的創(chuàng)建地方在

          vendor/qcom/proprietary/camx/src/hwl/titian17x/camxtitian17xfactory.cpp

          Node* Titan17xFactory::HwCreateNode(
          const NodeCreateInputData* pCreateInputData,
          NodeCreateOutputData* pCreateOutputData
          ) const
          {
          Node* pNode = NULL;

          switch (pCreateInputData->pNodeInfo->nodeId)
          {
          case AutoFocus:
          pNode = AutoFocusNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case BPS:
          pNode = BPSNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case IFE:
          pNode = IFENode::Create(pCreateInputData, pCreateOutputData);
          break;
          case IPE:
          pNode = IPENode::Create(pCreateInputData, pCreateOutputData);
          break;
          case Sensor:
          pNode = SensorNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case StatsProcessing:
          pNode = StatsProcessingNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case JPEG:
          pNode = JPEGEncNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case JPEGAggregator:
          pNode = JPEGAggrNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case StatsParse:
          pNode = StatsParseNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case ChiExternalNode:
          pNode = ChiNodeWrapper::Create(pCreateInputData, pCreateOutputData);
          break;
          case FDHw:
          pNode = FDHwNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case FDManager:
          pNode = FDManagerNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case OfflineStats:
          pNode = OfflineStatsNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case Torch:
          pNode = TorchNode::Create(pCreateInputData, pCreateOutputData);
          break;
          case LRME:
          pNode = LRMENode::Create(pCreateInputData, pCreateOutputData);
          break;
          case RANSAC:
          pNode = RANSACNode::Create(pCreateInputData, pCreateOutputData);
          break;
          default:
          CAMX_ASSERT_ALWAYS_MESSAGE("Unexpected node type");
          break;
          }

          return pNode;
          }

          camx_feature:


          在?vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxadvancedcamerausecase.cpp中的SelectFeatures(...)函數(shù)中有這些feature的創(chuàng)建代碼。

          拍照的場景分為前置和后置,前置是單攝,后置是多攝,前面也有介紹,單攝和多攝使用的usecase是不同:

          前置拍照創(chuàng)建的pipeline有:


          MiuiZSLSnapshotJpeg at index 0 for session 0, session's pipeline 0, camera id:1
          MiuiZSLPreviewRaw at index 1 for session 1, session's pipeline 0, camera id:1
          BinningZSLYuv2Jpeg at index 2 for session 2, session's pipeline 0, camera id:1
          BinningMerge3YuvCustomTo1Yuv at index 3 for session 3, session's pipeline 0, camera id:1
          ZSLSnapshotYUV at index 4 for session 4, session's pipeline 0, camera id:1
          AdvancedAsdMeta at index 5 for session 5, session's pipeline 0, camera id:1
          SWMFClearShotYuv at index 6 for session 6, session's pipeline 0, camera id:1
          BinningZSLSnapshotYUV at index 7 for session 7, session's pipeline 0, camera id:1

          后置拍照創(chuàng)建的pipeline有:

          BackCameraJpegEncode at index 0 for session 0, session's pipeline 0, camera id:0
          MfnrPrefilter at index 1 for session 0, session's pipeline 1, camera id:0
          MfnrBlend at index 2 for session 0, session's pipeline 2, camera id:0
          MfnrPostFilter at index 3 for session 0, session's pipeline 3, camera id:0
          MfnrScale at index 4 for session 0, session's pipeline 4, camera id:0
          Merge3YuvCustomTo1Yuv at index 5 for session 1, session's pipeline 0, camera id:0
          ZSLSnapshotYUV at index 6 for session 2, session's pipeline 0, camera id:0
          ZSLSnapshotYUVAux at index 7 for session 3, session's pipeline 0, camera id:3
          SWMFSRYuv at index 8 for session 4, session's pipeline 0, camera id:0
          AdvancedAsdMeta at index 9 for session 5, session's pipeline 0, camera id:0

          pipeline在camx中的配置文件是:vendor/qcom/proprietary/chi-cdk/vendor/topology/default/titan17x_usecases.xml,編譯時會根據(jù)此xml的配置生成對應(yīng)vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\g_pipelines.hvendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\build\android\Android.mk:

          ...
          $(info $(shell perl $(CAMX_CDK_PATH)/topology/usecaseconverter.pl $(CAMX_VENDOR_PATH)/topology/default/titan17x_usecases.xml $(LOCAL_PATH)/g_pipelines.h))
          ...

          然后在\vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\chxusecaseutils.cpp中會根據(jù)pStreamConfig->num_streams選擇到對應(yīng)的Usecases(g_pipelines.h中定義):

          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          // UsecaseSelector::DefaultMatchingUsecase
          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          ChiUsecase* UsecaseSelector::DefaultMatchingUsecase(
          camera3_stream_configuration_t* pStreamConfig)
          {
          ...
            pSelectedUsecase = &pChiTargetUsecases->pChiUsecases[i];
          ...

          }

          DefaultMatchingUsecase方法即在\vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\chxadvancedcamerausecase.cpp?被調(diào)用:

          CDKResult AdvancedCameraUsecase::SelectUsecaseConfig(
          LogicalCameraInfo* pCameraInfo, ///< Camera info
          camera3_stream_configuration_t* pStreamConfig) ///< Stream configuration
          {
          ...
          m_pChiUsecase = UsecaseSelector::DefaultMatchingUsecase(pStreamConfig);
          ...
          }

          四、camx 調(diào)試

          修改\vendor\qcom\proprietary\camx\src\core\camxsettings.xml?設(shè)置 log 打印級別,如:

          overrideLogLevels=0x1F
          logInfoMask=0x40080
          logVerboseMask=0x40000

          原文鏈接:https://www.cnblogs.com/blogs-of-lxl/p/10668554.html

          相關(guān)文章友情推薦?

          1. Android開發(fā)干貨分享

          至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,如有侵權(quán),懇請聯(lián)系小編刪除,歡迎您的建議與指正。同時期待您的關(guān)注,感謝您的閱讀,謝謝!

          點個在看,方便您使用時快速查看!


          瀏覽 74
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人日日夜夜av 成人三级电影久久 | 99热天天干 | 亚洲第一免费视频 | 久草新| 一级片在线观看视频 |