Android 平台上使用照相机拍照时,一般都会将当前的拍照参数写入到照片详细信息当中去:
主要有写如下信息:
那么这些信息是在哪里产生的呢,又是怎么写到照片详细信息中去的呢?
其中文件名,时间,路径等信息都是通过上层 APP 直接生成并且写入到详细信息的。而其它的信息则和驱动相关,包括照片宽度,高度,照片大小,光圈,焦距,曝光时间,ISO等参数。
一般摄像头不同,相关的参数就会有差别,摄像头的一些参数信息是直接写在摄像头的驱动信息当中的。我们通过更改驱动信息中的参数就可以最终改变写入到照片详细信息中的各项参数。
拍照的时候上层会通过 Feature Control这个接口来调用 GetExifInfo 的函数,此时 query 到的信息会写进去。具体如下所示:
在驱动中有如下代码:
UINT32 HI255BMIPIFeatureControl(MSDK_SENSOR_FEATURE_ENUM FeatureId,
UINT8 *pFeaturePara,UINT32 *pFeatureParaLen)
{
UINT16 u2Temp = 0;
UINT16 *pFeatureReturnPara16=(UINT16 *) pFeaturePara;
UINT16 *pFeatureData16=(UINT16 *) pFeaturePara;
UINT32 *pFeatureReturnPara32=(UINT32 *) pFeaturePara;
UINT32 *pFeatureData32=(UINT32 *) pFeaturePara;
PNVRAM_SENSOR_DATA_STRUCT pSensorDefaultData=(PNVRAM_SENSOR_DATA_STRUCT) pFeaturePara;
MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData=(MSDK_SENSOR_CONFIG_STRUCT *) pFeaturePara;
MSDK_SENSOR_REG_INFO_STRUCT *pSensorRegData=(MSDK_SENSOR_REG_INFO_STRUCT *) pFeaturePara;
MSDK_SENSOR_GROUP_INFO_STRUCT *pSensorGroupInfo=(MSDK_SENSOR_GROUP_INFO_STRUCT *) pFeaturePara;
MSDK_SENSOR_ITEM_INFO_STRUCT *pSensorItemInfo=(MSDK_SENSOR_ITEM_INFO_STRUCT *) pFeaturePara;
MSDK_SENSOR_ENG_INFO_STRUCT *pSensorEngInfo=(MSDK_SENSOR_ENG_INFO_STRUCT *) pFeaturePara;
switch (FeatureId)
{ ……
case SENSOR_FEATURE_GET_RESOLUTION:
*pFeatureReturnPara16++=HI255B_FULL_GRAB_WIDTH;
*pFeatureReturnPara16=HI255B_FULL_GRAB_HEIGHT;
*pFeatureParaLen=4;
break;
case SENSOR_FEATURE_GET_EXIF_INFO:
HI255BMIPIGetExifInfo(*pFeatureData32);
break;
default:
break;
}
return ERROR_NONE;
} /* HI255BMIPIFeatureControl() */
void HI255BMIPIGetExifInfo(UINT32 exifAddr)
{
SENSOR_EXIF_INFO_STRUCT * pExifInfo = (SENSOR_EXIF_INFO_STRUCT*)exifAddr;
pExifInfo->FNumber = 24;
pExifInfo->CapExposureTime = HI255BMIPI_sensor.capExposureTime;
pExifInfo->RealISOValue = HI255BMIPI_sensor.isoSpeed;
}
路径:ALPS.JB3.TDD.MP.V2_xxx\mediatek\custom\common\kernel\imgsensor\xxx_mipi_yuv\xxxxyuv_Sensor.c
1,FNumber 按照实际的光圈值填写即可;
2,拍照的曝光时间在 Capture 函数里面获取,单位为us(微秒),然后赋给全局变量;
3,ISO 值是指当菜单上的 ISO value 为 Auto 的时候,由驱动通过 ISP 来进行计算得到一个当前的 ISO 值。一般是从 capture 函数里面读当前的 Gain 值, 不同的Gain 值范围对应不同的 ISO 值,这里返回给上层的是 AE_ISO_100, AE_ISO_200 这样的值,与 shutter 一样,不同的sensor 可能判断条件和范围不一样的。
另外,在HAL层 \ALPS.JB3.TDD.MP.V2_TD_XXX\mediatek\platform\mt6572\hardware\camera\core\featureio\pipe\aaa\aaa_hal_yuv.cpp 文件中会去读取摄像头驱动中所摄的参数,如下函数所示:
MBOOL Hal3AYuv::set3AEXIFInfo(IBaseCamExif *pIBaseCamExif) const
{
MY_LOG("[%s()] \n", __FUNCTION__);
SENSOR_EXIF_INFO_STRUCT mSensorInfo;
EXIF_INFO_T rEXIFInfo;
memset(&rEXIFInfo, 0, sizeof(EXIF_INFO_T));
memset(&mSensorInfo, 0, sizeof(SENSOR_EXIF_INFO_STRUCT));
m_pSensorHal->sendCommand(static_cast(m_i4SensorDev),SENSOR_CMD_GET_YUV_EXIF_INFO,(int)&mSensorInfo,0,0);
MY_LOG("FNumber=%d, AEISOSpeed=%d, AWBMode=%d, CapExposureTime=%d, FlashLightTimeus=%d, RealISOValue=%d\n",
mSensorInfo.FNumber, m_rParam.u4IsoSpeedMode, m_rParam.u4AwbMode,
mSensorInfo.CapExposureTime, m_bExifFlashOn, mSensorInfo.RealISOValue);
rEXIFInfo.u4FNumber = 24;//mSensorInfo.FNumber>0 ? mSensorInfo.FNumber : 28;
rEXIFInfo.u4FocalLength = 319;
rEXIFInfo.u4SceneMode = m_rParam.u4SceneMode;
rEXIFInfo.u4AWBMode = m_rParam.u4AwbMode;
rEXIFInfo.u4CapExposureTime = mSensorInfo.CapExposureTime>0? mSensorInfo.CapExposureTime : 0;
rEXIFInfo.u4FlashLightTimeus = m_bExifFlashOn; //mSensorInfo.FlashLightTimeus>0? mSensorInfo.FlashLightTimeus : 0;
rEXIFInfo.u4AEISOSpeed = m_rParam.u4IsoSpeedMode;
rEXIFInfo.i4AEExpBias = 0;
pIBaseCamExif->set3AEXIFInfo(&rEXIFInfo);
return MTRUE;
}