高通 Camx 架構了解下(二)
和你一起終身學習,這里是程序員Android
經典好文推薦,通過閱讀本文,您將收獲以下知識點:
一、Android Hal3回顧
二、Qcom Hal3 CamX架構
三、Qcom Hal3 Camx 重點
一、 Android Hal3回顧
Camera HAL3學習


HAL層操作簡單總結:
Framework層發(fā)送捕獲數據的異步請求。
HAL層設備必須按照次序處理請求。對于每個請求,HAL層需要輸出元數據和一個或者多個圖像數據。
對于請求和結果都需要遵循先進先出的原則;這個數據流將被后續(xù)的請求所參考。
對于同一個請求,所有輸出數據的時間戳必須相同,以便framework層同步輸出數據,如果需要的話。
在請求和結果數據總,所有捕獲數據的配置和狀態(tài)(除了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,手機廠商對該層代碼有自己的改動,可能差別還是有的,具體項目大體框架一致但細節(jié)有區(qū)別,差異和機型的高通基線也保持一致.
2.1 CamX架構總體結構
簡單總結下:

在這里插入圖片描述
Camx的架構入口為Camx包中的camxhal3entry.cpp,Camx中是高通平臺Camx架構的核心跳轉及處理業(yè)務的代碼,一般手機廠商不會去更改,代碼目錄在vendor/qcom/proprietary/camx/下,編譯結果是camera.qcom.so
Camx通過chxentensionInterface調用到chi-cdk 包下的代碼,這里面一般是手機廠商自己定制功能的地方,代碼目錄在vendor/qcom/proprietary/chi-cdk/,編譯結果是com.qti.chi.override.so
從這張圖中大概知道一個request來業(yè)務流程交給camx處理,但會經過chi-cdk進行request定制化重新打包再交給camx實際去執(zhí)行或和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里面創(chuàng)建的Session都是要創(chuàng)建這一個。ChiSession是camx里面的一個部分,是對camxSession的繼承和透傳。
pipeline-包含單個經過驗證的topology的可重用容器。驅動程序通過pipeline來了解所使用的引擎以及數據處理的流程。
Node—camera pipeline 內的邏輯功能塊,在單個引擎上執(zhí)行。node鏈接在一起構成一個topology。在CHI API的初始版本中,ISP外部的所有節(jié)點都是通過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) //監(jiān)聽的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 循環(huán)處理,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); //發(fā)送設置命令
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); //發(fā)送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相關的點,具體細節(jié)不贅述,這里記錄下,方便記憶.
3.1 定制化
定制pipeline要走那些算法及節(jié)點配置在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,統(tǒng)計3A數據等 |
| IPE | Image-processing engine,圖像處理引擎。由NPS、PPS兩部分組成,主要做些硬件降噪(MFNR、MFSR)、調整大小、噪聲處理、顏色處理(色差校正、色度抑制)、細節(jié)增強(膚色增強) |
| JPEG | 打包jpeg |
| STATS | for 3A,ISP硬件給出的3A數據,用于后面的3A算法 |
| IS : | 圖像穩(wěn)定 (Image Stabilization) |
| RDI : | 原始數據轉儲接口 (Raw Dump Interface) |
| RoI AF : | 感興趣區(qū)域 (AF Region of Interest) |
| SNoC 系統(tǒng): | 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測試自動化。繼續(xù)支持手動測試,以確保涵蓋所有Android設備尺寸。 |
| HAF: | 混合自動變焦 |
| CRM: | camera request manager |
| Sensor CRA(主光線角): | 從鏡頭的傳感器一側,可以聚焦到像素上的光線的最大角度被定義為一個參數,稱為主光角(CRA)。對于主光角的一般性定義是:此角度處的像素響應降低為零度角像素響應(此時,此像素是垂直于光線的)的80%,https://blog.csdn.net/weixin_39839293/article/details/82118991,lens CRA與sensor 不配會使sensor 的pixel 出現在光檢測區(qū)域周圍,使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發(fā)送數據過程中涉及到的行、場同步信號。另外它還具有圖像提取和圖像鏡像能力,CAMIF hardware使外部camera sensor能夠通過一些簡單的外部協(xié)議鏈接到用戶單元。為camera提供了數據和時鐘接口,但并沒有提供控制接口,最具代表行的是用I2C做配置和狀態(tài)接口。當然,也可以是其他的一次控制信號做一些靜態(tài)控制。例如:睡眠喚醒模式控制。 |
| NPS: | 噪聲處理部分 |
| PPS: | 后處理部分 |
| MCTF: | 運動補償時間濾波 CAC、CCM、GLUT、2D LUT(二維查找表?)、CV(顏色轉換)、CC(顏色校正)、SCE(膚色增強)、MCE(記憶色彩增強):??? |
| SIMO: | 單輸入多輸出 |
| Pedestal Correction: | 基座校正 |
| Down Scaler: | 降低規(guī)模(尺寸) |
| Chroma Enhancement: | 色度增強 |
| Chroma Suppression: | 色度抑制 |
| PDAF: | 相位檢測自動對焦 |
| LSC: | 鏡頭陰影校正 |
| PNR: | 峰值降噪 |
| ADRC: | 自動動態(tài)范圍壓縮 |
| Backlit scene: | 背光場景 |
| Garage scene: | 車庫場景 |
| HNR: | 降低亮度噪聲,但保持紋理細節(jié) |
| LDC: | 鏡頭畸變校正 |
| EIS: | 電子穩(wěn)像 |
| 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,相機開發(fā)包; |
| HFR: | High Frame Rate, min HFR=90, means>=90時,需要enable HFR高幀率,目前最高960,但是是利用插值算法計算得出的,非實際960 |
3.4 日志資料
Camx日志由屬性控制,具體也是一套規(guī)則,首先獲取權限:adb root && adb remount,如果remount報錯:failed: Read-only file system,則執(zhí)行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][HAL ] 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中定義,不同的代碼可能有區(qū)別)
平常開的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/TaylorPotter/article/details/105630341
相關文章友情推薦?
1. Android開發(fā)干貨分享
至此,本篇已結束。轉載網絡的文章,小編覺得很優(yōu)秀,如有侵權,懇請聯系小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!
點個在看,方便您使用時快速查看!
