Seneor曝光基础知识

相关变量介绍

frame_rate:1s时间内sensor可以出几帧 (30fps,代表sensor 1s可以吐30帧数据)

line_length_pclk:active width + blanking width (sensor的宽度与水平消隐的和)

frame_length_lines: active height + blanking height (sensor的高度与垂直消隐的和)

vt_pixel_clk:单位时间内采样pixel的数量,单位是Hz。控制像素输出的时钟,即pixel采样时钟

公式及推导

vt_pixel_clk = line_length_pclk * frame_length_lines * frame rate (我感觉把这个公式记下来就可以了,后续帧率这些都可以推导出来)

exposure_time=linecount * line_length_pclk / vt_pixel_clk

1/vt_pixel_clk :这是填充一个像素点需要的时间

line_length_pclk * 1/vt_pixel_clk : 填充一行需要的时间

linecount * line_length_pclk * 1/vt_pixel_clk : 填充linecount需要的时间就是曝光时间

这个图片可以简单的参考一下一帧数据都是由什么组成的

遇到的问题

我遇到过在专业模式下手动设置曝光时间,但是倒计时还没有到时间图片就返回了。

正常情况下底层是要hold到设定那么多时间之后在返回APP的。所以说肯定是底层的曝光参数出现了问题

(

在sensor打印log方法:

)

因为曝光的时间越久,sensor的帧率越低,到一定时间之后是需要更换sensor的setting的,所以对应的sensor mode是需要进行更换的。区分的话可以跟APP的同事进行联调,设置一些meta之类的都可以。每组setting不一样对应的支持的最大曝光时间也不一样,然后就是hal和kernel需要设置对应的timeout,不然会进入recovery模式等

最大曝光时间

这几天测cts的时候遇到一个android.hardware.camera2.cts.CaptureRequestTest#testAeModeAndLock fail的问题,这个测试项是根据HAL上报的exposurerangetime的范围分成几份来测试。然后简单追了一下最大曝光时间的来源。

路径:camx/src/core/chi/camxchicontext.cpp

CamxResult ChiContext::InitializeStaticMetadataPool(
UINT32  cameraId)
{
	for (UINT key = 0; key < numCharacteristicsKeys; key++)
	{
		switch (pCameraInfo->pPlatformCaps->characteristicsKeys[key])
		{
            case SensorInfoExposureTimeRange:
            {
                if ((InfoSupportedHardwareLevelFull == (pCameraInfo->pPlatformCaps->supportedHwLevel)) ||
                    (InfoSupportedHardwareLevel3 == (pCameraInfo->pPlatformCaps->supportedHwLevel)))
                {
                    // For FULL capability devices (android.info.supportedHardwareLevel == FULL),
                    // the maximum of the range SHOULD be at least 1 second (1e9), MUST be at least 100ms.
                    CAMX_ASSERT(pCameraInfo->pSensorCaps->maxExposureTime >= 100000000);
                }

                RangeINT64 timeRange;

                timeRange.min = pCameraInfo->pSensorCaps->minExposureTime;
                timeRange.max = pCameraInfo->pSensorCaps->maxExposureTime;
				//设置meta,传递给上层
                result = pStaticMetadataSlot->SetMetadataByTag(SensorInfoExposureTimeRange,
                                                               static_cast<VOID*>(&timeRange),
                                                               sizeof(RangeINT64) / sizeof(INT64),
                                                               "camxContext");
                break;

            }
		}
    }
}


路径:src/utils/camxdefs.h

const UINT64 NanoSecondsPerSecond = 1000000000ULL;

路径:camx/src/core/camximagesensordata.cpp

CamxResult ImageSensorData::GetSensorStaticCapability(
SensorModuleStaticCaps* pCapability,
UINT32                  cameraID)
{
	for (UINT resolutionIndex = 0; resolutionIndex < pResolutionInfo->resolutionDataCount; resolutionIndex++)
	{
		pCapability->maxExposureTime = ULLONG_MAX;
		lineTime = Utils::RoundDOUBLE(((static_cast<DOUBLE>(GetLineLengthPixelClk(resolutionIndex,
										SensorSeamlessType::None)) * NanoSecondsPerSecond) /
										static_cast<DOUBLE>(GetVTPixelClk(resolutionIndex))));
		maxValue = lineTime * m_pSensorData->exposureControlInfo.maxLineCount;
		pCapability->maxExposureTime = Utils::MinUINT64(maxValue, pCapability->maxExposureTime);
		}
}

UINT16 ImageSensorData::GetLineLengthPixelClk(
	UINT                resolutionIndex,
	SensorSeamlessType  inputSeamlessType
	) const
{
	UINT16 returnValue       = 0;
	ResolutionData* pResData = &GetResolutionInfo()->resolutionData[resolutionIndex]; 
	if (SensorSeamlessType::None == inputSeamlessType)
	{
		returnValue = static_cast<UINT16>(pResData->lineLengthPixelClock); 
	}
	else if (SensorSeamlessType::SeamlessInSensorHDR3Exp == inputSeamlessType)
	{
		returnValue = static_cast<UINT16>(pResData->HDR3ExposureInfo.InSensorHDR3ExpLineLengthPixelClock);
	}
	return returnValue; 
}

UINT64 ImageSensorData::GetVTPixelClk(
	UINT resolutionIndex
	) const
{
	ResolutionData* pResData   = &GetResolutionInfo()->resolutionData[resolutionIndex];

	return static_cast<UINT64>(pResData->lineLengthPixelClock * pResData->frameLengthLines * pResData->frameRate);
}

最大曝光的结果就是从上面的函数一点点计算出来的。我只把涉及到的代码给贴出来了。

从ImageSensorData::GetSensorStaticCapability这个函数中在根据sensor的xml中resolution的个数不停的计算选一个小的值。下面把对应的计算方法推导一下

pCapability->maxExposureTime = Utils::MinUINT64(maxValue, pCapability->maxExposureTime);

这步是根据当前计算的值个上一个res的参数计算出来的值选出一个最小的值当maxExposureTime

maxValue = lineTime * m_pSensorData->exposureControlInfo.maxLineCount

根据这个公式说明影响maxExposureTime有两个参数1.lineTime  2.maxLineCount 这两个参数都是正相关的,说明这两个变量的数值越大,maxExposureTime的值就会越大。maxLineCount 这个变量是可以在sensor的xml配置中找到的,说明修改这个值是可以控制maxExposureTime这个数值的大小的。

接下来就是要分析lineTime这个数值是怎么来的,我们通过控制什么可以改变maxExposureTime的数值。

lineTime =(static_cast<DOUBLE>(GetLineLengthPixelClk(resolutionIndex,SensorSeamlessType::None)) * NanoSecondsPerSecond) / static_cast<DOUBLE>(GetVTPixelClk(resolutionIndex))

这是一个除法LineLengthPixelClk VTPixelClk 这两个值的计算需要知道怎么来的

根据GetLineLengthPixelClk

LineLengthPixelClk = lineLengthPixelClock

根据GetVTPixelClk

VTPixelClk=lineLengthPixelClock*frameLengthLines*frameRate

根据上面的推到可以整合成一个公式

maxExposureTime = (lineLengthPixelClock * NanoSecondsPerSecond * maxLineCount)/ 

lineLengthPixelClock*frameLengthLines*frameRate

可以看出lineLengthPixelClock对曝光不会有影响,NanoSecondsPerSecond 是一个定值

所以我们可以理解为

maxExposureTime = maxLineCount / frameLengthLines*frameRate

这三个变量都是在sensor的配置中有体现,所以我们只需要在xml中对maxLineCount、frameLengthLines、frameRate  只需要改变这三个值就可以控制最大曝光时间了。

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值