OSDN Git Service

Camera: Limit supported preview sizes
authorZhijun He <zhijunhe@google.com>
Thu, 12 Sep 2013 05:58:17 +0000 (22:58 -0700)
committerZhijun He <zhijunhe@google.com>
Fri, 13 Sep 2013 21:12:43 +0000 (14:12 -0700)
The ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES can provide sizes as large
as jpeg sizes, which could cause potential issues when trying to do
full size still capture and full size preview. This is not supported
by many devices due to hardware limitation. This change limits the
preview (as well video) size to no more than 1080p.

Bug: 10625115
Change-Id: I9467ab843553ec06e8249b4a17c0ecf4c6d6f04e

services/camera/libcameraservice/api1/client2/Parameters.cpp
services/camera/libcameraservice/api1/client2/Parameters.h

index 0459866..ad55feb 100644 (file)
@@ -58,13 +58,13 @@ status_t Parameters::initialize(const CameraMetadata *info) {
     res = buildQuirks();
     if (res != OK) return res;
 
-    camera_metadata_ro_entry_t availableProcessedSizes =
-        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
-    if (!availableProcessedSizes.count) return NO_INIT;
+    const Size MAX_PREVIEW_SIZE = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
+    res = getFilteredPreviewSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
+    if (res != OK) return res;
 
     // TODO: Pick more intelligently
-    previewWidth = availableProcessedSizes.data.i32[0];
-    previewHeight = availableProcessedSizes.data.i32[1];
+    previewWidth = availablePreviewSizes[0].width;
+    previewHeight = availablePreviewSizes[0].height;
     videoWidth = previewWidth;
     videoHeight = previewHeight;
 
@@ -75,12 +75,13 @@ status_t Parameters::initialize(const CameraMetadata *info) {
                     previewWidth, previewHeight));
     {
         String8 supportedPreviewSizes;
-        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
+        for (size_t i = 0; i < availablePreviewSizes.size(); i++) {
             if (i != 0) supportedPreviewSizes += ",";
             supportedPreviewSizes += String8::format("%dx%d",
-                    availableProcessedSizes.data.i32[i],
-                    availableProcessedSizes.data.i32[i+1]);
+                    availablePreviewSizes[i].width,
+                    availablePreviewSizes[i].height);
         }
+        ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.string());
         params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
                 supportedPreviewSizes);
         params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
@@ -1072,15 +1073,13 @@ status_t Parameters::set(const String8& paramString) {
                     validatedParams.previewWidth, validatedParams.previewHeight);
             return BAD_VALUE;
         }
-        camera_metadata_ro_entry_t availablePreviewSizes =
-            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
-            if ((availablePreviewSizes.data.i32[i] ==
+        for (i = 0; i < availablePreviewSizes.size(); i++) {
+            if ((availablePreviewSizes[i].width ==
                     validatedParams.previewWidth) &&
-                (availablePreviewSizes.data.i32[i+1] ==
+                (availablePreviewSizes[i].height ==
                     validatedParams.previewHeight)) break;
         }
-        if (i == availablePreviewSizes.count) {
+        if (i == availablePreviewSizes.size()) {
             ALOGE("%s: Requested preview size %d x %d is not supported",
                     __FUNCTION__, validatedParams.previewWidth,
                     validatedParams.previewHeight);
@@ -1618,15 +1617,13 @@ status_t Parameters::set(const String8& paramString) {
                     __FUNCTION__);
             return BAD_VALUE;
         }
-        camera_metadata_ro_entry_t availableVideoSizes =
-            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
-            if ((availableVideoSizes.data.i32[i] ==
+        for (i = 0; i < availablePreviewSizes.size(); i++) {
+            if ((availablePreviewSizes[i].width ==
                     validatedParams.videoWidth) &&
-                (availableVideoSizes.data.i32[i+1] ==
+                (availablePreviewSizes[i].height ==
                     validatedParams.videoHeight)) break;
         }
-        if (i == availableVideoSizes.count) {
+        if (i == availablePreviewSizes.size()) {
             ALOGE("%s: Requested video size %d x %d is not supported",
                     __FUNCTION__, validatedParams.videoWidth,
                     validatedParams.videoHeight);
@@ -2447,6 +2444,38 @@ int Parameters::normalizedYToArray(int y) const {
     return cropYToArray(normalizedYToCrop(y));
 }
 
+status_t Parameters::getFilteredPreviewSizes(Size limit, Vector<Size> *sizes) {
+    if (info == NULL) {
+        ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
+        return NO_INIT;
+    }
+    if (sizes == NULL) {
+        ALOGE("%s: Input size is null", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    const size_t SIZE_COUNT = sizeof(Size) / sizeof(int);
+    camera_metadata_ro_entry_t availableProcessedSizes =
+        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, SIZE_COUNT);
+    if (availableProcessedSizes.count < SIZE_COUNT) return BAD_VALUE;
+
+    Size previewSize;
+    for (size_t i = 0; i < availableProcessedSizes.count; i += SIZE_COUNT) {
+        previewSize.width = availableProcessedSizes.data.i32[i];
+        previewSize.height = availableProcessedSizes.data.i32[i+1];
+            // Need skip the preview sizes that are too large.
+            if (previewSize.width <= limit.width &&
+                    previewSize.height <= limit.height) {
+                sizes->push(previewSize);
+            }
+    }
+    if (sizes->isEmpty()) {
+        ALOGE("generated preview size list is empty!!");
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
 Parameters::CropRegion Parameters::calculateCropRegion(
                             Parameters::CropRegion::Outputs outputs) const {
 
index 464830c..a7111a3 100644 (file)
@@ -105,6 +105,11 @@ struct Parameters {
     };
     Vector<Area> focusingAreas;
 
+    struct Size {
+        int32_t width;
+        int32_t height;
+    };
+
     int32_t exposureCompensation;
     bool autoExposureLock;
     bool autoWhiteBalanceLock;
@@ -159,6 +164,9 @@ struct Parameters {
 
     // Number of zoom steps to simulate
     static const unsigned int NUM_ZOOM_STEPS = 100;
+    // Max preview size allowed
+    static const unsigned int MAX_PREVIEW_WIDTH = 1920;
+    static const unsigned int MAX_PREVIEW_HEIGHT = 1080;
 
     // Full static camera info, object owned by someone else, such as
     // Camera2Device.
@@ -317,6 +325,10 @@ private:
     int cropYToNormalized(int y) const;
     int normalizedXToCrop(int x) const;
     int normalizedYToCrop(int y) const;
+
+    Vector<Size> availablePreviewSizes;
+    // Get size list (that are no larger than limit) from static metadata.
+    status_t getFilteredPreviewSizes(Size limit, Vector<Size> *sizes);
 };
 
 // This class encapsulates the Parameters class so that it can only be accessed