本讲是Android Camera Native Framework专题的第17讲,我们介绍cameraserver进程启动之初始化VendorTags, Flashlight和PerfClass。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
创建VendorTagDescriptorCache
VendorTagDescriptorCache是一个Manager,管理不同Provider里面的Vendor Tag Descriptor,VendorTagDescriptor维护管理所有Vendor Tags的Section、Name、Type,ID之间的关系:
Android 13 代码逻辑:CameraProviderManager::setUpVendorTags()
status_t CameraProviderManager::setUpVendorTags() {
sp tagCache = new VendorTagDescriptorCache();
for (auto& provider : mProviders) {
tagCache->addVendorDescriptor(provider->mProviderTagid, provider->mVendorTagDescriptor);
}
VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
return OK;
}
Flashlight初始化
CameraServer通过CameraFlashlight来管理各CameraDevice的Flashlight,类图如下:
通过CameraFlashlight::findFlashUnits完成Flashlight的初始化,流程如下:
Android 13代码,CameraFlashlight::findFlashUnits:
status_t CameraFlashlight::findFlashUnits() {
Mutex::Autolock l(mLock);
status_t res;
std::vector cameraIds;
std::vector ids = mProviderManager->getCameraDeviceIds();
int numberOfCameras = static_cast(ids.size());
cameraIds.resize(numberOfCameras);
// No module, must be provider
for (size_t i = 0; i < cameraIds.size(); i++) {
cameraIds[i] = String8(ids[i].c_str());
}
mFlashControl.clear();
for (auto &id : cameraIds) {
ssize_t index = mHasFlashlightMap.indexOfKey(id);
if (0 <= index) {
continue;
}
bool hasFlash = false;
res = createFlashlightControl(id);
if (res) {
ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
id.string());
} else {
res = mFlashControl->hasFlashUnit(id, &hasFlash);
if (res == -EUSERS || res == -EBUSY) {
ALOGE("%s: failed to check if camera %s has a flash unit. Some "
"camera devices may be opened", __FUNCTION__,
id.string());
return res;
} else if (res) {
ALOGE("%s: failed to check if camera %s has a flash unit. %s"
" (%d)", __FUNCTION__, id.string(), strerror(-res),
res);
}
mFlashControl.clear();
}
mHasFlashlightMap.add(id, hasFlash);
}
mFlashlightMapInitialized = true;
return OK;
}
为SPerfClass过滤Characteristics
执行条件:
- ro.odm.build.media_performance_class >= 31
执行动作:
- 针对主后置和主前置,过滤掉<1080p的JPEG尺寸
CTS(SPerfClassTest.java):
- testSPerfClassJpegSizesByCamera
流程:
Android 13代码:
void CameraService::filterSPerfClassCharacteristicsLocked() {
// To claim to be S Performance primary cameras, the cameras must be
// backward compatible. So performance class primary camera Ids must be API1
// compatible.
bool firstRearCameraSeen = false, firstFrontCameraSeen = false;
for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) {
int facing = -1;
int orientation = 0;
String8 cameraId8(cameraId.c_str());
getDeviceVersion(cameraId8, /*out*/&facing, /*out*/&orientation);
if (facing == -1) {
ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
return;
}
if ((facing == hardware::CAMERA_FACING_BACK && !firstRearCameraSeen) ||
(facing == hardware::CAMERA_FACING_FRONT && !firstFrontCameraSeen)) {
status_t res = mCameraProviderManager->filterSmallJpegSizes(cameraId);
if (res == OK) {
mPerfClassPrimaryCameraIds.insert(cameraId);
} else {
ALOGE("%s: Failed to filter small JPEG sizes for performance class primary "
"camera %s: %s(%d)", __FUNCTION__, cameraId.c_str(), strerror(-res), res);
break;
}
if (facing == hardware::CAMERA_FACING_BACK) {
firstRearCameraSeen = true;
}
if (facing == hardware::CAMERA_FACING_FRONT) {
firstFrontCameraSeen = true;
}
}
if (firstRearCameraSeen && firstFrontCameraSeen) {
break;
}
}
}