Parameters.cpp revision 018d228ac43a8da7d5f36e45fd105c9baf2490a0
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2::Parameters"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
23
24#include <math.h>
25#include <stdlib.h>
26#include <cutils/properties.h>
27
28#include "Parameters.h"
29#include "system/camera.h"
30#include "camera/CameraParameters.h"
31
32namespace android {
33namespace camera2 {
34
35Parameters::Parameters(int cameraId,
36        int cameraFacing) :
37        cameraId(cameraId),
38        cameraFacing(cameraFacing),
39        info(NULL) {
40}
41
42Parameters::~Parameters() {
43}
44
45status_t Parameters::initialize(const CameraMetadata *info) {
46    status_t res;
47
48    if (info->entryCount() == 0) {
49        ALOGE("%s: No static information provided!", __FUNCTION__);
50        return BAD_VALUE;
51    }
52    Parameters::info = info;
53
54    res = buildFastInfo();
55    if (res != OK) return res;
56
57    CameraParameters params;
58
59    camera_metadata_ro_entry_t availableProcessedSizes =
60        staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
61    if (!availableProcessedSizes.count) return NO_INIT;
62
63    // TODO: Pick more intelligently
64    previewWidth = availableProcessedSizes.data.i32[0];
65    previewHeight = availableProcessedSizes.data.i32[1];
66    videoWidth = previewWidth;
67    videoHeight = previewHeight;
68
69    params.setPreviewSize(previewWidth, previewHeight);
70    params.setVideoSize(videoWidth, videoHeight);
71    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
72            String8::format("%dx%d",
73                    previewWidth, previewHeight));
74    {
75        String8 supportedPreviewSizes;
76        for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
77            if (i != 0) supportedPreviewSizes += ",";
78            supportedPreviewSizes += String8::format("%dx%d",
79                    availableProcessedSizes.data.i32[i],
80                    availableProcessedSizes.data.i32[i+1]);
81        }
82        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
83                supportedPreviewSizes);
84        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
85                supportedPreviewSizes);
86    }
87
88    camera_metadata_ro_entry_t availableFpsRanges =
89        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
90    if (!availableFpsRanges.count) return NO_INIT;
91
92    previewFpsRange[0] = availableFpsRanges.data.i32[0];
93    previewFpsRange[1] = availableFpsRanges.data.i32[1];
94
95    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
96            String8::format("%d,%d",
97                    previewFpsRange[0],
98                    previewFpsRange[1]));
99
100    {
101        String8 supportedPreviewFpsRange;
102        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
103            if (i != 0) supportedPreviewFpsRange += ",";
104            supportedPreviewFpsRange += String8::format("(%d,%d)",
105                    availableFpsRanges.data.i32[i],
106                    availableFpsRanges.data.i32[i+1]);
107        }
108        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
109                supportedPreviewFpsRange);
110    }
111
112    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
113    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
114            formatEnumToString(previewFormat)); // NV21
115
116    previewTransform = degToTransform(0,
117            cameraFacing == CAMERA_FACING_FRONT);
118
119    camera_metadata_ro_entry_t availableFormats =
120        staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
121
122    {
123        String8 supportedPreviewFormats;
124        bool addComma = false;
125        for (size_t i=0; i < availableFormats.count; i++) {
126            if (addComma) supportedPreviewFormats += ",";
127            addComma = true;
128            switch (availableFormats.data.i32[i]) {
129            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
130                supportedPreviewFormats +=
131                    CameraParameters::PIXEL_FORMAT_YUV422SP;
132                break;
133            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
134                supportedPreviewFormats +=
135                    CameraParameters::PIXEL_FORMAT_YUV420SP;
136                break;
137            case HAL_PIXEL_FORMAT_YCbCr_422_I:
138                supportedPreviewFormats +=
139                    CameraParameters::PIXEL_FORMAT_YUV422I;
140                break;
141            case HAL_PIXEL_FORMAT_YV12:
142                supportedPreviewFormats +=
143                    CameraParameters::PIXEL_FORMAT_YUV420P;
144                break;
145            case HAL_PIXEL_FORMAT_RGB_565:
146                supportedPreviewFormats +=
147                    CameraParameters::PIXEL_FORMAT_RGB565;
148                break;
149            case HAL_PIXEL_FORMAT_RGBA_8888:
150                supportedPreviewFormats +=
151                    CameraParameters::PIXEL_FORMAT_RGBA8888;
152                break;
153            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
154            case HAL_PIXEL_FORMAT_RAW_SENSOR:
155            case HAL_PIXEL_FORMAT_BLOB:
156                addComma = false;
157                break;
158
159            default:
160                ALOGW("%s: Camera %d: Unknown preview format: %x",
161                        __FUNCTION__, cameraId, availableFormats.data.i32[i]);
162                addComma = false;
163                break;
164            }
165        }
166        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
167                supportedPreviewFormats);
168    }
169
170    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
171    // still have to do something sane for them
172
173    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
174            previewFpsRange[0]);
175
176    {
177        String8 supportedPreviewFrameRates;
178        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
179            if (i != 0) supportedPreviewFrameRates += ",";
180            supportedPreviewFrameRates += String8::format("%d",
181                    availableFpsRanges.data.i32[i]);
182        }
183        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
184                supportedPreviewFrameRates);
185    }
186
187    camera_metadata_ro_entry_t availableJpegSizes =
188        staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
189    if (!availableJpegSizes.count) return NO_INIT;
190
191    // TODO: Pick maximum
192    pictureWidth = availableJpegSizes.data.i32[0];
193    pictureHeight = availableJpegSizes.data.i32[1];
194
195    params.setPictureSize(pictureWidth,
196            pictureHeight);
197
198    {
199        String8 supportedPictureSizes;
200        for (size_t i=0; i < availableJpegSizes.count; i += 2) {
201            if (i != 0) supportedPictureSizes += ",";
202            supportedPictureSizes += String8::format("%dx%d",
203                    availableJpegSizes.data.i32[i],
204                    availableJpegSizes.data.i32[i+1]);
205        }
206        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
207                supportedPictureSizes);
208    }
209
210    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
211    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
212            CameraParameters::PIXEL_FORMAT_JPEG);
213
214    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
215        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 4);
216    if (!availableJpegThumbnailSizes.count) return NO_INIT;
217
218    // TODO: Pick default thumbnail size sensibly
219    jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
220    jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
221
222    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
223            jpegThumbSize[0]);
224    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
225            jpegThumbSize[1]);
226
227    {
228        String8 supportedJpegThumbSizes;
229        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
230            if (i != 0) supportedJpegThumbSizes += ",";
231            supportedJpegThumbSizes += String8::format("%dx%d",
232                    availableJpegThumbnailSizes.data.i32[i],
233                    availableJpegThumbnailSizes.data.i32[i+1]);
234        }
235        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
236                supportedJpegThumbSizes);
237    }
238
239    jpegThumbQuality = 90;
240    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
241            jpegThumbQuality);
242    jpegQuality = 90;
243    params.set(CameraParameters::KEY_JPEG_QUALITY,
244            jpegQuality);
245    jpegRotation = 0;
246    params.set(CameraParameters::KEY_ROTATION,
247            jpegRotation);
248
249    gpsEnabled = false;
250    gpsProcessingMethod = "unknown";
251    // GPS fields in CameraParameters are not set by implementation
252
253    wbMode = ANDROID_CONTROL_AWB_AUTO;
254    params.set(CameraParameters::KEY_WHITE_BALANCE,
255            CameraParameters::WHITE_BALANCE_AUTO);
256
257    camera_metadata_ro_entry_t availableWhiteBalanceModes =
258        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
259    {
260        String8 supportedWhiteBalance;
261        bool addComma = false;
262        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
263            if (addComma) supportedWhiteBalance += ",";
264            addComma = true;
265            switch (availableWhiteBalanceModes.data.u8[i]) {
266            case ANDROID_CONTROL_AWB_AUTO:
267                supportedWhiteBalance +=
268                    CameraParameters::WHITE_BALANCE_AUTO;
269                break;
270            case ANDROID_CONTROL_AWB_INCANDESCENT:
271                supportedWhiteBalance +=
272                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
273                break;
274            case ANDROID_CONTROL_AWB_FLUORESCENT:
275                supportedWhiteBalance +=
276                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
277                break;
278            case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
279                supportedWhiteBalance +=
280                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
281                break;
282            case ANDROID_CONTROL_AWB_DAYLIGHT:
283                supportedWhiteBalance +=
284                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
285                break;
286            case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
287                supportedWhiteBalance +=
288                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
289                break;
290            case ANDROID_CONTROL_AWB_TWILIGHT:
291                supportedWhiteBalance +=
292                    CameraParameters::WHITE_BALANCE_TWILIGHT;
293                break;
294            case ANDROID_CONTROL_AWB_SHADE:
295                supportedWhiteBalance +=
296                    CameraParameters::WHITE_BALANCE_SHADE;
297                break;
298            // Skipping values not mappable to v1 API
299            case ANDROID_CONTROL_AWB_OFF:
300                addComma = false;
301                break;
302            default:
303                ALOGW("%s: Camera %d: Unknown white balance value: %d",
304                        __FUNCTION__, cameraId,
305                        availableWhiteBalanceModes.data.u8[i]);
306                addComma = false;
307                break;
308            }
309        }
310        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
311                supportedWhiteBalance);
312    }
313
314    effectMode = ANDROID_CONTROL_EFFECT_OFF;
315    params.set(CameraParameters::KEY_EFFECT,
316            CameraParameters::EFFECT_NONE);
317
318    camera_metadata_ro_entry_t availableEffects =
319        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
320    if (!availableEffects.count) return NO_INIT;
321    {
322        String8 supportedEffects;
323        bool addComma = false;
324        for (size_t i=0; i < availableEffects.count; i++) {
325            if (addComma) supportedEffects += ",";
326            addComma = true;
327            switch (availableEffects.data.u8[i]) {
328                case ANDROID_CONTROL_EFFECT_OFF:
329                    supportedEffects +=
330                        CameraParameters::EFFECT_NONE;
331                    break;
332                case ANDROID_CONTROL_EFFECT_MONO:
333                    supportedEffects +=
334                        CameraParameters::EFFECT_MONO;
335                    break;
336                case ANDROID_CONTROL_EFFECT_NEGATIVE:
337                    supportedEffects +=
338                        CameraParameters::EFFECT_NEGATIVE;
339                    break;
340                case ANDROID_CONTROL_EFFECT_SOLARIZE:
341                    supportedEffects +=
342                        CameraParameters::EFFECT_SOLARIZE;
343                    break;
344                case ANDROID_CONTROL_EFFECT_SEPIA:
345                    supportedEffects +=
346                        CameraParameters::EFFECT_SEPIA;
347                    break;
348                case ANDROID_CONTROL_EFFECT_POSTERIZE:
349                    supportedEffects +=
350                        CameraParameters::EFFECT_POSTERIZE;
351                    break;
352                case ANDROID_CONTROL_EFFECT_WHITEBOARD:
353                    supportedEffects +=
354                        CameraParameters::EFFECT_WHITEBOARD;
355                    break;
356                case ANDROID_CONTROL_EFFECT_BLACKBOARD:
357                    supportedEffects +=
358                        CameraParameters::EFFECT_BLACKBOARD;
359                    break;
360                case ANDROID_CONTROL_EFFECT_AQUA:
361                    supportedEffects +=
362                        CameraParameters::EFFECT_AQUA;
363                    break;
364                default:
365                    ALOGW("%s: Camera %d: Unknown effect value: %d",
366                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
367                    addComma = false;
368                    break;
369            }
370        }
371        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
372    }
373
374    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
375    params.set(CameraParameters::KEY_ANTIBANDING,
376            CameraParameters::ANTIBANDING_AUTO);
377
378    camera_metadata_ro_entry_t availableAntibandingModes =
379        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
380    if (!availableAntibandingModes.count) return NO_INIT;
381    {
382        String8 supportedAntibanding;
383        bool addComma = false;
384        for (size_t i=0; i < availableAntibandingModes.count; i++) {
385            if (addComma) supportedAntibanding += ",";
386            addComma = true;
387            switch (availableAntibandingModes.data.u8[i]) {
388                case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
389                    supportedAntibanding +=
390                        CameraParameters::ANTIBANDING_OFF;
391                    break;
392                case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
393                    supportedAntibanding +=
394                        CameraParameters::ANTIBANDING_50HZ;
395                    break;
396                case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
397                    supportedAntibanding +=
398                        CameraParameters::ANTIBANDING_60HZ;
399                    break;
400                case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
401                    supportedAntibanding +=
402                        CameraParameters::ANTIBANDING_AUTO;
403                    break;
404                default:
405                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
406                        __FUNCTION__, cameraId,
407                            availableAntibandingModes.data.u8[i]);
408                    addComma = false;
409                    break;
410            }
411        }
412        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
413                supportedAntibanding);
414    }
415
416    sceneMode = ANDROID_CONTROL_OFF;
417    params.set(CameraParameters::KEY_SCENE_MODE,
418            CameraParameters::SCENE_MODE_AUTO);
419
420    camera_metadata_ro_entry_t availableSceneModes =
421        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
422    if (!availableSceneModes.count) return NO_INIT;
423    {
424        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
425        bool addComma = true;
426        bool noSceneModes = false;
427        for (size_t i=0; i < availableSceneModes.count; i++) {
428            if (addComma) supportedSceneModes += ",";
429            addComma = true;
430            switch (availableSceneModes.data.u8[i]) {
431                case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
432                    noSceneModes = true;
433                    break;
434                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
435                    // Not in old API
436                    addComma = false;
437                    break;
438                case ANDROID_CONTROL_SCENE_MODE_ACTION:
439                    supportedSceneModes +=
440                        CameraParameters::SCENE_MODE_ACTION;
441                    break;
442                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
443                    supportedSceneModes +=
444                        CameraParameters::SCENE_MODE_PORTRAIT;
445                    break;
446                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
447                    supportedSceneModes +=
448                        CameraParameters::SCENE_MODE_LANDSCAPE;
449                    break;
450                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
451                    supportedSceneModes +=
452                        CameraParameters::SCENE_MODE_NIGHT;
453                    break;
454                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
455                    supportedSceneModes +=
456                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
457                    break;
458                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
459                    supportedSceneModes +=
460                        CameraParameters::SCENE_MODE_THEATRE;
461                    break;
462                case ANDROID_CONTROL_SCENE_MODE_BEACH:
463                    supportedSceneModes +=
464                        CameraParameters::SCENE_MODE_BEACH;
465                    break;
466                case ANDROID_CONTROL_SCENE_MODE_SNOW:
467                    supportedSceneModes +=
468                        CameraParameters::SCENE_MODE_SNOW;
469                    break;
470                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
471                    supportedSceneModes +=
472                        CameraParameters::SCENE_MODE_SUNSET;
473                    break;
474                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
475                    supportedSceneModes +=
476                        CameraParameters::SCENE_MODE_STEADYPHOTO;
477                    break;
478                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
479                    supportedSceneModes +=
480                        CameraParameters::SCENE_MODE_FIREWORKS;
481                    break;
482                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
483                    supportedSceneModes +=
484                        CameraParameters::SCENE_MODE_SPORTS;
485                    break;
486                case ANDROID_CONTROL_SCENE_MODE_PARTY:
487                    supportedSceneModes +=
488                        CameraParameters::SCENE_MODE_PARTY;
489                    break;
490                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
491                    supportedSceneModes +=
492                        CameraParameters::SCENE_MODE_CANDLELIGHT;
493                    break;
494                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
495                    supportedSceneModes +=
496                        CameraParameters::SCENE_MODE_BARCODE;
497                    break;
498                default:
499                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
500                        __FUNCTION__, cameraId,
501                            availableSceneModes.data.u8[i]);
502                    addComma = false;
503                    break;
504            }
505        }
506        if (!noSceneModes) {
507            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
508                    supportedSceneModes);
509        }
510    }
511
512    camera_metadata_ro_entry_t flashAvailable =
513        staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
514    if (!flashAvailable.count) return NO_INIT;
515
516    camera_metadata_ro_entry_t availableAeModes =
517        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
518    if (!availableAeModes.count) return NO_INIT;
519
520    if (flashAvailable.data.u8[0]) {
521        flashMode = Parameters::FLASH_MODE_AUTO;
522        params.set(CameraParameters::KEY_FLASH_MODE,
523                CameraParameters::FLASH_MODE_AUTO);
524
525        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
526        supportedFlashModes = supportedFlashModes +
527            "," + CameraParameters::FLASH_MODE_AUTO +
528            "," + CameraParameters::FLASH_MODE_ON +
529            "," + CameraParameters::FLASH_MODE_TORCH;
530        for (size_t i=0; i < availableAeModes.count; i++) {
531            if (availableAeModes.data.u8[i] ==
532                    ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
533                supportedFlashModes = supportedFlashModes + "," +
534                    CameraParameters::FLASH_MODE_RED_EYE;
535                break;
536            }
537        }
538        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
539                supportedFlashModes);
540    } else {
541        flashMode = Parameters::FLASH_MODE_OFF;
542        params.set(CameraParameters::KEY_FLASH_MODE,
543                CameraParameters::FLASH_MODE_OFF);
544        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
545                CameraParameters::FLASH_MODE_OFF);
546    }
547
548    camera_metadata_ro_entry_t minFocusDistance =
549        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
550    if (!minFocusDistance.count) return NO_INIT;
551
552    camera_metadata_ro_entry_t availableAfModes =
553        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
554    if (!availableAfModes.count) return NO_INIT;
555
556    if (minFocusDistance.data.f[0] == 0) {
557        // Fixed-focus lens
558        focusMode = Parameters::FOCUS_MODE_FIXED;
559        params.set(CameraParameters::KEY_FOCUS_MODE,
560                CameraParameters::FOCUS_MODE_FIXED);
561        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
562                CameraParameters::FOCUS_MODE_FIXED);
563    } else {
564        focusMode = Parameters::FOCUS_MODE_AUTO;
565        params.set(CameraParameters::KEY_FOCUS_MODE,
566                CameraParameters::FOCUS_MODE_AUTO);
567        String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
568        bool addComma = true;
569
570        for (size_t i=0; i < availableAfModes.count; i++) {
571            if (addComma) supportedFocusModes += ",";
572            addComma = true;
573            switch (availableAfModes.data.u8[i]) {
574                case ANDROID_CONTROL_AF_AUTO:
575                    supportedFocusModes +=
576                        CameraParameters::FOCUS_MODE_AUTO;
577                    break;
578                case ANDROID_CONTROL_AF_MACRO:
579                    supportedFocusModes +=
580                        CameraParameters::FOCUS_MODE_MACRO;
581                    break;
582                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
583                    supportedFocusModes +=
584                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
585                    break;
586                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
587                    supportedFocusModes +=
588                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
589                    break;
590                case ANDROID_CONTROL_AF_EDOF:
591                    supportedFocusModes +=
592                        CameraParameters::FOCUS_MODE_EDOF;
593                    break;
594                // Not supported in old API
595                case ANDROID_CONTROL_AF_OFF:
596                    addComma = false;
597                    break;
598                default:
599                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
600                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
601                    addComma = false;
602                    break;
603            }
604        }
605        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
606                supportedFocusModes);
607    }
608
609    camera_metadata_ro_entry_t max3aRegions =
610        staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
611    if (!max3aRegions.count) return NO_INIT;
612
613    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
614            max3aRegions.data.i32[0]);
615    params.set(CameraParameters::KEY_FOCUS_AREAS,
616            "(0,0,0,0,0)");
617    focusingAreas.clear();
618    focusingAreas.add(Parameters::Area(0,0,0,0,0));
619
620    camera_metadata_ro_entry_t availableFocalLengths =
621        staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
622    if (!availableFocalLengths.count) return NO_INIT;
623
624    float minFocalLength = availableFocalLengths.data.f[0];
625    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
626
627    camera_metadata_ro_entry_t sensorSize =
628        staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
629    if (!sensorSize.count) return NO_INIT;
630
631    // The fields of view here assume infinity focus, maximum wide angle
632    float horizFov = 180 / M_PI *
633            2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
634    float vertFov  = 180 / M_PI *
635            2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
636    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
637    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
638
639    exposureCompensation = 0;
640    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
641                exposureCompensation);
642
643    camera_metadata_ro_entry_t exposureCompensationRange =
644        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
645    if (!exposureCompensationRange.count) return NO_INIT;
646
647    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
648            exposureCompensationRange.data.i32[1]);
649    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
650            exposureCompensationRange.data.i32[0]);
651
652    camera_metadata_ro_entry_t exposureCompensationStep =
653        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
654    if (!exposureCompensationStep.count) return NO_INIT;
655
656    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
657            (float)exposureCompensationStep.data.r[0].numerator /
658            exposureCompensationStep.data.r[0].denominator);
659
660    autoExposureLock = false;
661    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
662            CameraParameters::FALSE);
663    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
664            CameraParameters::TRUE);
665
666    autoWhiteBalanceLock = false;
667    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
668            CameraParameters::FALSE);
669    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
670            CameraParameters::TRUE);
671
672    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
673    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
674            max3aRegions.data.i32[0]);
675    params.set(CameraParameters::KEY_METERING_AREAS,
676            "(0,0,0,0,0)");
677
678    zoom = 0;
679    params.set(CameraParameters::KEY_ZOOM, zoom);
680    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
681
682    camera_metadata_ro_entry_t maxDigitalZoom =
683        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, /*minCount*/1, /*maxCount*/1);
684    if (!maxDigitalZoom.count) return NO_INIT;
685
686    {
687        String8 zoomRatios;
688        float zoom = 1.f;
689        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
690                (NUM_ZOOM_STEPS-1);
691        bool addComma = false;
692        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
693            if (addComma) zoomRatios += ",";
694            addComma = true;
695            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
696            zoom += zoomIncrement;
697        }
698        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
699    }
700
701    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
702            CameraParameters::TRUE);
703    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
704            CameraParameters::TRUE);
705
706    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
707            "Infinity,Infinity,Infinity");
708
709    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
710            fastInfo.maxFaces);
711    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
712            0);
713
714    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
715            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
716
717    params.set(CameraParameters::KEY_RECORDING_HINT,
718            CameraParameters::FALSE);
719
720    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
721            CameraParameters::TRUE);
722
723    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
724            CameraParameters::FALSE);
725
726    camera_metadata_ro_entry_t availableVideoStabilizationModes =
727        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
728    if (!availableVideoStabilizationModes.count) return NO_INIT;
729
730    if (availableVideoStabilizationModes.count > 1) {
731        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
732                CameraParameters::TRUE);
733    } else {
734        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
735                CameraParameters::FALSE);
736    }
737
738    // Set up initial state for non-Camera.Parameters state variables
739
740    storeMetadataInBuffers = true;
741    playShutterSound = true;
742    enableFaceDetect = false;
743
744    enableFocusMoveMessages = false;
745    afTriggerCounter = 1;
746    currentAfTriggerId = -1;
747
748    precaptureTriggerCounter = 1;
749
750    previewCallbackFlags = 0;
751
752    char value[PROPERTY_VALUE_MAX];
753    property_get("camera.disable_zsl_mode", value, "0");
754    if (!strcmp(value,"1")) {
755        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
756        zslMode = false;
757    } else {
758        zslMode = true;
759    }
760
761    lightFx = LIGHTFX_NONE;
762
763    state = STOPPED;
764
765    paramsFlattened = params.flatten();
766
767    return OK;
768}
769
770status_t Parameters::buildFastInfo() {
771
772    camera_metadata_ro_entry_t activeArraySize =
773        staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
774    if (!activeArraySize.count) return NO_INIT;
775    int32_t arrayWidth = activeArraySize.data.i32[0];
776    int32_t arrayHeight = activeArraySize.data.i32[1];
777
778    camera_metadata_ro_entry_t availableFaceDetectModes =
779        staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
780    if (!availableFaceDetectModes.count) return NO_INIT;
781
782    uint8_t bestFaceDetectMode =
783        ANDROID_STATS_FACE_DETECTION_OFF;
784    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
785        switch (availableFaceDetectModes.data.u8[i]) {
786            case ANDROID_STATS_FACE_DETECTION_OFF:
787                break;
788            case ANDROID_STATS_FACE_DETECTION_SIMPLE:
789                if (bestFaceDetectMode !=
790                        ANDROID_STATS_FACE_DETECTION_FULL) {
791                    bestFaceDetectMode =
792                        ANDROID_STATS_FACE_DETECTION_SIMPLE;
793                }
794                break;
795            case ANDROID_STATS_FACE_DETECTION_FULL:
796                bestFaceDetectMode =
797                    ANDROID_STATS_FACE_DETECTION_FULL;
798                break;
799            default:
800                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
801                        __FUNCTION__, cameraId,
802                        availableFaceDetectModes.data.u8[i]);
803                return NO_INIT;
804        }
805    }
806
807    camera_metadata_ro_entry_t maxFacesDetected =
808        staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
809    if (!maxFacesDetected.count) return NO_INIT;
810
811    int32_t maxFaces = maxFacesDetected.data.i32[0];
812
813    fastInfo.arrayWidth = arrayWidth;
814    fastInfo.arrayHeight = arrayHeight;
815    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
816    fastInfo.maxFaces = maxFaces;
817    return OK;
818}
819
820camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
821        size_t minCount, size_t maxCount) const {
822    status_t res;
823    camera_metadata_ro_entry_t entry = info->find(tag);
824
825    if (CC_UNLIKELY( entry.count == 0 )) {
826        const char* tagSection = get_camera_metadata_section_name(tag);
827        if (tagSection == NULL) tagSection = "<unknown>";
828        const char* tagName = get_camera_metadata_tag_name(tag);
829        if (tagName == NULL) tagName = "<unknown>";
830
831        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
832                tagSection, tagName, tag);
833    } else if (CC_UNLIKELY(
834            (minCount != 0 && entry.count < minCount) ||
835            (maxCount != 0 && entry.count > maxCount) ) ) {
836        const char* tagSection = get_camera_metadata_section_name(tag);
837        if (tagSection == NULL) tagSection = "<unknown>";
838        const char* tagName = get_camera_metadata_tag_name(tag);
839        if (tagName == NULL) tagName = "<unknown>";
840        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
841                "Expected between %d and %d values, but got %d values",
842                tagSection, tagName, tag, minCount, maxCount, entry.count);
843    }
844
845    return entry;
846}
847
848status_t Parameters::set(const String8& params) {
849    status_t res;
850
851    CameraParameters newParams(params);
852
853    // TODO: Currently ignoring any changes to supposedly read-only parameters
854    // such as supported preview sizes, etc. Should probably produce an error if
855    // they're changed.
856
857    /** Extract and verify new parameters */
858
859    size_t i;
860
861    Parameters validatedParams(*this);
862
863    // PREVIEW_SIZE
864    newParams.getPreviewSize(&validatedParams.previewWidth,
865            &validatedParams.previewHeight);
866
867    if (validatedParams.previewWidth != previewWidth ||
868            validatedParams.previewHeight != previewHeight) {
869        if (state >= PREVIEW) {
870            ALOGE("%s: Preview size cannot be updated when preview "
871                    "is active! (Currently %d x %d, requested %d x %d",
872                    __FUNCTION__,
873                    previewWidth, previewHeight,
874                    validatedParams.previewWidth, validatedParams.previewHeight);
875            return BAD_VALUE;
876        }
877        camera_metadata_ro_entry_t availablePreviewSizes =
878            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
879        for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
880            if ((availablePreviewSizes.data.i32[i] ==
881                    validatedParams.previewWidth) &&
882                (availablePreviewSizes.data.i32[i+1] ==
883                    validatedParams.previewHeight)) break;
884        }
885        if (i == availablePreviewSizes.count) {
886            ALOGE("%s: Requested preview size %d x %d is not supported",
887                    __FUNCTION__, validatedParams.previewWidth,
888                    validatedParams.previewHeight);
889            return BAD_VALUE;
890        }
891    }
892
893    // PREVIEW_FPS_RANGE
894    bool fpsRangeChanged = false;
895    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
896            &validatedParams.previewFpsRange[1]);
897    if (validatedParams.previewFpsRange[0] != previewFpsRange[0] ||
898            validatedParams.previewFpsRange[1] != previewFpsRange[1]) {
899        fpsRangeChanged = true;
900        camera_metadata_ro_entry_t availablePreviewFpsRanges =
901            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
902        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
903            if ((availablePreviewFpsRanges.data.i32[i] ==
904                    validatedParams.previewFpsRange[0]) &&
905                (availablePreviewFpsRanges.data.i32[i+1] ==
906                    validatedParams.previewFpsRange[1]) ) {
907                break;
908            }
909        }
910        if (i == availablePreviewFpsRanges.count) {
911            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
912                __FUNCTION__, validatedParams.previewFpsRange[0],
913                    validatedParams.previewFpsRange[1]);
914            return BAD_VALUE;
915        }
916        validatedParams.previewFps = validatedParams.previewFpsRange[0];
917    }
918
919    // PREVIEW_FORMAT
920    validatedParams.previewFormat =
921            formatStringToEnum(newParams.getPreviewFormat());
922    if (validatedParams.previewFormat != previewFormat) {
923        if (state >= PREVIEW) {
924            ALOGE("%s: Preview format cannot be updated when preview "
925                    "is active!", __FUNCTION__);
926            return BAD_VALUE;
927        }
928        camera_metadata_ro_entry_t availableFormats =
929            staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
930        for (i = 0; i < availableFormats.count; i++) {
931            if (availableFormats.data.i32[i] == validatedParams.previewFormat)
932                break;
933        }
934        if (i == availableFormats.count) {
935            ALOGE("%s: Requested preview format %s (0x%x) is not supported",
936                    __FUNCTION__, newParams.getPreviewFormat(),
937                    validatedParams.previewFormat);
938            return BAD_VALUE;
939        }
940    }
941
942    // PREVIEW_FRAME_RATE
943    // Deprecated, only use if the preview fps range is unchanged this time.
944    // The single-value FPS is the same as the minimum of the range.
945    if (!fpsRangeChanged) {
946        validatedParams.previewFps = newParams.getPreviewFrameRate();
947        if (validatedParams.previewFps != previewFps) {
948            camera_metadata_ro_entry_t availableFrameRates =
949                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
950            for (i = 0; i < availableFrameRates.count; i+=2) {
951                if (availableFrameRates.data.i32[i] ==
952                        validatedParams.previewFps) break;
953            }
954            if (i == availableFrameRates.count) {
955                ALOGE("%s: Requested preview frame rate %d is not supported",
956                        __FUNCTION__, validatedParams.previewFps);
957                return BAD_VALUE;
958            }
959            validatedParams.previewFpsRange[0] =
960                    availableFrameRates.data.i32[i];
961            validatedParams.previewFpsRange[1] =
962                    availableFrameRates.data.i32[i+1];
963        }
964    }
965
966    // PICTURE_SIZE
967    newParams.getPictureSize(&validatedParams.pictureWidth,
968            &validatedParams.pictureHeight);
969    if (validatedParams.pictureWidth == pictureWidth ||
970            validatedParams.pictureHeight == pictureHeight) {
971        camera_metadata_ro_entry_t availablePictureSizes =
972            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
973        for (i = 0; i < availablePictureSizes.count; i+=2) {
974            if ((availablePictureSizes.data.i32[i] ==
975                    validatedParams.pictureWidth) &&
976                (availablePictureSizes.data.i32[i+1] ==
977                    validatedParams.pictureHeight)) break;
978        }
979        if (i == availablePictureSizes.count) {
980            ALOGE("%s: Requested picture size %d x %d is not supported",
981                    __FUNCTION__, validatedParams.pictureWidth,
982                    validatedParams.pictureHeight);
983            return BAD_VALUE;
984        }
985    }
986
987    // JPEG_THUMBNAIL_WIDTH/HEIGHT
988    validatedParams.jpegThumbSize[0] =
989            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
990    validatedParams.jpegThumbSize[1] =
991            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
992    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
993            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
994        camera_metadata_ro_entry_t availableJpegThumbSizes =
995            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
996        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
997            if ((availableJpegThumbSizes.data.i32[i] ==
998                    validatedParams.jpegThumbSize[0]) &&
999                (availableJpegThumbSizes.data.i32[i+1] ==
1000                    validatedParams.jpegThumbSize[1])) break;
1001        }
1002        if (i == availableJpegThumbSizes.count) {
1003            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1004                    __FUNCTION__, validatedParams.jpegThumbSize[0],
1005                    validatedParams.jpegThumbSize[1]);
1006            return BAD_VALUE;
1007        }
1008    }
1009
1010    // JPEG_THUMBNAIL_QUALITY
1011    validatedParams.jpegThumbQuality =
1012            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1013    if (validatedParams.jpegThumbQuality < 0 ||
1014            validatedParams.jpegThumbQuality > 100) {
1015        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1016                __FUNCTION__, validatedParams.jpegThumbQuality);
1017        return BAD_VALUE;
1018    }
1019
1020    // JPEG_QUALITY
1021    validatedParams.jpegQuality =
1022            newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1023    if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
1024        ALOGE("%s: Requested JPEG quality %d is not supported",
1025                __FUNCTION__, validatedParams.jpegQuality);
1026        return BAD_VALUE;
1027    }
1028
1029    // ROTATION
1030    validatedParams.jpegRotation =
1031            newParams.getInt(CameraParameters::KEY_ROTATION);
1032    if (validatedParams.jpegRotation != 0 &&
1033            validatedParams.jpegRotation != 90 &&
1034            validatedParams.jpegRotation != 180 &&
1035            validatedParams.jpegRotation != 270) {
1036        ALOGE("%s: Requested picture rotation angle %d is not supported",
1037                __FUNCTION__, validatedParams.jpegRotation);
1038        return BAD_VALUE;
1039    }
1040
1041    // GPS
1042
1043    const char *gpsLatStr =
1044            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1045    if (gpsLatStr != NULL) {
1046        const char *gpsLongStr =
1047                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1048        const char *gpsAltitudeStr =
1049                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1050        const char *gpsTimeStr =
1051                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1052        const char *gpsProcMethodStr =
1053                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1054        if (gpsLongStr == NULL ||
1055                gpsAltitudeStr == NULL ||
1056                gpsTimeStr == NULL ||
1057                gpsProcMethodStr == NULL) {
1058            ALOGE("%s: Incomplete set of GPS parameters provided",
1059                    __FUNCTION__);
1060            return BAD_VALUE;
1061        }
1062        char *endPtr;
1063        errno = 0;
1064        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1065        if (errno || endPtr == gpsLatStr) {
1066            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1067            return BAD_VALUE;
1068        }
1069        errno = 0;
1070        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1071        if (errno || endPtr == gpsLongStr) {
1072            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1073            return BAD_VALUE;
1074        }
1075        errno = 0;
1076        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1077        if (errno || endPtr == gpsAltitudeStr) {
1078            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1079                    gpsAltitudeStr);
1080            return BAD_VALUE;
1081        }
1082        errno = 0;
1083        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1084        if (errno || endPtr == gpsTimeStr) {
1085            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1086            return BAD_VALUE;
1087        }
1088        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1089
1090        validatedParams.gpsEnabled = true;
1091    } else {
1092        validatedParams.gpsEnabled = false;
1093    }
1094
1095    // WHITE_BALANCE
1096    validatedParams.wbMode = wbModeStringToEnum(
1097        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1098    if (validatedParams.wbMode != wbMode) {
1099        camera_metadata_ro_entry_t availableWbModes =
1100            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1101        for (i = 0; i < availableWbModes.count; i++) {
1102            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1103        }
1104        if (i == availableWbModes.count) {
1105            ALOGE("%s: Requested white balance mode %s is not supported",
1106                    __FUNCTION__,
1107                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1108            return BAD_VALUE;
1109        }
1110    }
1111
1112    // EFFECT
1113    validatedParams.effectMode = effectModeStringToEnum(
1114        newParams.get(CameraParameters::KEY_EFFECT) );
1115    if (validatedParams.effectMode != effectMode) {
1116        camera_metadata_ro_entry_t availableEffectModes =
1117            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1118        for (i = 0; i < availableEffectModes.count; i++) {
1119            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1120        }
1121        if (i == availableEffectModes.count) {
1122            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1123                    __FUNCTION__,
1124                    newParams.get(CameraParameters::KEY_EFFECT) );
1125            return BAD_VALUE;
1126        }
1127    }
1128
1129    // ANTIBANDING
1130    validatedParams.antibandingMode = abModeStringToEnum(
1131        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1132    if (validatedParams.antibandingMode != antibandingMode) {
1133        camera_metadata_ro_entry_t availableAbModes =
1134            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1135        for (i = 0; i < availableAbModes.count; i++) {
1136            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1137                break;
1138        }
1139        if (i == availableAbModes.count) {
1140            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1141                    __FUNCTION__,
1142                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1143            return BAD_VALUE;
1144        }
1145    }
1146
1147    // SCENE_MODE
1148    validatedParams.sceneMode = sceneModeStringToEnum(
1149        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1150    if (validatedParams.sceneMode != sceneMode &&
1151            validatedParams.sceneMode !=
1152            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1153        camera_metadata_ro_entry_t availableSceneModes =
1154            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1155        for (i = 0; i < availableSceneModes.count; i++) {
1156            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1157                break;
1158        }
1159        if (i == availableSceneModes.count) {
1160            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1161                    __FUNCTION__,
1162                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1163            return BAD_VALUE;
1164        }
1165    }
1166
1167    // FLASH_MODE
1168    validatedParams.flashMode = flashModeStringToEnum(
1169        newParams.get(CameraParameters::KEY_FLASH_MODE) );
1170    if (validatedParams.flashMode != flashMode) {
1171        camera_metadata_ro_entry_t flashAvailable =
1172            staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1173        if (!flashAvailable.data.u8[0] &&
1174                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1175            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1176                    "No flash on device", __FUNCTION__,
1177                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1178            return BAD_VALUE;
1179        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1180            camera_metadata_ro_entry_t availableAeModes =
1181                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1182            for (i = 0; i < availableAeModes.count; i++) {
1183                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1184                    break;
1185            }
1186            if (i == availableAeModes.count) {
1187                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1188                        __FUNCTION__,
1189                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1190                return BAD_VALUE;
1191            }
1192        } else if (validatedParams.flashMode == -1) {
1193            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1194                    __FUNCTION__,
1195                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1196            return BAD_VALUE;
1197        }
1198    }
1199
1200    // FOCUS_MODE
1201    validatedParams.focusMode = focusModeStringToEnum(
1202        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1203    if (validatedParams.focusMode != focusMode) {
1204        validatedParams.currentAfTriggerId = -1;
1205        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1206            camera_metadata_ro_entry_t minFocusDistance =
1207                staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1208            if (minFocusDistance.data.f[0] == 0) {
1209                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1210                        "fixed focus lens",
1211                        __FUNCTION__,
1212                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1213                return BAD_VALUE;
1214            } else if (validatedParams.focusMode !=
1215                    Parameters::FOCUS_MODE_INFINITY) {
1216                camera_metadata_ro_entry_t availableFocusModes =
1217                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1218                for (i = 0; i < availableFocusModes.count; i++) {
1219                    if (validatedParams.focusMode ==
1220                            availableFocusModes.data.u8[i]) break;
1221                }
1222                if (i == availableFocusModes.count) {
1223                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1224                            __FUNCTION__,
1225                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1226                    return BAD_VALUE;
1227                }
1228            }
1229        }
1230    } else {
1231        validatedParams.currentAfTriggerId = currentAfTriggerId;
1232    }
1233
1234    // FOCUS_AREAS
1235    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1236            &validatedParams.focusingAreas);
1237    size_t max3aRegions =
1238        (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1239    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1240            max3aRegions);
1241    if (res != OK) {
1242        ALOGE("%s: Requested focus areas are malformed: %s",
1243                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1244        return BAD_VALUE;
1245    }
1246
1247    // EXPOSURE_COMPENSATION
1248    validatedParams.exposureCompensation =
1249        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1250    camera_metadata_ro_entry_t exposureCompensationRange =
1251        staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1252    if ((validatedParams.exposureCompensation <
1253            exposureCompensationRange.data.i32[0]) ||
1254        (validatedParams.exposureCompensation >
1255            exposureCompensationRange.data.i32[1])) {
1256        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1257                __FUNCTION__, validatedParams.exposureCompensation);
1258        return BAD_VALUE;
1259    }
1260
1261    // AUTO_EXPOSURE_LOCK (always supported)
1262    validatedParams.autoExposureLock = boolFromString(
1263        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1264
1265    // AUTO_WHITEBALANCE_LOCK (always supported)
1266    validatedParams.autoWhiteBalanceLock = boolFromString(
1267        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1268
1269    // METERING_AREAS
1270    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1271            &validatedParams.meteringAreas);
1272    if (res == OK) {
1273        res = validateAreas(validatedParams.meteringAreas, max3aRegions);
1274    }
1275    if (res != OK) {
1276        ALOGE("%s: Requested metering areas are malformed: %s",
1277                __FUNCTION__,
1278                newParams.get(CameraParameters::KEY_METERING_AREAS));
1279        return BAD_VALUE;
1280    }
1281
1282    // ZOOM
1283    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1284    if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
1285        ALOGE("%s: Requested zoom level %d is not supported",
1286                __FUNCTION__, validatedParams.zoom);
1287        return BAD_VALUE;
1288    }
1289
1290    // VIDEO_SIZE
1291    newParams.getVideoSize(&validatedParams.videoWidth,
1292            &validatedParams.videoHeight);
1293    if (validatedParams.videoWidth != videoWidth ||
1294            validatedParams.videoHeight != videoHeight) {
1295        if (state == RECORD) {
1296            ALOGE("%s: Video size cannot be updated when recording is active!",
1297                    __FUNCTION__);
1298            return BAD_VALUE;
1299        }
1300        camera_metadata_ro_entry_t availableVideoSizes =
1301            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1302        for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1303            if ((availableVideoSizes.data.i32[i] ==
1304                    validatedParams.videoWidth) &&
1305                (availableVideoSizes.data.i32[i+1] ==
1306                    validatedParams.videoHeight)) break;
1307        }
1308        if (i == availableVideoSizes.count) {
1309            ALOGE("%s: Requested video size %d x %d is not supported",
1310                    __FUNCTION__, validatedParams.videoWidth,
1311                    validatedParams.videoHeight);
1312            return BAD_VALUE;
1313        }
1314    }
1315
1316    // RECORDING_HINT (always supported)
1317    validatedParams.recordingHint = boolFromString(
1318        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1319
1320    // VIDEO_STABILIZATION
1321    validatedParams.videoStabilization = boolFromString(
1322        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1323    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1324        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1325    if (validatedParams.videoStabilization &&
1326            availableVideoStabilizationModes.count == 1) {
1327        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1328    }
1329
1330    // LIGHTFX
1331    validatedParams.lightFx = lightFxStringToEnum(
1332        newParams.get(CameraParameters::KEY_LIGHTFX));
1333
1334    /** Update internal parameters */
1335
1336    validatedParams.paramsFlattened = params;
1337    *this = validatedParams;
1338
1339    return OK;
1340}
1341
1342status_t Parameters::updateRequest(CameraMetadata *request) const {
1343    ATRACE_CALL();
1344    status_t res;
1345
1346    uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
1347    res = request->update(ANDROID_REQUEST_METADATA_MODE,
1348            &metadataMode, 1);
1349    if (res != OK) return res;
1350
1351    res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1352            previewFpsRange, 2);
1353    if (res != OK) return res;
1354
1355    res = request->update(ANDROID_CONTROL_AWB_MODE,
1356            &wbMode, 1);
1357    if (res != OK) return res;
1358
1359    uint8_t reqWbLock = autoWhiteBalanceLock ?
1360            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1361    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1362            &reqWbLock, 1);
1363
1364    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1365            &effectMode, 1);
1366    if (res != OK) return res;
1367    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1368            &antibandingMode, 1);
1369    if (res != OK) return res;
1370
1371    // android.hardware.Camera requires that when face detect is enabled, the
1372    // camera is in a face-priority mode. HAL2 splits this into separate parts
1373    // (face detection statistics and face priority scene mode). Map from other
1374    // to the other.
1375    uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
1376    if (enableFaceDetect || sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1377        reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
1378    }
1379    res = request->update(ANDROID_CONTROL_MODE,
1380            &reqControlMode, 1);
1381    if (res != OK) return res;
1382
1383    uint8_t reqSceneMode =
1384            (sceneMode !=
1385                    (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ? sceneMode :
1386            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1387            (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
1388    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1389            &reqSceneMode, 1);
1390    if (res != OK) return res;
1391
1392    uint8_t reqFlashMode = ANDROID_FLASH_OFF;
1393    uint8_t reqAeMode;
1394    switch (flashMode) {
1395        case Parameters::FLASH_MODE_OFF:
1396            reqAeMode = ANDROID_CONTROL_AE_ON; break;
1397        case Parameters::FLASH_MODE_AUTO:
1398            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
1399        case Parameters::FLASH_MODE_ON:
1400            reqAeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
1401        case Parameters::FLASH_MODE_TORCH:
1402            reqAeMode = ANDROID_CONTROL_AE_ON;
1403            reqFlashMode = ANDROID_FLASH_TORCH;
1404            break;
1405        case Parameters::FLASH_MODE_RED_EYE:
1406            reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
1407        default:
1408            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1409                    cameraId, flashMode);
1410            return BAD_VALUE;
1411    }
1412    res = request->update(ANDROID_FLASH_MODE,
1413            &reqFlashMode, 1);
1414    if (res != OK) return res;
1415    res = request->update(ANDROID_CONTROL_AE_MODE,
1416            &reqAeMode, 1);
1417    if (res != OK) return res;
1418
1419    uint8_t reqAeLock = autoExposureLock ?
1420            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1421    res = request->update(ANDROID_CONTROL_AE_LOCK,
1422            &reqAeLock, 1);
1423
1424    float reqFocusDistance = 0; // infinity focus in diopters
1425    uint8_t reqFocusMode;
1426    switch (focusMode) {
1427        case Parameters::FOCUS_MODE_AUTO:
1428        case Parameters::FOCUS_MODE_MACRO:
1429        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1430        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1431        case Parameters::FOCUS_MODE_EDOF:
1432            reqFocusMode = focusMode;
1433            break;
1434        case Parameters::FOCUS_MODE_INFINITY:
1435        case Parameters::FOCUS_MODE_FIXED:
1436            reqFocusMode = ANDROID_CONTROL_AF_OFF;
1437            break;
1438        default:
1439            ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1440                    cameraId, focusMode);
1441            return BAD_VALUE;
1442    }
1443    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1444            &reqFocusDistance, 1);
1445    if (res != OK) return res;
1446    res = request->update(ANDROID_CONTROL_AF_MODE,
1447            &reqFocusMode, 1);
1448    if (res != OK) return res;
1449
1450    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1451    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1452    for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
1453        if (focusingAreas[i].weight != 0) {
1454            reqFocusingAreas[i + 0] =
1455                    normalizedXToArray(focusingAreas[i].left);
1456            reqFocusingAreas[i + 1] =
1457                    normalizedYToArray(focusingAreas[i].top);
1458            reqFocusingAreas[i + 2] =
1459                    normalizedXToArray(focusingAreas[i].right);
1460            reqFocusingAreas[i + 3] =
1461                    normalizedYToArray(focusingAreas[i].bottom);
1462        } else {
1463            reqFocusingAreas[i + 0] = 0;
1464            reqFocusingAreas[i + 1] = 0;
1465            reqFocusingAreas[i + 2] = 0;
1466            reqFocusingAreas[i + 3] = 0;
1467        }
1468        reqFocusingAreas[i + 4] = focusingAreas[i].weight;
1469    }
1470    res = request->update(ANDROID_CONTROL_AF_REGIONS,
1471            reqFocusingAreas, reqFocusingAreasSize);
1472    if (res != OK) return res;
1473    delete[] reqFocusingAreas;
1474
1475    res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
1476            &exposureCompensation, 1);
1477    if (res != OK) return res;
1478
1479    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1480    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1481    for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
1482        if (meteringAreas[i].weight != 0) {
1483            reqMeteringAreas[i + 0] =
1484                normalizedXToArray(meteringAreas[i].left);
1485            reqMeteringAreas[i + 1] =
1486                normalizedYToArray(meteringAreas[i].top);
1487            reqMeteringAreas[i + 2] =
1488                normalizedXToArray(meteringAreas[i].right);
1489            reqMeteringAreas[i + 3] =
1490                normalizedYToArray(meteringAreas[i].bottom);
1491        } else {
1492            reqMeteringAreas[i + 0] = 0;
1493            reqMeteringAreas[i + 1] = 0;
1494            reqMeteringAreas[i + 2] = 0;
1495            reqMeteringAreas[i + 3] = 0;
1496        }
1497        reqMeteringAreas[i + 4] = meteringAreas[i].weight;
1498    }
1499    res = request->update(ANDROID_CONTROL_AE_REGIONS,
1500            reqMeteringAreas, reqMeteringAreasSize);
1501    if (res != OK) return res;
1502
1503    res = request->update(ANDROID_CONTROL_AWB_REGIONS,
1504            reqMeteringAreas, reqMeteringAreasSize);
1505    if (res != OK) return res;
1506    delete[] reqMeteringAreas;
1507
1508    CropRegion crop = calculateCropRegion();
1509    int32_t reqCropRegion[3] = { crop.left, crop.top, crop.width };
1510    res = request->update(ANDROID_SCALER_CROP_REGION,
1511            reqCropRegion, 3);
1512    if (res != OK) return res;
1513
1514    uint8_t reqVstabMode = videoStabilization ?
1515            ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
1516            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
1517    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1518            &reqVstabMode, 1);
1519    if (res != OK) return res;
1520
1521    uint8_t reqFaceDetectMode = enableFaceDetect ?
1522            fastInfo.bestFaceDetectMode :
1523            (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
1524    res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
1525            &reqFaceDetectMode, 1);
1526    if (res != OK) return res;
1527
1528    return OK;
1529}
1530
1531const char* Parameters::getStateName(State state) {
1532#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1533    switch(state) {
1534        CASE_ENUM_TO_CHAR(DISCONNECTED)
1535        CASE_ENUM_TO_CHAR(STOPPED)
1536        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1537        CASE_ENUM_TO_CHAR(PREVIEW)
1538        CASE_ENUM_TO_CHAR(RECORD)
1539        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
1540        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
1541        default:
1542            return "Unknown state!";
1543            break;
1544    }
1545#undef CASE_ENUM_TO_CHAR
1546}
1547
1548int Parameters::formatStringToEnum(const char *format) {
1549    return
1550        !format ?
1551            HAL_PIXEL_FORMAT_YCrCb_420_SP :
1552        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
1553            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
1554        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
1555            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
1556        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
1557            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
1558        !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
1559            HAL_PIXEL_FORMAT_YV12 :         // YV12
1560        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
1561            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
1562        !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
1563            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
1564        !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
1565            HAL_PIXEL_FORMAT_RAW_SENSOR :   // Raw sensor data
1566        -1;
1567}
1568
1569const char* Parameters::formatEnumToString(int format) {
1570    const char *fmt;
1571    switch(format) {
1572        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1573            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
1574            break;
1575        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1576            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
1577            break;
1578        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1579            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
1580            break;
1581        case HAL_PIXEL_FORMAT_YV12:        // YV12
1582            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
1583            break;
1584        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
1585            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
1586            break;
1587        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
1588            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
1589            break;
1590        case HAL_PIXEL_FORMAT_RAW_SENSOR:
1591            ALOGW("Raw sensor preview format requested.");
1592            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
1593            break;
1594        default:
1595            ALOGE("%s: Unknown preview format: %x",
1596                    __FUNCTION__,  format);
1597            fmt = NULL;
1598            break;
1599    }
1600    return fmt;
1601}
1602
1603int Parameters::wbModeStringToEnum(const char *wbMode) {
1604    return
1605        !wbMode ?
1606            ANDROID_CONTROL_AWB_AUTO :
1607        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
1608            ANDROID_CONTROL_AWB_AUTO :
1609        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
1610            ANDROID_CONTROL_AWB_INCANDESCENT :
1611        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
1612            ANDROID_CONTROL_AWB_FLUORESCENT :
1613        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
1614            ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
1615        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
1616            ANDROID_CONTROL_AWB_DAYLIGHT :
1617        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
1618            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
1619        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
1620            ANDROID_CONTROL_AWB_TWILIGHT :
1621        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
1622            ANDROID_CONTROL_AWB_SHADE :
1623        -1;
1624}
1625
1626int Parameters::effectModeStringToEnum(const char *effectMode) {
1627    return
1628        !effectMode ?
1629            ANDROID_CONTROL_EFFECT_OFF :
1630        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
1631            ANDROID_CONTROL_EFFECT_OFF :
1632        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
1633            ANDROID_CONTROL_EFFECT_MONO :
1634        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
1635            ANDROID_CONTROL_EFFECT_NEGATIVE :
1636        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
1637            ANDROID_CONTROL_EFFECT_SOLARIZE :
1638        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
1639            ANDROID_CONTROL_EFFECT_SEPIA :
1640        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
1641            ANDROID_CONTROL_EFFECT_POSTERIZE :
1642        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
1643            ANDROID_CONTROL_EFFECT_WHITEBOARD :
1644        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
1645            ANDROID_CONTROL_EFFECT_BLACKBOARD :
1646        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
1647            ANDROID_CONTROL_EFFECT_AQUA :
1648        -1;
1649}
1650
1651int Parameters::abModeStringToEnum(const char *abMode) {
1652    return
1653        !abMode ?
1654            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1655        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
1656            ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1657        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
1658            ANDROID_CONTROL_AE_ANTIBANDING_OFF :
1659        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
1660            ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
1661        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
1662            ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
1663        -1;
1664}
1665
1666int Parameters::sceneModeStringToEnum(const char *sceneMode) {
1667    return
1668        !sceneMode ?
1669            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1670        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
1671            ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1672        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
1673            ANDROID_CONTROL_SCENE_MODE_ACTION :
1674        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
1675            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
1676        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
1677            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
1678        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
1679            ANDROID_CONTROL_SCENE_MODE_NIGHT :
1680        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
1681            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
1682        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
1683            ANDROID_CONTROL_SCENE_MODE_THEATRE :
1684        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
1685            ANDROID_CONTROL_SCENE_MODE_BEACH :
1686        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
1687            ANDROID_CONTROL_SCENE_MODE_SNOW :
1688        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
1689            ANDROID_CONTROL_SCENE_MODE_SUNSET :
1690        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
1691            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
1692        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
1693            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
1694        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
1695            ANDROID_CONTROL_SCENE_MODE_SPORTS :
1696        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
1697            ANDROID_CONTROL_SCENE_MODE_PARTY :
1698        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
1699            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
1700        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
1701            ANDROID_CONTROL_SCENE_MODE_BARCODE:
1702        -1;
1703}
1704
1705Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
1706        const char *flashMode) {
1707    return
1708        !flashMode ?
1709            Parameters::FLASH_MODE_INVALID :
1710        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
1711            Parameters::FLASH_MODE_OFF :
1712        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
1713            Parameters::FLASH_MODE_AUTO :
1714        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
1715            Parameters::FLASH_MODE_ON :
1716        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
1717            Parameters::FLASH_MODE_RED_EYE :
1718        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
1719            Parameters::FLASH_MODE_TORCH :
1720        Parameters::FLASH_MODE_INVALID;
1721}
1722
1723Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
1724        const char *focusMode) {
1725    return
1726        !focusMode ?
1727            Parameters::FOCUS_MODE_INVALID :
1728        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
1729            Parameters::FOCUS_MODE_AUTO :
1730        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
1731            Parameters::FOCUS_MODE_INFINITY :
1732        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
1733            Parameters::FOCUS_MODE_MACRO :
1734        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
1735            Parameters::FOCUS_MODE_FIXED :
1736        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
1737            Parameters::FOCUS_MODE_EDOF :
1738        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
1739            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
1740        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
1741            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
1742        Parameters::FOCUS_MODE_INVALID;
1743}
1744
1745Parameters::Parameters::lightFxMode_t Parameters::lightFxStringToEnum(
1746        const char *lightFxMode) {
1747    return
1748        !lightFxMode ?
1749            Parameters::LIGHTFX_NONE :
1750        !strcmp(lightFxMode, CameraParameters::LIGHTFX_LOWLIGHT) ?
1751            Parameters::LIGHTFX_LOWLIGHT :
1752        !strcmp(lightFxMode, CameraParameters::LIGHTFX_HDR) ?
1753            Parameters::LIGHTFX_HDR :
1754        Parameters::LIGHTFX_NONE;
1755}
1756
1757status_t Parameters::parseAreas(const char *areasCStr,
1758        Vector<Parameters::Area> *areas) {
1759    static const size_t NUM_FIELDS = 5;
1760    areas->clear();
1761    if (areasCStr == NULL) {
1762        // If no key exists, use default (0,0,0,0,0)
1763        areas->push();
1764        return OK;
1765    }
1766    String8 areasStr(areasCStr);
1767    ssize_t areaStart = areasStr.find("(", 0) + 1;
1768    while (areaStart != 0) {
1769        const char* area = areasStr.string() + areaStart;
1770        char *numEnd;
1771        int vals[NUM_FIELDS];
1772        for (size_t i = 0; i < NUM_FIELDS; i++) {
1773            errno = 0;
1774            vals[i] = strtol(area, &numEnd, 10);
1775            if (errno || numEnd == area) return BAD_VALUE;
1776            area = numEnd + 1;
1777        }
1778        areas->push(Parameters::Area(
1779            vals[0], vals[1], vals[2], vals[3], vals[4]) );
1780        areaStart = areasStr.find("(", areaStart) + 1;
1781    }
1782    return OK;
1783}
1784
1785status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
1786                                      size_t maxRegions) {
1787    // Definition of valid area can be found in
1788    // include/camera/CameraParameters.h
1789    if (areas.size() == 0) return BAD_VALUE;
1790    if (areas.size() == 1) {
1791        if (areas[0].left == 0 &&
1792                areas[0].top == 0 &&
1793                areas[0].right == 0 &&
1794                areas[0].bottom == 0 &&
1795                areas[0].weight == 0) {
1796            // Single (0,0,0,0,0) entry is always valid (== driver decides)
1797            return OK;
1798        }
1799    }
1800    if (areas.size() > maxRegions) {
1801        ALOGE("%s: Too many areas requested: %d",
1802                __FUNCTION__, areas.size());
1803        return BAD_VALUE;
1804    }
1805
1806    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
1807         a != areas.end(); a++) {
1808        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
1809        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
1810        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
1811        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
1812        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
1813        if (a->left >= a->right) return BAD_VALUE;
1814        if (a->top >= a->bottom) return BAD_VALUE;
1815    }
1816    return OK;
1817}
1818
1819bool Parameters::boolFromString(const char *boolStr) {
1820    return !boolStr ? false :
1821        !strcmp(boolStr, CameraParameters::TRUE) ? true :
1822        false;
1823}
1824
1825int Parameters::degToTransform(int degrees, bool mirror) {
1826    if (!mirror) {
1827        if (degrees == 0) return 0;
1828        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
1829        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
1830        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1831    } else {  // Do mirror (horizontal flip)
1832        if (degrees == 0) {           // FLIP_H and ROT_0
1833            return HAL_TRANSFORM_FLIP_H;
1834        } else if (degrees == 90) {   // FLIP_H and ROT_90
1835            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1836        } else if (degrees == 180) {  // FLIP_H and ROT_180
1837            return HAL_TRANSFORM_FLIP_V;
1838        } else if (degrees == 270) {  // FLIP_H and ROT_270
1839            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1840        }
1841    }
1842    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
1843    return -1;
1844}
1845
1846int Parameters::arrayXToNormalized(int width) const {
1847    return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
1848}
1849
1850int Parameters::arrayYToNormalized(int height) const {
1851    return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
1852}
1853
1854int Parameters::normalizedXToArray(int x) const {
1855    return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
1856}
1857
1858int Parameters::normalizedYToArray(int y) const {
1859    return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
1860}
1861
1862Parameters::CropRegion Parameters::calculateCropRegion(void) const {
1863
1864    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
1865
1866    // Need to convert zoom index into a crop rectangle. The rectangle is
1867    // chosen to maximize its area on the sensor
1868
1869    camera_metadata_ro_entry_t maxDigitalZoom =
1870            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
1871    // For each zoom step by how many pixels more do we change the zoom
1872    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
1873            (NUM_ZOOM_STEPS-1);
1874    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
1875    // via interpolating zoom step into a zoom ratio
1876    float zoomRatio = 1 + zoomIncrement * zoom;
1877    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
1878        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
1879        maxDigitalZoom.data.f[0], zoomRatio);
1880
1881    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
1882          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
1883          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
1884          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
1885
1886    /*
1887     * Assumption: On the HAL side each stream buffer calculates its crop
1888     * rectangle as follows:
1889     *   cropRect = (zoomLeft, zoomRight,
1890     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
1891     *
1892     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
1893     *      (we can then get into trouble if the cropHeight > arrayHeight).
1894     * By selecting the zoomRatio based on the smallest outputRatio, we
1895     * guarantee this will never happen.
1896     */
1897
1898    // Enumerate all possible output sizes, select the one with the smallest
1899    // aspect ratio
1900    float minOutputWidth, minOutputHeight, minOutputRatio;
1901    {
1902        float outputSizes[][2] = {
1903            { previewWidth,     previewHeight },
1904            { videoWidth,       videoHeight },
1905            /* don't include jpeg thumbnail size - it's valid for
1906               it to be set to (0,0), meaning 'no thumbnail' */
1907        //  { jpegThumbSize[0], jpegThumbSize[1] },
1908            { pictureWidth,     pictureHeight },
1909        };
1910
1911        minOutputWidth = outputSizes[0][0];
1912        minOutputHeight = outputSizes[0][1];
1913        minOutputRatio = minOutputWidth / minOutputHeight;
1914        for (unsigned int i = 0;
1915             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
1916             ++i) {
1917
1918            float outputWidth = outputSizes[i][0];
1919            float outputHeight = outputSizes[i][1];
1920            float outputRatio = outputWidth / outputHeight;
1921
1922            if (minOutputRatio > outputRatio) {
1923                minOutputRatio = outputRatio;
1924                minOutputWidth = outputWidth;
1925                minOutputHeight = outputHeight;
1926            }
1927
1928            // and then use this output ratio instead of preview output ratio
1929            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
1930                  outputRatio, outputWidth, outputHeight, minOutputRatio);
1931        }
1932    }
1933
1934    /* Ensure that the width/height never go out of bounds
1935     * by scaling across a diffent dimension if an out-of-bounds
1936     * possibility exists.
1937     *
1938     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
1939     * calculating the zoomWidth from zoomHeight we'll actually get a
1940     * zoomheight > arrayheight
1941     */
1942    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
1943    if (minOutputRatio >= arrayRatio) {
1944        // Adjust the height based on the width
1945        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
1946        zoomHeight = zoomWidth *
1947                minOutputHeight / minOutputWidth;
1948
1949    } else {
1950        // Adjust the width based on the height
1951        zoomHeight = fastInfo.arrayHeight / zoomRatio;
1952        zoomWidth = zoomHeight *
1953                minOutputWidth / minOutputHeight;
1954    }
1955    // centering the zoom area within the active area
1956    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
1957    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
1958
1959    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
1960        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
1961
1962
1963    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
1964    return crop;
1965}
1966
1967}; // namespace camera2
1968}; // namespace android
1969