共计 14264 个字符,预计需要花费 36 分钟才能阅读完成。
和你一起一生学习,这里是程序员 Android
本篇文章次要介绍 Android
开发中的局部知识点,通过浏览本篇文章,您将播种以下内容:
一、Android Hal3 回顾
二、Qcom Hal3 CamX 架构
三、Qcom Hal3 Camx 重点
一、Android Hal3 回顾
Camera HAL3 学习
HAL 层操作简略总结:
- Framework 层发送捕捉数据的异步申请。
- HAL 层设施必须依照秩序解决申请。对于每个申请,HAL 层须要输入元数据和一个或者多个图像数据。
- 对于申请和后果都须要遵循先进先出的准则;这个数据流将被后续的申请所参考。
- 对于同一个申请,所有输入数据的工夫戳必须雷同,以便 framework 层同步输入数据,如果需要的话。
- 在申请和后果数据总,所有捕捉数据的配置和状态(除了 3A 解决),都须要封装起来。
二、Qcom Hal3 CamX 架构
Qcom 作为平台厂商会依据谷歌定义的 HAL3 接口来实现本人的 Camera HAL3, 新的支流的 Qcom Camera HAL3 架构就是 CamX 了.
Camx 的具体过程可参考高通文档:
80-pc212-1_d_qualcomm_spectra_isp_camera_chi_api_reference.pdf
最次要还是要看 code, 手机厂商对该层代码有本人的改变, 可能差异还是有的, 具体我的项目大体框架统一但细节有区别, 差别和机型的高通基线也保持一致.
2.1 CamX 架构总体构造
简略总结下:
- Camx 的架构入口为 Camx 包中的 camxhal3entry.cpp,Camx 中是高通平台 Camx 架构的外围跳转及解决业务的代码, 个别手机厂商不会去更改, 代码目录在 vendor/qcom/proprietary/camx/ 下, 编译后果是 camera.qcom.so
- Camx 通过 chxentensionInterface 调用到 chi-cdk 包下的代码, 这外面个别是手机厂商本人定制性能的中央, 代码目录在 vendor/qcom/proprietary/chi-cdk/, 编译后果是 com.qti.chi.override.so
- 从这张图中大略晓得一个 request 来业务流程交给 camx 解决, 但会通过 chi-cdk 进行 request 定制化从新打包再交给 camx 理论去执行或和 kernel driver 层进行交互,camx 局部代码即外围流程管控的代码, 而 chi-cdk 正是手机厂商想要实现本人定制化性能的代码中央.
2.2 CamX 架构中重要的数据结构及关系
缺一张图
Usecase /Session/ Feature /pipeline/ Node
- Chi 对 Camx 的操作,须要通过 ExtensionModule 进行操作,因而,camx 对外提供的接口扩大须要通过 ExtensionModule 进行,外面一个重要的变量就是 g_chiContextOps。
- Camx 对 Chi 的操作,是通过 HAL3Module 接口的 m_ChiAppCallbacks 进行的,因而 chi 外面开释的接口,都会在 m_ChiAppCallbacks 外面体现
- Usecase:基本上与 App 上的各种模式有肯定的对应关系,包含 PreviewZSL,VideoLiveShot, SAT(Multicamera), RTB(Reatime Bokeh),QCFA, Dual, superslowmotionfrc…,一个 usecase 蕴含了 realtime 和 snapshot 的 session,须要蕴含所有的在这个 usecase 的所有 feature 的 pipeline 列表
- Feature: 在 Usecase 下关上某个功能设计的一种架构,通常状况下一个 Usecase 能够启用各种不同的 feature,feture 蕴含了 usecase 外面的局部 pipeline, 个别都是 snapshot 的才会蕴含 feature 进行解决,因而,usecase 与 feautre 的界线并不显著。
- Session:蕴含了 ChxSession,ChiSession 和 CamxSession。Chxsession 是对 chi 接口外面对 CamxSession 的封装,Usecase 外面创立的 Session 都是要创立这一个。ChiSession 是 camx 外面的一个局部,是对 camxSession 的继承和透传。
- pipeline- 蕴含单个通过验证的 topology 的可重用容器。驱动程序通过 pipeline 来理解所应用的引擎以及数据处理的流程。
- Node—camera pipeline 内的逻辑功能块,在单个引擎上执行。node 链接在一起形成一个 topology。在 CHI API 的初始版本中,ISP 内部的所有节点都是通过 CPU 代码调用的,调的是 native API。
不同机型, 产品性能及定位不同, 即便基线一样 usecase 等也有可能不一样, 高通这么做给了手机厂商极大的自定义空间, 举个某机型例子,UseCase 能够场景复用, 对应的 pipeline 也能够不必或复用.
2.3 CamX 操作过程
基本操作, 截图自高通文档:
具体过程:
2.3.1 Open Camera
2.3.2 ConfigureStream
2.3.3 Request & Result
request:
result:
一旦底层有事件上传就会走到 SyncManagerPollMethod 中:file: vendor/qcom/proprietary/camx/src/csl/hw/camxsyncmanager.cpp | |
--> VOID* SyncManager::SyncManagerPollMethod(VOID* pPollData) | |
|--> rc = poll(fds, 2, -1) // 监听的 syncFd 有事件上传 | |
| |--> VOID* pData[] = {pEv, NULL}; // 这里的 pEv 是蕴含回调办法的,依据 setRepeatingRequest 中的剖析,这里的回调就是 Node::CSLFenceCallback | |
| |--> ioctl(pCtrl->syncFd, VIDIOC_DQEVENT, pEv); // 取出事件 | |
| |--> result = pCtrl->pThreadManager->PostJob(pCtrl->hJob, SyncManager::StoppedCbDispatchJob, pData, FALSE, FALSE); // 这里就会调到之前注册的线程并回调 SyncManager::CbDispatchJob 办法 | |
file: vendor/qcom/proprietary/camx/src/csl/hw/camxsyncmanager.cpp | |
| |--> VOID* SyncManager::CbDispatchJob(VOID* pData) | |
| | |--> Utils::Memcpy(&ev, reinterpret_cast<struct v4l2_event*> (pData), sizeof(ev)); | |
| | |--> pPayloadData = CAM_SYNC_GET_PAYLOAD_PTR(ev, uint64_t); | |
| | |--> reinterpret_cast<CSLFenceHandler>(pPayloadData[0]))(reinterpret_cast<VOID* >(pPayloadData[1]), pEvHeader->sync_obj, fenceResult); // 回调 Node::CSLFenceCallback | |
file: vendor/qcom/proprietary/camx/src/core/camxnode.cpp | |
| | |--> VOID Node::CSLFenceCallback(...) | |
| | | |--> result = pNode->GetThreadManager()->PostJob(pNode->GetJobFamilyHandle(), NULL, &pData[0], FALSE, FALSE) // 将工作放到 JobFamilyHandle 线程去做, 回调 Node::NodeThreadJobFamilyCb 办法 | |
| | | | |--> VOID* Node::NodeThreadJobFamilyCb(...) // 因为是另一个线程解决,所以这个以缩进代表异步关系 | |
| | | | | |--> FenceCallbackData* pFenceCallbackData = static_cast<FenceCallbackData*>(pCbData); | |
| | | | | |--> NodeFenceHandlerData* pNodeFenceHandlerData = static_cast<NodeFenceHandlerData*>(pFenceCallbackData->pNodePrivateData); | |
| | | | | |--> pFenceCallbackData->pNode->ProcessFenceCallback(pNodeFenceHandlerData); | |
| | | | | | |--> OutputPort* pOutputPort = pFenceHandlerData->pOutputPort; | |
| | | | | | |--> UINT64 requestId = pFenceHandlerData->requestId; | |
| | | | | | |--> UINT requestIdIndex = requestId % MaxRequestQueueDepth; | |
| | | | | | |--> m_pPipeline->NonSinkPortFenceSignaled(&pFenceHandlerData->hFence, pFenceHandlerData->requestId); // 如果是 no sink port | |
file: vendor/qcom/proprietary/camx/src/core/camxpipeline.cpp | |
| | | | | | |--> VOID Pipeline::NonSinkPortFenceSignaled(...) | |
| | | | | | | |--> m_pDeferredRequestQueue->FenceSignaledCallback(phFence, requestId); | |
file: vendor/qcom/proprietary/camx/src/core/camxdeferredrequestqueue.cpp | |
| | | | | | | |--> VOID DeferredRequestQueue::FenceSignaledCallback(...) | |
| | | | | | | | |--> UpdateDependency(PropertyIDInvalid, phFence, NULL, requestId, 0, TRUE); | |
| | | | | | | | |--> DispatchReadyNodes(); | |
| | | | | | | | | |--> CamxResult result = m_pThreadManager->PostJob(m_hDeferredWorker, NULL, &pData[0], FALSE, FALSE); // 针对所有 ready Nodes 循环解决,m_hDefferredWorker 对应的回调是 DeferredWorkerWrapper | |
| | | | | | | | | | |--> VOID* DeferredRequestQueue::DeferredWorkerWrapper(VOID* pData) // 异步调用, 以缩进示意 | |
| | | | | | | | | | | |--> Dependency* pDependency = reinterpret_cast<Dependency*>(pData); | |
| | | | | | | | | | | |--> DeferredRequestQueue* pDeferredQueue = pDependency->pInstance; | |
| | | | | | | | | | | |--> result = pDeferredQueue->DeferredWorkerCore(pDependency); | |
| | | | | | | | | | | | |--> pNode->ProcessRequest(&processRequest, pDependency->requestId) | |
file: vendor/qcom/proprietary/camx/src/core/camxnode.cpp | |
| | | | | | | | | | | | |--> CamxResult Node::ProcessRequest(NodeProcessRequestData* pNodeRequestData, UINT64 requestId) | |
| | | | | | | | | | | | | |--> result = ExecuteProcessRequest(&executeProcessData); // 这里临时以 ipe node 为例进行剖析 | |
file: vendor/qcom/proprietary/camx/src/hwl/ipe/camxipenode.cpp | |
| | | | | | | | | | | | | |--> CamxResult IPENode::ExecuteProcessRequest(ExecuteProcessRequestData* pExecuteProcessRequestData) | |
| | | | | | | | | | | | | | |--> GetHwContext()->Submit(GetCSLSession(), m_hDevice, pIQPacket); // 发送设置命令 | |
file: vendor/qcom/proprietary/camx/src/core/camxhwcontext.cpp | |
| | | | | | | | | | | | | | |--> CamxResult HwContext::Submit(CSLHandle hCSLSession, CSLDeviceHandle hDevice, Packet* pPacket) | |
| | | | | | | | | | | | | | | |--> result = CSLSubmit(hCSLSession, hDevice, pPacket->GetMemHandle(), pPacket->GetOffset()); | |
file: vendor/qcom/proprietary/camx/src/csl/camxcsl.cpp | |
| | | | | | | | | | | | | | | |--> CamxResult CSLSubmit(...) | |
| | | | | | | | | | | | | | | | |--> return pJumpTable->CSLSubmit(hCSL, hDevice, hPacket, offset); // 跳转办法见 func_list_camx_chi ⑤ , 接下来我就不剖析了 | |
| | | | | | |--> m_pPipeline->SinkPortFenceSignaled(pOutputPort->sinkTargetStreamId, ...) // 如果是 sink port | |
file: vendor/qcom/proprietary/camx/src/core/camxpipeline.cpp | |
| | | | | | |--> VOID Pipeline::SinkPortFenceSignaled(...) | |
| | | | | | | |--> ResultsData resultsData = {}; | |
| | | | | | | |--> resultsData.pPrivData = pPerRequestInfo->request.pPrivData; | |
| | | | | | | |--> resultsData.type = CbType::Buffer; | |
| | | | | | | |--> m_pSession->NotifyResult(&resultsData); | |
file: vendor/qcom/proprietary/camx/src/core/camxsession.cpp | |
| | | | | | | |--> VOID Session::NotifyResult(ResultsData* pResultsData) | |
| | | | | | | | |--> switch (pResultsData->type) | |
| | | | | | | | |--> case CbType::Buffer: | |
| | | | | | | | |--> HandleBufferCb(&pResultsData->cbPayload.buffer, pResultsData->pipelineIndex, pResultsData->pPrivData); | |
| | | | | | | | | |--> InjectResult(ResultType::BufferOK, &outBuffer, pPayload->sequenceId, pPrivData, pipelineIndex); | |
| | | | | | | | | | |--> result = m_pThreadManager->PostJob(m_hJobFamilyHandle, NULL, &pData[0], FALSE, FALSE); // 这里的线程 cb 是 CHISession::ThreadJobCallback, 为什么呢?file: vendor/qcom/proprietary/camx/src/core/chi/camxchisession.cpp | |
| | | | | | | | | | |--> VOID* CHISession::ThreadJobCallback(VOID* pData) | |
| | | | | | | | | | | |--> result = pSession->ThreadJobExecute(); | |
| | | | | | | | | | | | |--> result = ProcessResults(); | |
file: vendor/qcom/proprietary/camx/src/core/camxsession.cpp | |
| | | | | | | | | | | | |--> CamxResult Session::ProcessResults() | |
| | | | | | | | | | | | | |--> LightweightDoublyLinkedListNode* pNode = m_resultHolderList.Head(); | |
| | | | | | | | | | | | | |--> bufferReady = ProcessResultBuffers(pResultHolder, metadataReady, &numResults); // 针对每一个 node 都调用这个办法,感觉这里就是全副 node 解决 buffer 的一个过程,前期须要确认下 | |
| | | | | | | | | | | | | |--> pNode = m_resultHolderList.NextNode(pNode); // 取出下一个 node 进行操作 | |
| | | | | | | | | | | | | |--> DispatchResults(&m_pCaptureResult[0], numResults); // 发送 results | |
| | | | | | | | | | | | | | |--> m_chiCallBacks.ChiProcessCaptureResult(&pCaptureResults[index], m_pPrivateCbData); // 这里的 m_chiCallBacks 的介绍见 func_list_camx_chi ⑦ | |
file: vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxadvancedcamerausecase.h | |
| | | | | | | | | | | | | | |--> static VOID ProcessResultCb(...) | |
| | | | | | | | | | | | | | | |--> static_cast<AdvancedCameraUsecase*>(pCbData->pUsecase)->ProcessResult(pResult, pPrivateCallbackData); | |
file: vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxadvancedcamerausecase.cpp | |
| | | | | | | | | | | | | | | |--> VOID AdvancedCameraUsecase::ProcessResult(...) | |
| | | | | | | | | | | | | | | | |--> pFeature->ProcessResult(pResult, pPrivateCallbackData); // 如果是 AdvancedFeatureEnabled, 这里咱们思考的是预览,所以不是这分支 | |
| | | | | | | | | | | | | | | | |--> CameraUsecaseBase::SessionCbCaptureResult(pResult, pPrivateCallbackData); | |
| | | | | | | | | | | | | | | | | |--> pCameraUsecase->SessionProcessResult(pCaptureResult, pSessionPrivateData); | |
| | | | | | | | | | | | | | | | | | |--> camera3_capture_result_t* pUsecaseResult = GetCaptureResult(resultFrameIndex); | |
| | | | | | | | | | | | | | | | | | |--> ChxUtils::PopulateChiToHALStreamBuffer(&pResult->pOutputBuffers[i], pResultBuffer); | |
| | | | | | | | | | | | | | | | | | |--> ProcessAndReturnFinishedResults(); | |
| | | | | | | | | | | | | | | | | | | |--> Usecase::ReturnFrameworkResult(&result, m_cameraId); | |
file: vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.cpp | |
| | | | | | | | | | | | | | | | | | | |--> VOID Usecase::ReturnFrameworkResult(...) | |
| | | | | | | | | | | | | | | | | | | | |--> ExtensionModule::GetInstance()->ReturnFrameworkResult(pResult, cameraID); | |
file: vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp | |
| | | | | | | | | | | | | | | | | | | | |--> VOID ExtensionModule::ReturnFrameworkResult(const camera3_capture_result_t* pResult, UINT32 cameraID) | |
| | | | | | | | | | | | | | | | | | | | | |--> m_pHALOps->process_capture_result(m_logicalCameraInfo[cameraID].m_pCamera3Device, pResult); // 这里就将 result 给到下面了 |
2.3.4 Flush
三、Qcom Hal3 Camx 重点
上面是具体我的项目上的工作者须要晓得的 camera 相干的点, 具体细节不赘述, 这里记录下, 不便记忆.
3.1 定制化
定制 pipeline 要走那些算法及节点配置在 xml 中, 相似鱼如下门路
vendor/qcom/proprietary/chi-cdk/vendor/topology/qcom/sdm845/sdm845_usecase.xml
源码下可能因为共线有多个, 要看清楚 makefile 中指定的是哪个.
bypass 是高通做的一套框架,目标在于缩小不必要的拷贝。
3.2 性能 perflock
高通的 perflock 调试, 须要把握, 能够通过抓取 systrace 来看 cpu 相干的变动, 也能够通过读取
/sys/devices/system/cpu/ 下的信息来考察 cpu 变动状况.
3.3 常见的 node 及作用
Node | 作用 |
---|---|
BPS | Bayer Processing Segment,Bayer 解决阶段。仅做 snapshot 的噪点升高和 Bayer 解决,不良像素、PDAF、LSC 校对,绿色不均衡校对,彩色级别,通道增益,demosaic,Down scaler,HDR 的合并与记录,Bayer 混合降噪等 |
IFE | Image front-end engine,图像前端引擎。仅做 video/preview 的 Bayer 解决,做些色彩校对,Down scaler,demosaic,统计 3A 数据等 |
IPE | Image-processing engine,图像处理引擎。由 NPS、PPS 两局部组成,次要做些硬件降噪(MFNR、MFSR)、调整大小、噪声解决、色彩解决(色差校对、色度克制)、细节加强(肤色加强) |
JPEG | 打包 jpeg |
STATS | for 3A,ISP 硬件给出的 3A 数据,用于前面的 3A 算法 |
IS : | 图像稳固 (Image Stabilization) |
RDI : | 原始数据转储接口 (Raw Dump Interface) |
RoI AF : | 感兴趣区域 (AF Region of Interest) |
SNoC 零碎: | NoC (System NoC) |
SOF: | start of frame |
ANR: | application not response |
MCC: | mutil camera control |
LPM: | low power manager(低功耗下运行) |
CTS/ITS: | Android Camera Image Test Suite (ITS) is part of Android Compatibility Test Suite (CTS),Android 相机图像测试套件(ITS)是 Android 兼容性测试套件(CTS)的一部分验证程序,包含验证图像内容的测试。从 CTS 7.0_r8 开始,CTS Verifier 通过一体式摄像机 ITS 反对 ITS 测试自动化。持续反对手动测试,以确保涵盖所有 Android 设施尺寸。 |
HAF: | 混合主动变焦 |
CRM: | camera request manager |
Sensor CRA(主光线角): | 从镜头的传感器一侧,能够聚焦到像素上的光线的最大角度被定义为一个参数,称为主光角 (CRA)。对于主光角的一般性定义是:此角度处的像素响应升高为零度角像素响应(此时,此像素是垂直于光线的) 的 80%,https://blog.csdn.net/weixin_…,lens CRA 与 sensor 不配会使 sensor 的 pixel 呈现在光检测区域四周,使 pixel 曝光有余,亮度不够,会使整个画面造成亮度不平均的状况。还有可能造成 chroma shading 或部分色偏。部分色偏比较严重,无奈用算法弥补 |
Sensor HDR: | sensor 在一幅图像里可能同时体现高光和暗影局部内容的能力 |
lens fov: | 视场角, 视场角与焦距的关系:个别状况下,视场角越大,焦距就越短. |
IFE: | Image Front End,Bayer processing for video/preview only,HDR/De-mosic,color correction,scaler,也能够间接输入 Raw 到 RDI |
RDI : | Raw Dump Interface,间接从 IFE 吐出来用于 capture 的 |
STATS: | for 3A,ISP 硬件给出的 3A 数据,用于前面的 3A 算法 |
PDPC: | PhaseDetection Pixel Correction,相位检测像素校对 |
ASD: | Auto scene detection,主动场景检测 |
CSIC: | Camera serial interface decoder, 摄像机串行接口解码器 |
CAMIF: | Ideal Raw 的第一个 dump 点 |
FD: | Face-based, 基于人脸,也就是人脸识别 |
ICA: | 图像校对和调整 是一个硬件单元,次要用于由镜头和静止引起的几何扭曲 |
LENR: | 低 / 中频加强和降噪 |
TMC: | 色调映射管制 |
CSID: | 摄像机串行接口解码器模块 |
IFE: | 图像前端 |
BPS: | Bayer 解决段 |
IPE: | 图像处理引擎 |
VPU: | 视频处理单元 |
DPU: | 显示处理单元 |
BPC: | 坏像素校对 |
BCC: | 坏群集校对 |
ABF: | 自适应拜耳滤波器 |
GIC: | 绿色不均衡校对 |
GTM: | 全局色调映射 |
HNR: | 混合降噪 |
ANR: | 先进的降噪性能 |
TF: | 工夫过滤器 |
MFNR: | 多帧降噪 |
LTM: | 部分色调映射 |
CS: | 色度克制 |
ASF: | 自适应空间滤波器 |
Upscaler: | 升频器 |
GRA: | Grain Adder(纹理减少器?)?? |
CPAS: | 相机外围设备和反对 |
CAMIF: | 摄像头接口???它是 VFE(video front-end)硬件的第一局部,次要工作是同步 sensor 发送数据过程中波及到的行、场同步信号。另外它还具备图像提取和图像镜像能力,CAMIF hardware 使内部 camera sensor 可能通过一些简略的内部协定链接到用户单元。为 camera 提供了数据和时钟接口,但并没有提供管制接口,最具代表行的是用 I2C 做配置和状态接口。当然,也能够是其余的一次管制信号做一些动态管制。例如:睡眠唤醒模式管制。 |
NPS: | 噪声解决局部 |
PPS: | 后处理局部 |
MCTF: | 静止弥补工夫滤波 CAC、CCM、GLUT、2D LUT(二维查找表?)、CV(色彩转换)、CC(色彩校对)、SCE(肤色加强)、MCE(记忆色调加强):??? |
SIMO: | 单输出多输入 |
Pedestal Correction: | 基座校对 |
Down Scaler: | 升高规模(尺寸) |
Chroma Enhancement: | 色度加强 |
Chroma Suppression: | 色度克制 |
PDAF: | 相位检测主动对焦 |
LSC: | 镜头暗影校对 |
PNR: | 峰值降噪 |
ADRC: | 主动动静范畴压缩 |
Backlit scene: | 背光场景 |
Garage scene: | 车库场景 |
HNR: | 升高亮度噪声,但放弃纹理细节 |
LDC: | 镜头畸变校对 |
EIS: | 电子稳像 |
Multi pass spatial noise filtering: | 多通空间噪声滤波 |
LNR: | 镜头降噪 |
Invert gamma: | 反转伽玛 |
hue, saturation, lightness: | 色调,饱和度,亮度 |
Upscaler: | 升频器 |
ACE: | 高级色度加强 |
CPP: | 相机后处理器(相当于新版的 BPS、IPE) |
BSP: | board support package,板级反对安装包?也就是“做出反对安装包,来实现手机上各个硬件的基本功能”。 |
CCT: | correlated color temperature,相干色温,具体不详; |
chi-cdk: | Camera Hardward Interface 相机硬件接口;Camera Development Kit,相机开发包; |
HFR: | High Frame Rate, min HFR=90, means>=90 时,须要 enable HFR 高帧率,目前最高 960,然而是利用插值算法计算得出的,非理论 960 |
3.4 日志材料
Camx 日志由属性管制, 具体也是一套规定, 首先获取权限:adb root && adb remount
, 如果 remount 报错:failed: Read-only file system
, 则执行adb disable-verity && adb reboot
解决,而后从新adb root && adb remount
.
Camera user mode driver (UMD) ——相机用户模式驱动
UMD 的显示格局
CamX: [<Verbosity Level>][<Group>] <File>:<Line Number> <Function Name> <Message>
例如:CamX : INFO camxhal3.cpp:1086 process_capture_request() frame_number 140
这里将 log 分为不同的 level,不同的 level 上面有不同的 group
如何关上指定 level 的指定 group 的 log?其各 level 和 group 见相应的 camxtypes.h
如何关上指定 level? level 间接通过 Name 设定;
group 通过二进制的每一位来确定,每个 group 对应一个 bit, 置 1 示意关上
例如:logVerboseMask=0xFFFFFFFF // 关上所有 group 的 verbose 级别的 log
logWarningMask=0x82 //Warning 级别关上第 1 个位和第 6 位示意的 group,其实是 Sensor 和 HAL 的 group
平时测试开的 log:
如何理论进行关上 log
在手机中的:/vendor/etc/camera/camxoverridesettings.txt
例如:adb shell "echo logInfoMask=0xFFFFFFFF>> /vendor/etc/camera/camxoverridesettings.txt"
chi log:
例如:CHX_LOG_ERROR(fmt, args);
adb shell "echo overrideLogLevels=0x1f >> /vendor/etc/camera/camxoverridesettings.txt" | |
或:adb shell setprop vendor.debug.camera.overrideLogLevels 0x1F (camxsettings.xml 中定义,不同的代码可能有区别) |
平时开的 log:
adb shell "echo logInfoMask=0x50080 >> /vendor/etc/camera/camxoverridesettings.txt" hal/core/chi | |
adb shell setprop persist.vendor.camera.logVerboseMask 0xFFFFFFFF | |
adb shell setprop persist.vendor.camera.logEntryExitMask 0xFFFFFFFF | |
adb shell setprop persist.vendor.camera.logInfoMask 0xFFFFFFFF | |
adb shell setprop persist.vendor.camera.logWarningMask 0xFFFFFFFF | |
adb shell setprop persist.vendor.camera.logConfigMask 0xFFFFFFFF | |
adb shell setprop persist.vendor.camera.systemLogEnable TRUE | |
adb shell setprop persist.vendor.camera.logLogDRQMask 0xFFFFFFFF |
camx log:
adb shell "echo overrideLogLevels=0xF >> /vendor/etc/camera/camxoverridesettings.txt" | |
adb shell "echo logVerboseMask=0x1000 >> /vendor/etc/camera/camxoverridesettings.txt" | |
adb shell "echo logInfoMask=0xFFFFFFFF >> /vendor/etc/camera/camxoverridesettings.txt" |
原文链接:https://blog.csdn.net/TaylorP…
情谊举荐:
Android 干货分享
至此,本篇已完结,如有不对的中央,欢迎您的倡议与斧正。同时期待您的关注,感谢您的浏览,谢谢!