blob: a115ef46c4463a5c1922ab9957b1fcb856078588 [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 Talvala9e4c3db2012-07-20 11:07:52 -070070 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070071 status_t res;
72
73 res = mDevice->initialize(module);
74 if (res != OK) {
75 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
76 __FUNCTION__, mCameraId, strerror(-res), res);
77 return NO_INIT;
78 }
79
80 res = buildDefaultParameters();
81 if (res != OK) {
82 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
83 __FUNCTION__, mCameraId, strerror(-res), res);
84 return NO_INIT;
85 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070086
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070087 if (gLogLevel >= 1) {
88 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
89 mCameraId);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070090 ALOGD("%s", mParamsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070091 }
92
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070093 mState = STOPPED;
94
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070095 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070096}
97
98Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070099 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700100 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
101
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700102 mDestructionStarted = true;
103
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700105
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700106}
107
108status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700109 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700110 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700111 mCameraId,
112 getCameraClient()->asBinder().get(),
113 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700114 result.append(" State: ");
115#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
116
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700117 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700118
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700119 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700120 result.appendFormat(" Preview size: %d x %d\n",
121 mParameters.previewWidth, mParameters.previewHeight);
122 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700123 mParameters.previewFpsRange[0], mParameters.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700124 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
125 mParameters.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700126 result.appendFormat(" Preview transform: %x\n",
127 mParameters.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700128 result.appendFormat(" Picture size: %d x %d\n",
129 mParameters.pictureWidth, mParameters.pictureHeight);
130 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700131 mParameters.jpegThumbSize[0], mParameters.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700132 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
133 mParameters.jpegQuality, mParameters.jpegThumbQuality);
134 result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
135 result.appendFormat(" GPS tags %s\n",
136 mParameters.gpsEnabled ? "enabled" : "disabled");
137 if (mParameters.gpsEnabled) {
138 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700139 mParameters.gpsCoordinates[0], mParameters.gpsCoordinates[1],
140 mParameters.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700141 result.appendFormat(" GPS timestamp: %lld\n",
142 mParameters.gpsTimestamp);
143 result.appendFormat(" GPS processing method: %s\n",
144 mParameters.gpsProcessingMethod.string());
145 }
146
147 result.append(" White balance mode: ");
148 switch (mParameters.wbMode) {
149 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
150 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
151 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
152 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
156 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
157 default: result.append("UNKNOWN\n");
158 }
159
160 result.append(" Effect mode: ");
161 switch (mParameters.effectMode) {
162 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
163 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
164 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
171 default: result.append("UNKNOWN\n");
172 }
173
174 result.append(" Antibanding mode: ");
175 switch (mParameters.antibandingMode) {
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
180 default: result.append("UNKNOWN\n");
181 }
182
183 result.append(" Scene mode: ");
184 switch (mParameters.sceneMode) {
185 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
186 result.append("AUTO\n"); break;
187 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
202 default: result.append("UNKNOWN\n");
203 }
204
205 result.append(" Flash mode: ");
206 switch (mParameters.flashMode) {
207 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
208 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
209 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
210 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
212 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
213 default: result.append("UNKNOWN\n");
214 }
215
216 result.append(" Focus mode: ");
217 switch (mParameters.focusMode) {
218 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
219 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
220 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
221 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
225 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
226 default: result.append("UNKNOWN\n");
227 }
228
229 result.append(" Focusing areas:\n");
230 for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
231 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
232 mParameters.focusingAreas[i].left,
233 mParameters.focusingAreas[i].top,
234 mParameters.focusingAreas[i].right,
235 mParameters.focusingAreas[i].bottom,
236 mParameters.focusingAreas[i].weight);
237 }
238
239 result.appendFormat(" Exposure compensation index: %d\n",
240 mParameters.exposureCompensation);
241
242 result.appendFormat(" AE lock %s, AWB lock %s\n",
243 mParameters.autoExposureLock ? "enabled" : "disabled",
244 mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
245
246 result.appendFormat(" Metering areas:\n");
247 for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
248 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
249 mParameters.meteringAreas[i].left,
250 mParameters.meteringAreas[i].top,
251 mParameters.meteringAreas[i].right,
252 mParameters.meteringAreas[i].bottom,
253 mParameters.meteringAreas[i].weight);
254 }
255
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700256 result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
257 result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 mParameters.videoHeight);
259
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700260 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700261 mParameters.recordingHint ? "set" : "not set");
262
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700263 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700264 mParameters.videoStabilization ? "enabled" : "disabled");
265
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700266 result.append(" Current streams:\n");
267 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
268 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
269
270 result.append(" Current requests:\n");
271 if (mPreviewRequest != NULL) {
272 result.append(" Preview request:\n");
273 write(fd, result.string(), result.size());
274 dump_camera_metadata(mPreviewRequest, fd, 2);
275 } else {
276 result.append(" Preview request: undefined\n");
277 write(fd, result.string(), result.size());
278 }
279
280 if (mCaptureRequest != NULL) {
281 result = " Capture request:\n";
282 write(fd, result.string(), result.size());
283 dump_camera_metadata(mCaptureRequest, fd, 2);
284 } else {
285 result = " Capture request: undefined\n";
286 write(fd, result.string(), result.size());
287 }
288
289 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700290 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700291
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292 status_t res = mDevice->dump(fd, args);
293 if (res != OK) {
294 result = String8::format(" Error dumping device: %s (%d)",
295 strerror(-res), res);
296 write(fd, result.string(), result.size());
297 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700298
299#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700300 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700301}
302
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700303const char* Camera2Client::getStateName(State state) {
304#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
305 switch(state) {
306 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
307 CASE_ENUM_TO_CHAR(STOPPED)
308 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
309 CASE_ENUM_TO_CHAR(PREVIEW)
310 CASE_ENUM_TO_CHAR(RECORD)
311 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
312 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
313 default:
314 return "Unknown state!";
315 break;
316 }
317#undef CASE_ENUM_TO_CHAR
318}
319
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700320// ICamera interface
321
322void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700323 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700324 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700325 Mutex::Autolock icl(mICameraLock);
326
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700327 if (mDevice == 0) return;
328
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700329 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700330
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700331 mDevice->waitUntilDrained();
332
333 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700334 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700335 mPreviewStreamId = NO_STREAM;
336 }
337
338 if (mCaptureStreamId != NO_STREAM) {
339 mDevice->deleteStream(mCaptureStreamId);
340 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700341 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700342
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700343 if (mRecordingStreamId != NO_STREAM) {
344 mDevice->deleteStream(mRecordingStreamId);
345 mRecordingStreamId = NO_STREAM;
346 }
347
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700348 CameraService::Client::disconnect();
349}
350
351status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700352 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700353 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700354 Mutex::Autolock icl(mICameraLock);
355
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700356 if (mClientPid != 0 && getCallingPid() != mClientPid) {
357 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
358 "current locked to pid %d", __FUNCTION__,
359 mCameraId, getCallingPid(), mClientPid);
360 return BAD_VALUE;
361 }
362
363 mClientPid = getCallingPid();
364 mCameraClient = client;
365
366 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700367}
368
369status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700370 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700371 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700372 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700373 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
374 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700375
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700376 if (mClientPid == 0) {
377 mClientPid = getCallingPid();
378 return OK;
379 }
380
381 if (mClientPid != getCallingPid()) {
382 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
383 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
384 return EBUSY;
385 }
386
387 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700388}
389
390status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700391 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700392 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700393 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700394 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
395 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700396
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700397 // TODO: Check for uninterruptable conditions
398
399 if (mClientPid == getCallingPid()) {
400 mClientPid = 0;
401 mCameraClient.clear();
402 return OK;
403 }
404
405 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
406 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
407 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700408}
409
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700410status_t Camera2Client::setPreviewDisplay(
411 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700412 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700413 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700414 Mutex::Autolock icl(mICameraLock);
415
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700416 sp<IBinder> binder;
417 sp<ANativeWindow> window;
418 if (surface != 0) {
419 binder = surface->asBinder();
420 window = surface;
421 }
422
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700423 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700424}
425
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700426status_t Camera2Client::setPreviewTexture(
427 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700428 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700429 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700430 Mutex::Autolock icl(mICameraLock);
431
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700432 sp<IBinder> binder;
433 sp<ANativeWindow> window;
434 if (surfaceTexture != 0) {
435 binder = surfaceTexture->asBinder();
436 window = new SurfaceTextureClient(surfaceTexture);
437 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700438 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700439}
440
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700441status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700442 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700443 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700444 status_t res;
445
446 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700447 ALOGV("%s: Camera %d: New window is same as old window",
448 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700449 return NO_ERROR;
450 }
451
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700452 switch (mState) {
453 case NOT_INITIALIZED:
454 case RECORD:
455 case STILL_CAPTURE:
456 case VIDEO_SNAPSHOT:
457 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
458 __FUNCTION__, mCameraId, getStateName(mState));
459 return INVALID_OPERATION;
460 case STOPPED:
461 case WAITING_FOR_PREVIEW_WINDOW:
462 // OK
463 break;
464 case PREVIEW:
465 // Already running preview - need to stop and create a new stream
466 // TODO: Optimize this so that we don't wait for old stream to drain
467 // before spinning up new stream
468 mDevice->setStreamingRequest(NULL);
469 mState = WAITING_FOR_PREVIEW_WINDOW;
470 break;
471 }
472
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700473 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700474 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700475 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700476 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
477 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700478 return res;
479 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700480 res = mDevice->deleteStream(mPreviewStreamId);
481 if (res != OK) {
482 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
483 __FUNCTION__, strerror(-res), res);
484 return res;
485 }
486 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700487 }
488
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700489 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700490 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700491
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700492 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700493 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700494 }
495
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700496 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700497}
498
499void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700500 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700501 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700502}
503
504status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700505 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700506 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700507 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700508 return startPreviewLocked();
509}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700510
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700511status_t Camera2Client::startPreviewLocked() {
512 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700513 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700514 if (mState >= PREVIEW) {
515 ALOGE("%s: Can't start preview in state %s",
516 __FUNCTION__, getStateName(mState));
517 return INVALID_OPERATION;
518 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700519
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700520 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700521 mState = WAITING_FOR_PREVIEW_WINDOW;
522 return OK;
523 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700524 mState = STOPPED;
525
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700526 Mutex::Autolock pl(mParamsLock);
527
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700528 res = updatePreviewStream();
529 if (res != OK) {
530 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
531 __FUNCTION__, mCameraId, strerror(-res), res);
532 return res;
533 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700534
535 if (mPreviewRequest == NULL) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700536 res = updatePreviewRequest();
537 if (res != OK) {
538 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
539 __FUNCTION__, mCameraId, strerror(-res), res);
540 return res;
541 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700542 }
543
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700544 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700545 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700546 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700547 if (res != OK) {
548 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
549 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700550 return res;
551 }
552 res = sort_camera_metadata(mPreviewRequest);
553 if (res != OK) {
554 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
555 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700556 return res;
557 }
558
559 res = mDevice->setStreamingRequest(mPreviewRequest);
560 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700561 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
562 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700563 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700564 return res;
565 }
566 mState = PREVIEW;
567
568 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700569}
570
571void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700572 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700573 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700574 Mutex::Autolock icl(mICameraLock);
575 stopPreviewLocked();
576}
577
578void Camera2Client::stopPreviewLocked() {
579 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700580 switch (mState) {
581 case NOT_INITIALIZED:
582 ALOGE("%s: Camera %d: Call before initialized",
583 __FUNCTION__, mCameraId);
584 break;
585 case STOPPED:
586 break;
587 case STILL_CAPTURE:
588 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
589 __FUNCTION__, mCameraId);
590 break;
591 case RECORD:
592 // TODO: Handle record stop here
593 case PREVIEW:
594 mDevice->setStreamingRequest(NULL);
595 case WAITING_FOR_PREVIEW_WINDOW:
596 mState = STOPPED;
597 break;
598 default:
599 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
600 mState);
601 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700602}
603
604bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700605 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700606 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700607 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700608}
609
610status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700611 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700612 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700613 return BAD_VALUE;
614}
615
616status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700617 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700618 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700619 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700620 status_t res;
621 switch (mState) {
622 case STOPPED:
623 res = startPreviewLocked();
624 if (res != OK) return res;
625 break;
626 case PREVIEW:
627 // Ready to go
628 break;
629 case RECORD:
630 case VIDEO_SNAPSHOT:
631 // OK to call this when recording is already on
632 return OK;
633 break;
634 default:
635 ALOGE("%s: Camera %d: Can't start recording in state %s",
636 __FUNCTION__, mCameraId, getStateName(mState));
637 return INVALID_OPERATION;
638 };
639
640 Mutex::Autolock pl(mParamsLock);
641
642 res = updateRecordingStream();
643 if (res != OK) {
644 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
645 __FUNCTION__, mCameraId, strerror(-res), res);
646 return res;
647 }
648
649 if (mRecordingRequest == NULL) {
650 res = updateRecordingRequest();
651 if (res != OK) {
652 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
653 __FUNCTION__, mCameraId, strerror(-res), res);
654 return res;
655 }
656 }
657
658 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
659 res = updateEntry(mRecordingRequest,
660 ANDROID_REQUEST_OUTPUT_STREAMS,
661 outputStreams, 2);
662 if (res != OK) {
663 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
664 __FUNCTION__, mCameraId, strerror(-res), res);
665 return res;
666 }
667 res = sort_camera_metadata(mRecordingRequest);
668 if (res != OK) {
669 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
670 __FUNCTION__, mCameraId, strerror(-res), res);
671 return res;
672 }
673
674 res = mDevice->setStreamingRequest(mRecordingRequest);
675 if (res != OK) {
676 ALOGE("%s: Camera %d: Unable to set recording request to start "
677 "recording: %s (%d)", __FUNCTION__, mCameraId,
678 strerror(-res), res);
679 return res;
680 }
681 mState = RECORD;
682
683 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700684}
685
686void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700687 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700688 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700689 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700690 status_t res;
691 switch (mState) {
692 case RECORD:
693 // OK to stop
694 break;
695 case STOPPED:
696 case PREVIEW:
697 case STILL_CAPTURE:
698 case VIDEO_SNAPSHOT:
699 default:
700 ALOGE("%s: Camera %d: Can't stop recording in state %s",
701 __FUNCTION__, mCameraId, getStateName(mState));
702 return;
703 };
704
705 // Back to preview. Since record can only be reached through preview,
706 // all preview stream setup should be up to date.
707 res = mDevice->setStreamingRequest(mPreviewRequest);
708 if (res != OK) {
709 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
710 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
711 return;
712 }
713
714 // TODO: Should recording heap be freed? Can't do it yet since requests
715 // could still be in flight.
716
717 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700718}
719
720bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700721 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700722 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700723 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700724}
725
726void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700727 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700728 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700729 // Make sure this is for the current heap
730 ssize_t offset;
731 size_t size;
732 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
733 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
734 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
735 "(got %x, expected %x)", __FUNCTION__, mCameraId,
736 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
737 return;
738 }
739 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700740}
741
742status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700743 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700744 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700745 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700746}
747
748status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700749 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700750 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700751 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700752}
753
754status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700755 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700756 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700757 status_t res;
758
759 switch (mState) {
760 case NOT_INITIALIZED:
761 case STOPPED:
762 case WAITING_FOR_PREVIEW_WINDOW:
763 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
764 __FUNCTION__, mCameraId);
765 return INVALID_OPERATION;
766 case PREVIEW:
767 case RECORD:
768 // Good to go for takePicture
769 break;
770 case STILL_CAPTURE:
771 case VIDEO_SNAPSHOT:
772 ALOGE("%s: Camera %d: Already taking a picture",
773 __FUNCTION__, mCameraId);
774 return INVALID_OPERATION;
775 }
776
777 Mutex::Autolock pl(mParamsLock);
778
779 res = updateCaptureStream();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700780 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700781 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
782 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700783 return res;
784 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700785
786 if (mCaptureRequest == NULL) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700787 res = updateCaptureRequest();
788 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700789 ALOGE("%s: Camera %d: Can't create still image capture request: "
790 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700791 return res;
792 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700793 }
794
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700795 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700796 if (mState == PREVIEW) {
797 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
798 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
799 &streamIds, 2);
800 } else if (mState == RECORD) {
801 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
802 mCaptureStreamId };
803 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
804 &streamIds, 3);
805 }
806
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700807 if (res != OK) {
808 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
809 "%s (%d)",
810 __FUNCTION__, mCameraId, strerror(-res), res);
811 return res;
812 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700813 res = sort_camera_metadata(mCaptureRequest);
814 if (res != OK) {
815 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
816 __FUNCTION__, mCameraId, strerror(-res), res);
817 return res;
818 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700819
820 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
821 if (captureCopy == NULL) {
822 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
823 __FUNCTION__, mCameraId);
824 return NO_MEMORY;
825 }
826
827 if (mState == PREVIEW) {
828 res = mDevice->setStreamingRequest(NULL);
829 if (res != OK) {
830 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
831 "%s (%d)",
832 __FUNCTION__, mCameraId, strerror(-res), res);
833 return res;
834 }
835 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700836 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700837 res = mDevice->capture(captureCopy);
838 if (res != OK) {
839 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
840 "%s (%d)",
841 __FUNCTION__, mCameraId, strerror(-res), res);
842 return res;
843 }
844
845 switch (mState) {
846 case PREVIEW:
847 mState = STILL_CAPTURE;
848 break;
849 case RECORD:
850 mState = VIDEO_SNAPSHOT;
851 break;
852 default:
853 ALOGE("%s: Camera %d: Unknown state for still capture!",
854 __FUNCTION__, mCameraId);
855 return INVALID_OPERATION;
856 }
857
858 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700859}
860
861status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700862 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700863 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700864 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700865 Mutex::Autolock pl(mParamsLock);
866 status_t res;
867
868 CameraParameters newParams(params);
869
870 // TODO: Currently ignoring any changes to supposedly read-only
871 // parameters such as supported preview sizes, etc. Should probably
872 // produce an error if they're changed.
873
874 /** Extract and verify new parameters */
875
876 size_t i;
877
878 // PREVIEW_SIZE
879 int previewWidth, previewHeight;
880 newParams.getPreviewSize(&previewWidth, &previewHeight);
881
882 if (previewWidth != mParameters.previewWidth ||
883 previewHeight != mParameters.previewHeight) {
884 if (mState >= PREVIEW) {
885 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700886 "is active! (Currently %d x %d, requested %d x %d",
887 __FUNCTION__,
888 mParameters.previewWidth, mParameters.previewHeight,
889 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700890 return BAD_VALUE;
891 }
892 camera_metadata_entry_t availablePreviewSizes =
893 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
894 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
895 if (availablePreviewSizes.data.i32[i] == previewWidth &&
896 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
897 }
898 if (i == availablePreviewSizes.count) {
899 ALOGE("%s: Requested preview size %d x %d is not supported",
900 __FUNCTION__, previewWidth, previewHeight);
901 return BAD_VALUE;
902 }
903 }
904
905 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700906 int previewFpsRange[2];
907 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700908 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700909 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
910 if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
911 previewFpsRange[1] != mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700912 fpsRangeChanged = true;
913 camera_metadata_entry_t availablePreviewFpsRanges =
914 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
915 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
916 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700917 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700918 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700919 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700920 break;
921 }
922 }
923 if (i == availablePreviewFpsRanges.count) {
924 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700925 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700926 return BAD_VALUE;
927 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700928 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700929 }
930
931 // PREVIEW_FORMAT
932 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
933 if (previewFormat != mParameters.previewFormat) {
934 if (mState >= PREVIEW) {
935 ALOGE("%s: Preview format cannot be updated when preview "
936 "is active!", __FUNCTION__);
937 return BAD_VALUE;
938 }
939 camera_metadata_entry_t availableFormats =
940 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
941 for (i = 0; i < availableFormats.count; i++) {
942 if (availableFormats.data.i32[i] == previewFormat) break;
943 }
944 if (i == availableFormats.count) {
945 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
946 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
947 return BAD_VALUE;
948 }
949 }
950
951 // PREVIEW_FRAME_RATE
952 // Deprecated, only use if the preview fps range is unchanged this time.
953 // The single-value FPS is the same as the minimum of the range.
954 if (!fpsRangeChanged) {
955 previewFps = newParams.getPreviewFrameRate();
956 if (previewFps != mParameters.previewFps) {
957 camera_metadata_entry_t availableFrameRates =
958 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
959 for (i = 0; i < availableFrameRates.count; i+=2) {
960 if (availableFrameRates.data.i32[i] == previewFps) break;
961 }
962 if (i == availableFrameRates.count) {
963 ALOGE("%s: Requested preview frame rate %d is not supported",
964 __FUNCTION__, previewFps);
965 return BAD_VALUE;
966 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700967 previewFpsRange[0] = availableFrameRates.data.i32[i];
968 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700969 }
970 }
971
972 // PICTURE_SIZE
973 int pictureWidth, pictureHeight;
974 newParams.getPictureSize(&pictureWidth, &pictureHeight);
975 if (pictureWidth == mParameters.pictureWidth ||
976 pictureHeight == mParameters.pictureHeight) {
977 camera_metadata_entry_t availablePictureSizes =
978 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
979 for (i = 0; i < availablePictureSizes.count; i+=2) {
980 if (availablePictureSizes.data.i32[i] == pictureWidth &&
981 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
982 }
983 if (i == availablePictureSizes.count) {
984 ALOGE("%s: Requested picture size %d x %d is not supported",
985 __FUNCTION__, pictureWidth, pictureHeight);
986 return BAD_VALUE;
987 }
988 }
989
990 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700991 int jpegThumbSize[2];
992 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700993 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700994 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700995 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700996 if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
997 jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700998 camera_metadata_entry_t availableJpegThumbSizes =
999 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1000 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001001 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1002 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001003 break;
1004 }
1005 }
1006 if (i == availableJpegThumbSizes.count) {
1007 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001008 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001009 return BAD_VALUE;
1010 }
1011 }
1012
1013 // JPEG_THUMBNAIL_QUALITY
1014 int jpegThumbQuality =
1015 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1016 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1017 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1018 __FUNCTION__, jpegThumbQuality);
1019 return BAD_VALUE;
1020 }
1021
1022 // JPEG_QUALITY
1023 int jpegQuality =
1024 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1025 if (jpegQuality < 0 || jpegQuality > 100) {
1026 ALOGE("%s: Requested JPEG quality %d is not supported",
1027 __FUNCTION__, jpegQuality);
1028 return BAD_VALUE;
1029 }
1030
1031 // ROTATION
1032 int jpegRotation =
1033 newParams.getInt(CameraParameters::KEY_ROTATION);
1034 if (jpegRotation != 0 &&
1035 jpegRotation != 90 &&
1036 jpegRotation != 180 &&
1037 jpegRotation != 270) {
1038 ALOGE("%s: Requested picture rotation angle %d is not supported",
1039 __FUNCTION__, jpegRotation);
1040 return BAD_VALUE;
1041 }
1042
1043 // GPS
1044 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001045 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001046 int64_t gpsTimestamp = 0;
1047 String8 gpsProcessingMethod;
1048 const char *gpsLatStr =
1049 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1050 if (gpsLatStr != NULL) {
1051 const char *gpsLongStr =
1052 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1053 const char *gpsAltitudeStr =
1054 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1055 const char *gpsTimeStr =
1056 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1057 const char *gpsProcMethodStr =
1058 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1059 if (gpsLongStr == NULL ||
1060 gpsAltitudeStr == NULL ||
1061 gpsTimeStr == NULL ||
1062 gpsProcMethodStr == NULL) {
1063 ALOGE("%s: Incomplete set of GPS parameters provided",
1064 __FUNCTION__);
1065 return BAD_VALUE;
1066 }
1067 char *endPtr;
1068 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001069 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001070 if (errno || endPtr == gpsLatStr) {
1071 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1072 return BAD_VALUE;
1073 }
1074 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001075 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001076 if (errno || endPtr == gpsLongStr) {
1077 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1078 return BAD_VALUE;
1079 }
1080 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001081 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001082 if (errno || endPtr == gpsAltitudeStr) {
1083 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1084 gpsAltitudeStr);
1085 return BAD_VALUE;
1086 }
1087 errno = 0;
1088 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1089 if (errno || endPtr == gpsTimeStr) {
1090 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1091 return BAD_VALUE;
1092 }
1093 gpsProcessingMethod = gpsProcMethodStr;
1094
1095 gpsEnabled = true;
1096 }
1097
1098 // WHITE_BALANCE
1099 int wbMode = wbModeStringToEnum(
1100 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1101 if (wbMode != mParameters.wbMode) {
1102 camera_metadata_entry_t availableWbModes =
1103 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1104 for (i = 0; i < availableWbModes.count; i++) {
1105 if (wbMode == availableWbModes.data.u8[i]) break;
1106 }
1107 if (i == availableWbModes.count) {
1108 ALOGE("%s: Requested white balance mode %s is not supported",
1109 __FUNCTION__,
1110 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1111 return BAD_VALUE;
1112 }
1113 }
1114
1115 // EFFECT
1116 int effectMode = effectModeStringToEnum(
1117 newParams.get(CameraParameters::KEY_EFFECT) );
1118 if (effectMode != mParameters.effectMode) {
1119 camera_metadata_entry_t availableEffectModes =
1120 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1121 for (i = 0; i < availableEffectModes.count; i++) {
1122 if (effectMode == availableEffectModes.data.u8[i]) break;
1123 }
1124 if (i == availableEffectModes.count) {
1125 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1126 __FUNCTION__,
1127 newParams.get(CameraParameters::KEY_EFFECT) );
1128 return BAD_VALUE;
1129 }
1130 }
1131
1132 // ANTIBANDING
1133 int antibandingMode = abModeStringToEnum(
1134 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1135 if (antibandingMode != mParameters.antibandingMode) {
1136 camera_metadata_entry_t availableAbModes =
1137 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1138 for (i = 0; i < availableAbModes.count; i++) {
1139 if (antibandingMode == availableAbModes.data.u8[i]) break;
1140 }
1141 if (i == availableAbModes.count) {
1142 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1143 __FUNCTION__,
1144 newParams.get(CameraParameters::KEY_ANTIBANDING));
1145 return BAD_VALUE;
1146 }
1147 }
1148
1149 // SCENE_MODE
1150 int sceneMode = sceneModeStringToEnum(
1151 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1152 if (sceneMode != mParameters.sceneMode) {
1153 camera_metadata_entry_t availableSceneModes =
1154 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1155 for (i = 0; i < availableSceneModes.count; i++) {
1156 if (sceneMode == availableSceneModes.data.u8[i]) break;
1157 }
1158 if (i == availableSceneModes.count) {
1159 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1160 __FUNCTION__,
1161 newParams.get(CameraParameters::KEY_SCENE_MODE));
1162 return BAD_VALUE;
1163 }
1164 }
1165
1166 // FLASH_MODE
1167 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1168 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1169 if (flashMode != mParameters.flashMode) {
1170 camera_metadata_entry_t flashAvailable =
1171 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1172 if (!flashAvailable.data.u8[0] &&
1173 flashMode != Parameters::FLASH_MODE_OFF) {
1174 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1175 "No flash on device", __FUNCTION__,
1176 newParams.get(CameraParameters::KEY_FLASH_MODE));
1177 return BAD_VALUE;
1178 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1179 camera_metadata_entry_t availableAeModes =
1180 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1181 for (i = 0; i < availableAeModes.count; i++) {
1182 if (flashMode == availableAeModes.data.u8[i]) break;
1183 }
1184 if (i == availableAeModes.count) {
1185 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1186 __FUNCTION__,
1187 newParams.get(CameraParameters::KEY_FLASH_MODE));
1188 return BAD_VALUE;
1189 }
1190 } else if (flashMode == -1) {
1191 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1192 __FUNCTION__,
1193 newParams.get(CameraParameters::KEY_FLASH_MODE));
1194 return BAD_VALUE;
1195 }
1196 }
1197
1198 // FOCUS_MODE
1199 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1200 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1201 if (focusMode != mParameters.focusMode) {
1202 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1203 camera_metadata_entry_t minFocusDistance =
1204 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1205 if (minFocusDistance.data.f[0] == 0) {
1206 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1207 "fixed focus lens",
1208 __FUNCTION__,
1209 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1210 return BAD_VALUE;
1211 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1212 camera_metadata_entry_t availableFocusModes =
1213 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1214 for (i = 0; i < availableFocusModes.count; i++) {
1215 if (focusMode == availableFocusModes.data.u8[i]) break;
1216 }
1217 if (i == availableFocusModes.count) {
1218 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1219 __FUNCTION__,
1220 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1221 return BAD_VALUE;
1222 }
1223 }
1224 }
1225 }
1226
1227 // FOCUS_AREAS
1228 Vector<Parameters::Area> focusingAreas;
1229 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1230 &focusingAreas);
1231 size_t max3aRegions =
1232 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1233 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1234 if (res != OK) {
1235 ALOGE("%s: Requested focus areas are malformed: %s",
1236 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1237 return BAD_VALUE;
1238 }
1239
1240 // EXPOSURE_COMPENSATION
1241 int exposureCompensation =
1242 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1243 camera_metadata_entry_t exposureCompensationRange =
1244 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1245 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1246 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1247 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1248 __FUNCTION__, exposureCompensation);
1249 return BAD_VALUE;
1250 }
1251
1252 // AUTO_EXPOSURE_LOCK (always supported)
1253 bool autoExposureLock = boolFromString(
1254 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1255
1256 // AUTO_WHITEBALANCE_LOCK (always supported)
1257 bool autoWhiteBalanceLock = boolFromString(
1258 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1259
1260 // METERING_AREAS
1261 Vector<Parameters::Area> meteringAreas;
1262 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1263 &meteringAreas);
1264 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1265 if (res != OK) {
1266 ALOGE("%s: Requested metering areas are malformed: %s",
1267 __FUNCTION__,
1268 newParams.get(CameraParameters::KEY_METERING_AREAS));
1269 return BAD_VALUE;
1270 }
1271
1272 // ZOOM
1273 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1274 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1275 ALOGE("%s: Requested zoom level %d is not supported",
1276 __FUNCTION__, zoom);
1277 return BAD_VALUE;
1278 }
1279
1280 // VIDEO_SIZE
1281 int videoWidth, videoHeight;
1282 newParams.getVideoSize(&videoWidth, &videoHeight);
1283 if (videoWidth != mParameters.videoWidth ||
1284 videoHeight != mParameters.videoHeight) {
1285 if (mState == RECORD) {
1286 ALOGE("%s: Video size cannot be updated when recording is active!",
1287 __FUNCTION__);
1288 return BAD_VALUE;
1289 }
1290 camera_metadata_entry_t availableVideoSizes =
1291 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1292 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1293 if (availableVideoSizes.data.i32[i] == videoWidth &&
1294 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1295 }
1296 if (i == availableVideoSizes.count) {
1297 ALOGE("%s: Requested video size %d x %d is not supported",
1298 __FUNCTION__, videoWidth, videoHeight);
1299 return BAD_VALUE;
1300 }
1301 }
1302
1303 // RECORDING_HINT (always supported)
1304 bool recordingHint = boolFromString(
1305 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1306
1307 // VIDEO_STABILIZATION
1308 bool videoStabilization = boolFromString(
1309 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1310 camera_metadata_entry_t availableVideoStabilizationModes =
1311 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1312 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1313 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1314 }
1315
1316 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001317
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001318 mParameters.previewWidth = previewWidth;
1319 mParameters.previewHeight = previewHeight;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001320 mParameters.previewFpsRange[0] = previewFpsRange[0];
1321 mParameters.previewFpsRange[1] = previewFpsRange[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001322 mParameters.previewFps = previewFps;
1323 mParameters.previewFormat = previewFormat;
1324
1325 mParameters.pictureWidth = pictureWidth;
1326 mParameters.pictureHeight = pictureHeight;
1327
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001328 mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1329 mParameters.jpegThumbSize[1] = jpegThumbSize[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001330 mParameters.jpegQuality = jpegQuality;
1331 mParameters.jpegThumbQuality = jpegThumbQuality;
1332
1333 mParameters.gpsEnabled = gpsEnabled;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001334 mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1335 mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1336 mParameters.gpsCoordinates[2] = gpsCoordinates[2];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001337 mParameters.gpsTimestamp = gpsTimestamp;
1338 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1339
1340 mParameters.wbMode = wbMode;
1341 mParameters.effectMode = effectMode;
1342 mParameters.antibandingMode = antibandingMode;
1343 mParameters.sceneMode = sceneMode;
1344
1345 mParameters.flashMode = flashMode;
1346 mParameters.focusMode = focusMode;
1347
1348 mParameters.focusingAreas = focusingAreas;
1349 mParameters.exposureCompensation = exposureCompensation;
1350 mParameters.autoExposureLock = autoExposureLock;
1351 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1352 mParameters.meteringAreas = meteringAreas;
1353 mParameters.zoom = zoom;
1354
1355 mParameters.videoWidth = videoWidth;
1356 mParameters.videoHeight = videoHeight;
1357
1358 mParameters.recordingHint = recordingHint;
1359 mParameters.videoStabilization = videoStabilization;
1360
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001361 res = updatePreviewRequest();
1362 if (res != OK) {
1363 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1364 __FUNCTION__, mCameraId, strerror(-res), res);
1365 return res;
1366 }
1367 res = updateCaptureRequest();
1368 if (res != OK) {
1369 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1370 __FUNCTION__, mCameraId, strerror(-res), res);
1371 return res;
1372 }
1373
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001374 res = updateRecordingRequest();
1375 if (res != OK) {
1376 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1377 __FUNCTION__, mCameraId, strerror(-res), res);
1378 return res;
1379 }
1380
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001381 if (mState == PREVIEW) {
1382 res = mDevice->setStreamingRequest(mPreviewRequest);
1383 if (res != OK) {
1384 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1385 __FUNCTION__, mCameraId, strerror(-res), res);
1386 return res;
1387 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001388 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1389 res = mDevice->setStreamingRequest(mRecordingRequest);
1390 if (res != OK) {
1391 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1392 __FUNCTION__, mCameraId, strerror(-res), res);
1393 return res;
1394 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001395 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001396
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001397 mParamsFlattened = params;
1398
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001399 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001400}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001401
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001402String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001403 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001404 Mutex::Autolock icl(mICameraLock);
1405
1406 Mutex::Autolock pl(mParamsLock);
1407
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001408 // TODO: Deal with focus distances
1409 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001410}
1411
1412status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001413 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001414 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001415
1416 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1417 cmd, arg1, arg2);
1418
1419 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
1420 int transform = degToTransform(arg1,
1421 mCameraFacing == CAMERA_FACING_FRONT);
1422 if (transform == -1) {
1423 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1424 __FUNCTION__, mCameraId, arg1);
1425 return BAD_VALUE;
1426 }
1427 if (transform != mParameters.previewTransform &&
1428 mPreviewStreamId != NO_STREAM) {
1429 mDevice->setStreamTransform(mPreviewStreamId, transform);
1430 }
1431 mParameters.previewTransform = transform;
1432 return OK;
1433 }
1434
1435 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1436 mCameraId, cmd, arg1, arg2);
1437
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001438 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001439}
1440
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001441/** Device-related methods */
1442
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001443void Camera2Client::onCaptureAvailable() {
1444 ATRACE_CALL();
1445 status_t res;
1446 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001447 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1448
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001449 CpuConsumer::LockedBuffer imgBuffer;
1450 {
1451 Mutex::Autolock icl(mICameraLock);
1452
1453 // TODO: Signal errors here upstream
1454 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1455 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1456 __FUNCTION__, mCameraId);
1457 return;
1458 }
1459
1460 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1461 if (res != OK) {
1462 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1463 __FUNCTION__, mCameraId, strerror(-res), res);
1464 return;
1465 }
1466
1467 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1468 ALOGE("%s: Camera %d: Unexpected format for still image: "
1469 "%x, expected %x", __FUNCTION__, mCameraId,
1470 imgBuffer.format,
1471 HAL_PIXEL_FORMAT_BLOB);
1472 mCaptureConsumer->unlockBuffer(imgBuffer);
1473 return;
1474 }
1475
1476 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001477 void* captureMemory = mCaptureHeap->mHeap->getBase();
1478 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001479 memcpy(captureMemory, imgBuffer.data, size);
1480
1481 mCaptureConsumer->unlockBuffer(imgBuffer);
1482
1483 currentClient = mCameraClient;
1484 switch (mState) {
1485 case STILL_CAPTURE:
1486 mState = STOPPED;
1487 break;
1488 case VIDEO_SNAPSHOT:
1489 mState = RECORD;
1490 break;
1491 default:
1492 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1493 mCameraId, mState);
1494 break;
1495 }
1496 }
1497 // Call outside mICameraLock to allow re-entrancy from notification
1498 if (currentClient != 0) {
1499 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001500 mCaptureHeap->mBuffers[0], NULL);
1501 }
1502}
1503
1504void Camera2Client::onRecordingFrameAvailable() {
1505 ATRACE_CALL();
1506 status_t res;
1507 sp<ICameraClient> currentClient;
1508 size_t heapIdx = 0;
1509 nsecs_t timestamp;
1510 {
1511 Mutex::Autolock icl(mICameraLock);
1512 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001513 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001514 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001515 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1516 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001517 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001518 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001519 }
1520
1521 CpuConsumer::LockedBuffer imgBuffer;
1522 res = mRecordingConsumer->lockNextBuffer(&imgBuffer);
1523 if (res != OK) {
1524 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1525 __FUNCTION__, mCameraId, strerror(-res), res);
1526 return;
1527 }
1528
1529 if (imgBuffer.format != (int)kRecordingFormat) {
1530 ALOGE("%s: Camera %d: Unexpected recording format: %x",
1531 __FUNCTION__, mCameraId, imgBuffer.format);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001532 discardData = true;
1533 }
1534
1535 if (discardData) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001536 mRecordingConsumer->unlockBuffer(imgBuffer);
1537 return;
1538 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001539
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001540 size_t bufferSize = imgBuffer.width * imgBuffer.height * 3 / 2;
1541
1542 if (mRecordingHeap == 0 ||
1543 bufferSize >
1544 mRecordingHeap->mHeap->getSize() / kRecordingHeapCount) {
1545 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1546 "size %d bytes", __FUNCTION__, mCameraId,
1547 kRecordingHeapCount, bufferSize);
1548 if (mRecordingHeap != 0) {
1549 ALOGV("%s: Camera %d: Previous heap has size %d "
1550 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1551 mRecordingHeap->mHeap->getSize(),
1552 bufferSize * kRecordingHeapCount);
1553 }
1554 // Need to allocate memory for heap
1555 mRecordingHeap.clear();
1556
1557 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1558 "Camera2Client::RecordingHeap");
1559 if (mRecordingHeap->mHeap->getSize() == 0) {
1560 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1561 __FUNCTION__, mCameraId);
1562 mRecordingConsumer->unlockBuffer(imgBuffer);
1563 return;
1564 }
1565 mRecordingHeapHead = 0;
1566 mRecordingHeapFree = kRecordingHeapCount;
1567 }
1568
1569 // TODO: Optimize this to avoid memcopy
1570 if ( mRecordingHeapFree == 0) {
1571 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1572 __FUNCTION__, mCameraId);
1573 mRecordingConsumer->unlockBuffer(imgBuffer);
1574 return;
1575 }
1576 heapIdx = mRecordingHeapHead;
1577 timestamp = imgBuffer.timestamp;
1578 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1579 mRecordingHeapFree--;
1580
1581 ALOGV("%s: Camera %d: Timestamp %lld",
1582 __FUNCTION__, mCameraId, timestamp);
1583
1584 ssize_t offset;
1585 size_t size;
1586 sp<IMemoryHeap> heap =
1587 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1588 &size);
1589
1590 memcpy((uint8_t*)heap->getBase() + offset, imgBuffer.data, size);
1591
1592 mRecordingConsumer->unlockBuffer(imgBuffer);
1593
1594 currentClient = mCameraClient;
1595 }
1596 // Call outside mICameraLock to allow re-entrancy from notification
1597 if (currentClient != 0) {
1598 currentClient->dataCallbackTimestamp(timestamp,
1599 CAMERA_MSG_VIDEO_FRAME,
1600 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001601 }
1602}
1603
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001604camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1605 size_t minCount, size_t maxCount) {
1606 status_t res;
1607 camera_metadata_entry_t entry;
1608 res = find_camera_metadata_entry(mDevice->info(),
1609 tag,
1610 &entry);
1611 if (CC_UNLIKELY( res != OK )) {
1612 const char* tagSection = get_camera_metadata_section_name(tag);
1613 if (tagSection == NULL) tagSection = "<unknown>";
1614 const char* tagName = get_camera_metadata_tag_name(tag);
1615 if (tagName == NULL) tagName = "<unknown>";
1616
1617 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1618 tagSection, tagName, tag, strerror(-res), res);
1619 entry.count = 0;
1620 entry.data.u8 = NULL;
1621 } else if (CC_UNLIKELY(
1622 (minCount != 0 && entry.count < minCount) ||
1623 (maxCount != 0 && entry.count > maxCount) ) ) {
1624 const char* tagSection = get_camera_metadata_section_name(tag);
1625 if (tagSection == NULL) tagSection = "<unknown>";
1626 const char* tagName = get_camera_metadata_tag_name(tag);
1627 if (tagName == NULL) tagName = "<unknown>";
1628 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1629 "Expected between %d and %d values, but got %d values",
1630 tagSection, tagName, tag, minCount, maxCount, entry.count);
1631 entry.count = 0;
1632 entry.data.u8 = NULL;
1633 }
1634
1635 return entry;
1636}
1637
1638/** Utility methods */
1639
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001640
1641status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001642 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001643 Mutex::Autolock pl(mParamsLock);
1644
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001645 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001646 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001647
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001648 camera_metadata_entry_t availableProcessedSizes =
1649 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1650 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001651
1652 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001653 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1654 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1655 mParameters.videoWidth = mParameters.previewWidth;
1656 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001657
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001658 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1659 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1660 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1661 String8::format("%dx%d",
1662 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001663 {
1664 String8 supportedPreviewSizes;
1665 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1666 if (i != 0) supportedPreviewSizes += ",";
1667 supportedPreviewSizes += String8::format("%dx%d",
1668 availableProcessedSizes.data.i32[i],
1669 availableProcessedSizes.data.i32[i+1]);
1670 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001671 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001672 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001673 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001674 supportedPreviewSizes);
1675 }
1676
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001677 camera_metadata_entry_t availableFpsRanges =
1678 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1679 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001680
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001681 mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1682 mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001683
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001684 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1685 String8::format("%d,%d",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001686 mParameters.previewFpsRange[0],
1687 mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001688
1689 {
1690 String8 supportedPreviewFpsRange;
1691 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1692 if (i != 0) supportedPreviewFpsRange += ",";
1693 supportedPreviewFpsRange += String8::format("(%d,%d)",
1694 availableFpsRanges.data.i32[i],
1695 availableFpsRanges.data.i32[i+1]);
1696 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001697 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001698 supportedPreviewFpsRange);
1699 }
1700
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001701 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1702 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1703 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001704
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001705 mParameters.previewTransform = degToTransform(0,
1706 mCameraFacing == CAMERA_FACING_FRONT);
1707
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001708 camera_metadata_entry_t availableFormats =
1709 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1710
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001711 {
1712 String8 supportedPreviewFormats;
1713 bool addComma = false;
1714 for (size_t i=0; i < availableFormats.count; i++) {
1715 if (addComma) supportedPreviewFormats += ",";
1716 addComma = true;
1717 switch (availableFormats.data.i32[i]) {
1718 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001719 supportedPreviewFormats +=
1720 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001721 break;
1722 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001723 supportedPreviewFormats +=
1724 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001725 break;
1726 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001727 supportedPreviewFormats +=
1728 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001729 break;
1730 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001731 supportedPreviewFormats +=
1732 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001733 break;
1734 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001735 supportedPreviewFormats +=
1736 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001737 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001738 case HAL_PIXEL_FORMAT_RGBA_8888:
1739 supportedPreviewFormats +=
1740 CameraParameters::PIXEL_FORMAT_RGBA8888;
1741 break;
1742 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001743 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001744 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001745 addComma = false;
1746 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001747
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001748 default:
1749 ALOGW("%s: Camera %d: Unknown preview format: %x",
1750 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1751 addComma = false;
1752 break;
1753 }
1754 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001755 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001756 supportedPreviewFormats);
1757 }
1758
1759 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1760 // still have to do something sane for them
1761
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001762 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001763 mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001764
1765 {
1766 String8 supportedPreviewFrameRates;
1767 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1768 if (i != 0) supportedPreviewFrameRates += ",";
1769 supportedPreviewFrameRates += String8::format("%d",
1770 availableFpsRanges.data.i32[i]);
1771 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001772 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001773 supportedPreviewFrameRates);
1774 }
1775
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001776 camera_metadata_entry_t availableJpegSizes =
1777 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1778 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001779
1780 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001781 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1782 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001783
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001784 params.setPictureSize(mParameters.pictureWidth,
1785 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001786
1787 {
1788 String8 supportedPictureSizes;
1789 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1790 if (i != 0) supportedPictureSizes += ",";
1791 supportedPictureSizes += String8::format("%dx%d",
1792 availableJpegSizes.data.i32[i],
1793 availableJpegSizes.data.i32[i+1]);
1794 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001795 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001796 supportedPictureSizes);
1797 }
1798
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001799 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1800 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1801 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001802
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001803 camera_metadata_entry_t availableJpegThumbnailSizes =
1804 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1805 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001806
1807 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001808 mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1809 mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001810
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001811 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001812 mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001813 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001814 mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001815
1816 {
1817 String8 supportedJpegThumbSizes;
1818 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1819 if (i != 0) supportedJpegThumbSizes += ",";
1820 supportedJpegThumbSizes += String8::format("%dx%d",
1821 availableJpegThumbnailSizes.data.i32[i],
1822 availableJpegThumbnailSizes.data.i32[i+1]);
1823 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001824 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001825 supportedJpegThumbSizes);
1826 }
1827
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001828 mParameters.jpegThumbQuality = 90;
1829 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1830 mParameters.jpegThumbQuality);
1831 mParameters.jpegQuality = 90;
1832 params.set(CameraParameters::KEY_JPEG_QUALITY,
1833 mParameters.jpegQuality);
1834 mParameters.jpegRotation = 0;
1835 params.set(CameraParameters::KEY_ROTATION,
1836 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001837
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001838 mParameters.gpsEnabled = false;
1839 mParameters.gpsProcessingMethod = "unknown";
1840 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001841
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001842 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1843 params.set(CameraParameters::KEY_WHITE_BALANCE,
1844 CameraParameters::WHITE_BALANCE_AUTO);
1845
1846 camera_metadata_entry_t availableWhiteBalanceModes =
1847 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001848 {
1849 String8 supportedWhiteBalance;
1850 bool addComma = false;
1851 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1852 if (addComma) supportedWhiteBalance += ",";
1853 addComma = true;
1854 switch (availableWhiteBalanceModes.data.u8[i]) {
1855 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001856 supportedWhiteBalance +=
1857 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001858 break;
1859 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001860 supportedWhiteBalance +=
1861 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001862 break;
1863 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001864 supportedWhiteBalance +=
1865 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001866 break;
1867 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001868 supportedWhiteBalance +=
1869 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001870 break;
1871 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001872 supportedWhiteBalance +=
1873 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001874 break;
1875 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001876 supportedWhiteBalance +=
1877 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001878 break;
1879 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001880 supportedWhiteBalance +=
1881 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001882 break;
1883 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001884 supportedWhiteBalance +=
1885 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001886 break;
1887 // Skipping values not mappable to v1 API
1888 case ANDROID_CONTROL_AWB_OFF:
1889 addComma = false;
1890 break;
1891 default:
1892 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1893 __FUNCTION__, mCameraId,
1894 availableWhiteBalanceModes.data.u8[i]);
1895 addComma = false;
1896 break;
1897 }
1898 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001899 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001900 supportedWhiteBalance);
1901 }
1902
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001903 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1904 params.set(CameraParameters::KEY_EFFECT,
1905 CameraParameters::EFFECT_NONE);
1906
1907 camera_metadata_entry_t availableEffects =
1908 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1909 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001910 {
1911 String8 supportedEffects;
1912 bool addComma = false;
1913 for (size_t i=0; i < availableEffects.count; i++) {
1914 if (addComma) supportedEffects += ",";
1915 addComma = true;
1916 switch (availableEffects.data.u8[i]) {
1917 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001918 supportedEffects +=
1919 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001920 break;
1921 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001922 supportedEffects +=
1923 CameraParameters::EFFECT_MONO;
1924 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001925 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001926 supportedEffects +=
1927 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001928 break;
1929 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001930 supportedEffects +=
1931 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001932 break;
1933 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001934 supportedEffects +=
1935 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001936 break;
1937 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001938 supportedEffects +=
1939 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001940 break;
1941 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001942 supportedEffects +=
1943 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001944 break;
1945 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001946 supportedEffects +=
1947 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001948 break;
1949 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001950 supportedEffects +=
1951 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001952 break;
1953 default:
1954 ALOGW("%s: Camera %d: Unknown effect value: %d",
1955 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1956 addComma = false;
1957 break;
1958 }
1959 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001960 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001961 }
1962
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001963 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1964 params.set(CameraParameters::KEY_ANTIBANDING,
1965 CameraParameters::ANTIBANDING_AUTO);
1966
1967 camera_metadata_entry_t availableAntibandingModes =
1968 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1969 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001970 {
1971 String8 supportedAntibanding;
1972 bool addComma = false;
1973 for (size_t i=0; i < availableAntibandingModes.count; i++) {
1974 if (addComma) supportedAntibanding += ",";
1975 addComma = true;
1976 switch (availableAntibandingModes.data.u8[i]) {
1977 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001978 supportedAntibanding +=
1979 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001980 break;
1981 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001982 supportedAntibanding +=
1983 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001984 break;
1985 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001986 supportedAntibanding +=
1987 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001988 break;
1989 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001990 supportedAntibanding +=
1991 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001992 break;
1993 default:
1994 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
1995 __FUNCTION__, mCameraId,
1996 availableAntibandingModes.data.u8[i]);
1997 addComma = false;
1998 break;
1999 }
2000 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002001 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002002 supportedAntibanding);
2003 }
2004
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002005 mParameters.sceneMode = ANDROID_CONTROL_OFF;
2006 params.set(CameraParameters::KEY_SCENE_MODE,
2007 CameraParameters::SCENE_MODE_AUTO);
2008
2009 camera_metadata_entry_t availableSceneModes =
2010 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2011 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002012 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002013 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002014 bool addComma = true;
2015 bool noSceneModes = false;
2016 for (size_t i=0; i < availableSceneModes.count; i++) {
2017 if (addComma) supportedSceneModes += ",";
2018 addComma = true;
2019 switch (availableSceneModes.data.u8[i]) {
2020 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2021 noSceneModes = true;
2022 break;
2023 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2024 // Not in old API
2025 addComma = false;
2026 break;
2027 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002028 supportedSceneModes +=
2029 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002030 break;
2031 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002032 supportedSceneModes +=
2033 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002034 break;
2035 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002036 supportedSceneModes +=
2037 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002038 break;
2039 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002040 supportedSceneModes +=
2041 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002042 break;
2043 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002044 supportedSceneModes +=
2045 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002046 break;
2047 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002048 supportedSceneModes +=
2049 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002050 break;
2051 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002052 supportedSceneModes +=
2053 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002054 break;
2055 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002056 supportedSceneModes +=
2057 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002058 break;
2059 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002060 supportedSceneModes +=
2061 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002062 break;
2063 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002064 supportedSceneModes +=
2065 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002066 break;
2067 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002068 supportedSceneModes +=
2069 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002070 break;
2071 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002072 supportedSceneModes +=
2073 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002074 break;
2075 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002076 supportedSceneModes +=
2077 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002078 break;
2079 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002080 supportedSceneModes +=
2081 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002082 break;
2083 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002084 supportedSceneModes +=
2085 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002086 break;
2087 default:
2088 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002089 __FUNCTION__, mCameraId,
2090 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002091 addComma = false;
2092 break;
2093 }
2094 }
2095 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002096 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002097 supportedSceneModes);
2098 }
2099 }
2100
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002101 camera_metadata_entry_t flashAvailable =
2102 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2103 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002104
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002105 camera_metadata_entry_t availableAeModes =
2106 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2107 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002108
2109 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002110 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2111 params.set(CameraParameters::KEY_FLASH_MODE,
2112 CameraParameters::FLASH_MODE_AUTO);
2113
2114 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2115 supportedFlashModes = supportedFlashModes +
2116 "," + CameraParameters::FLASH_MODE_AUTO +
2117 "," + CameraParameters::FLASH_MODE_ON +
2118 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002119 for (size_t i=0; i < availableAeModes.count; i++) {
2120 if (availableAeModes.data.u8[i] ==
2121 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002122 supportedFlashModes = supportedFlashModes + "," +
2123 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002124 break;
2125 }
2126 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002127 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002128 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002129 } else {
2130 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2131 params.set(CameraParameters::KEY_FLASH_MODE,
2132 CameraParameters::FLASH_MODE_OFF);
2133 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2134 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002135 }
2136
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002137 camera_metadata_entry_t minFocusDistance =
2138 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2139 if (!minFocusDistance.count) return NO_INIT;
2140
2141 camera_metadata_entry_t availableAfModes =
2142 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2143 if (!availableAfModes.count) return NO_INIT;
2144
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002145 if (minFocusDistance.data.f[0] == 0) {
2146 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002147 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2148 params.set(CameraParameters::KEY_FOCUS_MODE,
2149 CameraParameters::FOCUS_MODE_FIXED);
2150 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2151 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002152 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002153 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2154 params.set(CameraParameters::KEY_FOCUS_MODE,
2155 CameraParameters::FOCUS_MODE_AUTO);
2156 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2157 supportedFocusModes = supportedFocusModes + "," +
2158 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002160
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002161 for (size_t i=0; i < availableAfModes.count; i++) {
2162 if (addComma) supportedFocusModes += ",";
2163 addComma = true;
2164 switch (availableAfModes.data.u8[i]) {
2165 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002166 supportedFocusModes +=
2167 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002168 break;
2169 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002170 supportedFocusModes +=
2171 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002172 break;
2173 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002174 supportedFocusModes +=
2175 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002176 break;
2177 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002178 supportedFocusModes +=
2179 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002180 break;
2181 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002182 supportedFocusModes +=
2183 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002184 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002185 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002186 case ANDROID_CONTROL_AF_OFF:
2187 addComma = false;
2188 break;
2189 default:
2190 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2191 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2192 addComma = false;
2193 break;
2194 }
2195 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002196 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002197 supportedFocusModes);
2198 }
2199
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002200 camera_metadata_entry_t max3aRegions =
2201 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2202 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002203
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002204 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002205 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002206 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002207 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002208 mParameters.focusingAreas.clear();
2209 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002210
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002211 camera_metadata_entry_t availableFocalLengths =
2212 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2213 if (!availableFocalLengths.count) return NO_INIT;
2214
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002215 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002216 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002217
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002218 camera_metadata_entry_t sensorSize =
2219 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2220 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002221
2222 // The fields of view here assume infinity focus, maximum wide angle
2223 float horizFov = 180 / M_PI *
2224 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2225 float vertFov = 180 / M_PI *
2226 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002227 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2228 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002229
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002230 mParameters.exposureCompensation = 0;
2231 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2232 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002233
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002234 camera_metadata_entry_t exposureCompensationRange =
2235 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2236 if (!exposureCompensationRange.count) return NO_INIT;
2237
2238 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002239 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002240 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002241 exposureCompensationRange.data.i32[0]);
2242
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002243 camera_metadata_entry_t exposureCompensationStep =
2244 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2245 if (!exposureCompensationStep.count) return NO_INIT;
2246
2247 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002248 exposureCompensationStep.data.r[0].numerator /
2249 exposureCompensationStep.data.r[0].denominator);
2250
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002251 mParameters.autoExposureLock = false;
2252 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2253 CameraParameters::FALSE);
2254 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2255 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002256
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002257 mParameters.autoWhiteBalanceLock = false;
2258 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2259 CameraParameters::FALSE);
2260 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2261 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002262
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002263 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2264 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002265 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002266 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002267 "(0,0,0,0,0)");
2268
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002269 mParameters.zoom = 0;
2270 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
2271 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002272
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002273 camera_metadata_entry_t maxDigitalZoom =
2274 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2275 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002276
2277 {
2278 String8 zoomRatios;
2279 float zoom = 1.f;
2280 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002281 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002282 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002283 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002284 if (addComma) zoomRatios += ",";
2285 addComma = true;
2286 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2287 zoom += zoomIncrement;
2288 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002289 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002290 }
2291
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002292 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2293 CameraParameters::TRUE);
2294 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2295 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002296
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002297 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002298 "Infinity,Infinity,Infinity");
2299
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002300 camera_metadata_entry_t maxFacesDetected =
2301 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2302 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002303 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002304 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305 0);
2306
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002307 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002308 formatEnumToString(kRecordingFormat));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002309
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002310 params.set(CameraParameters::KEY_RECORDING_HINT,
2311 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002312
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002313 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2314 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002316 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2317 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002318
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002319 camera_metadata_entry_t availableVideoStabilizationModes =
2320 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2321 if (!availableVideoStabilizationModes.count) return NO_INIT;
2322
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002323 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002324 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2325 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002326 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002327 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2328 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002329 }
2330
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002331 mParamsFlattened = params.flatten();
2332
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002333 return OK;
2334}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002335
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002336status_t Camera2Client::updatePreviewStream() {
2337 ATRACE_CALL();
2338 status_t res;
2339 if (mPreviewStreamId != NO_STREAM) {
2340 // Check if stream parameters have to change
2341 uint32_t currentWidth, currentHeight;
2342 res = mDevice->getStreamInfo(mPreviewStreamId,
2343 &currentWidth, &currentHeight, 0);
2344 if (res != OK) {
2345 ALOGE("%s: Camera %d: Error querying preview stream info: "
2346 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2347 return res;
2348 }
2349 if (currentWidth != (uint32_t)mParameters.previewWidth ||
2350 currentHeight != (uint32_t)mParameters.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002351 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2352 __FUNCTION__, mCameraId, currentWidth, currentHeight,
2353 mParameters.previewWidth, mParameters.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002354 res = mDevice->waitUntilDrained();
2355 if (res != OK) {
2356 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2357 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2358 return res;
2359 }
2360 res = mDevice->deleteStream(mPreviewStreamId);
2361 if (res != OK) {
2362 ALOGE("%s: Camera %d: Unable to delete old output stream "
2363 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2364 strerror(-res), res);
2365 return res;
2366 }
2367 mPreviewStreamId = NO_STREAM;
2368 }
2369 }
2370
2371 if (mPreviewStreamId == NO_STREAM) {
2372 res = mDevice->createStream(mPreviewWindow,
2373 mParameters.previewWidth, mParameters.previewHeight,
2374 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2375 &mPreviewStreamId);
2376 if (res != OK) {
2377 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2378 __FUNCTION__, mCameraId, strerror(-res), res);
2379 return res;
2380 }
2381 }
2382
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002383 res = mDevice->setStreamTransform(mPreviewStreamId,
2384 mParameters.previewTransform);
2385 if (res != OK) {
2386 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2387 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2388 return res;
2389 }
2390
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002391 return OK;
2392}
2393
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002394status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002395 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002396 status_t res;
2397 if (mPreviewRequest == NULL) {
2398 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2399 &mPreviewRequest);
2400 if (res != OK) {
2401 ALOGE("%s: Camera %d: Unable to create default preview request: "
2402 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2403 return res;
2404 }
2405 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002406
2407 res = updateRequestCommon(mPreviewRequest);
2408 if (res != OK) {
2409 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2410 "request: %s (%d)", __FUNCTION__, mCameraId,
2411 strerror(-res), res);
2412 return res;
2413 }
2414
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002415 return OK;
2416}
2417
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002418status_t Camera2Client::updateCaptureStream() {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002419 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002420 status_t res;
2421 // Find out buffer size for JPEG
2422 camera_metadata_entry_t maxJpegSize =
2423 staticInfo(ANDROID_JPEG_MAX_SIZE);
2424 if (maxJpegSize.count == 0) {
2425 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2426 __FUNCTION__, mCameraId);
2427 return INVALID_OPERATION;
2428 }
2429
2430 if (mCaptureConsumer == 0) {
2431 // Create CPU buffer queue endpoint
2432 mCaptureConsumer = new CpuConsumer(1);
2433 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2434 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2435 mCaptureWindow = new SurfaceTextureClient(
2436 mCaptureConsumer->getProducerInterface());
2437 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002438 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2439 "Camera2Client::CaptureHeap");
2440 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002441 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2442 __FUNCTION__, mCameraId);
2443 return NO_MEMORY;
2444 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002445 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002446
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002447 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002448 // Check if stream parameters have to change
2449 uint32_t currentWidth, currentHeight;
2450 res = mDevice->getStreamInfo(mCaptureStreamId,
2451 &currentWidth, &currentHeight, 0);
2452 if (res != OK) {
2453 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2454 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2455 return res;
2456 }
2457 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
2458 currentHeight != (uint32_t)mParameters.pictureHeight) {
2459 res = mDevice->deleteStream(mCaptureStreamId);
2460 if (res != OK) {
2461 ALOGE("%s: Camera %d: Unable to delete old output stream "
2462 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2463 strerror(-res), res);
2464 return res;
2465 }
2466 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002467 }
2468 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002469
2470 if (mCaptureStreamId == NO_STREAM) {
2471 // Create stream for HAL production
2472 res = mDevice->createStream(mCaptureWindow,
2473 mParameters.pictureWidth, mParameters.pictureHeight,
2474 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2475 &mCaptureStreamId);
2476 if (res != OK) {
2477 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2478 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2479 return res;
2480 }
2481
2482 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002483 return OK;
2484}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002485
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002486status_t Camera2Client::updateCaptureRequest() {
2487 ATRACE_CALL();
2488 status_t res;
2489 if (mCaptureRequest == NULL) {
2490 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2491 &mCaptureRequest);
2492 if (res != OK) {
2493 ALOGE("%s: Camera %d: Unable to create default still image request:"
2494 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2495 return res;
2496 }
2497 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002498
2499 res = updateRequestCommon(mCaptureRequest);
2500 if (res != OK) {
2501 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2502 "request: %s (%d)", __FUNCTION__, mCameraId,
2503 strerror(-res), res);
2504 return res;
2505 }
2506
2507 res = updateEntry(mCaptureRequest,
2508 ANDROID_JPEG_THUMBNAIL_SIZE,
2509 mParameters.jpegThumbSize, 2);
2510 if (res != OK) return res;
2511 res = updateEntry(mCaptureRequest,
2512 ANDROID_JPEG_THUMBNAIL_QUALITY,
2513 &mParameters.jpegThumbQuality, 1);
2514 if (res != OK) return res;
2515 res = updateEntry(mCaptureRequest,
2516 ANDROID_JPEG_QUALITY,
2517 &mParameters.jpegQuality, 1);
2518 if (res != OK) return res;
2519 res = updateEntry(mCaptureRequest,
2520 ANDROID_JPEG_ORIENTATION,
2521 &mParameters.jpegRotation, 1);
2522 if (res != OK) return res;
2523
2524 if (mParameters.gpsEnabled) {
2525 res = updateEntry(mCaptureRequest,
2526 ANDROID_JPEG_GPS_COORDINATES,
2527 mParameters.gpsCoordinates, 3);
2528 if (res != OK) return res;
2529 res = updateEntry(mCaptureRequest,
2530 ANDROID_JPEG_GPS_TIMESTAMP,
2531 &mParameters.gpsTimestamp, 1);
2532 if (res != OK) return res;
2533 res = updateEntry(mCaptureRequest,
2534 ANDROID_JPEG_GPS_PROCESSING_METHOD,
2535 mParameters.gpsProcessingMethod.string(),
2536 mParameters.gpsProcessingMethod.size());
2537 if (res != OK) return res;
2538 } else {
2539 res = deleteEntry(mCaptureRequest,
2540 ANDROID_JPEG_GPS_COORDINATES);
2541 if (res != OK) return res;
2542 res = deleteEntry(mCaptureRequest,
2543 ANDROID_JPEG_GPS_TIMESTAMP);
2544 if (res != OK) return res;
2545 res = deleteEntry(mCaptureRequest,
2546 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2547 if (res != OK) return res;
2548 }
2549
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002550 return OK;
2551}
2552
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002553status_t Camera2Client::updateRecordingRequest() {
2554 ATRACE_CALL();
2555 status_t res;
2556 if (mRecordingRequest == NULL) {
2557 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2558 &mRecordingRequest);
2559 if (res != OK) {
2560 ALOGE("%s: Camera %d: Unable to create default recording request:"
2561 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2562 return res;
2563 }
2564 }
2565
2566 res = updateRequestCommon(mRecordingRequest);
2567 if (res != OK) {
2568 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2569 "request: %s (%d)", __FUNCTION__, mCameraId,
2570 strerror(-res), res);
2571 return res;
2572 }
2573
2574 return OK;
2575}
2576
2577status_t Camera2Client::updateRecordingStream() {
2578 status_t res;
2579
2580 if (mRecordingConsumer == 0) {
2581 // Create CPU buffer queue endpoint
2582 mRecordingConsumer = new CpuConsumer(1);
2583 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2584 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2585 mRecordingWindow = new SurfaceTextureClient(
2586 mRecordingConsumer->getProducerInterface());
2587 // Allocate memory later, since we don't know buffer size until receipt
2588 }
2589
2590 if (mRecordingStreamId != NO_STREAM) {
2591 // Check if stream parameters have to change
2592 uint32_t currentWidth, currentHeight;
2593 res = mDevice->getStreamInfo(mRecordingStreamId,
2594 &currentWidth, &currentHeight, 0);
2595 if (res != OK) {
2596 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2597 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2598 return res;
2599 }
2600 if (currentWidth != (uint32_t)mParameters.videoWidth ||
2601 currentHeight != (uint32_t)mParameters.videoHeight) {
2602 // TODO: Should wait to be sure previous recording has finished
2603 res = mDevice->deleteStream(mRecordingStreamId);
2604 if (res != OK) {
2605 ALOGE("%s: Camera %d: Unable to delete old output stream "
2606 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2607 strerror(-res), res);
2608 return res;
2609 }
2610 mRecordingStreamId = NO_STREAM;
2611 }
2612 }
2613
2614 if (mRecordingStreamId == NO_STREAM) {
2615 res = mDevice->createStream(mRecordingWindow,
2616 mParameters.videoWidth, mParameters.videoHeight,
2617 kRecordingFormat, 0, &mRecordingStreamId);
2618 if (res != OK) {
2619 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2620 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2621 return res;
2622 }
2623 }
2624
2625 return OK;
2626}
2627
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002628status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
2629 ATRACE_CALL();
2630 status_t res;
2631 res = updateEntry(request,
2632 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
2633 if (res != OK) return res;
2634
2635 uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
2636 ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
2637 res = updateEntry(request,
2638 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2639 if (res != OK) return res;
2640 res = updateEntry(request,
2641 ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
2642 if (res != OK) return res;
2643 res = updateEntry(request,
2644 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2645 &mParameters.antibandingMode, 1);
2646 if (res != OK) return res;
2647
2648 uint8_t controlMode =
2649 (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2650 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2651 res = updateEntry(request,
2652 ANDROID_CONTROL_MODE, &controlMode, 1);
2653 if (res != OK) return res;
2654 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2655 res = updateEntry(request,
2656 ANDROID_CONTROL_SCENE_MODE,
2657 &mParameters.sceneMode, 1);
2658 if (res != OK) return res;
2659 }
2660
2661 uint8_t flashMode = ANDROID_FLASH_OFF;
2662 uint8_t aeMode;
2663 switch (mParameters.flashMode) {
2664 case Parameters::FLASH_MODE_OFF:
2665 aeMode = ANDROID_CONTROL_AE_ON; break;
2666 case Parameters::FLASH_MODE_AUTO:
2667 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2668 case Parameters::FLASH_MODE_ON:
2669 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2670 case Parameters::FLASH_MODE_TORCH:
2671 aeMode = ANDROID_CONTROL_AE_ON;
2672 flashMode = ANDROID_FLASH_TORCH;
2673 break;
2674 case Parameters::FLASH_MODE_RED_EYE:
2675 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2676 default:
2677 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2678 mCameraId, mParameters.flashMode);
2679 return BAD_VALUE;
2680 }
2681 if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2682
2683 res = updateEntry(request,
2684 ANDROID_FLASH_MODE, &flashMode, 1);
2685 if (res != OK) return res;
2686 res = updateEntry(request,
2687 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2688 if (res != OK) return res;
2689
2690 float focusDistance = 0; // infinity focus in diopters
2691 uint8_t focusMode;
2692 switch (mParameters.focusMode) {
2693 case Parameters::FOCUS_MODE_AUTO:
2694 case Parameters::FOCUS_MODE_MACRO:
2695 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2696 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2697 case Parameters::FOCUS_MODE_EDOF:
2698 focusMode = mParameters.focusMode;
2699 break;
2700 case Parameters::FOCUS_MODE_INFINITY:
2701 case Parameters::FOCUS_MODE_FIXED:
2702 focusMode = ANDROID_CONTROL_AF_OFF;
2703 break;
2704 default:
2705 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2706 mCameraId, mParameters.focusMode);
2707 return BAD_VALUE;
2708 }
2709 res = updateEntry(request,
2710 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2711 if (res != OK) return res;
2712 res = updateEntry(request,
2713 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2714 if (res != OK) return res;
2715
2716 size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
2717 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2718 for (size_t i = 0; i < focusingAreasSize; i += 5) {
2719 focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
2720 focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
2721 focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
2722 focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
2723 focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
2724 }
2725 res = updateEntry(request,
2726 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2727 if (res != OK) return res;
2728 delete[] focusingAreas;
2729
2730 res = updateEntry(request,
2731 ANDROID_CONTROL_AE_EXP_COMPENSATION,
2732 &mParameters.exposureCompensation, 1);
2733 if (res != OK) return res;
2734
2735 size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
2736 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2737 for (size_t i = 0; i < meteringAreasSize; i += 5) {
2738 meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
2739 meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
2740 meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
2741 meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
2742 meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
2743 }
2744 res = updateEntry(request,
2745 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2746 if (res != OK) return res;
2747
2748 res = updateEntry(request,
2749 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2750 if (res != OK) return res;
2751 delete[] meteringAreas;
2752
2753 // Need to convert zoom index into a crop rectangle. The rectangle is
2754 // chosen to maximize its area on the sensor
2755
2756 camera_metadata_entry_t maxDigitalZoom =
2757 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2758 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2759 (NUM_ZOOM_STEPS-1);
2760 float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
2761
2762 camera_metadata_entry_t activePixelArraySize =
2763 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2764 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2765 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2766 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2767 if (mParameters.previewWidth >= mParameters.previewHeight) {
2768 zoomWidth = arrayWidth / zoomRatio;
2769 zoomHeight = zoomWidth *
2770 mParameters.previewHeight / mParameters.previewWidth;
2771 } else {
2772 zoomHeight = arrayHeight / zoomRatio;
2773 zoomWidth = zoomHeight *
2774 mParameters.previewWidth / mParameters.previewHeight;
2775 }
2776 zoomLeft = (arrayWidth - zoomWidth) / 2;
2777 zoomTop = (arrayHeight - zoomHeight) / 2;
2778
2779 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2780 res = updateEntry(request,
2781 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2782 if (res != OK) return res;
2783
2784 // TODO: Decide how to map recordingHint, or whether just to ignore it
2785
2786 uint8_t vstabMode = mParameters.videoStabilization ?
2787 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2788 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2789 res = updateEntry(request,
2790 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2791 &vstabMode, 1);
2792 if (res != OK) return res;
2793
2794 return OK;
2795}
2796
2797status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2798 uint32_t tag, const void *data, size_t data_count) {
2799 camera_metadata_entry_t entry;
2800 status_t res;
2801 res = find_camera_metadata_entry(buffer, tag, &entry);
2802 if (res == NAME_NOT_FOUND) {
2803 res = add_camera_metadata_entry(buffer,
2804 tag, data, data_count);
2805 } else if (res == OK) {
2806 res = update_camera_metadata_entry(buffer,
2807 entry.index, data, data_count, NULL);
2808 }
2809
2810 if (res != OK) {
2811 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2812 __FUNCTION__, get_camera_metadata_section_name(tag),
2813 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2814 }
2815 return res;
2816}
2817
2818status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2819 camera_metadata_entry_t entry;
2820 status_t res;
2821 res = find_camera_metadata_entry(buffer, tag, &entry);
2822 if (res == NAME_NOT_FOUND) {
2823 return OK;
2824 } else if (res != OK) {
2825 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2826 __FUNCTION__,
2827 get_camera_metadata_section_name(tag),
2828 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2829 return res;
2830 }
2831 res = delete_camera_metadata_entry(buffer, entry.index);
2832 if (res != OK) {
2833 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2834 __FUNCTION__,
2835 get_camera_metadata_section_name(tag),
2836 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2837 }
2838 return res;
2839}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002840int Camera2Client::formatStringToEnum(const char *format) {
2841 return
2842 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2843 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2844 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2845 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2846 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2847 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2848 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2849 HAL_PIXEL_FORMAT_YV12 : // YV12
2850 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2851 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2852 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2853 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2854 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2855 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2856 -1;
2857}
2858
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002859const char* Camera2Client::formatEnumToString(int format) {
2860 const char *fmt;
2861 switch(format) {
2862 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2863 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2864 break;
2865 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2866 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2867 break;
2868 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2869 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2870 break;
2871 case HAL_PIXEL_FORMAT_YV12: // YV12
2872 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2873 break;
2874 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2875 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2876 break;
2877 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2878 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2879 break;
2880 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2881 ALOGW("Raw sensor preview format requested.");
2882 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2883 break;
2884 default:
2885 ALOGE("%s: Unknown preview format: %x",
2886 __FUNCTION__, format);
2887 fmt = NULL;
2888 break;
2889 }
2890 return fmt;
2891}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002892
2893int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2894 return
2895 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2896 ANDROID_CONTROL_AWB_AUTO :
2897 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2898 ANDROID_CONTROL_AWB_INCANDESCENT :
2899 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2900 ANDROID_CONTROL_AWB_FLUORESCENT :
2901 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2902 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2903 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2904 ANDROID_CONTROL_AWB_DAYLIGHT :
2905 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2906 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2907 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2908 ANDROID_CONTROL_AWB_TWILIGHT :
2909 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2910 ANDROID_CONTROL_AWB_SHADE :
2911 -1;
2912}
2913
2914int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2915 return
2916 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2917 ANDROID_CONTROL_EFFECT_OFF :
2918 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2919 ANDROID_CONTROL_EFFECT_MONO :
2920 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2921 ANDROID_CONTROL_EFFECT_NEGATIVE :
2922 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2923 ANDROID_CONTROL_EFFECT_SOLARIZE :
2924 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2925 ANDROID_CONTROL_EFFECT_SEPIA :
2926 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2927 ANDROID_CONTROL_EFFECT_POSTERIZE :
2928 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2929 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2930 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2931 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2932 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2933 ANDROID_CONTROL_EFFECT_AQUA :
2934 -1;
2935}
2936
2937int Camera2Client::abModeStringToEnum(const char *abMode) {
2938 return
2939 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2940 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2941 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2942 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2943 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2944 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2945 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2946 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2947 -1;
2948}
2949
2950int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2951 return
2952 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2953 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2954 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2955 ANDROID_CONTROL_SCENE_MODE_ACTION :
2956 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2957 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2958 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2959 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2960 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2961 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2962 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2963 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2964 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2965 ANDROID_CONTROL_SCENE_MODE_THEATRE :
2966 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2967 ANDROID_CONTROL_SCENE_MODE_BEACH :
2968 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2969 ANDROID_CONTROL_SCENE_MODE_SNOW :
2970 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2971 ANDROID_CONTROL_SCENE_MODE_SUNSET :
2972 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2973 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2974 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2975 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2976 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2977 ANDROID_CONTROL_SCENE_MODE_SPORTS :
2978 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2979 ANDROID_CONTROL_SCENE_MODE_PARTY :
2980 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2981 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2982 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2983 ANDROID_CONTROL_SCENE_MODE_BARCODE:
2984 -1;
2985}
2986
2987Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
2988 const char *flashMode) {
2989 return
2990 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2991 Parameters::FLASH_MODE_OFF :
2992 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2993 Parameters::FLASH_MODE_AUTO :
2994 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2995 Parameters::FLASH_MODE_ON :
2996 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2997 Parameters::FLASH_MODE_RED_EYE :
2998 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2999 Parameters::FLASH_MODE_TORCH :
3000 Parameters::FLASH_MODE_INVALID;
3001}
3002
3003Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3004 const char *focusMode) {
3005 return
3006 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3007 Parameters::FOCUS_MODE_AUTO :
3008 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3009 Parameters::FOCUS_MODE_INFINITY :
3010 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3011 Parameters::FOCUS_MODE_MACRO :
3012 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3013 Parameters::FOCUS_MODE_FIXED :
3014 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3015 Parameters::FOCUS_MODE_EDOF :
3016 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3017 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3018 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3019 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3020 Parameters::FOCUS_MODE_INVALID;
3021}
3022
3023status_t Camera2Client::parseAreas(const char *areasCStr,
3024 Vector<Parameters::Area> *areas) {
3025 static const size_t NUM_FIELDS = 5;
3026 areas->clear();
3027 if (areasCStr == NULL) {
3028 // If no key exists, use default (0,0,0,0,0)
3029 areas->push();
3030 return OK;
3031 }
3032 String8 areasStr(areasCStr);
3033 ssize_t areaStart = areasStr.find("(", 0) + 1;
3034 while (areaStart != 0) {
3035 const char* area = areasStr.string() + areaStart;
3036 char *numEnd;
3037 int vals[NUM_FIELDS];
3038 for (size_t i = 0; i < NUM_FIELDS; i++) {
3039 errno = 0;
3040 vals[i] = strtol(area, &numEnd, 10);
3041 if (errno || numEnd == area) return BAD_VALUE;
3042 area = numEnd + 1;
3043 }
3044 areas->push(Parameters::Area(
3045 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3046 areaStart = areasStr.find("(", areaStart) + 1;
3047 }
3048 return OK;
3049}
3050
3051status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3052 size_t maxRegions) {
3053 // Definition of valid area can be found in
3054 // include/camera/CameraParameters.h
3055 if (areas.size() == 0) return BAD_VALUE;
3056 if (areas.size() == 1) {
3057 if (areas[0].left == 0 &&
3058 areas[0].top == 0 &&
3059 areas[0].right == 0 &&
3060 areas[0].bottom == 0 &&
3061 areas[0].weight == 0) {
3062 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3063 return OK;
3064 }
3065 }
3066 if (areas.size() > maxRegions) {
3067 ALOGE("%s: Too many areas requested: %d",
3068 __FUNCTION__, areas.size());
3069 return BAD_VALUE;
3070 }
3071
3072 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3073 a != areas.end(); a++) {
3074 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3075 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3076 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3077 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3078 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3079 if (a->left >= a->right) return BAD_VALUE;
3080 if (a->top >= a->bottom) return BAD_VALUE;
3081 }
3082 return OK;
3083}
3084
3085bool Camera2Client::boolFromString(const char *boolStr) {
3086 return !boolStr ? false :
3087 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3088 false;
3089}
3090
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003091int Camera2Client::degToTransform(int degrees, bool mirror) {
3092 if (!mirror) {
3093 if (degrees == 0) return 0;
3094 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3095 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3096 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3097 } else { // Do mirror (horizontal flip)
3098 if (degrees == 0) { // FLIP_H and ROT_0
3099 return HAL_TRANSFORM_FLIP_H;
3100 } else if (degrees == 90) { // FLIP_H and ROT_90
3101 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3102 } else if (degrees == 180) { // FLIP_H and ROT_180
3103 return HAL_TRANSFORM_FLIP_V;
3104 } else if (degrees == 270) { // FLIP_H and ROT_270
3105 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3106 }
3107 }
3108 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3109 return -1;
3110}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003111
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003112} // namespace android