• MTK平台闪光灯相关信息


    (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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    (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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (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";
    	};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    //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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如下修改为闪光灯校准: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;
        
        //...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (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)
    
    • 1
    • 2
    • 3

    另可通过如下源码查看调用过程。

    //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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    可通过如上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
    
    • 1
    • 2
    • 3
    • 4

    备注:具体打闪阈值通过效果文件来控制。

    //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,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    【附gpt4.0升级秘笈】百度智能云万源全新一代智能计算操作系统发布:引领AI新纪元
    postgresql
    人大金仓分析型数据库JSON索引
    JAVA毕业设计129—基于Java+Springboot+thymeleaf的物业管理系统(源代码+数据库)
    融云「百幄」之视频会议和直播,让办公桌无限延伸
    关于 HTTPS 和 SSL
    K8s Pod 创建埋点处理(Mutating Admission Webhook)
    无恒实验室联合GORM推出安全好用的ORM框架-GEN
    实验语音学的基本概念
    支持断点续传的 文件下载器 实现方案
  • 原文地址:https://blog.csdn.net/dongxianfei/article/details/131210011