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