summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2012-09-28 15:30:03 -0700
committerIgor Murashkin <iam@google.com>2012-10-05 13:32:07 -0700
commit7373cbe85e617345f7002256a4be389fe62af913 (patch)
treeecc7614df98deb08d8e39e064be47cec63186a1f /services/camera
parentaf3d28870f7890370d6acb21d20cf1ccab4b9e08 (diff)
downloadframeworks_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.cpp4
-rw-r--r--services/camera/libcameraservice/camera2/Parameters.cpp131
-rw-r--r--services/camera/libcameraservice/camera2/Parameters.h25
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