From af3d28870f7890370d6acb21d20cf1ccab4b9e08 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Thu, 4 Oct 2012 14:22:18 -0700 Subject: Camera2: Change policy for calculating previewFpsRange from previewFps Bug: 7259959 Change-Id: I759a559d7115201264f88db1f23edc2d6aef6c43 --- .../camera/libcameraservice/camera2/Parameters.cpp | 112 ++++++++++++++++++--- .../camera/libcameraservice/camera2/Parameters.h | 8 ++ 2 files changed, 105 insertions(+), 15 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp index b05cdaf..dd2cacd 100644 --- a/services/camera/libcameraservice/camera2/Parameters.cpp +++ b/services/camera/libcameraservice/camera2/Parameters.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include @@ -171,16 +173,36 @@ status_t Parameters::initialize(const CameraMetadata *info) { // still have to do something sane for them // NOTE: Not scaled like FPS range values are. - previewFps = previewFpsRange[0]; + previewFps = fpsFromRange(previewFpsRange[0], previewFpsRange[1]); params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, - previewFpsRange[0]); + previewFps); { + SortedVector sortedPreviewFrameRates; + String8 supportedPreviewFrameRates; for (size_t i=0; i < availableFpsRanges.count; i += 2) { - if (i != 0) supportedPreviewFrameRates += ","; + // from the [min, max] fps range use the max value + int fps = fpsFromRange(availableFpsRanges.data.i32[i], + availableFpsRanges.data.i32[i+1]); + + // de-dupe frame rates + if (sortedPreviewFrameRates.indexOf(fps) == NAME_NOT_FOUND) { + sortedPreviewFrameRates.add(fps); + } + else { + continue; + } + + if (sortedPreviewFrameRates.size() > 1) { + supportedPreviewFrameRates += ","; + } + supportedPreviewFrameRates += String8::format("%d", - availableFpsRanges.data.i32[i]); + fps); + + ALOGV("%s: Supported preview frame rates: %s", + __FUNCTION__, supportedPreviewFrameRates.string()); } params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, supportedPreviewFrameRates); @@ -983,6 +1005,13 @@ status_t Parameters::set(const String8& paramString) { } } + // RECORDING_HINT (always supported) + validatedParams.recordingHint = boolFromString( + newParams.get(CameraParameters::KEY_RECORDING_HINT) ); + bool recordingHintChanged = validatedParams.recordingHint != recordingHint; + ALOGV_IF(recordingHintChanged, "%s: Recording hint changed to %d", + __FUNCTION__, recordingHintChanged); + // PREVIEW_FPS_RANGE bool fpsRangeChanged = false; newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0], @@ -1009,7 +1038,9 @@ status_t Parameters::set(const String8& paramString) { validatedParams.previewFpsRange[1]); return BAD_VALUE; } - validatedParams.previewFps = validatedParams.previewFpsRange[0]; + validatedParams.previewFps = + fpsFromRange(validatedParams.previewFpsRange[0], + validatedParams.previewFpsRange[1]); newParams.setPreviewFrameRate(validatedParams.previewFps); } @@ -1041,27 +1072,78 @@ status_t Parameters::set(const String8& paramString) { // The single-value FPS is the same as the minimum of the range. if (!fpsRangeChanged) { validatedParams.previewFps = newParams.getPreviewFrameRate(); - if (validatedParams.previewFps != previewFps) { + if (validatedParams.previewFps != previewFps || recordingHintChanged) { camera_metadata_ro_entry_t availableFrameRates = staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); + /** + * If recording hint is set, find the range that encompasses + * previewFps with the largest min index. + * + * If recording hint is not set, find the range with previewFps + * with the smallest min index. + * + * Either way, in case of multiple ranges, break the tie by + * selecting the smaller range. + */ + int targetFps = validatedParams.previewFps; + // all ranges which have targetFps + Vector candidateRanges; for (i = 0; i < availableFrameRates.count; i+=2) { - if (availableFrameRates.data.i32[i] == - validatedParams.previewFps) break; + Range r = { + availableFrameRates.data.i32[i], + availableFrameRates.data.i32[i+1] + }; + + if (r.min <= targetFps && targetFps <= r.max) { + candidateRanges.push(r); + } } - if (i == availableFrameRates.count) { + if (candidateRanges.isEmpty()) { ALOGE("%s: Requested preview frame rate %d is not supported", __FUNCTION__, validatedParams.previewFps); return BAD_VALUE; } + // most applicable range with targetFps + Range bestRange = candidateRanges[0]; + for (i = 1; i < candidateRanges.size(); ++i) { + Range r = candidateRanges[i]; + + // Find by largest minIndex in recording mode + if (validatedParams.recordingHint) { + if (r.min > bestRange.min) { + bestRange = r; + } + else if (r.min == bestRange.min && r.max < bestRange.max) { + bestRange = r; + } + } + // Find by smallest minIndex in preview mode + else { + if (r.min < bestRange.min) { + bestRange = r; + } + else if (r.min == bestRange.min && r.max < bestRange.max) { + bestRange = r; + } + } + } + validatedParams.previewFpsRange[0] = - availableFrameRates.data.i32[i]; + bestRange.min; validatedParams.previewFpsRange[1] = - availableFrameRates.data.i32[i+1]; + bestRange.max; + + ALOGV("%s: New preview FPS range: %d, %d, recordingHint = %d", + __FUNCTION__, + validatedParams.previewFpsRange[0], + validatedParams.previewFpsRange[1], + validatedParams.recordingHint); } newParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, String8::format("%d,%d", validatedParams.previewFpsRange[0] * kFpsToApiScale, validatedParams.previewFpsRange[1] * kFpsToApiScale)); + } // PICTURE_SIZE @@ -1455,10 +1537,6 @@ status_t Parameters::set(const String8& paramString) { } } - // RECORDING_HINT (always supported) - validatedParams.recordingHint = boolFromString( - newParams.get(CameraParameters::KEY_RECORDING_HINT) ); - // VIDEO_STABILIZATION validatedParams.videoStabilization = boolFromString( newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) ); @@ -2204,5 +2282,9 @@ Parameters::CropRegion Parameters::calculateCropRegion(void) const { return crop; } +int32_t Parameters::fpsFromRange(int32_t min, int32_t max) const { + return max; +} + }; // namespace camera2 }; // namespace android diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h index 53ddf99..cb9738b 100644 --- a/services/camera/libcameraservice/camera2/Parameters.h +++ b/services/camera/libcameraservice/camera2/Parameters.h @@ -267,6 +267,14 @@ struct Parameters { int arrayYToNormalized(int height) const; int normalizedXToArray(int x) const; int normalizedYToArray(int y) const; + + struct Range { + int min; + int max; + }; + + int32_t fpsFromRange(int32_t min, int32_t max) const; + }; // This class encapsulates the Parameters class so that it can only be accessed -- cgit v1.1