diff options
author | Igor Murashkin <iam@google.com> | 2012-09-28 15:30:03 -0700 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2012-10-05 13:32:07 -0700 |
commit | 7373cbe85e617345f7002256a4be389fe62af913 (patch) | |
tree | ecc7614df98deb08d8e39e064be47cec63186a1f /services/camera | |
parent | af3d28870f7890370d6acb21d20cf1ccab4b9e08 (diff) | |
download | frameworks_av-7373cbe85e617345f7002256a4be389fe62af913.zip frameworks_av-7373cbe85e617345f7002256a4be389fe62af913.tar.gz frameworks_av-7373cbe85e617345f7002256a4be389fe62af913.tar.bz2 |
Camera2: Fix metering regions to take into account the current zoom/crop region
Also adds a quirk to disable this fix to work around for incompliant HALs
Bug: 7246065
Change-Id: I80bad25e56ba59149270238e5639bb33cae495ae
Diffstat (limited to 'services/camera')
-rw-r--r-- | services/camera/libcameraservice/Camera2Client.cpp | 4 | ||||
-rw-r--r-- | services/camera/libcameraservice/camera2/Parameters.cpp | 131 | ||||
-rw-r--r-- | services/camera/libcameraservice/camera2/Parameters.h | 25 |
3 files changed, 150 insertions, 10 deletions
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index ed4567e..90cba46 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -334,6 +334,10 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { result.appendFormat(" useZslFormat\n"); haveQuirk = true; } + if (p.quirks.meteringCropRegion) { + result.appendFormat(" meteringCropRegion\n"); + haveQuirk = true; + } if (!haveQuirk) { result.appendFormat(" none\n"); } diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp index dd2cacd..1b15a1c 100644 --- a/services/camera/libcameraservice/camera2/Parameters.cpp +++ b/services/camera/libcameraservice/camera2/Parameters.cpp @@ -929,6 +929,11 @@ status_t Parameters::buildQuirks() { ALOGV_IF(quirks.useZslFormat, "Camera %d: Quirk useZslFormat enabled", cameraId); + entry = info->find(ANDROID_QUIRKS_METERING_CROP_REGION); + quirks.meteringCropRegion = (entry.count != 0 && entry.data.u8[0] == 1); + ALOGV_IF(quirks.meteringCropRegion, "Camera %d: Quirk meteringCropRegion" + " enabled", cameraId); + return OK; } @@ -1726,7 +1731,12 @@ status_t Parameters::updateRequest(CameraMetadata *request) const { if (res != OK) return res; delete[] reqMeteringAreas; - CropRegion crop = calculateCropRegion(); + /* don't include jpeg thumbnail size - it's valid for + it to be set to (0,0), meaning 'no thumbnail' */ + CropRegion crop = calculateCropRegion( (CropRegion::Outputs)( + CropRegion::OUTPUT_PREVIEW | + CropRegion::OUTPUT_VIDEO | + CropRegion::OUTPUT_PICTURE )); int32_t reqCropRegion[3] = { crop.left, crop.top, crop.width }; res = request->update(ANDROID_SCALER_CROP_REGION, reqCropRegion, 3); @@ -2161,23 +2171,123 @@ int Parameters::degToTransform(int degrees, bool mirror) { return -1; } +int Parameters::cropXToArray(int x) const { + ALOG_ASSERT(x >= 0, "Crop-relative X coordinate = '%d' is out of bounds" + "(lower = 0)", x); + + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + ALOG_ASSERT(x < previewCrop.width, "Crop-relative X coordinate = '%d' " + "is out of bounds (upper = %d)", x, previewCrop.width); + + int ret = x + previewCrop.left; + + ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayWidth), + "Calculated pixel array value X = '%d' is out of bounds (upper = %d)", + ret, fastInfo.arrayWidth); + return ret; +} + +int Parameters::cropYToArray(int y) const { + ALOG_ASSERT(y >= 0, "Crop-relative Y coordinate = '%d' is out of bounds " + "(lower = 0)", y); + + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + ALOG_ASSERT(y < previewCrop.height, "Crop-relative Y coordinate = '%d' is " + "out of bounds (upper = %d)", y, previewCrop.height); + + int ret = y + previewCrop.top; + + ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayHeight), + "Calculated pixel array value Y = '%d' is out of bounds (upper = %d)", + ret, fastInfo.arrayHeight); + + return ret; + +} + +int Parameters::normalizedXToCrop(int x) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return (x + 1000) * (previewCrop.width - 1) / 2000; +} + +int Parameters::normalizedYToCrop(int y) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return (y + 1000) * (previewCrop.height - 1) / 2000; +} + +int Parameters::arrayXToCrop(int x) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return x - previewCrop.left; +} + +int Parameters::arrayYToCrop(int y) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return y - previewCrop.top; +} + +int Parameters::cropXToNormalized(int x) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return x * 2000 / (previewCrop.width - 1) - 1000; +} + +int Parameters::cropYToNormalized(int y) const { + CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); + return y * 2000 / (previewCrop.height - 1) - 1000; +} + int Parameters::arrayXToNormalized(int width) const { - return width * 2000 / (fastInfo.arrayWidth - 1) - 1000; + int ret = cropXToNormalized(arrayXToCrop(width)); + + ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of " + "lower bounds %d", ret); + ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of " + "upper bounds %d", ret); + + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return width * 2000 / (fastInfo.arrayWidth - 1) - 1000; + } + + return ret; } int Parameters::arrayYToNormalized(int height) const { - return height * 2000 / (fastInfo.arrayHeight - 1) - 1000; + int ret = cropYToNormalized(arrayYToCrop(height)); + + ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds" + " %d", ret); + ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds" + " %d", ret); + + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return height * 2000 / (fastInfo.arrayHeight - 1) - 1000; + } + + return ret; } int Parameters::normalizedXToArray(int x) const { - return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + } + + return cropXToArray(normalizedXToCrop(x)); } int Parameters::normalizedYToArray(int y) const { - return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; + } + + return cropYToArray(normalizedYToCrop(y)); } -Parameters::CropRegion Parameters::calculateCropRegion(void) const { +Parameters::CropRegion Parameters::calculateCropRegion( + Parameters::CropRegion::Outputs outputs) const { float zoomLeft, zoomTop, zoomWidth, zoomHeight; @@ -2220,9 +2330,7 @@ Parameters::CropRegion Parameters::calculateCropRegion(void) const { float outputSizes[][2] = { { previewWidth, previewHeight }, { videoWidth, videoHeight }, - /* don't include jpeg thumbnail size - it's valid for - it to be set to (0,0), meaning 'no thumbnail' */ - // { jpegThumbSize[0], jpegThumbSize[1] }, + { jpegThumbSize[0], jpegThumbSize[1] }, { pictureWidth, pictureHeight }, }; @@ -2233,6 +2341,11 @@ Parameters::CropRegion Parameters::calculateCropRegion(void) const { i < sizeof(outputSizes) / sizeof(outputSizes[0]); ++i) { + // skip over outputs we don't want to consider for the crop region + if ( !((1 << i) & outputs) ) { + continue; + } + float outputWidth = outputSizes[i][0]; float outputHeight = outputSizes[i][1]; float outputRatio = outputWidth / outputHeight; diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h index cb9738b..daae7c4 100644 --- a/services/camera/libcameraservice/camera2/Parameters.h +++ b/services/camera/libcameraservice/camera2/Parameters.h @@ -186,6 +186,7 @@ struct Parameters { struct Quirks { bool triggerAfWithAuto; bool useZslFormat; + bool meteringCropRegion; } quirks; /** @@ -228,8 +229,15 @@ struct Parameters { float top; float width; float height; + + enum Outputs { + OUTPUT_PREVIEW = 0x01, + OUTPUT_VIDEO = 0x02, + OUTPUT_JPEG_THUMBNAIL = 0x04, + OUTPUT_PICTURE = 0x08, + }; }; - CropRegion calculateCropRegion(void) const; + CropRegion calculateCropRegion(CropRegion::Outputs outputs) const; // Static methods for debugging and converting between camera1 and camera2 // parameters @@ -275,6 +283,21 @@ struct Parameters { int32_t fpsFromRange(int32_t min, int32_t max) const; +private: + + // Convert between HAL2 sensor array coordinates and + // viewfinder crop-region relative array coordinates + int cropXToArray(int x) const; + int cropYToArray(int y) const; + int arrayXToCrop(int x) const; + int arrayYToCrop(int y) const; + + // Convert between viewfinder crop-region relative array coordinates + // and camera API (-1000,1000)-(1000,1000) normalized coords + int cropXToNormalized(int x) const; + int cropYToNormalized(int y) const; + int normalizedXToCrop(int x) const; + int normalizedYToCrop(int y) const; }; // This class encapsulates the Parameters class so that it can only be accessed |