Camera camx hal-架构(一),7年老Android一次操蛋的面试经历

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 中函数指针的一一映射关系。



![](https://img-blog.csdnimg.cn/img_convert/f2d3fe4ad0c2363b5b31e3723b356f2f.png)



`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,是多摄。



![](https://img-blog.csdnimg.cn/img_convert/c5effdebcfa503967719b5de36cc93df.png)



**camx-usecase**  

![ ](https://img-blog.csdnimg.cn/img_convert/e72d97d17c0a7b73bc88002741910ae7.png)



`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));

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

结尾

最后,针对上面谈的内容,给大家推荐一个Android资料,应该对大家有用。

首先是一个知识清单:(对于现在的Android及移动互联网来说,我们需要掌握的技术)

泛型原理丶反射原理丶Java虚拟机原理丶线程池原理丶
注解原理丶注解原理丶序列化
Activity知识体系(Activity的生命周期丶Activity的任务栈丶Activity的启动模式丶View源码丶Fragment内核相关丶service原理等)
代码框架结构优化(数据结构丶排序算法丶设计模式)
APP性能优化(用户体验优化丶适配丶代码调优)
热修复丶热升级丶Hook技术丶IOC架构设计
NDK(c编程丶C++丶JNI丶LINUX)
如何提高开发效率?
MVC丶MVP丶MVVM
微信小程序
Hybrid
Flutter

接下来是资料清单:(敲黑板!!!


1.数据结构和算法

2.设计模式

3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记

4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)

不论遇到什么困难,都不应该成为我们放弃的理由!共勉~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算


1.数据结构和算法

[外链图片转存中…(img-mmvCswRJ-1712129564257)]

2.设计模式

[外链图片转存中…(img-bMLnFtdn-1712129564257)]

3.全套体系化高级架构视频;七大主流技术模块,视频+源码+笔记

[外链图片转存中…(img-0Owt4eRg-1712129564258)]

4.面试专题资料包(怎么能少了一份全面的面试题总结呢~)

[外链图片转存中…(img-lSU3WR6z-1712129564258)]

不论遇到什么困难,都不应该成为我们放弃的理由!共勉~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

[外链图片转存中…(img-D3VKihZW-1712129564259)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 23
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值