blob: f21a5185ab501989197789583fa55e8746faa9a8 [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);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700595 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700596 case WAITING_FOR_PREVIEW_WINDOW:
597 mState = STOPPED;
598 break;
599 default:
600 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
601 mState);
602 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700603}
604
605bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700606 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700607 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700608 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700609}
610
611status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700612 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700613 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700614 return BAD_VALUE;
615}
616
617status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700618 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700619 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700620 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700621 status_t res;
622 switch (mState) {
623 case STOPPED:
624 res = startPreviewLocked();
625 if (res != OK) return res;
626 break;
627 case PREVIEW:
628 // Ready to go
629 break;
630 case RECORD:
631 case VIDEO_SNAPSHOT:
632 // OK to call this when recording is already on
633 return OK;
634 break;
635 default:
636 ALOGE("%s: Camera %d: Can't start recording in state %s",
637 __FUNCTION__, mCameraId, getStateName(mState));
638 return INVALID_OPERATION;
639 };
640
641 Mutex::Autolock pl(mParamsLock);
642
643 res = updateRecordingStream();
644 if (res != OK) {
645 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
646 __FUNCTION__, mCameraId, strerror(-res), res);
647 return res;
648 }
649
650 if (mRecordingRequest == NULL) {
651 res = updateRecordingRequest();
652 if (res != OK) {
653 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
654 __FUNCTION__, mCameraId, strerror(-res), res);
655 return res;
656 }
657 }
658
659 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
660 res = updateEntry(mRecordingRequest,
661 ANDROID_REQUEST_OUTPUT_STREAMS,
662 outputStreams, 2);
663 if (res != OK) {
664 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
665 __FUNCTION__, mCameraId, strerror(-res), res);
666 return res;
667 }
668 res = sort_camera_metadata(mRecordingRequest);
669 if (res != OK) {
670 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
671 __FUNCTION__, mCameraId, strerror(-res), res);
672 return res;
673 }
674
675 res = mDevice->setStreamingRequest(mRecordingRequest);
676 if (res != OK) {
677 ALOGE("%s: Camera %d: Unable to set recording request to start "
678 "recording: %s (%d)", __FUNCTION__, mCameraId,
679 strerror(-res), res);
680 return res;
681 }
682 mState = RECORD;
683
684 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700685}
686
687void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700688 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700689 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700690 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700691 status_t res;
692 switch (mState) {
693 case RECORD:
694 // OK to stop
695 break;
696 case STOPPED:
697 case PREVIEW:
698 case STILL_CAPTURE:
699 case VIDEO_SNAPSHOT:
700 default:
701 ALOGE("%s: Camera %d: Can't stop recording in state %s",
702 __FUNCTION__, mCameraId, getStateName(mState));
703 return;
704 };
705
706 // Back to preview. Since record can only be reached through preview,
707 // all preview stream setup should be up to date.
708 res = mDevice->setStreamingRequest(mPreviewRequest);
709 if (res != OK) {
710 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
711 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
712 return;
713 }
714
715 // TODO: Should recording heap be freed? Can't do it yet since requests
716 // could still be in flight.
717
718 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700719}
720
721bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700722 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700723 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700724 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700725}
726
727void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700728 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700729 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700730 // Make sure this is for the current heap
731 ssize_t offset;
732 size_t size;
733 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
734 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
735 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
736 "(got %x, expected %x)", __FUNCTION__, mCameraId,
737 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
738 return;
739 }
740 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700741}
742
743status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700744 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700745 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700746 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700747}
748
749status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700750 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700751 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700752 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700753}
754
755status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700756 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700757 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700758 status_t res;
759
760 switch (mState) {
761 case NOT_INITIALIZED:
762 case STOPPED:
763 case WAITING_FOR_PREVIEW_WINDOW:
764 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
765 __FUNCTION__, mCameraId);
766 return INVALID_OPERATION;
767 case PREVIEW:
768 case RECORD:
769 // Good to go for takePicture
770 break;
771 case STILL_CAPTURE:
772 case VIDEO_SNAPSHOT:
773 ALOGE("%s: Camera %d: Already taking a picture",
774 __FUNCTION__, mCameraId);
775 return INVALID_OPERATION;
776 }
777
778 Mutex::Autolock pl(mParamsLock);
779
780 res = updateCaptureStream();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700781 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700782 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
783 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700784 return res;
785 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700786
787 if (mCaptureRequest == NULL) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700788 res = updateCaptureRequest();
789 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700790 ALOGE("%s: Camera %d: Can't create still image capture request: "
791 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700792 return res;
793 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700794 }
795
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700796 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700797 if (mState == PREVIEW) {
798 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
799 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
800 &streamIds, 2);
801 } else if (mState == RECORD) {
802 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
803 mCaptureStreamId };
804 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
805 &streamIds, 3);
806 }
807
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700808 if (res != OK) {
809 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
810 "%s (%d)",
811 __FUNCTION__, mCameraId, strerror(-res), res);
812 return res;
813 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700814 res = sort_camera_metadata(mCaptureRequest);
815 if (res != OK) {
816 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
817 __FUNCTION__, mCameraId, strerror(-res), res);
818 return res;
819 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700820
821 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
822 if (captureCopy == NULL) {
823 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
824 __FUNCTION__, mCameraId);
825 return NO_MEMORY;
826 }
827
828 if (mState == PREVIEW) {
829 res = mDevice->setStreamingRequest(NULL);
830 if (res != OK) {
831 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
832 "%s (%d)",
833 __FUNCTION__, mCameraId, strerror(-res), res);
834 return res;
835 }
836 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700837 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700838 res = mDevice->capture(captureCopy);
839 if (res != OK) {
840 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
841 "%s (%d)",
842 __FUNCTION__, mCameraId, strerror(-res), res);
843 return res;
844 }
845
846 switch (mState) {
847 case PREVIEW:
848 mState = STILL_CAPTURE;
849 break;
850 case RECORD:
851 mState = VIDEO_SNAPSHOT;
852 break;
853 default:
854 ALOGE("%s: Camera %d: Unknown state for still capture!",
855 __FUNCTION__, mCameraId);
856 return INVALID_OPERATION;
857 }
858
859 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700860}
861
862status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700863 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700864 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700865 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700866 Mutex::Autolock pl(mParamsLock);
867 status_t res;
868
869 CameraParameters newParams(params);
870
871 // TODO: Currently ignoring any changes to supposedly read-only
872 // parameters such as supported preview sizes, etc. Should probably
873 // produce an error if they're changed.
874
875 /** Extract and verify new parameters */
876
877 size_t i;
878
879 // PREVIEW_SIZE
880 int previewWidth, previewHeight;
881 newParams.getPreviewSize(&previewWidth, &previewHeight);
882
883 if (previewWidth != mParameters.previewWidth ||
884 previewHeight != mParameters.previewHeight) {
885 if (mState >= PREVIEW) {
886 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700887 "is active! (Currently %d x %d, requested %d x %d",
888 __FUNCTION__,
889 mParameters.previewWidth, mParameters.previewHeight,
890 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700891 return BAD_VALUE;
892 }
893 camera_metadata_entry_t availablePreviewSizes =
894 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
895 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
896 if (availablePreviewSizes.data.i32[i] == previewWidth &&
897 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
898 }
899 if (i == availablePreviewSizes.count) {
900 ALOGE("%s: Requested preview size %d x %d is not supported",
901 __FUNCTION__, previewWidth, previewHeight);
902 return BAD_VALUE;
903 }
904 }
905
906 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700907 int previewFpsRange[2];
908 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700909 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700910 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
911 if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
912 previewFpsRange[1] != mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700913 fpsRangeChanged = true;
914 camera_metadata_entry_t availablePreviewFpsRanges =
915 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
916 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
917 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700918 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700919 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700920 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700921 break;
922 }
923 }
924 if (i == availablePreviewFpsRanges.count) {
925 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700926 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700927 return BAD_VALUE;
928 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700929 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700930 }
931
932 // PREVIEW_FORMAT
933 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
934 if (previewFormat != mParameters.previewFormat) {
935 if (mState >= PREVIEW) {
936 ALOGE("%s: Preview format cannot be updated when preview "
937 "is active!", __FUNCTION__);
938 return BAD_VALUE;
939 }
940 camera_metadata_entry_t availableFormats =
941 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
942 for (i = 0; i < availableFormats.count; i++) {
943 if (availableFormats.data.i32[i] == previewFormat) break;
944 }
945 if (i == availableFormats.count) {
946 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
947 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
948 return BAD_VALUE;
949 }
950 }
951
952 // PREVIEW_FRAME_RATE
953 // Deprecated, only use if the preview fps range is unchanged this time.
954 // The single-value FPS is the same as the minimum of the range.
955 if (!fpsRangeChanged) {
956 previewFps = newParams.getPreviewFrameRate();
957 if (previewFps != mParameters.previewFps) {
958 camera_metadata_entry_t availableFrameRates =
959 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
960 for (i = 0; i < availableFrameRates.count; i+=2) {
961 if (availableFrameRates.data.i32[i] == previewFps) break;
962 }
963 if (i == availableFrameRates.count) {
964 ALOGE("%s: Requested preview frame rate %d is not supported",
965 __FUNCTION__, previewFps);
966 return BAD_VALUE;
967 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700968 previewFpsRange[0] = availableFrameRates.data.i32[i];
969 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700970 }
971 }
972
973 // PICTURE_SIZE
974 int pictureWidth, pictureHeight;
975 newParams.getPictureSize(&pictureWidth, &pictureHeight);
976 if (pictureWidth == mParameters.pictureWidth ||
977 pictureHeight == mParameters.pictureHeight) {
978 camera_metadata_entry_t availablePictureSizes =
979 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
980 for (i = 0; i < availablePictureSizes.count; i+=2) {
981 if (availablePictureSizes.data.i32[i] == pictureWidth &&
982 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
983 }
984 if (i == availablePictureSizes.count) {
985 ALOGE("%s: Requested picture size %d x %d is not supported",
986 __FUNCTION__, pictureWidth, pictureHeight);
987 return BAD_VALUE;
988 }
989 }
990
991 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700992 int jpegThumbSize[2];
993 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700994 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700995 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700996 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700997 if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
998 jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700999 camera_metadata_entry_t availableJpegThumbSizes =
1000 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1001 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001002 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1003 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001004 break;
1005 }
1006 }
1007 if (i == availableJpegThumbSizes.count) {
1008 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001009 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001010 return BAD_VALUE;
1011 }
1012 }
1013
1014 // JPEG_THUMBNAIL_QUALITY
1015 int jpegThumbQuality =
1016 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1017 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1018 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1019 __FUNCTION__, jpegThumbQuality);
1020 return BAD_VALUE;
1021 }
1022
1023 // JPEG_QUALITY
1024 int jpegQuality =
1025 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1026 if (jpegQuality < 0 || jpegQuality > 100) {
1027 ALOGE("%s: Requested JPEG quality %d is not supported",
1028 __FUNCTION__, jpegQuality);
1029 return BAD_VALUE;
1030 }
1031
1032 // ROTATION
1033 int jpegRotation =
1034 newParams.getInt(CameraParameters::KEY_ROTATION);
1035 if (jpegRotation != 0 &&
1036 jpegRotation != 90 &&
1037 jpegRotation != 180 &&
1038 jpegRotation != 270) {
1039 ALOGE("%s: Requested picture rotation angle %d is not supported",
1040 __FUNCTION__, jpegRotation);
1041 return BAD_VALUE;
1042 }
1043
1044 // GPS
1045 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001046 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001047 int64_t gpsTimestamp = 0;
1048 String8 gpsProcessingMethod;
1049 const char *gpsLatStr =
1050 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1051 if (gpsLatStr != NULL) {
1052 const char *gpsLongStr =
1053 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1054 const char *gpsAltitudeStr =
1055 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1056 const char *gpsTimeStr =
1057 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1058 const char *gpsProcMethodStr =
1059 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1060 if (gpsLongStr == NULL ||
1061 gpsAltitudeStr == NULL ||
1062 gpsTimeStr == NULL ||
1063 gpsProcMethodStr == NULL) {
1064 ALOGE("%s: Incomplete set of GPS parameters provided",
1065 __FUNCTION__);
1066 return BAD_VALUE;
1067 }
1068 char *endPtr;
1069 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001070 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001071 if (errno || endPtr == gpsLatStr) {
1072 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1073 return BAD_VALUE;
1074 }
1075 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001076 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001077 if (errno || endPtr == gpsLongStr) {
1078 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1079 return BAD_VALUE;
1080 }
1081 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001082 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001083 if (errno || endPtr == gpsAltitudeStr) {
1084 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1085 gpsAltitudeStr);
1086 return BAD_VALUE;
1087 }
1088 errno = 0;
1089 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1090 if (errno || endPtr == gpsTimeStr) {
1091 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1092 return BAD_VALUE;
1093 }
1094 gpsProcessingMethod = gpsProcMethodStr;
1095
1096 gpsEnabled = true;
1097 }
1098
1099 // WHITE_BALANCE
1100 int wbMode = wbModeStringToEnum(
1101 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1102 if (wbMode != mParameters.wbMode) {
1103 camera_metadata_entry_t availableWbModes =
1104 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1105 for (i = 0; i < availableWbModes.count; i++) {
1106 if (wbMode == availableWbModes.data.u8[i]) break;
1107 }
1108 if (i == availableWbModes.count) {
1109 ALOGE("%s: Requested white balance mode %s is not supported",
1110 __FUNCTION__,
1111 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1112 return BAD_VALUE;
1113 }
1114 }
1115
1116 // EFFECT
1117 int effectMode = effectModeStringToEnum(
1118 newParams.get(CameraParameters::KEY_EFFECT) );
1119 if (effectMode != mParameters.effectMode) {
1120 camera_metadata_entry_t availableEffectModes =
1121 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1122 for (i = 0; i < availableEffectModes.count; i++) {
1123 if (effectMode == availableEffectModes.data.u8[i]) break;
1124 }
1125 if (i == availableEffectModes.count) {
1126 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1127 __FUNCTION__,
1128 newParams.get(CameraParameters::KEY_EFFECT) );
1129 return BAD_VALUE;
1130 }
1131 }
1132
1133 // ANTIBANDING
1134 int antibandingMode = abModeStringToEnum(
1135 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1136 if (antibandingMode != mParameters.antibandingMode) {
1137 camera_metadata_entry_t availableAbModes =
1138 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1139 for (i = 0; i < availableAbModes.count; i++) {
1140 if (antibandingMode == availableAbModes.data.u8[i]) break;
1141 }
1142 if (i == availableAbModes.count) {
1143 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1144 __FUNCTION__,
1145 newParams.get(CameraParameters::KEY_ANTIBANDING));
1146 return BAD_VALUE;
1147 }
1148 }
1149
1150 // SCENE_MODE
1151 int sceneMode = sceneModeStringToEnum(
1152 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1153 if (sceneMode != mParameters.sceneMode) {
1154 camera_metadata_entry_t availableSceneModes =
1155 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1156 for (i = 0; i < availableSceneModes.count; i++) {
1157 if (sceneMode == availableSceneModes.data.u8[i]) break;
1158 }
1159 if (i == availableSceneModes.count) {
1160 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1161 __FUNCTION__,
1162 newParams.get(CameraParameters::KEY_SCENE_MODE));
1163 return BAD_VALUE;
1164 }
1165 }
1166
1167 // FLASH_MODE
1168 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1169 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1170 if (flashMode != mParameters.flashMode) {
1171 camera_metadata_entry_t flashAvailable =
1172 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1173 if (!flashAvailable.data.u8[0] &&
1174 flashMode != Parameters::FLASH_MODE_OFF) {
1175 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1176 "No flash on device", __FUNCTION__,
1177 newParams.get(CameraParameters::KEY_FLASH_MODE));
1178 return BAD_VALUE;
1179 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1180 camera_metadata_entry_t availableAeModes =
1181 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1182 for (i = 0; i < availableAeModes.count; i++) {
1183 if (flashMode == availableAeModes.data.u8[i]) break;
1184 }
1185 if (i == availableAeModes.count) {
1186 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1187 __FUNCTION__,
1188 newParams.get(CameraParameters::KEY_FLASH_MODE));
1189 return BAD_VALUE;
1190 }
1191 } else if (flashMode == -1) {
1192 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1193 __FUNCTION__,
1194 newParams.get(CameraParameters::KEY_FLASH_MODE));
1195 return BAD_VALUE;
1196 }
1197 }
1198
1199 // FOCUS_MODE
1200 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1201 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1202 if (focusMode != mParameters.focusMode) {
1203 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1204 camera_metadata_entry_t minFocusDistance =
1205 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1206 if (minFocusDistance.data.f[0] == 0) {
1207 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1208 "fixed focus lens",
1209 __FUNCTION__,
1210 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1211 return BAD_VALUE;
1212 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1213 camera_metadata_entry_t availableFocusModes =
1214 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1215 for (i = 0; i < availableFocusModes.count; i++) {
1216 if (focusMode == availableFocusModes.data.u8[i]) break;
1217 }
1218 if (i == availableFocusModes.count) {
1219 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1220 __FUNCTION__,
1221 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1222 return BAD_VALUE;
1223 }
1224 }
1225 }
1226 }
1227
1228 // FOCUS_AREAS
1229 Vector<Parameters::Area> focusingAreas;
1230 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1231 &focusingAreas);
1232 size_t max3aRegions =
1233 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1234 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1235 if (res != OK) {
1236 ALOGE("%s: Requested focus areas are malformed: %s",
1237 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1238 return BAD_VALUE;
1239 }
1240
1241 // EXPOSURE_COMPENSATION
1242 int exposureCompensation =
1243 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1244 camera_metadata_entry_t exposureCompensationRange =
1245 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1246 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1247 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1248 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1249 __FUNCTION__, exposureCompensation);
1250 return BAD_VALUE;
1251 }
1252
1253 // AUTO_EXPOSURE_LOCK (always supported)
1254 bool autoExposureLock = boolFromString(
1255 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1256
1257 // AUTO_WHITEBALANCE_LOCK (always supported)
1258 bool autoWhiteBalanceLock = boolFromString(
1259 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1260
1261 // METERING_AREAS
1262 Vector<Parameters::Area> meteringAreas;
1263 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1264 &meteringAreas);
1265 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1266 if (res != OK) {
1267 ALOGE("%s: Requested metering areas are malformed: %s",
1268 __FUNCTION__,
1269 newParams.get(CameraParameters::KEY_METERING_AREAS));
1270 return BAD_VALUE;
1271 }
1272
1273 // ZOOM
1274 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1275 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1276 ALOGE("%s: Requested zoom level %d is not supported",
1277 __FUNCTION__, zoom);
1278 return BAD_VALUE;
1279 }
1280
1281 // VIDEO_SIZE
1282 int videoWidth, videoHeight;
1283 newParams.getVideoSize(&videoWidth, &videoHeight);
1284 if (videoWidth != mParameters.videoWidth ||
1285 videoHeight != mParameters.videoHeight) {
1286 if (mState == RECORD) {
1287 ALOGE("%s: Video size cannot be updated when recording is active!",
1288 __FUNCTION__);
1289 return BAD_VALUE;
1290 }
1291 camera_metadata_entry_t availableVideoSizes =
1292 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1293 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1294 if (availableVideoSizes.data.i32[i] == videoWidth &&
1295 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1296 }
1297 if (i == availableVideoSizes.count) {
1298 ALOGE("%s: Requested video size %d x %d is not supported",
1299 __FUNCTION__, videoWidth, videoHeight);
1300 return BAD_VALUE;
1301 }
1302 }
1303
1304 // RECORDING_HINT (always supported)
1305 bool recordingHint = boolFromString(
1306 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1307
1308 // VIDEO_STABILIZATION
1309 bool videoStabilization = boolFromString(
1310 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1311 camera_metadata_entry_t availableVideoStabilizationModes =
1312 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1313 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1314 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1315 }
1316
1317 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001318
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001319 mParameters.previewWidth = previewWidth;
1320 mParameters.previewHeight = previewHeight;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001321 mParameters.previewFpsRange[0] = previewFpsRange[0];
1322 mParameters.previewFpsRange[1] = previewFpsRange[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001323 mParameters.previewFps = previewFps;
1324 mParameters.previewFormat = previewFormat;
1325
1326 mParameters.pictureWidth = pictureWidth;
1327 mParameters.pictureHeight = pictureHeight;
1328
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001329 mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1330 mParameters.jpegThumbSize[1] = jpegThumbSize[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001331 mParameters.jpegQuality = jpegQuality;
1332 mParameters.jpegThumbQuality = jpegThumbQuality;
1333
1334 mParameters.gpsEnabled = gpsEnabled;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001335 mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1336 mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1337 mParameters.gpsCoordinates[2] = gpsCoordinates[2];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001338 mParameters.gpsTimestamp = gpsTimestamp;
1339 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1340
1341 mParameters.wbMode = wbMode;
1342 mParameters.effectMode = effectMode;
1343 mParameters.antibandingMode = antibandingMode;
1344 mParameters.sceneMode = sceneMode;
1345
1346 mParameters.flashMode = flashMode;
1347 mParameters.focusMode = focusMode;
1348
1349 mParameters.focusingAreas = focusingAreas;
1350 mParameters.exposureCompensation = exposureCompensation;
1351 mParameters.autoExposureLock = autoExposureLock;
1352 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1353 mParameters.meteringAreas = meteringAreas;
1354 mParameters.zoom = zoom;
1355
1356 mParameters.videoWidth = videoWidth;
1357 mParameters.videoHeight = videoHeight;
1358
1359 mParameters.recordingHint = recordingHint;
1360 mParameters.videoStabilization = videoStabilization;
1361
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001362 res = updatePreviewRequest();
1363 if (res != OK) {
1364 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1365 __FUNCTION__, mCameraId, strerror(-res), res);
1366 return res;
1367 }
1368 res = updateCaptureRequest();
1369 if (res != OK) {
1370 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1371 __FUNCTION__, mCameraId, strerror(-res), res);
1372 return res;
1373 }
1374
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001375 res = updateRecordingRequest();
1376 if (res != OK) {
1377 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1378 __FUNCTION__, mCameraId, strerror(-res), res);
1379 return res;
1380 }
1381
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001382 if (mState == PREVIEW) {
1383 res = mDevice->setStreamingRequest(mPreviewRequest);
1384 if (res != OK) {
1385 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1386 __FUNCTION__, mCameraId, strerror(-res), res);
1387 return res;
1388 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001389 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1390 res = mDevice->setStreamingRequest(mRecordingRequest);
1391 if (res != OK) {
1392 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1393 __FUNCTION__, mCameraId, strerror(-res), res);
1394 return res;
1395 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001396 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001397
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001398 mParamsFlattened = params;
1399
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001400 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001401}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001402
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001403String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001404 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001405 Mutex::Autolock icl(mICameraLock);
1406
1407 Mutex::Autolock pl(mParamsLock);
1408
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001409 // TODO: Deal with focus distances
1410 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001411}
1412
1413status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001414 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001415 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001416
1417 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1418 cmd, arg1, arg2);
1419
1420 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
1421 int transform = degToTransform(arg1,
1422 mCameraFacing == CAMERA_FACING_FRONT);
1423 if (transform == -1) {
1424 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1425 __FUNCTION__, mCameraId, arg1);
1426 return BAD_VALUE;
1427 }
1428 if (transform != mParameters.previewTransform &&
1429 mPreviewStreamId != NO_STREAM) {
1430 mDevice->setStreamTransform(mPreviewStreamId, transform);
1431 }
1432 mParameters.previewTransform = transform;
1433 return OK;
1434 }
1435
1436 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1437 mCameraId, cmd, arg1, arg2);
1438
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001439 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001440}
1441
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001442/** Device-related methods */
1443
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001444void Camera2Client::onCaptureAvailable() {
1445 ATRACE_CALL();
1446 status_t res;
1447 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001448 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1449
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001450 CpuConsumer::LockedBuffer imgBuffer;
1451 {
1452 Mutex::Autolock icl(mICameraLock);
1453
1454 // TODO: Signal errors here upstream
1455 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1456 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1457 __FUNCTION__, mCameraId);
1458 return;
1459 }
1460
1461 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1462 if (res != OK) {
1463 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1464 __FUNCTION__, mCameraId, strerror(-res), res);
1465 return;
1466 }
1467
1468 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1469 ALOGE("%s: Camera %d: Unexpected format for still image: "
1470 "%x, expected %x", __FUNCTION__, mCameraId,
1471 imgBuffer.format,
1472 HAL_PIXEL_FORMAT_BLOB);
1473 mCaptureConsumer->unlockBuffer(imgBuffer);
1474 return;
1475 }
1476
1477 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001478 void* captureMemory = mCaptureHeap->mHeap->getBase();
1479 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001480 memcpy(captureMemory, imgBuffer.data, size);
1481
1482 mCaptureConsumer->unlockBuffer(imgBuffer);
1483
1484 currentClient = mCameraClient;
1485 switch (mState) {
1486 case STILL_CAPTURE:
1487 mState = STOPPED;
1488 break;
1489 case VIDEO_SNAPSHOT:
1490 mState = RECORD;
1491 break;
1492 default:
1493 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1494 mCameraId, mState);
1495 break;
1496 }
1497 }
1498 // Call outside mICameraLock to allow re-entrancy from notification
1499 if (currentClient != 0) {
1500 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001501 mCaptureHeap->mBuffers[0], NULL);
1502 }
1503}
1504
1505void Camera2Client::onRecordingFrameAvailable() {
1506 ATRACE_CALL();
1507 status_t res;
1508 sp<ICameraClient> currentClient;
1509 size_t heapIdx = 0;
1510 nsecs_t timestamp;
1511 {
1512 Mutex::Autolock icl(mICameraLock);
1513 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001514 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001515 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001516 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1517 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001518 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001519 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001520 }
1521
1522 CpuConsumer::LockedBuffer imgBuffer;
1523 res = mRecordingConsumer->lockNextBuffer(&imgBuffer);
1524 if (res != OK) {
1525 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1526 __FUNCTION__, mCameraId, strerror(-res), res);
1527 return;
1528 }
1529
1530 if (imgBuffer.format != (int)kRecordingFormat) {
1531 ALOGE("%s: Camera %d: Unexpected recording format: %x",
1532 __FUNCTION__, mCameraId, imgBuffer.format);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001533 discardData = true;
1534 }
1535
1536 if (discardData) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001537 mRecordingConsumer->unlockBuffer(imgBuffer);
1538 return;
1539 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001540
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001541 size_t bufferSize = imgBuffer.width * imgBuffer.height * 3 / 2;
1542
1543 if (mRecordingHeap == 0 ||
1544 bufferSize >
1545 mRecordingHeap->mHeap->getSize() / kRecordingHeapCount) {
1546 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1547 "size %d bytes", __FUNCTION__, mCameraId,
1548 kRecordingHeapCount, bufferSize);
1549 if (mRecordingHeap != 0) {
1550 ALOGV("%s: Camera %d: Previous heap has size %d "
1551 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1552 mRecordingHeap->mHeap->getSize(),
1553 bufferSize * kRecordingHeapCount);
1554 }
1555 // Need to allocate memory for heap
1556 mRecordingHeap.clear();
1557
1558 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1559 "Camera2Client::RecordingHeap");
1560 if (mRecordingHeap->mHeap->getSize() == 0) {
1561 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1562 __FUNCTION__, mCameraId);
1563 mRecordingConsumer->unlockBuffer(imgBuffer);
1564 return;
1565 }
1566 mRecordingHeapHead = 0;
1567 mRecordingHeapFree = kRecordingHeapCount;
1568 }
1569
1570 // TODO: Optimize this to avoid memcopy
1571 if ( mRecordingHeapFree == 0) {
1572 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1573 __FUNCTION__, mCameraId);
1574 mRecordingConsumer->unlockBuffer(imgBuffer);
1575 return;
1576 }
1577 heapIdx = mRecordingHeapHead;
1578 timestamp = imgBuffer.timestamp;
1579 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1580 mRecordingHeapFree--;
1581
1582 ALOGV("%s: Camera %d: Timestamp %lld",
1583 __FUNCTION__, mCameraId, timestamp);
1584
1585 ssize_t offset;
1586 size_t size;
1587 sp<IMemoryHeap> heap =
1588 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1589 &size);
1590
1591 memcpy((uint8_t*)heap->getBase() + offset, imgBuffer.data, size);
1592
1593 mRecordingConsumer->unlockBuffer(imgBuffer);
1594
1595 currentClient = mCameraClient;
1596 }
1597 // Call outside mICameraLock to allow re-entrancy from notification
1598 if (currentClient != 0) {
1599 currentClient->dataCallbackTimestamp(timestamp,
1600 CAMERA_MSG_VIDEO_FRAME,
1601 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001602 }
1603}
1604
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001605camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1606 size_t minCount, size_t maxCount) {
1607 status_t res;
1608 camera_metadata_entry_t entry;
1609 res = find_camera_metadata_entry(mDevice->info(),
1610 tag,
1611 &entry);
1612 if (CC_UNLIKELY( res != OK )) {
1613 const char* tagSection = get_camera_metadata_section_name(tag);
1614 if (tagSection == NULL) tagSection = "<unknown>";
1615 const char* tagName = get_camera_metadata_tag_name(tag);
1616 if (tagName == NULL) tagName = "<unknown>";
1617
1618 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1619 tagSection, tagName, tag, strerror(-res), res);
1620 entry.count = 0;
1621 entry.data.u8 = NULL;
1622 } else if (CC_UNLIKELY(
1623 (minCount != 0 && entry.count < minCount) ||
1624 (maxCount != 0 && entry.count > maxCount) ) ) {
1625 const char* tagSection = get_camera_metadata_section_name(tag);
1626 if (tagSection == NULL) tagSection = "<unknown>";
1627 const char* tagName = get_camera_metadata_tag_name(tag);
1628 if (tagName == NULL) tagName = "<unknown>";
1629 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1630 "Expected between %d and %d values, but got %d values",
1631 tagSection, tagName, tag, minCount, maxCount, entry.count);
1632 entry.count = 0;
1633 entry.data.u8 = NULL;
1634 }
1635
1636 return entry;
1637}
1638
1639/** Utility methods */
1640
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001641
1642status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001643 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001644 Mutex::Autolock pl(mParamsLock);
1645
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001646 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001647 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001648
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001649 camera_metadata_entry_t availableProcessedSizes =
1650 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1651 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001652
1653 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001654 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1655 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1656 mParameters.videoWidth = mParameters.previewWidth;
1657 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001658
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001659 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1660 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1661 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1662 String8::format("%dx%d",
1663 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001664 {
1665 String8 supportedPreviewSizes;
1666 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1667 if (i != 0) supportedPreviewSizes += ",";
1668 supportedPreviewSizes += String8::format("%dx%d",
1669 availableProcessedSizes.data.i32[i],
1670 availableProcessedSizes.data.i32[i+1]);
1671 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001672 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001673 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001674 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001675 supportedPreviewSizes);
1676 }
1677
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001678 camera_metadata_entry_t availableFpsRanges =
1679 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1680 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001681
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001682 mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1683 mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001684
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001685 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1686 String8::format("%d,%d",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001687 mParameters.previewFpsRange[0],
1688 mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001689
1690 {
1691 String8 supportedPreviewFpsRange;
1692 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1693 if (i != 0) supportedPreviewFpsRange += ",";
1694 supportedPreviewFpsRange += String8::format("(%d,%d)",
1695 availableFpsRanges.data.i32[i],
1696 availableFpsRanges.data.i32[i+1]);
1697 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001698 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001699 supportedPreviewFpsRange);
1700 }
1701
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001702 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1703 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1704 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001705
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001706 mParameters.previewTransform = degToTransform(0,
1707 mCameraFacing == CAMERA_FACING_FRONT);
1708
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001709 camera_metadata_entry_t availableFormats =
1710 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1711
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001712 {
1713 String8 supportedPreviewFormats;
1714 bool addComma = false;
1715 for (size_t i=0; i < availableFormats.count; i++) {
1716 if (addComma) supportedPreviewFormats += ",";
1717 addComma = true;
1718 switch (availableFormats.data.i32[i]) {
1719 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001720 supportedPreviewFormats +=
1721 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001722 break;
1723 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001724 supportedPreviewFormats +=
1725 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001726 break;
1727 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001728 supportedPreviewFormats +=
1729 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001730 break;
1731 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001732 supportedPreviewFormats +=
1733 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001734 break;
1735 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001736 supportedPreviewFormats +=
1737 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001738 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001739 case HAL_PIXEL_FORMAT_RGBA_8888:
1740 supportedPreviewFormats +=
1741 CameraParameters::PIXEL_FORMAT_RGBA8888;
1742 break;
1743 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001744 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001745 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001746 addComma = false;
1747 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001748
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001749 default:
1750 ALOGW("%s: Camera %d: Unknown preview format: %x",
1751 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1752 addComma = false;
1753 break;
1754 }
1755 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001756 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001757 supportedPreviewFormats);
1758 }
1759
1760 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1761 // still have to do something sane for them
1762
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001763 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001764 mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001765
1766 {
1767 String8 supportedPreviewFrameRates;
1768 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1769 if (i != 0) supportedPreviewFrameRates += ",";
1770 supportedPreviewFrameRates += String8::format("%d",
1771 availableFpsRanges.data.i32[i]);
1772 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001773 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001774 supportedPreviewFrameRates);
1775 }
1776
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001777 camera_metadata_entry_t availableJpegSizes =
1778 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1779 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001780
1781 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001782 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1783 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001784
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001785 params.setPictureSize(mParameters.pictureWidth,
1786 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001787
1788 {
1789 String8 supportedPictureSizes;
1790 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1791 if (i != 0) supportedPictureSizes += ",";
1792 supportedPictureSizes += String8::format("%dx%d",
1793 availableJpegSizes.data.i32[i],
1794 availableJpegSizes.data.i32[i+1]);
1795 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001796 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001797 supportedPictureSizes);
1798 }
1799
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001800 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1801 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1802 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001803
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001804 camera_metadata_entry_t availableJpegThumbnailSizes =
1805 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1806 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001807
1808 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001809 mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1810 mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001811
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001812 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001813 mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001814 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001815 mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001816
1817 {
1818 String8 supportedJpegThumbSizes;
1819 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1820 if (i != 0) supportedJpegThumbSizes += ",";
1821 supportedJpegThumbSizes += String8::format("%dx%d",
1822 availableJpegThumbnailSizes.data.i32[i],
1823 availableJpegThumbnailSizes.data.i32[i+1]);
1824 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001825 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001826 supportedJpegThumbSizes);
1827 }
1828
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001829 mParameters.jpegThumbQuality = 90;
1830 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1831 mParameters.jpegThumbQuality);
1832 mParameters.jpegQuality = 90;
1833 params.set(CameraParameters::KEY_JPEG_QUALITY,
1834 mParameters.jpegQuality);
1835 mParameters.jpegRotation = 0;
1836 params.set(CameraParameters::KEY_ROTATION,
1837 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001838
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001839 mParameters.gpsEnabled = false;
1840 mParameters.gpsProcessingMethod = "unknown";
1841 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001842
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001843 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1844 params.set(CameraParameters::KEY_WHITE_BALANCE,
1845 CameraParameters::WHITE_BALANCE_AUTO);
1846
1847 camera_metadata_entry_t availableWhiteBalanceModes =
1848 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001849 {
1850 String8 supportedWhiteBalance;
1851 bool addComma = false;
1852 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1853 if (addComma) supportedWhiteBalance += ",";
1854 addComma = true;
1855 switch (availableWhiteBalanceModes.data.u8[i]) {
1856 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001857 supportedWhiteBalance +=
1858 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001859 break;
1860 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001861 supportedWhiteBalance +=
1862 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001863 break;
1864 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001865 supportedWhiteBalance +=
1866 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001867 break;
1868 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001869 supportedWhiteBalance +=
1870 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001871 break;
1872 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001873 supportedWhiteBalance +=
1874 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001875 break;
1876 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001877 supportedWhiteBalance +=
1878 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001879 break;
1880 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001881 supportedWhiteBalance +=
1882 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001883 break;
1884 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001885 supportedWhiteBalance +=
1886 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001887 break;
1888 // Skipping values not mappable to v1 API
1889 case ANDROID_CONTROL_AWB_OFF:
1890 addComma = false;
1891 break;
1892 default:
1893 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1894 __FUNCTION__, mCameraId,
1895 availableWhiteBalanceModes.data.u8[i]);
1896 addComma = false;
1897 break;
1898 }
1899 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001900 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001901 supportedWhiteBalance);
1902 }
1903
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001904 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1905 params.set(CameraParameters::KEY_EFFECT,
1906 CameraParameters::EFFECT_NONE);
1907
1908 camera_metadata_entry_t availableEffects =
1909 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1910 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001911 {
1912 String8 supportedEffects;
1913 bool addComma = false;
1914 for (size_t i=0; i < availableEffects.count; i++) {
1915 if (addComma) supportedEffects += ",";
1916 addComma = true;
1917 switch (availableEffects.data.u8[i]) {
1918 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001919 supportedEffects +=
1920 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001921 break;
1922 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001923 supportedEffects +=
1924 CameraParameters::EFFECT_MONO;
1925 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001926 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001927 supportedEffects +=
1928 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001929 break;
1930 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001931 supportedEffects +=
1932 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001933 break;
1934 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001935 supportedEffects +=
1936 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001937 break;
1938 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001939 supportedEffects +=
1940 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001941 break;
1942 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001943 supportedEffects +=
1944 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001945 break;
1946 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001947 supportedEffects +=
1948 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001949 break;
1950 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001951 supportedEffects +=
1952 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001953 break;
1954 default:
1955 ALOGW("%s: Camera %d: Unknown effect value: %d",
1956 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1957 addComma = false;
1958 break;
1959 }
1960 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001961 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001962 }
1963
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001964 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1965 params.set(CameraParameters::KEY_ANTIBANDING,
1966 CameraParameters::ANTIBANDING_AUTO);
1967
1968 camera_metadata_entry_t availableAntibandingModes =
1969 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1970 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001971 {
1972 String8 supportedAntibanding;
1973 bool addComma = false;
1974 for (size_t i=0; i < availableAntibandingModes.count; i++) {
1975 if (addComma) supportedAntibanding += ",";
1976 addComma = true;
1977 switch (availableAntibandingModes.data.u8[i]) {
1978 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001979 supportedAntibanding +=
1980 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001981 break;
1982 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001983 supportedAntibanding +=
1984 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001985 break;
1986 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001987 supportedAntibanding +=
1988 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001989 break;
1990 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001991 supportedAntibanding +=
1992 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001993 break;
1994 default:
1995 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
1996 __FUNCTION__, mCameraId,
1997 availableAntibandingModes.data.u8[i]);
1998 addComma = false;
1999 break;
2000 }
2001 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002002 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002003 supportedAntibanding);
2004 }
2005
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002006 mParameters.sceneMode = ANDROID_CONTROL_OFF;
2007 params.set(CameraParameters::KEY_SCENE_MODE,
2008 CameraParameters::SCENE_MODE_AUTO);
2009
2010 camera_metadata_entry_t availableSceneModes =
2011 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2012 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002013 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002014 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002015 bool addComma = true;
2016 bool noSceneModes = false;
2017 for (size_t i=0; i < availableSceneModes.count; i++) {
2018 if (addComma) supportedSceneModes += ",";
2019 addComma = true;
2020 switch (availableSceneModes.data.u8[i]) {
2021 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2022 noSceneModes = true;
2023 break;
2024 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2025 // Not in old API
2026 addComma = false;
2027 break;
2028 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002029 supportedSceneModes +=
2030 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002031 break;
2032 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002033 supportedSceneModes +=
2034 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002035 break;
2036 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002037 supportedSceneModes +=
2038 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002039 break;
2040 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002041 supportedSceneModes +=
2042 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002043 break;
2044 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002045 supportedSceneModes +=
2046 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002047 break;
2048 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002049 supportedSceneModes +=
2050 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002051 break;
2052 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002053 supportedSceneModes +=
2054 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002055 break;
2056 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002057 supportedSceneModes +=
2058 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002059 break;
2060 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002061 supportedSceneModes +=
2062 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002063 break;
2064 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002065 supportedSceneModes +=
2066 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002067 break;
2068 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002069 supportedSceneModes +=
2070 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002071 break;
2072 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002073 supportedSceneModes +=
2074 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002075 break;
2076 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002077 supportedSceneModes +=
2078 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002079 break;
2080 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002081 supportedSceneModes +=
2082 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002083 break;
2084 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002085 supportedSceneModes +=
2086 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002087 break;
2088 default:
2089 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002090 __FUNCTION__, mCameraId,
2091 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002092 addComma = false;
2093 break;
2094 }
2095 }
2096 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002097 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002098 supportedSceneModes);
2099 }
2100 }
2101
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002102 camera_metadata_entry_t flashAvailable =
2103 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2104 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002105
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002106 camera_metadata_entry_t availableAeModes =
2107 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2108 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002109
2110 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002111 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2112 params.set(CameraParameters::KEY_FLASH_MODE,
2113 CameraParameters::FLASH_MODE_AUTO);
2114
2115 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2116 supportedFlashModes = supportedFlashModes +
2117 "," + CameraParameters::FLASH_MODE_AUTO +
2118 "," + CameraParameters::FLASH_MODE_ON +
2119 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002120 for (size_t i=0; i < availableAeModes.count; i++) {
2121 if (availableAeModes.data.u8[i] ==
2122 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002123 supportedFlashModes = supportedFlashModes + "," +
2124 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002125 break;
2126 }
2127 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002128 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002129 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002130 } else {
2131 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2132 params.set(CameraParameters::KEY_FLASH_MODE,
2133 CameraParameters::FLASH_MODE_OFF);
2134 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2135 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002136 }
2137
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002138 camera_metadata_entry_t minFocusDistance =
2139 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2140 if (!minFocusDistance.count) return NO_INIT;
2141
2142 camera_metadata_entry_t availableAfModes =
2143 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2144 if (!availableAfModes.count) return NO_INIT;
2145
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002146 if (minFocusDistance.data.f[0] == 0) {
2147 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002148 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2149 params.set(CameraParameters::KEY_FOCUS_MODE,
2150 CameraParameters::FOCUS_MODE_FIXED);
2151 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2152 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002153 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002154 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2155 params.set(CameraParameters::KEY_FOCUS_MODE,
2156 CameraParameters::FOCUS_MODE_AUTO);
2157 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2158 supportedFocusModes = supportedFocusModes + "," +
2159 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002160 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002161
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002162 for (size_t i=0; i < availableAfModes.count; i++) {
2163 if (addComma) supportedFocusModes += ",";
2164 addComma = true;
2165 switch (availableAfModes.data.u8[i]) {
2166 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002167 supportedFocusModes +=
2168 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002169 break;
2170 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002171 supportedFocusModes +=
2172 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002173 break;
2174 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002175 supportedFocusModes +=
2176 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002177 break;
2178 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002179 supportedFocusModes +=
2180 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002181 break;
2182 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002183 supportedFocusModes +=
2184 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002185 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002186 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002187 case ANDROID_CONTROL_AF_OFF:
2188 addComma = false;
2189 break;
2190 default:
2191 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2192 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2193 addComma = false;
2194 break;
2195 }
2196 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002197 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002198 supportedFocusModes);
2199 }
2200
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002201 camera_metadata_entry_t max3aRegions =
2202 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2203 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002204
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002205 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002206 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002207 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002208 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002209 mParameters.focusingAreas.clear();
2210 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002211
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002212 camera_metadata_entry_t availableFocalLengths =
2213 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2214 if (!availableFocalLengths.count) return NO_INIT;
2215
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002216 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002217 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002218
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002219 camera_metadata_entry_t sensorSize =
2220 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2221 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002222
2223 // The fields of view here assume infinity focus, maximum wide angle
2224 float horizFov = 180 / M_PI *
2225 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2226 float vertFov = 180 / M_PI *
2227 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002228 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2229 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002230
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002231 mParameters.exposureCompensation = 0;
2232 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2233 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002234
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002235 camera_metadata_entry_t exposureCompensationRange =
2236 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2237 if (!exposureCompensationRange.count) return NO_INIT;
2238
2239 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002240 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002241 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002242 exposureCompensationRange.data.i32[0]);
2243
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002244 camera_metadata_entry_t exposureCompensationStep =
2245 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2246 if (!exposureCompensationStep.count) return NO_INIT;
2247
2248 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002249 exposureCompensationStep.data.r[0].numerator /
2250 exposureCompensationStep.data.r[0].denominator);
2251
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002252 mParameters.autoExposureLock = false;
2253 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2254 CameraParameters::FALSE);
2255 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2256 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002258 mParameters.autoWhiteBalanceLock = false;
2259 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2260 CameraParameters::FALSE);
2261 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2262 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002263
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002264 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2265 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002266 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002267 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002268 "(0,0,0,0,0)");
2269
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002270 mParameters.zoom = 0;
2271 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
2272 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002273
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002274 camera_metadata_entry_t maxDigitalZoom =
2275 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2276 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277
2278 {
2279 String8 zoomRatios;
2280 float zoom = 1.f;
2281 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002282 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002283 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002284 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002285 if (addComma) zoomRatios += ",";
2286 addComma = true;
2287 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2288 zoom += zoomIncrement;
2289 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002290 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002291 }
2292
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002293 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2294 CameraParameters::TRUE);
2295 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2296 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002297
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002298 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002299 "Infinity,Infinity,Infinity");
2300
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002301 camera_metadata_entry_t maxFacesDetected =
2302 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2303 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002304 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002305 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002306 0);
2307
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002308 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002309 formatEnumToString(kRecordingFormat));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002310
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002311 params.set(CameraParameters::KEY_RECORDING_HINT,
2312 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002313
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002314 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2315 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002316
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002317 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2318 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002319
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002320 camera_metadata_entry_t availableVideoStabilizationModes =
2321 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2322 if (!availableVideoStabilizationModes.count) return NO_INIT;
2323
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002324 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002325 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2326 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002327 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002328 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2329 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002330 }
2331
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002332 mParamsFlattened = params.flatten();
2333
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002334 return OK;
2335}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002336
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002337status_t Camera2Client::updatePreviewStream() {
2338 ATRACE_CALL();
2339 status_t res;
2340 if (mPreviewStreamId != NO_STREAM) {
2341 // Check if stream parameters have to change
2342 uint32_t currentWidth, currentHeight;
2343 res = mDevice->getStreamInfo(mPreviewStreamId,
2344 &currentWidth, &currentHeight, 0);
2345 if (res != OK) {
2346 ALOGE("%s: Camera %d: Error querying preview stream info: "
2347 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2348 return res;
2349 }
2350 if (currentWidth != (uint32_t)mParameters.previewWidth ||
2351 currentHeight != (uint32_t)mParameters.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002352 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2353 __FUNCTION__, mCameraId, currentWidth, currentHeight,
2354 mParameters.previewWidth, mParameters.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002355 res = mDevice->waitUntilDrained();
2356 if (res != OK) {
2357 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2358 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2359 return res;
2360 }
2361 res = mDevice->deleteStream(mPreviewStreamId);
2362 if (res != OK) {
2363 ALOGE("%s: Camera %d: Unable to delete old output stream "
2364 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2365 strerror(-res), res);
2366 return res;
2367 }
2368 mPreviewStreamId = NO_STREAM;
2369 }
2370 }
2371
2372 if (mPreviewStreamId == NO_STREAM) {
2373 res = mDevice->createStream(mPreviewWindow,
2374 mParameters.previewWidth, mParameters.previewHeight,
2375 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2376 &mPreviewStreamId);
2377 if (res != OK) {
2378 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2379 __FUNCTION__, mCameraId, strerror(-res), res);
2380 return res;
2381 }
2382 }
2383
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002384 res = mDevice->setStreamTransform(mPreviewStreamId,
2385 mParameters.previewTransform);
2386 if (res != OK) {
2387 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2388 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2389 return res;
2390 }
2391
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002392 return OK;
2393}
2394
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002395status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002396 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002397 status_t res;
2398 if (mPreviewRequest == NULL) {
2399 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2400 &mPreviewRequest);
2401 if (res != OK) {
2402 ALOGE("%s: Camera %d: Unable to create default preview request: "
2403 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2404 return res;
2405 }
2406 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002407
2408 res = updateRequestCommon(mPreviewRequest);
2409 if (res != OK) {
2410 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2411 "request: %s (%d)", __FUNCTION__, mCameraId,
2412 strerror(-res), res);
2413 return res;
2414 }
2415
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002416 return OK;
2417}
2418
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002419status_t Camera2Client::updateCaptureStream() {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002420 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002421 status_t res;
2422 // Find out buffer size for JPEG
2423 camera_metadata_entry_t maxJpegSize =
2424 staticInfo(ANDROID_JPEG_MAX_SIZE);
2425 if (maxJpegSize.count == 0) {
2426 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2427 __FUNCTION__, mCameraId);
2428 return INVALID_OPERATION;
2429 }
2430
2431 if (mCaptureConsumer == 0) {
2432 // Create CPU buffer queue endpoint
2433 mCaptureConsumer = new CpuConsumer(1);
2434 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2435 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2436 mCaptureWindow = new SurfaceTextureClient(
2437 mCaptureConsumer->getProducerInterface());
2438 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002439 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2440 "Camera2Client::CaptureHeap");
2441 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002442 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2443 __FUNCTION__, mCameraId);
2444 return NO_MEMORY;
2445 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002446 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002447
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002448 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002449 // Check if stream parameters have to change
2450 uint32_t currentWidth, currentHeight;
2451 res = mDevice->getStreamInfo(mCaptureStreamId,
2452 &currentWidth, &currentHeight, 0);
2453 if (res != OK) {
2454 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2455 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2456 return res;
2457 }
2458 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
2459 currentHeight != (uint32_t)mParameters.pictureHeight) {
2460 res = mDevice->deleteStream(mCaptureStreamId);
2461 if (res != OK) {
2462 ALOGE("%s: Camera %d: Unable to delete old output stream "
2463 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2464 strerror(-res), res);
2465 return res;
2466 }
2467 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002468 }
2469 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002470
2471 if (mCaptureStreamId == NO_STREAM) {
2472 // Create stream for HAL production
2473 res = mDevice->createStream(mCaptureWindow,
2474 mParameters.pictureWidth, mParameters.pictureHeight,
2475 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2476 &mCaptureStreamId);
2477 if (res != OK) {
2478 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2479 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2480 return res;
2481 }
2482
2483 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002484 return OK;
2485}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002486
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002487status_t Camera2Client::updateCaptureRequest() {
2488 ATRACE_CALL();
2489 status_t res;
2490 if (mCaptureRequest == NULL) {
2491 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2492 &mCaptureRequest);
2493 if (res != OK) {
2494 ALOGE("%s: Camera %d: Unable to create default still image request:"
2495 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2496 return res;
2497 }
2498 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002499
2500 res = updateRequestCommon(mCaptureRequest);
2501 if (res != OK) {
2502 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2503 "request: %s (%d)", __FUNCTION__, mCameraId,
2504 strerror(-res), res);
2505 return res;
2506 }
2507
2508 res = updateEntry(mCaptureRequest,
2509 ANDROID_JPEG_THUMBNAIL_SIZE,
2510 mParameters.jpegThumbSize, 2);
2511 if (res != OK) return res;
2512 res = updateEntry(mCaptureRequest,
2513 ANDROID_JPEG_THUMBNAIL_QUALITY,
2514 &mParameters.jpegThumbQuality, 1);
2515 if (res != OK) return res;
2516 res = updateEntry(mCaptureRequest,
2517 ANDROID_JPEG_QUALITY,
2518 &mParameters.jpegQuality, 1);
2519 if (res != OK) return res;
2520 res = updateEntry(mCaptureRequest,
2521 ANDROID_JPEG_ORIENTATION,
2522 &mParameters.jpegRotation, 1);
2523 if (res != OK) return res;
2524
2525 if (mParameters.gpsEnabled) {
2526 res = updateEntry(mCaptureRequest,
2527 ANDROID_JPEG_GPS_COORDINATES,
2528 mParameters.gpsCoordinates, 3);
2529 if (res != OK) return res;
2530 res = updateEntry(mCaptureRequest,
2531 ANDROID_JPEG_GPS_TIMESTAMP,
2532 &mParameters.gpsTimestamp, 1);
2533 if (res != OK) return res;
2534 res = updateEntry(mCaptureRequest,
2535 ANDROID_JPEG_GPS_PROCESSING_METHOD,
2536 mParameters.gpsProcessingMethod.string(),
2537 mParameters.gpsProcessingMethod.size());
2538 if (res != OK) return res;
2539 } else {
2540 res = deleteEntry(mCaptureRequest,
2541 ANDROID_JPEG_GPS_COORDINATES);
2542 if (res != OK) return res;
2543 res = deleteEntry(mCaptureRequest,
2544 ANDROID_JPEG_GPS_TIMESTAMP);
2545 if (res != OK) return res;
2546 res = deleteEntry(mCaptureRequest,
2547 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2548 if (res != OK) return res;
2549 }
2550
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002551 return OK;
2552}
2553
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002554status_t Camera2Client::updateRecordingRequest() {
2555 ATRACE_CALL();
2556 status_t res;
2557 if (mRecordingRequest == NULL) {
2558 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2559 &mRecordingRequest);
2560 if (res != OK) {
2561 ALOGE("%s: Camera %d: Unable to create default recording request:"
2562 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2563 return res;
2564 }
2565 }
2566
2567 res = updateRequestCommon(mRecordingRequest);
2568 if (res != OK) {
2569 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2570 "request: %s (%d)", __FUNCTION__, mCameraId,
2571 strerror(-res), res);
2572 return res;
2573 }
2574
2575 return OK;
2576}
2577
2578status_t Camera2Client::updateRecordingStream() {
2579 status_t res;
2580
2581 if (mRecordingConsumer == 0) {
2582 // Create CPU buffer queue endpoint
2583 mRecordingConsumer = new CpuConsumer(1);
2584 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2585 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2586 mRecordingWindow = new SurfaceTextureClient(
2587 mRecordingConsumer->getProducerInterface());
2588 // Allocate memory later, since we don't know buffer size until receipt
2589 }
2590
2591 if (mRecordingStreamId != NO_STREAM) {
2592 // Check if stream parameters have to change
2593 uint32_t currentWidth, currentHeight;
2594 res = mDevice->getStreamInfo(mRecordingStreamId,
2595 &currentWidth, &currentHeight, 0);
2596 if (res != OK) {
2597 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2598 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2599 return res;
2600 }
2601 if (currentWidth != (uint32_t)mParameters.videoWidth ||
2602 currentHeight != (uint32_t)mParameters.videoHeight) {
2603 // TODO: Should wait to be sure previous recording has finished
2604 res = mDevice->deleteStream(mRecordingStreamId);
2605 if (res != OK) {
2606 ALOGE("%s: Camera %d: Unable to delete old output stream "
2607 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2608 strerror(-res), res);
2609 return res;
2610 }
2611 mRecordingStreamId = NO_STREAM;
2612 }
2613 }
2614
2615 if (mRecordingStreamId == NO_STREAM) {
2616 res = mDevice->createStream(mRecordingWindow,
2617 mParameters.videoWidth, mParameters.videoHeight,
2618 kRecordingFormat, 0, &mRecordingStreamId);
2619 if (res != OK) {
2620 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2621 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2622 return res;
2623 }
2624 }
2625
2626 return OK;
2627}
2628
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002629status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
2630 ATRACE_CALL();
2631 status_t res;
2632 res = updateEntry(request,
2633 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
2634 if (res != OK) return res;
2635
2636 uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
2637 ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
2638 res = updateEntry(request,
2639 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2640 if (res != OK) return res;
2641 res = updateEntry(request,
2642 ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
2643 if (res != OK) return res;
2644 res = updateEntry(request,
2645 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2646 &mParameters.antibandingMode, 1);
2647 if (res != OK) return res;
2648
2649 uint8_t controlMode =
2650 (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2651 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2652 res = updateEntry(request,
2653 ANDROID_CONTROL_MODE, &controlMode, 1);
2654 if (res != OK) return res;
2655 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2656 res = updateEntry(request,
2657 ANDROID_CONTROL_SCENE_MODE,
2658 &mParameters.sceneMode, 1);
2659 if (res != OK) return res;
2660 }
2661
2662 uint8_t flashMode = ANDROID_FLASH_OFF;
2663 uint8_t aeMode;
2664 switch (mParameters.flashMode) {
2665 case Parameters::FLASH_MODE_OFF:
2666 aeMode = ANDROID_CONTROL_AE_ON; break;
2667 case Parameters::FLASH_MODE_AUTO:
2668 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2669 case Parameters::FLASH_MODE_ON:
2670 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2671 case Parameters::FLASH_MODE_TORCH:
2672 aeMode = ANDROID_CONTROL_AE_ON;
2673 flashMode = ANDROID_FLASH_TORCH;
2674 break;
2675 case Parameters::FLASH_MODE_RED_EYE:
2676 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2677 default:
2678 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2679 mCameraId, mParameters.flashMode);
2680 return BAD_VALUE;
2681 }
2682 if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2683
2684 res = updateEntry(request,
2685 ANDROID_FLASH_MODE, &flashMode, 1);
2686 if (res != OK) return res;
2687 res = updateEntry(request,
2688 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2689 if (res != OK) return res;
2690
2691 float focusDistance = 0; // infinity focus in diopters
2692 uint8_t focusMode;
2693 switch (mParameters.focusMode) {
2694 case Parameters::FOCUS_MODE_AUTO:
2695 case Parameters::FOCUS_MODE_MACRO:
2696 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2697 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2698 case Parameters::FOCUS_MODE_EDOF:
2699 focusMode = mParameters.focusMode;
2700 break;
2701 case Parameters::FOCUS_MODE_INFINITY:
2702 case Parameters::FOCUS_MODE_FIXED:
2703 focusMode = ANDROID_CONTROL_AF_OFF;
2704 break;
2705 default:
2706 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2707 mCameraId, mParameters.focusMode);
2708 return BAD_VALUE;
2709 }
2710 res = updateEntry(request,
2711 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2712 if (res != OK) return res;
2713 res = updateEntry(request,
2714 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2715 if (res != OK) return res;
2716
2717 size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
2718 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2719 for (size_t i = 0; i < focusingAreasSize; i += 5) {
2720 focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
2721 focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
2722 focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
2723 focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
2724 focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
2725 }
2726 res = updateEntry(request,
2727 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2728 if (res != OK) return res;
2729 delete[] focusingAreas;
2730
2731 res = updateEntry(request,
2732 ANDROID_CONTROL_AE_EXP_COMPENSATION,
2733 &mParameters.exposureCompensation, 1);
2734 if (res != OK) return res;
2735
2736 size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
2737 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2738 for (size_t i = 0; i < meteringAreasSize; i += 5) {
2739 meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
2740 meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
2741 meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
2742 meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
2743 meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
2744 }
2745 res = updateEntry(request,
2746 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2747 if (res != OK) return res;
2748
2749 res = updateEntry(request,
2750 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2751 if (res != OK) return res;
2752 delete[] meteringAreas;
2753
2754 // Need to convert zoom index into a crop rectangle. The rectangle is
2755 // chosen to maximize its area on the sensor
2756
2757 camera_metadata_entry_t maxDigitalZoom =
2758 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2759 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2760 (NUM_ZOOM_STEPS-1);
2761 float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
2762
2763 camera_metadata_entry_t activePixelArraySize =
2764 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2765 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2766 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2767 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2768 if (mParameters.previewWidth >= mParameters.previewHeight) {
2769 zoomWidth = arrayWidth / zoomRatio;
2770 zoomHeight = zoomWidth *
2771 mParameters.previewHeight / mParameters.previewWidth;
2772 } else {
2773 zoomHeight = arrayHeight / zoomRatio;
2774 zoomWidth = zoomHeight *
2775 mParameters.previewWidth / mParameters.previewHeight;
2776 }
2777 zoomLeft = (arrayWidth - zoomWidth) / 2;
2778 zoomTop = (arrayHeight - zoomHeight) / 2;
2779
2780 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2781 res = updateEntry(request,
2782 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2783 if (res != OK) return res;
2784
2785 // TODO: Decide how to map recordingHint, or whether just to ignore it
2786
2787 uint8_t vstabMode = mParameters.videoStabilization ?
2788 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2789 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2790 res = updateEntry(request,
2791 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2792 &vstabMode, 1);
2793 if (res != OK) return res;
2794
2795 return OK;
2796}
2797
2798status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2799 uint32_t tag, const void *data, size_t data_count) {
2800 camera_metadata_entry_t entry;
2801 status_t res;
2802 res = find_camera_metadata_entry(buffer, tag, &entry);
2803 if (res == NAME_NOT_FOUND) {
2804 res = add_camera_metadata_entry(buffer,
2805 tag, data, data_count);
2806 } else if (res == OK) {
2807 res = update_camera_metadata_entry(buffer,
2808 entry.index, data, data_count, NULL);
2809 }
2810
2811 if (res != OK) {
2812 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2813 __FUNCTION__, get_camera_metadata_section_name(tag),
2814 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2815 }
2816 return res;
2817}
2818
2819status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2820 camera_metadata_entry_t entry;
2821 status_t res;
2822 res = find_camera_metadata_entry(buffer, tag, &entry);
2823 if (res == NAME_NOT_FOUND) {
2824 return OK;
2825 } else if (res != OK) {
2826 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2827 __FUNCTION__,
2828 get_camera_metadata_section_name(tag),
2829 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2830 return res;
2831 }
2832 res = delete_camera_metadata_entry(buffer, entry.index);
2833 if (res != OK) {
2834 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2835 __FUNCTION__,
2836 get_camera_metadata_section_name(tag),
2837 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2838 }
2839 return res;
2840}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002841int Camera2Client::formatStringToEnum(const char *format) {
2842 return
2843 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2844 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2845 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2846 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2847 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2848 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2849 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2850 HAL_PIXEL_FORMAT_YV12 : // YV12
2851 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2852 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2853 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2854 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2855 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2856 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2857 -1;
2858}
2859
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002860const char* Camera2Client::formatEnumToString(int format) {
2861 const char *fmt;
2862 switch(format) {
2863 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2864 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2865 break;
2866 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2867 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2868 break;
2869 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2870 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2871 break;
2872 case HAL_PIXEL_FORMAT_YV12: // YV12
2873 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2874 break;
2875 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2876 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2877 break;
2878 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2879 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2880 break;
2881 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2882 ALOGW("Raw sensor preview format requested.");
2883 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2884 break;
2885 default:
2886 ALOGE("%s: Unknown preview format: %x",
2887 __FUNCTION__, format);
2888 fmt = NULL;
2889 break;
2890 }
2891 return fmt;
2892}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002893
2894int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2895 return
2896 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2897 ANDROID_CONTROL_AWB_AUTO :
2898 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2899 ANDROID_CONTROL_AWB_INCANDESCENT :
2900 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2901 ANDROID_CONTROL_AWB_FLUORESCENT :
2902 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2903 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2904 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2905 ANDROID_CONTROL_AWB_DAYLIGHT :
2906 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2907 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2908 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2909 ANDROID_CONTROL_AWB_TWILIGHT :
2910 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2911 ANDROID_CONTROL_AWB_SHADE :
2912 -1;
2913}
2914
2915int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2916 return
2917 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2918 ANDROID_CONTROL_EFFECT_OFF :
2919 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2920 ANDROID_CONTROL_EFFECT_MONO :
2921 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2922 ANDROID_CONTROL_EFFECT_NEGATIVE :
2923 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2924 ANDROID_CONTROL_EFFECT_SOLARIZE :
2925 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2926 ANDROID_CONTROL_EFFECT_SEPIA :
2927 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2928 ANDROID_CONTROL_EFFECT_POSTERIZE :
2929 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2930 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2931 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2932 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2933 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2934 ANDROID_CONTROL_EFFECT_AQUA :
2935 -1;
2936}
2937
2938int Camera2Client::abModeStringToEnum(const char *abMode) {
2939 return
2940 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2941 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2942 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2943 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2944 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2945 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2946 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2947 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2948 -1;
2949}
2950
2951int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2952 return
2953 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2954 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2955 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2956 ANDROID_CONTROL_SCENE_MODE_ACTION :
2957 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2958 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2959 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2960 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2961 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2962 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2963 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2964 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2965 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2966 ANDROID_CONTROL_SCENE_MODE_THEATRE :
2967 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2968 ANDROID_CONTROL_SCENE_MODE_BEACH :
2969 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2970 ANDROID_CONTROL_SCENE_MODE_SNOW :
2971 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2972 ANDROID_CONTROL_SCENE_MODE_SUNSET :
2973 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2974 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2975 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2976 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2977 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2978 ANDROID_CONTROL_SCENE_MODE_SPORTS :
2979 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2980 ANDROID_CONTROL_SCENE_MODE_PARTY :
2981 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2982 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2983 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2984 ANDROID_CONTROL_SCENE_MODE_BARCODE:
2985 -1;
2986}
2987
2988Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
2989 const char *flashMode) {
2990 return
2991 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2992 Parameters::FLASH_MODE_OFF :
2993 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2994 Parameters::FLASH_MODE_AUTO :
2995 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2996 Parameters::FLASH_MODE_ON :
2997 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2998 Parameters::FLASH_MODE_RED_EYE :
2999 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3000 Parameters::FLASH_MODE_TORCH :
3001 Parameters::FLASH_MODE_INVALID;
3002}
3003
3004Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3005 const char *focusMode) {
3006 return
3007 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3008 Parameters::FOCUS_MODE_AUTO :
3009 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3010 Parameters::FOCUS_MODE_INFINITY :
3011 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3012 Parameters::FOCUS_MODE_MACRO :
3013 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3014 Parameters::FOCUS_MODE_FIXED :
3015 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3016 Parameters::FOCUS_MODE_EDOF :
3017 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3018 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3019 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3020 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3021 Parameters::FOCUS_MODE_INVALID;
3022}
3023
3024status_t Camera2Client::parseAreas(const char *areasCStr,
3025 Vector<Parameters::Area> *areas) {
3026 static const size_t NUM_FIELDS = 5;
3027 areas->clear();
3028 if (areasCStr == NULL) {
3029 // If no key exists, use default (0,0,0,0,0)
3030 areas->push();
3031 return OK;
3032 }
3033 String8 areasStr(areasCStr);
3034 ssize_t areaStart = areasStr.find("(", 0) + 1;
3035 while (areaStart != 0) {
3036 const char* area = areasStr.string() + areaStart;
3037 char *numEnd;
3038 int vals[NUM_FIELDS];
3039 for (size_t i = 0; i < NUM_FIELDS; i++) {
3040 errno = 0;
3041 vals[i] = strtol(area, &numEnd, 10);
3042 if (errno || numEnd == area) return BAD_VALUE;
3043 area = numEnd + 1;
3044 }
3045 areas->push(Parameters::Area(
3046 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3047 areaStart = areasStr.find("(", areaStart) + 1;
3048 }
3049 return OK;
3050}
3051
3052status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3053 size_t maxRegions) {
3054 // Definition of valid area can be found in
3055 // include/camera/CameraParameters.h
3056 if (areas.size() == 0) return BAD_VALUE;
3057 if (areas.size() == 1) {
3058 if (areas[0].left == 0 &&
3059 areas[0].top == 0 &&
3060 areas[0].right == 0 &&
3061 areas[0].bottom == 0 &&
3062 areas[0].weight == 0) {
3063 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3064 return OK;
3065 }
3066 }
3067 if (areas.size() > maxRegions) {
3068 ALOGE("%s: Too many areas requested: %d",
3069 __FUNCTION__, areas.size());
3070 return BAD_VALUE;
3071 }
3072
3073 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3074 a != areas.end(); a++) {
3075 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3076 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3077 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3078 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3079 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3080 if (a->left >= a->right) return BAD_VALUE;
3081 if (a->top >= a->bottom) return BAD_VALUE;
3082 }
3083 return OK;
3084}
3085
3086bool Camera2Client::boolFromString(const char *boolStr) {
3087 return !boolStr ? false :
3088 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3089 false;
3090}
3091
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003092int Camera2Client::degToTransform(int degrees, bool mirror) {
3093 if (!mirror) {
3094 if (degrees == 0) return 0;
3095 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3096 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3097 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3098 } else { // Do mirror (horizontal flip)
3099 if (degrees == 0) { // FLIP_H and ROT_0
3100 return HAL_TRANSFORM_FLIP_H;
3101 } else if (degrees == 90) { // FLIP_H and ROT_90
3102 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3103 } else if (degrees == 180) { // FLIP_H and ROT_180
3104 return HAL_TRANSFORM_FLIP_V;
3105 } else if (degrees == 270) { // FLIP_H and ROT_270
3106 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3107 }
3108 }
3109 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3110 return -1;
3111}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003112
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003113} // namespace android