(1)加载其他Static Metadata
在 MetadataProvider.cpp 中的 constructStaticMetadata()进行 static metadata 加载。
(A)MetadataProvider::onCreate()
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/MetadataProvider.cpp
status_t
MetadataProvider::
onCreate()
{
status_t status = OK;
//prepare data for TagInfo
IMetadataTagSet mtagInfo;
setTagInfo(mtagInfo);
//create IMetadataConverter
sp<IMetadataConverter> pMetadataConverter = IMetadataConverter::createInstance(mtagInfo);
{
RWLock::AutoWLock _l(mRWLock);
status = (mVersion==0)?
constructStaticMetadata(pMetadataConverter, mpStaticCharacteristics, mpHALMetadata) :
constructStaticMetadata_v1(pMetadataConverter, mpStaticCharacteristics, mpHALMetadata);
if ( CC_UNLIKELY( status!=OK ) ) {
META_LOGE("constructStaticMetadata - status[%s(%d)]", ::strerror(-status), -status);
return status;
}
}
return status;
}
可以看到这里通过constructStaticMetadata()和constructStaticMetadata_v1来加载不同版本的Metadata,这两个函数分别加载metadata。
- constructStaticMetadata = impConstructStaticMetadata(mtkMetadata) + updateData(mtkMetadata)
- constructStaticMetadata_v1 = impConstructStaticMetadata_v1(mtkMetadata) + updateData(mtkMetadata)
这里我们就以constructStaticMetadata为例来简单说明。
(B)constructStaticMetadata::impConstructStaticMetadata(mtkMetadata)
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/constructStaticMetadata.cpp
status_t
MetadataProvider::
impConstructStaticMetadata(
IMetadata &metadata
)
{
size_t count = (sizeof(kStaticMetadataTypeNames)/sizeof(char const*)) ;
std::vector<bool> vMap(count, false);
//(1)加载libmtkcam_metastore.so来加载metadata
std::string libPath = "libmtkcam_metastore.so";
void* handle = ::dlopen(libPath.c_str(), RTLD_GLOBAL);
if (!handle) {
char const* err_str = ::dlerror();
META_LOGW("dlopen library=%s %s", libPath.c_str(), err_str ? err_str : "unknown");
return NAME_NOT_FOUND;
}
//
for (size_t i = 0; NULL != kStaticMetadataTypeNames[i]; i++)
{
char const*const pTypeName = kStaticMetadataTypeNames[i];
status_t status = OK;
//(2)加载DEVICE类型的Metadata
String8 const s8Symbol_Sensor = String8::format("%s_DEVICE_%s_%s", PREFIX_FUNCTION_STATIC_METADATA, pTypeName, mInfo.getSensorDrvName());
status = impConstructStaticMetadata_by_SymbolName(s8Symbol_Sensor, metadata, handle);
if ( OK == status ) {
vMap[i] = true;
continue;
}
//
String8 const s8Symbol_Common = String8::format("%s_DEVICE_%s_%s", PREFIX_FUNCTION_STATIC_METADATA, pTypeName, "COMMON");
status = impConstructStaticMetadata_by_SymbolName(s8Symbol_Common, metadata, handle);
if ( OK == status ) {
vMap[i] = true;
continue;
}
//
META_LOGW_IF(0, "Fail for both %s & %s", s8Symbol_Sensor.string(), s8Symbol_Common.string());
}
//(3)加载PROJECT类型的Metadata
//...
::dlclose(handle);
return OK;
}
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/Android.mk
LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam_metastore.static
LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam_metastore.request
LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam_metastore.session
LOCAL_MODULE := libmtkcam_metastore
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk
(C)constructStaticMetadata::updateData(mtkMetadata)
void
MetadataProvider::
updateData(IMetadata &rMetadata)
{
updateStreamConfiguration(rMetadata);
updateRecommendedStreamConfiguration(rMetadata);
updateAfRegions(rMetadata);
IMetadata::IEntry availReqEntry = rMetadata.entryFor(MTK_REQUEST_AVAILABLE_REQUEST_KEYS);
availReqEntry.push_back(MTK_EIS_FEATURE_EIS_MODE, Type2Type< MINT32 >());
rMetadata.update(availReqEntry.tag(), availReqEntry);
IMetadata::IEntry availReqEntry = rMetadata.entryFor(MTK_REQUEST_AVAILABLE_REQUEST_KEYS);
availReqEntry.push_back(MTK_EIS_FEATURE_PREVIEW_EIS, Type2Type< MINT32 >());
rMetadata.update(availReqEntry.tag(), availReqEntry);
IMetadata::IEntry entry(MTK_REQUEST_AVAILABLE_SESSION_KEYS);
entry.push_back(MTK_STREAMING_FEATURE_HDR10, Type2Type< MINT32 >());
rMetadata.update(entry.tag(), entry);
//...
}
同加载 Sensor 与 3A metadata 一样,这里也会调用到 impConstructStaticMetadata 进行配置文件中的
static metadata 记载,在 updateData(mtkMetadata)中自动生成特定的 meteadata。
备注(这里有一处代码自动添加不同ratio的size),就解释了为什么metadata没有配置相关的size,但是dump出来却有相应的size列表
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/constructStaticMetadata.cpp
const std::vector<MSize> size720 = {
MSize(720,720), // 1:1
MSize(960,720), // 4:3
MSize(1080,720), // 3:2
MSize(1280,720), // 16:9
MSize(1440,720), // 18:9
MSize(1520,720), // 19:9
MSize(1560,720), // 19.5:9
MSize(1600,720), // 20:9
};
IMetadata::IEntry
createDefaultSizeCandidate()
{
IMetadata::IEntry out;
for (const MSize& s : size720) {
out.push_back(HAL_PIXEL_FORMAT_YCbCr_420_888, Type2Type<MINT64>());
out.push_back(s.w, Type2Type<MINT64>());
out.push_back(s.h, Type2Type<MINT64>());
out.push_back(MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, Type2Type<MINT64>());
out.push_back(33333333, Type2Type<MINT64>());
out.push_back(0, Type2Type<MINT64>());
out.push_back(HAL_PIXEL_FORMAT_BLOB, Type2Type<MINT64>());
out.push_back(s.w, Type2Type<MINT64>());
out.push_back(s.h, Type2Type<MINT64>());
out.push_back(MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, Type2Type<MINT64>());
out.push_back(33333333, Type2Type<MINT64>());
out.push_back(33333333, Type2Type<MINT64>());
}
//...
}
如上加载Metadata的顺序同之前是一样的:project > mtxxxx > common,默认加载的是 libmtkcam_metastore.so文件。
(D)Android.mk
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/custom/Android.mk
define my-all-config.metadata-under
$(patsubst ./%,%, \
$(shell if [ -d $(1) ] ; then find $(1) -maxdepth 4 \( -name 'config_static_metadata_*.h' \) -and -not -name '.*' ; fi) \
)
endef
LOCAL_MODULE := libmtkcam_metastore.static.custom
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
libmtkcam_metastore.so加载了libmtkcam_metastore.static.custom,默认会加载"config_static_metadata_
*.h"类型的文件。
- config_static_metadata_feature.h
- config_static_metadata_project.h
- config_static_metadata_request_commonType.h
- config_static_metadata_scaler.h
(2)加载RequestTemplate
当 APK 调用 CameraDevice.createCaptureRequest(eg:CameraDevice.TEMPLATE_PREVIEW),会触发
RequestTemplate 的加载过程,通过 HIDL 接口会调用到 CameraDevice3SessionImpl.cpp 中的constructDefaultRequestSettings()方法并创建 TemplateRequest 实例。
(A)CameraDevice3SessionImpl::constructDefaultRequestSettings()
//vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp
auto
ThisNamespace::
constructDefaultRequestSettings(
RequestTemplate type
) -> const camera_metadata_t*
{
String8 const stateTag(String8::format("-> constructDefaultRequestSettings (type:%#x)", type));
mStateLog.add(stateTag + " +");
MY_LOGD_IF(1, "%s", stateTag.c_str());
ITemplateRequest* obj = NSTemplateRequestManager::valueFor(getInstanceId());
if (obj == nullptr) {
//调用 ITemplateRequest::getInstance来创建对象
obj = ITemplateRequest::getInstance(getInstanceId());
NSTemplateRequestManager::add(getInstanceId(), obj);
}
mStateLog.add(stateTag + " -");
return obj->getData(static_cast<int>(type));
}
(B)TemplateRequest::getInstance()
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/TemplateRequest.cpp
ITemplateRequest*
ITemplateRequest::
getInstance(int iOpenId)
{
TemplateRequest* p = new TemplateRequest();
if(p != NULL) {
p->onCreate(iOpenId);
}
return p;
}
在ITemplateRequest的getIstatnce()方法中会进行TemplateRequest.onCreate()的创建动作,紧着调用constructRequestMetedata()加载TemplateRequest。
还是与之前一样,constructRequestMetedata()中调用impConstructRequestMetadata()加载的是配置文件中的TemplateRequest信息,updateData()是自动生成的TemplateRequest信息。
(C)TemplateRequest::constructRequestMetadata()
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/TemplateRequest.cpp
status_t
TemplateRequest::
constructRequestMetadata(
int const requestType,
camera_metadata*& rpMetadata,
IMetadata& rMtkMetadata
)
{
META_LOGD("constructRequestMetadata");
status_t status = OK;
//(1)内部通过impConstructRequestMetadata_by_SymbolName函数来加载配置文件的TempalteRequest信息
if ( OK != (status = impConstructRequestMetadata(rMtkMetadata, requestType)) ) {
META_LOGE("Unable evaluate the size for camera static info - status[%s(%d)]\n", ::strerror(-status), -status);
return status;
}
//...
//(2)自动生成的TempalteRequest信息
updateData(requestType, rMtkMetadata);
return status;
}
(D)TemplateRequest::impConstructRequestMetadata()
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/TemplateRequest.cpp
status_t
TemplateRequest::
impConstructRequestMetadata(
IMetadata& metadata,
int const requestType
)
{
int32_t result = 0;
std::string libPath = "libmtkcam_metastore.so";
void* handle = ::dlopen(libPath.c_str(), RTLD_GLOBAL);
if (!handle) {
char const* err_str = ::dlerror();
META_LOGW("dlopen library=%s %s", libPath.c_str(), err_str ? err_str : "unknown");
return NAME_NOT_FOUND;
}
//加载相关的Metadata文件
String8 const s8Symbol_Sensor = String8::format("%s_DEVICE_%s", PREFIX_FUNCTION_REQUEST_METADATA, mInfo.getSensorDrvName());
status = impConstructRequestMetadata_by_SymbolName(s8Symbol_Sensor, metadata, requestType, handle);
if ( OK == status ) {
goto lbDevice;
}
//...
return OK;
}
RequestTemplate 类型:
- CAMERA3_TEMPLATE_PREVIEW
- CAMERA3_TEMPLATE_STILL_CAPTURE
- CAMERA3_TEMPLATE_VIDEO_RECORD
- CAMERA3_TEMPLATE_VIDEO_SNAPSHOT
- CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG
impConstructRequestMetadata加载的是默认搜索路径的so,这里加载的是libmtkcam_metastore.so,这个动态库会加载libmtkcam_metastore.request.custom。
它会从metadata配置文件夹中加载名为"config_request_metadata_*.h"类型的文件。
- config_request_metadata__.h
(E)Android.mk
//vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/custom/Android.mk
define my-all-config.request-under
$(patsubst ./%,%, \
$(shell if [ -d $(1) ] ; then find $(1) -maxdepth 4 \( -name 'config_request_metadata_*.h' \) -and -not -name '.*' ; fi) \
)
endef
LOCAL_MODULE := libmtkcam_metastore.request.custom
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
(3)Android P部分Metadata文件的作用
- config_request_metadata__.h:该文件配置的是 RequestTemplate 的 meta 信息,必须以 REQUEST_METADATA_BEGIN 开始;
- config_static_metadata.lens.xxx_mipiraw.h:该文件配置的是 LENS 相关的 meta 信息,以 STATIC_METADATA2_BEGIN 开始,类型配置为LENS;
- config_static_metadata.project.camera.xxx_mipiraw.h:该文件配置的是 CAMERA PROJECT 相关的信息,如MTK_SENSOR_INFO_ORIENTATION,以STATIC_METADATA_BEGIN 开始,配置为 CAMERA 类型;
- config_static_metadata.project.flashlight.xxx_mipiraw.h:该文件配置的是 FLASHLIGHT 相关的信息,以STATIC_METADATA2_BEGIN 开始,配置为 FLASHLIGHT 类型;
- config_static_metadata.sensor.xxx_mipiraw.h:该文件配置的是SENSOR 属性相关的信息,如MTK_SENSOR_INFO_EXPOSURE_TIME_RANGE,以 STATIC_METADATA2_BEGIN 开始,配置为 SENSOR 类型;
- config_static_metadata.tuning_3a.xxx_mipiraw.h:该文件配置的是 tuning 属性相关的信息,如MTK_CONTROL_AE_AVAILABLE_MODES、MTK_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES 等,以STATIC_METADATA2_BEGIN 开始,配置为TUNING_3A类型。
- config_static_metadata_feature.h:该文件配置的是客制化 Feaure 属性相关的信息,如MTK_CSHOT_FEATURE_AVAILABLE_MODES等,为FEATURE类型。
- config_static_metadata_request_commonType.h:该文件主要配置的是相关的 request keys、result keys、charateristics keys、session keys,以STATIC_METADATA2_BEGIN 开始,配置为 REQUEST 类型。
- config_static_metadata_scaler.h:该文件主要配置的是 stream size 相关的信息,比如可以支持的预览 size、拍照 size 等。以STATIC_METADATA2_BEGIN 开始,配置为 SCALER 类型。
对Metadata进行配置,推荐配置在 CUSTOM$(PLARFORM)\hal\imgsensor_metadata\imxxxx_mipi_raw
中。