(1)概念
- MTK打闪一般分为预闪、主闪两个阶段。相应的执行一次拍照会有预闪、主闪两次开灯。预闪可以用来防红眼(red-eye reduction)。闪光时使环境发生变化,会按新的光线条件(有闪光时)重新测光,来实现更精确;
- 预闪是开灯让AE/AF收敛,其持续的时间取决于AF/AF收敛的速度,Flash本身没有控制预闪时间长短的能力。理论上环境亮度越暗,对应的Sensor Framerate越低,AE/AF收敛的时间就越长(AE收敛完之后,才会做AF收敛)。预闪阶段会提前计算主闪时会使用的参数(AE/AWB/AF/Duty)。
- 主闪是在Capture阶段去开灯,一般flow至少会亮三张Frame,在第三帧P1 Done关灯。主闪Duty, doCap要使用的AE参数、AWB权重、AF lock focus都是在预闪阶段就决定了。所以主闪的持续时间相对比预闪的会短一些,电流强度也会稍微高一点。
这里我们以普通的mt6761为例,可以查看部分代码的设置。
(2)闪光灯Hal逻辑代码
//vendor/mediatek/proprietary/hardware/mtkcam/aaa/source/common/flash_mgr/flash_hal.cpp
int FlashHal::getTorchStatus()
{
logI("getTorchStatus(): torch status(%d).", mTorchStatus);
return mTorchStatus;
}
int FlashHal::setTorchOnOff(MBOOL enable)
{
logI("[CAT][flash] setTorchOnOff(): type:%d enable:%d", mStrobeTypeId, enable);
if (mStrobeTypeId == STROBE_TYPE_FRONT && !cust_isSubFlashSupport())
return 1;
if (enable == 1) {
init();
setInCharge(1);
setOnOff(enable, FLASH_HAL_SCENARIO_TORCH);
mTorchStatus = 1;
} else {
setOnOff(enable, FLASH_HAL_SCENARIO_TORCH);
setInCharge(0);
uninit();
mTorchStatus = 0;
}
return 0;
}
int FlashHal::setVideoTorchOnOff(int enable)
{
logI("setVideoTorchOnOff(): enable(%d).", enable);
setOnOff(enable, FLASH_HAL_SCENARIO_VIDEO_TORCH);
return 0;
}
int FlashHal::setAfLampOnOff(int enable)
{
logI("setAfLampOnOff(): enable(%d).", enable);
setOnOff(enable, FLASH_HAL_SCENARIO_AF_LAMP);
return 0;
}
int FlashHal::setPfOnOff(int enable)
{
logI("setPfOnOff(): enable(%d).", enable);
setOnOff(enable, FLASH_HAL_SCENARIO_PRE_FLASH);
return 0;
}
int FlashHal::setCaptureFlashOnOff(int enable)
{
logI("setCaptureFlashOnOff(): enable(%d).", enable);
setOnOff(enable, FLASH_HAL_SCENARIO_MAIN_FLASH);
return 0;
}
int FlashHal::setTorchDuty(int level)
{
int duty = 0, dutyLt = 0;
logI("setTorchLevel(): level(%d).", level);
mTorchLevel = level;
FlashCustomAdapter::getInstance(mSensorDev)->getTorchDuty(level, &duty, &dutyLt);
mpStrobe->setDuty(duty);
if (mStrobeCtNum > 1) {
mpStrobe2->setDuty(dutyLt);
}
return 0;
}
//setOnOff
int FlashHal::setOnOff(int enable, FLASH_HAL_SCENARIO_ENUM scenario)
{
logI("[CAT][flash] setOnOff(): type:%d enable:%d scenario:%d", mStrobeTypeId, enable, scenario);
/* verify arguments */
if (verifyScenario(scenario)) {
logE("setOnOff(): invalid arguments.");
return -1;
}
if (!isAvailable()) {
logI("setOnOff(): sensorDev(%d) not available.", mSensorDev);
return -1;
}
if (scenario == FLASH_HAL_SCENARIO_MAIN_FLASH) {
//...
} else if (scenario == FLASH_HAL_SCENARIO_VIDEO_TORCH) {
//...
}
if (enable)
return setFlashOn(mFlashHalInfo[scenario]);
else
return setFlashOff();
}
(3)关闭真闪配置
//vendor/mediatek/proprietary/custom/mt6761/hal/camera_3a/flashawb_tuning_custom.cpp
MBOOL
isFlashAWBv2Enabled(MINT32 i4SensorDev)
{
switch (i4SensorDev)
{
case NSIspTuning::ESensorDev_Main: // Main Sensor
return MTRUE;//MFALSE
case NSIspTuning::ESensorDev_MainSecond: // Main Second Sensor
return MTRUE;
case NSIspTuning::ESensorDev_Sub: // Sub Sensor
return MTRUE;
case NSIspTuning::ESensorDev_SubSecond: // Sub Second Sensor
return MTRUE;
default:
return MTRUE;
}
}
(4)默认关闭双闪通道,并进行闪光灯校准
//kernel-4.19/arch/arm64/boot/dts/mediatek/mt6761.dts
flashlight_core: flashlight_core {
compatible = "mediatek,flashlight_core";
};
flashlights_mt6370: flashlights_mt6370 {
compatible = "mediatek,flashlights_mt6370";
decouple = <1>;//默认为0,需要配置为1
channel@1 {
type = <0>;
ct = <0>;
part = <0>;
};
};
flashlights_aw3644: flashlights_aw3644 {
compatible = "mediatek,flashlights_aw3644";
};
//vendor/mediatek/proprietary/custom/mt6761/hal/flashlight/flash_custom.cpp
int cust_isDualFlashSupport(int sensorDev)
{
if(sensorDev == DUAL_CAMERA_MAIN_SENSOR || sensorDev == DUAL_CAMERA_MAIN_2_SENSOR)
return 0;
else
return 0;
return 0;
}
如下修改为闪光灯校准:vendor/mediatek/proprietary/custom/mt6761/hal/flashlight/flash_tuning_custom_cct.cpp
(5)闪光灯亮度相关参数
//vendor/mediatek/proprietary/custom/mt6761/hal/flashlight
//flash_tuning_custom_cct.cpp
//--------------------
//eng level
//index mode
//torch
p->engLevel.torchDuty = 6;//手电筒亮度
//af
p->engLevel.afDuty = 6;//对焦闪光灯亮度
//pf, mf, normal
p->engLevel.pfDuty = 6;//预闪亮度
p->engLevel.mfDutyMax = 27;//主闪亮度范围值
p->engLevel.mfDutyMin = 0;
//...
(6)闪光灯打闪Log分析
(A)main Log查看(3次打闪)
打闪几次可通过如下Log判断。
W TaskMgr : [sendEvent] TaskEvent:TouchAEStart, fgLampflashCond(1)/bCustEnableFlash(1)/bStrobeBVTrigger(1)
W TaskMgr : [sendEvent] TaskEvent:TouchAEStart, fgLampflashCond(1)/bCustEnableFlash(1)/bStrobeBVTrigger(1)
W TaskMgr : [sendEvent] TaskEvent:TouchAEStart, fgLampflashCond(1)/bCustEnableFlash(1)/bStrobeBVTrigger(1)
另可通过如下源码查看调用过程。
//vendor/mediatek/proprietary/hardware/mtkcam/aaa/source/isp_30/ae_mgr/ae_mgr.cpp
MBOOL AeMgr::IsStrobeBVTrigger()
{
MBOOL bStrobeBVTrigger;
MINT32 i4Bv = 0;
if (m_rAEInitInput.rAEPARAM.strAEParasetting.bEV0TriggerStrobe == MTRUE)
{
// The strobe trigger by the EV 0 index
i4Bv = m_BVvalueWOStrobe;
}
else
{
if (m_rAEInitInput.rAEPARAM.pEVValueArray[m_eAEEVcomp])
{
if (m_pIAeAlgo != NULL)
{
i4Bv = m_BVvalueWOStrobe + m_pIAeAlgo->getSenstivityDeltaIndex(1024 * 1024 / m_rAEInitInput.rAEPARAM.pEVValueArray[m_eAEEVcomp]);
}
else
{
i4Bv = m_BVvalueWOStrobe;
AE_LOG("[%s()] The AE algo class is NULL, i4SensorDev:%d line:%d\n", __FUNCTION__, m_eSensorDev, __LINE__);
}
}
}
bStrobeBVTrigger = (i4Bv < m_CurrentCaptureTable.i4StrobeTrigerBV)?MTRUE:MFALSE;
AE_LOG_IF(m_3ALogEnable, "[%s()] i4SensorDev:%d bStrobeBVTrigger:%d BV:%d %d\n", __FUNCTION__, m_eSensorDev, bStrobeBVTrigger, i4Bv, m_CurrentCaptureTable.i4StrobeTrigerBV);
return bStrobeBVTrigger;
}
可通过如上Code中的bStrobeBVTrigger字段来查看当前环境值和打闪阈值。
D ae_mgr : [IsStrobeBVTrigger()] i4SensorDev:1 bStrobeBVTrigger:0 BV:11 -28
D ae_mgr : [IsStrobeBVTrigger()] i4SensorDev:1 bStrobeBVTrigger:0 BV:10 -28
D ae_mgr : [IsStrobeBVTrigger()] i4SensorDev:1 bStrobeBVTrigger:1 BV:-36 -28
D ae_mgr : [IsStrobeBVTrigger()] i4SensorDev:1 bStrobeBVTrigger:0 BV:-2 -28
备注:具体打闪阈值通过效果文件来控制。
//camera_AE_PLineTable_xxxxraw.h
static constexpr strAETable g_AE_PreviewAutoTable =
{
AETABLE_RPEVIEW_AUTO, //eAETableID
147, //u4TotalIndex
-28, //i4StrobeTrigerBV //为当前配置的打闪阈值
102, //i4MaxBV
-44, //i4MinBV, Original:-45
90, //i4EffectiveMaxBV
-30, //i4EffectiveMinBV
LIB3A_AE_ISO_SPEED_AUTO, //ISO
sPreviewPLineTable_60Hz,
sPreviewPLineTable_50Hz,
NULL,
};
(B)kernel Log查看(3次打闪)
//预闪
kernel_log_6__2023_0613_212218:10220: <7>[ 2188.129555] (0)[7550:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:11035: <7>[ 2189.912077] (2)[7550:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
//主闪
kernel_log_6__2023_0613_212218:11260: <7>[ 2190.348990] (0)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:11305: <7>[ 2190.453573] (3)[7512:CAM_P1]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:11463: <7>[ 2190.665271] (1)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:12779: <7>[ 2193.272978] (1)[7639:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:13307: <7>[ 2194.481592] (3)[7639:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:13497: <7>[ 2194.918873] (0)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:13542: <7>[ 2195.016548] (1)[7512:CAM_P1]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:13705: <7>[ 2195.222145] (2)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:15349: <7>[ 2198.889098] (2)[7653:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:15942: <7>[ 2200.201315] (3)[7653:3AEventThd]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:16129: <7>[ 2200.869104] (3)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 1
kernel_log_6__2023_0613_212218:16174: <7>[ 2200.967390] (0)[7512:CAM_P1]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0
kernel_log_6__2023_0613_212218:16347: <7>[ 2201.322911] (1)[7467:3ATHREAD]flashlight: _flashlight_ioctl: FLASH_IOC_SET_ONOFF(0,0,0): 0