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