blob: 9d904e8665b0aaa283a3710fc268b50c2cd36fd8 [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
27
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070028#include <math.h>
29
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030#include "Camera2Client.h"
31
32namespace android {
33
34#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
35#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
36
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037static int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
41static int getCallingUid() {
42 return IPCThreadState::self()->getCallingUid();
43}
44
45// Interface used by CameraService
46
47Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
48 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 int cameraId,
50 int cameraFacing,
51 int clientPid):
52 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070053 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070054 mState(NOT_INITIALIZED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070055 mPreviewStreamId(NO_STREAM),
56 mPreviewRequest(NULL),
57 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070058 mCaptureRequest(NULL),
59 mRecordingStreamId(NO_STREAM),
60 mRecordingRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070061{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070062 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070064 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065}
66
67status_t Camera2Client::initialize(camera_module_t *module)
68{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070069 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070 status_t res;
71
72 res = mDevice->initialize(module);
73 if (res != OK) {
74 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
75 __FUNCTION__, mCameraId, strerror(-res), res);
76 return NO_INIT;
77 }
78
79 res = buildDefaultParameters();
80 if (res != OK) {
81 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
82 __FUNCTION__, mCameraId, strerror(-res), res);
83 return NO_INIT;
84 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070085
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070086 if (gLogLevel >= 1) {
87 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
88 mCameraId);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070089 ALOGD("%s", mParamsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 }
91
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070092 mState = STOPPED;
93
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070094 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070095}
96
97Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070098 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -070099 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
100
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700101 mDestructionStarted = true;
102
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700104
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700105}
106
107status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700108 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700109 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700110 mCameraId,
111 getCameraClient()->asBinder().get(),
112 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700113 result.append(" State: ");
114#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
115
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700116 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700117
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700118 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700119 result.appendFormat(" Preview size: %d x %d\n",
120 mParameters.previewWidth, mParameters.previewHeight);
121 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700122 mParameters.previewFpsRange[0], mParameters.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700123 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
124 mParameters.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700125 result.appendFormat(" Preview transform: %x\n",
126 mParameters.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700127 result.appendFormat(" Picture size: %d x %d\n",
128 mParameters.pictureWidth, mParameters.pictureHeight);
129 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700130 mParameters.jpegThumbSize[0], mParameters.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700131 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
132 mParameters.jpegQuality, mParameters.jpegThumbQuality);
133 result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
134 result.appendFormat(" GPS tags %s\n",
135 mParameters.gpsEnabled ? "enabled" : "disabled");
136 if (mParameters.gpsEnabled) {
137 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700138 mParameters.gpsCoordinates[0], mParameters.gpsCoordinates[1],
139 mParameters.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140 result.appendFormat(" GPS timestamp: %lld\n",
141 mParameters.gpsTimestamp);
142 result.appendFormat(" GPS processing method: %s\n",
143 mParameters.gpsProcessingMethod.string());
144 }
145
146 result.append(" White balance mode: ");
147 switch (mParameters.wbMode) {
148 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
149 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
150 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
151 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
152 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
156 default: result.append("UNKNOWN\n");
157 }
158
159 result.append(" Effect mode: ");
160 switch (mParameters.effectMode) {
161 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
162 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
163 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
164 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
170 default: result.append("UNKNOWN\n");
171 }
172
173 result.append(" Antibanding mode: ");
174 switch (mParameters.antibandingMode) {
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
179 default: result.append("UNKNOWN\n");
180 }
181
182 result.append(" Scene mode: ");
183 switch (mParameters.sceneMode) {
184 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
185 result.append("AUTO\n"); break;
186 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
201 default: result.append("UNKNOWN\n");
202 }
203
204 result.append(" Flash mode: ");
205 switch (mParameters.flashMode) {
206 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
207 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
208 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
209 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
210 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
212 default: result.append("UNKNOWN\n");
213 }
214
215 result.append(" Focus mode: ");
216 switch (mParameters.focusMode) {
217 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
218 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
219 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
220 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
221 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
225 default: result.append("UNKNOWN\n");
226 }
227
228 result.append(" Focusing areas:\n");
229 for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
230 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
231 mParameters.focusingAreas[i].left,
232 mParameters.focusingAreas[i].top,
233 mParameters.focusingAreas[i].right,
234 mParameters.focusingAreas[i].bottom,
235 mParameters.focusingAreas[i].weight);
236 }
237
238 result.appendFormat(" Exposure compensation index: %d\n",
239 mParameters.exposureCompensation);
240
241 result.appendFormat(" AE lock %s, AWB lock %s\n",
242 mParameters.autoExposureLock ? "enabled" : "disabled",
243 mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
244
245 result.appendFormat(" Metering areas:\n");
246 for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
247 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
248 mParameters.meteringAreas[i].left,
249 mParameters.meteringAreas[i].top,
250 mParameters.meteringAreas[i].right,
251 mParameters.meteringAreas[i].bottom,
252 mParameters.meteringAreas[i].weight);
253 }
254
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700255 result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
256 result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700257 mParameters.videoHeight);
258
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700259 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700260 mParameters.recordingHint ? "set" : "not set");
261
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700262 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263 mParameters.videoStabilization ? "enabled" : "disabled");
264
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700265 result.append(" Current streams:\n");
266 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
267 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
268
269 result.append(" Current requests:\n");
270 if (mPreviewRequest != NULL) {
271 result.append(" Preview request:\n");
272 write(fd, result.string(), result.size());
273 dump_camera_metadata(mPreviewRequest, fd, 2);
274 } else {
275 result.append(" Preview request: undefined\n");
276 write(fd, result.string(), result.size());
277 }
278
279 if (mCaptureRequest != NULL) {
280 result = " Capture request:\n";
281 write(fd, result.string(), result.size());
282 dump_camera_metadata(mCaptureRequest, fd, 2);
283 } else {
284 result = " Capture request: undefined\n";
285 write(fd, result.string(), result.size());
286 }
287
288 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700289 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700290
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700291 status_t res = mDevice->dump(fd, args);
292 if (res != OK) {
293 result = String8::format(" Error dumping device: %s (%d)",
294 strerror(-res), res);
295 write(fd, result.string(), result.size());
296 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700297
298#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700299 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700300}
301
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700302const char* Camera2Client::getStateName(State state) {
303#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
304 switch(state) {
305 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
306 CASE_ENUM_TO_CHAR(STOPPED)
307 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
308 CASE_ENUM_TO_CHAR(PREVIEW)
309 CASE_ENUM_TO_CHAR(RECORD)
310 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
311 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
312 default:
313 return "Unknown state!";
314 break;
315 }
316#undef CASE_ENUM_TO_CHAR
317}
318
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700319// ICamera interface
320
321void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700322 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700323 Mutex::Autolock icl(mICameraLock);
324
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700325 if (mDevice == 0) return;
326
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700327 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700328
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700329 mDevice->waitUntilDrained();
330
331 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700332 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700333 mPreviewStreamId = NO_STREAM;
334 }
335
336 if (mCaptureStreamId != NO_STREAM) {
337 mDevice->deleteStream(mCaptureStreamId);
338 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700339 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700340
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700341 if (mRecordingStreamId != NO_STREAM) {
342 mDevice->deleteStream(mRecordingStreamId);
343 mRecordingStreamId = NO_STREAM;
344 }
345
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700346 CameraService::Client::disconnect();
347}
348
349status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700350 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700351
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700352 Mutex::Autolock icl(mICameraLock);
353
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700354 if (mClientPid != 0 && getCallingPid() != mClientPid) {
355 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
356 "current locked to pid %d", __FUNCTION__,
357 mCameraId, getCallingPid(), mClientPid);
358 return BAD_VALUE;
359 }
360
361 mClientPid = getCallingPid();
362 mCameraClient = client;
363
364 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700365}
366
367status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700368 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700369 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700370 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
371 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700372
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700373 if (mClientPid == 0) {
374 mClientPid = getCallingPid();
375 return OK;
376 }
377
378 if (mClientPid != getCallingPid()) {
379 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
380 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
381 return EBUSY;
382 }
383
384 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700385}
386
387status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700388 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700389 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700390 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
391 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700392
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700393 // TODO: Check for uninterruptable conditions
394
395 if (mClientPid == getCallingPid()) {
396 mClientPid = 0;
397 mCameraClient.clear();
398 return OK;
399 }
400
401 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
402 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
403 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700404}
405
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700406status_t Camera2Client::setPreviewDisplay(
407 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700408 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700409 Mutex::Autolock icl(mICameraLock);
410
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700411 sp<IBinder> binder;
412 sp<ANativeWindow> window;
413 if (surface != 0) {
414 binder = surface->asBinder();
415 window = surface;
416 }
417
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700418 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700419}
420
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700421status_t Camera2Client::setPreviewTexture(
422 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700423 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700424 Mutex::Autolock icl(mICameraLock);
425
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700426 sp<IBinder> binder;
427 sp<ANativeWindow> window;
428 if (surfaceTexture != 0) {
429 binder = surfaceTexture->asBinder();
430 window = new SurfaceTextureClient(surfaceTexture);
431 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700432 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700433}
434
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700435status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700436 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700437 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700438 status_t res;
439
440 if (binder == mPreviewSurface) {
441 return NO_ERROR;
442 }
443
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700444 switch (mState) {
445 case NOT_INITIALIZED:
446 case RECORD:
447 case STILL_CAPTURE:
448 case VIDEO_SNAPSHOT:
449 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
450 __FUNCTION__, mCameraId, getStateName(mState));
451 return INVALID_OPERATION;
452 case STOPPED:
453 case WAITING_FOR_PREVIEW_WINDOW:
454 // OK
455 break;
456 case PREVIEW:
457 // Already running preview - need to stop and create a new stream
458 // TODO: Optimize this so that we don't wait for old stream to drain
459 // before spinning up new stream
460 mDevice->setStreamingRequest(NULL);
461 mState = WAITING_FOR_PREVIEW_WINDOW;
462 break;
463 }
464
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700465 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700466 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700467 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700468 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
469 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700470 return res;
471 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700472 res = mDevice->deleteStream(mPreviewStreamId);
473 if (res != OK) {
474 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
475 __FUNCTION__, strerror(-res), res);
476 return res;
477 }
478 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700479 }
480
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700481 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700482 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700483
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700484 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700485 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700486 }
487
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700488 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700489}
490
491void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700492 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700493 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700494}
495
496status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700497 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700498 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700499 return startPreviewLocked();
500}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700501
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700502status_t Camera2Client::startPreviewLocked() {
503 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700504 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700505 if (mState >= PREVIEW) {
506 ALOGE("%s: Can't start preview in state %s",
507 __FUNCTION__, getStateName(mState));
508 return INVALID_OPERATION;
509 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700510
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700511 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700512 mState = WAITING_FOR_PREVIEW_WINDOW;
513 return OK;
514 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700515 mState = STOPPED;
516
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700517 Mutex::Autolock pl(mParamsLock);
518
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700519 res = updatePreviewStream();
520 if (res != OK) {
521 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
522 __FUNCTION__, mCameraId, strerror(-res), res);
523 return res;
524 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700525
526 if (mPreviewRequest == NULL) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700527 res = updatePreviewRequest();
528 if (res != OK) {
529 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
530 __FUNCTION__, mCameraId, strerror(-res), res);
531 return res;
532 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 }
534
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700535 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700536 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700537 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700538 if (res != OK) {
539 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
540 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700541 return res;
542 }
543 res = sort_camera_metadata(mPreviewRequest);
544 if (res != OK) {
545 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
546 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700547 return res;
548 }
549
550 res = mDevice->setStreamingRequest(mPreviewRequest);
551 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700552 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
553 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700554 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700555 return res;
556 }
557 mState = PREVIEW;
558
559 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700560}
561
562void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700563 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700564 Mutex::Autolock icl(mICameraLock);
565 stopPreviewLocked();
566}
567
568void Camera2Client::stopPreviewLocked() {
569 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700570 switch (mState) {
571 case NOT_INITIALIZED:
572 ALOGE("%s: Camera %d: Call before initialized",
573 __FUNCTION__, mCameraId);
574 break;
575 case STOPPED:
576 break;
577 case STILL_CAPTURE:
578 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
579 __FUNCTION__, mCameraId);
580 break;
581 case RECORD:
582 // TODO: Handle record stop here
583 case PREVIEW:
584 mDevice->setStreamingRequest(NULL);
585 case WAITING_FOR_PREVIEW_WINDOW:
586 mState = STOPPED;
587 break;
588 default:
589 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
590 mState);
591 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700592}
593
594bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700595 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700596 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700597 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700598}
599
600status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700601 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700602 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700603 return BAD_VALUE;
604}
605
606status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700607 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700608 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700609 status_t res;
610 switch (mState) {
611 case STOPPED:
612 res = startPreviewLocked();
613 if (res != OK) return res;
614 break;
615 case PREVIEW:
616 // Ready to go
617 break;
618 case RECORD:
619 case VIDEO_SNAPSHOT:
620 // OK to call this when recording is already on
621 return OK;
622 break;
623 default:
624 ALOGE("%s: Camera %d: Can't start recording in state %s",
625 __FUNCTION__, mCameraId, getStateName(mState));
626 return INVALID_OPERATION;
627 };
628
629 Mutex::Autolock pl(mParamsLock);
630
631 res = updateRecordingStream();
632 if (res != OK) {
633 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
634 __FUNCTION__, mCameraId, strerror(-res), res);
635 return res;
636 }
637
638 if (mRecordingRequest == NULL) {
639 res = updateRecordingRequest();
640 if (res != OK) {
641 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
642 __FUNCTION__, mCameraId, strerror(-res), res);
643 return res;
644 }
645 }
646
647 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
648 res = updateEntry(mRecordingRequest,
649 ANDROID_REQUEST_OUTPUT_STREAMS,
650 outputStreams, 2);
651 if (res != OK) {
652 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
653 __FUNCTION__, mCameraId, strerror(-res), res);
654 return res;
655 }
656 res = sort_camera_metadata(mRecordingRequest);
657 if (res != OK) {
658 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
659 __FUNCTION__, mCameraId, strerror(-res), res);
660 return res;
661 }
662
663 res = mDevice->setStreamingRequest(mRecordingRequest);
664 if (res != OK) {
665 ALOGE("%s: Camera %d: Unable to set recording request to start "
666 "recording: %s (%d)", __FUNCTION__, mCameraId,
667 strerror(-res), res);
668 return res;
669 }
670 mState = RECORD;
671
672 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700673}
674
675void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700676 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700677 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700678 status_t res;
679 switch (mState) {
680 case RECORD:
681 // OK to stop
682 break;
683 case STOPPED:
684 case PREVIEW:
685 case STILL_CAPTURE:
686 case VIDEO_SNAPSHOT:
687 default:
688 ALOGE("%s: Camera %d: Can't stop recording in state %s",
689 __FUNCTION__, mCameraId, getStateName(mState));
690 return;
691 };
692
693 // Back to preview. Since record can only be reached through preview,
694 // all preview stream setup should be up to date.
695 res = mDevice->setStreamingRequest(mPreviewRequest);
696 if (res != OK) {
697 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
698 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
699 return;
700 }
701
702 // TODO: Should recording heap be freed? Can't do it yet since requests
703 // could still be in flight.
704
705 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700706}
707
708bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700709 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700710 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700711 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700712}
713
714void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700715 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700716 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700717 // Make sure this is for the current heap
718 ssize_t offset;
719 size_t size;
720 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
721 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
722 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
723 "(got %x, expected %x)", __FUNCTION__, mCameraId,
724 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
725 return;
726 }
727 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700728}
729
730status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700731 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700732 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700733 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700734}
735
736status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700737 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700738 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700739 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700740}
741
742status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700743 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700744 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700745 status_t res;
746
747 switch (mState) {
748 case NOT_INITIALIZED:
749 case STOPPED:
750 case WAITING_FOR_PREVIEW_WINDOW:
751 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
752 __FUNCTION__, mCameraId);
753 return INVALID_OPERATION;
754 case PREVIEW:
755 case RECORD:
756 // Good to go for takePicture
757 break;
758 case STILL_CAPTURE:
759 case VIDEO_SNAPSHOT:
760 ALOGE("%s: Camera %d: Already taking a picture",
761 __FUNCTION__, mCameraId);
762 return INVALID_OPERATION;
763 }
764
765 Mutex::Autolock pl(mParamsLock);
766
767 res = updateCaptureStream();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700768 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700769 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
770 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700771 return res;
772 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700773
774 if (mCaptureRequest == NULL) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700775 res = updateCaptureRequest();
776 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700777 ALOGE("%s: Camera %d: Can't create still image capture request: "
778 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700779 return res;
780 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700781 }
782
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700783 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700784 if (mState == PREVIEW) {
785 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
786 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
787 &streamIds, 2);
788 } else if (mState == RECORD) {
789 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
790 mCaptureStreamId };
791 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
792 &streamIds, 3);
793 }
794
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700795 if (res != OK) {
796 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
797 "%s (%d)",
798 __FUNCTION__, mCameraId, strerror(-res), res);
799 return res;
800 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700801 res = sort_camera_metadata(mCaptureRequest);
802 if (res != OK) {
803 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
804 __FUNCTION__, mCameraId, strerror(-res), res);
805 return res;
806 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700807
808 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
809 if (captureCopy == NULL) {
810 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
811 __FUNCTION__, mCameraId);
812 return NO_MEMORY;
813 }
814
815 if (mState == PREVIEW) {
816 res = mDevice->setStreamingRequest(NULL);
817 if (res != OK) {
818 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
819 "%s (%d)",
820 __FUNCTION__, mCameraId, strerror(-res), res);
821 return res;
822 }
823 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700824 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700825 res = mDevice->capture(captureCopy);
826 if (res != OK) {
827 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
828 "%s (%d)",
829 __FUNCTION__, mCameraId, strerror(-res), res);
830 return res;
831 }
832
833 switch (mState) {
834 case PREVIEW:
835 mState = STILL_CAPTURE;
836 break;
837 case RECORD:
838 mState = VIDEO_SNAPSHOT;
839 break;
840 default:
841 ALOGE("%s: Camera %d: Unknown state for still capture!",
842 __FUNCTION__, mCameraId);
843 return INVALID_OPERATION;
844 }
845
846 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700847}
848
849status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700850 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700851 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700852 Mutex::Autolock pl(mParamsLock);
853 status_t res;
854
855 CameraParameters newParams(params);
856
857 // TODO: Currently ignoring any changes to supposedly read-only
858 // parameters such as supported preview sizes, etc. Should probably
859 // produce an error if they're changed.
860
861 /** Extract and verify new parameters */
862
863 size_t i;
864
865 // PREVIEW_SIZE
866 int previewWidth, previewHeight;
867 newParams.getPreviewSize(&previewWidth, &previewHeight);
868
869 if (previewWidth != mParameters.previewWidth ||
870 previewHeight != mParameters.previewHeight) {
871 if (mState >= PREVIEW) {
872 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700873 "is active! (Currently %d x %d, requested %d x %d",
874 __FUNCTION__,
875 mParameters.previewWidth, mParameters.previewHeight,
876 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700877 return BAD_VALUE;
878 }
879 camera_metadata_entry_t availablePreviewSizes =
880 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
881 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
882 if (availablePreviewSizes.data.i32[i] == previewWidth &&
883 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
884 }
885 if (i == availablePreviewSizes.count) {
886 ALOGE("%s: Requested preview size %d x %d is not supported",
887 __FUNCTION__, previewWidth, previewHeight);
888 return BAD_VALUE;
889 }
890 }
891
892 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700893 int previewFpsRange[2];
894 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700895 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700896 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
897 if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
898 previewFpsRange[1] != mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700899 fpsRangeChanged = true;
900 camera_metadata_entry_t availablePreviewFpsRanges =
901 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
902 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
903 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700904 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700905 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700906 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700907 break;
908 }
909 }
910 if (i == availablePreviewFpsRanges.count) {
911 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700912 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700913 return BAD_VALUE;
914 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700915 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700916 }
917
918 // PREVIEW_FORMAT
919 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
920 if (previewFormat != mParameters.previewFormat) {
921 if (mState >= PREVIEW) {
922 ALOGE("%s: Preview format cannot be updated when preview "
923 "is active!", __FUNCTION__);
924 return BAD_VALUE;
925 }
926 camera_metadata_entry_t availableFormats =
927 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
928 for (i = 0; i < availableFormats.count; i++) {
929 if (availableFormats.data.i32[i] == previewFormat) break;
930 }
931 if (i == availableFormats.count) {
932 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
933 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
934 return BAD_VALUE;
935 }
936 }
937
938 // PREVIEW_FRAME_RATE
939 // Deprecated, only use if the preview fps range is unchanged this time.
940 // The single-value FPS is the same as the minimum of the range.
941 if (!fpsRangeChanged) {
942 previewFps = newParams.getPreviewFrameRate();
943 if (previewFps != mParameters.previewFps) {
944 camera_metadata_entry_t availableFrameRates =
945 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
946 for (i = 0; i < availableFrameRates.count; i+=2) {
947 if (availableFrameRates.data.i32[i] == previewFps) break;
948 }
949 if (i == availableFrameRates.count) {
950 ALOGE("%s: Requested preview frame rate %d is not supported",
951 __FUNCTION__, previewFps);
952 return BAD_VALUE;
953 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700954 previewFpsRange[0] = availableFrameRates.data.i32[i];
955 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700956 }
957 }
958
959 // PICTURE_SIZE
960 int pictureWidth, pictureHeight;
961 newParams.getPictureSize(&pictureWidth, &pictureHeight);
962 if (pictureWidth == mParameters.pictureWidth ||
963 pictureHeight == mParameters.pictureHeight) {
964 camera_metadata_entry_t availablePictureSizes =
965 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
966 for (i = 0; i < availablePictureSizes.count; i+=2) {
967 if (availablePictureSizes.data.i32[i] == pictureWidth &&
968 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
969 }
970 if (i == availablePictureSizes.count) {
971 ALOGE("%s: Requested picture size %d x %d is not supported",
972 __FUNCTION__, pictureWidth, pictureHeight);
973 return BAD_VALUE;
974 }
975 }
976
977 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700978 int jpegThumbSize[2];
979 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700980 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700981 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700982 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700983 if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
984 jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700985 camera_metadata_entry_t availableJpegThumbSizes =
986 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
987 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700988 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
989 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700990 break;
991 }
992 }
993 if (i == availableJpegThumbSizes.count) {
994 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700995 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700996 return BAD_VALUE;
997 }
998 }
999
1000 // JPEG_THUMBNAIL_QUALITY
1001 int jpegThumbQuality =
1002 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1003 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1004 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1005 __FUNCTION__, jpegThumbQuality);
1006 return BAD_VALUE;
1007 }
1008
1009 // JPEG_QUALITY
1010 int jpegQuality =
1011 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1012 if (jpegQuality < 0 || jpegQuality > 100) {
1013 ALOGE("%s: Requested JPEG quality %d is not supported",
1014 __FUNCTION__, jpegQuality);
1015 return BAD_VALUE;
1016 }
1017
1018 // ROTATION
1019 int jpegRotation =
1020 newParams.getInt(CameraParameters::KEY_ROTATION);
1021 if (jpegRotation != 0 &&
1022 jpegRotation != 90 &&
1023 jpegRotation != 180 &&
1024 jpegRotation != 270) {
1025 ALOGE("%s: Requested picture rotation angle %d is not supported",
1026 __FUNCTION__, jpegRotation);
1027 return BAD_VALUE;
1028 }
1029
1030 // GPS
1031 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001032 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001033 int64_t gpsTimestamp = 0;
1034 String8 gpsProcessingMethod;
1035 const char *gpsLatStr =
1036 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1037 if (gpsLatStr != NULL) {
1038 const char *gpsLongStr =
1039 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1040 const char *gpsAltitudeStr =
1041 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1042 const char *gpsTimeStr =
1043 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1044 const char *gpsProcMethodStr =
1045 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1046 if (gpsLongStr == NULL ||
1047 gpsAltitudeStr == NULL ||
1048 gpsTimeStr == NULL ||
1049 gpsProcMethodStr == NULL) {
1050 ALOGE("%s: Incomplete set of GPS parameters provided",
1051 __FUNCTION__);
1052 return BAD_VALUE;
1053 }
1054 char *endPtr;
1055 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001056 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001057 if (errno || endPtr == gpsLatStr) {
1058 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1059 return BAD_VALUE;
1060 }
1061 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001062 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001063 if (errno || endPtr == gpsLongStr) {
1064 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1065 return BAD_VALUE;
1066 }
1067 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001068 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001069 if (errno || endPtr == gpsAltitudeStr) {
1070 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1071 gpsAltitudeStr);
1072 return BAD_VALUE;
1073 }
1074 errno = 0;
1075 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1076 if (errno || endPtr == gpsTimeStr) {
1077 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1078 return BAD_VALUE;
1079 }
1080 gpsProcessingMethod = gpsProcMethodStr;
1081
1082 gpsEnabled = true;
1083 }
1084
1085 // WHITE_BALANCE
1086 int wbMode = wbModeStringToEnum(
1087 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1088 if (wbMode != mParameters.wbMode) {
1089 camera_metadata_entry_t availableWbModes =
1090 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1091 for (i = 0; i < availableWbModes.count; i++) {
1092 if (wbMode == availableWbModes.data.u8[i]) break;
1093 }
1094 if (i == availableWbModes.count) {
1095 ALOGE("%s: Requested white balance mode %s is not supported",
1096 __FUNCTION__,
1097 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1098 return BAD_VALUE;
1099 }
1100 }
1101
1102 // EFFECT
1103 int effectMode = effectModeStringToEnum(
1104 newParams.get(CameraParameters::KEY_EFFECT) );
1105 if (effectMode != mParameters.effectMode) {
1106 camera_metadata_entry_t availableEffectModes =
1107 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1108 for (i = 0; i < availableEffectModes.count; i++) {
1109 if (effectMode == availableEffectModes.data.u8[i]) break;
1110 }
1111 if (i == availableEffectModes.count) {
1112 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1113 __FUNCTION__,
1114 newParams.get(CameraParameters::KEY_EFFECT) );
1115 return BAD_VALUE;
1116 }
1117 }
1118
1119 // ANTIBANDING
1120 int antibandingMode = abModeStringToEnum(
1121 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1122 if (antibandingMode != mParameters.antibandingMode) {
1123 camera_metadata_entry_t availableAbModes =
1124 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1125 for (i = 0; i < availableAbModes.count; i++) {
1126 if (antibandingMode == availableAbModes.data.u8[i]) break;
1127 }
1128 if (i == availableAbModes.count) {
1129 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1130 __FUNCTION__,
1131 newParams.get(CameraParameters::KEY_ANTIBANDING));
1132 return BAD_VALUE;
1133 }
1134 }
1135
1136 // SCENE_MODE
1137 int sceneMode = sceneModeStringToEnum(
1138 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1139 if (sceneMode != mParameters.sceneMode) {
1140 camera_metadata_entry_t availableSceneModes =
1141 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1142 for (i = 0; i < availableSceneModes.count; i++) {
1143 if (sceneMode == availableSceneModes.data.u8[i]) break;
1144 }
1145 if (i == availableSceneModes.count) {
1146 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1147 __FUNCTION__,
1148 newParams.get(CameraParameters::KEY_SCENE_MODE));
1149 return BAD_VALUE;
1150 }
1151 }
1152
1153 // FLASH_MODE
1154 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1155 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1156 if (flashMode != mParameters.flashMode) {
1157 camera_metadata_entry_t flashAvailable =
1158 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1159 if (!flashAvailable.data.u8[0] &&
1160 flashMode != Parameters::FLASH_MODE_OFF) {
1161 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1162 "No flash on device", __FUNCTION__,
1163 newParams.get(CameraParameters::KEY_FLASH_MODE));
1164 return BAD_VALUE;
1165 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1166 camera_metadata_entry_t availableAeModes =
1167 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1168 for (i = 0; i < availableAeModes.count; i++) {
1169 if (flashMode == availableAeModes.data.u8[i]) break;
1170 }
1171 if (i == availableAeModes.count) {
1172 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1173 __FUNCTION__,
1174 newParams.get(CameraParameters::KEY_FLASH_MODE));
1175 return BAD_VALUE;
1176 }
1177 } else if (flashMode == -1) {
1178 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1179 __FUNCTION__,
1180 newParams.get(CameraParameters::KEY_FLASH_MODE));
1181 return BAD_VALUE;
1182 }
1183 }
1184
1185 // FOCUS_MODE
1186 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1187 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1188 if (focusMode != mParameters.focusMode) {
1189 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1190 camera_metadata_entry_t minFocusDistance =
1191 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1192 if (minFocusDistance.data.f[0] == 0) {
1193 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1194 "fixed focus lens",
1195 __FUNCTION__,
1196 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1197 return BAD_VALUE;
1198 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1199 camera_metadata_entry_t availableFocusModes =
1200 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1201 for (i = 0; i < availableFocusModes.count; i++) {
1202 if (focusMode == availableFocusModes.data.u8[i]) break;
1203 }
1204 if (i == availableFocusModes.count) {
1205 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1206 __FUNCTION__,
1207 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1208 return BAD_VALUE;
1209 }
1210 }
1211 }
1212 }
1213
1214 // FOCUS_AREAS
1215 Vector<Parameters::Area> focusingAreas;
1216 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1217 &focusingAreas);
1218 size_t max3aRegions =
1219 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1220 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1221 if (res != OK) {
1222 ALOGE("%s: Requested focus areas are malformed: %s",
1223 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1224 return BAD_VALUE;
1225 }
1226
1227 // EXPOSURE_COMPENSATION
1228 int exposureCompensation =
1229 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1230 camera_metadata_entry_t exposureCompensationRange =
1231 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1232 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1233 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1234 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1235 __FUNCTION__, exposureCompensation);
1236 return BAD_VALUE;
1237 }
1238
1239 // AUTO_EXPOSURE_LOCK (always supported)
1240 bool autoExposureLock = boolFromString(
1241 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1242
1243 // AUTO_WHITEBALANCE_LOCK (always supported)
1244 bool autoWhiteBalanceLock = boolFromString(
1245 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1246
1247 // METERING_AREAS
1248 Vector<Parameters::Area> meteringAreas;
1249 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1250 &meteringAreas);
1251 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1252 if (res != OK) {
1253 ALOGE("%s: Requested metering areas are malformed: %s",
1254 __FUNCTION__,
1255 newParams.get(CameraParameters::KEY_METERING_AREAS));
1256 return BAD_VALUE;
1257 }
1258
1259 // ZOOM
1260 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1261 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1262 ALOGE("%s: Requested zoom level %d is not supported",
1263 __FUNCTION__, zoom);
1264 return BAD_VALUE;
1265 }
1266
1267 // VIDEO_SIZE
1268 int videoWidth, videoHeight;
1269 newParams.getVideoSize(&videoWidth, &videoHeight);
1270 if (videoWidth != mParameters.videoWidth ||
1271 videoHeight != mParameters.videoHeight) {
1272 if (mState == RECORD) {
1273 ALOGE("%s: Video size cannot be updated when recording is active!",
1274 __FUNCTION__);
1275 return BAD_VALUE;
1276 }
1277 camera_metadata_entry_t availableVideoSizes =
1278 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1279 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1280 if (availableVideoSizes.data.i32[i] == videoWidth &&
1281 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1282 }
1283 if (i == availableVideoSizes.count) {
1284 ALOGE("%s: Requested video size %d x %d is not supported",
1285 __FUNCTION__, videoWidth, videoHeight);
1286 return BAD_VALUE;
1287 }
1288 }
1289
1290 // RECORDING_HINT (always supported)
1291 bool recordingHint = boolFromString(
1292 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1293
1294 // VIDEO_STABILIZATION
1295 bool videoStabilization = boolFromString(
1296 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1297 camera_metadata_entry_t availableVideoStabilizationModes =
1298 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1299 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1300 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1301 }
1302
1303 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001304
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001305 mParameters.previewWidth = previewWidth;
1306 mParameters.previewHeight = previewHeight;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001307 mParameters.previewFpsRange[0] = previewFpsRange[0];
1308 mParameters.previewFpsRange[1] = previewFpsRange[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001309 mParameters.previewFps = previewFps;
1310 mParameters.previewFormat = previewFormat;
1311
1312 mParameters.pictureWidth = pictureWidth;
1313 mParameters.pictureHeight = pictureHeight;
1314
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001315 mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1316 mParameters.jpegThumbSize[1] = jpegThumbSize[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001317 mParameters.jpegQuality = jpegQuality;
1318 mParameters.jpegThumbQuality = jpegThumbQuality;
1319
1320 mParameters.gpsEnabled = gpsEnabled;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001321 mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1322 mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1323 mParameters.gpsCoordinates[2] = gpsCoordinates[2];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001324 mParameters.gpsTimestamp = gpsTimestamp;
1325 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1326
1327 mParameters.wbMode = wbMode;
1328 mParameters.effectMode = effectMode;
1329 mParameters.antibandingMode = antibandingMode;
1330 mParameters.sceneMode = sceneMode;
1331
1332 mParameters.flashMode = flashMode;
1333 mParameters.focusMode = focusMode;
1334
1335 mParameters.focusingAreas = focusingAreas;
1336 mParameters.exposureCompensation = exposureCompensation;
1337 mParameters.autoExposureLock = autoExposureLock;
1338 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1339 mParameters.meteringAreas = meteringAreas;
1340 mParameters.zoom = zoom;
1341
1342 mParameters.videoWidth = videoWidth;
1343 mParameters.videoHeight = videoHeight;
1344
1345 mParameters.recordingHint = recordingHint;
1346 mParameters.videoStabilization = videoStabilization;
1347
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001348 res = updatePreviewRequest();
1349 if (res != OK) {
1350 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1351 __FUNCTION__, mCameraId, strerror(-res), res);
1352 return res;
1353 }
1354 res = updateCaptureRequest();
1355 if (res != OK) {
1356 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1357 __FUNCTION__, mCameraId, strerror(-res), res);
1358 return res;
1359 }
1360
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001361 res = updateRecordingRequest();
1362 if (res != OK) {
1363 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1364 __FUNCTION__, mCameraId, strerror(-res), res);
1365 return res;
1366 }
1367
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001368 if (mState == PREVIEW) {
1369 res = mDevice->setStreamingRequest(mPreviewRequest);
1370 if (res != OK) {
1371 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1372 __FUNCTION__, mCameraId, strerror(-res), res);
1373 return res;
1374 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001375 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1376 res = mDevice->setStreamingRequest(mRecordingRequest);
1377 if (res != OK) {
1378 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1379 __FUNCTION__, mCameraId, strerror(-res), res);
1380 return res;
1381 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001382 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001383
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001384 mParamsFlattened = params;
1385
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001386 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001387}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001388
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001389String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001390 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001391 Mutex::Autolock icl(mICameraLock);
1392
1393 Mutex::Autolock pl(mParamsLock);
1394
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001395 // TODO: Deal with focus distances
1396 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001397}
1398
1399status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001400 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001401 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001402
1403 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1404 cmd, arg1, arg2);
1405
1406 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
1407 int transform = degToTransform(arg1,
1408 mCameraFacing == CAMERA_FACING_FRONT);
1409 if (transform == -1) {
1410 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1411 __FUNCTION__, mCameraId, arg1);
1412 return BAD_VALUE;
1413 }
1414 if (transform != mParameters.previewTransform &&
1415 mPreviewStreamId != NO_STREAM) {
1416 mDevice->setStreamTransform(mPreviewStreamId, transform);
1417 }
1418 mParameters.previewTransform = transform;
1419 return OK;
1420 }
1421
1422 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1423 mCameraId, cmd, arg1, arg2);
1424
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001425 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001426}
1427
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001428/** Device-related methods */
1429
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001430void Camera2Client::onCaptureAvailable() {
1431 ATRACE_CALL();
1432 status_t res;
1433 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001434 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1435
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001436 CpuConsumer::LockedBuffer imgBuffer;
1437 {
1438 Mutex::Autolock icl(mICameraLock);
1439
1440 // TODO: Signal errors here upstream
1441 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1442 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1443 __FUNCTION__, mCameraId);
1444 return;
1445 }
1446
1447 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1448 if (res != OK) {
1449 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1450 __FUNCTION__, mCameraId, strerror(-res), res);
1451 return;
1452 }
1453
1454 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1455 ALOGE("%s: Camera %d: Unexpected format for still image: "
1456 "%x, expected %x", __FUNCTION__, mCameraId,
1457 imgBuffer.format,
1458 HAL_PIXEL_FORMAT_BLOB);
1459 mCaptureConsumer->unlockBuffer(imgBuffer);
1460 return;
1461 }
1462
1463 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001464 void* captureMemory = mCaptureHeap->mHeap->getBase();
1465 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001466 memcpy(captureMemory, imgBuffer.data, size);
1467
1468 mCaptureConsumer->unlockBuffer(imgBuffer);
1469
1470 currentClient = mCameraClient;
1471 switch (mState) {
1472 case STILL_CAPTURE:
1473 mState = STOPPED;
1474 break;
1475 case VIDEO_SNAPSHOT:
1476 mState = RECORD;
1477 break;
1478 default:
1479 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1480 mCameraId, mState);
1481 break;
1482 }
1483 }
1484 // Call outside mICameraLock to allow re-entrancy from notification
1485 if (currentClient != 0) {
1486 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001487 mCaptureHeap->mBuffers[0], NULL);
1488 }
1489}
1490
1491void Camera2Client::onRecordingFrameAvailable() {
1492 ATRACE_CALL();
1493 status_t res;
1494 sp<ICameraClient> currentClient;
1495 size_t heapIdx = 0;
1496 nsecs_t timestamp;
1497 {
1498 Mutex::Autolock icl(mICameraLock);
1499 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001500 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001501 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001502 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1503 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001504 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001505 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001506 }
1507
1508 CpuConsumer::LockedBuffer imgBuffer;
1509 res = mRecordingConsumer->lockNextBuffer(&imgBuffer);
1510 if (res != OK) {
1511 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1512 __FUNCTION__, mCameraId, strerror(-res), res);
1513 return;
1514 }
1515
1516 if (imgBuffer.format != (int)kRecordingFormat) {
1517 ALOGE("%s: Camera %d: Unexpected recording format: %x",
1518 __FUNCTION__, mCameraId, imgBuffer.format);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001519 discardData = true;
1520 }
1521
1522 if (discardData) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001523 mRecordingConsumer->unlockBuffer(imgBuffer);
1524 return;
1525 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001526
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001527 size_t bufferSize = imgBuffer.width * imgBuffer.height * 3 / 2;
1528
1529 if (mRecordingHeap == 0 ||
1530 bufferSize >
1531 mRecordingHeap->mHeap->getSize() / kRecordingHeapCount) {
1532 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1533 "size %d bytes", __FUNCTION__, mCameraId,
1534 kRecordingHeapCount, bufferSize);
1535 if (mRecordingHeap != 0) {
1536 ALOGV("%s: Camera %d: Previous heap has size %d "
1537 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1538 mRecordingHeap->mHeap->getSize(),
1539 bufferSize * kRecordingHeapCount);
1540 }
1541 // Need to allocate memory for heap
1542 mRecordingHeap.clear();
1543
1544 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1545 "Camera2Client::RecordingHeap");
1546 if (mRecordingHeap->mHeap->getSize() == 0) {
1547 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1548 __FUNCTION__, mCameraId);
1549 mRecordingConsumer->unlockBuffer(imgBuffer);
1550 return;
1551 }
1552 mRecordingHeapHead = 0;
1553 mRecordingHeapFree = kRecordingHeapCount;
1554 }
1555
1556 // TODO: Optimize this to avoid memcopy
1557 if ( mRecordingHeapFree == 0) {
1558 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1559 __FUNCTION__, mCameraId);
1560 mRecordingConsumer->unlockBuffer(imgBuffer);
1561 return;
1562 }
1563 heapIdx = mRecordingHeapHead;
1564 timestamp = imgBuffer.timestamp;
1565 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1566 mRecordingHeapFree--;
1567
1568 ALOGV("%s: Camera %d: Timestamp %lld",
1569 __FUNCTION__, mCameraId, timestamp);
1570
1571 ssize_t offset;
1572 size_t size;
1573 sp<IMemoryHeap> heap =
1574 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1575 &size);
1576
1577 memcpy((uint8_t*)heap->getBase() + offset, imgBuffer.data, size);
1578
1579 mRecordingConsumer->unlockBuffer(imgBuffer);
1580
1581 currentClient = mCameraClient;
1582 }
1583 // Call outside mICameraLock to allow re-entrancy from notification
1584 if (currentClient != 0) {
1585 currentClient->dataCallbackTimestamp(timestamp,
1586 CAMERA_MSG_VIDEO_FRAME,
1587 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001588 }
1589}
1590
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001591camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1592 size_t minCount, size_t maxCount) {
1593 status_t res;
1594 camera_metadata_entry_t entry;
1595 res = find_camera_metadata_entry(mDevice->info(),
1596 tag,
1597 &entry);
1598 if (CC_UNLIKELY( res != OK )) {
1599 const char* tagSection = get_camera_metadata_section_name(tag);
1600 if (tagSection == NULL) tagSection = "<unknown>";
1601 const char* tagName = get_camera_metadata_tag_name(tag);
1602 if (tagName == NULL) tagName = "<unknown>";
1603
1604 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1605 tagSection, tagName, tag, strerror(-res), res);
1606 entry.count = 0;
1607 entry.data.u8 = NULL;
1608 } else if (CC_UNLIKELY(
1609 (minCount != 0 && entry.count < minCount) ||
1610 (maxCount != 0 && entry.count > maxCount) ) ) {
1611 const char* tagSection = get_camera_metadata_section_name(tag);
1612 if (tagSection == NULL) tagSection = "<unknown>";
1613 const char* tagName = get_camera_metadata_tag_name(tag);
1614 if (tagName == NULL) tagName = "<unknown>";
1615 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1616 "Expected between %d and %d values, but got %d values",
1617 tagSection, tagName, tag, minCount, maxCount, entry.count);
1618 entry.count = 0;
1619 entry.data.u8 = NULL;
1620 }
1621
1622 return entry;
1623}
1624
1625/** Utility methods */
1626
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001627
1628status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001629 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001630 Mutex::Autolock pl(mParamsLock);
1631
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001632 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001633 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001634
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001635 camera_metadata_entry_t availableProcessedSizes =
1636 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1637 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001638
1639 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001640 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1641 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1642 mParameters.videoWidth = mParameters.previewWidth;
1643 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001644
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001645 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1646 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1647 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1648 String8::format("%dx%d",
1649 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001650 {
1651 String8 supportedPreviewSizes;
1652 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1653 if (i != 0) supportedPreviewSizes += ",";
1654 supportedPreviewSizes += String8::format("%dx%d",
1655 availableProcessedSizes.data.i32[i],
1656 availableProcessedSizes.data.i32[i+1]);
1657 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001658 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001659 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001660 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001661 supportedPreviewSizes);
1662 }
1663
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001664 camera_metadata_entry_t availableFpsRanges =
1665 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1666 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001667
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001668 mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1669 mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001670
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001671 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1672 String8::format("%d,%d",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001673 mParameters.previewFpsRange[0],
1674 mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001675
1676 {
1677 String8 supportedPreviewFpsRange;
1678 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1679 if (i != 0) supportedPreviewFpsRange += ",";
1680 supportedPreviewFpsRange += String8::format("(%d,%d)",
1681 availableFpsRanges.data.i32[i],
1682 availableFpsRanges.data.i32[i+1]);
1683 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001684 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001685 supportedPreviewFpsRange);
1686 }
1687
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001688 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1689 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1690 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001691
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001692 mParameters.previewTransform = degToTransform(0,
1693 mCameraFacing == CAMERA_FACING_FRONT);
1694
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001695 camera_metadata_entry_t availableFormats =
1696 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1697
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001698 {
1699 String8 supportedPreviewFormats;
1700 bool addComma = false;
1701 for (size_t i=0; i < availableFormats.count; i++) {
1702 if (addComma) supportedPreviewFormats += ",";
1703 addComma = true;
1704 switch (availableFormats.data.i32[i]) {
1705 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001706 supportedPreviewFormats +=
1707 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001708 break;
1709 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001710 supportedPreviewFormats +=
1711 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001712 break;
1713 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001714 supportedPreviewFormats +=
1715 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001716 break;
1717 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001718 supportedPreviewFormats +=
1719 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001720 break;
1721 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001722 supportedPreviewFormats +=
1723 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001724 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001725 case HAL_PIXEL_FORMAT_RGBA_8888:
1726 supportedPreviewFormats +=
1727 CameraParameters::PIXEL_FORMAT_RGBA8888;
1728 break;
1729 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001730 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001731 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001732 addComma = false;
1733 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001734
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001735 default:
1736 ALOGW("%s: Camera %d: Unknown preview format: %x",
1737 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1738 addComma = false;
1739 break;
1740 }
1741 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001742 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001743 supportedPreviewFormats);
1744 }
1745
1746 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1747 // still have to do something sane for them
1748
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001749 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001750 mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001751
1752 {
1753 String8 supportedPreviewFrameRates;
1754 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1755 if (i != 0) supportedPreviewFrameRates += ",";
1756 supportedPreviewFrameRates += String8::format("%d",
1757 availableFpsRanges.data.i32[i]);
1758 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001759 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001760 supportedPreviewFrameRates);
1761 }
1762
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001763 camera_metadata_entry_t availableJpegSizes =
1764 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1765 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001766
1767 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001768 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1769 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001770
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001771 params.setPictureSize(mParameters.pictureWidth,
1772 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001773
1774 {
1775 String8 supportedPictureSizes;
1776 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1777 if (i != 0) supportedPictureSizes += ",";
1778 supportedPictureSizes += String8::format("%dx%d",
1779 availableJpegSizes.data.i32[i],
1780 availableJpegSizes.data.i32[i+1]);
1781 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001782 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001783 supportedPictureSizes);
1784 }
1785
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001786 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1787 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1788 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001789
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001790 camera_metadata_entry_t availableJpegThumbnailSizes =
1791 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1792 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001793
1794 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001795 mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1796 mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001797
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001798 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001799 mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001800 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001801 mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001802
1803 {
1804 String8 supportedJpegThumbSizes;
1805 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1806 if (i != 0) supportedJpegThumbSizes += ",";
1807 supportedJpegThumbSizes += String8::format("%dx%d",
1808 availableJpegThumbnailSizes.data.i32[i],
1809 availableJpegThumbnailSizes.data.i32[i+1]);
1810 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001811 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001812 supportedJpegThumbSizes);
1813 }
1814
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001815 mParameters.jpegThumbQuality = 90;
1816 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1817 mParameters.jpegThumbQuality);
1818 mParameters.jpegQuality = 90;
1819 params.set(CameraParameters::KEY_JPEG_QUALITY,
1820 mParameters.jpegQuality);
1821 mParameters.jpegRotation = 0;
1822 params.set(CameraParameters::KEY_ROTATION,
1823 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001824
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001825 mParameters.gpsEnabled = false;
1826 mParameters.gpsProcessingMethod = "unknown";
1827 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001828
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001829 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1830 params.set(CameraParameters::KEY_WHITE_BALANCE,
1831 CameraParameters::WHITE_BALANCE_AUTO);
1832
1833 camera_metadata_entry_t availableWhiteBalanceModes =
1834 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001835 {
1836 String8 supportedWhiteBalance;
1837 bool addComma = false;
1838 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1839 if (addComma) supportedWhiteBalance += ",";
1840 addComma = true;
1841 switch (availableWhiteBalanceModes.data.u8[i]) {
1842 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001843 supportedWhiteBalance +=
1844 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001845 break;
1846 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001847 supportedWhiteBalance +=
1848 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001849 break;
1850 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001851 supportedWhiteBalance +=
1852 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001853 break;
1854 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001855 supportedWhiteBalance +=
1856 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001857 break;
1858 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001859 supportedWhiteBalance +=
1860 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001861 break;
1862 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001863 supportedWhiteBalance +=
1864 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001865 break;
1866 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001867 supportedWhiteBalance +=
1868 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001869 break;
1870 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001871 supportedWhiteBalance +=
1872 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001873 break;
1874 // Skipping values not mappable to v1 API
1875 case ANDROID_CONTROL_AWB_OFF:
1876 addComma = false;
1877 break;
1878 default:
1879 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1880 __FUNCTION__, mCameraId,
1881 availableWhiteBalanceModes.data.u8[i]);
1882 addComma = false;
1883 break;
1884 }
1885 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001886 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001887 supportedWhiteBalance);
1888 }
1889
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001890 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1891 params.set(CameraParameters::KEY_EFFECT,
1892 CameraParameters::EFFECT_NONE);
1893
1894 camera_metadata_entry_t availableEffects =
1895 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1896 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001897 {
1898 String8 supportedEffects;
1899 bool addComma = false;
1900 for (size_t i=0; i < availableEffects.count; i++) {
1901 if (addComma) supportedEffects += ",";
1902 addComma = true;
1903 switch (availableEffects.data.u8[i]) {
1904 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001905 supportedEffects +=
1906 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001907 break;
1908 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001909 supportedEffects +=
1910 CameraParameters::EFFECT_MONO;
1911 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001912 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001913 supportedEffects +=
1914 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915 break;
1916 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001917 supportedEffects +=
1918 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001919 break;
1920 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001921 supportedEffects +=
1922 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001923 break;
1924 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001925 supportedEffects +=
1926 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001927 break;
1928 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001929 supportedEffects +=
1930 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001931 break;
1932 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001933 supportedEffects +=
1934 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001935 break;
1936 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001937 supportedEffects +=
1938 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001939 break;
1940 default:
1941 ALOGW("%s: Camera %d: Unknown effect value: %d",
1942 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1943 addComma = false;
1944 break;
1945 }
1946 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001947 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001948 }
1949
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001950 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1951 params.set(CameraParameters::KEY_ANTIBANDING,
1952 CameraParameters::ANTIBANDING_AUTO);
1953
1954 camera_metadata_entry_t availableAntibandingModes =
1955 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1956 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001957 {
1958 String8 supportedAntibanding;
1959 bool addComma = false;
1960 for (size_t i=0; i < availableAntibandingModes.count; i++) {
1961 if (addComma) supportedAntibanding += ",";
1962 addComma = true;
1963 switch (availableAntibandingModes.data.u8[i]) {
1964 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001965 supportedAntibanding +=
1966 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 break;
1968 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001969 supportedAntibanding +=
1970 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001971 break;
1972 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001973 supportedAntibanding +=
1974 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001975 break;
1976 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001977 supportedAntibanding +=
1978 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001979 break;
1980 default:
1981 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
1982 __FUNCTION__, mCameraId,
1983 availableAntibandingModes.data.u8[i]);
1984 addComma = false;
1985 break;
1986 }
1987 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001988 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001989 supportedAntibanding);
1990 }
1991
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001992 mParameters.sceneMode = ANDROID_CONTROL_OFF;
1993 params.set(CameraParameters::KEY_SCENE_MODE,
1994 CameraParameters::SCENE_MODE_AUTO);
1995
1996 camera_metadata_entry_t availableSceneModes =
1997 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1998 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001999 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002000 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002001 bool addComma = true;
2002 bool noSceneModes = false;
2003 for (size_t i=0; i < availableSceneModes.count; i++) {
2004 if (addComma) supportedSceneModes += ",";
2005 addComma = true;
2006 switch (availableSceneModes.data.u8[i]) {
2007 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2008 noSceneModes = true;
2009 break;
2010 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2011 // Not in old API
2012 addComma = false;
2013 break;
2014 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002015 supportedSceneModes +=
2016 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017 break;
2018 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002019 supportedSceneModes +=
2020 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002021 break;
2022 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002023 supportedSceneModes +=
2024 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002025 break;
2026 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002027 supportedSceneModes +=
2028 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002029 break;
2030 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002031 supportedSceneModes +=
2032 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002033 break;
2034 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002035 supportedSceneModes +=
2036 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002037 break;
2038 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002039 supportedSceneModes +=
2040 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002041 break;
2042 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002043 supportedSceneModes +=
2044 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002045 break;
2046 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002047 supportedSceneModes +=
2048 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049 break;
2050 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002051 supportedSceneModes +=
2052 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002053 break;
2054 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002055 supportedSceneModes +=
2056 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002057 break;
2058 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002059 supportedSceneModes +=
2060 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002061 break;
2062 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002063 supportedSceneModes +=
2064 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002065 break;
2066 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002067 supportedSceneModes +=
2068 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002069 break;
2070 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002071 supportedSceneModes +=
2072 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002073 break;
2074 default:
2075 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002076 __FUNCTION__, mCameraId,
2077 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002078 addComma = false;
2079 break;
2080 }
2081 }
2082 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002083 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002084 supportedSceneModes);
2085 }
2086 }
2087
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002088 camera_metadata_entry_t flashAvailable =
2089 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2090 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002091
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002092 camera_metadata_entry_t availableAeModes =
2093 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2094 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002095
2096 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002097 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2098 params.set(CameraParameters::KEY_FLASH_MODE,
2099 CameraParameters::FLASH_MODE_AUTO);
2100
2101 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2102 supportedFlashModes = supportedFlashModes +
2103 "," + CameraParameters::FLASH_MODE_AUTO +
2104 "," + CameraParameters::FLASH_MODE_ON +
2105 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002106 for (size_t i=0; i < availableAeModes.count; i++) {
2107 if (availableAeModes.data.u8[i] ==
2108 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002109 supportedFlashModes = supportedFlashModes + "," +
2110 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002111 break;
2112 }
2113 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002114 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002115 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002116 } else {
2117 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2118 params.set(CameraParameters::KEY_FLASH_MODE,
2119 CameraParameters::FLASH_MODE_OFF);
2120 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2121 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002122 }
2123
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002124 camera_metadata_entry_t minFocusDistance =
2125 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2126 if (!minFocusDistance.count) return NO_INIT;
2127
2128 camera_metadata_entry_t availableAfModes =
2129 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2130 if (!availableAfModes.count) return NO_INIT;
2131
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002132 if (minFocusDistance.data.f[0] == 0) {
2133 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002134 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2135 params.set(CameraParameters::KEY_FOCUS_MODE,
2136 CameraParameters::FOCUS_MODE_FIXED);
2137 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2138 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002139 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002140 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2141 params.set(CameraParameters::KEY_FOCUS_MODE,
2142 CameraParameters::FOCUS_MODE_AUTO);
2143 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2144 supportedFocusModes = supportedFocusModes + "," +
2145 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002146 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002147
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002148 for (size_t i=0; i < availableAfModes.count; i++) {
2149 if (addComma) supportedFocusModes += ",";
2150 addComma = true;
2151 switch (availableAfModes.data.u8[i]) {
2152 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002153 supportedFocusModes +=
2154 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002155 break;
2156 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002157 supportedFocusModes +=
2158 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 break;
2160 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002161 supportedFocusModes +=
2162 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002163 break;
2164 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002165 supportedFocusModes +=
2166 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002167 break;
2168 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002169 supportedFocusModes +=
2170 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002171 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002172 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002173 case ANDROID_CONTROL_AF_OFF:
2174 addComma = false;
2175 break;
2176 default:
2177 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2178 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2179 addComma = false;
2180 break;
2181 }
2182 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002183 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002184 supportedFocusModes);
2185 }
2186
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002187 camera_metadata_entry_t max3aRegions =
2188 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2189 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002190
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002191 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002192 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002193 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002194 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002195 mParameters.focusingAreas.clear();
2196 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002197
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002198 camera_metadata_entry_t availableFocalLengths =
2199 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2200 if (!availableFocalLengths.count) return NO_INIT;
2201
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002202 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002203 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002204
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002205 camera_metadata_entry_t sensorSize =
2206 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2207 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002208
2209 // The fields of view here assume infinity focus, maximum wide angle
2210 float horizFov = 180 / M_PI *
2211 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2212 float vertFov = 180 / M_PI *
2213 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002214 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2215 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002216
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002217 mParameters.exposureCompensation = 0;
2218 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2219 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002220
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002221 camera_metadata_entry_t exposureCompensationRange =
2222 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2223 if (!exposureCompensationRange.count) return NO_INIT;
2224
2225 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002226 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002227 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002228 exposureCompensationRange.data.i32[0]);
2229
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002230 camera_metadata_entry_t exposureCompensationStep =
2231 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2232 if (!exposureCompensationStep.count) return NO_INIT;
2233
2234 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002235 exposureCompensationStep.data.r[0].numerator /
2236 exposureCompensationStep.data.r[0].denominator);
2237
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002238 mParameters.autoExposureLock = false;
2239 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2240 CameraParameters::FALSE);
2241 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2242 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002243
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002244 mParameters.autoWhiteBalanceLock = false;
2245 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2246 CameraParameters::FALSE);
2247 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2248 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002249
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002250 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2251 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002252 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002253 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002254 "(0,0,0,0,0)");
2255
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002256 mParameters.zoom = 0;
2257 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
2258 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002259
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002260 camera_metadata_entry_t maxDigitalZoom =
2261 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2262 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002263
2264 {
2265 String8 zoomRatios;
2266 float zoom = 1.f;
2267 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002268 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002269 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002270 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002271 if (addComma) zoomRatios += ",";
2272 addComma = true;
2273 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2274 zoom += zoomIncrement;
2275 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002276 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277 }
2278
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002279 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2280 CameraParameters::TRUE);
2281 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2282 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002283
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002284 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002285 "Infinity,Infinity,Infinity");
2286
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002287 camera_metadata_entry_t maxFacesDetected =
2288 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2289 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002290 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002291 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002292 0);
2293
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002294 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002295 formatEnumToString(kRecordingFormat));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002296
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002297 params.set(CameraParameters::KEY_RECORDING_HINT,
2298 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002299
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002300 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2301 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002302
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002303 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2304 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002306 camera_metadata_entry_t availableVideoStabilizationModes =
2307 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2308 if (!availableVideoStabilizationModes.count) return NO_INIT;
2309
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002310 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002311 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2312 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002313 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002314 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2315 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002316 }
2317
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002318 mParamsFlattened = params.flatten();
2319
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002320 return OK;
2321}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002322
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002323status_t Camera2Client::updatePreviewStream() {
2324 ATRACE_CALL();
2325 status_t res;
2326 if (mPreviewStreamId != NO_STREAM) {
2327 // Check if stream parameters have to change
2328 uint32_t currentWidth, currentHeight;
2329 res = mDevice->getStreamInfo(mPreviewStreamId,
2330 &currentWidth, &currentHeight, 0);
2331 if (res != OK) {
2332 ALOGE("%s: Camera %d: Error querying preview stream info: "
2333 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2334 return res;
2335 }
2336 if (currentWidth != (uint32_t)mParameters.previewWidth ||
2337 currentHeight != (uint32_t)mParameters.previewHeight) {
2338 res = mDevice->waitUntilDrained();
2339 if (res != OK) {
2340 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2341 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2342 return res;
2343 }
2344 res = mDevice->deleteStream(mPreviewStreamId);
2345 if (res != OK) {
2346 ALOGE("%s: Camera %d: Unable to delete old output stream "
2347 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2348 strerror(-res), res);
2349 return res;
2350 }
2351 mPreviewStreamId = NO_STREAM;
2352 }
2353 }
2354
2355 if (mPreviewStreamId == NO_STREAM) {
2356 res = mDevice->createStream(mPreviewWindow,
2357 mParameters.previewWidth, mParameters.previewHeight,
2358 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2359 &mPreviewStreamId);
2360 if (res != OK) {
2361 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2362 __FUNCTION__, mCameraId, strerror(-res), res);
2363 return res;
2364 }
2365 }
2366
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002367 res = mDevice->setStreamTransform(mPreviewStreamId,
2368 mParameters.previewTransform);
2369 if (res != OK) {
2370 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2371 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2372 return res;
2373 }
2374
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002375 return OK;
2376}
2377
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002378status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002379 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002380 status_t res;
2381 if (mPreviewRequest == NULL) {
2382 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2383 &mPreviewRequest);
2384 if (res != OK) {
2385 ALOGE("%s: Camera %d: Unable to create default preview request: "
2386 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2387 return res;
2388 }
2389 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002390
2391 res = updateRequestCommon(mPreviewRequest);
2392 if (res != OK) {
2393 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2394 "request: %s (%d)", __FUNCTION__, mCameraId,
2395 strerror(-res), res);
2396 return res;
2397 }
2398
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002399 return OK;
2400}
2401
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002402status_t Camera2Client::updateCaptureStream() {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002403 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002404 status_t res;
2405 // Find out buffer size for JPEG
2406 camera_metadata_entry_t maxJpegSize =
2407 staticInfo(ANDROID_JPEG_MAX_SIZE);
2408 if (maxJpegSize.count == 0) {
2409 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2410 __FUNCTION__, mCameraId);
2411 return INVALID_OPERATION;
2412 }
2413
2414 if (mCaptureConsumer == 0) {
2415 // Create CPU buffer queue endpoint
2416 mCaptureConsumer = new CpuConsumer(1);
2417 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2418 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2419 mCaptureWindow = new SurfaceTextureClient(
2420 mCaptureConsumer->getProducerInterface());
2421 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002422 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2423 "Camera2Client::CaptureHeap");
2424 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002425 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2426 __FUNCTION__, mCameraId);
2427 return NO_MEMORY;
2428 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002429 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002430
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002431 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002432 // Check if stream parameters have to change
2433 uint32_t currentWidth, currentHeight;
2434 res = mDevice->getStreamInfo(mCaptureStreamId,
2435 &currentWidth, &currentHeight, 0);
2436 if (res != OK) {
2437 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2438 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2439 return res;
2440 }
2441 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
2442 currentHeight != (uint32_t)mParameters.pictureHeight) {
2443 res = mDevice->deleteStream(mCaptureStreamId);
2444 if (res != OK) {
2445 ALOGE("%s: Camera %d: Unable to delete old output stream "
2446 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2447 strerror(-res), res);
2448 return res;
2449 }
2450 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002451 }
2452 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002453
2454 if (mCaptureStreamId == NO_STREAM) {
2455 // Create stream for HAL production
2456 res = mDevice->createStream(mCaptureWindow,
2457 mParameters.pictureWidth, mParameters.pictureHeight,
2458 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2459 &mCaptureStreamId);
2460 if (res != OK) {
2461 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2462 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2463 return res;
2464 }
2465
2466 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002467 return OK;
2468}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002469
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002470status_t Camera2Client::updateCaptureRequest() {
2471 ATRACE_CALL();
2472 status_t res;
2473 if (mCaptureRequest == NULL) {
2474 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2475 &mCaptureRequest);
2476 if (res != OK) {
2477 ALOGE("%s: Camera %d: Unable to create default still image request:"
2478 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2479 return res;
2480 }
2481 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002482
2483 res = updateRequestCommon(mCaptureRequest);
2484 if (res != OK) {
2485 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2486 "request: %s (%d)", __FUNCTION__, mCameraId,
2487 strerror(-res), res);
2488 return res;
2489 }
2490
2491 res = updateEntry(mCaptureRequest,
2492 ANDROID_JPEG_THUMBNAIL_SIZE,
2493 mParameters.jpegThumbSize, 2);
2494 if (res != OK) return res;
2495 res = updateEntry(mCaptureRequest,
2496 ANDROID_JPEG_THUMBNAIL_QUALITY,
2497 &mParameters.jpegThumbQuality, 1);
2498 if (res != OK) return res;
2499 res = updateEntry(mCaptureRequest,
2500 ANDROID_JPEG_QUALITY,
2501 &mParameters.jpegQuality, 1);
2502 if (res != OK) return res;
2503 res = updateEntry(mCaptureRequest,
2504 ANDROID_JPEG_ORIENTATION,
2505 &mParameters.jpegRotation, 1);
2506 if (res != OK) return res;
2507
2508 if (mParameters.gpsEnabled) {
2509 res = updateEntry(mCaptureRequest,
2510 ANDROID_JPEG_GPS_COORDINATES,
2511 mParameters.gpsCoordinates, 3);
2512 if (res != OK) return res;
2513 res = updateEntry(mCaptureRequest,
2514 ANDROID_JPEG_GPS_TIMESTAMP,
2515 &mParameters.gpsTimestamp, 1);
2516 if (res != OK) return res;
2517 res = updateEntry(mCaptureRequest,
2518 ANDROID_JPEG_GPS_PROCESSING_METHOD,
2519 mParameters.gpsProcessingMethod.string(),
2520 mParameters.gpsProcessingMethod.size());
2521 if (res != OK) return res;
2522 } else {
2523 res = deleteEntry(mCaptureRequest,
2524 ANDROID_JPEG_GPS_COORDINATES);
2525 if (res != OK) return res;
2526 res = deleteEntry(mCaptureRequest,
2527 ANDROID_JPEG_GPS_TIMESTAMP);
2528 if (res != OK) return res;
2529 res = deleteEntry(mCaptureRequest,
2530 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2531 if (res != OK) return res;
2532 }
2533
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002534 return OK;
2535}
2536
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002537status_t Camera2Client::updateRecordingRequest() {
2538 ATRACE_CALL();
2539 status_t res;
2540 if (mRecordingRequest == NULL) {
2541 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2542 &mRecordingRequest);
2543 if (res != OK) {
2544 ALOGE("%s: Camera %d: Unable to create default recording request:"
2545 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2546 return res;
2547 }
2548 }
2549
2550 res = updateRequestCommon(mRecordingRequest);
2551 if (res != OK) {
2552 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2553 "request: %s (%d)", __FUNCTION__, mCameraId,
2554 strerror(-res), res);
2555 return res;
2556 }
2557
2558 return OK;
2559}
2560
2561status_t Camera2Client::updateRecordingStream() {
2562 status_t res;
2563
2564 if (mRecordingConsumer == 0) {
2565 // Create CPU buffer queue endpoint
2566 mRecordingConsumer = new CpuConsumer(1);
2567 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2568 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2569 mRecordingWindow = new SurfaceTextureClient(
2570 mRecordingConsumer->getProducerInterface());
2571 // Allocate memory later, since we don't know buffer size until receipt
2572 }
2573
2574 if (mRecordingStreamId != NO_STREAM) {
2575 // Check if stream parameters have to change
2576 uint32_t currentWidth, currentHeight;
2577 res = mDevice->getStreamInfo(mRecordingStreamId,
2578 &currentWidth, &currentHeight, 0);
2579 if (res != OK) {
2580 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2581 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2582 return res;
2583 }
2584 if (currentWidth != (uint32_t)mParameters.videoWidth ||
2585 currentHeight != (uint32_t)mParameters.videoHeight) {
2586 // TODO: Should wait to be sure previous recording has finished
2587 res = mDevice->deleteStream(mRecordingStreamId);
2588 if (res != OK) {
2589 ALOGE("%s: Camera %d: Unable to delete old output stream "
2590 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2591 strerror(-res), res);
2592 return res;
2593 }
2594 mRecordingStreamId = NO_STREAM;
2595 }
2596 }
2597
2598 if (mRecordingStreamId == NO_STREAM) {
2599 res = mDevice->createStream(mRecordingWindow,
2600 mParameters.videoWidth, mParameters.videoHeight,
2601 kRecordingFormat, 0, &mRecordingStreamId);
2602 if (res != OK) {
2603 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2604 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2605 return res;
2606 }
2607 }
2608
2609 return OK;
2610}
2611
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002612status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
2613 ATRACE_CALL();
2614 status_t res;
2615 res = updateEntry(request,
2616 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
2617 if (res != OK) return res;
2618
2619 uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
2620 ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
2621 res = updateEntry(request,
2622 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2623 if (res != OK) return res;
2624 res = updateEntry(request,
2625 ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
2626 if (res != OK) return res;
2627 res = updateEntry(request,
2628 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2629 &mParameters.antibandingMode, 1);
2630 if (res != OK) return res;
2631
2632 uint8_t controlMode =
2633 (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2634 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2635 res = updateEntry(request,
2636 ANDROID_CONTROL_MODE, &controlMode, 1);
2637 if (res != OK) return res;
2638 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2639 res = updateEntry(request,
2640 ANDROID_CONTROL_SCENE_MODE,
2641 &mParameters.sceneMode, 1);
2642 if (res != OK) return res;
2643 }
2644
2645 uint8_t flashMode = ANDROID_FLASH_OFF;
2646 uint8_t aeMode;
2647 switch (mParameters.flashMode) {
2648 case Parameters::FLASH_MODE_OFF:
2649 aeMode = ANDROID_CONTROL_AE_ON; break;
2650 case Parameters::FLASH_MODE_AUTO:
2651 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2652 case Parameters::FLASH_MODE_ON:
2653 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2654 case Parameters::FLASH_MODE_TORCH:
2655 aeMode = ANDROID_CONTROL_AE_ON;
2656 flashMode = ANDROID_FLASH_TORCH;
2657 break;
2658 case Parameters::FLASH_MODE_RED_EYE:
2659 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2660 default:
2661 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2662 mCameraId, mParameters.flashMode);
2663 return BAD_VALUE;
2664 }
2665 if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2666
2667 res = updateEntry(request,
2668 ANDROID_FLASH_MODE, &flashMode, 1);
2669 if (res != OK) return res;
2670 res = updateEntry(request,
2671 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2672 if (res != OK) return res;
2673
2674 float focusDistance = 0; // infinity focus in diopters
2675 uint8_t focusMode;
2676 switch (mParameters.focusMode) {
2677 case Parameters::FOCUS_MODE_AUTO:
2678 case Parameters::FOCUS_MODE_MACRO:
2679 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2680 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2681 case Parameters::FOCUS_MODE_EDOF:
2682 focusMode = mParameters.focusMode;
2683 break;
2684 case Parameters::FOCUS_MODE_INFINITY:
2685 case Parameters::FOCUS_MODE_FIXED:
2686 focusMode = ANDROID_CONTROL_AF_OFF;
2687 break;
2688 default:
2689 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2690 mCameraId, mParameters.focusMode);
2691 return BAD_VALUE;
2692 }
2693 res = updateEntry(request,
2694 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2695 if (res != OK) return res;
2696 res = updateEntry(request,
2697 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2698 if (res != OK) return res;
2699
2700 size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
2701 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2702 for (size_t i = 0; i < focusingAreasSize; i += 5) {
2703 focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
2704 focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
2705 focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
2706 focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
2707 focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
2708 }
2709 res = updateEntry(request,
2710 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2711 if (res != OK) return res;
2712 delete[] focusingAreas;
2713
2714 res = updateEntry(request,
2715 ANDROID_CONTROL_AE_EXP_COMPENSATION,
2716 &mParameters.exposureCompensation, 1);
2717 if (res != OK) return res;
2718
2719 size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
2720 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2721 for (size_t i = 0; i < meteringAreasSize; i += 5) {
2722 meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
2723 meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
2724 meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
2725 meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
2726 meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
2727 }
2728 res = updateEntry(request,
2729 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2730 if (res != OK) return res;
2731
2732 res = updateEntry(request,
2733 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2734 if (res != OK) return res;
2735 delete[] meteringAreas;
2736
2737 // Need to convert zoom index into a crop rectangle. The rectangle is
2738 // chosen to maximize its area on the sensor
2739
2740 camera_metadata_entry_t maxDigitalZoom =
2741 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2742 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2743 (NUM_ZOOM_STEPS-1);
2744 float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
2745
2746 camera_metadata_entry_t activePixelArraySize =
2747 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2748 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2749 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2750 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2751 if (mParameters.previewWidth >= mParameters.previewHeight) {
2752 zoomWidth = arrayWidth / zoomRatio;
2753 zoomHeight = zoomWidth *
2754 mParameters.previewHeight / mParameters.previewWidth;
2755 } else {
2756 zoomHeight = arrayHeight / zoomRatio;
2757 zoomWidth = zoomHeight *
2758 mParameters.previewWidth / mParameters.previewHeight;
2759 }
2760 zoomLeft = (arrayWidth - zoomWidth) / 2;
2761 zoomTop = (arrayHeight - zoomHeight) / 2;
2762
2763 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2764 res = updateEntry(request,
2765 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2766 if (res != OK) return res;
2767
2768 // TODO: Decide how to map recordingHint, or whether just to ignore it
2769
2770 uint8_t vstabMode = mParameters.videoStabilization ?
2771 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2772 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2773 res = updateEntry(request,
2774 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2775 &vstabMode, 1);
2776 if (res != OK) return res;
2777
2778 return OK;
2779}
2780
2781status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2782 uint32_t tag, const void *data, size_t data_count) {
2783 camera_metadata_entry_t entry;
2784 status_t res;
2785 res = find_camera_metadata_entry(buffer, tag, &entry);
2786 if (res == NAME_NOT_FOUND) {
2787 res = add_camera_metadata_entry(buffer,
2788 tag, data, data_count);
2789 } else if (res == OK) {
2790 res = update_camera_metadata_entry(buffer,
2791 entry.index, data, data_count, NULL);
2792 }
2793
2794 if (res != OK) {
2795 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2796 __FUNCTION__, get_camera_metadata_section_name(tag),
2797 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2798 }
2799 return res;
2800}
2801
2802status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2803 camera_metadata_entry_t entry;
2804 status_t res;
2805 res = find_camera_metadata_entry(buffer, tag, &entry);
2806 if (res == NAME_NOT_FOUND) {
2807 return OK;
2808 } else if (res != OK) {
2809 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2810 __FUNCTION__,
2811 get_camera_metadata_section_name(tag),
2812 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2813 return res;
2814 }
2815 res = delete_camera_metadata_entry(buffer, entry.index);
2816 if (res != OK) {
2817 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2818 __FUNCTION__,
2819 get_camera_metadata_section_name(tag),
2820 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2821 }
2822 return res;
2823}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002824int Camera2Client::formatStringToEnum(const char *format) {
2825 return
2826 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2827 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2828 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2829 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2830 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2831 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2832 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2833 HAL_PIXEL_FORMAT_YV12 : // YV12
2834 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2835 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2836 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2837 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2838 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2839 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2840 -1;
2841}
2842
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002843const char* Camera2Client::formatEnumToString(int format) {
2844 const char *fmt;
2845 switch(format) {
2846 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2847 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2848 break;
2849 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2850 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2851 break;
2852 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2853 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2854 break;
2855 case HAL_PIXEL_FORMAT_YV12: // YV12
2856 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2857 break;
2858 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2859 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2860 break;
2861 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2862 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2863 break;
2864 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2865 ALOGW("Raw sensor preview format requested.");
2866 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2867 break;
2868 default:
2869 ALOGE("%s: Unknown preview format: %x",
2870 __FUNCTION__, format);
2871 fmt = NULL;
2872 break;
2873 }
2874 return fmt;
2875}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002876
2877int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2878 return
2879 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2880 ANDROID_CONTROL_AWB_AUTO :
2881 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2882 ANDROID_CONTROL_AWB_INCANDESCENT :
2883 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2884 ANDROID_CONTROL_AWB_FLUORESCENT :
2885 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2886 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2887 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2888 ANDROID_CONTROL_AWB_DAYLIGHT :
2889 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2890 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2891 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2892 ANDROID_CONTROL_AWB_TWILIGHT :
2893 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2894 ANDROID_CONTROL_AWB_SHADE :
2895 -1;
2896}
2897
2898int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2899 return
2900 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2901 ANDROID_CONTROL_EFFECT_OFF :
2902 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2903 ANDROID_CONTROL_EFFECT_MONO :
2904 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2905 ANDROID_CONTROL_EFFECT_NEGATIVE :
2906 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2907 ANDROID_CONTROL_EFFECT_SOLARIZE :
2908 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2909 ANDROID_CONTROL_EFFECT_SEPIA :
2910 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2911 ANDROID_CONTROL_EFFECT_POSTERIZE :
2912 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2913 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2914 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2915 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2916 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2917 ANDROID_CONTROL_EFFECT_AQUA :
2918 -1;
2919}
2920
2921int Camera2Client::abModeStringToEnum(const char *abMode) {
2922 return
2923 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2924 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2925 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2926 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2927 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2928 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2929 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2930 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2931 -1;
2932}
2933
2934int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2935 return
2936 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2937 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2938 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2939 ANDROID_CONTROL_SCENE_MODE_ACTION :
2940 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2941 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2942 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2943 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2944 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2945 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2946 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2947 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2948 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2949 ANDROID_CONTROL_SCENE_MODE_THEATRE :
2950 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2951 ANDROID_CONTROL_SCENE_MODE_BEACH :
2952 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2953 ANDROID_CONTROL_SCENE_MODE_SNOW :
2954 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2955 ANDROID_CONTROL_SCENE_MODE_SUNSET :
2956 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2957 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2958 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2959 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2960 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2961 ANDROID_CONTROL_SCENE_MODE_SPORTS :
2962 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2963 ANDROID_CONTROL_SCENE_MODE_PARTY :
2964 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2965 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2966 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2967 ANDROID_CONTROL_SCENE_MODE_BARCODE:
2968 -1;
2969}
2970
2971Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
2972 const char *flashMode) {
2973 return
2974 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2975 Parameters::FLASH_MODE_OFF :
2976 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2977 Parameters::FLASH_MODE_AUTO :
2978 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2979 Parameters::FLASH_MODE_ON :
2980 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2981 Parameters::FLASH_MODE_RED_EYE :
2982 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2983 Parameters::FLASH_MODE_TORCH :
2984 Parameters::FLASH_MODE_INVALID;
2985}
2986
2987Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
2988 const char *focusMode) {
2989 return
2990 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2991 Parameters::FOCUS_MODE_AUTO :
2992 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2993 Parameters::FOCUS_MODE_INFINITY :
2994 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2995 Parameters::FOCUS_MODE_MACRO :
2996 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2997 Parameters::FOCUS_MODE_FIXED :
2998 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2999 Parameters::FOCUS_MODE_EDOF :
3000 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3001 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3002 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3003 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3004 Parameters::FOCUS_MODE_INVALID;
3005}
3006
3007status_t Camera2Client::parseAreas(const char *areasCStr,
3008 Vector<Parameters::Area> *areas) {
3009 static const size_t NUM_FIELDS = 5;
3010 areas->clear();
3011 if (areasCStr == NULL) {
3012 // If no key exists, use default (0,0,0,0,0)
3013 areas->push();
3014 return OK;
3015 }
3016 String8 areasStr(areasCStr);
3017 ssize_t areaStart = areasStr.find("(", 0) + 1;
3018 while (areaStart != 0) {
3019 const char* area = areasStr.string() + areaStart;
3020 char *numEnd;
3021 int vals[NUM_FIELDS];
3022 for (size_t i = 0; i < NUM_FIELDS; i++) {
3023 errno = 0;
3024 vals[i] = strtol(area, &numEnd, 10);
3025 if (errno || numEnd == area) return BAD_VALUE;
3026 area = numEnd + 1;
3027 }
3028 areas->push(Parameters::Area(
3029 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3030 areaStart = areasStr.find("(", areaStart) + 1;
3031 }
3032 return OK;
3033}
3034
3035status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3036 size_t maxRegions) {
3037 // Definition of valid area can be found in
3038 // include/camera/CameraParameters.h
3039 if (areas.size() == 0) return BAD_VALUE;
3040 if (areas.size() == 1) {
3041 if (areas[0].left == 0 &&
3042 areas[0].top == 0 &&
3043 areas[0].right == 0 &&
3044 areas[0].bottom == 0 &&
3045 areas[0].weight == 0) {
3046 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3047 return OK;
3048 }
3049 }
3050 if (areas.size() > maxRegions) {
3051 ALOGE("%s: Too many areas requested: %d",
3052 __FUNCTION__, areas.size());
3053 return BAD_VALUE;
3054 }
3055
3056 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3057 a != areas.end(); a++) {
3058 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3059 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3060 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3061 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3062 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3063 if (a->left >= a->right) return BAD_VALUE;
3064 if (a->top >= a->bottom) return BAD_VALUE;
3065 }
3066 return OK;
3067}
3068
3069bool Camera2Client::boolFromString(const char *boolStr) {
3070 return !boolStr ? false :
3071 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3072 false;
3073}
3074
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003075int Camera2Client::degToTransform(int degrees, bool mirror) {
3076 if (!mirror) {
3077 if (degrees == 0) return 0;
3078 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3079 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3080 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3081 } else { // Do mirror (horizontal flip)
3082 if (degrees == 0) { // FLIP_H and ROT_0
3083 return HAL_TRANSFORM_FLIP_H;
3084 } else if (degrees == 90) { // FLIP_H and ROT_90
3085 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3086 } else if (degrees == 180) { // FLIP_H and ROT_180
3087 return HAL_TRANSFORM_FLIP_V;
3088 } else if (degrees == 270) { // FLIP_H and ROT_270
3089 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3090 }
3091 }
3092 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3093 return -1;
3094}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003095
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003096} // namespace android