blob: 8d4add45286e92b515f2ed80ebbbc3a4d370b6ff [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -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
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
27
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070028#include <math.h>
29
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030#include "Camera2Client.h"
31
32namespace android {
33
34#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
35#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
36
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037static int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
41static int getCallingUid() {
42 return IPCThreadState::self()->getCallingUid();
43}
44
45// Interface used by CameraService
46
47Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
48 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 int cameraId,
50 int cameraFacing,
51 int clientPid):
52 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070053 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070054 mState(NOT_INITIALIZED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070055 mPreviewStreamId(NO_STREAM),
56 mPreviewRequest(NULL),
57 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070058 mCaptureRequest(NULL),
59 mRecordingStreamId(NO_STREAM),
60 mRecordingRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070061{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070062 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070064 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065}
66
67status_t Camera2Client::initialize(camera_module_t *module)
68{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070069 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070 status_t res;
71
72 res = mDevice->initialize(module);
73 if (res != OK) {
74 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
75 __FUNCTION__, mCameraId, strerror(-res), res);
76 return NO_INIT;
77 }
78
79 res = buildDefaultParameters();
80 if (res != OK) {
81 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
82 __FUNCTION__, mCameraId, strerror(-res), res);
83 return NO_INIT;
84 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070085
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070086 if (gLogLevel >= 1) {
87 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
88 mCameraId);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070089 ALOGD("%s", mParamsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 }
91
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070092 mState = STOPPED;
93
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070094 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070095}
96
97Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070098 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -070099 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
100
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700101 mDestructionStarted = true;
102
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700104
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700105}
106
107status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700108 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700109 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700110 mCameraId,
111 getCameraClient()->asBinder().get(),
112 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700113 result.append(" State: ");
114#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
115
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700116 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700117
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700118 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700119 result.appendFormat(" Preview size: %d x %d\n",
120 mParameters.previewWidth, mParameters.previewHeight);
121 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700122 mParameters.previewFpsRange[0], mParameters.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700123 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
124 mParameters.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700125 result.appendFormat(" Preview transform: %x\n",
126 mParameters.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700127 result.appendFormat(" Picture size: %d x %d\n",
128 mParameters.pictureWidth, mParameters.pictureHeight);
129 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700130 mParameters.jpegThumbSize[0], mParameters.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700131 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
132 mParameters.jpegQuality, mParameters.jpegThumbQuality);
133 result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
134 result.appendFormat(" GPS tags %s\n",
135 mParameters.gpsEnabled ? "enabled" : "disabled");
136 if (mParameters.gpsEnabled) {
137 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700138 mParameters.gpsCoordinates[0], mParameters.gpsCoordinates[1],
139 mParameters.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140 result.appendFormat(" GPS timestamp: %lld\n",
141 mParameters.gpsTimestamp);
142 result.appendFormat(" GPS processing method: %s\n",
143 mParameters.gpsProcessingMethod.string());
144 }
145
146 result.append(" White balance mode: ");
147 switch (mParameters.wbMode) {
148 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
149 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
150 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
151 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
152 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
156 default: result.append("UNKNOWN\n");
157 }
158
159 result.append(" Effect mode: ");
160 switch (mParameters.effectMode) {
161 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
162 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
163 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
164 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
170 default: result.append("UNKNOWN\n");
171 }
172
173 result.append(" Antibanding mode: ");
174 switch (mParameters.antibandingMode) {
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
179 default: result.append("UNKNOWN\n");
180 }
181
182 result.append(" Scene mode: ");
183 switch (mParameters.sceneMode) {
184 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
185 result.append("AUTO\n"); break;
186 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
201 default: result.append("UNKNOWN\n");
202 }
203
204 result.append(" Flash mode: ");
205 switch (mParameters.flashMode) {
206 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
207 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
208 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
209 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
210 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
212 default: result.append("UNKNOWN\n");
213 }
214
215 result.append(" Focus mode: ");
216 switch (mParameters.focusMode) {
217 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
218 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
219 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
220 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
221 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
225 default: result.append("UNKNOWN\n");
226 }
227
228 result.append(" Focusing areas:\n");
229 for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
230 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
231 mParameters.focusingAreas[i].left,
232 mParameters.focusingAreas[i].top,
233 mParameters.focusingAreas[i].right,
234 mParameters.focusingAreas[i].bottom,
235 mParameters.focusingAreas[i].weight);
236 }
237
238 result.appendFormat(" Exposure compensation index: %d\n",
239 mParameters.exposureCompensation);
240
241 result.appendFormat(" AE lock %s, AWB lock %s\n",
242 mParameters.autoExposureLock ? "enabled" : "disabled",
243 mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
244
245 result.appendFormat(" Metering areas:\n");
246 for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
247 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
248 mParameters.meteringAreas[i].left,
249 mParameters.meteringAreas[i].top,
250 mParameters.meteringAreas[i].right,
251 mParameters.meteringAreas[i].bottom,
252 mParameters.meteringAreas[i].weight);
253 }
254
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700255 result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
256 result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700257 mParameters.videoHeight);
258
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700259 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700260 mParameters.recordingHint ? "set" : "not set");
261
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700262 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263 mParameters.videoStabilization ? "enabled" : "disabled");
264
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700265 result.append(" Current streams:\n");
266 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
267 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
268
269 result.append(" Current requests:\n");
270 if (mPreviewRequest != NULL) {
271 result.append(" Preview request:\n");
272 write(fd, result.string(), result.size());
273 dump_camera_metadata(mPreviewRequest, fd, 2);
274 } else {
275 result.append(" Preview request: undefined\n");
276 write(fd, result.string(), result.size());
277 }
278
279 if (mCaptureRequest != NULL) {
280 result = " Capture request:\n";
281 write(fd, result.string(), result.size());
282 dump_camera_metadata(mCaptureRequest, fd, 2);
283 } else {
284 result = " Capture request: undefined\n";
285 write(fd, result.string(), result.size());
286 }
287
288 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700289 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700290
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700291 status_t res = mDevice->dump(fd, args);
292 if (res != OK) {
293 result = String8::format(" Error dumping device: %s (%d)",
294 strerror(-res), res);
295 write(fd, result.string(), result.size());
296 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700297
298#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700299 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700300}
301
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700302const char* Camera2Client::getStateName(State state) {
303#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
304 switch(state) {
305 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
306 CASE_ENUM_TO_CHAR(STOPPED)
307 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
308 CASE_ENUM_TO_CHAR(PREVIEW)
309 CASE_ENUM_TO_CHAR(RECORD)
310 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
311 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
312 default:
313 return "Unknown state!";
314 break;
315 }
316#undef CASE_ENUM_TO_CHAR
317}
318
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700319// ICamera interface
320
321void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700322 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700323 Mutex::Autolock icl(mICameraLock);
324
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700325 if (mDevice == 0) return;
326
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700327 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700328
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700329 mDevice->waitUntilDrained();
330
331 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700332 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700333 mPreviewStreamId = NO_STREAM;
334 }
335
336 if (mCaptureStreamId != NO_STREAM) {
337 mDevice->deleteStream(mCaptureStreamId);
338 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700339 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700340
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700341 CameraService::Client::disconnect();
342}
343
344status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700345 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700346
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700347 Mutex::Autolock icl(mICameraLock);
348
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700349 if (mClientPid != 0 && getCallingPid() != mClientPid) {
350 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
351 "current locked to pid %d", __FUNCTION__,
352 mCameraId, getCallingPid(), mClientPid);
353 return BAD_VALUE;
354 }
355
356 mClientPid = getCallingPid();
357 mCameraClient = client;
358
359 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700360}
361
362status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700363 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700364 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700365 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
366 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700367
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700368 if (mClientPid == 0) {
369 mClientPid = getCallingPid();
370 return OK;
371 }
372
373 if (mClientPid != getCallingPid()) {
374 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
375 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
376 return EBUSY;
377 }
378
379 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700380}
381
382status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700383 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700384 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700385 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
386 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700387
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700388 // TODO: Check for uninterruptable conditions
389
390 if (mClientPid == getCallingPid()) {
391 mClientPid = 0;
392 mCameraClient.clear();
393 return OK;
394 }
395
396 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
397 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
398 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700399}
400
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700401status_t Camera2Client::setPreviewDisplay(
402 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700403 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700404 Mutex::Autolock icl(mICameraLock);
405
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700406 sp<IBinder> binder;
407 sp<ANativeWindow> window;
408 if (surface != 0) {
409 binder = surface->asBinder();
410 window = surface;
411 }
412
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700413 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700414}
415
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700416status_t Camera2Client::setPreviewTexture(
417 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700418 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700419 Mutex::Autolock icl(mICameraLock);
420
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700421 sp<IBinder> binder;
422 sp<ANativeWindow> window;
423 if (surfaceTexture != 0) {
424 binder = surfaceTexture->asBinder();
425 window = new SurfaceTextureClient(surfaceTexture);
426 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700427 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700428}
429
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700430status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700431 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700432 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700433 status_t res;
434
435 if (binder == mPreviewSurface) {
436 return NO_ERROR;
437 }
438
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700439 switch (mState) {
440 case NOT_INITIALIZED:
441 case RECORD:
442 case STILL_CAPTURE:
443 case VIDEO_SNAPSHOT:
444 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
445 __FUNCTION__, mCameraId, getStateName(mState));
446 return INVALID_OPERATION;
447 case STOPPED:
448 case WAITING_FOR_PREVIEW_WINDOW:
449 // OK
450 break;
451 case PREVIEW:
452 // Already running preview - need to stop and create a new stream
453 // TODO: Optimize this so that we don't wait for old stream to drain
454 // before spinning up new stream
455 mDevice->setStreamingRequest(NULL);
456 mState = WAITING_FOR_PREVIEW_WINDOW;
457 break;
458 }
459
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700460 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700461 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700462 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700463 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
464 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700465 return res;
466 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700467 res = mDevice->deleteStream(mPreviewStreamId);
468 if (res != OK) {
469 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
470 __FUNCTION__, strerror(-res), res);
471 return res;
472 }
473 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700474 }
475
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700476 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700477 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700478
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700479 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700480 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700481 }
482
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700484}
485
486void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700487 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700488 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700489}
490
491status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700492 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700493 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700494 return startPreviewLocked();
495}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700496
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700497status_t Camera2Client::startPreviewLocked() {
498 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700499 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700500 if (mState >= PREVIEW) {
501 ALOGE("%s: Can't start preview in state %s",
502 __FUNCTION__, getStateName(mState));
503 return INVALID_OPERATION;
504 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700505
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700506 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700507 mState = WAITING_FOR_PREVIEW_WINDOW;
508 return OK;
509 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700510 mState = STOPPED;
511
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700512 Mutex::Autolock pl(mParamsLock);
513
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700514 res = updatePreviewStream();
515 if (res != OK) {
516 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
517 __FUNCTION__, mCameraId, strerror(-res), res);
518 return res;
519 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700520
521 if (mPreviewRequest == NULL) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700522 res = updatePreviewRequest();
523 if (res != OK) {
524 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
525 __FUNCTION__, mCameraId, strerror(-res), res);
526 return res;
527 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700528 }
529
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700530 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700531 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700532 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 if (res != OK) {
534 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
535 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700536 return res;
537 }
538 res = sort_camera_metadata(mPreviewRequest);
539 if (res != OK) {
540 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
541 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700542 return res;
543 }
544
545 res = mDevice->setStreamingRequest(mPreviewRequest);
546 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700547 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
548 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700549 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700550 return res;
551 }
552 mState = PREVIEW;
553
554 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700555}
556
557void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700558 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700559 Mutex::Autolock icl(mICameraLock);
560 stopPreviewLocked();
561}
562
563void Camera2Client::stopPreviewLocked() {
564 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700565 switch (mState) {
566 case NOT_INITIALIZED:
567 ALOGE("%s: Camera %d: Call before initialized",
568 __FUNCTION__, mCameraId);
569 break;
570 case STOPPED:
571 break;
572 case STILL_CAPTURE:
573 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
574 __FUNCTION__, mCameraId);
575 break;
576 case RECORD:
577 // TODO: Handle record stop here
578 case PREVIEW:
579 mDevice->setStreamingRequest(NULL);
580 case WAITING_FOR_PREVIEW_WINDOW:
581 mState = STOPPED;
582 break;
583 default:
584 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
585 mState);
586 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700587}
588
589bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700590 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700591 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700592 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700593}
594
595status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700596 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700597 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700598 return BAD_VALUE;
599}
600
601status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700602 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700603 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700604 status_t res;
605 switch (mState) {
606 case STOPPED:
607 res = startPreviewLocked();
608 if (res != OK) return res;
609 break;
610 case PREVIEW:
611 // Ready to go
612 break;
613 case RECORD:
614 case VIDEO_SNAPSHOT:
615 // OK to call this when recording is already on
616 return OK;
617 break;
618 default:
619 ALOGE("%s: Camera %d: Can't start recording in state %s",
620 __FUNCTION__, mCameraId, getStateName(mState));
621 return INVALID_OPERATION;
622 };
623
624 Mutex::Autolock pl(mParamsLock);
625
626 res = updateRecordingStream();
627 if (res != OK) {
628 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
629 __FUNCTION__, mCameraId, strerror(-res), res);
630 return res;
631 }
632
633 if (mRecordingRequest == NULL) {
634 res = updateRecordingRequest();
635 if (res != OK) {
636 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
637 __FUNCTION__, mCameraId, strerror(-res), res);
638 return res;
639 }
640 }
641
642 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
643 res = updateEntry(mRecordingRequest,
644 ANDROID_REQUEST_OUTPUT_STREAMS,
645 outputStreams, 2);
646 if (res != OK) {
647 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
648 __FUNCTION__, mCameraId, strerror(-res), res);
649 return res;
650 }
651 res = sort_camera_metadata(mRecordingRequest);
652 if (res != OK) {
653 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
654 __FUNCTION__, mCameraId, strerror(-res), res);
655 return res;
656 }
657
658 res = mDevice->setStreamingRequest(mRecordingRequest);
659 if (res != OK) {
660 ALOGE("%s: Camera %d: Unable to set recording request to start "
661 "recording: %s (%d)", __FUNCTION__, mCameraId,
662 strerror(-res), res);
663 return res;
664 }
665 mState = RECORD;
666
667 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700668}
669
670void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700671 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700672 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700673 status_t res;
674 switch (mState) {
675 case RECORD:
676 // OK to stop
677 break;
678 case STOPPED:
679 case PREVIEW:
680 case STILL_CAPTURE:
681 case VIDEO_SNAPSHOT:
682 default:
683 ALOGE("%s: Camera %d: Can't stop recording in state %s",
684 __FUNCTION__, mCameraId, getStateName(mState));
685 return;
686 };
687
688 // Back to preview. Since record can only be reached through preview,
689 // all preview stream setup should be up to date.
690 res = mDevice->setStreamingRequest(mPreviewRequest);
691 if (res != OK) {
692 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
693 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
694 return;
695 }
696
697 // TODO: Should recording heap be freed? Can't do it yet since requests
698 // could still be in flight.
699
700 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700701}
702
703bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700704 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700705 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700706 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700707}
708
709void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700710 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700711 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700712 // Make sure this is for the current heap
713 ssize_t offset;
714 size_t size;
715 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
716 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
717 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
718 "(got %x, expected %x)", __FUNCTION__, mCameraId,
719 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
720 return;
721 }
722 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700723}
724
725status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700726 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700727 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700728 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700729}
730
731status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700732 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700733 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700734 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700735}
736
737status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700738 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700739 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700740 status_t res;
741
742 switch (mState) {
743 case NOT_INITIALIZED:
744 case STOPPED:
745 case WAITING_FOR_PREVIEW_WINDOW:
746 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
747 __FUNCTION__, mCameraId);
748 return INVALID_OPERATION;
749 case PREVIEW:
750 case RECORD:
751 // Good to go for takePicture
752 break;
753 case STILL_CAPTURE:
754 case VIDEO_SNAPSHOT:
755 ALOGE("%s: Camera %d: Already taking a picture",
756 __FUNCTION__, mCameraId);
757 return INVALID_OPERATION;
758 }
759
760 Mutex::Autolock pl(mParamsLock);
761
762 res = updateCaptureStream();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700763 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700764 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
765 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700766 return res;
767 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700768
769 if (mCaptureRequest == NULL) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700770 res = updateCaptureRequest();
771 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700772 ALOGE("%s: Camera %d: Can't create still image capture request: "
773 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700774 return res;
775 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700776 }
777
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700778 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700779 if (mState == PREVIEW) {
780 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
781 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
782 &streamIds, 2);
783 } else if (mState == RECORD) {
784 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
785 mCaptureStreamId };
786 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
787 &streamIds, 3);
788 }
789
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700790 if (res != OK) {
791 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
792 "%s (%d)",
793 __FUNCTION__, mCameraId, strerror(-res), res);
794 return res;
795 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700796 res = sort_camera_metadata(mCaptureRequest);
797 if (res != OK) {
798 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
799 __FUNCTION__, mCameraId, strerror(-res), res);
800 return res;
801 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700802
803 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
804 if (captureCopy == NULL) {
805 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
806 __FUNCTION__, mCameraId);
807 return NO_MEMORY;
808 }
809
810 if (mState == PREVIEW) {
811 res = mDevice->setStreamingRequest(NULL);
812 if (res != OK) {
813 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
814 "%s (%d)",
815 __FUNCTION__, mCameraId, strerror(-res), res);
816 return res;
817 }
818 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700819 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700820 res = mDevice->capture(captureCopy);
821 if (res != OK) {
822 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
823 "%s (%d)",
824 __FUNCTION__, mCameraId, strerror(-res), res);
825 return res;
826 }
827
828 switch (mState) {
829 case PREVIEW:
830 mState = STILL_CAPTURE;
831 break;
832 case RECORD:
833 mState = VIDEO_SNAPSHOT;
834 break;
835 default:
836 ALOGE("%s: Camera %d: Unknown state for still capture!",
837 __FUNCTION__, mCameraId);
838 return INVALID_OPERATION;
839 }
840
841 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700842}
843
844status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700845 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700846 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700847 Mutex::Autolock pl(mParamsLock);
848 status_t res;
849
850 CameraParameters newParams(params);
851
852 // TODO: Currently ignoring any changes to supposedly read-only
853 // parameters such as supported preview sizes, etc. Should probably
854 // produce an error if they're changed.
855
856 /** Extract and verify new parameters */
857
858 size_t i;
859
860 // PREVIEW_SIZE
861 int previewWidth, previewHeight;
862 newParams.getPreviewSize(&previewWidth, &previewHeight);
863
864 if (previewWidth != mParameters.previewWidth ||
865 previewHeight != mParameters.previewHeight) {
866 if (mState >= PREVIEW) {
867 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700868 "is active! (Currently %d x %d, requested %d x %d",
869 __FUNCTION__,
870 mParameters.previewWidth, mParameters.previewHeight,
871 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700872 return BAD_VALUE;
873 }
874 camera_metadata_entry_t availablePreviewSizes =
875 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
876 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
877 if (availablePreviewSizes.data.i32[i] == previewWidth &&
878 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
879 }
880 if (i == availablePreviewSizes.count) {
881 ALOGE("%s: Requested preview size %d x %d is not supported",
882 __FUNCTION__, previewWidth, previewHeight);
883 return BAD_VALUE;
884 }
885 }
886
887 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700888 int previewFpsRange[2];
889 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700890 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700891 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
892 if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
893 previewFpsRange[1] != mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700894 fpsRangeChanged = true;
895 camera_metadata_entry_t availablePreviewFpsRanges =
896 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
897 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
898 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700899 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700900 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700901 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700902 break;
903 }
904 }
905 if (i == availablePreviewFpsRanges.count) {
906 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700907 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700908 return BAD_VALUE;
909 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700910 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700911 }
912
913 // PREVIEW_FORMAT
914 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
915 if (previewFormat != mParameters.previewFormat) {
916 if (mState >= PREVIEW) {
917 ALOGE("%s: Preview format cannot be updated when preview "
918 "is active!", __FUNCTION__);
919 return BAD_VALUE;
920 }
921 camera_metadata_entry_t availableFormats =
922 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
923 for (i = 0; i < availableFormats.count; i++) {
924 if (availableFormats.data.i32[i] == previewFormat) break;
925 }
926 if (i == availableFormats.count) {
927 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
928 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
929 return BAD_VALUE;
930 }
931 }
932
933 // PREVIEW_FRAME_RATE
934 // Deprecated, only use if the preview fps range is unchanged this time.
935 // The single-value FPS is the same as the minimum of the range.
936 if (!fpsRangeChanged) {
937 previewFps = newParams.getPreviewFrameRate();
938 if (previewFps != mParameters.previewFps) {
939 camera_metadata_entry_t availableFrameRates =
940 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
941 for (i = 0; i < availableFrameRates.count; i+=2) {
942 if (availableFrameRates.data.i32[i] == previewFps) break;
943 }
944 if (i == availableFrameRates.count) {
945 ALOGE("%s: Requested preview frame rate %d is not supported",
946 __FUNCTION__, previewFps);
947 return BAD_VALUE;
948 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700949 previewFpsRange[0] = availableFrameRates.data.i32[i];
950 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700951 }
952 }
953
954 // PICTURE_SIZE
955 int pictureWidth, pictureHeight;
956 newParams.getPictureSize(&pictureWidth, &pictureHeight);
957 if (pictureWidth == mParameters.pictureWidth ||
958 pictureHeight == mParameters.pictureHeight) {
959 camera_metadata_entry_t availablePictureSizes =
960 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
961 for (i = 0; i < availablePictureSizes.count; i+=2) {
962 if (availablePictureSizes.data.i32[i] == pictureWidth &&
963 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
964 }
965 if (i == availablePictureSizes.count) {
966 ALOGE("%s: Requested picture size %d x %d is not supported",
967 __FUNCTION__, pictureWidth, pictureHeight);
968 return BAD_VALUE;
969 }
970 }
971
972 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700973 int jpegThumbSize[2];
974 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700975 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700976 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700977 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700978 if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
979 jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700980 camera_metadata_entry_t availableJpegThumbSizes =
981 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
982 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700983 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
984 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700985 break;
986 }
987 }
988 if (i == availableJpegThumbSizes.count) {
989 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700990 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700991 return BAD_VALUE;
992 }
993 }
994
995 // JPEG_THUMBNAIL_QUALITY
996 int jpegThumbQuality =
997 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
998 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
999 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1000 __FUNCTION__, jpegThumbQuality);
1001 return BAD_VALUE;
1002 }
1003
1004 // JPEG_QUALITY
1005 int jpegQuality =
1006 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1007 if (jpegQuality < 0 || jpegQuality > 100) {
1008 ALOGE("%s: Requested JPEG quality %d is not supported",
1009 __FUNCTION__, jpegQuality);
1010 return BAD_VALUE;
1011 }
1012
1013 // ROTATION
1014 int jpegRotation =
1015 newParams.getInt(CameraParameters::KEY_ROTATION);
1016 if (jpegRotation != 0 &&
1017 jpegRotation != 90 &&
1018 jpegRotation != 180 &&
1019 jpegRotation != 270) {
1020 ALOGE("%s: Requested picture rotation angle %d is not supported",
1021 __FUNCTION__, jpegRotation);
1022 return BAD_VALUE;
1023 }
1024
1025 // GPS
1026 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001027 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001028 int64_t gpsTimestamp = 0;
1029 String8 gpsProcessingMethod;
1030 const char *gpsLatStr =
1031 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1032 if (gpsLatStr != NULL) {
1033 const char *gpsLongStr =
1034 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1035 const char *gpsAltitudeStr =
1036 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1037 const char *gpsTimeStr =
1038 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1039 const char *gpsProcMethodStr =
1040 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1041 if (gpsLongStr == NULL ||
1042 gpsAltitudeStr == NULL ||
1043 gpsTimeStr == NULL ||
1044 gpsProcMethodStr == NULL) {
1045 ALOGE("%s: Incomplete set of GPS parameters provided",
1046 __FUNCTION__);
1047 return BAD_VALUE;
1048 }
1049 char *endPtr;
1050 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001051 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001052 if (errno || endPtr == gpsLatStr) {
1053 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1054 return BAD_VALUE;
1055 }
1056 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001057 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001058 if (errno || endPtr == gpsLongStr) {
1059 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1060 return BAD_VALUE;
1061 }
1062 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001063 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001064 if (errno || endPtr == gpsAltitudeStr) {
1065 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1066 gpsAltitudeStr);
1067 return BAD_VALUE;
1068 }
1069 errno = 0;
1070 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1071 if (errno || endPtr == gpsTimeStr) {
1072 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1073 return BAD_VALUE;
1074 }
1075 gpsProcessingMethod = gpsProcMethodStr;
1076
1077 gpsEnabled = true;
1078 }
1079
1080 // WHITE_BALANCE
1081 int wbMode = wbModeStringToEnum(
1082 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1083 if (wbMode != mParameters.wbMode) {
1084 camera_metadata_entry_t availableWbModes =
1085 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1086 for (i = 0; i < availableWbModes.count; i++) {
1087 if (wbMode == availableWbModes.data.u8[i]) break;
1088 }
1089 if (i == availableWbModes.count) {
1090 ALOGE("%s: Requested white balance mode %s is not supported",
1091 __FUNCTION__,
1092 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1093 return BAD_VALUE;
1094 }
1095 }
1096
1097 // EFFECT
1098 int effectMode = effectModeStringToEnum(
1099 newParams.get(CameraParameters::KEY_EFFECT) );
1100 if (effectMode != mParameters.effectMode) {
1101 camera_metadata_entry_t availableEffectModes =
1102 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1103 for (i = 0; i < availableEffectModes.count; i++) {
1104 if (effectMode == availableEffectModes.data.u8[i]) break;
1105 }
1106 if (i == availableEffectModes.count) {
1107 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1108 __FUNCTION__,
1109 newParams.get(CameraParameters::KEY_EFFECT) );
1110 return BAD_VALUE;
1111 }
1112 }
1113
1114 // ANTIBANDING
1115 int antibandingMode = abModeStringToEnum(
1116 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1117 if (antibandingMode != mParameters.antibandingMode) {
1118 camera_metadata_entry_t availableAbModes =
1119 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1120 for (i = 0; i < availableAbModes.count; i++) {
1121 if (antibandingMode == availableAbModes.data.u8[i]) break;
1122 }
1123 if (i == availableAbModes.count) {
1124 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1125 __FUNCTION__,
1126 newParams.get(CameraParameters::KEY_ANTIBANDING));
1127 return BAD_VALUE;
1128 }
1129 }
1130
1131 // SCENE_MODE
1132 int sceneMode = sceneModeStringToEnum(
1133 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1134 if (sceneMode != mParameters.sceneMode) {
1135 camera_metadata_entry_t availableSceneModes =
1136 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1137 for (i = 0; i < availableSceneModes.count; i++) {
1138 if (sceneMode == availableSceneModes.data.u8[i]) break;
1139 }
1140 if (i == availableSceneModes.count) {
1141 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1142 __FUNCTION__,
1143 newParams.get(CameraParameters::KEY_SCENE_MODE));
1144 return BAD_VALUE;
1145 }
1146 }
1147
1148 // FLASH_MODE
1149 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1150 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1151 if (flashMode != mParameters.flashMode) {
1152 camera_metadata_entry_t flashAvailable =
1153 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1154 if (!flashAvailable.data.u8[0] &&
1155 flashMode != Parameters::FLASH_MODE_OFF) {
1156 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1157 "No flash on device", __FUNCTION__,
1158 newParams.get(CameraParameters::KEY_FLASH_MODE));
1159 return BAD_VALUE;
1160 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1161 camera_metadata_entry_t availableAeModes =
1162 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1163 for (i = 0; i < availableAeModes.count; i++) {
1164 if (flashMode == availableAeModes.data.u8[i]) break;
1165 }
1166 if (i == availableAeModes.count) {
1167 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1168 __FUNCTION__,
1169 newParams.get(CameraParameters::KEY_FLASH_MODE));
1170 return BAD_VALUE;
1171 }
1172 } else if (flashMode == -1) {
1173 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1174 __FUNCTION__,
1175 newParams.get(CameraParameters::KEY_FLASH_MODE));
1176 return BAD_VALUE;
1177 }
1178 }
1179
1180 // FOCUS_MODE
1181 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1182 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1183 if (focusMode != mParameters.focusMode) {
1184 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1185 camera_metadata_entry_t minFocusDistance =
1186 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1187 if (minFocusDistance.data.f[0] == 0) {
1188 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1189 "fixed focus lens",
1190 __FUNCTION__,
1191 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1192 return BAD_VALUE;
1193 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1194 camera_metadata_entry_t availableFocusModes =
1195 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1196 for (i = 0; i < availableFocusModes.count; i++) {
1197 if (focusMode == availableFocusModes.data.u8[i]) break;
1198 }
1199 if (i == availableFocusModes.count) {
1200 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1201 __FUNCTION__,
1202 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1203 return BAD_VALUE;
1204 }
1205 }
1206 }
1207 }
1208
1209 // FOCUS_AREAS
1210 Vector<Parameters::Area> focusingAreas;
1211 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1212 &focusingAreas);
1213 size_t max3aRegions =
1214 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1215 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1216 if (res != OK) {
1217 ALOGE("%s: Requested focus areas are malformed: %s",
1218 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1219 return BAD_VALUE;
1220 }
1221
1222 // EXPOSURE_COMPENSATION
1223 int exposureCompensation =
1224 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1225 camera_metadata_entry_t exposureCompensationRange =
1226 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1227 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1228 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1229 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1230 __FUNCTION__, exposureCompensation);
1231 return BAD_VALUE;
1232 }
1233
1234 // AUTO_EXPOSURE_LOCK (always supported)
1235 bool autoExposureLock = boolFromString(
1236 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1237
1238 // AUTO_WHITEBALANCE_LOCK (always supported)
1239 bool autoWhiteBalanceLock = boolFromString(
1240 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1241
1242 // METERING_AREAS
1243 Vector<Parameters::Area> meteringAreas;
1244 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1245 &meteringAreas);
1246 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1247 if (res != OK) {
1248 ALOGE("%s: Requested metering areas are malformed: %s",
1249 __FUNCTION__,
1250 newParams.get(CameraParameters::KEY_METERING_AREAS));
1251 return BAD_VALUE;
1252 }
1253
1254 // ZOOM
1255 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1256 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1257 ALOGE("%s: Requested zoom level %d is not supported",
1258 __FUNCTION__, zoom);
1259 return BAD_VALUE;
1260 }
1261
1262 // VIDEO_SIZE
1263 int videoWidth, videoHeight;
1264 newParams.getVideoSize(&videoWidth, &videoHeight);
1265 if (videoWidth != mParameters.videoWidth ||
1266 videoHeight != mParameters.videoHeight) {
1267 if (mState == RECORD) {
1268 ALOGE("%s: Video size cannot be updated when recording is active!",
1269 __FUNCTION__);
1270 return BAD_VALUE;
1271 }
1272 camera_metadata_entry_t availableVideoSizes =
1273 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1274 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1275 if (availableVideoSizes.data.i32[i] == videoWidth &&
1276 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1277 }
1278 if (i == availableVideoSizes.count) {
1279 ALOGE("%s: Requested video size %d x %d is not supported",
1280 __FUNCTION__, videoWidth, videoHeight);
1281 return BAD_VALUE;
1282 }
1283 }
1284
1285 // RECORDING_HINT (always supported)
1286 bool recordingHint = boolFromString(
1287 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1288
1289 // VIDEO_STABILIZATION
1290 bool videoStabilization = boolFromString(
1291 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1292 camera_metadata_entry_t availableVideoStabilizationModes =
1293 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1294 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1295 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1296 }
1297
1298 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001299
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001300 mParameters.previewWidth = previewWidth;
1301 mParameters.previewHeight = previewHeight;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001302 mParameters.previewFpsRange[0] = previewFpsRange[0];
1303 mParameters.previewFpsRange[1] = previewFpsRange[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001304 mParameters.previewFps = previewFps;
1305 mParameters.previewFormat = previewFormat;
1306
1307 mParameters.pictureWidth = pictureWidth;
1308 mParameters.pictureHeight = pictureHeight;
1309
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001310 mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1311 mParameters.jpegThumbSize[1] = jpegThumbSize[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001312 mParameters.jpegQuality = jpegQuality;
1313 mParameters.jpegThumbQuality = jpegThumbQuality;
1314
1315 mParameters.gpsEnabled = gpsEnabled;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001316 mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1317 mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1318 mParameters.gpsCoordinates[2] = gpsCoordinates[2];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001319 mParameters.gpsTimestamp = gpsTimestamp;
1320 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1321
1322 mParameters.wbMode = wbMode;
1323 mParameters.effectMode = effectMode;
1324 mParameters.antibandingMode = antibandingMode;
1325 mParameters.sceneMode = sceneMode;
1326
1327 mParameters.flashMode = flashMode;
1328 mParameters.focusMode = focusMode;
1329
1330 mParameters.focusingAreas = focusingAreas;
1331 mParameters.exposureCompensation = exposureCompensation;
1332 mParameters.autoExposureLock = autoExposureLock;
1333 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1334 mParameters.meteringAreas = meteringAreas;
1335 mParameters.zoom = zoom;
1336
1337 mParameters.videoWidth = videoWidth;
1338 mParameters.videoHeight = videoHeight;
1339
1340 mParameters.recordingHint = recordingHint;
1341 mParameters.videoStabilization = videoStabilization;
1342
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001343 res = updatePreviewRequest();
1344 if (res != OK) {
1345 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1346 __FUNCTION__, mCameraId, strerror(-res), res);
1347 return res;
1348 }
1349 res = updateCaptureRequest();
1350 if (res != OK) {
1351 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1352 __FUNCTION__, mCameraId, strerror(-res), res);
1353 return res;
1354 }
1355
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001356 res = updateRecordingRequest();
1357 if (res != OK) {
1358 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1359 __FUNCTION__, mCameraId, strerror(-res), res);
1360 return res;
1361 }
1362
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001363 if (mState == PREVIEW) {
1364 res = mDevice->setStreamingRequest(mPreviewRequest);
1365 if (res != OK) {
1366 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1367 __FUNCTION__, mCameraId, strerror(-res), res);
1368 return res;
1369 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001370 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1371 res = mDevice->setStreamingRequest(mRecordingRequest);
1372 if (res != OK) {
1373 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1374 __FUNCTION__, mCameraId, strerror(-res), res);
1375 return res;
1376 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001377 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001378
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001379 mParamsFlattened = params;
1380
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001381 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001382}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001383
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001384String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001385 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001386 Mutex::Autolock icl(mICameraLock);
1387
1388 Mutex::Autolock pl(mParamsLock);
1389
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001390 // TODO: Deal with focus distances
1391 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001392}
1393
1394status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001395 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001396 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001397
1398 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1399 cmd, arg1, arg2);
1400
1401 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
1402 int transform = degToTransform(arg1,
1403 mCameraFacing == CAMERA_FACING_FRONT);
1404 if (transform == -1) {
1405 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1406 __FUNCTION__, mCameraId, arg1);
1407 return BAD_VALUE;
1408 }
1409 if (transform != mParameters.previewTransform &&
1410 mPreviewStreamId != NO_STREAM) {
1411 mDevice->setStreamTransform(mPreviewStreamId, transform);
1412 }
1413 mParameters.previewTransform = transform;
1414 return OK;
1415 }
1416
1417 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1418 mCameraId, cmd, arg1, arg2);
1419
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001420 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001421}
1422
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001423/** Device-related methods */
1424
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001425void Camera2Client::onCaptureAvailable() {
1426 ATRACE_CALL();
1427 status_t res;
1428 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001429 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1430
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001431 CpuConsumer::LockedBuffer imgBuffer;
1432 {
1433 Mutex::Autolock icl(mICameraLock);
1434
1435 // TODO: Signal errors here upstream
1436 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1437 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1438 __FUNCTION__, mCameraId);
1439 return;
1440 }
1441
1442 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1443 if (res != OK) {
1444 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1445 __FUNCTION__, mCameraId, strerror(-res), res);
1446 return;
1447 }
1448
1449 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1450 ALOGE("%s: Camera %d: Unexpected format for still image: "
1451 "%x, expected %x", __FUNCTION__, mCameraId,
1452 imgBuffer.format,
1453 HAL_PIXEL_FORMAT_BLOB);
1454 mCaptureConsumer->unlockBuffer(imgBuffer);
1455 return;
1456 }
1457
1458 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001459 void* captureMemory = mCaptureHeap->mHeap->getBase();
1460 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001461 memcpy(captureMemory, imgBuffer.data, size);
1462
1463 mCaptureConsumer->unlockBuffer(imgBuffer);
1464
1465 currentClient = mCameraClient;
1466 switch (mState) {
1467 case STILL_CAPTURE:
1468 mState = STOPPED;
1469 break;
1470 case VIDEO_SNAPSHOT:
1471 mState = RECORD;
1472 break;
1473 default:
1474 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1475 mCameraId, mState);
1476 break;
1477 }
1478 }
1479 // Call outside mICameraLock to allow re-entrancy from notification
1480 if (currentClient != 0) {
1481 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001482 mCaptureHeap->mBuffers[0], NULL);
1483 }
1484}
1485
1486void Camera2Client::onRecordingFrameAvailable() {
1487 ATRACE_CALL();
1488 status_t res;
1489 sp<ICameraClient> currentClient;
1490 size_t heapIdx = 0;
1491 nsecs_t timestamp;
1492 {
1493 Mutex::Autolock icl(mICameraLock);
1494 // TODO: Signal errors here upstream
1495 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
1496 ALOGE("%s: Camera %d: Recording image buffer produced unexpectedly!",
1497 __FUNCTION__, mCameraId);
1498 return;
1499 }
1500
1501 CpuConsumer::LockedBuffer imgBuffer;
1502 res = mRecordingConsumer->lockNextBuffer(&imgBuffer);
1503 if (res != OK) {
1504 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1505 __FUNCTION__, mCameraId, strerror(-res), res);
1506 return;
1507 }
1508
1509 if (imgBuffer.format != (int)kRecordingFormat) {
1510 ALOGE("%s: Camera %d: Unexpected recording format: %x",
1511 __FUNCTION__, mCameraId, imgBuffer.format);
1512 mRecordingConsumer->unlockBuffer(imgBuffer);
1513 return;
1514 }
1515 size_t bufferSize = imgBuffer.width * imgBuffer.height * 3 / 2;
1516
1517 if (mRecordingHeap == 0 ||
1518 bufferSize >
1519 mRecordingHeap->mHeap->getSize() / kRecordingHeapCount) {
1520 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1521 "size %d bytes", __FUNCTION__, mCameraId,
1522 kRecordingHeapCount, bufferSize);
1523 if (mRecordingHeap != 0) {
1524 ALOGV("%s: Camera %d: Previous heap has size %d "
1525 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1526 mRecordingHeap->mHeap->getSize(),
1527 bufferSize * kRecordingHeapCount);
1528 }
1529 // Need to allocate memory for heap
1530 mRecordingHeap.clear();
1531
1532 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1533 "Camera2Client::RecordingHeap");
1534 if (mRecordingHeap->mHeap->getSize() == 0) {
1535 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1536 __FUNCTION__, mCameraId);
1537 mRecordingConsumer->unlockBuffer(imgBuffer);
1538 return;
1539 }
1540 mRecordingHeapHead = 0;
1541 mRecordingHeapFree = kRecordingHeapCount;
1542 }
1543
1544 // TODO: Optimize this to avoid memcopy
1545 if ( mRecordingHeapFree == 0) {
1546 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1547 __FUNCTION__, mCameraId);
1548 mRecordingConsumer->unlockBuffer(imgBuffer);
1549 return;
1550 }
1551 heapIdx = mRecordingHeapHead;
1552 timestamp = imgBuffer.timestamp;
1553 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1554 mRecordingHeapFree--;
1555
1556 ALOGV("%s: Camera %d: Timestamp %lld",
1557 __FUNCTION__, mCameraId, timestamp);
1558
1559 ssize_t offset;
1560 size_t size;
1561 sp<IMemoryHeap> heap =
1562 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1563 &size);
1564
1565 memcpy((uint8_t*)heap->getBase() + offset, imgBuffer.data, size);
1566
1567 mRecordingConsumer->unlockBuffer(imgBuffer);
1568
1569 currentClient = mCameraClient;
1570 }
1571 // Call outside mICameraLock to allow re-entrancy from notification
1572 if (currentClient != 0) {
1573 currentClient->dataCallbackTimestamp(timestamp,
1574 CAMERA_MSG_VIDEO_FRAME,
1575 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001576 }
1577}
1578
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001579camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1580 size_t minCount, size_t maxCount) {
1581 status_t res;
1582 camera_metadata_entry_t entry;
1583 res = find_camera_metadata_entry(mDevice->info(),
1584 tag,
1585 &entry);
1586 if (CC_UNLIKELY( res != OK )) {
1587 const char* tagSection = get_camera_metadata_section_name(tag);
1588 if (tagSection == NULL) tagSection = "<unknown>";
1589 const char* tagName = get_camera_metadata_tag_name(tag);
1590 if (tagName == NULL) tagName = "<unknown>";
1591
1592 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1593 tagSection, tagName, tag, strerror(-res), res);
1594 entry.count = 0;
1595 entry.data.u8 = NULL;
1596 } else if (CC_UNLIKELY(
1597 (minCount != 0 && entry.count < minCount) ||
1598 (maxCount != 0 && entry.count > maxCount) ) ) {
1599 const char* tagSection = get_camera_metadata_section_name(tag);
1600 if (tagSection == NULL) tagSection = "<unknown>";
1601 const char* tagName = get_camera_metadata_tag_name(tag);
1602 if (tagName == NULL) tagName = "<unknown>";
1603 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1604 "Expected between %d and %d values, but got %d values",
1605 tagSection, tagName, tag, minCount, maxCount, entry.count);
1606 entry.count = 0;
1607 entry.data.u8 = NULL;
1608 }
1609
1610 return entry;
1611}
1612
1613/** Utility methods */
1614
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001615
1616status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001617 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001618 Mutex::Autolock pl(mParamsLock);
1619
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001620 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001621 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001622
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001623 camera_metadata_entry_t availableProcessedSizes =
1624 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1625 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001626
1627 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001628 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1629 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1630 mParameters.videoWidth = mParameters.previewWidth;
1631 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001632
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001633 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1634 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1635 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1636 String8::format("%dx%d",
1637 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001638 {
1639 String8 supportedPreviewSizes;
1640 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1641 if (i != 0) supportedPreviewSizes += ",";
1642 supportedPreviewSizes += String8::format("%dx%d",
1643 availableProcessedSizes.data.i32[i],
1644 availableProcessedSizes.data.i32[i+1]);
1645 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001646 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001647 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001648 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001649 supportedPreviewSizes);
1650 }
1651
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001652 camera_metadata_entry_t availableFpsRanges =
1653 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1654 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001655
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001656 mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1657 mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001658
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001659 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1660 String8::format("%d,%d",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001661 mParameters.previewFpsRange[0],
1662 mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001663
1664 {
1665 String8 supportedPreviewFpsRange;
1666 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1667 if (i != 0) supportedPreviewFpsRange += ",";
1668 supportedPreviewFpsRange += String8::format("(%d,%d)",
1669 availableFpsRanges.data.i32[i],
1670 availableFpsRanges.data.i32[i+1]);
1671 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001672 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001673 supportedPreviewFpsRange);
1674 }
1675
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001676 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1677 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1678 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001679
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001680 mParameters.previewTransform = degToTransform(0,
1681 mCameraFacing == CAMERA_FACING_FRONT);
1682
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001683 camera_metadata_entry_t availableFormats =
1684 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1685
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001686 {
1687 String8 supportedPreviewFormats;
1688 bool addComma = false;
1689 for (size_t i=0; i < availableFormats.count; i++) {
1690 if (addComma) supportedPreviewFormats += ",";
1691 addComma = true;
1692 switch (availableFormats.data.i32[i]) {
1693 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001694 supportedPreviewFormats +=
1695 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001696 break;
1697 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001698 supportedPreviewFormats +=
1699 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001700 break;
1701 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001702 supportedPreviewFormats +=
1703 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001704 break;
1705 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001706 supportedPreviewFormats +=
1707 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001708 break;
1709 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001710 supportedPreviewFormats +=
1711 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001712 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001713 case HAL_PIXEL_FORMAT_RGBA_8888:
1714 supportedPreviewFormats +=
1715 CameraParameters::PIXEL_FORMAT_RGBA8888;
1716 break;
1717 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001718 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001719 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001720 addComma = false;
1721 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001722
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001723 default:
1724 ALOGW("%s: Camera %d: Unknown preview format: %x",
1725 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1726 addComma = false;
1727 break;
1728 }
1729 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001730 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001731 supportedPreviewFormats);
1732 }
1733
1734 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1735 // still have to do something sane for them
1736
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001737 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001738 mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001739
1740 {
1741 String8 supportedPreviewFrameRates;
1742 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1743 if (i != 0) supportedPreviewFrameRates += ",";
1744 supportedPreviewFrameRates += String8::format("%d",
1745 availableFpsRanges.data.i32[i]);
1746 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001747 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001748 supportedPreviewFrameRates);
1749 }
1750
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001751 camera_metadata_entry_t availableJpegSizes =
1752 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1753 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001754
1755 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001756 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1757 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001758
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001759 params.setPictureSize(mParameters.pictureWidth,
1760 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001761
1762 {
1763 String8 supportedPictureSizes;
1764 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1765 if (i != 0) supportedPictureSizes += ",";
1766 supportedPictureSizes += String8::format("%dx%d",
1767 availableJpegSizes.data.i32[i],
1768 availableJpegSizes.data.i32[i+1]);
1769 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001770 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001771 supportedPictureSizes);
1772 }
1773
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001774 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1775 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1776 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001777
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001778 camera_metadata_entry_t availableJpegThumbnailSizes =
1779 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1780 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001781
1782 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001783 mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1784 mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001785
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001786 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001787 mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001788 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001789 mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001790
1791 {
1792 String8 supportedJpegThumbSizes;
1793 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1794 if (i != 0) supportedJpegThumbSizes += ",";
1795 supportedJpegThumbSizes += String8::format("%dx%d",
1796 availableJpegThumbnailSizes.data.i32[i],
1797 availableJpegThumbnailSizes.data.i32[i+1]);
1798 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001799 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001800 supportedJpegThumbSizes);
1801 }
1802
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001803 mParameters.jpegThumbQuality = 90;
1804 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1805 mParameters.jpegThumbQuality);
1806 mParameters.jpegQuality = 90;
1807 params.set(CameraParameters::KEY_JPEG_QUALITY,
1808 mParameters.jpegQuality);
1809 mParameters.jpegRotation = 0;
1810 params.set(CameraParameters::KEY_ROTATION,
1811 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001812
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001813 mParameters.gpsEnabled = false;
1814 mParameters.gpsProcessingMethod = "unknown";
1815 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001816
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001817 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1818 params.set(CameraParameters::KEY_WHITE_BALANCE,
1819 CameraParameters::WHITE_BALANCE_AUTO);
1820
1821 camera_metadata_entry_t availableWhiteBalanceModes =
1822 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001823 {
1824 String8 supportedWhiteBalance;
1825 bool addComma = false;
1826 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1827 if (addComma) supportedWhiteBalance += ",";
1828 addComma = true;
1829 switch (availableWhiteBalanceModes.data.u8[i]) {
1830 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001831 supportedWhiteBalance +=
1832 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001833 break;
1834 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001835 supportedWhiteBalance +=
1836 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001837 break;
1838 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001839 supportedWhiteBalance +=
1840 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001841 break;
1842 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001843 supportedWhiteBalance +=
1844 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001845 break;
1846 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001847 supportedWhiteBalance +=
1848 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001849 break;
1850 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001851 supportedWhiteBalance +=
1852 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001853 break;
1854 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001855 supportedWhiteBalance +=
1856 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001857 break;
1858 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001859 supportedWhiteBalance +=
1860 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001861 break;
1862 // Skipping values not mappable to v1 API
1863 case ANDROID_CONTROL_AWB_OFF:
1864 addComma = false;
1865 break;
1866 default:
1867 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1868 __FUNCTION__, mCameraId,
1869 availableWhiteBalanceModes.data.u8[i]);
1870 addComma = false;
1871 break;
1872 }
1873 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001874 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001875 supportedWhiteBalance);
1876 }
1877
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001878 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1879 params.set(CameraParameters::KEY_EFFECT,
1880 CameraParameters::EFFECT_NONE);
1881
1882 camera_metadata_entry_t availableEffects =
1883 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1884 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001885 {
1886 String8 supportedEffects;
1887 bool addComma = false;
1888 for (size_t i=0; i < availableEffects.count; i++) {
1889 if (addComma) supportedEffects += ",";
1890 addComma = true;
1891 switch (availableEffects.data.u8[i]) {
1892 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001893 supportedEffects +=
1894 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001895 break;
1896 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001897 supportedEffects +=
1898 CameraParameters::EFFECT_MONO;
1899 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001900 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001901 supportedEffects +=
1902 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001903 break;
1904 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001905 supportedEffects +=
1906 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001907 break;
1908 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001909 supportedEffects +=
1910 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001911 break;
1912 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001913 supportedEffects +=
1914 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915 break;
1916 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001917 supportedEffects +=
1918 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001919 break;
1920 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001921 supportedEffects +=
1922 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001923 break;
1924 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001925 supportedEffects +=
1926 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001927 break;
1928 default:
1929 ALOGW("%s: Camera %d: Unknown effect value: %d",
1930 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1931 addComma = false;
1932 break;
1933 }
1934 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001935 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001936 }
1937
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001938 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1939 params.set(CameraParameters::KEY_ANTIBANDING,
1940 CameraParameters::ANTIBANDING_AUTO);
1941
1942 camera_metadata_entry_t availableAntibandingModes =
1943 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1944 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001945 {
1946 String8 supportedAntibanding;
1947 bool addComma = false;
1948 for (size_t i=0; i < availableAntibandingModes.count; i++) {
1949 if (addComma) supportedAntibanding += ",";
1950 addComma = true;
1951 switch (availableAntibandingModes.data.u8[i]) {
1952 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001953 supportedAntibanding +=
1954 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001955 break;
1956 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001957 supportedAntibanding +=
1958 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001959 break;
1960 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001961 supportedAntibanding +=
1962 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001963 break;
1964 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001965 supportedAntibanding +=
1966 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 break;
1968 default:
1969 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
1970 __FUNCTION__, mCameraId,
1971 availableAntibandingModes.data.u8[i]);
1972 addComma = false;
1973 break;
1974 }
1975 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001976 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001977 supportedAntibanding);
1978 }
1979
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001980 mParameters.sceneMode = ANDROID_CONTROL_OFF;
1981 params.set(CameraParameters::KEY_SCENE_MODE,
1982 CameraParameters::SCENE_MODE_AUTO);
1983
1984 camera_metadata_entry_t availableSceneModes =
1985 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1986 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001987 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001988 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001989 bool addComma = true;
1990 bool noSceneModes = false;
1991 for (size_t i=0; i < availableSceneModes.count; i++) {
1992 if (addComma) supportedSceneModes += ",";
1993 addComma = true;
1994 switch (availableSceneModes.data.u8[i]) {
1995 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
1996 noSceneModes = true;
1997 break;
1998 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
1999 // Not in old API
2000 addComma = false;
2001 break;
2002 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002003 supportedSceneModes +=
2004 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002005 break;
2006 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002007 supportedSceneModes +=
2008 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002009 break;
2010 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002011 supportedSceneModes +=
2012 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002013 break;
2014 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002015 supportedSceneModes +=
2016 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017 break;
2018 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002019 supportedSceneModes +=
2020 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002021 break;
2022 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002023 supportedSceneModes +=
2024 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002025 break;
2026 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002027 supportedSceneModes +=
2028 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002029 break;
2030 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002031 supportedSceneModes +=
2032 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002033 break;
2034 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002035 supportedSceneModes +=
2036 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002037 break;
2038 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002039 supportedSceneModes +=
2040 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002041 break;
2042 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002043 supportedSceneModes +=
2044 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002045 break;
2046 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002047 supportedSceneModes +=
2048 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049 break;
2050 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002051 supportedSceneModes +=
2052 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002053 break;
2054 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002055 supportedSceneModes +=
2056 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002057 break;
2058 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002059 supportedSceneModes +=
2060 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002061 break;
2062 default:
2063 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002064 __FUNCTION__, mCameraId,
2065 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002066 addComma = false;
2067 break;
2068 }
2069 }
2070 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002071 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002072 supportedSceneModes);
2073 }
2074 }
2075
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002076 camera_metadata_entry_t flashAvailable =
2077 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2078 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002079
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002080 camera_metadata_entry_t availableAeModes =
2081 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2082 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002083
2084 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002085 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2086 params.set(CameraParameters::KEY_FLASH_MODE,
2087 CameraParameters::FLASH_MODE_AUTO);
2088
2089 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2090 supportedFlashModes = supportedFlashModes +
2091 "," + CameraParameters::FLASH_MODE_AUTO +
2092 "," + CameraParameters::FLASH_MODE_ON +
2093 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002094 for (size_t i=0; i < availableAeModes.count; i++) {
2095 if (availableAeModes.data.u8[i] ==
2096 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002097 supportedFlashModes = supportedFlashModes + "," +
2098 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002099 break;
2100 }
2101 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002102 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002103 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002104 } else {
2105 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2106 params.set(CameraParameters::KEY_FLASH_MODE,
2107 CameraParameters::FLASH_MODE_OFF);
2108 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2109 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002110 }
2111
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002112 camera_metadata_entry_t minFocusDistance =
2113 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2114 if (!minFocusDistance.count) return NO_INIT;
2115
2116 camera_metadata_entry_t availableAfModes =
2117 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2118 if (!availableAfModes.count) return NO_INIT;
2119
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002120 if (minFocusDistance.data.f[0] == 0) {
2121 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002122 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2123 params.set(CameraParameters::KEY_FOCUS_MODE,
2124 CameraParameters::FOCUS_MODE_FIXED);
2125 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2126 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002127 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002128 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2129 params.set(CameraParameters::KEY_FOCUS_MODE,
2130 CameraParameters::FOCUS_MODE_AUTO);
2131 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2132 supportedFocusModes = supportedFocusModes + "," +
2133 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002134 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002135
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002136 for (size_t i=0; i < availableAfModes.count; i++) {
2137 if (addComma) supportedFocusModes += ",";
2138 addComma = true;
2139 switch (availableAfModes.data.u8[i]) {
2140 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002141 supportedFocusModes +=
2142 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002143 break;
2144 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002145 supportedFocusModes +=
2146 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002147 break;
2148 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002149 supportedFocusModes +=
2150 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002151 break;
2152 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002153 supportedFocusModes +=
2154 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002155 break;
2156 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002157 supportedFocusModes +=
2158 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002160 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002161 case ANDROID_CONTROL_AF_OFF:
2162 addComma = false;
2163 break;
2164 default:
2165 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2166 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2167 addComma = false;
2168 break;
2169 }
2170 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002171 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002172 supportedFocusModes);
2173 }
2174
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002175 camera_metadata_entry_t max3aRegions =
2176 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2177 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002178
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002179 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002180 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002181 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002182 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002183 mParameters.focusingAreas.clear();
2184 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002185
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002186 camera_metadata_entry_t availableFocalLengths =
2187 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2188 if (!availableFocalLengths.count) return NO_INIT;
2189
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002190 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002191 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002192
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002193 camera_metadata_entry_t sensorSize =
2194 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2195 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002196
2197 // The fields of view here assume infinity focus, maximum wide angle
2198 float horizFov = 180 / M_PI *
2199 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2200 float vertFov = 180 / M_PI *
2201 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002202 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2203 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002204
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002205 mParameters.exposureCompensation = 0;
2206 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2207 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002208
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002209 camera_metadata_entry_t exposureCompensationRange =
2210 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2211 if (!exposureCompensationRange.count) return NO_INIT;
2212
2213 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002214 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002215 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002216 exposureCompensationRange.data.i32[0]);
2217
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002218 camera_metadata_entry_t exposureCompensationStep =
2219 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2220 if (!exposureCompensationStep.count) return NO_INIT;
2221
2222 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002223 exposureCompensationStep.data.r[0].numerator /
2224 exposureCompensationStep.data.r[0].denominator);
2225
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002226 mParameters.autoExposureLock = false;
2227 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2228 CameraParameters::FALSE);
2229 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2230 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002231
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002232 mParameters.autoWhiteBalanceLock = false;
2233 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2234 CameraParameters::FALSE);
2235 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2236 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002237
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002238 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2239 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002240 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002241 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002242 "(0,0,0,0,0)");
2243
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002244 mParameters.zoom = 0;
2245 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
2246 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002247
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002248 camera_metadata_entry_t maxDigitalZoom =
2249 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2250 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002251
2252 {
2253 String8 zoomRatios;
2254 float zoom = 1.f;
2255 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002256 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002258 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002259 if (addComma) zoomRatios += ",";
2260 addComma = true;
2261 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2262 zoom += zoomIncrement;
2263 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002264 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002265 }
2266
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002267 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2268 CameraParameters::TRUE);
2269 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2270 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002271
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002272 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002273 "Infinity,Infinity,Infinity");
2274
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002275 camera_metadata_entry_t maxFacesDetected =
2276 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2277 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002278 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002279 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002280 0);
2281
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002282 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002283 formatEnumToString(kRecordingFormat));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002284
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002285 params.set(CameraParameters::KEY_RECORDING_HINT,
2286 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002287
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002288 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2289 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002290
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002291 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2292 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002293
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002294 camera_metadata_entry_t availableVideoStabilizationModes =
2295 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2296 if (!availableVideoStabilizationModes.count) return NO_INIT;
2297
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002298 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002299 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2300 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002301 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002302 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2303 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002304 }
2305
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002306 mParamsFlattened = params.flatten();
2307
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002308 return OK;
2309}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002310
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002311status_t Camera2Client::updatePreviewStream() {
2312 ATRACE_CALL();
2313 status_t res;
2314 if (mPreviewStreamId != NO_STREAM) {
2315 // Check if stream parameters have to change
2316 uint32_t currentWidth, currentHeight;
2317 res = mDevice->getStreamInfo(mPreviewStreamId,
2318 &currentWidth, &currentHeight, 0);
2319 if (res != OK) {
2320 ALOGE("%s: Camera %d: Error querying preview stream info: "
2321 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2322 return res;
2323 }
2324 if (currentWidth != (uint32_t)mParameters.previewWidth ||
2325 currentHeight != (uint32_t)mParameters.previewHeight) {
2326 res = mDevice->waitUntilDrained();
2327 if (res != OK) {
2328 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2329 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2330 return res;
2331 }
2332 res = mDevice->deleteStream(mPreviewStreamId);
2333 if (res != OK) {
2334 ALOGE("%s: Camera %d: Unable to delete old output stream "
2335 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2336 strerror(-res), res);
2337 return res;
2338 }
2339 mPreviewStreamId = NO_STREAM;
2340 }
2341 }
2342
2343 if (mPreviewStreamId == NO_STREAM) {
2344 res = mDevice->createStream(mPreviewWindow,
2345 mParameters.previewWidth, mParameters.previewHeight,
2346 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2347 &mPreviewStreamId);
2348 if (res != OK) {
2349 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2350 __FUNCTION__, mCameraId, strerror(-res), res);
2351 return res;
2352 }
2353 }
2354
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002355 res = mDevice->setStreamTransform(mPreviewStreamId,
2356 mParameters.previewTransform);
2357 if (res != OK) {
2358 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2359 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2360 return res;
2361 }
2362
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002363 return OK;
2364}
2365
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002366status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002367 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002368 status_t res;
2369 if (mPreviewRequest == NULL) {
2370 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2371 &mPreviewRequest);
2372 if (res != OK) {
2373 ALOGE("%s: Camera %d: Unable to create default preview request: "
2374 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2375 return res;
2376 }
2377 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002378
2379 res = updateRequestCommon(mPreviewRequest);
2380 if (res != OK) {
2381 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2382 "request: %s (%d)", __FUNCTION__, mCameraId,
2383 strerror(-res), res);
2384 return res;
2385 }
2386
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002387 return OK;
2388}
2389
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002390status_t Camera2Client::updateCaptureStream() {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002391 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002392 status_t res;
2393 // Find out buffer size for JPEG
2394 camera_metadata_entry_t maxJpegSize =
2395 staticInfo(ANDROID_JPEG_MAX_SIZE);
2396 if (maxJpegSize.count == 0) {
2397 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2398 __FUNCTION__, mCameraId);
2399 return INVALID_OPERATION;
2400 }
2401
2402 if (mCaptureConsumer == 0) {
2403 // Create CPU buffer queue endpoint
2404 mCaptureConsumer = new CpuConsumer(1);
2405 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2406 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2407 mCaptureWindow = new SurfaceTextureClient(
2408 mCaptureConsumer->getProducerInterface());
2409 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002410 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2411 "Camera2Client::CaptureHeap");
2412 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002413 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2414 __FUNCTION__, mCameraId);
2415 return NO_MEMORY;
2416 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002417 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002418
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002419 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002420 // Check if stream parameters have to change
2421 uint32_t currentWidth, currentHeight;
2422 res = mDevice->getStreamInfo(mCaptureStreamId,
2423 &currentWidth, &currentHeight, 0);
2424 if (res != OK) {
2425 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2426 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2427 return res;
2428 }
2429 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
2430 currentHeight != (uint32_t)mParameters.pictureHeight) {
2431 res = mDevice->deleteStream(mCaptureStreamId);
2432 if (res != OK) {
2433 ALOGE("%s: Camera %d: Unable to delete old output stream "
2434 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2435 strerror(-res), res);
2436 return res;
2437 }
2438 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002439 }
2440 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002441
2442 if (mCaptureStreamId == NO_STREAM) {
2443 // Create stream for HAL production
2444 res = mDevice->createStream(mCaptureWindow,
2445 mParameters.pictureWidth, mParameters.pictureHeight,
2446 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2447 &mCaptureStreamId);
2448 if (res != OK) {
2449 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2450 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2451 return res;
2452 }
2453
2454 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002455 return OK;
2456}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002457
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002458status_t Camera2Client::updateCaptureRequest() {
2459 ATRACE_CALL();
2460 status_t res;
2461 if (mCaptureRequest == NULL) {
2462 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2463 &mCaptureRequest);
2464 if (res != OK) {
2465 ALOGE("%s: Camera %d: Unable to create default still image request:"
2466 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2467 return res;
2468 }
2469 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002470
2471 res = updateRequestCommon(mCaptureRequest);
2472 if (res != OK) {
2473 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2474 "request: %s (%d)", __FUNCTION__, mCameraId,
2475 strerror(-res), res);
2476 return res;
2477 }
2478
2479 res = updateEntry(mCaptureRequest,
2480 ANDROID_JPEG_THUMBNAIL_SIZE,
2481 mParameters.jpegThumbSize, 2);
2482 if (res != OK) return res;
2483 res = updateEntry(mCaptureRequest,
2484 ANDROID_JPEG_THUMBNAIL_QUALITY,
2485 &mParameters.jpegThumbQuality, 1);
2486 if (res != OK) return res;
2487 res = updateEntry(mCaptureRequest,
2488 ANDROID_JPEG_QUALITY,
2489 &mParameters.jpegQuality, 1);
2490 if (res != OK) return res;
2491 res = updateEntry(mCaptureRequest,
2492 ANDROID_JPEG_ORIENTATION,
2493 &mParameters.jpegRotation, 1);
2494 if (res != OK) return res;
2495
2496 if (mParameters.gpsEnabled) {
2497 res = updateEntry(mCaptureRequest,
2498 ANDROID_JPEG_GPS_COORDINATES,
2499 mParameters.gpsCoordinates, 3);
2500 if (res != OK) return res;
2501 res = updateEntry(mCaptureRequest,
2502 ANDROID_JPEG_GPS_TIMESTAMP,
2503 &mParameters.gpsTimestamp, 1);
2504 if (res != OK) return res;
2505 res = updateEntry(mCaptureRequest,
2506 ANDROID_JPEG_GPS_PROCESSING_METHOD,
2507 mParameters.gpsProcessingMethod.string(),
2508 mParameters.gpsProcessingMethod.size());
2509 if (res != OK) return res;
2510 } else {
2511 res = deleteEntry(mCaptureRequest,
2512 ANDROID_JPEG_GPS_COORDINATES);
2513 if (res != OK) return res;
2514 res = deleteEntry(mCaptureRequest,
2515 ANDROID_JPEG_GPS_TIMESTAMP);
2516 if (res != OK) return res;
2517 res = deleteEntry(mCaptureRequest,
2518 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2519 if (res != OK) return res;
2520 }
2521
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002522 return OK;
2523}
2524
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002525status_t Camera2Client::updateRecordingRequest() {
2526 ATRACE_CALL();
2527 status_t res;
2528 if (mRecordingRequest == NULL) {
2529 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2530 &mRecordingRequest);
2531 if (res != OK) {
2532 ALOGE("%s: Camera %d: Unable to create default recording request:"
2533 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2534 return res;
2535 }
2536 }
2537
2538 res = updateRequestCommon(mRecordingRequest);
2539 if (res != OK) {
2540 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2541 "request: %s (%d)", __FUNCTION__, mCameraId,
2542 strerror(-res), res);
2543 return res;
2544 }
2545
2546 return OK;
2547}
2548
2549status_t Camera2Client::updateRecordingStream() {
2550 status_t res;
2551
2552 if (mRecordingConsumer == 0) {
2553 // Create CPU buffer queue endpoint
2554 mRecordingConsumer = new CpuConsumer(1);
2555 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2556 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2557 mRecordingWindow = new SurfaceTextureClient(
2558 mRecordingConsumer->getProducerInterface());
2559 // Allocate memory later, since we don't know buffer size until receipt
2560 }
2561
2562 if (mRecordingStreamId != NO_STREAM) {
2563 // Check if stream parameters have to change
2564 uint32_t currentWidth, currentHeight;
2565 res = mDevice->getStreamInfo(mRecordingStreamId,
2566 &currentWidth, &currentHeight, 0);
2567 if (res != OK) {
2568 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2569 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2570 return res;
2571 }
2572 if (currentWidth != (uint32_t)mParameters.videoWidth ||
2573 currentHeight != (uint32_t)mParameters.videoHeight) {
2574 // TODO: Should wait to be sure previous recording has finished
2575 res = mDevice->deleteStream(mRecordingStreamId);
2576 if (res != OK) {
2577 ALOGE("%s: Camera %d: Unable to delete old output stream "
2578 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2579 strerror(-res), res);
2580 return res;
2581 }
2582 mRecordingStreamId = NO_STREAM;
2583 }
2584 }
2585
2586 if (mRecordingStreamId == NO_STREAM) {
2587 res = mDevice->createStream(mRecordingWindow,
2588 mParameters.videoWidth, mParameters.videoHeight,
2589 kRecordingFormat, 0, &mRecordingStreamId);
2590 if (res != OK) {
2591 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2592 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2593 return res;
2594 }
2595 }
2596
2597 return OK;
2598}
2599
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002600status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
2601 ATRACE_CALL();
2602 status_t res;
2603 res = updateEntry(request,
2604 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
2605 if (res != OK) return res;
2606
2607 uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
2608 ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
2609 res = updateEntry(request,
2610 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2611 if (res != OK) return res;
2612 res = updateEntry(request,
2613 ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
2614 if (res != OK) return res;
2615 res = updateEntry(request,
2616 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2617 &mParameters.antibandingMode, 1);
2618 if (res != OK) return res;
2619
2620 uint8_t controlMode =
2621 (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2622 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2623 res = updateEntry(request,
2624 ANDROID_CONTROL_MODE, &controlMode, 1);
2625 if (res != OK) return res;
2626 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2627 res = updateEntry(request,
2628 ANDROID_CONTROL_SCENE_MODE,
2629 &mParameters.sceneMode, 1);
2630 if (res != OK) return res;
2631 }
2632
2633 uint8_t flashMode = ANDROID_FLASH_OFF;
2634 uint8_t aeMode;
2635 switch (mParameters.flashMode) {
2636 case Parameters::FLASH_MODE_OFF:
2637 aeMode = ANDROID_CONTROL_AE_ON; break;
2638 case Parameters::FLASH_MODE_AUTO:
2639 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2640 case Parameters::FLASH_MODE_ON:
2641 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2642 case Parameters::FLASH_MODE_TORCH:
2643 aeMode = ANDROID_CONTROL_AE_ON;
2644 flashMode = ANDROID_FLASH_TORCH;
2645 break;
2646 case Parameters::FLASH_MODE_RED_EYE:
2647 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2648 default:
2649 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2650 mCameraId, mParameters.flashMode);
2651 return BAD_VALUE;
2652 }
2653 if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2654
2655 res = updateEntry(request,
2656 ANDROID_FLASH_MODE, &flashMode, 1);
2657 if (res != OK) return res;
2658 res = updateEntry(request,
2659 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2660 if (res != OK) return res;
2661
2662 float focusDistance = 0; // infinity focus in diopters
2663 uint8_t focusMode;
2664 switch (mParameters.focusMode) {
2665 case Parameters::FOCUS_MODE_AUTO:
2666 case Parameters::FOCUS_MODE_MACRO:
2667 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2668 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2669 case Parameters::FOCUS_MODE_EDOF:
2670 focusMode = mParameters.focusMode;
2671 break;
2672 case Parameters::FOCUS_MODE_INFINITY:
2673 case Parameters::FOCUS_MODE_FIXED:
2674 focusMode = ANDROID_CONTROL_AF_OFF;
2675 break;
2676 default:
2677 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2678 mCameraId, mParameters.focusMode);
2679 return BAD_VALUE;
2680 }
2681 res = updateEntry(request,
2682 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2683 if (res != OK) return res;
2684 res = updateEntry(request,
2685 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2686 if (res != OK) return res;
2687
2688 size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
2689 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2690 for (size_t i = 0; i < focusingAreasSize; i += 5) {
2691 focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
2692 focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
2693 focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
2694 focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
2695 focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
2696 }
2697 res = updateEntry(request,
2698 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2699 if (res != OK) return res;
2700 delete[] focusingAreas;
2701
2702 res = updateEntry(request,
2703 ANDROID_CONTROL_AE_EXP_COMPENSATION,
2704 &mParameters.exposureCompensation, 1);
2705 if (res != OK) return res;
2706
2707 size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
2708 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2709 for (size_t i = 0; i < meteringAreasSize; i += 5) {
2710 meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
2711 meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
2712 meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
2713 meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
2714 meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
2715 }
2716 res = updateEntry(request,
2717 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2718 if (res != OK) return res;
2719
2720 res = updateEntry(request,
2721 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2722 if (res != OK) return res;
2723 delete[] meteringAreas;
2724
2725 // Need to convert zoom index into a crop rectangle. The rectangle is
2726 // chosen to maximize its area on the sensor
2727
2728 camera_metadata_entry_t maxDigitalZoom =
2729 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2730 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2731 (NUM_ZOOM_STEPS-1);
2732 float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
2733
2734 camera_metadata_entry_t activePixelArraySize =
2735 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2736 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2737 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2738 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2739 if (mParameters.previewWidth >= mParameters.previewHeight) {
2740 zoomWidth = arrayWidth / zoomRatio;
2741 zoomHeight = zoomWidth *
2742 mParameters.previewHeight / mParameters.previewWidth;
2743 } else {
2744 zoomHeight = arrayHeight / zoomRatio;
2745 zoomWidth = zoomHeight *
2746 mParameters.previewWidth / mParameters.previewHeight;
2747 }
2748 zoomLeft = (arrayWidth - zoomWidth) / 2;
2749 zoomTop = (arrayHeight - zoomHeight) / 2;
2750
2751 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2752 res = updateEntry(request,
2753 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2754 if (res != OK) return res;
2755
2756 // TODO: Decide how to map recordingHint, or whether just to ignore it
2757
2758 uint8_t vstabMode = mParameters.videoStabilization ?
2759 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2760 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2761 res = updateEntry(request,
2762 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2763 &vstabMode, 1);
2764 if (res != OK) return res;
2765
2766 return OK;
2767}
2768
2769status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2770 uint32_t tag, const void *data, size_t data_count) {
2771 camera_metadata_entry_t entry;
2772 status_t res;
2773 res = find_camera_metadata_entry(buffer, tag, &entry);
2774 if (res == NAME_NOT_FOUND) {
2775 res = add_camera_metadata_entry(buffer,
2776 tag, data, data_count);
2777 } else if (res == OK) {
2778 res = update_camera_metadata_entry(buffer,
2779 entry.index, data, data_count, NULL);
2780 }
2781
2782 if (res != OK) {
2783 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2784 __FUNCTION__, get_camera_metadata_section_name(tag),
2785 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2786 }
2787 return res;
2788}
2789
2790status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2791 camera_metadata_entry_t entry;
2792 status_t res;
2793 res = find_camera_metadata_entry(buffer, tag, &entry);
2794 if (res == NAME_NOT_FOUND) {
2795 return OK;
2796 } else if (res != OK) {
2797 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2798 __FUNCTION__,
2799 get_camera_metadata_section_name(tag),
2800 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2801 return res;
2802 }
2803 res = delete_camera_metadata_entry(buffer, entry.index);
2804 if (res != OK) {
2805 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2806 __FUNCTION__,
2807 get_camera_metadata_section_name(tag),
2808 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2809 }
2810 return res;
2811}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002812int Camera2Client::formatStringToEnum(const char *format) {
2813 return
2814 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2815 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2816 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2817 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2818 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2819 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2820 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2821 HAL_PIXEL_FORMAT_YV12 : // YV12
2822 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2823 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2824 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2825 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2826 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2827 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2828 -1;
2829}
2830
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002831const char* Camera2Client::formatEnumToString(int format) {
2832 const char *fmt;
2833 switch(format) {
2834 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2835 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2836 break;
2837 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2838 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2839 break;
2840 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2841 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2842 break;
2843 case HAL_PIXEL_FORMAT_YV12: // YV12
2844 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2845 break;
2846 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2847 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2848 break;
2849 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2850 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2851 break;
2852 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2853 ALOGW("Raw sensor preview format requested.");
2854 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2855 break;
2856 default:
2857 ALOGE("%s: Unknown preview format: %x",
2858 __FUNCTION__, format);
2859 fmt = NULL;
2860 break;
2861 }
2862 return fmt;
2863}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002864
2865int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2866 return
2867 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2868 ANDROID_CONTROL_AWB_AUTO :
2869 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2870 ANDROID_CONTROL_AWB_INCANDESCENT :
2871 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2872 ANDROID_CONTROL_AWB_FLUORESCENT :
2873 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2874 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2875 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2876 ANDROID_CONTROL_AWB_DAYLIGHT :
2877 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2878 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2879 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2880 ANDROID_CONTROL_AWB_TWILIGHT :
2881 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2882 ANDROID_CONTROL_AWB_SHADE :
2883 -1;
2884}
2885
2886int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2887 return
2888 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2889 ANDROID_CONTROL_EFFECT_OFF :
2890 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2891 ANDROID_CONTROL_EFFECT_MONO :
2892 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2893 ANDROID_CONTROL_EFFECT_NEGATIVE :
2894 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2895 ANDROID_CONTROL_EFFECT_SOLARIZE :
2896 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2897 ANDROID_CONTROL_EFFECT_SEPIA :
2898 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2899 ANDROID_CONTROL_EFFECT_POSTERIZE :
2900 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2901 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2902 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2903 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2904 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2905 ANDROID_CONTROL_EFFECT_AQUA :
2906 -1;
2907}
2908
2909int Camera2Client::abModeStringToEnum(const char *abMode) {
2910 return
2911 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2912 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2913 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2914 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2915 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2916 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2917 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2918 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2919 -1;
2920}
2921
2922int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2923 return
2924 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2925 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2926 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2927 ANDROID_CONTROL_SCENE_MODE_ACTION :
2928 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2929 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2930 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2931 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2932 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2933 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2934 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2935 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2936 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2937 ANDROID_CONTROL_SCENE_MODE_THEATRE :
2938 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2939 ANDROID_CONTROL_SCENE_MODE_BEACH :
2940 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2941 ANDROID_CONTROL_SCENE_MODE_SNOW :
2942 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2943 ANDROID_CONTROL_SCENE_MODE_SUNSET :
2944 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2945 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2946 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2947 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2948 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2949 ANDROID_CONTROL_SCENE_MODE_SPORTS :
2950 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2951 ANDROID_CONTROL_SCENE_MODE_PARTY :
2952 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2953 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2954 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2955 ANDROID_CONTROL_SCENE_MODE_BARCODE:
2956 -1;
2957}
2958
2959Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
2960 const char *flashMode) {
2961 return
2962 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2963 Parameters::FLASH_MODE_OFF :
2964 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2965 Parameters::FLASH_MODE_AUTO :
2966 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2967 Parameters::FLASH_MODE_ON :
2968 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2969 Parameters::FLASH_MODE_RED_EYE :
2970 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2971 Parameters::FLASH_MODE_TORCH :
2972 Parameters::FLASH_MODE_INVALID;
2973}
2974
2975Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
2976 const char *focusMode) {
2977 return
2978 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2979 Parameters::FOCUS_MODE_AUTO :
2980 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2981 Parameters::FOCUS_MODE_INFINITY :
2982 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2983 Parameters::FOCUS_MODE_MACRO :
2984 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2985 Parameters::FOCUS_MODE_FIXED :
2986 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2987 Parameters::FOCUS_MODE_EDOF :
2988 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
2989 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
2990 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
2991 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
2992 Parameters::FOCUS_MODE_INVALID;
2993}
2994
2995status_t Camera2Client::parseAreas(const char *areasCStr,
2996 Vector<Parameters::Area> *areas) {
2997 static const size_t NUM_FIELDS = 5;
2998 areas->clear();
2999 if (areasCStr == NULL) {
3000 // If no key exists, use default (0,0,0,0,0)
3001 areas->push();
3002 return OK;
3003 }
3004 String8 areasStr(areasCStr);
3005 ssize_t areaStart = areasStr.find("(", 0) + 1;
3006 while (areaStart != 0) {
3007 const char* area = areasStr.string() + areaStart;
3008 char *numEnd;
3009 int vals[NUM_FIELDS];
3010 for (size_t i = 0; i < NUM_FIELDS; i++) {
3011 errno = 0;
3012 vals[i] = strtol(area, &numEnd, 10);
3013 if (errno || numEnd == area) return BAD_VALUE;
3014 area = numEnd + 1;
3015 }
3016 areas->push(Parameters::Area(
3017 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3018 areaStart = areasStr.find("(", areaStart) + 1;
3019 }
3020 return OK;
3021}
3022
3023status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3024 size_t maxRegions) {
3025 // Definition of valid area can be found in
3026 // include/camera/CameraParameters.h
3027 if (areas.size() == 0) return BAD_VALUE;
3028 if (areas.size() == 1) {
3029 if (areas[0].left == 0 &&
3030 areas[0].top == 0 &&
3031 areas[0].right == 0 &&
3032 areas[0].bottom == 0 &&
3033 areas[0].weight == 0) {
3034 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3035 return OK;
3036 }
3037 }
3038 if (areas.size() > maxRegions) {
3039 ALOGE("%s: Too many areas requested: %d",
3040 __FUNCTION__, areas.size());
3041 return BAD_VALUE;
3042 }
3043
3044 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3045 a != areas.end(); a++) {
3046 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3047 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3048 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3049 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3050 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3051 if (a->left >= a->right) return BAD_VALUE;
3052 if (a->top >= a->bottom) return BAD_VALUE;
3053 }
3054 return OK;
3055}
3056
3057bool Camera2Client::boolFromString(const char *boolStr) {
3058 return !boolStr ? false :
3059 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3060 false;
3061}
3062
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003063int Camera2Client::degToTransform(int degrees, bool mirror) {
3064 if (!mirror) {
3065 if (degrees == 0) return 0;
3066 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3067 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3068 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3069 } else { // Do mirror (horizontal flip)
3070 if (degrees == 0) { // FLIP_H and ROT_0
3071 return HAL_TRANSFORM_FLIP_H;
3072 } else if (degrees == 90) { // FLIP_H and ROT_90
3073 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3074 } else if (degrees == 180) { // FLIP_H and ROT_180
3075 return HAL_TRANSFORM_FLIP_V;
3076 } else if (degrees == 270) { // FLIP_H and ROT_270
3077 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3078 }
3079 }
3080 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3081 return -1;
3082}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003083
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003084} // namespace android