diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2013-04-29 13:50:24 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2013-05-01 14:56:12 -0700 |
commit | a1220f482f5a50488777ab789abd861b5565acdc (patch) | |
tree | c08d6a49f9a96f8c6bb16d92060290e7ec044124 /services | |
parent | 948700612e987b49185f7916befd38f39a2b0a3b (diff) | |
download | frameworks_av-a1220f482f5a50488777ab789abd861b5565acdc.zip frameworks_av-a1220f482f5a50488777ab789abd861b5565acdc.tar.gz frameworks_av-a1220f482f5a50488777ab789abd861b5565acdc.tar.bz2 |
Camera2/3: Fix still image FOV reporting.
Still FOV can vary as a function of the output sizes, with
the function depending on the HAL version.
Calculate and update the FOV whenever the output sizes might change.
Bug: 8484377
Change-Id: I56f2cc768a1e128a159b326588be55b2752db06e
Diffstat (limited to 'services')
-rw-r--r-- | services/camera/libcameraservice/camera2/Parameters.cpp | 131 | ||||
-rw-r--r-- | services/camera/libcameraservice/camera2/Parameters.h | 4 |
2 files changed, 125 insertions, 10 deletions
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp index a304b35..c1b1daf 100644 --- a/services/camera/libcameraservice/camera2/Parameters.cpp +++ b/services/camera/libcameraservice/camera2/Parameters.cpp @@ -659,15 +659,13 @@ status_t Parameters::initialize(const CameraMetadata *info) { float minFocalLength = availableFocalLengths.data.f[0]; params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength); - camera_metadata_ro_entry_t sensorSize = - staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2); - if (!sensorSize.count) return NO_INIT; + float horizFov, vertFov; + res = calculatePictureFovs(&horizFov, &vertFov); + if (res != OK) { + ALOGE("%s: Can't calculate field of views!", __FUNCTION__); + return res; + } - // The fields of view here assume infinity focus, maximum wide angle - float horizFov = 180 / M_PI * - 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength)); - float vertFov = 180 / M_PI * - 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength)); params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov); params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov); @@ -861,6 +859,10 @@ status_t Parameters::buildFastInfo() { staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE); bool fixedLens = (minFocusDistance.data.f[0] == 0); + camera_metadata_ro_entry_t availableFocalLengths = + staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS); + if (!availableFocalLengths.count) return NO_INIT; + if (sceneModeOverrides.count > 0) { // sceneModeOverrides is defined to have 3 entries for each scene mode, // which are AE, AWB, and AF override modes the HAL wants for that scene @@ -928,6 +930,16 @@ status_t Parameters::buildFastInfo() { fastInfo.arrayHeight = arrayHeight; fastInfo.bestFaceDetectMode = bestFaceDetectMode; fastInfo.maxFaces = maxFaces; + + // Find smallest (widest-angle) focal length to use as basis of still + // picture FOV reporting. + fastInfo.minFocalLength = availableFocalLengths.data.f[0]; + for (size_t i = 1; i < availableFocalLengths.count; i++) { + if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) { + fastInfo.minFocalLength = availableFocalLengths.data.f[i]; + } + } + return OK; } @@ -1577,6 +1589,21 @@ status_t Parameters::set(const String8& paramString) { *this = validatedParams; + /** Update external parameters calculated from the internal ones */ + + // HORIZONTAL/VERTICAL FIELD OF VIEW + float horizFov, vertFov; + res = calculatePictureFovs(&horizFov, &vertFov); + if (res != OK) { + ALOGE("%s: Can't calculate FOVs", __FUNCTION__); + // continue so parameters are at least consistent + } + newParams.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, + horizFov); + newParams.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, + vertFov); + ALOGV("Current still picture FOV: %f x %f deg", horizFov, vertFov); + // Need to flatten again in case of overrides paramsFlattened = newParams.flatten(); params = newParams; @@ -2244,7 +2271,7 @@ int Parameters::cropXToArray(int x) const { 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); + "is out of bounds (upper = %f)", x, previewCrop.width); int ret = x + previewCrop.left; @@ -2260,7 +2287,7 @@ int Parameters::cropYToArray(int y) const { 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); + "out of bounds (upper = %f)", y, previewCrop.height); int ret = y + previewCrop.top; @@ -2466,6 +2493,90 @@ Parameters::CropRegion Parameters::calculateCropRegion( return crop; } +status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov) + const { + camera_metadata_ro_entry_t sensorSize = + staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2); + if (!sensorSize.count) return NO_INIT; + + camera_metadata_ro_entry_t availableFocalLengths = + staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS); + if (!availableFocalLengths.count) return NO_INIT; + + float arrayAspect = static_cast<float>(fastInfo.arrayWidth) / + fastInfo.arrayHeight; + float stillAspect = static_cast<float>(pictureWidth) / pictureHeight; + ALOGV("Array aspect: %f, still aspect: %f", arrayAspect, stillAspect); + + // The crop factors from the full sensor array to the still picture crop + // region + float horizCropFactor = 1.f; + float vertCropFactor = 1.f; + + /** + * Need to calculate the still image field of view based on the total pixel + * array field of view, and the relative aspect ratios of the pixel array + * and output streams. + * + * Special treatment for quirky definition of crop region and relative + * stream cropping. + */ + if (quirks.meteringCropRegion) { + /** + * All streams are the same in height, so narrower aspect ratios will + * get cropped on the sides. First find the largest (widest) aspect + * ratio, then calculate the crop of the still FOV based on that. + */ + float cropAspect = arrayAspect; + float aspects[] = { + stillAspect, + static_cast<float>(previewWidth) / previewHeight, + static_cast<float>(videoWidth) / videoHeight + }; + for (size_t i = 0; i < sizeof(aspects)/sizeof(aspects[0]); i++) { + if (cropAspect < aspects[i]) cropAspect = aspects[i]; + } + ALOGV("Widest crop aspect: %f", cropAspect); + // Horizontal crop of still is done based on fitting in the widest + // aspect ratio + horizCropFactor = stillAspect / cropAspect; + // Vertical crop is a function of the array aspect ratio and the + // widest aspect ratio. + vertCropFactor = arrayAspect / cropAspect; + } else { + /** + * Crop are just a function of just the still/array relative aspect + * ratios. Since each stream will maximize its area within the crop + * region, and for FOV we assume a full-sensor crop region, we only ever + * crop the FOV either vertically or horizontally, never both. + */ + horizCropFactor = (arrayAspect > stillAspect) ? + (stillAspect / arrayAspect) : 1.f; + vertCropFactor = (arrayAspect < stillAspect) ? + (arrayAspect / stillAspect) : 1.f; + } + ALOGV("Horiz crop factor: %f, vert crop fact: %f", + horizCropFactor, vertCropFactor); + /** + * Basic field of view formula is: + * angle of view = 2 * arctangent ( d / 2f ) + * where d is the physical sensor dimension of interest, and f is + * the focal length. This only applies to rectilinear sensors, for focusing + * at distances >> f, etc. + */ + if (horizFov != NULL) { + *horizFov = 180 / M_PI * 2 * + atanf(horizCropFactor * sensorSize.data.f[0] / + (2 * fastInfo.minFocalLength)); + } + if (vertFov != NULL) { + *vertFov = 180 / M_PI * 2 * + atanf(vertCropFactor * sensorSize.data.f[1] / + (2 * fastInfo.minFocalLength)); + } + return OK; +} + int32_t Parameters::fpsFromRange(int32_t /*min*/, int32_t max) const { return max; } diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h index fe3ec1d..15a1ef8 100644 --- a/services/camera/libcameraservice/camera2/Parameters.h +++ b/services/camera/libcameraservice/camera2/Parameters.h @@ -183,6 +183,7 @@ struct Parameters { } }; DefaultKeyedVector<uint8_t, OverrideModes> sceneModeOverrides; + float minFocalLength; } fastInfo; // Quirks information; these are short-lived flags to enable workarounds for @@ -243,6 +244,9 @@ struct Parameters { }; CropRegion calculateCropRegion(CropRegion::Outputs outputs) const; + // Calculate the field of view of the high-resolution JPEG capture + status_t calculatePictureFovs(float *horizFov, float *vertFov) const; + // Static methods for debugging and converting between camera1 and camera2 // parameters |