Merge "Camera: use compact copy when necessary" into pi-dev

This commit is contained in:
Yin-Chia Yeh
2018-05-23 18:41:38 +00:00
committed by Android (Google) Code Review
4 changed files with 115 additions and 28 deletions

View File

@@ -306,7 +306,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
return ret;
}
CameraMetadata m;
m = rawInfo.static_camera_characteristics;
m.append(rawInfo.static_camera_characteristics);
deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
cameraInfo = rawInfo;
cameraInfo.static_camera_characteristics = m.release();

View File

@@ -35,6 +35,13 @@ static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
// Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer.
static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
// Metadata sent by HAL will be replaced by a compact copy
// if their (total size >= compact size + METADATA_SHRINK_ABS_THRESHOLD &&
// total_size >= compact size * METADATA_SHRINK_REL_THRESHOLD)
// Heuristically picked by size of one page
static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096;
static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;
HandleImporter CameraDeviceSession::sHandleImporter;
const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
@@ -780,13 +787,11 @@ Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraM
mOverridenRequest.update(
ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
defaultBoost, 1);
const camera_metadata_t *metaBuffer =
mOverridenRequest.getAndLock();
convertToHidl(metaBuffer, outMetadata);
mOverridenRequest.unlock(metaBuffer);
} else {
convertToHidl(rawRequest, outMetadata);
}
const camera_metadata_t *metaBuffer =
mOverridenRequest.getAndLock();
convertToHidl(metaBuffer, outMetadata);
mOverridenRequest.unlock(metaBuffer);
}
}
return status;
@@ -1362,6 +1367,62 @@ status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
return OK;
}
// Static helper method to copy/shrink capture result metadata sent by HAL
void CameraDeviceSession::sShrinkCaptureResult(
camera3_capture_result* dst, const camera3_capture_result* src,
std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
std::vector<const camera_metadata_t*>* physCamMdArray,
bool handlePhysCam) {
*dst = *src;
if (sShouldShrink(src->result)) {
mds->emplace_back(sCreateCompactCopy(src->result));
dst->result = mds->back().getAndLock();
}
if (handlePhysCam) {
// First determine if we need to create new camera_metadata_t* array
bool needShrink = false;
for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
if (sShouldShrink(src->physcam_metadata[i])) {
needShrink = true;
}
}
if (!needShrink) return;
physCamMdArray->reserve(src->num_physcam_metadata);
dst->physcam_metadata = physCamMdArray->data();
for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
if (sShouldShrink(src->physcam_metadata[i])) {
mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
dst->physcam_metadata[i] = mds->back().getAndLock();
} else {
dst->physcam_metadata[i] = src->physcam_metadata[i];
}
}
}
}
bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
size_t compactSize = get_camera_metadata_compact_size(md);
size_t totalSize = get_camera_metadata_size(md);
if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
return true;
}
return false;
}
camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
size_t compactSize = get_camera_metadata_compact_size(src);
void* buffer = calloc(1, compactSize);
if (buffer == nullptr) {
ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
}
return copy_camera_metadata(buffer, compactSize, src);
}
/**
* Static callback forwarding methods from HAL to instance
*/
@@ -1372,7 +1433,13 @@ void CameraDeviceSession::sProcessCaptureResult(
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
CaptureResult result = {};
status_t ret = d->constructCaptureResult(result, hal_result);
camera3_capture_result shadowResult;
bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
std::vector<const camera_metadata_t*> physCamMdArray;
sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
status_t ret = d->constructCaptureResult(result, &shadowResult);
if (ret == OK) {
d->mResultBatcher.processCaptureResult(result);
}

View File

@@ -141,7 +141,7 @@ protected:
};
camera3_device_t* mDevice;
uint32_t mDeviceVersion;
const uint32_t mDeviceVersion;
bool mIsAELockAvailable;
bool mDerivePostRawSensKey;
uint32_t mNumPartialResults;
@@ -329,6 +329,17 @@ protected:
status_t constructCaptureResult(CaptureResult& result,
const camera3_capture_result *hal_result);
// Static helper method to copy/shrink capture result metadata sent by HAL
// Temporarily allocated metadata copy will be hold in mds
static void sShrinkCaptureResult(
camera3_capture_result* dst, const camera3_capture_result* src,
std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
std::vector<const camera_metadata_t*>* physCamMdArray,
bool handlePhysCam);
static bool sShouldShrink(const camera_metadata_t* md);
static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
private:
struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {

View File

@@ -479,31 +479,40 @@ void CameraDeviceSession::sProcessCaptureResult_3_4(
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
CaptureResult result = {};
status_t ret = d->constructCaptureResult(result.v3_2, hal_result);
camera3_capture_result shadowResult;
bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
std::vector<const camera_metadata_t*> physCamMdArray;
sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
status_t ret = d->constructCaptureResult(result.v3_2, &shadowResult);
if (ret != OK) {
return;
}
if (hal_result->num_physcam_metadata > d->mPhysicalCameraIds.size()) {
ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
hal_result->num_physcam_metadata);
return;
}
result.physicalCameraMetadata.resize(hal_result->num_physcam_metadata);
for (uint32_t i = 0; i < hal_result->num_physcam_metadata; i++) {
std::string physicalId = hal_result->physcam_ids[i];
if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
i, hal_result->physcam_ids[i]);
if (handlePhysCam) {
if (shadowResult.num_physcam_metadata > d->mPhysicalCameraIds.size()) {
ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
shadowResult.num_physcam_metadata);
return;
}
V3_2::CameraMetadata physicalMetadata;
V3_2::implementation::convertToHidl(hal_result->physcam_metadata[i], &physicalMetadata);
PhysicalCameraMetadata physicalCameraMetadata = {
.fmqMetadataSize = 0,
.physicalCameraId = physicalId,
.metadata = physicalMetadata };
result.physicalCameraMetadata[i] = physicalCameraMetadata;
result.physicalCameraMetadata.resize(shadowResult.num_physcam_metadata);
for (uint32_t i = 0; i < shadowResult.num_physcam_metadata; i++) {
std::string physicalId = shadowResult.physcam_ids[i];
if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
i, shadowResult.physcam_ids[i]);
return;
}
V3_2::CameraMetadata physicalMetadata;
V3_2::implementation::convertToHidl(
shadowResult.physcam_metadata[i], &physicalMetadata);
PhysicalCameraMetadata physicalCameraMetadata = {
.fmqMetadataSize = 0,
.physicalCameraId = physicalId,
.metadata = physicalMetadata };
result.physicalCameraMetadata[i] = physicalCameraMetadata;
}
}
d->mResultBatcher_3_4.processCaptureResult_3_4(result);
}