參考資料:極客筆記
以ov7251的cpp介面檔案為例,編譯生成so庫檔案
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2018 Qualcomm Technologies, Inc. // All Rights Reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "camxsensordriverapi.h" // NOWHINE ENTIRE FILE #ifdef __cplusplus extern "C" { #endif // __cplusplus //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // RegisterToRealGain //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static DOUBLE RegisterToRealGain( UINT registerGain) { DOUBLE real_gain; real_gain = (DOUBLE) (((DOUBLE)(registerGain))/16.0); return real_gain; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // RealToRegisterGain //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static UINT RealToRegisterGain( DOUBLE realGain) { UINT reg_gain = 0; realGain = realGain*16.0; reg_gain = (UINT)realGain; return reg_gain; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CalculateDigitalGain //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static UINT CalculateDigitalGain( FLOAT totalRealGain, FLOAT sensorRealGain) { CDK_UNUSED_PARAM(totalRealGain); CDK_UNUSED_PARAM(sensorRealGain); return 1; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FillExposureSettings //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CalculateExposure( // 計算曝光的具體介面 SensorExposureInfo* pExposureInfo, // 輸出 SensorCalculateExposureData* pCalculateExposureData) // 平臺傳進來的 { ... ... pExposureInfo->analogRegisterGain = RealToRegisterGain(pCalculateExposureData->realGain); // 平臺傳進來的realGain轉到暫存器的模擬gain pExposureInfo->analogRealGain = static_cast<FLOAT>(RegisterToRealGain(pExposureInfo->analogRegisterGain)); // 變成register值 pExposureInfo->digitalRegisterGain = CalculateDigitalGain(pCalculateExposureData->realGain, pExposureInfo->analogRealGain); // 平臺傳進來的realGain轉到暫存器數字gain pExposureInfo->digitalRealGain = 1.0; // 係數 pExposureInfo->ISPDigitalGain = pCalculateExposureData->realGain /(pExposureInfo->analogRealGain * pExposureInfo->digitalRealGain); // 還不滿足,就需要ISP數字gain pExposureInfo->lineCount = pCalculateExposureData->lineCount; // 平臺傳入直接賦值 ... ... return TRUE; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FillExposureSettings //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL FillExposureSettings( // 具體實現程式碼邏輯 RegSettingsInfo* pRegSettingsInfo, // 輸出引數 SensorFillExposureData* pExposureData) // 輸入引數 { ... ... for (index = 0; index < pExposureData->pRegInfo->groupHoldOnSettings.regSettingCount; index++) // 配置holdon暫存器 { pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].registerAddr; pRegSettingsInfo->regSetting[regCount].registerData = pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].registerData; pRegSettingsInfo->regSetting[regCount].regAddrType = pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].regAddrType; pRegSettingsInfo->regSetting[regCount].regDataType = pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].regDataType; pRegSettingsInfo->regSetting[regCount].delayUs = pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].delayUs; regCount++; // 多少個暫存器要去寫 } pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->frameLengthLinesAddr; // 曝光相關暫存器VTS pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->frameLengthLines & 0xFF00) >> 8; regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->frameLengthLinesAddr + 1; pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->frameLengthLines & 0xFF); regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->coarseIntgTimeAddr - 1; // line count pRegSettingsInfo->regSetting[regCount].registerData = pExposureData->lineCount >> 12; regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->coarseIntgTimeAddr; pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->lineCount >> 4) & 0xFF; regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->coarseIntgTimeAddr + 1; pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->lineCount << 4) & 0xFF; regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->globalAnalogGainAddr; // gain配置 pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->analogRegisterGain & 0xFF00) >> 8; regCount++; pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->globalAnalogGainAddr+ 1; pRegSettingsInfo->regSetting[regCount].registerData = (pExposureData->analogRegisterGain & 0xFF); regCount++; for (index = 0; index < pExposureData->pRegInfo->groupHoldOffSettings.regSettingCount; index++) // hold off配置 { pRegSettingsInfo->regSetting[regCount].registerAddr = pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].registerAddr; pRegSettingsInfo->regSetting[regCount].registerData = pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].registerData; pRegSettingsInfo->regSetting[regCount].regAddrType = pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].regAddrType; pRegSettingsInfo->regSetting[regCount].regDataType= pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].regDataType; regCount++; } pRegSettingsInfo->regSettingCount = regCount; // 總共的暫存器 if (MAX_REG_SETTINGS <= regCount) { return FALSE; } else { return TRUE; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // GetSensorLibraryAPIs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VOID GetSensorLibraryAPIs( SensorLibraryAPI* pSensorLibraryAPI) { pSensorLibraryAPI->majorVersion = 1; pSensorLibraryAPI->minorVersion = 0; pSensorLibraryAPI->pCalculateExposure = CalculateExposure; // 主要就是實現這兩個介面,計算曝光的關係 pSensorLibraryAPI->pFillExposureSettings = FillExposureSettings; } #ifdef __cplusplus } #endif // __cplusplus // SensorCalculateExposureData結構體,平臺傳入 typedef struct SensorCalculateExposureData { FLOAT realGain; // AE演算法提供過來的,TOTAL gain UNIT lineCount; // 曝光時間轉換成linecount FLOAT middleRealGain; // 針對HDR sensor,普通sensor不用care UINT middleLinecount; FLOAT shortRealGain; UINT shortLinecount; UNIT32 sensorResolutionIndex; // xml中不同的settings,平臺傳入的 } SensorCalculateExposureData; // 輸出函式 typedef struct SensorExposureInfo { FLOAT analogRealGain; // 模擬gain UINT analogRegisterGain; // 模擬gain對應的值 FLOAT digitalRealGain; // sensor數字gain UINT digitalRegisterGain; // sensor數字gain對應暫存器的值 FLOAT shortAnalogRealGain; // HDR sensor才有 UINT shortRegisterGain; FLOAT shortDigitalRealGain; UINT shortDigitalRegisterGain; FLOAT middleAnalogRealGain; UINT middleRegisterGain; FLOAT middleDigitalRealGain; UINT middleDigitalRegisterGain; FLOAT ISPDigitalGain; // ISP數字gain,ISP只有數字gain,沒有不用填 UINT lineCount; // 和傳過來一樣 UNIT shortLinecount; UINT middleLinecount; FLOAT sensitivityCorrectionFactor; // sensor感光度矯正因子,tunning管理 } SensorExposureInfo; struct SensorFillExposureData // 填充曝光資料,輸入引數資料結構 { SensorExposureRegInfo* pRegInfo; // sensor的曝光暫存器資訊 UINT analogRegisterGain; // 模擬Gain暫存器值 UINT digitalRegisterGain; // 數字gain暫存器值 UNIT lineCount; // linecount UNIT frameLengthLines; // VTS UNIT shortRegisterGain; // HDR相關 UNIT shortDigitalRegisterGain; UNIT middleRegisterGain; UNIT middleDigitalRegisterGain; UNIT shortLineCount; UNIT middleLineCount; INT32 additionalInfo[MAX_REG_CONTROL_EXT_DATA_SIZE]; // 擴充的相關 BOOL applyShortExposure; BOOL applyMiddleExposure; FLOAT sensitivityCorrectionFactor; // tunning填寫 UINT32 sensorResolutionIndex; // 娜一組配置 } SensorFillExposureData; struct RegSettingsInfo // 輸出引數 { UINT regSettingCount; // 多少個暫存器 RegSetting regSetting[MAX_REG_SETTINGS]; } RegSettingsInfo;
暫存器的值和實際gain的轉換關係參考:
LineCount = ExposureTime / Tline(行的曝光時間),而是一行要曝光多少的時間 Tline = HTS x 1/ VT_CLK VT_CLK = VTS x HTS x FPS Tline = 1/(VTS x FPS)