Parameters.cpp revision a4c95a6bc3b801bf41ca841440e9124f947e53fe
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#include <utils/Vector.h>
24#include <utils/SortedVector.h>
25
26#include <math.h>
27#include <stdlib.h>
28#include <cutils/properties.h>
29
30#include "Parameters.h"
31#include "system/camera.h"
32#include "hardware/camera_common.h"
33#include <media/MediaProfiles.h>
34#include <media/mediarecorder.h>
35
36namespace android {
37namespace camera2 {
38
39Parameters::Parameters(int cameraId,
40        int cameraFacing) :
41        cameraId(cameraId),
42        cameraFacing(cameraFacing),
43        info(NULL) {
44}
45
46Parameters::~Parameters() {
47}
48
49status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {
50    status_t res;
51
52    if (info->entryCount() == 0) {
53        ALOGE("%s: No static information provided!", __FUNCTION__);
54        return BAD_VALUE;
55    }
56    Parameters::info = info;
57    mDeviceVersion = deviceVersion;
58
59    res = buildFastInfo();
60    if (res != OK) return res;
61
62    res = buildQuirks();
63    if (res != OK) return res;
64
65    const Size MAX_PREVIEW_SIZE = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
66    // Treat the H.264 max size as the max supported video size.
67    MediaProfiles *videoEncoderProfiles = MediaProfiles::getInstance();
68    int32_t maxVideoWidth = videoEncoderProfiles->getVideoEncoderParamByName(
69                            "enc.vid.width.max", VIDEO_ENCODER_H264);
70    int32_t maxVideoHeight = videoEncoderProfiles->getVideoEncoderParamByName(
71                            "enc.vid.height.max", VIDEO_ENCODER_H264);
72    const Size MAX_VIDEO_SIZE = {maxVideoWidth, maxVideoHeight};
73
74    res = getFilteredSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
75    if (res != OK) return res;
76    res = getFilteredSizes(MAX_VIDEO_SIZE, &availableVideoSizes);
77    if (res != OK) return res;
78
79    // Select initial preview and video size that's under the initial bound and
80    // on the list of both preview and recording sizes
81    previewWidth = 0;
82    previewHeight = 0;
83    for (size_t i = 0 ; i < availablePreviewSizes.size(); i++) {
84        int newWidth = availablePreviewSizes[i].width;
85        int newHeight = availablePreviewSizes[i].height;
86        if (newWidth >= previewWidth && newHeight >= previewHeight &&
87                newWidth <= MAX_INITIAL_PREVIEW_WIDTH &&
88                newHeight <= MAX_INITIAL_PREVIEW_HEIGHT) {
89            for (size_t j = 0; j < availableVideoSizes.size(); j++) {
90                if (availableVideoSizes[j].width == newWidth &&
91                        availableVideoSizes[j].height == newHeight) {
92                    previewWidth = newWidth;
93                    previewHeight = newHeight;
94                }
95            }
96        }
97    }
98    if (previewWidth == 0) {
99        ALOGE("%s: No initial preview size can be found!", __FUNCTION__);
100        return BAD_VALUE;
101    }
102    videoWidth = previewWidth;
103    videoHeight = previewHeight;
104
105    params.setPreviewSize(previewWidth, previewHeight);
106    params.setVideoSize(videoWidth, videoHeight);
107    params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
108            String8::format("%dx%d",
109                    previewWidth, previewHeight));
110    {
111        String8 supportedPreviewSizes;
112        for (size_t i = 0; i < availablePreviewSizes.size(); i++) {
113            if (i != 0) supportedPreviewSizes += ",";
114            supportedPreviewSizes += String8::format("%dx%d",
115                    availablePreviewSizes[i].width,
116                    availablePreviewSizes[i].height);
117        }
118        ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.string());
119        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
120                supportedPreviewSizes);
121
122        String8 supportedVideoSizes;
123        for (size_t i = 0; i < availableVideoSizes.size(); i++) {
124            if (i != 0) supportedVideoSizes += ",";
125            supportedVideoSizes += String8::format("%dx%d",
126                    availableVideoSizes[i].width,
127                    availableVideoSizes[i].height);
128        }
129        ALOGV("Supported video sizes are: %s", supportedVideoSizes.string());
130        params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
131                supportedVideoSizes);
132    }
133
134    camera_metadata_ro_entry_t availableFpsRanges =
135        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
136    if (!availableFpsRanges.count) return NO_INIT;
137
138    previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
139    params.set(CameraParameters::KEY_PREVIEW_FORMAT,
140            formatEnumToString(previewFormat)); // NV21
141
142    previewTransform = degToTransform(0,
143            cameraFacing == CAMERA_FACING_FRONT);
144
145    {
146        String8 supportedPreviewFormats;
147        SortedVector<int32_t> outputFormats = getAvailableOutputFormats();
148        bool addComma = false;
149        for (size_t i=0; i < outputFormats.size(); i++) {
150            if (addComma) supportedPreviewFormats += ",";
151            addComma = true;
152            switch (outputFormats[i]) {
153            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
154                supportedPreviewFormats +=
155                    CameraParameters::PIXEL_FORMAT_YUV422SP;
156                break;
157            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
158                supportedPreviewFormats +=
159                    CameraParameters::PIXEL_FORMAT_YUV420SP;
160                break;
161            case HAL_PIXEL_FORMAT_YCbCr_422_I:
162                supportedPreviewFormats +=
163                    CameraParameters::PIXEL_FORMAT_YUV422I;
164                break;
165            case HAL_PIXEL_FORMAT_YV12:
166                supportedPreviewFormats +=
167                    CameraParameters::PIXEL_FORMAT_YUV420P;
168                break;
169            case HAL_PIXEL_FORMAT_RGB_565:
170                supportedPreviewFormats +=
171                    CameraParameters::PIXEL_FORMAT_RGB565;
172                break;
173            case HAL_PIXEL_FORMAT_RGBA_8888:
174                supportedPreviewFormats +=
175                    CameraParameters::PIXEL_FORMAT_RGBA8888;
176                break;
177            case HAL_PIXEL_FORMAT_YCbCr_420_888:
178                // Flexible YUV allows both YV12 and NV21
179                supportedPreviewFormats +=
180                    CameraParameters::PIXEL_FORMAT_YUV420P;
181                supportedPreviewFormats += ",";
182                supportedPreviewFormats +=
183                    CameraParameters::PIXEL_FORMAT_YUV420SP;
184                break;
185            // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
186            case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
187            case HAL_PIXEL_FORMAT_RAW_SENSOR:
188            case HAL_PIXEL_FORMAT_BLOB:
189                addComma = false;
190                break;
191
192            default:
193                ALOGW("%s: Camera %d: Unknown preview format: %x",
194                        __FUNCTION__, cameraId, outputFormats[i]);
195                addComma = false;
196                break;
197            }
198        }
199        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
200                supportedPreviewFormats);
201    }
202
203    previewFpsRange[0] = availableFpsRanges.data.i32[0];
204    previewFpsRange[1] = availableFpsRanges.data.i32[1];
205
206    // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
207    // still have to do something sane for them
208
209    // NOTE: Not scaled like FPS range values are.
210    int previewFps = fpsFromRange(previewFpsRange[0], previewFpsRange[1]);
211    params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
212            previewFps);
213
214    // PREVIEW_FPS_RANGE
215    // -- Order matters. Set range after single value to so that a roundtrip
216    //    of setParameters(getParameters()) would keep the FPS range in higher
217    //    order.
218    params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
219            String8::format("%d,%d",
220                    previewFpsRange[0] * kFpsToApiScale,
221                    previewFpsRange[1] * kFpsToApiScale));
222
223    {
224        String8 supportedPreviewFpsRange;
225        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
226            if (i != 0) supportedPreviewFpsRange += ",";
227            supportedPreviewFpsRange += String8::format("(%d,%d)",
228                    availableFpsRanges.data.i32[i] * kFpsToApiScale,
229                    availableFpsRanges.data.i32[i+1] * kFpsToApiScale);
230        }
231        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
232                supportedPreviewFpsRange);
233    }
234
235    {
236        SortedVector<int32_t> sortedPreviewFrameRates;
237
238        String8 supportedPreviewFrameRates;
239        for (size_t i=0; i < availableFpsRanges.count; i += 2) {
240            // from the [min, max] fps range use the max value
241            int fps = fpsFromRange(availableFpsRanges.data.i32[i],
242                                   availableFpsRanges.data.i32[i+1]);
243
244            // de-dupe frame rates
245            if (sortedPreviewFrameRates.indexOf(fps) == NAME_NOT_FOUND) {
246                sortedPreviewFrameRates.add(fps);
247            }
248            else {
249                continue;
250            }
251
252            if (sortedPreviewFrameRates.size() > 1) {
253                supportedPreviewFrameRates += ",";
254            }
255
256            supportedPreviewFrameRates += String8::format("%d",
257                    fps);
258
259            ALOGV("%s: Supported preview frame rates: %s",
260                    __FUNCTION__, supportedPreviewFrameRates.string());
261        }
262        params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
263                supportedPreviewFrameRates);
264    }
265
266    Vector<Size> availableJpegSizes = getAvailableJpegSizes();
267    if (!availableJpegSizes.size()) return NO_INIT;
268
269    // TODO: Pick maximum
270    pictureWidth = availableJpegSizes[0].width;
271    pictureHeight = availableJpegSizes[0].height;
272    pictureWidthLastSet = pictureWidth;
273    pictureHeightLastSet = pictureHeight;
274    pictureSizeOverriden = false;
275
276    params.setPictureSize(pictureWidth,
277            pictureHeight);
278
279    {
280        String8 supportedPictureSizes;
281        for (size_t i=0; i < availableJpegSizes.size(); i++) {
282            if (i != 0) supportedPictureSizes += ",";
283            supportedPictureSizes += String8::format("%dx%d",
284                    availableJpegSizes[i].width,
285                    availableJpegSizes[i].height);
286        }
287        params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
288                supportedPictureSizes);
289    }
290
291    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
292    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
293            CameraParameters::PIXEL_FORMAT_JPEG);
294
295    camera_metadata_ro_entry_t availableJpegThumbnailSizes =
296        staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 4);
297    if (!availableJpegThumbnailSizes.count) return NO_INIT;
298
299    // Pick the largest thumbnail size that matches still image aspect ratio.
300    ALOG_ASSERT(pictureWidth > 0 && pictureHeight > 0,
301            "Invalid picture size, %d x %d", pictureWidth, pictureHeight);
302    float picAspectRatio = static_cast<float>(pictureWidth) / pictureHeight;
303    Size thumbnailSize =
304            getMaxSizeForRatio(
305                    picAspectRatio,
306                    &availableJpegThumbnailSizes.data.i32[0],
307                    availableJpegThumbnailSizes.count);
308    jpegThumbSize[0] = thumbnailSize.width;
309    jpegThumbSize[1] = thumbnailSize.height;
310
311    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
312            jpegThumbSize[0]);
313    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
314            jpegThumbSize[1]);
315
316    {
317        String8 supportedJpegThumbSizes;
318        for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
319            if (i != 0) supportedJpegThumbSizes += ",";
320            supportedJpegThumbSizes += String8::format("%dx%d",
321                    availableJpegThumbnailSizes.data.i32[i],
322                    availableJpegThumbnailSizes.data.i32[i+1]);
323        }
324        params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
325                supportedJpegThumbSizes);
326    }
327
328    jpegThumbQuality = 90;
329    params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
330            jpegThumbQuality);
331    jpegQuality = 90;
332    params.set(CameraParameters::KEY_JPEG_QUALITY,
333            jpegQuality);
334    jpegRotation = 0;
335    params.set(CameraParameters::KEY_ROTATION,
336            jpegRotation);
337
338    gpsEnabled = false;
339    gpsCoordinates[0] = 0.0;
340    gpsCoordinates[1] = 0.0;
341    gpsCoordinates[2] = 0.0;
342    gpsTimestamp = 0;
343    gpsProcessingMethod = "unknown";
344    // GPS fields in CameraParameters are not set by implementation
345
346    wbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
347    params.set(CameraParameters::KEY_WHITE_BALANCE,
348            CameraParameters::WHITE_BALANCE_AUTO);
349
350    camera_metadata_ro_entry_t availableWhiteBalanceModes =
351        staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES, 0, 0, false);
352    if (!availableWhiteBalanceModes.count) {
353        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
354                CameraParameters::WHITE_BALANCE_AUTO);
355    } else {
356        String8 supportedWhiteBalance;
357        bool addComma = false;
358        for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
359            if (addComma) supportedWhiteBalance += ",";
360            addComma = true;
361            switch (availableWhiteBalanceModes.data.u8[i]) {
362            case ANDROID_CONTROL_AWB_MODE_AUTO:
363                supportedWhiteBalance +=
364                    CameraParameters::WHITE_BALANCE_AUTO;
365                break;
366            case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
367                supportedWhiteBalance +=
368                    CameraParameters::WHITE_BALANCE_INCANDESCENT;
369                break;
370            case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
371                supportedWhiteBalance +=
372                    CameraParameters::WHITE_BALANCE_FLUORESCENT;
373                break;
374            case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
375                supportedWhiteBalance +=
376                    CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
377                break;
378            case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
379                supportedWhiteBalance +=
380                    CameraParameters::WHITE_BALANCE_DAYLIGHT;
381                break;
382            case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
383                supportedWhiteBalance +=
384                    CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
385                break;
386            case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
387                supportedWhiteBalance +=
388                    CameraParameters::WHITE_BALANCE_TWILIGHT;
389                break;
390            case ANDROID_CONTROL_AWB_MODE_SHADE:
391                supportedWhiteBalance +=
392                    CameraParameters::WHITE_BALANCE_SHADE;
393                break;
394            // Skipping values not mappable to v1 API
395            case ANDROID_CONTROL_AWB_MODE_OFF:
396                addComma = false;
397                break;
398            default:
399                ALOGW("%s: Camera %d: Unknown white balance value: %d",
400                        __FUNCTION__, cameraId,
401                        availableWhiteBalanceModes.data.u8[i]);
402                addComma = false;
403                break;
404            }
405        }
406        params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
407                supportedWhiteBalance);
408    }
409
410    effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
411    params.set(CameraParameters::KEY_EFFECT,
412            CameraParameters::EFFECT_NONE);
413
414    camera_metadata_ro_entry_t availableEffects =
415        staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS, 0, 0, false);
416    if (!availableEffects.count) {
417        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS,
418                CameraParameters::EFFECT_NONE);
419    } else {
420        String8 supportedEffects;
421        bool addComma = false;
422        for (size_t i=0; i < availableEffects.count; i++) {
423            if (addComma) supportedEffects += ",";
424            addComma = true;
425            switch (availableEffects.data.u8[i]) {
426                case ANDROID_CONTROL_EFFECT_MODE_OFF:
427                    supportedEffects +=
428                        CameraParameters::EFFECT_NONE;
429                    break;
430                case ANDROID_CONTROL_EFFECT_MODE_MONO:
431                    supportedEffects +=
432                        CameraParameters::EFFECT_MONO;
433                    break;
434                case ANDROID_CONTROL_EFFECT_MODE_NEGATIVE:
435                    supportedEffects +=
436                        CameraParameters::EFFECT_NEGATIVE;
437                    break;
438                case ANDROID_CONTROL_EFFECT_MODE_SOLARIZE:
439                    supportedEffects +=
440                        CameraParameters::EFFECT_SOLARIZE;
441                    break;
442                case ANDROID_CONTROL_EFFECT_MODE_SEPIA:
443                    supportedEffects +=
444                        CameraParameters::EFFECT_SEPIA;
445                    break;
446                case ANDROID_CONTROL_EFFECT_MODE_POSTERIZE:
447                    supportedEffects +=
448                        CameraParameters::EFFECT_POSTERIZE;
449                    break;
450                case ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD:
451                    supportedEffects +=
452                        CameraParameters::EFFECT_WHITEBOARD;
453                    break;
454                case ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD:
455                    supportedEffects +=
456                        CameraParameters::EFFECT_BLACKBOARD;
457                    break;
458                case ANDROID_CONTROL_EFFECT_MODE_AQUA:
459                    supportedEffects +=
460                        CameraParameters::EFFECT_AQUA;
461                    break;
462                default:
463                    ALOGW("%s: Camera %d: Unknown effect value: %d",
464                        __FUNCTION__, cameraId, availableEffects.data.u8[i]);
465                    addComma = false;
466                    break;
467            }
468        }
469        params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
470    }
471
472    antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
473    params.set(CameraParameters::KEY_ANTIBANDING,
474            CameraParameters::ANTIBANDING_AUTO);
475
476    camera_metadata_ro_entry_t availableAntibandingModes =
477        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, 0, 0, false);
478    if (!availableAntibandingModes.count) {
479        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
480                CameraParameters::ANTIBANDING_OFF);
481    } else {
482        String8 supportedAntibanding;
483        bool addComma = false;
484        for (size_t i=0; i < availableAntibandingModes.count; i++) {
485            if (addComma) supportedAntibanding += ",";
486            addComma = true;
487            switch (availableAntibandingModes.data.u8[i]) {
488                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF:
489                    supportedAntibanding +=
490                        CameraParameters::ANTIBANDING_OFF;
491                    break;
492                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ:
493                    supportedAntibanding +=
494                        CameraParameters::ANTIBANDING_50HZ;
495                    break;
496                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ:
497                    supportedAntibanding +=
498                        CameraParameters::ANTIBANDING_60HZ;
499                    break;
500                case ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO:
501                    supportedAntibanding +=
502                        CameraParameters::ANTIBANDING_AUTO;
503                    break;
504                default:
505                    ALOGW("%s: Camera %d: Unknown antibanding value: %d",
506                        __FUNCTION__, cameraId,
507                            availableAntibandingModes.data.u8[i]);
508                    addComma = false;
509                    break;
510            }
511        }
512        params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
513                supportedAntibanding);
514    }
515
516    sceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
517    params.set(CameraParameters::KEY_SCENE_MODE,
518            CameraParameters::SCENE_MODE_AUTO);
519
520    camera_metadata_ro_entry_t availableSceneModes =
521        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, 0, 0, false);
522    if (!availableSceneModes.count) {
523        params.remove(CameraParameters::KEY_SCENE_MODE);
524    } else {
525        String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
526        bool addComma = true;
527        bool noSceneModes = false;
528        for (size_t i=0; i < availableSceneModes.count; i++) {
529            if (addComma) supportedSceneModes += ",";
530            addComma = true;
531            switch (availableSceneModes.data.u8[i]) {
532                case ANDROID_CONTROL_SCENE_MODE_DISABLED:
533                    noSceneModes = true;
534                    break;
535                case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
536                    // Not in old API
537                    addComma = false;
538                    break;
539                case ANDROID_CONTROL_SCENE_MODE_ACTION:
540                    supportedSceneModes +=
541                        CameraParameters::SCENE_MODE_ACTION;
542                    break;
543                case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
544                    supportedSceneModes +=
545                        CameraParameters::SCENE_MODE_PORTRAIT;
546                    break;
547                case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
548                    supportedSceneModes +=
549                        CameraParameters::SCENE_MODE_LANDSCAPE;
550                    break;
551                case ANDROID_CONTROL_SCENE_MODE_NIGHT:
552                    supportedSceneModes +=
553                        CameraParameters::SCENE_MODE_NIGHT;
554                    break;
555                case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
556                    supportedSceneModes +=
557                        CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
558                    break;
559                case ANDROID_CONTROL_SCENE_MODE_THEATRE:
560                    supportedSceneModes +=
561                        CameraParameters::SCENE_MODE_THEATRE;
562                    break;
563                case ANDROID_CONTROL_SCENE_MODE_BEACH:
564                    supportedSceneModes +=
565                        CameraParameters::SCENE_MODE_BEACH;
566                    break;
567                case ANDROID_CONTROL_SCENE_MODE_SNOW:
568                    supportedSceneModes +=
569                        CameraParameters::SCENE_MODE_SNOW;
570                    break;
571                case ANDROID_CONTROL_SCENE_MODE_SUNSET:
572                    supportedSceneModes +=
573                        CameraParameters::SCENE_MODE_SUNSET;
574                    break;
575                case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
576                    supportedSceneModes +=
577                        CameraParameters::SCENE_MODE_STEADYPHOTO;
578                    break;
579                case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
580                    supportedSceneModes +=
581                        CameraParameters::SCENE_MODE_FIREWORKS;
582                    break;
583                case ANDROID_CONTROL_SCENE_MODE_SPORTS:
584                    supportedSceneModes +=
585                        CameraParameters::SCENE_MODE_SPORTS;
586                    break;
587                case ANDROID_CONTROL_SCENE_MODE_PARTY:
588                    supportedSceneModes +=
589                        CameraParameters::SCENE_MODE_PARTY;
590                    break;
591                case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
592                    supportedSceneModes +=
593                        CameraParameters::SCENE_MODE_CANDLELIGHT;
594                    break;
595                case ANDROID_CONTROL_SCENE_MODE_BARCODE:
596                    supportedSceneModes +=
597                        CameraParameters::SCENE_MODE_BARCODE;
598                    break;
599                default:
600                    ALOGW("%s: Camera %d: Unknown scene mode value: %d",
601                        __FUNCTION__, cameraId,
602                            availableSceneModes.data.u8[i]);
603                    addComma = false;
604                    break;
605            }
606        }
607        if (!noSceneModes) {
608            params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
609                    supportedSceneModes);
610        } else {
611            params.remove(CameraParameters::KEY_SCENE_MODE);
612        }
613    }
614
615    bool isFlashAvailable = false;
616    camera_metadata_ro_entry_t flashAvailable =
617        staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 0, 1, false);
618    if (flashAvailable.count) {
619        isFlashAvailable = flashAvailable.data.u8[0];
620    }
621
622    camera_metadata_ro_entry_t availableAeModes =
623        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES, 0, 0, false);
624
625    if (isFlashAvailable) {
626        flashMode = Parameters::FLASH_MODE_OFF;
627        params.set(CameraParameters::KEY_FLASH_MODE,
628                CameraParameters::FLASH_MODE_OFF);
629
630        String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
631        supportedFlashModes = supportedFlashModes +
632            "," + CameraParameters::FLASH_MODE_AUTO +
633            "," + CameraParameters::FLASH_MODE_ON +
634            "," + CameraParameters::FLASH_MODE_TORCH;
635        for (size_t i=0; i < availableAeModes.count; i++) {
636            if (availableAeModes.data.u8[i] ==
637                    ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
638                supportedFlashModes = supportedFlashModes + "," +
639                    CameraParameters::FLASH_MODE_RED_EYE;
640                break;
641            }
642        }
643        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
644                supportedFlashModes);
645    } else {
646        flashMode = Parameters::FLASH_MODE_OFF;
647        params.set(CameraParameters::KEY_FLASH_MODE,
648                CameraParameters::FLASH_MODE_OFF);
649        params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
650                CameraParameters::FLASH_MODE_OFF);
651    }
652
653    camera_metadata_ro_entry_t minFocusDistance =
654        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 1, false);
655
656    camera_metadata_ro_entry_t availableAfModes =
657        staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES, 0, 0, false);
658
659    if (!minFocusDistance.count || minFocusDistance.data.f[0] == 0) {
660        // Fixed-focus lens
661        focusMode = Parameters::FOCUS_MODE_FIXED;
662        params.set(CameraParameters::KEY_FOCUS_MODE,
663                CameraParameters::FOCUS_MODE_FIXED);
664        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
665                CameraParameters::FOCUS_MODE_FIXED);
666    } else {
667        focusMode = Parameters::FOCUS_MODE_AUTO;
668        params.set(CameraParameters::KEY_FOCUS_MODE,
669                CameraParameters::FOCUS_MODE_AUTO);
670        String8 supportedFocusModes;
671        bool addComma = false;
672        camera_metadata_ro_entry_t focusDistanceCalibration =
673            staticInfo(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, 0, 0, false);
674
675        if (focusDistanceCalibration.count &&
676                focusDistanceCalibration.data.u8[0] !=
677                ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED) {
678            supportedFocusModes += CameraParameters::FOCUS_MODE_INFINITY;
679            addComma = true;
680        }
681
682        for (size_t i=0; i < availableAfModes.count; i++) {
683            if (addComma) supportedFocusModes += ",";
684            addComma = true;
685            switch (availableAfModes.data.u8[i]) {
686                case ANDROID_CONTROL_AF_MODE_AUTO:
687                    supportedFocusModes +=
688                        CameraParameters::FOCUS_MODE_AUTO;
689                    break;
690                case ANDROID_CONTROL_AF_MODE_MACRO:
691                    supportedFocusModes +=
692                        CameraParameters::FOCUS_MODE_MACRO;
693                    break;
694                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
695                    supportedFocusModes +=
696                        CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
697                    break;
698                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
699                    supportedFocusModes +=
700                        CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
701                    break;
702                case ANDROID_CONTROL_AF_MODE_EDOF:
703                    supportedFocusModes +=
704                        CameraParameters::FOCUS_MODE_EDOF;
705                    break;
706                // Not supported in old API
707                case ANDROID_CONTROL_AF_MODE_OFF:
708                    addComma = false;
709                    break;
710                default:
711                    ALOGW("%s: Camera %d: Unknown AF mode value: %d",
712                        __FUNCTION__, cameraId, availableAfModes.data.u8[i]);
713                    addComma = false;
714                    break;
715            }
716        }
717        params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
718                supportedFocusModes);
719    }
720    focusState = ANDROID_CONTROL_AF_STATE_INACTIVE;
721    shadowFocusMode = FOCUS_MODE_INVALID;
722
723    camera_metadata_ro_entry_t max3aRegions = staticInfo(ANDROID_CONTROL_MAX_REGIONS,
724            Parameters::NUM_REGION, Parameters::NUM_REGION);
725    if (max3aRegions.count != Parameters::NUM_REGION) return NO_INIT;
726
727    int32_t maxNumFocusAreas = 0;
728    if (focusMode != Parameters::FOCUS_MODE_FIXED) {
729        maxNumFocusAreas = max3aRegions.data.i32[Parameters::REGION_AF];
730    }
731    params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, maxNumFocusAreas);
732    params.set(CameraParameters::KEY_FOCUS_AREAS,
733            "(0,0,0,0,0)");
734    focusingAreas.clear();
735    focusingAreas.add(Parameters::Area(0,0,0,0,0));
736
737    camera_metadata_ro_entry_t availableFocalLengths =
738        staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
739    if (!availableFocalLengths.count) return NO_INIT;
740
741    float minFocalLength = availableFocalLengths.data.f[0];
742    params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
743
744    float horizFov, vertFov;
745    res = calculatePictureFovs(&horizFov, &vertFov);
746    if (res != OK) {
747        ALOGE("%s: Can't calculate field of views!", __FUNCTION__);
748        return res;
749    }
750
751    params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
752    params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
753
754    exposureCompensation = 0;
755    params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
756                exposureCompensation);
757
758    camera_metadata_ro_entry_t exposureCompensationRange =
759        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE, 2, 2);
760    if (!exposureCompensationRange.count) return NO_INIT;
761
762    params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
763            exposureCompensationRange.data.i32[1]);
764    params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
765            exposureCompensationRange.data.i32[0]);
766
767    camera_metadata_ro_entry_t exposureCompensationStep =
768        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_STEP, 1, 1);
769    if (!exposureCompensationStep.count) return NO_INIT;
770
771    params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
772            (float)exposureCompensationStep.data.r[0].numerator /
773            exposureCompensationStep.data.r[0].denominator);
774
775    autoExposureLock = false;
776    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
777            CameraParameters::FALSE);
778    params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
779            CameraParameters::TRUE);
780
781    autoWhiteBalanceLock = false;
782    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
783            CameraParameters::FALSE);
784    params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
785            CameraParameters::TRUE);
786
787    meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
788    params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
789            max3aRegions.data.i32[Parameters::REGION_AE]);
790    params.set(CameraParameters::KEY_METERING_AREAS,
791            "(0,0,0,0,0)");
792
793    zoom = 0;
794    params.set(CameraParameters::KEY_ZOOM, zoom);
795    params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
796
797    camera_metadata_ro_entry_t maxDigitalZoom =
798        staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, /*minCount*/1, /*maxCount*/1);
799    if (!maxDigitalZoom.count) return NO_INIT;
800
801    {
802        String8 zoomRatios;
803        float zoom = 1.f;
804        float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
805                (NUM_ZOOM_STEPS-1);
806        bool addComma = false;
807        for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
808            if (addComma) zoomRatios += ",";
809            addComma = true;
810            zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
811            zoom += zoomIncrement;
812        }
813        params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
814    }
815
816    params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
817            CameraParameters::TRUE);
818    params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
819            CameraParameters::FALSE);
820
821    params.set(CameraParameters::KEY_FOCUS_DISTANCES,
822            "Infinity,Infinity,Infinity");
823
824    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
825            fastInfo.maxFaces);
826    params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
827            0);
828
829    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
830            CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
831
832    recordingHint = false;
833    params.set(CameraParameters::KEY_RECORDING_HINT,
834            CameraParameters::FALSE);
835
836    params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
837            CameraParameters::TRUE);
838
839    videoStabilization = false;
840    params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
841            CameraParameters::FALSE);
842
843    camera_metadata_ro_entry_t availableVideoStabilizationModes =
844        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 0, 0,
845                false);
846
847    if (availableVideoStabilizationModes.count > 1) {
848        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
849                CameraParameters::TRUE);
850    } else {
851        params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
852                CameraParameters::FALSE);
853    }
854
855    // Set up initial state for non-Camera.Parameters state variables
856
857    storeMetadataInBuffers = true;
858    playShutterSound = true;
859    enableFaceDetect = false;
860
861    enableFocusMoveMessages = false;
862    afTriggerCounter = 1;
863    afStateCounter = 0;
864    currentAfTriggerId = -1;
865    afInMotion = false;
866
867    precaptureTriggerCounter = 1;
868
869    takePictureCounter = 0;
870
871    previewCallbackFlags = 0;
872    previewCallbackOneShot = false;
873    previewCallbackSurface = false;
874
875    char value[PROPERTY_VALUE_MAX];
876    property_get("camera.disable_zsl_mode", value, "0");
877    if (!strcmp(value,"1")) {
878        ALOGI("Camera %d: Disabling ZSL mode", cameraId);
879        zslMode = false;
880    } else {
881        zslMode = true;
882    }
883
884    lightFx = LIGHTFX_NONE;
885
886    state = STOPPED;
887
888    paramsFlattened = params.flatten();
889
890    return OK;
891}
892
893String8 Parameters::get() const {
894    return paramsFlattened;
895}
896
897status_t Parameters::buildFastInfo() {
898
899    camera_metadata_ro_entry_t activeArraySize =
900        staticInfo(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 2, 4);
901    if (!activeArraySize.count) return NO_INIT;
902    int32_t arrayWidth;
903    int32_t arrayHeight;
904    if (activeArraySize.count == 2) {
905        ALOGW("%s: Camera %d: activeArraySize is missing xmin/ymin!",
906                __FUNCTION__, cameraId);
907        arrayWidth = activeArraySize.data.i32[0];
908        arrayHeight = activeArraySize.data.i32[1];
909    } else if (activeArraySize.count == 4) {
910        arrayWidth = activeArraySize.data.i32[2];
911        arrayHeight = activeArraySize.data.i32[3];
912    } else return NO_INIT;
913
914    // We'll set the target FPS range for still captures to be as wide
915    // as possible to give the HAL maximum latitude for exposure selection
916    camera_metadata_ro_entry_t availableFpsRanges =
917        staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
918    if (availableFpsRanges.count < 2 || availableFpsRanges.count % 2 != 0) {
919        return NO_INIT;
920    }
921
922    int32_t bestStillCaptureFpsRange[2] = {
923        availableFpsRanges.data.i32[0], availableFpsRanges.data.i32[1]
924    };
925    int32_t curRange =
926            bestStillCaptureFpsRange[1] - bestStillCaptureFpsRange[0];
927    for (size_t i = 2; i < availableFpsRanges.count; i += 2) {
928        int32_t nextRange =
929                availableFpsRanges.data.i32[i + 1] -
930                availableFpsRanges.data.i32[i];
931        if ( (nextRange > curRange) ||       // Maximize size of FPS range first
932                (nextRange == curRange &&    // Then minimize low-end FPS
933                 bestStillCaptureFpsRange[0] > availableFpsRanges.data.i32[i])) {
934
935            bestStillCaptureFpsRange[0] = availableFpsRanges.data.i32[i];
936            bestStillCaptureFpsRange[1] = availableFpsRanges.data.i32[i + 1];
937            curRange = nextRange;
938        }
939    }
940
941    camera_metadata_ro_entry_t availableFaceDetectModes =
942        staticInfo(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, 0, 0,
943                false);
944
945    uint8_t bestFaceDetectMode =
946        ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
947    for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
948        switch (availableFaceDetectModes.data.u8[i]) {
949            case ANDROID_STATISTICS_FACE_DETECT_MODE_OFF:
950                break;
951            case ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE:
952                if (bestFaceDetectMode !=
953                        ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
954                    bestFaceDetectMode =
955                        ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE;
956                }
957                break;
958            case ANDROID_STATISTICS_FACE_DETECT_MODE_FULL:
959                bestFaceDetectMode =
960                    ANDROID_STATISTICS_FACE_DETECT_MODE_FULL;
961                break;
962            default:
963                ALOGE("%s: Camera %d: Unknown face detect mode %d:",
964                        __FUNCTION__, cameraId,
965                        availableFaceDetectModes.data.u8[i]);
966                return NO_INIT;
967        }
968    }
969
970    int32_t maxFaces = 0;
971    camera_metadata_ro_entry_t maxFacesDetected =
972        staticInfo(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 0, 1, false);
973    if (maxFacesDetected.count) {
974        maxFaces = maxFacesDetected.data.i32[0];
975    }
976
977    camera_metadata_ro_entry_t availableSceneModes =
978        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, 0, 0, false);
979    camera_metadata_ro_entry_t sceneModeOverrides =
980        staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES, 0, 0, false);
981    camera_metadata_ro_entry_t minFocusDistance =
982        staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 0, false);
983    bool fixedLens = minFocusDistance.count == 0 ||
984        minFocusDistance.data.f[0] == 0;
985
986    camera_metadata_ro_entry_t availableFocalLengths =
987        staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
988    if (!availableFocalLengths.count) return NO_INIT;
989
990    SortedVector<int32_t> availableFormats = getAvailableOutputFormats();
991    if (!availableFormats.size()) return NO_INIT;
992
993
994    if (sceneModeOverrides.count > 0) {
995        // sceneModeOverrides is defined to have 3 entries for each scene mode,
996        // which are AE, AWB, and AF override modes the HAL wants for that scene
997        // mode.
998        const size_t kModesPerSceneMode = 3;
999        if (sceneModeOverrides.count !=
1000                availableSceneModes.count * kModesPerSceneMode) {
1001            ALOGE("%s: Camera %d: Scene mode override list is an "
1002                    "unexpected size: %zu (expected %zu)", __FUNCTION__,
1003                    cameraId, sceneModeOverrides.count,
1004                    availableSceneModes.count);
1005            return NO_INIT;
1006        }
1007        for (size_t i = 0; i < availableSceneModes.count; i++) {
1008            DeviceInfo::OverrideModes modes;
1009            uint8_t aeMode =
1010                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
1011            switch(aeMode) {
1012                case ANDROID_CONTROL_AE_MODE_ON:
1013                    modes.flashMode = FLASH_MODE_OFF;
1014                    break;
1015                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
1016                    modes.flashMode = FLASH_MODE_AUTO;
1017                    break;
1018                case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
1019                    modes.flashMode = FLASH_MODE_ON;
1020                    break;
1021                case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
1022                    modes.flashMode = FLASH_MODE_RED_EYE;
1023                    break;
1024                default:
1025                    ALOGE("%s: Unknown override AE mode: %d", __FUNCTION__,
1026                            aeMode);
1027                    modes.flashMode = FLASH_MODE_INVALID;
1028                    break;
1029            }
1030            modes.wbMode =
1031                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 1];
1032            uint8_t afMode =
1033                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
1034            switch(afMode) {
1035                case ANDROID_CONTROL_AF_MODE_OFF:
1036                    modes.focusMode = fixedLens ?
1037                            FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
1038                    break;
1039                case ANDROID_CONTROL_AF_MODE_AUTO:
1040                case ANDROID_CONTROL_AF_MODE_MACRO:
1041                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
1042                case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
1043                case ANDROID_CONTROL_AF_MODE_EDOF:
1044                    modes.focusMode = static_cast<focusMode_t>(afMode);
1045                    break;
1046                default:
1047                    ALOGE("%s: Unknown override AF mode: %d", __FUNCTION__,
1048                            afMode);
1049                    modes.focusMode = FOCUS_MODE_INVALID;
1050                    break;
1051            }
1052            fastInfo.sceneModeOverrides.add(availableSceneModes.data.u8[i],
1053                    modes);
1054        }
1055    }
1056
1057    fastInfo.arrayWidth = arrayWidth;
1058    fastInfo.arrayHeight = arrayHeight;
1059    fastInfo.bestStillCaptureFpsRange[0] = bestStillCaptureFpsRange[0];
1060    fastInfo.bestStillCaptureFpsRange[1] = bestStillCaptureFpsRange[1];
1061    fastInfo.bestFaceDetectMode = bestFaceDetectMode;
1062    fastInfo.maxFaces = maxFaces;
1063
1064    // Find smallest (widest-angle) focal length to use as basis of still
1065    // picture FOV reporting.
1066    fastInfo.minFocalLength = availableFocalLengths.data.f[0];
1067    for (size_t i = 1; i < availableFocalLengths.count; i++) {
1068        if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
1069            fastInfo.minFocalLength = availableFocalLengths.data.f[i];
1070        }
1071    }
1072
1073    // Check if the HAL supports HAL_PIXEL_FORMAT_YCbCr_420_888
1074    fastInfo.useFlexibleYuv = false;
1075    for (size_t i = 0; i < availableFormats.size(); i++) {
1076        if (availableFormats[i] == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1077            fastInfo.useFlexibleYuv = true;
1078            break;
1079        }
1080    }
1081    ALOGV("Camera %d: Flexible YUV %s supported",
1082            cameraId, fastInfo.useFlexibleYuv ? "is" : "is not");
1083
1084    return OK;
1085}
1086
1087status_t Parameters::buildQuirks() {
1088    camera_metadata_ro_entry_t entry;
1089    entry = info->find(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO);
1090    quirks.triggerAfWithAuto = (entry.count != 0 && entry.data.u8[0] == 1);
1091    ALOGV_IF(quirks.triggerAfWithAuto, "Camera %d: Quirk triggerAfWithAuto enabled",
1092            cameraId);
1093
1094    entry = info->find(ANDROID_QUIRKS_USE_ZSL_FORMAT);
1095    quirks.useZslFormat = (entry.count != 0 && entry.data.u8[0] == 1);
1096    ALOGV_IF(quirks.useZslFormat, "Camera %d: Quirk useZslFormat enabled",
1097            cameraId);
1098
1099    entry = info->find(ANDROID_QUIRKS_METERING_CROP_REGION);
1100    quirks.meteringCropRegion = (entry.count != 0 && entry.data.u8[0] == 1);
1101    ALOGV_IF(quirks.meteringCropRegion, "Camera %d: Quirk meteringCropRegion"
1102                " enabled", cameraId);
1103
1104    entry = info->find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
1105    quirks.partialResults = (entry.count != 0 && entry.data.u8[0] == 1);
1106    ALOGV_IF(quirks.partialResults, "Camera %d: Quirk usePartialResult"
1107                " enabled", cameraId);
1108
1109    return OK;
1110}
1111
1112camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
1113        size_t minCount, size_t maxCount, bool required) const {
1114    camera_metadata_ro_entry_t entry = info->find(tag);
1115
1116    if (CC_UNLIKELY( entry.count == 0 ) && required) {
1117        const char* tagSection = get_camera_metadata_section_name(tag);
1118        if (tagSection == NULL) tagSection = "<unknown>";
1119        const char* tagName = get_camera_metadata_tag_name(tag);
1120        if (tagName == NULL) tagName = "<unknown>";
1121
1122        ALOGE("Error finding static metadata entry '%s.%s' (%x)",
1123                tagSection, tagName, tag);
1124    } else if (CC_UNLIKELY(
1125            (minCount != 0 && entry.count < minCount) ||
1126            (maxCount != 0 && entry.count > maxCount) ) ) {
1127        const char* tagSection = get_camera_metadata_section_name(tag);
1128        if (tagSection == NULL) tagSection = "<unknown>";
1129        const char* tagName = get_camera_metadata_tag_name(tag);
1130        if (tagName == NULL) tagName = "<unknown>";
1131        ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1132                "Expected between %zu and %zu values, but got %zu values",
1133                tagSection, tagName, tag, minCount, maxCount, entry.count);
1134    }
1135
1136    return entry;
1137}
1138
1139status_t Parameters::set(const String8& paramString) {
1140    status_t res;
1141
1142    CameraParameters2 newParams(paramString);
1143
1144    // TODO: Currently ignoring any changes to supposedly read-only parameters
1145    // such as supported preview sizes, etc. Should probably produce an error if
1146    // they're changed.
1147
1148    /** Extract and verify new parameters */
1149
1150    size_t i;
1151
1152    Parameters validatedParams(*this);
1153
1154    // PREVIEW_SIZE
1155    newParams.getPreviewSize(&validatedParams.previewWidth,
1156            &validatedParams.previewHeight);
1157
1158    if (validatedParams.previewWidth != previewWidth ||
1159            validatedParams.previewHeight != previewHeight) {
1160        if (state >= PREVIEW) {
1161            ALOGE("%s: Preview size cannot be updated when preview "
1162                    "is active! (Currently %d x %d, requested %d x %d",
1163                    __FUNCTION__,
1164                    previewWidth, previewHeight,
1165                    validatedParams.previewWidth, validatedParams.previewHeight);
1166            return BAD_VALUE;
1167        }
1168        for (i = 0; i < availablePreviewSizes.size(); i++) {
1169            if ((availablePreviewSizes[i].width ==
1170                    validatedParams.previewWidth) &&
1171                (availablePreviewSizes[i].height ==
1172                    validatedParams.previewHeight)) break;
1173        }
1174        if (i == availablePreviewSizes.size()) {
1175            ALOGE("%s: Requested preview size %d x %d is not supported",
1176                    __FUNCTION__, validatedParams.previewWidth,
1177                    validatedParams.previewHeight);
1178            return BAD_VALUE;
1179        }
1180    }
1181
1182    // RECORDING_HINT (always supported)
1183    validatedParams.recordingHint = boolFromString(
1184        newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1185    IF_ALOGV() { // Avoid unused variable warning
1186        bool recordingHintChanged =
1187                validatedParams.recordingHint != recordingHint;
1188        if (recordingHintChanged) {
1189            ALOGV("%s: Recording hint changed to %d",
1190                  __FUNCTION__, validatedParams.recordingHint);
1191        }
1192    }
1193
1194    // PREVIEW_FPS_RANGE
1195
1196    /**
1197     * Use the single FPS value if it was set later than the range.
1198     * Otherwise, use the range value.
1199     */
1200    bool fpsUseSingleValue;
1201    {
1202        const char *fpsRange, *fpsSingle;
1203
1204        fpsRange = newParams.get(CameraParameters::KEY_PREVIEW_FRAME_RATE);
1205        fpsSingle = newParams.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
1206
1207        /**
1208         * Pick either the range or the single key if only one was set.
1209         *
1210         * If both are set, pick the one that has greater set order.
1211         */
1212        if (fpsRange == NULL && fpsSingle == NULL) {
1213            ALOGE("%s: FPS was not set. One of %s or %s must be set.",
1214                  __FUNCTION__, CameraParameters::KEY_PREVIEW_FRAME_RATE,
1215                  CameraParameters::KEY_PREVIEW_FPS_RANGE);
1216            return BAD_VALUE;
1217        } else if (fpsRange == NULL) {
1218            fpsUseSingleValue = true;
1219            ALOGV("%s: FPS range not set, using FPS single value",
1220                  __FUNCTION__);
1221        } else if (fpsSingle == NULL) {
1222            fpsUseSingleValue = false;
1223            ALOGV("%s: FPS single not set, using FPS range value",
1224                  __FUNCTION__);
1225        } else {
1226            int fpsKeyOrder;
1227            res = newParams.compareSetOrder(
1228                    CameraParameters::KEY_PREVIEW_FRAME_RATE,
1229                    CameraParameters::KEY_PREVIEW_FPS_RANGE,
1230                    &fpsKeyOrder);
1231            LOG_ALWAYS_FATAL_IF(res != OK, "Impossibly bad FPS keys");
1232
1233            fpsUseSingleValue = (fpsKeyOrder > 0);
1234
1235        }
1236
1237        ALOGV("%s: Preview FPS value is used from '%s'",
1238              __FUNCTION__, fpsUseSingleValue ? "single" : "range");
1239    }
1240    newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
1241            &validatedParams.previewFpsRange[1]);
1242
1243    validatedParams.previewFpsRange[0] /= kFpsToApiScale;
1244    validatedParams.previewFpsRange[1] /= kFpsToApiScale;
1245
1246    // Ignore the FPS range if the FPS single has higher precedence
1247    if (!fpsUseSingleValue) {
1248        ALOGV("%s: Preview FPS range (%d, %d)", __FUNCTION__,
1249                validatedParams.previewFpsRange[0],
1250                validatedParams.previewFpsRange[1]);
1251
1252        camera_metadata_ro_entry_t availablePreviewFpsRanges =
1253            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1254        for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1255            if ((availablePreviewFpsRanges.data.i32[i] ==
1256                    validatedParams.previewFpsRange[0]) &&
1257                (availablePreviewFpsRanges.data.i32[i+1] ==
1258                    validatedParams.previewFpsRange[1]) ) {
1259                break;
1260            }
1261        }
1262        if (i == availablePreviewFpsRanges.count) {
1263            ALOGE("%s: Requested preview FPS range %d - %d is not supported",
1264                __FUNCTION__, validatedParams.previewFpsRange[0],
1265                    validatedParams.previewFpsRange[1]);
1266            return BAD_VALUE;
1267        }
1268    }
1269
1270    // PREVIEW_FORMAT
1271    validatedParams.previewFormat =
1272            formatStringToEnum(newParams.getPreviewFormat());
1273    if (validatedParams.previewFormat != previewFormat) {
1274        if (state >= PREVIEW) {
1275            ALOGE("%s: Preview format cannot be updated when preview "
1276                    "is active!", __FUNCTION__);
1277            return BAD_VALUE;
1278        }
1279        SortedVector<int32_t> availableFormats = getAvailableOutputFormats();
1280        // If using flexible YUV, always support NV21/YV12. Otherwise, check
1281        // HAL's list.
1282        if (! (fastInfo.useFlexibleYuv &&
1283                (validatedParams.previewFormat ==
1284                        HAL_PIXEL_FORMAT_YCrCb_420_SP ||
1285                 validatedParams.previewFormat ==
1286                        HAL_PIXEL_FORMAT_YV12) ) ) {
1287            // Not using flexible YUV format, so check explicitly
1288            for (i = 0; i < availableFormats.size(); i++) {
1289                if (availableFormats[i] == validatedParams.previewFormat) break;
1290            }
1291            if (i == availableFormats.size()) {
1292                ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1293                        __FUNCTION__, newParams.getPreviewFormat(),
1294                        validatedParams.previewFormat);
1295                return BAD_VALUE;
1296            }
1297        }
1298    }
1299
1300    // PREVIEW_FRAME_RATE Deprecated
1301    // - Use only if the single FPS value was set later than the FPS range
1302    if (fpsUseSingleValue) {
1303        int previewFps = newParams.getPreviewFrameRate();
1304        ALOGV("%s: Preview FPS single value requested: %d",
1305              __FUNCTION__, previewFps);
1306        {
1307            camera_metadata_ro_entry_t availableFrameRates =
1308                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1309            /**
1310              * If recording hint is set, find the range that encompasses
1311              * previewFps with the largest min index.
1312              *
1313              * If recording hint is not set, find the range with previewFps
1314              * with the smallest min index.
1315              *
1316              * Either way, in case of multiple ranges, break the tie by
1317              * selecting the smaller range.
1318              */
1319
1320            // all ranges which have previewFps
1321            Vector<Range> candidateRanges;
1322            for (i = 0; i < availableFrameRates.count; i+=2) {
1323                Range r = {
1324                            availableFrameRates.data.i32[i],
1325                            availableFrameRates.data.i32[i+1]
1326                };
1327
1328                if (r.min <= previewFps && previewFps <= r.max) {
1329                    candidateRanges.push(r);
1330                }
1331            }
1332            if (candidateRanges.isEmpty()) {
1333                ALOGE("%s: Requested preview frame rate %d is not supported",
1334                        __FUNCTION__, previewFps);
1335                return BAD_VALUE;
1336            }
1337            // most applicable range with targetFps
1338            Range bestRange = candidateRanges[0];
1339            for (i = 1; i < candidateRanges.size(); ++i) {
1340                Range r = candidateRanges[i];
1341
1342                // Find by largest minIndex in recording mode
1343                if (validatedParams.recordingHint) {
1344                    if (r.min > bestRange.min) {
1345                        bestRange = r;
1346                    }
1347                    else if (r.min == bestRange.min && r.max < bestRange.max) {
1348                        bestRange = r;
1349                    }
1350                }
1351                // Find by smallest minIndex in preview mode
1352                else {
1353                    if (r.min < bestRange.min) {
1354                        bestRange = r;
1355                    }
1356                    else if (r.min == bestRange.min && r.max < bestRange.max) {
1357                        bestRange = r;
1358                    }
1359                }
1360            }
1361
1362            validatedParams.previewFpsRange[0] =
1363                    bestRange.min;
1364            validatedParams.previewFpsRange[1] =
1365                    bestRange.max;
1366
1367            ALOGV("%s: New preview FPS range: %d, %d, recordingHint = %d",
1368                __FUNCTION__,
1369                validatedParams.previewFpsRange[0],
1370                validatedParams.previewFpsRange[1],
1371                validatedParams.recordingHint);
1372        }
1373    }
1374
1375    /**
1376     * Update Preview FPS and Preview FPS ranges based on
1377     * what we actually set.
1378     *
1379     * This updates the API-visible (Camera.Parameters#getParameters) values of
1380     * the FPS fields, not only the internal versions.
1381     *
1382     * Order matters: The value that was set last takes precedence.
1383     * - If the client does a setParameters(getParameters()) we retain
1384     *   the same order for preview FPS.
1385     */
1386    if (!fpsUseSingleValue) {
1387        // Set fps single, then fps range (range wins)
1388        newParams.setPreviewFrameRate(
1389                fpsFromRange(/*min*/validatedParams.previewFpsRange[0],
1390                             /*max*/validatedParams.previewFpsRange[1]));
1391        newParams.setPreviewFpsRange(
1392                validatedParams.previewFpsRange[0] * kFpsToApiScale,
1393                validatedParams.previewFpsRange[1] * kFpsToApiScale);
1394    } else {
1395        // Set fps range, then fps single (single wins)
1396        newParams.setPreviewFpsRange(
1397                validatedParams.previewFpsRange[0] * kFpsToApiScale,
1398                validatedParams.previewFpsRange[1] * kFpsToApiScale);
1399        // Set this to the same value, but with higher priority
1400        newParams.setPreviewFrameRate(
1401                newParams.getPreviewFrameRate());
1402    }
1403
1404    // PICTURE_SIZE
1405    newParams.getPictureSize(&validatedParams.pictureWidth,
1406            &validatedParams.pictureHeight);
1407    if (validatedParams.pictureWidth != pictureWidth ||
1408            validatedParams.pictureHeight != pictureHeight) {
1409        Vector<Size> availablePictureSizes = getAvailableJpegSizes();
1410        for (i = 0; i < availablePictureSizes.size(); i++) {
1411            if ((availablePictureSizes[i].width ==
1412                    validatedParams.pictureWidth) &&
1413                (availablePictureSizes[i].height ==
1414                    validatedParams.pictureHeight)) break;
1415        }
1416        if (i == availablePictureSizes.size()) {
1417            ALOGE("%s: Requested picture size %d x %d is not supported",
1418                    __FUNCTION__, validatedParams.pictureWidth,
1419                    validatedParams.pictureHeight);
1420            return BAD_VALUE;
1421        }
1422    }
1423
1424    // JPEG_THUMBNAIL_WIDTH/HEIGHT
1425    validatedParams.jpegThumbSize[0] =
1426            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1427    validatedParams.jpegThumbSize[1] =
1428            newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1429    if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
1430            validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
1431        camera_metadata_ro_entry_t availableJpegThumbSizes =
1432            staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1433        for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1434            if ((availableJpegThumbSizes.data.i32[i] ==
1435                    validatedParams.jpegThumbSize[0]) &&
1436                (availableJpegThumbSizes.data.i32[i+1] ==
1437                    validatedParams.jpegThumbSize[1])) break;
1438        }
1439        if (i == availableJpegThumbSizes.count) {
1440            ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1441                    __FUNCTION__, validatedParams.jpegThumbSize[0],
1442                    validatedParams.jpegThumbSize[1]);
1443            return BAD_VALUE;
1444        }
1445    }
1446
1447    // JPEG_THUMBNAIL_QUALITY
1448    int quality = newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1449    // also makes sure quality fits in uint8_t
1450    if (quality < 0 || quality > 100) {
1451        ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1452                __FUNCTION__, quality);
1453        return BAD_VALUE;
1454    }
1455    validatedParams.jpegThumbQuality = quality;
1456
1457    // JPEG_QUALITY
1458    quality = newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1459    // also makes sure quality fits in uint8_t
1460    if (quality < 0 || quality > 100) {
1461        ALOGE("%s: Requested JPEG quality %d is not supported",
1462                __FUNCTION__, quality);
1463        return BAD_VALUE;
1464    }
1465    validatedParams.jpegQuality = quality;
1466
1467    // ROTATION
1468    validatedParams.jpegRotation =
1469            newParams.getInt(CameraParameters::KEY_ROTATION);
1470    if (validatedParams.jpegRotation != 0 &&
1471            validatedParams.jpegRotation != 90 &&
1472            validatedParams.jpegRotation != 180 &&
1473            validatedParams.jpegRotation != 270) {
1474        ALOGE("%s: Requested picture rotation angle %d is not supported",
1475                __FUNCTION__, validatedParams.jpegRotation);
1476        return BAD_VALUE;
1477    }
1478
1479    // GPS
1480
1481    const char *gpsLatStr =
1482            newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1483    if (gpsLatStr != NULL) {
1484        const char *gpsLongStr =
1485                newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1486        const char *gpsAltitudeStr =
1487                newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1488        const char *gpsTimeStr =
1489                newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1490        const char *gpsProcMethodStr =
1491                newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1492        if (gpsLongStr == NULL ||
1493                gpsAltitudeStr == NULL ||
1494                gpsTimeStr == NULL ||
1495                gpsProcMethodStr == NULL) {
1496            ALOGE("%s: Incomplete set of GPS parameters provided",
1497                    __FUNCTION__);
1498            return BAD_VALUE;
1499        }
1500        char *endPtr;
1501        errno = 0;
1502        validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1503        if (errno || endPtr == gpsLatStr) {
1504            ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1505            return BAD_VALUE;
1506        }
1507        errno = 0;
1508        validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1509        if (errno || endPtr == gpsLongStr) {
1510            ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1511            return BAD_VALUE;
1512        }
1513        errno = 0;
1514        validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1515        if (errno || endPtr == gpsAltitudeStr) {
1516            ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1517                    gpsAltitudeStr);
1518            return BAD_VALUE;
1519        }
1520        errno = 0;
1521        validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1522        if (errno || endPtr == gpsTimeStr) {
1523            ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1524            return BAD_VALUE;
1525        }
1526        validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1527
1528        validatedParams.gpsEnabled = true;
1529    } else {
1530        validatedParams.gpsEnabled = false;
1531    }
1532
1533    // EFFECT
1534    validatedParams.effectMode = effectModeStringToEnum(
1535        newParams.get(CameraParameters::KEY_EFFECT) );
1536    if (validatedParams.effectMode != effectMode) {
1537        camera_metadata_ro_entry_t availableEffectModes =
1538            staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1539        for (i = 0; i < availableEffectModes.count; i++) {
1540            if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1541        }
1542        if (i == availableEffectModes.count) {
1543            ALOGE("%s: Requested effect mode \"%s\" is not supported",
1544                    __FUNCTION__,
1545                    newParams.get(CameraParameters::KEY_EFFECT) );
1546            return BAD_VALUE;
1547        }
1548    }
1549
1550    // ANTIBANDING
1551    validatedParams.antibandingMode = abModeStringToEnum(
1552        newParams.get(CameraParameters::KEY_ANTIBANDING) );
1553    if (validatedParams.antibandingMode != antibandingMode) {
1554        camera_metadata_ro_entry_t availableAbModes =
1555            staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1556        for (i = 0; i < availableAbModes.count; i++) {
1557            if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1558                break;
1559        }
1560        if (i == availableAbModes.count) {
1561            ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1562                    __FUNCTION__,
1563                    newParams.get(CameraParameters::KEY_ANTIBANDING));
1564            return BAD_VALUE;
1565        }
1566    }
1567
1568    // SCENE_MODE
1569    validatedParams.sceneMode = sceneModeStringToEnum(
1570        newParams.get(CameraParameters::KEY_SCENE_MODE) );
1571    if (validatedParams.sceneMode != sceneMode &&
1572            validatedParams.sceneMode !=
1573            ANDROID_CONTROL_SCENE_MODE_DISABLED) {
1574        camera_metadata_ro_entry_t availableSceneModes =
1575            staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1576        for (i = 0; i < availableSceneModes.count; i++) {
1577            if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1578                break;
1579        }
1580        if (i == availableSceneModes.count) {
1581            ALOGE("%s: Requested scene mode \"%s\" is not supported",
1582                    __FUNCTION__,
1583                    newParams.get(CameraParameters::KEY_SCENE_MODE));
1584            return BAD_VALUE;
1585        }
1586    }
1587    bool sceneModeSet =
1588            validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_DISABLED;
1589
1590    // FLASH_MODE
1591    if (sceneModeSet) {
1592        validatedParams.flashMode =
1593                fastInfo.sceneModeOverrides.
1594                        valueFor(validatedParams.sceneMode).flashMode;
1595    } else {
1596        validatedParams.flashMode = FLASH_MODE_INVALID;
1597    }
1598    if (validatedParams.flashMode == FLASH_MODE_INVALID) {
1599        validatedParams.flashMode = flashModeStringToEnum(
1600            newParams.get(CameraParameters::KEY_FLASH_MODE) );
1601    }
1602
1603    if (validatedParams.flashMode != flashMode) {
1604        camera_metadata_ro_entry_t flashAvailable =
1605            staticInfo(ANDROID_FLASH_INFO_AVAILABLE, 1, 1);
1606        if (!flashAvailable.data.u8[0] &&
1607                validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1608            ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1609                    "No flash on device", __FUNCTION__,
1610                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1611            return BAD_VALUE;
1612        } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1613            camera_metadata_ro_entry_t availableAeModes =
1614                staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1615            for (i = 0; i < availableAeModes.count; i++) {
1616                if (validatedParams.flashMode == availableAeModes.data.u8[i])
1617                    break;
1618            }
1619            if (i == availableAeModes.count) {
1620                ALOGE("%s: Requested flash mode \"%s\" is not supported",
1621                        __FUNCTION__,
1622                        newParams.get(CameraParameters::KEY_FLASH_MODE));
1623                return BAD_VALUE;
1624            }
1625        } else if (validatedParams.flashMode == -1) {
1626            ALOGE("%s: Requested flash mode \"%s\" is unknown",
1627                    __FUNCTION__,
1628                    newParams.get(CameraParameters::KEY_FLASH_MODE));
1629            return BAD_VALUE;
1630        }
1631        // Update in case of override
1632        newParams.set(CameraParameters::KEY_FLASH_MODE,
1633                flashModeEnumToString(validatedParams.flashMode));
1634    }
1635
1636    // WHITE_BALANCE
1637    if (sceneModeSet) {
1638        validatedParams.wbMode =
1639                fastInfo.sceneModeOverrides.
1640                        valueFor(validatedParams.sceneMode).wbMode;
1641    } else {
1642        validatedParams.wbMode = ANDROID_CONTROL_AWB_MODE_OFF;
1643    }
1644    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_MODE_OFF) {
1645        validatedParams.wbMode = wbModeStringToEnum(
1646            newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1647    }
1648    if (validatedParams.wbMode != wbMode) {
1649        camera_metadata_ro_entry_t availableWbModes =
1650            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES, 0, 0, false);
1651        for (i = 0; i < availableWbModes.count; i++) {
1652            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1653        }
1654        if (i == availableWbModes.count) {
1655            ALOGE("%s: Requested white balance mode %s is not supported",
1656                    __FUNCTION__,
1657                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1658            return BAD_VALUE;
1659        }
1660        // Update in case of override
1661        newParams.set(CameraParameters::KEY_WHITE_BALANCE,
1662                wbModeEnumToString(validatedParams.wbMode));
1663    }
1664
1665    // FOCUS_MODE
1666    if (sceneModeSet) {
1667        validatedParams.focusMode =
1668                fastInfo.sceneModeOverrides.
1669                        valueFor(validatedParams.sceneMode).focusMode;
1670    } else {
1671        validatedParams.focusMode = FOCUS_MODE_INVALID;
1672    }
1673    if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
1674        validatedParams.focusMode = focusModeStringToEnum(
1675                newParams.get(CameraParameters::KEY_FOCUS_MODE) );
1676    }
1677    if (validatedParams.focusMode != focusMode) {
1678        validatedParams.currentAfTriggerId = -1;
1679        if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1680            camera_metadata_ro_entry_t minFocusDistance =
1681                staticInfo(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, 0, 0,
1682                        false);
1683            if (minFocusDistance.count && minFocusDistance.data.f[0] == 0) {
1684                ALOGE("%s: Requested focus mode \"%s\" is not available: "
1685                        "fixed focus lens",
1686                        __FUNCTION__,
1687                        newParams.get(CameraParameters::KEY_FOCUS_MODE));
1688                return BAD_VALUE;
1689            } else if (validatedParams.focusMode !=
1690                    Parameters::FOCUS_MODE_INFINITY) {
1691                camera_metadata_ro_entry_t availableFocusModes =
1692                    staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1693                for (i = 0; i < availableFocusModes.count; i++) {
1694                    if (validatedParams.focusMode ==
1695                            availableFocusModes.data.u8[i]) break;
1696                }
1697                if (i == availableFocusModes.count) {
1698                    ALOGE("%s: Requested focus mode \"%s\" is not supported",
1699                            __FUNCTION__,
1700                            newParams.get(CameraParameters::KEY_FOCUS_MODE));
1701                    return BAD_VALUE;
1702                }
1703            }
1704        }
1705        validatedParams.focusState = ANDROID_CONTROL_AF_STATE_INACTIVE;
1706        // Always reset shadow focus mode to avoid reverting settings
1707        validatedParams.shadowFocusMode = FOCUS_MODE_INVALID;
1708        // Update in case of override
1709        newParams.set(CameraParameters::KEY_FOCUS_MODE,
1710                focusModeEnumToString(validatedParams.focusMode));
1711    } else {
1712        validatedParams.currentAfTriggerId = currentAfTriggerId;
1713    }
1714
1715    // FOCUS_AREAS
1716    res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1717            &validatedParams.focusingAreas);
1718    size_t maxAfRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
1719              Parameters::NUM_REGION, Parameters::NUM_REGION).
1720              data.i32[Parameters::REGION_AF];
1721    if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1722            maxAfRegions, AREA_KIND_FOCUS);
1723    if (res != OK) {
1724        ALOGE("%s: Requested focus areas are malformed: %s",
1725                __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1726        return BAD_VALUE;
1727    }
1728
1729    // EXPOSURE_COMPENSATION
1730    validatedParams.exposureCompensation =
1731        newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1732    camera_metadata_ro_entry_t exposureCompensationRange =
1733        staticInfo(ANDROID_CONTROL_AE_COMPENSATION_RANGE);
1734    if ((validatedParams.exposureCompensation <
1735            exposureCompensationRange.data.i32[0]) ||
1736        (validatedParams.exposureCompensation >
1737            exposureCompensationRange.data.i32[1])) {
1738        ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1739                __FUNCTION__, validatedParams.exposureCompensation);
1740        return BAD_VALUE;
1741    }
1742
1743    // AUTO_EXPOSURE_LOCK (always supported)
1744    validatedParams.autoExposureLock = boolFromString(
1745        newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1746
1747    // AUTO_WHITEBALANCE_LOCK (always supported)
1748    validatedParams.autoWhiteBalanceLock = boolFromString(
1749        newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1750
1751    // METERING_AREAS
1752    size_t maxAeRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
1753            Parameters::NUM_REGION, Parameters::NUM_REGION).
1754            data.i32[Parameters::REGION_AE];
1755    res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1756            &validatedParams.meteringAreas);
1757    if (res == OK) {
1758        res = validateAreas(validatedParams.meteringAreas, maxAeRegions,
1759                            AREA_KIND_METERING);
1760    }
1761    if (res != OK) {
1762        ALOGE("%s: Requested metering areas are malformed: %s",
1763                __FUNCTION__,
1764                newParams.get(CameraParameters::KEY_METERING_AREAS));
1765        return BAD_VALUE;
1766    }
1767
1768    // ZOOM
1769    validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1770    if (validatedParams.zoom < 0
1771                || validatedParams.zoom >= (int)NUM_ZOOM_STEPS) {
1772        ALOGE("%s: Requested zoom level %d is not supported",
1773                __FUNCTION__, validatedParams.zoom);
1774        return BAD_VALUE;
1775    }
1776
1777    // VIDEO_SIZE
1778    newParams.getVideoSize(&validatedParams.videoWidth,
1779            &validatedParams.videoHeight);
1780    if (validatedParams.videoWidth != videoWidth ||
1781            validatedParams.videoHeight != videoHeight) {
1782        if (state == RECORD) {
1783            ALOGW("%s: Video size cannot be updated (from %d x %d to %d x %d)"
1784                    " when recording is active! Ignore the size update!",
1785                    __FUNCTION__, videoWidth, videoHeight, validatedParams.videoWidth,
1786                    validatedParams.videoHeight);
1787            validatedParams.videoWidth = videoWidth;
1788            validatedParams.videoHeight = videoHeight;
1789            newParams.setVideoSize(videoWidth, videoHeight);
1790        } else {
1791            for (i = 0; i < availableVideoSizes.size(); i++) {
1792                if ((availableVideoSizes[i].width ==
1793                        validatedParams.videoWidth) &&
1794                    (availableVideoSizes[i].height ==
1795                        validatedParams.videoHeight)) break;
1796            }
1797            if (i == availableVideoSizes.size()) {
1798                ALOGE("%s: Requested video size %d x %d is not supported",
1799                        __FUNCTION__, validatedParams.videoWidth,
1800                        validatedParams.videoHeight);
1801                return BAD_VALUE;
1802            }
1803        }
1804    }
1805
1806    // VIDEO_STABILIZATION
1807    validatedParams.videoStabilization = boolFromString(
1808        newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1809    camera_metadata_ro_entry_t availableVideoStabilizationModes =
1810        staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 0, 0,
1811                false);
1812    if (validatedParams.videoStabilization &&
1813            availableVideoStabilizationModes.count == 1) {
1814        ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1815    }
1816
1817    // LIGHTFX
1818    validatedParams.lightFx = lightFxStringToEnum(
1819        newParams.get(CameraParameters::KEY_LIGHTFX));
1820
1821    /** Update internal parameters */
1822
1823    *this = validatedParams;
1824    updateOverriddenJpegSize();
1825
1826    /** Update external parameters calculated from the internal ones */
1827
1828    // HORIZONTAL/VERTICAL FIELD OF VIEW
1829    float horizFov, vertFov;
1830    res = calculatePictureFovs(&horizFov, &vertFov);
1831    if (res != OK) {
1832        ALOGE("%s: Can't calculate FOVs", __FUNCTION__);
1833        // continue so parameters are at least consistent
1834    }
1835    newParams.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE,
1836            horizFov);
1837    newParams.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE,
1838            vertFov);
1839    ALOGV("Current still picture FOV: %f x %f deg", horizFov, vertFov);
1840
1841    // Need to flatten again in case of overrides
1842    paramsFlattened = newParams.flatten();
1843    params = newParams;
1844
1845    return OK;
1846}
1847
1848status_t Parameters::updateRequest(CameraMetadata *request) const {
1849    ATRACE_CALL();
1850    status_t res;
1851
1852    /**
1853     * Mixin default important security values
1854     * - android.led.transmit = defaulted ON
1855     */
1856    camera_metadata_ro_entry_t entry = staticInfo(ANDROID_LED_AVAILABLE_LEDS,
1857                                                  /*minimumCount*/0,
1858                                                  /*maximumCount*/0,
1859                                                  /*required*/false);
1860    for(size_t i = 0; i < entry.count; ++i) {
1861        uint8_t led = entry.data.u8[i];
1862
1863        switch(led) {
1864            // Transmit LED is unconditionally on when using
1865            // the android.hardware.Camera API
1866            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1867                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1868                res = request->update(ANDROID_LED_TRANSMIT,
1869                                      &transmitDefault, 1);
1870                if (res != OK) return res;
1871                break;
1872            }
1873        }
1874    }
1875
1876    /**
1877     * Construct metadata from parameters
1878     */
1879
1880    uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
1881    res = request->update(ANDROID_REQUEST_METADATA_MODE,
1882            &metadataMode, 1);
1883    if (res != OK) return res;
1884
1885    camera_metadata_entry_t intent =
1886            request->find(ANDROID_CONTROL_CAPTURE_INTENT);
1887
1888    if (intent.count == 0) return BAD_VALUE;
1889
1890    if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
1891        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1892                fastInfo.bestStillCaptureFpsRange, 2);
1893    } else {
1894        res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1895                previewFpsRange, 2);
1896    }
1897    if (res != OK) return res;
1898
1899    uint8_t reqWbLock = autoWhiteBalanceLock ?
1900            ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1901    res = request->update(ANDROID_CONTROL_AWB_LOCK,
1902            &reqWbLock, 1);
1903
1904    res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1905            &effectMode, 1);
1906    if (res != OK) return res;
1907    res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1908            &antibandingMode, 1);
1909    if (res != OK) return res;
1910
1911    // android.hardware.Camera requires that when face detect is enabled, the
1912    // camera is in a face-priority mode. HAL2 splits this into separate parts
1913    // (face detection statistics and face priority scene mode). Map from other
1914    // to the other.
1915    bool sceneModeActive =
1916            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_DISABLED;
1917    uint8_t reqControlMode = ANDROID_CONTROL_MODE_AUTO;
1918    if (enableFaceDetect || sceneModeActive) {
1919        reqControlMode = ANDROID_CONTROL_MODE_USE_SCENE_MODE;
1920    }
1921    res = request->update(ANDROID_CONTROL_MODE,
1922            &reqControlMode, 1);
1923    if (res != OK) return res;
1924
1925    uint8_t reqSceneMode =
1926            sceneModeActive ? sceneMode :
1927            enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1928            (uint8_t)ANDROID_CONTROL_SCENE_MODE_DISABLED;
1929    res = request->update(ANDROID_CONTROL_SCENE_MODE,
1930            &reqSceneMode, 1);
1931    if (res != OK) return res;
1932
1933    uint8_t reqFlashMode = ANDROID_FLASH_MODE_OFF;
1934    uint8_t reqAeMode = ANDROID_CONTROL_AE_MODE_OFF;
1935    switch (flashMode) {
1936        case Parameters::FLASH_MODE_OFF:
1937            reqAeMode = ANDROID_CONTROL_AE_MODE_ON; break;
1938        case Parameters::FLASH_MODE_AUTO:
1939            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; break;
1940        case Parameters::FLASH_MODE_ON:
1941            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH; break;
1942        case Parameters::FLASH_MODE_TORCH:
1943            reqAeMode = ANDROID_CONTROL_AE_MODE_ON;
1944            reqFlashMode = ANDROID_FLASH_MODE_TORCH;
1945            break;
1946        case Parameters::FLASH_MODE_RED_EYE:
1947            reqAeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; break;
1948        default:
1949            ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1950                    cameraId, flashMode);
1951                return BAD_VALUE;
1952    }
1953    res = request->update(ANDROID_FLASH_MODE,
1954            &reqFlashMode, 1);
1955    if (res != OK) return res;
1956    res = request->update(ANDROID_CONTROL_AE_MODE,
1957            &reqAeMode, 1);
1958    if (res != OK) return res;
1959
1960    uint8_t reqAeLock = autoExposureLock ?
1961            ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1962    res = request->update(ANDROID_CONTROL_AE_LOCK,
1963            &reqAeLock, 1);
1964    if (res != OK) return res;
1965
1966    res = request->update(ANDROID_CONTROL_AWB_MODE,
1967            &wbMode, 1);
1968    if (res != OK) return res;
1969
1970    float reqFocusDistance = 0; // infinity focus in diopters
1971    uint8_t reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1972    switch (focusMode) {
1973        case Parameters::FOCUS_MODE_AUTO:
1974        case Parameters::FOCUS_MODE_MACRO:
1975        case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1976        case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1977        case Parameters::FOCUS_MODE_EDOF:
1978            reqFocusMode = focusMode;
1979            break;
1980        case Parameters::FOCUS_MODE_INFINITY:
1981        case Parameters::FOCUS_MODE_FIXED:
1982            reqFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
1983            break;
1984        default:
1985                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1986                        cameraId, focusMode);
1987                return BAD_VALUE;
1988    }
1989    res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1990            &reqFocusDistance, 1);
1991    if (res != OK) return res;
1992    res = request->update(ANDROID_CONTROL_AF_MODE,
1993            &reqFocusMode, 1);
1994    if (res != OK) return res;
1995
1996    size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1997    int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1998    for (size_t i = 0, j = 0; i < reqFocusingAreasSize; i += 5, j++) {
1999        if (focusingAreas[j].weight != 0) {
2000            reqFocusingAreas[i + 0] =
2001                    normalizedXToArray(focusingAreas[j].left);
2002            reqFocusingAreas[i + 1] =
2003                    normalizedYToArray(focusingAreas[j].top);
2004            reqFocusingAreas[i + 2] =
2005                    normalizedXToArray(focusingAreas[j].right);
2006            reqFocusingAreas[i + 3] =
2007                    normalizedYToArray(focusingAreas[j].bottom);
2008        } else {
2009            reqFocusingAreas[i + 0] = 0;
2010            reqFocusingAreas[i + 1] = 0;
2011            reqFocusingAreas[i + 2] = 0;
2012            reqFocusingAreas[i + 3] = 0;
2013        }
2014        reqFocusingAreas[i + 4] = focusingAreas[j].weight;
2015    }
2016    res = request->update(ANDROID_CONTROL_AF_REGIONS,
2017            reqFocusingAreas, reqFocusingAreasSize);
2018    if (res != OK) return res;
2019    delete[] reqFocusingAreas;
2020
2021    res = request->update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2022            &exposureCompensation, 1);
2023    if (res != OK) return res;
2024
2025    size_t reqMeteringAreasSize = meteringAreas.size() * 5;
2026    int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
2027    for (size_t i = 0, j = 0; i < reqMeteringAreasSize; i += 5, j++) {
2028        if (meteringAreas[j].weight != 0) {
2029            reqMeteringAreas[i + 0] =
2030                normalizedXToArray(meteringAreas[j].left);
2031            reqMeteringAreas[i + 1] =
2032                normalizedYToArray(meteringAreas[j].top);
2033            reqMeteringAreas[i + 2] =
2034                normalizedXToArray(meteringAreas[j].right);
2035            reqMeteringAreas[i + 3] =
2036                normalizedYToArray(meteringAreas[j].bottom);
2037        } else {
2038            reqMeteringAreas[i + 0] = 0;
2039            reqMeteringAreas[i + 1] = 0;
2040            reqMeteringAreas[i + 2] = 0;
2041            reqMeteringAreas[i + 3] = 0;
2042        }
2043        reqMeteringAreas[i + 4] = meteringAreas[j].weight;
2044    }
2045    res = request->update(ANDROID_CONTROL_AE_REGIONS,
2046            reqMeteringAreas, reqMeteringAreasSize);
2047    if (res != OK) return res;
2048
2049    // Set awb regions to be the same as the metering regions if allowed
2050    size_t maxAwbRegions = (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS,
2051            Parameters::NUM_REGION, Parameters::NUM_REGION).
2052            data.i32[Parameters::REGION_AWB];
2053    if (maxAwbRegions > 0) {
2054        if (maxAwbRegions >= meteringAreas.size()) {
2055            res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2056                    reqMeteringAreas, reqMeteringAreasSize);
2057        } else {
2058            // Ensure the awb regions are zeroed if the region count is too high.
2059            int32_t zeroedAwbAreas[5] = {0, 0, 0, 0, 0};
2060            res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2061                    zeroedAwbAreas, sizeof(zeroedAwbAreas)/sizeof(int32_t));
2062        }
2063        if (res != OK) return res;
2064    }
2065
2066    delete[] reqMeteringAreas;
2067
2068    /* don't include jpeg thumbnail size - it's valid for
2069       it to be set to (0,0), meaning 'no thumbnail' */
2070    CropRegion crop = calculateCropRegion( (CropRegion::Outputs)(
2071            CropRegion::OUTPUT_PREVIEW     |
2072            CropRegion::OUTPUT_VIDEO       |
2073            CropRegion::OUTPUT_PICTURE    ));
2074    int32_t reqCropRegion[4] = {
2075        static_cast<int32_t>(crop.left),
2076        static_cast<int32_t>(crop.top),
2077        static_cast<int32_t>(crop.width),
2078        static_cast<int32_t>(crop.height)
2079    };
2080    res = request->update(ANDROID_SCALER_CROP_REGION,
2081            reqCropRegion, 4);
2082    if (res != OK) return res;
2083
2084    uint8_t reqVstabMode = videoStabilization ?
2085            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON :
2086            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2087    res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2088            &reqVstabMode, 1);
2089    if (res != OK) return res;
2090
2091    uint8_t reqFaceDetectMode = enableFaceDetect ?
2092            fastInfo.bestFaceDetectMode :
2093            (uint8_t)ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2094    res = request->update(ANDROID_STATISTICS_FACE_DETECT_MODE,
2095            &reqFaceDetectMode, 1);
2096    if (res != OK) return res;
2097
2098    return OK;
2099}
2100
2101status_t Parameters::updateRequestJpeg(CameraMetadata *request) const {
2102    status_t res;
2103
2104    res = request->update(ANDROID_JPEG_THUMBNAIL_SIZE,
2105            jpegThumbSize, 2);
2106    if (res != OK) return res;
2107    res = request->update(ANDROID_JPEG_THUMBNAIL_QUALITY,
2108            &jpegThumbQuality, 1);
2109    if (res != OK) return res;
2110    res = request->update(ANDROID_JPEG_QUALITY,
2111            &jpegQuality, 1);
2112    if (res != OK) return res;
2113    res = request->update(
2114            ANDROID_JPEG_ORIENTATION,
2115            &jpegRotation, 1);
2116    if (res != OK) return res;
2117
2118    if (gpsEnabled) {
2119        res = request->update(
2120                ANDROID_JPEG_GPS_COORDINATES,
2121                gpsCoordinates, 3);
2122        if (res != OK) return res;
2123        res = request->update(
2124                ANDROID_JPEG_GPS_TIMESTAMP,
2125                &gpsTimestamp, 1);
2126        if (res != OK) return res;
2127        res = request->update(
2128                ANDROID_JPEG_GPS_PROCESSING_METHOD,
2129                gpsProcessingMethod);
2130        if (res != OK) return res;
2131    } else {
2132        res = request->erase(ANDROID_JPEG_GPS_COORDINATES);
2133        if (res != OK) return res;
2134        res = request->erase(ANDROID_JPEG_GPS_TIMESTAMP);
2135        if (res != OK) return res;
2136        res = request->erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
2137        if (res != OK) return res;
2138    }
2139    return OK;
2140}
2141
2142status_t Parameters::overrideJpegSizeByVideoSize() {
2143    if (pictureSizeOverriden) {
2144        ALOGV("Picture size has been overridden. Skip overriding");
2145        return OK;
2146    }
2147
2148    pictureSizeOverriden = true;
2149    pictureWidthLastSet = pictureWidth;
2150    pictureHeightLastSet = pictureHeight;
2151    pictureWidth = videoWidth;
2152    pictureHeight = videoHeight;
2153    // This change of picture size is invisible to app layer.
2154    // Do not update app visible params
2155    return OK;
2156}
2157
2158status_t Parameters::updateOverriddenJpegSize() {
2159    if (!pictureSizeOverriden) {
2160        ALOGV("Picture size has not been overridden. Skip checking");
2161        return OK;
2162    }
2163
2164    pictureWidthLastSet = pictureWidth;
2165    pictureHeightLastSet = pictureHeight;
2166
2167    if (pictureWidth <= videoWidth && pictureHeight <= videoHeight) {
2168        // Picture size is now smaller than video size. No need to override anymore
2169        return recoverOverriddenJpegSize();
2170    }
2171
2172    pictureWidth = videoWidth;
2173    pictureHeight = videoHeight;
2174
2175    return OK;
2176}
2177
2178status_t Parameters::recoverOverriddenJpegSize() {
2179    if (!pictureSizeOverriden) {
2180        ALOGV("Picture size has not been overridden. Skip recovering");
2181        return OK;
2182    }
2183    pictureSizeOverriden = false;
2184    pictureWidth = pictureWidthLastSet;
2185    pictureHeight = pictureHeightLastSet;
2186    return OK;
2187}
2188
2189const char* Parameters::getStateName(State state) {
2190#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
2191    switch(state) {
2192        CASE_ENUM_TO_CHAR(DISCONNECTED)
2193        CASE_ENUM_TO_CHAR(STOPPED)
2194        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
2195        CASE_ENUM_TO_CHAR(PREVIEW)
2196        CASE_ENUM_TO_CHAR(RECORD)
2197        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
2198        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
2199        default:
2200            return "Unknown state!";
2201            break;
2202    }
2203#undef CASE_ENUM_TO_CHAR
2204}
2205
2206int Parameters::formatStringToEnum(const char *format) {
2207    return CameraParameters::previewFormatToEnum(format);
2208}
2209
2210const char* Parameters::formatEnumToString(int format) {
2211    const char *fmt;
2212    switch(format) {
2213        case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2214            fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2215            break;
2216        case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2217            fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2218            break;
2219        case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2220            fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2221            break;
2222        case HAL_PIXEL_FORMAT_YV12:        // YV12
2223            fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2224            break;
2225        case HAL_PIXEL_FORMAT_RGB_565:     // RGB565
2226            fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2227            break;
2228        case HAL_PIXEL_FORMAT_RGBA_8888:   // RGBA8888
2229            fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2230            break;
2231        case HAL_PIXEL_FORMAT_RAW_SENSOR:
2232            ALOGW("Raw sensor preview format requested.");
2233            fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2234            break;
2235        default:
2236            ALOGE("%s: Unknown preview format: %x",
2237                    __FUNCTION__,  format);
2238            fmt = NULL;
2239            break;
2240    }
2241    return fmt;
2242}
2243
2244int Parameters::wbModeStringToEnum(const char *wbMode) {
2245    return
2246        !wbMode ?
2247            ANDROID_CONTROL_AWB_MODE_AUTO :
2248        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2249            ANDROID_CONTROL_AWB_MODE_AUTO :
2250        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2251            ANDROID_CONTROL_AWB_MODE_INCANDESCENT :
2252        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2253            ANDROID_CONTROL_AWB_MODE_FLUORESCENT :
2254        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2255            ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT :
2256        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2257            ANDROID_CONTROL_AWB_MODE_DAYLIGHT :
2258        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2259            ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT :
2260        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2261            ANDROID_CONTROL_AWB_MODE_TWILIGHT :
2262        !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2263            ANDROID_CONTROL_AWB_MODE_SHADE :
2264        -1;
2265}
2266
2267const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
2268    switch (wbMode) {
2269        case ANDROID_CONTROL_AWB_MODE_AUTO:
2270            return CameraParameters::WHITE_BALANCE_AUTO;
2271        case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
2272            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
2273        case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
2274            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
2275        case ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT:
2276            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
2277        case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
2278            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
2279        case ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
2280            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
2281        case ANDROID_CONTROL_AWB_MODE_TWILIGHT:
2282            return CameraParameters::WHITE_BALANCE_TWILIGHT;
2283        case ANDROID_CONTROL_AWB_MODE_SHADE:
2284            return CameraParameters::WHITE_BALANCE_SHADE;
2285        default:
2286            ALOGE("%s: Unknown AWB mode enum: %d",
2287                    __FUNCTION__, wbMode);
2288            return "unknown";
2289    }
2290}
2291
2292int Parameters::effectModeStringToEnum(const char *effectMode) {
2293    return
2294        !effectMode ?
2295            ANDROID_CONTROL_EFFECT_MODE_OFF :
2296        !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2297            ANDROID_CONTROL_EFFECT_MODE_OFF :
2298        !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2299            ANDROID_CONTROL_EFFECT_MODE_MONO :
2300        !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2301            ANDROID_CONTROL_EFFECT_MODE_NEGATIVE :
2302        !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2303            ANDROID_CONTROL_EFFECT_MODE_SOLARIZE :
2304        !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2305            ANDROID_CONTROL_EFFECT_MODE_SEPIA :
2306        !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2307            ANDROID_CONTROL_EFFECT_MODE_POSTERIZE :
2308        !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2309            ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD :
2310        !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2311            ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD :
2312        !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2313            ANDROID_CONTROL_EFFECT_MODE_AQUA :
2314        -1;
2315}
2316
2317int Parameters::abModeStringToEnum(const char *abMode) {
2318    return
2319        !abMode ?
2320            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2321        !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2322            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO :
2323        !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2324            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF :
2325        !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2326            ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ :
2327        !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2328            ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ :
2329        -1;
2330}
2331
2332int Parameters::sceneModeStringToEnum(const char *sceneMode) {
2333    return
2334        !sceneMode ?
2335            ANDROID_CONTROL_SCENE_MODE_DISABLED :
2336        !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2337            ANDROID_CONTROL_SCENE_MODE_DISABLED :
2338        !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2339            ANDROID_CONTROL_SCENE_MODE_ACTION :
2340        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2341            ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2342        !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2343            ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2344        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2345            ANDROID_CONTROL_SCENE_MODE_NIGHT :
2346        !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2347            ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2348        !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2349            ANDROID_CONTROL_SCENE_MODE_THEATRE :
2350        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2351            ANDROID_CONTROL_SCENE_MODE_BEACH :
2352        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2353            ANDROID_CONTROL_SCENE_MODE_SNOW :
2354        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2355            ANDROID_CONTROL_SCENE_MODE_SUNSET :
2356        !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2357            ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2358        !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2359            ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2360        !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2361            ANDROID_CONTROL_SCENE_MODE_SPORTS :
2362        !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2363            ANDROID_CONTROL_SCENE_MODE_PARTY :
2364        !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2365            ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2366        !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2367            ANDROID_CONTROL_SCENE_MODE_BARCODE:
2368        -1;
2369}
2370
2371Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
2372        const char *flashMode) {
2373    return
2374        !flashMode ?
2375            Parameters::FLASH_MODE_INVALID :
2376        !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2377            Parameters::FLASH_MODE_OFF :
2378        !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2379            Parameters::FLASH_MODE_AUTO :
2380        !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2381            Parameters::FLASH_MODE_ON :
2382        !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2383            Parameters::FLASH_MODE_RED_EYE :
2384        !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2385            Parameters::FLASH_MODE_TORCH :
2386        Parameters::FLASH_MODE_INVALID;
2387}
2388
2389const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
2390    switch (flashMode) {
2391        case FLASH_MODE_OFF:
2392            return CameraParameters::FLASH_MODE_OFF;
2393        case FLASH_MODE_AUTO:
2394            return CameraParameters::FLASH_MODE_AUTO;
2395        case FLASH_MODE_ON:
2396            return CameraParameters::FLASH_MODE_ON;
2397        case FLASH_MODE_RED_EYE:
2398            return CameraParameters::FLASH_MODE_RED_EYE;
2399        case FLASH_MODE_TORCH:
2400            return CameraParameters::FLASH_MODE_TORCH;
2401        default:
2402            ALOGE("%s: Unknown flash mode enum %d",
2403                    __FUNCTION__, flashMode);
2404            return "unknown";
2405    }
2406}
2407
2408Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
2409        const char *focusMode) {
2410    return
2411        !focusMode ?
2412            Parameters::FOCUS_MODE_INVALID :
2413        !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2414            Parameters::FOCUS_MODE_AUTO :
2415        !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2416            Parameters::FOCUS_MODE_INFINITY :
2417        !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2418            Parameters::FOCUS_MODE_MACRO :
2419        !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2420            Parameters::FOCUS_MODE_FIXED :
2421        !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2422            Parameters::FOCUS_MODE_EDOF :
2423        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
2424            Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
2425        !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
2426            Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
2427        Parameters::FOCUS_MODE_INVALID;
2428}
2429
2430const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
2431    switch (focusMode) {
2432        case FOCUS_MODE_AUTO:
2433            return CameraParameters::FOCUS_MODE_AUTO;
2434        case FOCUS_MODE_MACRO:
2435            return CameraParameters::FOCUS_MODE_MACRO;
2436        case FOCUS_MODE_CONTINUOUS_VIDEO:
2437            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
2438        case FOCUS_MODE_CONTINUOUS_PICTURE:
2439            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
2440        case FOCUS_MODE_EDOF:
2441            return CameraParameters::FOCUS_MODE_EDOF;
2442        case FOCUS_MODE_INFINITY:
2443            return CameraParameters::FOCUS_MODE_INFINITY;
2444        case FOCUS_MODE_FIXED:
2445            return CameraParameters::FOCUS_MODE_FIXED;
2446        default:
2447            ALOGE("%s: Unknown focus mode enum: %d",
2448                    __FUNCTION__, focusMode);
2449            return "unknown";
2450    }
2451}
2452
2453Parameters::Parameters::lightFxMode_t Parameters::lightFxStringToEnum(
2454        const char *lightFxMode) {
2455    return
2456        !lightFxMode ?
2457            Parameters::LIGHTFX_NONE :
2458        !strcmp(lightFxMode, CameraParameters::LIGHTFX_LOWLIGHT) ?
2459            Parameters::LIGHTFX_LOWLIGHT :
2460        !strcmp(lightFxMode, CameraParameters::LIGHTFX_HDR) ?
2461            Parameters::LIGHTFX_HDR :
2462        Parameters::LIGHTFX_NONE;
2463}
2464
2465status_t Parameters::parseAreas(const char *areasCStr,
2466        Vector<Parameters::Area> *areas) {
2467    static const size_t NUM_FIELDS = 5;
2468    areas->clear();
2469    if (areasCStr == NULL) {
2470        // If no key exists, use default (0,0,0,0,0)
2471        areas->push();
2472        return OK;
2473    }
2474    String8 areasStr(areasCStr);
2475    ssize_t areaStart = areasStr.find("(", 0) + 1;
2476    while (areaStart != 0) {
2477        const char* area = areasStr.string() + areaStart;
2478        char *numEnd;
2479        int vals[NUM_FIELDS];
2480        for (size_t i = 0; i < NUM_FIELDS; i++) {
2481            errno = 0;
2482            vals[i] = strtol(area, &numEnd, 10);
2483            if (errno || numEnd == area) return BAD_VALUE;
2484            area = numEnd + 1;
2485        }
2486        areas->push(Parameters::Area(
2487            vals[0], vals[1], vals[2], vals[3], vals[4]) );
2488        areaStart = areasStr.find("(", areaStart) + 1;
2489    }
2490    return OK;
2491}
2492
2493status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
2494                                      size_t maxRegions,
2495                                      AreaKind areaKind) const {
2496    // Definition of valid area can be found in
2497    // include/camera/CameraParameters.h
2498    if (areas.size() == 0) return BAD_VALUE;
2499    if (areas.size() == 1) {
2500        if (areas[0].left == 0 &&
2501                areas[0].top == 0 &&
2502                areas[0].right == 0 &&
2503                areas[0].bottom == 0 &&
2504                areas[0].weight == 0) {
2505            // Single (0,0,0,0,0) entry is always valid (== driver decides)
2506            return OK;
2507        }
2508    }
2509
2510    // fixed focus can only set (0,0,0,0,0) focus area
2511    if (areaKind == AREA_KIND_FOCUS && focusMode == FOCUS_MODE_FIXED) {
2512        return BAD_VALUE;
2513    }
2514
2515    if (areas.size() > maxRegions) {
2516        ALOGE("%s: Too many areas requested: %zu",
2517                __FUNCTION__, areas.size());
2518        return BAD_VALUE;
2519    }
2520
2521    for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2522         a != areas.end(); a++) {
2523        if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2524        if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2525        if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2526        if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2527        if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2528        if (a->left >= a->right) return BAD_VALUE;
2529        if (a->top >= a->bottom) return BAD_VALUE;
2530    }
2531    return OK;
2532}
2533
2534bool Parameters::boolFromString(const char *boolStr) {
2535    return !boolStr ? false :
2536        !strcmp(boolStr, CameraParameters::TRUE) ? true :
2537        false;
2538}
2539
2540int Parameters::degToTransform(int degrees, bool mirror) {
2541    if (!mirror) {
2542        if (degrees == 0) return 0;
2543        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2544        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2545        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2546    } else {  // Do mirror (horizontal flip)
2547        if (degrees == 0) {           // FLIP_H and ROT_0
2548            return HAL_TRANSFORM_FLIP_H;
2549        } else if (degrees == 90) {   // FLIP_H and ROT_90
2550            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2551        } else if (degrees == 180) {  // FLIP_H and ROT_180
2552            return HAL_TRANSFORM_FLIP_V;
2553        } else if (degrees == 270) {  // FLIP_H and ROT_270
2554            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2555        }
2556    }
2557    ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2558    return -1;
2559}
2560
2561int Parameters::cropXToArray(int x) const {
2562    ALOG_ASSERT(x >= 0, "Crop-relative X coordinate = '%d' is out of bounds"
2563                         "(lower = 0)", x);
2564
2565    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2566    ALOG_ASSERT(x < previewCrop.width, "Crop-relative X coordinate = '%d' "
2567                    "is out of bounds (upper = %f)", x, previewCrop.width);
2568
2569    int ret = x + previewCrop.left;
2570
2571    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayWidth),
2572        "Calculated pixel array value X = '%d' is out of bounds (upper = %d)",
2573        ret, fastInfo.arrayWidth);
2574    return ret;
2575}
2576
2577int Parameters::cropYToArray(int y) const {
2578    ALOG_ASSERT(y >= 0, "Crop-relative Y coordinate = '%d' is out of bounds "
2579        "(lower = 0)", y);
2580
2581    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2582    ALOG_ASSERT(y < previewCrop.height, "Crop-relative Y coordinate = '%d' is "
2583                "out of bounds (upper = %f)", y, previewCrop.height);
2584
2585    int ret = y + previewCrop.top;
2586
2587    ALOG_ASSERT( (ret >= 0 && ret < fastInfo.arrayHeight),
2588        "Calculated pixel array value Y = '%d' is out of bounds (upper = %d)",
2589        ret, fastInfo.arrayHeight);
2590
2591    return ret;
2592
2593}
2594
2595int Parameters::normalizedXToCrop(int x) const {
2596    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2597    return (x + 1000) * (previewCrop.width - 1) / 2000;
2598}
2599
2600int Parameters::normalizedYToCrop(int y) const {
2601    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2602    return (y + 1000) * (previewCrop.height - 1) / 2000;
2603}
2604
2605int Parameters::arrayXToCrop(int x) const {
2606    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2607    return x - previewCrop.left;
2608}
2609
2610int Parameters::arrayYToCrop(int y) const {
2611    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2612    return y - previewCrop.top;
2613}
2614
2615int Parameters::cropXToNormalized(int x) const {
2616    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2617    return x * 2000 / (previewCrop.width - 1) - 1000;
2618}
2619
2620int Parameters::cropYToNormalized(int y) const {
2621    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW);
2622    return y * 2000 / (previewCrop.height - 1) - 1000;
2623}
2624
2625int Parameters::arrayXToNormalized(int width) const {
2626    int ret = cropXToNormalized(arrayXToCrop(width));
2627
2628    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of "
2629        "lower bounds %d", ret);
2630    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of "
2631        "upper bounds %d", ret);
2632
2633    // Work-around for HAL pre-scaling the coordinates themselves
2634    if (quirks.meteringCropRegion) {
2635        return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2636    }
2637
2638    return ret;
2639}
2640
2641int Parameters::arrayYToNormalized(int height) const {
2642    int ret = cropYToNormalized(arrayYToCrop(height));
2643
2644    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds"
2645        " %d", ret);
2646    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds"
2647        " %d", ret);
2648
2649    // Work-around for HAL pre-scaling the coordinates themselves
2650    if (quirks.meteringCropRegion) {
2651        return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2652    }
2653
2654    return ret;
2655}
2656
2657int Parameters::normalizedXToArray(int x) const {
2658
2659    // Work-around for HAL pre-scaling the coordinates themselves
2660    if (quirks.meteringCropRegion) {
2661        return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2662    }
2663
2664    return cropXToArray(normalizedXToCrop(x));
2665}
2666
2667int Parameters::normalizedYToArray(int y) const {
2668    // Work-around for HAL pre-scaling the coordinates themselves
2669    if (quirks.meteringCropRegion) {
2670        return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2671    }
2672
2673    return cropYToArray(normalizedYToCrop(y));
2674}
2675
2676status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) {
2677    if (info == NULL) {
2678        ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
2679        return NO_INIT;
2680    }
2681    if (sizes == NULL) {
2682        ALOGE("%s: Input size is null", __FUNCTION__);
2683        return BAD_VALUE;
2684    }
2685    sizes->clear();
2686
2687    if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2688        Vector<StreamConfiguration> scs = getStreamConfigurations();
2689        for (size_t i=0; i < scs.size(); i++) {
2690            const StreamConfiguration &sc = scs[i];
2691            if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
2692                    sc.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
2693                    sc.width <= limit.width && sc.height <= limit.height) {
2694                Size sz = {sc.width, sc.height};
2695                sizes->push(sz);
2696            }
2697        }
2698    } else {
2699        const size_t SIZE_COUNT = sizeof(Size) / sizeof(int);
2700        camera_metadata_ro_entry_t availableProcessedSizes =
2701            staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, SIZE_COUNT);
2702        if (availableProcessedSizes.count < SIZE_COUNT) return BAD_VALUE;
2703
2704        Size filteredSize;
2705        for (size_t i = 0; i < availableProcessedSizes.count; i += SIZE_COUNT) {
2706            filteredSize.width = availableProcessedSizes.data.i32[i];
2707            filteredSize.height = availableProcessedSizes.data.i32[i+1];
2708                // Need skip the preview sizes that are too large.
2709                if (filteredSize.width <= limit.width &&
2710                        filteredSize.height <= limit.height) {
2711                    sizes->push(filteredSize);
2712                }
2713        }
2714    }
2715
2716    if (sizes->isEmpty()) {
2717        ALOGE("generated preview size list is empty!!");
2718        return BAD_VALUE;
2719    }
2720    return OK;
2721}
2722
2723Parameters::Size Parameters::getMaxSizeForRatio(
2724        float ratio, const int32_t* sizeArray, size_t count) {
2725    ALOG_ASSERT(sizeArray != NULL, "size array shouldn't be NULL");
2726    ALOG_ASSERT(count >= 2 && count % 2 == 0, "count must be a positive even number");
2727
2728    Size maxSize = {0, 0};
2729    for (size_t i = 0; i < count; i += 2) {
2730        if (sizeArray[i] > 0 && sizeArray[i+1] > 0) {
2731            float curRatio = static_cast<float>(sizeArray[i]) / sizeArray[i+1];
2732            if (fabs(curRatio - ratio) < ASPECT_RATIO_TOLERANCE && maxSize.width < sizeArray[i]) {
2733                maxSize.width = sizeArray[i];
2734                maxSize.height = sizeArray[i+1];
2735            }
2736        }
2737    }
2738
2739    if (maxSize.width == 0 || maxSize.height == 0) {
2740        maxSize.width = sizeArray[0];
2741        maxSize.height = sizeArray[1];
2742        ALOGW("Unable to find the size to match the given aspect ratio %f."
2743                "Fall back to %d x %d", ratio, maxSize.width, maxSize.height);
2744    }
2745
2746    return maxSize;
2747}
2748
2749Vector<Parameters::StreamConfiguration> Parameters::getStreamConfigurations() {
2750    const int STREAM_CONFIGURATION_SIZE = 4;
2751    const int STREAM_FORMAT_OFFSET = 0;
2752    const int STREAM_WIDTH_OFFSET = 1;
2753    const int STREAM_HEIGHT_OFFSET = 2;
2754    const int STREAM_IS_INPUT_OFFSET = 3;
2755    Vector<StreamConfiguration> scs;
2756    if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
2757        ALOGE("StreamConfiguration is only valid after device HAL 3.2!");
2758        return scs;
2759    }
2760
2761    camera_metadata_ro_entry_t availableStreamConfigs =
2762                staticInfo(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
2763    for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
2764        int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
2765        int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
2766        int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
2767        int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
2768        StreamConfiguration sc = {format, width, height, isInput};
2769        scs.add(sc);
2770    }
2771    return scs;
2772}
2773
2774SortedVector<int32_t> Parameters::getAvailableOutputFormats() {
2775    SortedVector<int32_t> outputFormats; // Non-duplicated output formats
2776    if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2777        Vector<StreamConfiguration> scs = getStreamConfigurations();
2778        for (size_t i=0; i < scs.size(); i++) {
2779            const StreamConfiguration &sc = scs[i];
2780            if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
2781                outputFormats.add(sc.format);
2782            }
2783        }
2784    } else {
2785        camera_metadata_ro_entry_t availableFormats = staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2786        for (size_t i=0; i < availableFormats.count; i++) {
2787            outputFormats.add(availableFormats.data.i32[i]);
2788        }
2789    }
2790    return outputFormats;
2791}
2792
2793Vector<Parameters::Size> Parameters::getAvailableJpegSizes() {
2794    Vector<Parameters::Size> jpegSizes;
2795    if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2796        Vector<StreamConfiguration> scs = getStreamConfigurations();
2797        for (size_t i=0; i < scs.size(); i++) {
2798            const StreamConfiguration &sc = scs[i];
2799            if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
2800                    sc.format == HAL_PIXEL_FORMAT_BLOB) {
2801                Size sz = {sc.width, sc.height};
2802                jpegSizes.add(sz);
2803            }
2804        }
2805    } else {
2806        const int JPEG_SIZE_ENTRY_COUNT = 2;
2807        const int WIDTH_OFFSET = 0;
2808        const int HEIGHT_OFFSET = 1;
2809        camera_metadata_ro_entry_t availableJpegSizes =
2810            staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
2811        for (size_t i=0; i < availableJpegSizes.count; i+= JPEG_SIZE_ENTRY_COUNT) {
2812            int width = availableJpegSizes.data.i32[i + WIDTH_OFFSET];
2813            int height = availableJpegSizes.data.i32[i + HEIGHT_OFFSET];
2814            Size sz = {width, height};
2815            jpegSizes.add(sz);
2816        }
2817    }
2818    return jpegSizes;
2819}
2820
2821Parameters::CropRegion Parameters::calculateCropRegion(
2822                            Parameters::CropRegion::Outputs outputs) const {
2823
2824    float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2825
2826    // Need to convert zoom index into a crop rectangle. The rectangle is
2827    // chosen to maximize its area on the sensor
2828
2829    camera_metadata_ro_entry_t maxDigitalZoom =
2830            staticInfo(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
2831    // For each zoom step by how many pixels more do we change the zoom
2832    float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2833            (NUM_ZOOM_STEPS-1);
2834    // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2835    // via interpolating zoom step into a zoom ratio
2836    float zoomRatio = 1 + zoomIncrement * zoom;
2837    ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2838        "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2839        maxDigitalZoom.data.f[0], zoomRatio);
2840
2841    ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2842          "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2843          maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2844          previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2845
2846    /*
2847     * Assumption: On the HAL side each stream buffer calculates its crop
2848     * rectangle as follows:
2849     *   cropRect = (zoomLeft, zoomRight,
2850     *               zoomWidth, zoomHeight * zoomWidth / outputWidth);
2851     *
2852     * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2853     *      (we can then get into trouble if the cropHeight > arrayHeight).
2854     * By selecting the zoomRatio based on the smallest outputRatio, we
2855     * guarantee this will never happen.
2856     */
2857
2858    // Enumerate all possible output sizes, select the one with the smallest
2859    // aspect ratio
2860    float minOutputWidth, minOutputHeight, minOutputRatio;
2861    {
2862        float outputSizes[][2] = {
2863            { static_cast<float>(previewWidth),
2864              static_cast<float>(previewHeight) },
2865            { static_cast<float>(videoWidth),
2866              static_cast<float>(videoHeight) },
2867            { static_cast<float>(jpegThumbSize[0]),
2868              static_cast<float>(jpegThumbSize[1]) },
2869            { static_cast<float>(pictureWidth),
2870              static_cast<float>(pictureHeight) },
2871        };
2872
2873        minOutputWidth = outputSizes[0][0];
2874        minOutputHeight = outputSizes[0][1];
2875        minOutputRatio = minOutputWidth / minOutputHeight;
2876        for (unsigned int i = 0;
2877             i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2878             ++i) {
2879
2880            // skip over outputs we don't want to consider for the crop region
2881            if ( !((1 << i) & outputs) ) {
2882                continue;
2883            }
2884
2885            float outputWidth = outputSizes[i][0];
2886            float outputHeight = outputSizes[i][1];
2887            float outputRatio = outputWidth / outputHeight;
2888
2889            if (minOutputRatio > outputRatio) {
2890                minOutputRatio = outputRatio;
2891                minOutputWidth = outputWidth;
2892                minOutputHeight = outputHeight;
2893            }
2894
2895            // and then use this output ratio instead of preview output ratio
2896            ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2897                  outputRatio, outputWidth, outputHeight, minOutputRatio);
2898        }
2899    }
2900
2901    /* Ensure that the width/height never go out of bounds
2902     * by scaling across a diffent dimension if an out-of-bounds
2903     * possibility exists.
2904     *
2905     * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2906     * calculating the zoomWidth from zoomHeight we'll actually get a
2907     * zoomheight > arrayheight
2908     */
2909    float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2910    if (minOutputRatio >= arrayRatio) {
2911        // Adjust the height based on the width
2912        zoomWidth =  fastInfo.arrayWidth / zoomRatio;
2913        zoomHeight = zoomWidth *
2914                minOutputHeight / minOutputWidth;
2915
2916    } else {
2917        // Adjust the width based on the height
2918        zoomHeight = fastInfo.arrayHeight / zoomRatio;
2919        zoomWidth = zoomHeight *
2920                minOutputWidth / minOutputHeight;
2921    }
2922    // centering the zoom area within the active area
2923    zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2924    zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2925
2926    ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2927        (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2928
2929
2930    CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2931    return crop;
2932}
2933
2934status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)
2935        const {
2936    camera_metadata_ro_entry_t sensorSize =
2937            staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
2938    if (!sensorSize.count) return NO_INIT;
2939
2940    float arrayAspect = static_cast<float>(fastInfo.arrayWidth) /
2941            fastInfo.arrayHeight;
2942    float stillAspect = static_cast<float>(pictureWidth) / pictureHeight;
2943    ALOGV("Array aspect: %f, still aspect: %f", arrayAspect, stillAspect);
2944
2945    // The crop factors from the full sensor array to the still picture crop
2946    // region
2947    float horizCropFactor = 1.f;
2948    float vertCropFactor = 1.f;
2949
2950    /**
2951     * Need to calculate the still image field of view based on the total pixel
2952     * array field of view, and the relative aspect ratios of the pixel array
2953     * and output streams.
2954     *
2955     * Special treatment for quirky definition of crop region and relative
2956     * stream cropping.
2957     */
2958    if (quirks.meteringCropRegion) {
2959        // Use max of preview and video as first crop
2960        float previewAspect = static_cast<float>(previewWidth) / previewHeight;
2961        float videoAspect = static_cast<float>(videoWidth) / videoHeight;
2962        if (videoAspect > previewAspect) {
2963            previewAspect = videoAspect;
2964        }
2965        // First crop sensor to preview aspect ratio
2966        if (arrayAspect < previewAspect) {
2967            vertCropFactor = arrayAspect / previewAspect;
2968        } else {
2969            horizCropFactor = previewAspect / arrayAspect;
2970        }
2971        // Second crop to still aspect ratio
2972        if (stillAspect < previewAspect) {
2973            horizCropFactor *= stillAspect / previewAspect;
2974        } else {
2975            vertCropFactor *= previewAspect / stillAspect;
2976        }
2977    } else {
2978        /**
2979         * Crop are just a function of just the still/array relative aspect
2980         * ratios. Since each stream will maximize its area within the crop
2981         * region, and for FOV we assume a full-sensor crop region, we only ever
2982         * crop the FOV either vertically or horizontally, never both.
2983         */
2984        horizCropFactor = (arrayAspect > stillAspect) ?
2985                (stillAspect / arrayAspect) : 1.f;
2986        vertCropFactor = (arrayAspect < stillAspect) ?
2987                (arrayAspect / stillAspect) : 1.f;
2988    }
2989    ALOGV("Horiz crop factor: %f, vert crop fact: %f",
2990            horizCropFactor, vertCropFactor);
2991    /**
2992     * Basic field of view formula is:
2993     *   angle of view = 2 * arctangent ( d / 2f )
2994     * where d is the physical sensor dimension of interest, and f is
2995     * the focal length. This only applies to rectilinear sensors, for focusing
2996     * at distances >> f, etc.
2997     */
2998    if (horizFov != NULL) {
2999        *horizFov = 180 / M_PI * 2 *
3000                atanf(horizCropFactor * sensorSize.data.f[0] /
3001                        (2 * fastInfo.minFocalLength));
3002    }
3003    if (vertFov != NULL) {
3004        *vertFov = 180 / M_PI * 2 *
3005                atanf(vertCropFactor * sensorSize.data.f[1] /
3006                        (2 * fastInfo.minFocalLength));
3007    }
3008    return OK;
3009}
3010
3011int32_t Parameters::fpsFromRange(int32_t /*min*/, int32_t max) const {
3012    return max;
3013}
3014
3015}; // namespace camera2
3016}; // namespace android
3017