blob: 5ba564d99578c76308e3622d11cec1b19d729242 [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 }
Eino-Ville Talvalad6cc8642012-10-03 14:59:29 -07001042 newParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1043 String8::format("%d,%d",
1044 validatedParams.previewFpsRange[0] * kFpsToApiScale,
1045 validatedParams.previewFpsRange[1] * kFpsToApiScale));
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001046 }
1047
1048 // PICTURE_SIZE
1049 newParams.getPictureSize(&validatedParams.pictureWidth,
1050 &validatedParams.pictureHeight);
1051 if (validatedParams.pictureWidth == pictureWidth ||
1052 validatedParams.pictureHeight == pictureHeight) {
1053 camera_metadata_ro_entry_t availablePictureSizes =
1054 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1055 for (i = 0; i < availablePictureSizes.count; i+=2) {
1056 if ((availablePictureSizes.data.i32[i] ==
1057 validatedParams.pictureWidth) &&
1058 (availablePictureSizes.data.i32[i+1] ==
1059 validatedParams.pictureHeight)) break;
1060 }
1061 if (i == availablePictureSizes.count) {
1062 ALOGE("%s: Requested picture size %d x %d is not supported",
1063 __FUNCTION__, validatedParams.pictureWidth,
1064 validatedParams.pictureHeight);
1065 return BAD_VALUE;
1066 }
1067 }
1068
1069 // JPEG_THUMBNAIL_WIDTH/HEIGHT
1070 validatedParams.jpegThumbSize[0] =
1071 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
1072 validatedParams.jpegThumbSize[1] =
1073 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
1074 if (validatedParams.jpegThumbSize[0] != jpegThumbSize[0] ||
1075 validatedParams.jpegThumbSize[1] != jpegThumbSize[1]) {
1076 camera_metadata_ro_entry_t availableJpegThumbSizes =
1077 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1078 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
1079 if ((availableJpegThumbSizes.data.i32[i] ==
1080 validatedParams.jpegThumbSize[0]) &&
1081 (availableJpegThumbSizes.data.i32[i+1] ==
1082 validatedParams.jpegThumbSize[1])) break;
1083 }
1084 if (i == availableJpegThumbSizes.count) {
1085 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
1086 __FUNCTION__, validatedParams.jpegThumbSize[0],
1087 validatedParams.jpegThumbSize[1]);
1088 return BAD_VALUE;
1089 }
1090 }
1091
1092 // JPEG_THUMBNAIL_QUALITY
1093 validatedParams.jpegThumbQuality =
1094 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1095 if (validatedParams.jpegThumbQuality < 0 ||
1096 validatedParams.jpegThumbQuality > 100) {
1097 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1098 __FUNCTION__, validatedParams.jpegThumbQuality);
1099 return BAD_VALUE;
1100 }
1101
1102 // JPEG_QUALITY
1103 validatedParams.jpegQuality =
1104 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1105 if (validatedParams.jpegQuality < 0 || validatedParams.jpegQuality > 100) {
1106 ALOGE("%s: Requested JPEG quality %d is not supported",
1107 __FUNCTION__, validatedParams.jpegQuality);
1108 return BAD_VALUE;
1109 }
1110
1111 // ROTATION
1112 validatedParams.jpegRotation =
1113 newParams.getInt(CameraParameters::KEY_ROTATION);
1114 if (validatedParams.jpegRotation != 0 &&
1115 validatedParams.jpegRotation != 90 &&
1116 validatedParams.jpegRotation != 180 &&
1117 validatedParams.jpegRotation != 270) {
1118 ALOGE("%s: Requested picture rotation angle %d is not supported",
1119 __FUNCTION__, validatedParams.jpegRotation);
1120 return BAD_VALUE;
1121 }
1122
1123 // GPS
1124
1125 const char *gpsLatStr =
1126 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1127 if (gpsLatStr != NULL) {
1128 const char *gpsLongStr =
1129 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1130 const char *gpsAltitudeStr =
1131 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1132 const char *gpsTimeStr =
1133 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1134 const char *gpsProcMethodStr =
1135 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1136 if (gpsLongStr == NULL ||
1137 gpsAltitudeStr == NULL ||
1138 gpsTimeStr == NULL ||
1139 gpsProcMethodStr == NULL) {
1140 ALOGE("%s: Incomplete set of GPS parameters provided",
1141 __FUNCTION__);
1142 return BAD_VALUE;
1143 }
1144 char *endPtr;
1145 errno = 0;
1146 validatedParams.gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
1147 if (errno || endPtr == gpsLatStr) {
1148 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1149 return BAD_VALUE;
1150 }
1151 errno = 0;
1152 validatedParams.gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
1153 if (errno || endPtr == gpsLongStr) {
1154 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1155 return BAD_VALUE;
1156 }
1157 errno = 0;
1158 validatedParams.gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
1159 if (errno || endPtr == gpsAltitudeStr) {
1160 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1161 gpsAltitudeStr);
1162 return BAD_VALUE;
1163 }
1164 errno = 0;
1165 validatedParams.gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1166 if (errno || endPtr == gpsTimeStr) {
1167 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1168 return BAD_VALUE;
1169 }
1170 validatedParams.gpsProcessingMethod = gpsProcMethodStr;
1171
1172 validatedParams.gpsEnabled = true;
1173 } else {
1174 validatedParams.gpsEnabled = false;
1175 }
1176
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001177 // EFFECT
1178 validatedParams.effectMode = effectModeStringToEnum(
1179 newParams.get(CameraParameters::KEY_EFFECT) );
1180 if (validatedParams.effectMode != effectMode) {
1181 camera_metadata_ro_entry_t availableEffectModes =
1182 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1183 for (i = 0; i < availableEffectModes.count; i++) {
1184 if (validatedParams.effectMode == availableEffectModes.data.u8[i]) break;
1185 }
1186 if (i == availableEffectModes.count) {
1187 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1188 __FUNCTION__,
1189 newParams.get(CameraParameters::KEY_EFFECT) );
1190 return BAD_VALUE;
1191 }
1192 }
1193
1194 // ANTIBANDING
1195 validatedParams.antibandingMode = abModeStringToEnum(
1196 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1197 if (validatedParams.antibandingMode != antibandingMode) {
1198 camera_metadata_ro_entry_t availableAbModes =
1199 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1200 for (i = 0; i < availableAbModes.count; i++) {
1201 if (validatedParams.antibandingMode == availableAbModes.data.u8[i])
1202 break;
1203 }
1204 if (i == availableAbModes.count) {
1205 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1206 __FUNCTION__,
1207 newParams.get(CameraParameters::KEY_ANTIBANDING));
1208 return BAD_VALUE;
1209 }
1210 }
1211
1212 // SCENE_MODE
1213 validatedParams.sceneMode = sceneModeStringToEnum(
1214 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1215 if (validatedParams.sceneMode != sceneMode &&
1216 validatedParams.sceneMode !=
1217 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
1218 camera_metadata_ro_entry_t availableSceneModes =
1219 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1220 for (i = 0; i < availableSceneModes.count; i++) {
1221 if (validatedParams.sceneMode == availableSceneModes.data.u8[i])
1222 break;
1223 }
1224 if (i == availableSceneModes.count) {
1225 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1226 __FUNCTION__,
1227 newParams.get(CameraParameters::KEY_SCENE_MODE));
1228 return BAD_VALUE;
1229 }
1230 }
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001231 bool sceneModeSet =
1232 validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001233
1234 // FLASH_MODE
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001235 if (sceneModeSet) {
1236 validatedParams.flashMode =
1237 fastInfo.sceneModeOverrides.
1238 valueFor(validatedParams.sceneMode).flashMode;
1239 } else {
1240 validatedParams.flashMode = FLASH_MODE_INVALID;
1241 }
1242 if (validatedParams.flashMode == FLASH_MODE_INVALID) {
1243 validatedParams.flashMode = flashModeStringToEnum(
1244 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1245 }
1246
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001247 if (validatedParams.flashMode != flashMode) {
1248 camera_metadata_ro_entry_t flashAvailable =
1249 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1250 if (!flashAvailable.data.u8[0] &&
1251 validatedParams.flashMode != Parameters::FLASH_MODE_OFF) {
1252 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1253 "No flash on device", __FUNCTION__,
1254 newParams.get(CameraParameters::KEY_FLASH_MODE));
1255 return BAD_VALUE;
1256 } else if (validatedParams.flashMode == Parameters::FLASH_MODE_RED_EYE) {
1257 camera_metadata_ro_entry_t availableAeModes =
1258 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1259 for (i = 0; i < availableAeModes.count; i++) {
1260 if (validatedParams.flashMode == availableAeModes.data.u8[i])
1261 break;
1262 }
1263 if (i == availableAeModes.count) {
1264 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1265 __FUNCTION__,
1266 newParams.get(CameraParameters::KEY_FLASH_MODE));
1267 return BAD_VALUE;
1268 }
1269 } else if (validatedParams.flashMode == -1) {
1270 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1271 __FUNCTION__,
1272 newParams.get(CameraParameters::KEY_FLASH_MODE));
1273 return BAD_VALUE;
1274 }
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001275 // Update in case of override
1276 newParams.set(CameraParameters::KEY_FLASH_MODE,
1277 flashModeEnumToString(validatedParams.flashMode));
1278 }
1279
1280 // WHITE_BALANCE
1281 if (sceneModeSet) {
1282 validatedParams.wbMode =
1283 fastInfo.sceneModeOverrides.
1284 valueFor(validatedParams.sceneMode).wbMode;
1285 } else {
1286 validatedParams.wbMode = ANDROID_CONTROL_AWB_OFF;
1287 }
1288 if (validatedParams.wbMode == ANDROID_CONTROL_AWB_OFF) {
1289 validatedParams.wbMode = wbModeStringToEnum(
1290 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1291 }
1292 if (validatedParams.wbMode != wbMode) {
1293 camera_metadata_ro_entry_t availableWbModes =
1294 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1295 for (i = 0; i < availableWbModes.count; i++) {
1296 if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
1297 }
1298 if (i == availableWbModes.count) {
1299 ALOGE("%s: Requested white balance mode %s is not supported",
1300 __FUNCTION__,
1301 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1302 return BAD_VALUE;
1303 }
1304 // Update in case of override
1305 newParams.set(CameraParameters::KEY_WHITE_BALANCE,
1306 wbModeEnumToString(validatedParams.wbMode));
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001307 }
1308
1309 // FOCUS_MODE
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001310 if (sceneModeSet) {
1311 validatedParams.focusMode =
1312 fastInfo.sceneModeOverrides.
1313 valueFor(validatedParams.sceneMode).focusMode;
1314 } else {
1315 validatedParams.focusMode = FOCUS_MODE_INVALID;
1316 }
1317 if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
1318 validatedParams.focusMode = focusModeStringToEnum(
1319 newParams.get(CameraParameters::KEY_FOCUS_MODE) );
1320 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001321 if (validatedParams.focusMode != focusMode) {
1322 validatedParams.currentAfTriggerId = -1;
1323 if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
1324 camera_metadata_ro_entry_t minFocusDistance =
1325 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1326 if (minFocusDistance.data.f[0] == 0) {
1327 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1328 "fixed focus lens",
1329 __FUNCTION__,
1330 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1331 return BAD_VALUE;
1332 } else if (validatedParams.focusMode !=
1333 Parameters::FOCUS_MODE_INFINITY) {
1334 camera_metadata_ro_entry_t availableFocusModes =
1335 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1336 for (i = 0; i < availableFocusModes.count; i++) {
1337 if (validatedParams.focusMode ==
1338 availableFocusModes.data.u8[i]) break;
1339 }
1340 if (i == availableFocusModes.count) {
1341 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1342 __FUNCTION__,
1343 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1344 return BAD_VALUE;
1345 }
1346 }
1347 }
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001348 // Update in case of override
1349 newParams.set(CameraParameters::KEY_FOCUS_MODE,
1350 focusModeEnumToString(validatedParams.focusMode));
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001351 } else {
1352 validatedParams.currentAfTriggerId = currentAfTriggerId;
1353 }
1354
1355 // FOCUS_AREAS
1356 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1357 &validatedParams.focusingAreas);
1358 size_t max3aRegions =
1359 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1360 if (res == OK) res = validateAreas(validatedParams.focusingAreas,
1361 max3aRegions);
1362 if (res != OK) {
1363 ALOGE("%s: Requested focus areas are malformed: %s",
1364 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1365 return BAD_VALUE;
1366 }
1367
1368 // EXPOSURE_COMPENSATION
1369 validatedParams.exposureCompensation =
1370 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1371 camera_metadata_ro_entry_t exposureCompensationRange =
1372 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1373 if ((validatedParams.exposureCompensation <
1374 exposureCompensationRange.data.i32[0]) ||
1375 (validatedParams.exposureCompensation >
1376 exposureCompensationRange.data.i32[1])) {
1377 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1378 __FUNCTION__, validatedParams.exposureCompensation);
1379 return BAD_VALUE;
1380 }
1381
1382 // AUTO_EXPOSURE_LOCK (always supported)
1383 validatedParams.autoExposureLock = boolFromString(
1384 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1385
1386 // AUTO_WHITEBALANCE_LOCK (always supported)
1387 validatedParams.autoWhiteBalanceLock = boolFromString(
1388 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1389
1390 // METERING_AREAS
1391 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1392 &validatedParams.meteringAreas);
1393 if (res == OK) {
1394 res = validateAreas(validatedParams.meteringAreas, max3aRegions);
1395 }
1396 if (res != OK) {
1397 ALOGE("%s: Requested metering areas are malformed: %s",
1398 __FUNCTION__,
1399 newParams.get(CameraParameters::KEY_METERING_AREAS));
1400 return BAD_VALUE;
1401 }
1402
1403 // ZOOM
1404 validatedParams.zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1405 if (validatedParams.zoom < 0 || validatedParams.zoom > (int)NUM_ZOOM_STEPS) {
1406 ALOGE("%s: Requested zoom level %d is not supported",
1407 __FUNCTION__, validatedParams.zoom);
1408 return BAD_VALUE;
1409 }
1410
1411 // VIDEO_SIZE
1412 newParams.getVideoSize(&validatedParams.videoWidth,
1413 &validatedParams.videoHeight);
1414 if (validatedParams.videoWidth != videoWidth ||
1415 validatedParams.videoHeight != videoHeight) {
1416 if (state == RECORD) {
1417 ALOGE("%s: Video size cannot be updated when recording is active!",
1418 __FUNCTION__);
1419 return BAD_VALUE;
1420 }
1421 camera_metadata_ro_entry_t availableVideoSizes =
1422 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1423 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1424 if ((availableVideoSizes.data.i32[i] ==
1425 validatedParams.videoWidth) &&
1426 (availableVideoSizes.data.i32[i+1] ==
1427 validatedParams.videoHeight)) break;
1428 }
1429 if (i == availableVideoSizes.count) {
1430 ALOGE("%s: Requested video size %d x %d is not supported",
1431 __FUNCTION__, validatedParams.videoWidth,
1432 validatedParams.videoHeight);
1433 return BAD_VALUE;
1434 }
1435 }
1436
1437 // RECORDING_HINT (always supported)
1438 validatedParams.recordingHint = boolFromString(
1439 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1440
1441 // VIDEO_STABILIZATION
1442 validatedParams.videoStabilization = boolFromString(
1443 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1444 camera_metadata_ro_entry_t availableVideoStabilizationModes =
1445 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1446 if (validatedParams.videoStabilization &&
1447 availableVideoStabilizationModes.count == 1) {
1448 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1449 }
1450
1451 /** Update internal parameters */
1452
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001453 *this = validatedParams;
1454
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001455 // Need to flatten again in case of overrides
1456 paramsFlattened = newParams.flatten();
1457 params = newParams;
1458
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001459 return OK;
1460}
1461
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001462status_t Parameters::updateRequest(CameraMetadata *request) const {
1463 ATRACE_CALL();
1464 status_t res;
1465
1466 uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
1467 res = request->update(ANDROID_REQUEST_METADATA_MODE,
1468 &metadataMode, 1);
1469 if (res != OK) return res;
1470
1471 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1472 previewFpsRange, 2);
1473 if (res != OK) return res;
1474
Eino-Ville Talvala96150cf2012-09-03 10:03:26 -07001475 uint8_t reqWbLock = autoWhiteBalanceLock ?
1476 ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
1477 res = request->update(ANDROID_CONTROL_AWB_LOCK,
1478 &reqWbLock, 1);
1479
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001480 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1481 &effectMode, 1);
1482 if (res != OK) return res;
1483 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1484 &antibandingMode, 1);
1485 if (res != OK) return res;
1486
Eino-Ville Talvala61c0cc62012-09-07 14:26:29 -07001487 // android.hardware.Camera requires that when face detect is enabled, the
1488 // camera is in a face-priority mode. HAL2 splits this into separate parts
1489 // (face detection statistics and face priority scene mode). Map from other
1490 // to the other.
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001491 bool sceneModeActive =
1492 sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
Eino-Ville Talvala61c0cc62012-09-07 14:26:29 -07001493 uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001494 if (enableFaceDetect || sceneModeActive) {
Eino-Ville Talvala61c0cc62012-09-07 14:26:29 -07001495 reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
1496 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001497 res = request->update(ANDROID_CONTROL_MODE,
1498 &reqControlMode, 1);
1499 if (res != OK) return res;
Eino-Ville Talvala61c0cc62012-09-07 14:26:29 -07001500
Eino-Ville Talvalad14de472012-09-17 16:43:14 -07001501 uint8_t reqSceneMode =
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001502 sceneModeActive ? sceneMode :
Eino-Ville Talvalad14de472012-09-17 16:43:14 -07001503 enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
1504 (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
Eino-Ville Talvala61c0cc62012-09-07 14:26:29 -07001505 res = request->update(ANDROID_CONTROL_SCENE_MODE,
1506 &reqSceneMode, 1);
1507 if (res != OK) return res;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001508
1509 uint8_t reqFlashMode = ANDROID_FLASH_OFF;
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001510 uint8_t reqAeMode = ANDROID_CONTROL_AE_OFF;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001511 switch (flashMode) {
1512 case Parameters::FLASH_MODE_OFF:
1513 reqAeMode = ANDROID_CONTROL_AE_ON; break;
1514 case Parameters::FLASH_MODE_AUTO:
1515 reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
1516 case Parameters::FLASH_MODE_ON:
1517 reqAeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
1518 case Parameters::FLASH_MODE_TORCH:
1519 reqAeMode = ANDROID_CONTROL_AE_ON;
1520 reqFlashMode = ANDROID_FLASH_TORCH;
1521 break;
1522 case Parameters::FLASH_MODE_RED_EYE:
1523 reqAeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
1524 default:
1525 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
1526 cameraId, flashMode);
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001527 return BAD_VALUE;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001528 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001529 res = request->update(ANDROID_FLASH_MODE,
1530 &reqFlashMode, 1);
1531 if (res != OK) return res;
1532 res = request->update(ANDROID_CONTROL_AE_MODE,
1533 &reqAeMode, 1);
1534 if (res != OK) return res;
1535
Eino-Ville Talvala96150cf2012-09-03 10:03:26 -07001536 uint8_t reqAeLock = autoExposureLock ?
1537 ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
1538 res = request->update(ANDROID_CONTROL_AE_LOCK,
1539 &reqAeLock, 1);
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001540 if (res != OK) return res;
1541
1542 res = request->update(ANDROID_CONTROL_AWB_MODE,
1543 &wbMode, 1);
1544 if (res != OK) return res;
Eino-Ville Talvala96150cf2012-09-03 10:03:26 -07001545
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001546 float reqFocusDistance = 0; // infinity focus in diopters
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001547 uint8_t reqFocusMode = ANDROID_CONTROL_AF_OFF;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001548 switch (focusMode) {
1549 case Parameters::FOCUS_MODE_AUTO:
1550 case Parameters::FOCUS_MODE_MACRO:
1551 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1552 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1553 case Parameters::FOCUS_MODE_EDOF:
1554 reqFocusMode = focusMode;
1555 break;
1556 case Parameters::FOCUS_MODE_INFINITY:
1557 case Parameters::FOCUS_MODE_FIXED:
1558 reqFocusMode = ANDROID_CONTROL_AF_OFF;
1559 break;
1560 default:
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001561 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
1562 cameraId, focusMode);
1563 return BAD_VALUE;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001564 }
1565 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1566 &reqFocusDistance, 1);
1567 if (res != OK) return res;
1568 res = request->update(ANDROID_CONTROL_AF_MODE,
1569 &reqFocusMode, 1);
1570 if (res != OK) return res;
1571
1572 size_t reqFocusingAreasSize = focusingAreas.size() * 5;
1573 int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
1574 for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
1575 if (focusingAreas[i].weight != 0) {
1576 reqFocusingAreas[i + 0] =
1577 normalizedXToArray(focusingAreas[i].left);
1578 reqFocusingAreas[i + 1] =
1579 normalizedYToArray(focusingAreas[i].top);
1580 reqFocusingAreas[i + 2] =
1581 normalizedXToArray(focusingAreas[i].right);
1582 reqFocusingAreas[i + 3] =
1583 normalizedYToArray(focusingAreas[i].bottom);
1584 } else {
1585 reqFocusingAreas[i + 0] = 0;
1586 reqFocusingAreas[i + 1] = 0;
1587 reqFocusingAreas[i + 2] = 0;
1588 reqFocusingAreas[i + 3] = 0;
1589 }
1590 reqFocusingAreas[i + 4] = focusingAreas[i].weight;
1591 }
1592 res = request->update(ANDROID_CONTROL_AF_REGIONS,
1593 reqFocusingAreas, reqFocusingAreasSize);
1594 if (res != OK) return res;
1595 delete[] reqFocusingAreas;
1596
1597 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
1598 &exposureCompensation, 1);
1599 if (res != OK) return res;
1600
1601 size_t reqMeteringAreasSize = meteringAreas.size() * 5;
1602 int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
1603 for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
1604 if (meteringAreas[i].weight != 0) {
1605 reqMeteringAreas[i + 0] =
1606 normalizedXToArray(meteringAreas[i].left);
1607 reqMeteringAreas[i + 1] =
1608 normalizedYToArray(meteringAreas[i].top);
1609 reqMeteringAreas[i + 2] =
1610 normalizedXToArray(meteringAreas[i].right);
1611 reqMeteringAreas[i + 3] =
1612 normalizedYToArray(meteringAreas[i].bottom);
1613 } else {
1614 reqMeteringAreas[i + 0] = 0;
1615 reqMeteringAreas[i + 1] = 0;
1616 reqMeteringAreas[i + 2] = 0;
1617 reqMeteringAreas[i + 3] = 0;
1618 }
1619 reqMeteringAreas[i + 4] = meteringAreas[i].weight;
1620 }
1621 res = request->update(ANDROID_CONTROL_AE_REGIONS,
1622 reqMeteringAreas, reqMeteringAreasSize);
1623 if (res != OK) return res;
1624
1625 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
1626 reqMeteringAreas, reqMeteringAreasSize);
1627 if (res != OK) return res;
1628 delete[] reqMeteringAreas;
1629
Igor Murashkin018d2282012-09-18 18:23:49 -07001630 CropRegion crop = calculateCropRegion();
1631 int32_t reqCropRegion[3] = { crop.left, crop.top, crop.width };
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001632 res = request->update(ANDROID_SCALER_CROP_REGION,
1633 reqCropRegion, 3);
1634 if (res != OK) return res;
1635
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001636 uint8_t reqVstabMode = videoStabilization ?
1637 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
1638 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
1639 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1640 &reqVstabMode, 1);
1641 if (res != OK) return res;
1642
1643 uint8_t reqFaceDetectMode = enableFaceDetect ?
1644 fastInfo.bestFaceDetectMode :
1645 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
1646 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
1647 &reqFaceDetectMode, 1);
1648 if (res != OK) return res;
1649
1650 return OK;
1651}
1652
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001653const char* Parameters::getStateName(State state) {
1654#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
1655 switch(state) {
1656 CASE_ENUM_TO_CHAR(DISCONNECTED)
1657 CASE_ENUM_TO_CHAR(STOPPED)
1658 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
1659 CASE_ENUM_TO_CHAR(PREVIEW)
1660 CASE_ENUM_TO_CHAR(RECORD)
1661 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
1662 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
1663 default:
1664 return "Unknown state!";
1665 break;
1666 }
1667#undef CASE_ENUM_TO_CHAR
1668}
1669
1670int Parameters::formatStringToEnum(const char *format) {
1671 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001672 !format ?
1673 HAL_PIXEL_FORMAT_YCrCb_420_SP :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001674 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
1675 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
1676 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
1677 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
1678 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
1679 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
1680 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
1681 HAL_PIXEL_FORMAT_YV12 : // YV12
1682 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
1683 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
1684 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
1685 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
1686 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
1687 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
1688 -1;
1689}
1690
1691const char* Parameters::formatEnumToString(int format) {
1692 const char *fmt;
1693 switch(format) {
1694 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1695 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
1696 break;
1697 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1698 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
1699 break;
1700 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1701 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
1702 break;
1703 case HAL_PIXEL_FORMAT_YV12: // YV12
1704 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
1705 break;
1706 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
1707 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
1708 break;
1709 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
1710 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
1711 break;
1712 case HAL_PIXEL_FORMAT_RAW_SENSOR:
1713 ALOGW("Raw sensor preview format requested.");
1714 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
1715 break;
1716 default:
1717 ALOGE("%s: Unknown preview format: %x",
1718 __FUNCTION__, format);
1719 fmt = NULL;
1720 break;
1721 }
1722 return fmt;
1723}
1724
1725int Parameters::wbModeStringToEnum(const char *wbMode) {
1726 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001727 !wbMode ?
1728 ANDROID_CONTROL_AWB_AUTO :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001729 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
1730 ANDROID_CONTROL_AWB_AUTO :
1731 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
1732 ANDROID_CONTROL_AWB_INCANDESCENT :
1733 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
1734 ANDROID_CONTROL_AWB_FLUORESCENT :
1735 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
1736 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
1737 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
1738 ANDROID_CONTROL_AWB_DAYLIGHT :
1739 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
1740 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
1741 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
1742 ANDROID_CONTROL_AWB_TWILIGHT :
1743 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
1744 ANDROID_CONTROL_AWB_SHADE :
1745 -1;
1746}
1747
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001748const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
1749 switch (wbMode) {
1750 case ANDROID_CONTROL_AWB_AUTO:
1751 return CameraParameters::WHITE_BALANCE_AUTO;
1752 case ANDROID_CONTROL_AWB_INCANDESCENT:
1753 return CameraParameters::WHITE_BALANCE_INCANDESCENT;
1754 case ANDROID_CONTROL_AWB_FLUORESCENT:
1755 return CameraParameters::WHITE_BALANCE_FLUORESCENT;
1756 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
1757 return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
1758 case ANDROID_CONTROL_AWB_DAYLIGHT:
1759 return CameraParameters::WHITE_BALANCE_DAYLIGHT;
1760 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
1761 return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
1762 case ANDROID_CONTROL_AWB_TWILIGHT:
1763 return CameraParameters::WHITE_BALANCE_TWILIGHT;
1764 case ANDROID_CONTROL_AWB_SHADE:
1765 return CameraParameters::WHITE_BALANCE_SHADE;
1766 default:
1767 ALOGE("%s: Unknown AWB mode enum: %d",
1768 __FUNCTION__, wbMode);
1769 return "unknown";
1770 }
1771}
1772
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001773int Parameters::effectModeStringToEnum(const char *effectMode) {
1774 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001775 !effectMode ?
1776 ANDROID_CONTROL_EFFECT_OFF :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001777 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
1778 ANDROID_CONTROL_EFFECT_OFF :
1779 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
1780 ANDROID_CONTROL_EFFECT_MONO :
1781 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
1782 ANDROID_CONTROL_EFFECT_NEGATIVE :
1783 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
1784 ANDROID_CONTROL_EFFECT_SOLARIZE :
1785 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
1786 ANDROID_CONTROL_EFFECT_SEPIA :
1787 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
1788 ANDROID_CONTROL_EFFECT_POSTERIZE :
1789 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
1790 ANDROID_CONTROL_EFFECT_WHITEBOARD :
1791 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
1792 ANDROID_CONTROL_EFFECT_BLACKBOARD :
1793 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
1794 ANDROID_CONTROL_EFFECT_AQUA :
1795 -1;
1796}
1797
1798int Parameters::abModeStringToEnum(const char *abMode) {
1799 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001800 !abMode ?
1801 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001802 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
1803 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
1804 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
1805 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
1806 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
1807 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
1808 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
1809 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
1810 -1;
1811}
1812
1813int Parameters::sceneModeStringToEnum(const char *sceneMode) {
1814 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001815 !sceneMode ?
1816 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001817 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
1818 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
1819 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
1820 ANDROID_CONTROL_SCENE_MODE_ACTION :
1821 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
1822 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
1823 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
1824 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
1825 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
1826 ANDROID_CONTROL_SCENE_MODE_NIGHT :
1827 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
1828 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
1829 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
1830 ANDROID_CONTROL_SCENE_MODE_THEATRE :
1831 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
1832 ANDROID_CONTROL_SCENE_MODE_BEACH :
1833 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
1834 ANDROID_CONTROL_SCENE_MODE_SNOW :
1835 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
1836 ANDROID_CONTROL_SCENE_MODE_SUNSET :
1837 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
1838 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
1839 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
1840 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
1841 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
1842 ANDROID_CONTROL_SCENE_MODE_SPORTS :
1843 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
1844 ANDROID_CONTROL_SCENE_MODE_PARTY :
1845 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
1846 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
1847 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
1848 ANDROID_CONTROL_SCENE_MODE_BARCODE:
1849 -1;
1850}
1851
1852Parameters::Parameters::flashMode_t Parameters::flashModeStringToEnum(
1853 const char *flashMode) {
1854 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001855 !flashMode ?
1856 Parameters::FLASH_MODE_INVALID :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001857 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
1858 Parameters::FLASH_MODE_OFF :
1859 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
1860 Parameters::FLASH_MODE_AUTO :
1861 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
1862 Parameters::FLASH_MODE_ON :
1863 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
1864 Parameters::FLASH_MODE_RED_EYE :
1865 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
1866 Parameters::FLASH_MODE_TORCH :
1867 Parameters::FLASH_MODE_INVALID;
1868}
1869
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001870const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
1871 switch (flashMode) {
1872 case FLASH_MODE_OFF:
1873 return CameraParameters::FLASH_MODE_OFF;
1874 case FLASH_MODE_AUTO:
1875 return CameraParameters::FLASH_MODE_AUTO;
1876 case FLASH_MODE_ON:
1877 return CameraParameters::FLASH_MODE_ON;
1878 case FLASH_MODE_RED_EYE:
1879 return CameraParameters::FLASH_MODE_RED_EYE;
1880 case FLASH_MODE_TORCH:
1881 return CameraParameters::FLASH_MODE_TORCH;
1882 default:
1883 ALOGE("%s: Unknown flash mode enum %d",
1884 __FUNCTION__, flashMode);
1885 return "unknown";
1886 }
1887}
1888
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001889Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
1890 const char *focusMode) {
1891 return
Eino-Ville Talvala4a02cc82012-09-10 09:53:09 -07001892 !focusMode ?
1893 Parameters::FOCUS_MODE_INVALID :
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001894 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
1895 Parameters::FOCUS_MODE_AUTO :
1896 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
1897 Parameters::FOCUS_MODE_INFINITY :
1898 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
1899 Parameters::FOCUS_MODE_MACRO :
1900 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
1901 Parameters::FOCUS_MODE_FIXED :
1902 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
1903 Parameters::FOCUS_MODE_EDOF :
1904 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
1905 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
1906 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
1907 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
1908 Parameters::FOCUS_MODE_INVALID;
1909}
1910
Eino-Ville Talvala8a42dd82012-10-02 13:30:04 -07001911const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
1912 switch (focusMode) {
1913 case FOCUS_MODE_AUTO:
1914 return CameraParameters::FOCUS_MODE_AUTO;
1915 case FOCUS_MODE_MACRO:
1916 return CameraParameters::FOCUS_MODE_MACRO;
1917 case FOCUS_MODE_CONTINUOUS_VIDEO:
1918 return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
1919 case FOCUS_MODE_CONTINUOUS_PICTURE:
1920 return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
1921 case FOCUS_MODE_EDOF:
1922 return CameraParameters::FOCUS_MODE_EDOF;
1923 case FOCUS_MODE_INFINITY:
1924 return CameraParameters::FOCUS_MODE_INFINITY;
1925 case FOCUS_MODE_FIXED:
1926 return CameraParameters::FOCUS_MODE_FIXED;
1927 default:
1928 ALOGE("%s: Unknown focus mode enum: %d",
1929 __FUNCTION__, focusMode);
1930 return "unknown";
1931 }
1932}
1933
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001934status_t Parameters::parseAreas(const char *areasCStr,
1935 Vector<Parameters::Area> *areas) {
1936 static const size_t NUM_FIELDS = 5;
1937 areas->clear();
1938 if (areasCStr == NULL) {
1939 // If no key exists, use default (0,0,0,0,0)
1940 areas->push();
1941 return OK;
1942 }
1943 String8 areasStr(areasCStr);
1944 ssize_t areaStart = areasStr.find("(", 0) + 1;
1945 while (areaStart != 0) {
1946 const char* area = areasStr.string() + areaStart;
1947 char *numEnd;
1948 int vals[NUM_FIELDS];
1949 for (size_t i = 0; i < NUM_FIELDS; i++) {
1950 errno = 0;
1951 vals[i] = strtol(area, &numEnd, 10);
1952 if (errno || numEnd == area) return BAD_VALUE;
1953 area = numEnd + 1;
1954 }
1955 areas->push(Parameters::Area(
1956 vals[0], vals[1], vals[2], vals[3], vals[4]) );
1957 areaStart = areasStr.find("(", areaStart) + 1;
1958 }
1959 return OK;
1960}
1961
1962status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
1963 size_t maxRegions) {
1964 // Definition of valid area can be found in
1965 // include/camera/CameraParameters.h
1966 if (areas.size() == 0) return BAD_VALUE;
1967 if (areas.size() == 1) {
1968 if (areas[0].left == 0 &&
1969 areas[0].top == 0 &&
1970 areas[0].right == 0 &&
1971 areas[0].bottom == 0 &&
1972 areas[0].weight == 0) {
1973 // Single (0,0,0,0,0) entry is always valid (== driver decides)
1974 return OK;
1975 }
1976 }
1977 if (areas.size() > maxRegions) {
1978 ALOGE("%s: Too many areas requested: %d",
1979 __FUNCTION__, areas.size());
1980 return BAD_VALUE;
1981 }
1982
1983 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
1984 a != areas.end(); a++) {
1985 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
1986 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
1987 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
1988 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
1989 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
1990 if (a->left >= a->right) return BAD_VALUE;
1991 if (a->top >= a->bottom) return BAD_VALUE;
1992 }
1993 return OK;
1994}
1995
1996bool Parameters::boolFromString(const char *boolStr) {
1997 return !boolStr ? false :
1998 !strcmp(boolStr, CameraParameters::TRUE) ? true :
1999 false;
2000}
2001
2002int Parameters::degToTransform(int degrees, bool mirror) {
2003 if (!mirror) {
2004 if (degrees == 0) return 0;
2005 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
2006 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
2007 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
2008 } else { // Do mirror (horizontal flip)
2009 if (degrees == 0) { // FLIP_H and ROT_0
2010 return HAL_TRANSFORM_FLIP_H;
2011 } else if (degrees == 90) { // FLIP_H and ROT_90
2012 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
2013 } else if (degrees == 180) { // FLIP_H and ROT_180
2014 return HAL_TRANSFORM_FLIP_V;
2015 } else if (degrees == 270) { // FLIP_H and ROT_270
2016 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
2017 }
2018 }
2019 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
2020 return -1;
2021}
2022
2023int Parameters::arrayXToNormalized(int width) const {
2024 return width * 2000 / (fastInfo.arrayWidth - 1) - 1000;
2025}
2026
2027int Parameters::arrayYToNormalized(int height) const {
2028 return height * 2000 / (fastInfo.arrayHeight - 1) - 1000;
2029}
2030
2031int Parameters::normalizedXToArray(int x) const {
2032 return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000;
2033}
2034
2035int Parameters::normalizedYToArray(int y) const {
2036 return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;
2037}
2038
Igor Murashkin018d2282012-09-18 18:23:49 -07002039Parameters::CropRegion Parameters::calculateCropRegion(void) const {
2040
2041 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2042
2043 // Need to convert zoom index into a crop rectangle. The rectangle is
2044 // chosen to maximize its area on the sensor
2045
2046 camera_metadata_ro_entry_t maxDigitalZoom =
2047 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2048 // For each zoom step by how many pixels more do we change the zoom
2049 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2050 (NUM_ZOOM_STEPS-1);
2051 // The desired activeAreaWidth/cropAreaWidth ratio (or height if h>w)
2052 // via interpolating zoom step into a zoom ratio
2053 float zoomRatio = 1 + zoomIncrement * zoom;
2054 ALOG_ASSERT( (zoomRatio >= 1.f && zoomRatio <= maxDigitalZoom.data.f[0]),
2055 "Zoom ratio calculated out of bounds. Expected 1 - %f, actual: %f",
2056 maxDigitalZoom.data.f[0], zoomRatio);
2057
2058 ALOGV("Zoom maxDigital=%f, increment=%f, ratio=%f, previewWidth=%d, "
2059 "previewHeight=%d, activeWidth=%d, activeHeight=%d",
2060 maxDigitalZoom.data.f[0], zoomIncrement, zoomRatio, previewWidth,
2061 previewHeight, fastInfo.arrayWidth, fastInfo.arrayHeight);
2062
2063 /*
2064 * Assumption: On the HAL side each stream buffer calculates its crop
2065 * rectangle as follows:
2066 * cropRect = (zoomLeft, zoomRight,
2067 * zoomWidth, zoomHeight * zoomWidth / outputWidth);
2068 *
2069 * Note that if zoomWidth > bufferWidth, the new cropHeight > zoomHeight
2070 * (we can then get into trouble if the cropHeight > arrayHeight).
2071 * By selecting the zoomRatio based on the smallest outputRatio, we
2072 * guarantee this will never happen.
2073 */
2074
2075 // Enumerate all possible output sizes, select the one with the smallest
2076 // aspect ratio
2077 float minOutputWidth, minOutputHeight, minOutputRatio;
2078 {
2079 float outputSizes[][2] = {
2080 { previewWidth, previewHeight },
2081 { videoWidth, videoHeight },
2082 /* don't include jpeg thumbnail size - it's valid for
2083 it to be set to (0,0), meaning 'no thumbnail' */
2084 // { jpegThumbSize[0], jpegThumbSize[1] },
2085 { pictureWidth, pictureHeight },
2086 };
2087
2088 minOutputWidth = outputSizes[0][0];
2089 minOutputHeight = outputSizes[0][1];
2090 minOutputRatio = minOutputWidth / minOutputHeight;
2091 for (unsigned int i = 0;
2092 i < sizeof(outputSizes) / sizeof(outputSizes[0]);
2093 ++i) {
2094
2095 float outputWidth = outputSizes[i][0];
2096 float outputHeight = outputSizes[i][1];
2097 float outputRatio = outputWidth / outputHeight;
2098
2099 if (minOutputRatio > outputRatio) {
2100 minOutputRatio = outputRatio;
2101 minOutputWidth = outputWidth;
2102 minOutputHeight = outputHeight;
2103 }
2104
2105 // and then use this output ratio instead of preview output ratio
2106 ALOGV("Enumerating output ratio %f = %f / %f, min is %f",
2107 outputRatio, outputWidth, outputHeight, minOutputRatio);
2108 }
2109 }
2110
2111 /* Ensure that the width/height never go out of bounds
2112 * by scaling across a diffent dimension if an out-of-bounds
2113 * possibility exists.
2114 *
2115 * e.g. if the previewratio < arrayratio and e.g. zoomratio = 1.0, then by
2116 * calculating the zoomWidth from zoomHeight we'll actually get a
2117 * zoomheight > arrayheight
2118 */
2119 float arrayRatio = 1.f * fastInfo.arrayWidth / fastInfo.arrayHeight;
2120 if (minOutputRatio >= arrayRatio) {
2121 // Adjust the height based on the width
2122 zoomWidth = fastInfo.arrayWidth / zoomRatio;
2123 zoomHeight = zoomWidth *
2124 minOutputHeight / minOutputWidth;
2125
2126 } else {
2127 // Adjust the width based on the height
2128 zoomHeight = fastInfo.arrayHeight / zoomRatio;
2129 zoomWidth = zoomHeight *
2130 minOutputWidth / minOutputHeight;
2131 }
2132 // centering the zoom area within the active area
2133 zoomLeft = (fastInfo.arrayWidth - zoomWidth) / 2;
2134 zoomTop = (fastInfo.arrayHeight - zoomHeight) / 2;
2135
2136 ALOGV("Crop region calculated (x=%d,y=%d,w=%f,h=%f) for zoom=%d",
2137 (int32_t)zoomLeft, (int32_t)zoomTop, zoomWidth, zoomHeight, this->zoom);
2138
2139
2140 CropRegion crop = { zoomLeft, zoomTop, zoomWidth, zoomHeight };
2141 return crop;
2142}
2143
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002144}; // namespace camera2
2145}; // namespace android