1、camx的代碼結構node
目前主流的機型都使用camx架構,這個架構和以前架構的主要區別就是 芯片接口層的代碼從hardware/qcom 遷移到 vendor/qcom/proprietary/下面,
咱們主要關注的camera hal層的源碼也是放在vendor/qcom/proprietary/camx/下面。
android
2、camx 編譯:shell
camx的核心目錄是 vendor/qcom/proprietary/camx/src/ 目錄下面:session
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 中。
其中包括的靜態庫以下:架構
# 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
這些靜態庫都是camx或者其餘的目錄下編譯的,編譯工程的時候,咱們要先編譯這些靜態庫,而後編譯camx的動態庫(/vendor/lib/hw/camera.qcom.so)。app
3、camx 代碼流程分析:ide
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)函數
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 映射函數指針操做: hardware/libhardware/modules/camera/3_0/Camera.cppui
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層的函數指針的映射關係。
映射到:vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp 中的:this
// Global dispatch 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}, };
/// 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獲取,創建聯繫:
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 };
這兒直接構成了指針函數的映射關係(對應camxhaldevice.cpp中的函數)。
vendor/qcom/proprietary/camx/src/core/chi/camxchitypes.h中定義了CHIAppCallbacks結構體,以下:
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);
這個結構體是函數指針,映射關係:
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構造函數中,存在下面的執行語句:
CHIHALOverrideEntry funcCHIHALOverrideEntry = reinterpret_cast<CHIHALOverrideEntry>( CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry")); if (NULL != funcCHIHALOverrideEntry) { funcCHIHALOverrideEntry(&m_ChiAppCallbacks); //對應到 chxextensioninterface.cpp 中的chi_hal_override_entry函數 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 函數,以下:
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 中函數指針的一一映射關係。
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp 中的 ExtensionModule::OverrideProcessRequest 函數中執行了 m_pUsecaseFactory->CreateUsecaseObject,以下:
m_pSelectedUsecase[logicalCameraId] = m_pUsecaseFactory->CreateUsecaseObject(&m_logicalCameraInfo[logicalCameraId], static_cast<UsecaseId>(m_SelectedUsecaseId[logicalCameraId]), m_pStreamConfig[logicalCameraId]);
直接調用到: vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecaseutils.cpp 中的 UsecaseFactory::CreateUsecaseObject 函數:
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函數以下:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// 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)); }
這個函數映射關係很重要,也在camx chi中比較常見,直接映射在此文件的CamxChi類中。都是從 vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp中調用過來的。
下面是預覽時capture request 處理流程圖:
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節點來進行的。
camxnode結構圖:
node節點的建立地方在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(...)函數中有這些feature的建立代碼。
拍照的場景分爲前置和後置,前置是單攝,後置是多攝,前面也有介紹,單攝和多攝使用的usecase是不一樣:
前置拍照建立的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
後置拍照建立的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,編譯時會根據此xml的配置生成對應vendor\qcom\proprietary\chi-cdk\vendor\chioverride\default\g_pipelines.h,
vendor\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中會根據pStreamConfig->num_streams選擇到對應的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 被調用:
CDKResult AdvancedCameraUsecase::SelectUsecaseConfig( LogicalCameraInfo* pCameraInfo, ///< Camera info camera3_stream_configuration_t* pStreamConfig) ///< Stream configuration { ... m_pChiUsecase = UsecaseSelector::DefaultMatchingUsecase(pStreamConfig); ... }
4、調試:
修改 \vendor\qcom\proprietary\camx\src\core\camxsettings.xml 設置 log 打印級別,如:
overrideLogLevels=0x1F logInfoMask=0x40080 logVerboseMask=0x40000
-end-