当前位置:   article > 正文

高通Camx 架构学习笔记

camx

418a7ac46685a6e694849c4eed6d99f0.gif

和你一起终身学习,这里是程序员Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、Camx 代码结构
二、Camx 编译
三、Camx 代码流程分析
四、Camx 调试

一、Camx 代码结构

目前主流的机型都使用camx架构,这个架构和之前架构的主要区别就是 芯片接口层的代码从hardware/qcom 迁移到 vendor/qcom/proprietary/下面,我们主要关注的camera hal层的源码也是放在vendor/qcom/proprietary/camx/下面。

1.1 camera 相关代码目录

e8471d4332d63d74d889909440a6c4fc.jpeg

二、camx 编译

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

  1. total 40
  2. drwxrwxr-x 10 lxl lxl 4096 44 10:52 ./
  3. drwxrwxr-x 4 lxl lxl 4096 44 10:52 ../
  4. drwxrwxr-x 3 lxl lxl 4096 44 10:52 chiiqutils/
  5. drwxrwxr-x 7 lxl lxl 4096 44 10:56 core/
  6. drwxrwxr-x 7 lxl lxl 4096 44 10:52 csl/
  7. drwxrwxr-x 14 lxl lxl 4096 44 10:52 hwl/
  8. drwxrwxr-x 3 lxl lx 4096 44 10:52 lib/
  9. drwxrwxr-x 3 lxl lxl 4096 44 10:52 osutils/
  10. drwxrwxr-x 11 lxl lxl 4096 44 10:52 swl/
  11. drwxrwxr-x 3 lxl lxl 4096 44 10:52 utils/

核心的Android.mk在 ./lib/build/android/Android.mk 中。
其中包括的静态库如下:

  1. # Libraries to link
  2. LOCAL_STATIC_LIBRARIES := \
  3. libcamxcore \
  4. libcamxchi \
  5. libcamxcsl \
  6. libcamxofflinestats \
  7. libnc \
  8. libcamxncs \
  9. libifestriping \
  10. libstriping
  11. LOCAL_WHOLE_STATIC_LIBRARIES := \
  12. libcamxdspstreamer \
  13. libcamxhwlbps \
  14. libcamxgenerated \
  15. libcamxhal \
  16. libcamxhalutils \
  17. libcamxhwlfd \
  18. libcamxhwlife \
  19. libcamxhwlipe \
  20. libcamxhwliqmodule \
  21. libcamxswlfdmanager \
  22. libcamxswljpeg \
  23. libcamxhwljpeg \
  24. libcamxhwllrme \
  25. libcamxswlransac \
  26. libcamxhwltitan17x \
  27. libcamxiqsetting \
  28. libcamxosutils \
  29. libcamxstats \
  30. libcamxsensor \
  31. libcamxutils

这些静态库都是camx或者其他的目录下编译的,编译工程的时候,我们要先编译这些静态库,然后编译camx的动态库(/vendor/lib/hw/camera.qcom.so)。

三、camx 代码流程分析

camera.provider中如何实现到camera hal层的跳跃,camera service调用到camera provider中的接口方法,现在调用到 camera provider中的 hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp中的processCaptureRequest(...)方法,最终会调用到:

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

这个mDevice->ops 就是 hardware/libhardware/include/hardware/camera3.h中的 camera3_device_ops 结构体: (参考:https://www.jianshu.com/p/099cc3b0ab25)

  1. typedef struct camera3_device_ops {
  2. int (*initialize)(const struct camera3_device *,
  3. const camera3_callback_ops_t *callback_ops);
  4. int (*configure_streams)(const struct camera3_device *,
  5. camera3_stream_configuration_t *stream_list);
  6. int (*register_stream_buffers)(const struct camera3_device *,
  7. const camera3_stream_buffer_set_t *buffer_set);
  8. const camera_metadata_t* (*construct_default_request_settings)(
  9. const struct camera3_device *,
  10. int type);
  11. int (*process_capture_request)(const struct camera3_device *,
  12. camera3_capture_request_t *request);
  13. void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,
  14. vendor_tag_query_ops_t* ops);
  15. void (*dump)(const struct camera3_device *, int fd);
  16. int (*flush)(const struct camera3_device *);
  17. /* reserved for future use */
  18. void *reserved[8];
  19. } camera3_device_ops_t;

camera3_device_ops_t 映射函数指针操作: hardware/libhardware/modules/camera/3_0/Camera.cpp

  1. const camera3_device_ops_t Camera::sOps = {
  2. .initialize = default_camera_hal::initialize,
  3. .configure_streams = default_camera_hal::configure_streams,
  4. .register_stream_buffers = default_camera_hal::register_stream_buffers,
  5. .construct_default_request_settings
  6. = default_camera_hal::construct_default_request_settings,
  7. .process_capture_request = default_camera_hal::process_capture_request,
  8. .get_metadata_vendor_tag_ops = NULL,
  9. .dump = default_camera_hal::dump,
  10. .flush = default_camera_hal::flush,
  11. .reserved = {0},
  12. };

这样找到在camera hal层的函数指针的映射关系。
  映射到:vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp中的static Dispatch g_dispatchHAL3(&g_jumpTableHAL3);

  1. /// Array containing camera3_device_ops_t methods
  2. static camera3_device_ops_t g_camera3DeviceOps =
  3. {
  4. CamX::initialize,
  5. CamX::configure_streams,
  6. NULL,
  7. CamX::construct_default_request_settings,
  8. CamX::process_capture_request,
  9. NULL,
  10. CamX::dump,
  11. CamX::flush,
  12. {0},
  13. };

定义了g_camera3DeviceOps变量:

  1. /// Array containing camera3_device_ops_t methods
  2. static camera3_device_ops_t g_camera3DeviceOps =
  3. {
  4. CamX::initialize,
  5. CamX::configure_streams,
  6. NULL,
  7. CamX::construct_default_request_settings,
  8. CamX::process_capture_request,
  9. NULL,
  10. CamX::dump,
  11. CamX::flush,
  12. {0},
  13. };

并在\vendor\qcom\proprietary\camx\src\core\hal\camxhaldevice.cpp的Initialize方法中通过GetCamera3DeviceOps获取,建立联系:

  1. CamxResult HALDevice::Initialize(
  2. const HwModule* pHwModule,
  3. UINT32 cameraId)
  4. {
  5. CamxResult result = CamxResultSuccess;
  6. m_cameraId = cameraId;
  7. if (CamxResultSuccess == result)
  8. {
  9. m_camera3Device.hwDevice.tag = HARDWARE_DEVICE_TAG; /// @todo (CAMX-351) Get from local macro
  10. m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_3;
  11. m_camera3Device.hwDevice.close = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());
  12. m_camera3Device.pDeviceOps = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());
  13. m_camera3Device.pPrivateData = this;
  14. // NOWHINE CP036a: Need exception here
  15. m_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);
  16. m_HALCallbacks.ProcessCaptureResult = ProcessCaptureResult;
  17. m_HALCallbacks.NotifyResult = Notify;
  18. CamX::ChiOverrideBypass(&m_HALCallbacks);
  19. }
  20. m_pHALSession = NULL;
  21. Utils::Memset(m_flushRequest, 0, sizeof(m_flushRequest));
  22. return result;
  23. }

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

  1. // Jump table for HAL3
  2. JumpTableHAL3 g_jumpTableHAL3 =
  3. {
  4. open,
  5. get_number_of_cameras,
  6. get_camera_info,
  7. set_callbacks,
  8. get_vendor_tag_ops,
  9. open_legacy,
  10. set_torch_mode,
  11. init,
  12. parallelQuery,
  13. setCallBack,
  14. get_tag_count,
  15. get_all_tags,
  16. get_section_name,
  17. get_tag_name,
  18. get_tag_type,
  19. close,
  20. initialize,
  21. configure_streams,
  22. construct_default_request_settings,
  23. process_capture_request,
  24. dump,
  25. flush,
  26. camera_device_status_change,
  27. torch_mode_status_change,
  28. process_capture_result,
  29. notify
  30. };

这儿直接构成了指针函数的映射关系(对应camxhaldevice.cpp中的函数)。vendor/qcom/proprietary/camx/src/core/chi/camxchitypes.h中定义了CHIAppCallbacks结构体,如下:

  1. struct CHIAppCallbacks
  2. {
  3. /// @brief Called by the driver to get number of cameras
  4. INT(*CHIGetNumCameras)(
  5. UINT32* pNumFwCameras,
  6. UINT32* pNumLogicalCameras);
  7. /// @brief Called by the driver to get the camera info for the camera id
  8. CamxResult (*CHIGetCameraInfo)(
  9. UINT32 cameraId,
  10. CameraInfo* pCameraInfo);
  11. /// @brief Defines the prototype for the device status change callback method from to the framework. Please refer to
  12. /// the camera_device_status_change documentation in hardware/camera_common.h.
  13. VOID (*CHIInitializeOverrideSession)(
  14. UINT32 cameraId,
  15. const Camera3Device* pCamera3Device,
  16. const HALCallbacks* pHALCallbacks,
  17. Camera3StreamConfig* pStreamConfig,
  18. BOOL* isOverrideEnabled,
  19. VOID** ppPrivate);
  20. /// @brief Defines the prototype for the torch mode status change callback method from to the framework. Please refer to
  21. /// the torch_mode_status_change documentation in hardware/camera_common.h.
  22. VOID (*CHIFinalizeOverrideSession)(
  23. const Camera3Device* pCamera3Device,
  24. UINT64* pSession,
  25. VOID** ppPrivate);
  26. /// @brief Called by the driver to inform about session closing
  27. VOID (*CHITeardownOverrideSession)(
  28. const Camera3Device* pCamera3Device,
  29. UINT64* pSession,
  30. VOID* pPrivate);
  31. /// @brief Called by the driver to pass on capture request call to CHI
  32. INT (*CHIOverrideProcessRequest)(
  33. const Camera3Device* pCamera3Device,
  34. Camera3CaptureRequest* pCaptureRequest,
  35. VOID* pPrivate);
  36. /// @brief Called by the driver to allow for additional override processing during open()
  37. INT(*CHIExtendOpen)(
  38. UINT32 cameraId,
  39. VOID* pPrivateData);
  40. /// @brief Called by the driver to allow for additional override processing during close()
  41. INT(*CHIExtendClose)(
  42. UINT32 cameraId,
  43. VOID* pPrivateData);
  44. /// @brief Called by the driver to allow override to remap special camera IDs into logical camera IDs
  45. UINT32(*CHIRemapCameraId)(
  46. UINT32 frameworkCameraId,
  47. CameraIdRemapMode mode);
  48. /// @brief Interface to allow various override-specific settings to be toggled.
  49. UINT32(*CHIModifySettings)(
  50. VOID* pPrivateData);
  51. /// @brief Get any vendor tag specific request settings the override wants to get added to the default settings
  52. VOID (*CHIGetDefaultRequestSettings)(
  53. UINT32 frameworkCameraId,
  54. INT requestTemplate,
  55. const Metadata** pAdditionalMetadata);
  56. /// @brief Called by the driver to allow for flush()
  57. INT(*CHIOverrideFlush)(
  58. const Camera3Device* pCamera3Device);
  59. INT(*CHIParallelQuery) (INT num, char* list[]);
  60. INT(*CHISetCallback) (void*);
  61. };
  62. typedef VOID(*CHIHALOverrideEntry)(CHIAppCallbacks* pCHIAppCallbacks);

这个结构体是函数指针,映射关系: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构造函数中,存在下面的执行语句:

  1. CHIHALOverrideEntry funcCHIHALOverrideEntry =
  2. reinterpret_cast<CHIHALOverrideEntry>(
  3. CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry"));
  4. if (NULL != funcCHIHALOverrideEntry)
  5. {
  6. funcCHIHALOverrideEntry(&m_ChiAppCallbacks); //对应到 chxextensioninterface.cpp 中的chi_hal_override_entry函数
  7. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetNumCameras);
  8. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIGetCameraInfo);
  9. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession);
  10. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession);
  11. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest);
  12. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIOverrideFlush);
  13. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHITeardownOverrideSession);
  14. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendOpen);
  15. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIExtendClose);
  16. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIRemapCameraId);
  17. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIModifySettings);
  18. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHIParallelQuery);
  19. CAMX_ASSERT(NULL != m_ChiAppCallbacks.CHISetCallback);
  20. if ((NULL != m_ChiAppCallbacks.CHIGetNumCameras) &&
  21. (NULL != m_ChiAppCallbacks.CHIGetCameraInfo) &&
  22. (NULL != m_ChiAppCallbacks.CHIFinalizeOverrideSession) &&
  23. (NULL != m_ChiAppCallbacks.CHIInitializeOverrideSession) &&
  24. (NULL != m_ChiAppCallbacks.CHIOverrideProcessRequest) &&
  25. (NULL != m_ChiAppCallbacks.CHIOverrideFlush) &&
  26. (NULL != m_ChiAppCallbacks.CHITeardownOverrideSession) &&
  27. (NULL != m_ChiAppCallbacks.CHIExtendOpen) &&
  28. (NULL != m_ChiAppCallbacks.CHIExtendClose) &&
  29. (NULL != m_ChiAppCallbacks.CHIRemapCameraId) &&
  30. (NULL != m_ChiAppCallbacks.CHIModifySettings) &&
  31. (NULL != m_ChiAppCallbacks.CHIParallelQuery) &&
  32. (NULL != m_ChiAppCallbacks.CHISetCallback))
  33. {
  34. CAMX_LOG_WARN(CamxLogGroupHAL, "CHI Module library function pointers exchanged");
  35. }
  36. }

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 函数,如下:

  1. void chi_hal_override_entry(
  2. chi_hal_callback_ops_t* callbacks)
  3. {
  4. ExtensionModule* pExtensionModule = ExtensionModule::GetInstance();
  5. CHX_ASSERT(NULL != callbacks);
  6. if (NULL != pExtensionModule)
  7. {
  8. callbacks->chi_get_num_cameras = chi_get_num_cameras;
  9. callbacks->chi_get_camera_info = chi_get_camera_info;
  10. callbacks->chi_initialize_override_session = chi_initialize_override_session;
  11. callbacks->chi_finalize_override_session = chi_finalize_override_session;
  12. callbacks->chi_override_process_request = chi_override_process_request;
  13. callbacks->chi_teardown_override_session = chi_teardown_override_session;
  14. callbacks->chi_extend_open = chi_extend_open;
  15. callbacks->chi_extend_close = chi_extend_close;
  16. callbacks->chi_remap_camera_id = chi_remap_camera_id;
  17. callbacks->chi_modify_settings = chi_modify_settings;
  18. callbacks->chi_get_default_request_settings = chi_get_default_request_settings;
  19. callbacks->chi_override_flush = chi_override_flush;
  20. callbacks->chi_parallelquery = chi_parallelquery;
  21. callbacks->chi_setcallback = chi_setcallback;
  22. }
  23. }

这样就建立了 CHIAppCallbacks 中函数指针的一一映射关系。

d62d96252f127aa7ea7d2d90ea3f0469.jpeg

vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp 中的 ExtensionModule::OverrideProcessRequest 函数中执行了 m_pUsecaseFactory->CreateUsecaseObject,如下:

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

直接调用到:vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecaseutils.cpp中的 UsecaseFactory::CreateUsecaseObject 函数:

  1. Usecase* UsecaseFactory::CreateUsecaseObject(
  2. LogicalCameraInfo* pLogicalCameraInfo, ///< camera info
  3. UsecaseId usecaseId, ///< Usecase Id
  4. camera3_stream_configuration_t* pStreamConfig) ///< Stream config
  5. {
  6. Usecase* pUsecase = NULL;
  7. UINT camera0Id = pLogicalCameraInfo->ppDeviceInfo[0]->cameraId;
  8. CHX_LOG_ERROR("UsecaseFactory::CreateUsecaseObject id = %d", usecaseId);
  9. switch (usecaseId)
  10. {
  11. case UsecaseId::PreviewZSL:
  12. pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
  13. break;
  14. case UsecaseId::MultiCamera:
  15. pUsecase = UsecaseMultiCamera::Create(pLogicalCameraInfo, pStreamConfig);
  16. break;
  17. case UsecaseId::MultiCameraVR:
  18. pUsecase = UsecaseMultiVRCamera::Create(pLogicalCameraInfo, pStreamConfig);
  19. break;
  20. case UsecaseId::MFNR:
  21. pUsecase = UsecaseMFNR::Create(camera0Id, pStreamConfig);
  22. break;
  23. case UsecaseId::QuadCFA:
  24. pUsecase = UsecaseQuadCFA::Create(pLogicalCameraInfo, pStreamConfig);
  25. break;
  26. case UsecaseId::Torch:
  27. pUsecase = UsecaseTorch::Create(camera0Id, pStreamConfig);
  28. break;
  29. default:
  30. pUsecase = AdvancedCameraUsecase::Create(pLogicalCameraInfo, pStreamConfig, usecaseId);
  31. break;
  32. }
  33. return pUsecase;
  34. }
  1. enum class UsecaseId
  2. {
  3. NoMatch = 0,
  4. Default = 1,
  5. Preview = 2,
  6. PreviewZSL = 3,
  7. MFNR = 4,
  8. MFSR = 5,
  9. MultiCamera = 6,
  10. QuadCFA = 7,
  11. RawJPEG = 8,
  12. MultiCameraVR = 9,
  13. Torch = 10,
  14. YUVInBlobOut = 11,
  15. MaxUsecases = 12,
  16. };

前置摄像头的UsecaseId是 PreviewZSL,是单摄,后置摄像头的UsecaseId是 MultiCamera,是多摄。

f125fedce56fd9a10acd1d5a31371981.jpeg

camx-usecase

386c268632861d13d4e630e8709ed0b8.jpeg

vendor/qcom/proprietary/camx/src/core/chi/camxchi.cpp中的 ChiEntry函数如下:

  1. /// ChiEntry
  2. CAMX_VISIBILITY_PUBLIC VOID ChiEntry(
  3. ChiContextOps* pChiContextOps)
  4. {
  5. if (NULL != pChiContextOps)
  6. {
  7. pChiContextOps->size = sizeof(ChiContextOps);
  8. pChiContextOps->majorVersion = CHI_API_MAJOR_VERSION;
  9. pChiContextOps->minorVersion = CHI_API_MINOR_VERSION;
  10. pChiContextOps->pOpenContext = CamX::ChiOpenContext;
  11. pChiContextOps->pCloseContext = CamX::ChiCloseContext;
  12. pChiContextOps->pGetNumCameras = CamX::ChiGetNumCameras;
  13. pChiContextOps->pGetCameraInfo = CamX::ChiGetCameraInfo;
  14. pChiContextOps->pEnumerateSensorModes = CamX::ChiEnumerateSensorModes;
  15. pChiContextOps->pCreatePipelineDescriptor = CamX::ChiCreatePipelineDescriptor;
  16. pChiContextOps->pDestroyPipelineDescriptor = CamX::ChiDestroyPipelineDescriptor;
  17. pChiContextOps->pCreateSession = CamX::ChiCreateSession;
  18. pChiContextOps->pDestroySession = CamX::ChiDestroySession;
  19. pChiContextOps->pFlushSession = CamX::ChiFlushSession;
  20. pChiContextOps->pActivatePipeline = CamX::ChiActivatePipeline;
  21. pChiContextOps->pDeactivatePipeline = CamX::ChiDeactivatePipeline;
  22. pChiContextOps->pSubmitPipelineRequest = CamX::ChiSubmitPipelineRequest;
  23. pChiContextOps->pTagOps = CamX::ChiGetTagOps;
  24. }
  25. // This is the workaround for presil HAL3test on Windows
  26. // On Device, set_camera_metadata_vendor_ops will be call the set the
  27. // static vendor tag operation in camera_metadata.c
  28. //
  29. // On Windows side, theoretically hal3test should mimic what Android framework
  30. // does and call the set_camera_metadata_vendor_ops function in libcamxext library
  31. // However, in Windows, if both hal3test.exe and hal.dll link to libcamxext library,
  32. // there are two different instance of static varibles sit in different memory location.
  33. // Even if set_camera_metadata_vendor_ops is called in hal3test, when hal try to
  34. // access to vendor tag ops, it is still not set.
  35. //
  36. // This is also a workaround to call vendor tag ops in Chi at GetNumCameras which happens to get called before
  37. // GetVendorTagOps
  38. CamX::g_vendorTagOps.get_all_tags = CamX::ChiGetAllTags;
  39. CamX::g_vendorTagOps.get_section_name = CamX::ChiGetSectionName;
  40. CamX::g_vendorTagOps.get_tag_count = CamX::ChiGetTagCount;
  41. CamX::g_vendorTagOps.get_tag_name = CamX::ChiGetTagName;
  42. CamX::g_vendorTagOps.get_tag_type = CamX::ChiGetTagType;
  43. set_camera_metadata_vendor_ops(&(CamX::g_vendorTagOps));
  44. }

这个函数映射关系很重要,也在camx chi中比较常见,直接映射在此文件的CamxChi类中。都是从 vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp中调用过来的。

下面是预览时capture request 处理流程图:

8ac3f8a2d68f6be7b106a0cf963813c5.jpeg

 check这段流程的时候我们最关注应该是5个重要的处理类型:

  • 1.UseCase
    vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.h上面有介绍类图。UseCase在camx中很有很多衍生类,这是camx针对不同的stream来建立不同的usecase对象,用来管理选择feature,并且创建 pipeline以及session。

  • 2.ChiFeature
    vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxfeature.h, usecase选择相应的feature,关联一组pipeline,收到request请求,根据request选择对应的feature。

  • 3.Node
    vendro/qcom/propriatary/camx/src/core/camxnode.h,下面有类图。Node是camx中非常重要的一个父类,是camx中处理camera 请求的一个中间节点,用于处理pipeline下发的请求,下面有类图介绍,比较重要**的Node子类已经标出来了。

  • 4.pipeline
    一连串node的集合,通过pipeline下发给各个node处理。

  • 5.session
    若干个有关联的pipeline的集合,用来管理pipeline,使用pipeline处理请求。

注: Node 节点在camx chi架构中至关重要,数据的处理都是通过封装好的Node节点来进行的。

1e9c500f2b66599748f76ca20e6a4516.jpeg


  camxnode结构图:

1ec4e413e3404b276c000eafffe55f72.jpeg


node节点的创建地方在vendor/qcom/proprietary/camx/src/hwl/titian17x/camxtitian17xfactory.cpp

  1. Node* Titan17xFactory::HwCreateNode(
  2. const NodeCreateInputData* pCreateInputData,
  3. NodeCreateOutputData* pCreateOutputData
  4. ) const
  5. {
  6. Node* pNode = NULL;
  7. switch (pCreateInputData->pNodeInfo->nodeId)
  8. {
  9. case AutoFocus:
  10. pNode = AutoFocusNode::Create(pCreateInputData, pCreateOutputData);
  11. break;
  12. case BPS:
  13. pNode = BPSNode::Create(pCreateInputData, pCreateOutputData);
  14. break;
  15. case IFE:
  16. pNode = IFENode::Create(pCreateInputData, pCreateOutputData);
  17. break;
  18. case IPE:
  19. pNode = IPENode::Create(pCreateInputData, pCreateOutputData);
  20. break;
  21. case Sensor:
  22. pNode = SensorNode::Create(pCreateInputData, pCreateOutputData);
  23. break;
  24. case StatsProcessing:
  25. pNode = StatsProcessingNode::Create(pCreateInputData, pCreateOutputData);
  26. break;
  27. case JPEG:
  28. pNode = JPEGEncNode::Create(pCreateInputData, pCreateOutputData);
  29. break;
  30. case JPEGAggregator:
  31. pNode = JPEGAggrNode::Create(pCreateInputData, pCreateOutputData);
  32. break;
  33. case StatsParse:
  34. pNode = StatsParseNode::Create(pCreateInputData, pCreateOutputData);
  35. break;
  36. case ChiExternalNode:
  37. pNode = ChiNodeWrapper::Create(pCreateInputData, pCreateOutputData);
  38. break;
  39. case FDHw:
  40. pNode = FDHwNode::Create(pCreateInputData, pCreateOutputData);
  41. break;
  42. case FDManager:
  43. pNode = FDManagerNode::Create(pCreateInputData, pCreateOutputData);
  44. break;
  45. case OfflineStats:
  46. pNode = OfflineStatsNode::Create(pCreateInputData, pCreateOutputData);
  47. break;
  48. case Torch:
  49. pNode = TorchNode::Create(pCreateInputData, pCreateOutputData);
  50. break;
  51. case LRME:
  52. pNode = LRMENode::Create(pCreateInputData, pCreateOutputData);
  53. break;
  54. case RANSAC:
  55. pNode = RANSACNode::Create(pCreateInputData, pCreateOutputData);
  56. break;
  57. default:
  58. CAMX_ASSERT_ALWAYS_MESSAGE("Unexpected node type");
  59. break;
  60. }
  61. return pNode;
  62. }

ca470f10ffe465f0ce2bc96879028337.jpeg

camx_feature:

d78948b7fddd603c8f6ddb76d30a7c5d.jpeg

在 vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxadvancedcamerausecase.cpp中的SelectFeatures(...)函数中有这些feature的创建代码。

拍照的场景分为前置和后置,前置是单摄,后置是多摄,前面也有介绍,单摄和多摄使用的usecase是不同:

前置拍照创建的pipeline有:

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

后置拍照创建的pipeline有:

  1. BackCameraJpegEncode at index 0 for session 0, session's pipeline 0, camera id:0
  2. MfnrPrefilter at index 1 for session 0, session's pipeline 1, camera id:0
  3. MfnrBlend at index 2 for session 0, session's pipeline 2, camera id:0
  4. MfnrPostFilter at index 3 for session 0, session's pipeline 3, camera id:0
  5. MfnrScale at index 4 for session 0, session's pipeline 4, camera id:0
  6. Merge3YuvCustomTo1Yuv at index 5 for session 1, session's pipeline 0, camera id:0
  7. ZSLSnapshotYUV at index 6 for session 2, session's pipeline 0, camera id:0
  8. ZSLSnapshotYUVAux at index 7 for session 3, session's pipeline 0, camera id:3
  9. SWMFSRYuv at index 8 for session 4, session's pipeline 0, camera id:0
  10. 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,编译时会根据此xml的配置生成对应vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\g_pipelines.hvendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\build\android\Android.mk:

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

然后在\vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\chxusecaseutils.cpp中会根据pStreamConfig->num_streams选择到对应的Usecases(g_pipelines.h中定义):

  1. // UsecaseSelector::DefaultMatchingUsecase
  2. ChiUsecase* UsecaseSelector::DefaultMatchingUsecase(
  3. camera3_stream_configuration_t* pStreamConfig)
  4. {
  5. ...
  6.   pSelectedUsecase = &pChiTargetUsecases->pChiUsecases[i];
  7. ...
  8. }

DefaultMatchingUsecase方法即在\vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\chxadvancedcamerausecase.cpp 被调用:

  1. CDKResult AdvancedCameraUsecase::SelectUsecaseConfig(
  2. LogicalCameraInfo* pCameraInfo, ///< Camera info
  3. camera3_stream_configuration_t* pStreamConfig) ///< Stream configuration
  4. {
  5. ...
  6. m_pChiUsecase = UsecaseSelector::DefaultMatchingUsecase(pStreamConfig);
  7. ...
  8. }

四、Camx 调试log开关

修改\vendor\qcom\proprietary\camx\src\core\camxsettings.xml 设置 log 打印级别,如:

  1. overrideLogLevels=0x1F
  2. logInfoMask=0x40080
  3. logVerboseMask=0x40000

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

友情推荐:

Android 开发干货集锦

至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

117046265a79101ae4e97c9b9a8a7853.jpeg

点击阅读原文,为大佬点赞!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/596313
推荐阅读
相关标签
  

闽ICP备14008679号