blob: 47d1588731de1ead571fb9ddd545dbe244bff050 [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>
Eino-Ville Talvala78822d72012-07-18 17:52:18 -070027#include <media/hardware/MetadataBufferType.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070028
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070029#include <math.h>
30
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#include "Camera2Client.h"
32
33namespace android {
34
35#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
36#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
37
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43 return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050 int cameraId,
51 int cameraFacing,
52 int clientPid):
53 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070055 mState(NOT_INITIALIZED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
58 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070059 mCaptureRequest(NULL),
60 mRecordingStreamId(NO_STREAM),
61 mRecordingRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066}
67
68status_t Camera2Client::initialize(camera_module_t *module)
69{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070070 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070071 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072 status_t res;
73
74 res = mDevice->initialize(module);
75 if (res != OK) {
76 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
77 __FUNCTION__, mCameraId, strerror(-res), res);
78 return NO_INIT;
79 }
80
81 res = buildDefaultParameters();
82 if (res != OK) {
83 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
84 __FUNCTION__, mCameraId, strerror(-res), res);
85 return NO_INIT;
86 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070087
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 if (gLogLevel >= 1) {
89 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
90 mCameraId);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070091 ALOGD("%s", mParamsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 }
93
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070094 mState = STOPPED;
95
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070096 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070097}
98
99Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700100 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700101 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
102
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 mDestructionStarted = true;
104
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700105 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700106
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700107}
108
109status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700110 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700111 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700112 mCameraId,
113 getCameraClient()->asBinder().get(),
114 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700115 result.append(" State: ");
116#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
117
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700118 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700119
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700120 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700121 result.appendFormat(" Preview size: %d x %d\n",
122 mParameters.previewWidth, mParameters.previewHeight);
123 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700124 mParameters.previewFpsRange[0], mParameters.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700125 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
126 mParameters.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700127 result.appendFormat(" Preview transform: %x\n",
128 mParameters.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700129 result.appendFormat(" Picture size: %d x %d\n",
130 mParameters.pictureWidth, mParameters.pictureHeight);
131 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700132 mParameters.jpegThumbSize[0], mParameters.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700133 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
134 mParameters.jpegQuality, mParameters.jpegThumbQuality);
135 result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
136 result.appendFormat(" GPS tags %s\n",
137 mParameters.gpsEnabled ? "enabled" : "disabled");
138 if (mParameters.gpsEnabled) {
139 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700140 mParameters.gpsCoordinates[0], mParameters.gpsCoordinates[1],
141 mParameters.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" GPS timestamp: %lld\n",
143 mParameters.gpsTimestamp);
144 result.appendFormat(" GPS processing method: %s\n",
145 mParameters.gpsProcessingMethod.string());
146 }
147
148 result.append(" White balance mode: ");
149 switch (mParameters.wbMode) {
150 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
151 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
152 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
156 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
157 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
158 default: result.append("UNKNOWN\n");
159 }
160
161 result.append(" Effect mode: ");
162 switch (mParameters.effectMode) {
163 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
164 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
172 default: result.append("UNKNOWN\n");
173 }
174
175 result.append(" Antibanding mode: ");
176 switch (mParameters.antibandingMode) {
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
181 default: result.append("UNKNOWN\n");
182 }
183
184 result.append(" Scene mode: ");
185 switch (mParameters.sceneMode) {
186 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
187 result.append("AUTO\n"); break;
188 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
203 default: result.append("UNKNOWN\n");
204 }
205
206 result.append(" Flash mode: ");
207 switch (mParameters.flashMode) {
208 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
209 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
210 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
212 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
213 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
214 default: result.append("UNKNOWN\n");
215 }
216
217 result.append(" Focus mode: ");
218 switch (mParameters.focusMode) {
219 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
220 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
221 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
225 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
226 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
227 default: result.append("UNKNOWN\n");
228 }
229
230 result.append(" Focusing areas:\n");
231 for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
232 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
233 mParameters.focusingAreas[i].left,
234 mParameters.focusingAreas[i].top,
235 mParameters.focusingAreas[i].right,
236 mParameters.focusingAreas[i].bottom,
237 mParameters.focusingAreas[i].weight);
238 }
239
240 result.appendFormat(" Exposure compensation index: %d\n",
241 mParameters.exposureCompensation);
242
243 result.appendFormat(" AE lock %s, AWB lock %s\n",
244 mParameters.autoExposureLock ? "enabled" : "disabled",
245 mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
246
247 result.appendFormat(" Metering areas:\n");
248 for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
249 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
250 mParameters.meteringAreas[i].left,
251 mParameters.meteringAreas[i].top,
252 mParameters.meteringAreas[i].right,
253 mParameters.meteringAreas[i].bottom,
254 mParameters.meteringAreas[i].weight);
255 }
256
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700257 result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
258 result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700259 mParameters.videoHeight);
260
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700261 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700262 mParameters.recordingHint ? "set" : "not set");
263
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700264 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700265 mParameters.videoStabilization ? "enabled" : "disabled");
266
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700267 result.append(" Current streams:\n");
268 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
269 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
270
271 result.append(" Current requests:\n");
272 if (mPreviewRequest != NULL) {
273 result.append(" Preview request:\n");
274 write(fd, result.string(), result.size());
275 dump_camera_metadata(mPreviewRequest, fd, 2);
276 } else {
277 result.append(" Preview request: undefined\n");
278 write(fd, result.string(), result.size());
279 }
280
281 if (mCaptureRequest != NULL) {
282 result = " Capture request:\n";
283 write(fd, result.string(), result.size());
284 dump_camera_metadata(mCaptureRequest, fd, 2);
285 } else {
286 result = " Capture request: undefined\n";
287 write(fd, result.string(), result.size());
288 }
289
290 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700291 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700292
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700293 status_t res = mDevice->dump(fd, args);
294 if (res != OK) {
295 result = String8::format(" Error dumping device: %s (%d)",
296 strerror(-res), res);
297 write(fd, result.string(), result.size());
298 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700299
300#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700301 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700302}
303
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700304const char* Camera2Client::getStateName(State state) {
305#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
306 switch(state) {
307 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
308 CASE_ENUM_TO_CHAR(STOPPED)
309 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
310 CASE_ENUM_TO_CHAR(PREVIEW)
311 CASE_ENUM_TO_CHAR(RECORD)
312 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
313 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
314 default:
315 return "Unknown state!";
316 break;
317 }
318#undef CASE_ENUM_TO_CHAR
319}
320
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700321// ICamera interface
322
323void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700324 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700325 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700326 Mutex::Autolock icl(mICameraLock);
327
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700328 if (mDevice == 0) return;
329
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700330 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700331
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700332 mDevice->waitUntilDrained();
333
334 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700335 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700336 mPreviewStreamId = NO_STREAM;
337 }
338
339 if (mCaptureStreamId != NO_STREAM) {
340 mDevice->deleteStream(mCaptureStreamId);
341 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700342 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700343
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700344 if (mRecordingStreamId != NO_STREAM) {
345 mDevice->deleteStream(mRecordingStreamId);
346 mRecordingStreamId = NO_STREAM;
347 }
348
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700349 CameraService::Client::disconnect();
350}
351
352status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700353 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700354 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700355 Mutex::Autolock icl(mICameraLock);
356
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700357 if (mClientPid != 0 && getCallingPid() != mClientPid) {
358 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
359 "current locked to pid %d", __FUNCTION__,
360 mCameraId, getCallingPid(), mClientPid);
361 return BAD_VALUE;
362 }
363
364 mClientPid = getCallingPid();
365 mCameraClient = client;
366
367 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700368}
369
370status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700371 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700372 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700373 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700374 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
375 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700376
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700377 if (mClientPid == 0) {
378 mClientPid = getCallingPid();
379 return OK;
380 }
381
382 if (mClientPid != getCallingPid()) {
383 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
384 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
385 return EBUSY;
386 }
387
388 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700389}
390
391status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700392 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700393 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700394 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700395 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
396 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700397
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700398 // TODO: Check for uninterruptable conditions
399
400 if (mClientPid == getCallingPid()) {
401 mClientPid = 0;
402 mCameraClient.clear();
403 return OK;
404 }
405
406 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
407 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
408 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700409}
410
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700411status_t Camera2Client::setPreviewDisplay(
412 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700413 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700414 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700415 Mutex::Autolock icl(mICameraLock);
416
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700417 sp<IBinder> binder;
418 sp<ANativeWindow> window;
419 if (surface != 0) {
420 binder = surface->asBinder();
421 window = surface;
422 }
423
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700424 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700425}
426
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700427status_t Camera2Client::setPreviewTexture(
428 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700429 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700430 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700431 Mutex::Autolock icl(mICameraLock);
432
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700433 sp<IBinder> binder;
434 sp<ANativeWindow> window;
435 if (surfaceTexture != 0) {
436 binder = surfaceTexture->asBinder();
437 window = new SurfaceTextureClient(surfaceTexture);
438 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700439 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700440}
441
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700442status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700443 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700444 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700445 status_t res;
446
447 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700448 ALOGV("%s: Camera %d: New window is same as old window",
449 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700450 return NO_ERROR;
451 }
452
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700453 switch (mState) {
454 case NOT_INITIALIZED:
455 case RECORD:
456 case STILL_CAPTURE:
457 case VIDEO_SNAPSHOT:
458 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
459 __FUNCTION__, mCameraId, getStateName(mState));
460 return INVALID_OPERATION;
461 case STOPPED:
462 case WAITING_FOR_PREVIEW_WINDOW:
463 // OK
464 break;
465 case PREVIEW:
466 // Already running preview - need to stop and create a new stream
467 // TODO: Optimize this so that we don't wait for old stream to drain
468 // before spinning up new stream
469 mDevice->setStreamingRequest(NULL);
470 mState = WAITING_FOR_PREVIEW_WINDOW;
471 break;
472 }
473
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700474 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700475 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700476 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700477 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
478 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700479 return res;
480 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700481 res = mDevice->deleteStream(mPreviewStreamId);
482 if (res != OK) {
483 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
484 __FUNCTION__, strerror(-res), res);
485 return res;
486 }
487 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700488 }
489
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700490 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700491 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700492
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700493 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700494 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700495 }
496
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700497 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700498}
499
500void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700501 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700502 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700503}
504
505status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700506 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700507 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700508 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700509 return startPreviewLocked();
510}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700511
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700512status_t Camera2Client::startPreviewLocked() {
513 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700514 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700515 if (mState >= PREVIEW) {
516 ALOGE("%s: Can't start preview in state %s",
517 __FUNCTION__, getStateName(mState));
518 return INVALID_OPERATION;
519 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700520
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700521 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700522 mState = WAITING_FOR_PREVIEW_WINDOW;
523 return OK;
524 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700525 mState = STOPPED;
526
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700527 Mutex::Autolock pl(mParamsLock);
528
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700529 res = updatePreviewStream();
530 if (res != OK) {
531 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
532 __FUNCTION__, mCameraId, strerror(-res), res);
533 return res;
534 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700535
536 if (mPreviewRequest == NULL) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700537 res = updatePreviewRequest();
538 if (res != OK) {
539 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
540 __FUNCTION__, mCameraId, strerror(-res), res);
541 return res;
542 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700543 }
544
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700545 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700546 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700547 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700548 if (res != OK) {
549 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
550 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700551 return res;
552 }
553 res = sort_camera_metadata(mPreviewRequest);
554 if (res != OK) {
555 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
556 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700557 return res;
558 }
559
560 res = mDevice->setStreamingRequest(mPreviewRequest);
561 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700562 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
563 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700564 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700565 return res;
566 }
567 mState = PREVIEW;
568
569 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700570}
571
572void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700573 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700574 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700575 Mutex::Autolock icl(mICameraLock);
576 stopPreviewLocked();
577}
578
579void Camera2Client::stopPreviewLocked() {
580 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700581 switch (mState) {
582 case NOT_INITIALIZED:
583 ALOGE("%s: Camera %d: Call before initialized",
584 __FUNCTION__, mCameraId);
585 break;
586 case STOPPED:
587 break;
588 case STILL_CAPTURE:
589 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
590 __FUNCTION__, mCameraId);
591 break;
592 case RECORD:
593 // TODO: Handle record stop here
594 case PREVIEW:
595 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700596 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700597 case WAITING_FOR_PREVIEW_WINDOW:
598 mState = STOPPED;
599 break;
600 default:
601 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
602 mState);
603 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700604}
605
606bool Camera2Client::previewEnabled() {
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 Talvala6db981c2012-05-21 18:54:30 -0700609 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700610}
611
612status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700613 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700614 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700615 switch (mState) {
616 case RECORD:
617 case VIDEO_SNAPSHOT:
618 ALOGE("%s: Camera %d: Can't be called in state %s",
619 __FUNCTION__, mCameraId, getStateName(mState));
620 return INVALID_OPERATION;
621 default:
622 // OK
623 break;
624 }
625 Mutex::Autolock pl(mParamsLock);
626
627 mParameters.storeMetadataInBuffers = enabled;
628
629 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700630}
631
632status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700633 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700634 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700635 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700636 status_t res;
637 switch (mState) {
638 case STOPPED:
639 res = startPreviewLocked();
640 if (res != OK) return res;
641 break;
642 case PREVIEW:
643 // Ready to go
644 break;
645 case RECORD:
646 case VIDEO_SNAPSHOT:
647 // OK to call this when recording is already on
648 return OK;
649 break;
650 default:
651 ALOGE("%s: Camera %d: Can't start recording in state %s",
652 __FUNCTION__, mCameraId, getStateName(mState));
653 return INVALID_OPERATION;
654 };
655
656 Mutex::Autolock pl(mParamsLock);
657
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700658 if (!mParameters.storeMetadataInBuffers) {
659 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
660 "non-metadata recording mode requested!", __FUNCTION__,
661 mCameraId);
662 return INVALID_OPERATION;
663 }
664
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700665 res = updateRecordingStream();
666 if (res != OK) {
667 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
668 __FUNCTION__, mCameraId, strerror(-res), res);
669 return res;
670 }
671
672 if (mRecordingRequest == NULL) {
673 res = updateRecordingRequest();
674 if (res != OK) {
675 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
676 __FUNCTION__, mCameraId, strerror(-res), res);
677 return res;
678 }
679 }
680
681 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
682 res = updateEntry(mRecordingRequest,
683 ANDROID_REQUEST_OUTPUT_STREAMS,
684 outputStreams, 2);
685 if (res != OK) {
686 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
687 __FUNCTION__, mCameraId, strerror(-res), res);
688 return res;
689 }
690 res = sort_camera_metadata(mRecordingRequest);
691 if (res != OK) {
692 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
693 __FUNCTION__, mCameraId, strerror(-res), res);
694 return res;
695 }
696
697 res = mDevice->setStreamingRequest(mRecordingRequest);
698 if (res != OK) {
699 ALOGE("%s: Camera %d: Unable to set recording request to start "
700 "recording: %s (%d)", __FUNCTION__, mCameraId,
701 strerror(-res), res);
702 return res;
703 }
704 mState = RECORD;
705
706 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700707}
708
709void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700710 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700711 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700712 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700713 status_t res;
714 switch (mState) {
715 case RECORD:
716 // OK to stop
717 break;
718 case STOPPED:
719 case PREVIEW:
720 case STILL_CAPTURE:
721 case VIDEO_SNAPSHOT:
722 default:
723 ALOGE("%s: Camera %d: Can't stop recording in state %s",
724 __FUNCTION__, mCameraId, getStateName(mState));
725 return;
726 };
727
728 // Back to preview. Since record can only be reached through preview,
729 // all preview stream setup should be up to date.
730 res = mDevice->setStreamingRequest(mPreviewRequest);
731 if (res != OK) {
732 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
733 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
734 return;
735 }
736
737 // TODO: Should recording heap be freed? Can't do it yet since requests
738 // could still be in flight.
739
740 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700741}
742
743bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700744 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700745 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700746 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700747}
748
749void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700750 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700751 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700752 // Make sure this is for the current heap
753 ssize_t offset;
754 size_t size;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700755 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700756 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
757 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
758 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
759 "(got %x, expected %x)", __FUNCTION__, mCameraId,
760 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
761 return;
762 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700763 uint8_t *data = (uint8_t*)heap->getBase() + offset;
764 uint32_t type = *(uint32_t*)data;
765 if (type != kMetadataBufferTypeGrallocSource) {
766 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
767 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
768 return;
769 }
770 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
771 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700772 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700773 res = mRecordingConsumer->freeBuffer(imgBuffer);
774 if (res != OK) {
775 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
776 "%s (%d)",
777 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
778 return;
779 }
780
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700781 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700782}
783
784status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700785 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700786 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700787 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700788}
789
790status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700791 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700792 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700793 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700794}
795
796status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700797 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700798 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700799 status_t res;
800
801 switch (mState) {
802 case NOT_INITIALIZED:
803 case STOPPED:
804 case WAITING_FOR_PREVIEW_WINDOW:
805 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
806 __FUNCTION__, mCameraId);
807 return INVALID_OPERATION;
808 case PREVIEW:
809 case RECORD:
810 // Good to go for takePicture
811 break;
812 case STILL_CAPTURE:
813 case VIDEO_SNAPSHOT:
814 ALOGE("%s: Camera %d: Already taking a picture",
815 __FUNCTION__, mCameraId);
816 return INVALID_OPERATION;
817 }
818
819 Mutex::Autolock pl(mParamsLock);
820
821 res = updateCaptureStream();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700822 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700823 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
824 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700825 return res;
826 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700827
828 if (mCaptureRequest == NULL) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700829 res = updateCaptureRequest();
830 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700831 ALOGE("%s: Camera %d: Can't create still image capture request: "
832 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700833 return res;
834 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700835 }
836
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700837 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700838 if (mState == PREVIEW) {
839 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
840 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
841 &streamIds, 2);
842 } else if (mState == RECORD) {
843 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
844 mCaptureStreamId };
845 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
846 &streamIds, 3);
847 }
848
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700849 if (res != OK) {
850 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
851 "%s (%d)",
852 __FUNCTION__, mCameraId, strerror(-res), res);
853 return res;
854 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700855 res = sort_camera_metadata(mCaptureRequest);
856 if (res != OK) {
857 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
858 __FUNCTION__, mCameraId, strerror(-res), res);
859 return res;
860 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700861
862 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
863 if (captureCopy == NULL) {
864 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
865 __FUNCTION__, mCameraId);
866 return NO_MEMORY;
867 }
868
869 if (mState == PREVIEW) {
870 res = mDevice->setStreamingRequest(NULL);
871 if (res != OK) {
872 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
873 "%s (%d)",
874 __FUNCTION__, mCameraId, strerror(-res), res);
875 return res;
876 }
877 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700878 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700879 res = mDevice->capture(captureCopy);
880 if (res != OK) {
881 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
882 "%s (%d)",
883 __FUNCTION__, mCameraId, strerror(-res), res);
884 return res;
885 }
886
887 switch (mState) {
888 case PREVIEW:
889 mState = STILL_CAPTURE;
890 break;
891 case RECORD:
892 mState = VIDEO_SNAPSHOT;
893 break;
894 default:
895 ALOGE("%s: Camera %d: Unknown state for still capture!",
896 __FUNCTION__, mCameraId);
897 return INVALID_OPERATION;
898 }
899
900 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700901}
902
903status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700904 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700905 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700906 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700907 Mutex::Autolock pl(mParamsLock);
908 status_t res;
909
910 CameraParameters newParams(params);
911
912 // TODO: Currently ignoring any changes to supposedly read-only
913 // parameters such as supported preview sizes, etc. Should probably
914 // produce an error if they're changed.
915
916 /** Extract and verify new parameters */
917
918 size_t i;
919
920 // PREVIEW_SIZE
921 int previewWidth, previewHeight;
922 newParams.getPreviewSize(&previewWidth, &previewHeight);
923
924 if (previewWidth != mParameters.previewWidth ||
925 previewHeight != mParameters.previewHeight) {
926 if (mState >= PREVIEW) {
927 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700928 "is active! (Currently %d x %d, requested %d x %d",
929 __FUNCTION__,
930 mParameters.previewWidth, mParameters.previewHeight,
931 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700932 return BAD_VALUE;
933 }
934 camera_metadata_entry_t availablePreviewSizes =
935 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
936 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
937 if (availablePreviewSizes.data.i32[i] == previewWidth &&
938 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
939 }
940 if (i == availablePreviewSizes.count) {
941 ALOGE("%s: Requested preview size %d x %d is not supported",
942 __FUNCTION__, previewWidth, previewHeight);
943 return BAD_VALUE;
944 }
945 }
946
947 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700948 int previewFpsRange[2];
949 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700950 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700951 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
952 if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
953 previewFpsRange[1] != mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700954 fpsRangeChanged = true;
955 camera_metadata_entry_t availablePreviewFpsRanges =
956 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
957 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
958 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700959 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700960 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700961 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700962 break;
963 }
964 }
965 if (i == availablePreviewFpsRanges.count) {
966 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700967 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700968 return BAD_VALUE;
969 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700970 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700971 }
972
973 // PREVIEW_FORMAT
974 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
975 if (previewFormat != mParameters.previewFormat) {
976 if (mState >= PREVIEW) {
977 ALOGE("%s: Preview format cannot be updated when preview "
978 "is active!", __FUNCTION__);
979 return BAD_VALUE;
980 }
981 camera_metadata_entry_t availableFormats =
982 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
983 for (i = 0; i < availableFormats.count; i++) {
984 if (availableFormats.data.i32[i] == previewFormat) break;
985 }
986 if (i == availableFormats.count) {
987 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
988 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
989 return BAD_VALUE;
990 }
991 }
992
993 // PREVIEW_FRAME_RATE
994 // Deprecated, only use if the preview fps range is unchanged this time.
995 // The single-value FPS is the same as the minimum of the range.
996 if (!fpsRangeChanged) {
997 previewFps = newParams.getPreviewFrameRate();
998 if (previewFps != mParameters.previewFps) {
999 camera_metadata_entry_t availableFrameRates =
1000 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1001 for (i = 0; i < availableFrameRates.count; i+=2) {
1002 if (availableFrameRates.data.i32[i] == previewFps) break;
1003 }
1004 if (i == availableFrameRates.count) {
1005 ALOGE("%s: Requested preview frame rate %d is not supported",
1006 __FUNCTION__, previewFps);
1007 return BAD_VALUE;
1008 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001009 previewFpsRange[0] = availableFrameRates.data.i32[i];
1010 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001011 }
1012 }
1013
1014 // PICTURE_SIZE
1015 int pictureWidth, pictureHeight;
1016 newParams.getPictureSize(&pictureWidth, &pictureHeight);
1017 if (pictureWidth == mParameters.pictureWidth ||
1018 pictureHeight == mParameters.pictureHeight) {
1019 camera_metadata_entry_t availablePictureSizes =
1020 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1021 for (i = 0; i < availablePictureSizes.count; i+=2) {
1022 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1023 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1024 }
1025 if (i == availablePictureSizes.count) {
1026 ALOGE("%s: Requested picture size %d x %d is not supported",
1027 __FUNCTION__, pictureWidth, pictureHeight);
1028 return BAD_VALUE;
1029 }
1030 }
1031
1032 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001033 int jpegThumbSize[2];
1034 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001035 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001036 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001037 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001038 if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
1039 jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001040 camera_metadata_entry_t availableJpegThumbSizes =
1041 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1042 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001043 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1044 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001045 break;
1046 }
1047 }
1048 if (i == availableJpegThumbSizes.count) {
1049 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001050 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001051 return BAD_VALUE;
1052 }
1053 }
1054
1055 // JPEG_THUMBNAIL_QUALITY
1056 int jpegThumbQuality =
1057 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1058 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1059 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1060 __FUNCTION__, jpegThumbQuality);
1061 return BAD_VALUE;
1062 }
1063
1064 // JPEG_QUALITY
1065 int jpegQuality =
1066 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1067 if (jpegQuality < 0 || jpegQuality > 100) {
1068 ALOGE("%s: Requested JPEG quality %d is not supported",
1069 __FUNCTION__, jpegQuality);
1070 return BAD_VALUE;
1071 }
1072
1073 // ROTATION
1074 int jpegRotation =
1075 newParams.getInt(CameraParameters::KEY_ROTATION);
1076 if (jpegRotation != 0 &&
1077 jpegRotation != 90 &&
1078 jpegRotation != 180 &&
1079 jpegRotation != 270) {
1080 ALOGE("%s: Requested picture rotation angle %d is not supported",
1081 __FUNCTION__, jpegRotation);
1082 return BAD_VALUE;
1083 }
1084
1085 // GPS
1086 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001087 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001088 int64_t gpsTimestamp = 0;
1089 String8 gpsProcessingMethod;
1090 const char *gpsLatStr =
1091 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1092 if (gpsLatStr != NULL) {
1093 const char *gpsLongStr =
1094 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1095 const char *gpsAltitudeStr =
1096 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1097 const char *gpsTimeStr =
1098 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1099 const char *gpsProcMethodStr =
1100 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1101 if (gpsLongStr == NULL ||
1102 gpsAltitudeStr == NULL ||
1103 gpsTimeStr == NULL ||
1104 gpsProcMethodStr == NULL) {
1105 ALOGE("%s: Incomplete set of GPS parameters provided",
1106 __FUNCTION__);
1107 return BAD_VALUE;
1108 }
1109 char *endPtr;
1110 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001111 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001112 if (errno || endPtr == gpsLatStr) {
1113 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1114 return BAD_VALUE;
1115 }
1116 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001117 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001118 if (errno || endPtr == gpsLongStr) {
1119 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1120 return BAD_VALUE;
1121 }
1122 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001123 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001124 if (errno || endPtr == gpsAltitudeStr) {
1125 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1126 gpsAltitudeStr);
1127 return BAD_VALUE;
1128 }
1129 errno = 0;
1130 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1131 if (errno || endPtr == gpsTimeStr) {
1132 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1133 return BAD_VALUE;
1134 }
1135 gpsProcessingMethod = gpsProcMethodStr;
1136
1137 gpsEnabled = true;
1138 }
1139
1140 // WHITE_BALANCE
1141 int wbMode = wbModeStringToEnum(
1142 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
1143 if (wbMode != mParameters.wbMode) {
1144 camera_metadata_entry_t availableWbModes =
1145 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1146 for (i = 0; i < availableWbModes.count; i++) {
1147 if (wbMode == availableWbModes.data.u8[i]) break;
1148 }
1149 if (i == availableWbModes.count) {
1150 ALOGE("%s: Requested white balance mode %s is not supported",
1151 __FUNCTION__,
1152 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1153 return BAD_VALUE;
1154 }
1155 }
1156
1157 // EFFECT
1158 int effectMode = effectModeStringToEnum(
1159 newParams.get(CameraParameters::KEY_EFFECT) );
1160 if (effectMode != mParameters.effectMode) {
1161 camera_metadata_entry_t availableEffectModes =
1162 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1163 for (i = 0; i < availableEffectModes.count; i++) {
1164 if (effectMode == availableEffectModes.data.u8[i]) break;
1165 }
1166 if (i == availableEffectModes.count) {
1167 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1168 __FUNCTION__,
1169 newParams.get(CameraParameters::KEY_EFFECT) );
1170 return BAD_VALUE;
1171 }
1172 }
1173
1174 // ANTIBANDING
1175 int antibandingMode = abModeStringToEnum(
1176 newParams.get(CameraParameters::KEY_ANTIBANDING) );
1177 if (antibandingMode != mParameters.antibandingMode) {
1178 camera_metadata_entry_t availableAbModes =
1179 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1180 for (i = 0; i < availableAbModes.count; i++) {
1181 if (antibandingMode == availableAbModes.data.u8[i]) break;
1182 }
1183 if (i == availableAbModes.count) {
1184 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1185 __FUNCTION__,
1186 newParams.get(CameraParameters::KEY_ANTIBANDING));
1187 return BAD_VALUE;
1188 }
1189 }
1190
1191 // SCENE_MODE
1192 int sceneMode = sceneModeStringToEnum(
1193 newParams.get(CameraParameters::KEY_SCENE_MODE) );
1194 if (sceneMode != mParameters.sceneMode) {
1195 camera_metadata_entry_t availableSceneModes =
1196 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1197 for (i = 0; i < availableSceneModes.count; i++) {
1198 if (sceneMode == availableSceneModes.data.u8[i]) break;
1199 }
1200 if (i == availableSceneModes.count) {
1201 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1202 __FUNCTION__,
1203 newParams.get(CameraParameters::KEY_SCENE_MODE));
1204 return BAD_VALUE;
1205 }
1206 }
1207
1208 // FLASH_MODE
1209 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1210 newParams.get(CameraParameters::KEY_FLASH_MODE) );
1211 if (flashMode != mParameters.flashMode) {
1212 camera_metadata_entry_t flashAvailable =
1213 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1214 if (!flashAvailable.data.u8[0] &&
1215 flashMode != Parameters::FLASH_MODE_OFF) {
1216 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1217 "No flash on device", __FUNCTION__,
1218 newParams.get(CameraParameters::KEY_FLASH_MODE));
1219 return BAD_VALUE;
1220 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1221 camera_metadata_entry_t availableAeModes =
1222 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1223 for (i = 0; i < availableAeModes.count; i++) {
1224 if (flashMode == availableAeModes.data.u8[i]) break;
1225 }
1226 if (i == availableAeModes.count) {
1227 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1228 __FUNCTION__,
1229 newParams.get(CameraParameters::KEY_FLASH_MODE));
1230 return BAD_VALUE;
1231 }
1232 } else if (flashMode == -1) {
1233 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1234 __FUNCTION__,
1235 newParams.get(CameraParameters::KEY_FLASH_MODE));
1236 return BAD_VALUE;
1237 }
1238 }
1239
1240 // FOCUS_MODE
1241 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1242 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1243 if (focusMode != mParameters.focusMode) {
1244 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1245 camera_metadata_entry_t minFocusDistance =
1246 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1247 if (minFocusDistance.data.f[0] == 0) {
1248 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1249 "fixed focus lens",
1250 __FUNCTION__,
1251 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1252 return BAD_VALUE;
1253 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1254 camera_metadata_entry_t availableFocusModes =
1255 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1256 for (i = 0; i < availableFocusModes.count; i++) {
1257 if (focusMode == availableFocusModes.data.u8[i]) break;
1258 }
1259 if (i == availableFocusModes.count) {
1260 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1261 __FUNCTION__,
1262 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1263 return BAD_VALUE;
1264 }
1265 }
1266 }
1267 }
1268
1269 // FOCUS_AREAS
1270 Vector<Parameters::Area> focusingAreas;
1271 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1272 &focusingAreas);
1273 size_t max3aRegions =
1274 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1275 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1276 if (res != OK) {
1277 ALOGE("%s: Requested focus areas are malformed: %s",
1278 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1279 return BAD_VALUE;
1280 }
1281
1282 // EXPOSURE_COMPENSATION
1283 int exposureCompensation =
1284 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1285 camera_metadata_entry_t exposureCompensationRange =
1286 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1287 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1288 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1289 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1290 __FUNCTION__, exposureCompensation);
1291 return BAD_VALUE;
1292 }
1293
1294 // AUTO_EXPOSURE_LOCK (always supported)
1295 bool autoExposureLock = boolFromString(
1296 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1297
1298 // AUTO_WHITEBALANCE_LOCK (always supported)
1299 bool autoWhiteBalanceLock = boolFromString(
1300 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1301
1302 // METERING_AREAS
1303 Vector<Parameters::Area> meteringAreas;
1304 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1305 &meteringAreas);
1306 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1307 if (res != OK) {
1308 ALOGE("%s: Requested metering areas are malformed: %s",
1309 __FUNCTION__,
1310 newParams.get(CameraParameters::KEY_METERING_AREAS));
1311 return BAD_VALUE;
1312 }
1313
1314 // ZOOM
1315 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1316 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1317 ALOGE("%s: Requested zoom level %d is not supported",
1318 __FUNCTION__, zoom);
1319 return BAD_VALUE;
1320 }
1321
1322 // VIDEO_SIZE
1323 int videoWidth, videoHeight;
1324 newParams.getVideoSize(&videoWidth, &videoHeight);
1325 if (videoWidth != mParameters.videoWidth ||
1326 videoHeight != mParameters.videoHeight) {
1327 if (mState == RECORD) {
1328 ALOGE("%s: Video size cannot be updated when recording is active!",
1329 __FUNCTION__);
1330 return BAD_VALUE;
1331 }
1332 camera_metadata_entry_t availableVideoSizes =
1333 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1334 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1335 if (availableVideoSizes.data.i32[i] == videoWidth &&
1336 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1337 }
1338 if (i == availableVideoSizes.count) {
1339 ALOGE("%s: Requested video size %d x %d is not supported",
1340 __FUNCTION__, videoWidth, videoHeight);
1341 return BAD_VALUE;
1342 }
1343 }
1344
1345 // RECORDING_HINT (always supported)
1346 bool recordingHint = boolFromString(
1347 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1348
1349 // VIDEO_STABILIZATION
1350 bool videoStabilization = boolFromString(
1351 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1352 camera_metadata_entry_t availableVideoStabilizationModes =
1353 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1354 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1355 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1356 }
1357
1358 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001359
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001360 mParameters.previewWidth = previewWidth;
1361 mParameters.previewHeight = previewHeight;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001362 mParameters.previewFpsRange[0] = previewFpsRange[0];
1363 mParameters.previewFpsRange[1] = previewFpsRange[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001364 mParameters.previewFps = previewFps;
1365 mParameters.previewFormat = previewFormat;
1366
1367 mParameters.pictureWidth = pictureWidth;
1368 mParameters.pictureHeight = pictureHeight;
1369
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001370 mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1371 mParameters.jpegThumbSize[1] = jpegThumbSize[1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001372 mParameters.jpegQuality = jpegQuality;
1373 mParameters.jpegThumbQuality = jpegThumbQuality;
1374
1375 mParameters.gpsEnabled = gpsEnabled;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001376 mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1377 mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1378 mParameters.gpsCoordinates[2] = gpsCoordinates[2];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001379 mParameters.gpsTimestamp = gpsTimestamp;
1380 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1381
1382 mParameters.wbMode = wbMode;
1383 mParameters.effectMode = effectMode;
1384 mParameters.antibandingMode = antibandingMode;
1385 mParameters.sceneMode = sceneMode;
1386
1387 mParameters.flashMode = flashMode;
1388 mParameters.focusMode = focusMode;
1389
1390 mParameters.focusingAreas = focusingAreas;
1391 mParameters.exposureCompensation = exposureCompensation;
1392 mParameters.autoExposureLock = autoExposureLock;
1393 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1394 mParameters.meteringAreas = meteringAreas;
1395 mParameters.zoom = zoom;
1396
1397 mParameters.videoWidth = videoWidth;
1398 mParameters.videoHeight = videoHeight;
1399
1400 mParameters.recordingHint = recordingHint;
1401 mParameters.videoStabilization = videoStabilization;
1402
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001403 res = updatePreviewRequest();
1404 if (res != OK) {
1405 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1406 __FUNCTION__, mCameraId, strerror(-res), res);
1407 return res;
1408 }
1409 res = updateCaptureRequest();
1410 if (res != OK) {
1411 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1412 __FUNCTION__, mCameraId, strerror(-res), res);
1413 return res;
1414 }
1415
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001416 res = updateRecordingRequest();
1417 if (res != OK) {
1418 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1419 __FUNCTION__, mCameraId, strerror(-res), res);
1420 return res;
1421 }
1422
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001423 if (mState == PREVIEW) {
1424 res = mDevice->setStreamingRequest(mPreviewRequest);
1425 if (res != OK) {
1426 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1427 __FUNCTION__, mCameraId, strerror(-res), res);
1428 return res;
1429 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001430 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1431 res = mDevice->setStreamingRequest(mRecordingRequest);
1432 if (res != OK) {
1433 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1434 __FUNCTION__, mCameraId, strerror(-res), res);
1435 return res;
1436 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001437 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001438
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001439 mParamsFlattened = params;
1440
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001441 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001442}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001443
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001444String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001445 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001446 Mutex::Autolock icl(mICameraLock);
1447
1448 Mutex::Autolock pl(mParamsLock);
1449
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001450 // TODO: Deal with focus distances
1451 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001452}
1453
1454status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001455 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001456 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001457
1458 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1459 cmd, arg1, arg2);
1460
1461 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
1462 int transform = degToTransform(arg1,
1463 mCameraFacing == CAMERA_FACING_FRONT);
1464 if (transform == -1) {
1465 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1466 __FUNCTION__, mCameraId, arg1);
1467 return BAD_VALUE;
1468 }
1469 if (transform != mParameters.previewTransform &&
1470 mPreviewStreamId != NO_STREAM) {
1471 mDevice->setStreamTransform(mPreviewStreamId, transform);
1472 }
1473 mParameters.previewTransform = transform;
1474 return OK;
1475 }
1476
1477 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1478 mCameraId, cmd, arg1, arg2);
1479
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001480 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001481}
1482
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001483/** Device-related methods */
1484
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001485void Camera2Client::onCaptureAvailable() {
1486 ATRACE_CALL();
1487 status_t res;
1488 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001489 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1490
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001491 CpuConsumer::LockedBuffer imgBuffer;
1492 {
1493 Mutex::Autolock icl(mICameraLock);
1494
1495 // TODO: Signal errors here upstream
1496 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1497 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1498 __FUNCTION__, mCameraId);
1499 return;
1500 }
1501
1502 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1503 if (res != OK) {
1504 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1505 __FUNCTION__, mCameraId, strerror(-res), res);
1506 return;
1507 }
1508
1509 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1510 ALOGE("%s: Camera %d: Unexpected format for still image: "
1511 "%x, expected %x", __FUNCTION__, mCameraId,
1512 imgBuffer.format,
1513 HAL_PIXEL_FORMAT_BLOB);
1514 mCaptureConsumer->unlockBuffer(imgBuffer);
1515 return;
1516 }
1517
1518 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001519 void* captureMemory = mCaptureHeap->mHeap->getBase();
1520 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001521 memcpy(captureMemory, imgBuffer.data, size);
1522
1523 mCaptureConsumer->unlockBuffer(imgBuffer);
1524
1525 currentClient = mCameraClient;
1526 switch (mState) {
1527 case STILL_CAPTURE:
1528 mState = STOPPED;
1529 break;
1530 case VIDEO_SNAPSHOT:
1531 mState = RECORD;
1532 break;
1533 default:
1534 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1535 mCameraId, mState);
1536 break;
1537 }
1538 }
1539 // Call outside mICameraLock to allow re-entrancy from notification
1540 if (currentClient != 0) {
1541 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001542 mCaptureHeap->mBuffers[0], NULL);
1543 }
1544}
1545
1546void Camera2Client::onRecordingFrameAvailable() {
1547 ATRACE_CALL();
1548 status_t res;
1549 sp<ICameraClient> currentClient;
1550 size_t heapIdx = 0;
1551 nsecs_t timestamp;
1552 {
1553 Mutex::Autolock icl(mICameraLock);
1554 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001555 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001556 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001557 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1558 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001559 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001560 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001561 }
1562
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001563 buffer_handle_t imgBuffer;
1564 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001565 if (res != OK) {
1566 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1567 __FUNCTION__, mCameraId, strerror(-res), res);
1568 return;
1569 }
1570
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001571 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001572 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001573 return;
1574 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001575
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001576 if (mRecordingHeap == 0) {
1577 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001578 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1579 "size %d bytes", __FUNCTION__, mCameraId,
1580 kRecordingHeapCount, bufferSize);
1581 if (mRecordingHeap != 0) {
1582 ALOGV("%s: Camera %d: Previous heap has size %d "
1583 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1584 mRecordingHeap->mHeap->getSize(),
1585 bufferSize * kRecordingHeapCount);
1586 }
1587 // Need to allocate memory for heap
1588 mRecordingHeap.clear();
1589
1590 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1591 "Camera2Client::RecordingHeap");
1592 if (mRecordingHeap->mHeap->getSize() == 0) {
1593 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1594 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001595 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001596 return;
1597 }
1598 mRecordingHeapHead = 0;
1599 mRecordingHeapFree = kRecordingHeapCount;
1600 }
1601
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001602 if ( mRecordingHeapFree == 0) {
1603 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1604 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001605 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001606 return;
1607 }
1608 heapIdx = mRecordingHeapHead;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001609 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1610 mRecordingHeapFree--;
1611
1612 ALOGV("%s: Camera %d: Timestamp %lld",
1613 __FUNCTION__, mCameraId, timestamp);
1614
1615 ssize_t offset;
1616 size_t size;
1617 sp<IMemoryHeap> heap =
1618 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1619 &size);
1620
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001621 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1622 uint32_t type = kMetadataBufferTypeGrallocSource;
1623 memcpy(data, &type, 4);
1624 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1625 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001626 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001627 currentClient = mCameraClient;
1628 }
1629 // Call outside mICameraLock to allow re-entrancy from notification
1630 if (currentClient != 0) {
1631 currentClient->dataCallbackTimestamp(timestamp,
1632 CAMERA_MSG_VIDEO_FRAME,
1633 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001634 }
1635}
1636
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001637camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1638 size_t minCount, size_t maxCount) {
1639 status_t res;
1640 camera_metadata_entry_t entry;
1641 res = find_camera_metadata_entry(mDevice->info(),
1642 tag,
1643 &entry);
1644 if (CC_UNLIKELY( res != OK )) {
1645 const char* tagSection = get_camera_metadata_section_name(tag);
1646 if (tagSection == NULL) tagSection = "<unknown>";
1647 const char* tagName = get_camera_metadata_tag_name(tag);
1648 if (tagName == NULL) tagName = "<unknown>";
1649
1650 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1651 tagSection, tagName, tag, strerror(-res), res);
1652 entry.count = 0;
1653 entry.data.u8 = NULL;
1654 } else if (CC_UNLIKELY(
1655 (minCount != 0 && entry.count < minCount) ||
1656 (maxCount != 0 && entry.count > maxCount) ) ) {
1657 const char* tagSection = get_camera_metadata_section_name(tag);
1658 if (tagSection == NULL) tagSection = "<unknown>";
1659 const char* tagName = get_camera_metadata_tag_name(tag);
1660 if (tagName == NULL) tagName = "<unknown>";
1661 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1662 "Expected between %d and %d values, but got %d values",
1663 tagSection, tagName, tag, minCount, maxCount, entry.count);
1664 entry.count = 0;
1665 entry.data.u8 = NULL;
1666 }
1667
1668 return entry;
1669}
1670
1671/** Utility methods */
1672
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001673
1674status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001675 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001676 Mutex::Autolock pl(mParamsLock);
1677
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001678 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001679 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001680
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001681 camera_metadata_entry_t availableProcessedSizes =
1682 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1683 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001684
1685 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001686 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1687 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1688 mParameters.videoWidth = mParameters.previewWidth;
1689 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001690
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001691 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1692 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1693 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1694 String8::format("%dx%d",
1695 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001696 {
1697 String8 supportedPreviewSizes;
1698 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1699 if (i != 0) supportedPreviewSizes += ",";
1700 supportedPreviewSizes += String8::format("%dx%d",
1701 availableProcessedSizes.data.i32[i],
1702 availableProcessedSizes.data.i32[i+1]);
1703 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001704 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001705 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001706 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001707 supportedPreviewSizes);
1708 }
1709
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001710 camera_metadata_entry_t availableFpsRanges =
1711 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1712 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001713
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001714 mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1715 mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001716
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001717 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1718 String8::format("%d,%d",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001719 mParameters.previewFpsRange[0],
1720 mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001721
1722 {
1723 String8 supportedPreviewFpsRange;
1724 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1725 if (i != 0) supportedPreviewFpsRange += ",";
1726 supportedPreviewFpsRange += String8::format("(%d,%d)",
1727 availableFpsRanges.data.i32[i],
1728 availableFpsRanges.data.i32[i+1]);
1729 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001730 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001731 supportedPreviewFpsRange);
1732 }
1733
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001734 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1735 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1736 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001737
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001738 mParameters.previewTransform = degToTransform(0,
1739 mCameraFacing == CAMERA_FACING_FRONT);
1740
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001741 camera_metadata_entry_t availableFormats =
1742 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1743
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001744 {
1745 String8 supportedPreviewFormats;
1746 bool addComma = false;
1747 for (size_t i=0; i < availableFormats.count; i++) {
1748 if (addComma) supportedPreviewFormats += ",";
1749 addComma = true;
1750 switch (availableFormats.data.i32[i]) {
1751 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001752 supportedPreviewFormats +=
1753 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001754 break;
1755 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001756 supportedPreviewFormats +=
1757 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001758 break;
1759 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001760 supportedPreviewFormats +=
1761 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001762 break;
1763 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001764 supportedPreviewFormats +=
1765 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001766 break;
1767 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001768 supportedPreviewFormats +=
1769 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001770 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001771 case HAL_PIXEL_FORMAT_RGBA_8888:
1772 supportedPreviewFormats +=
1773 CameraParameters::PIXEL_FORMAT_RGBA8888;
1774 break;
1775 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001776 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001777 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001778 addComma = false;
1779 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001780
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001781 default:
1782 ALOGW("%s: Camera %d: Unknown preview format: %x",
1783 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1784 addComma = false;
1785 break;
1786 }
1787 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001788 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001789 supportedPreviewFormats);
1790 }
1791
1792 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1793 // still have to do something sane for them
1794
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001795 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001796 mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001797
1798 {
1799 String8 supportedPreviewFrameRates;
1800 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1801 if (i != 0) supportedPreviewFrameRates += ",";
1802 supportedPreviewFrameRates += String8::format("%d",
1803 availableFpsRanges.data.i32[i]);
1804 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001805 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001806 supportedPreviewFrameRates);
1807 }
1808
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001809 camera_metadata_entry_t availableJpegSizes =
1810 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1811 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001812
1813 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001814 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1815 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001816
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001817 params.setPictureSize(mParameters.pictureWidth,
1818 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001819
1820 {
1821 String8 supportedPictureSizes;
1822 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1823 if (i != 0) supportedPictureSizes += ",";
1824 supportedPictureSizes += String8::format("%dx%d",
1825 availableJpegSizes.data.i32[i],
1826 availableJpegSizes.data.i32[i+1]);
1827 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001828 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001829 supportedPictureSizes);
1830 }
1831
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001832 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1833 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1834 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001835
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001836 camera_metadata_entry_t availableJpegThumbnailSizes =
1837 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1838 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001839
1840 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001841 mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1842 mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001843
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001844 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001845 mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001846 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001847 mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001848
1849 {
1850 String8 supportedJpegThumbSizes;
1851 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1852 if (i != 0) supportedJpegThumbSizes += ",";
1853 supportedJpegThumbSizes += String8::format("%dx%d",
1854 availableJpegThumbnailSizes.data.i32[i],
1855 availableJpegThumbnailSizes.data.i32[i+1]);
1856 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001857 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001858 supportedJpegThumbSizes);
1859 }
1860
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001861 mParameters.jpegThumbQuality = 90;
1862 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1863 mParameters.jpegThumbQuality);
1864 mParameters.jpegQuality = 90;
1865 params.set(CameraParameters::KEY_JPEG_QUALITY,
1866 mParameters.jpegQuality);
1867 mParameters.jpegRotation = 0;
1868 params.set(CameraParameters::KEY_ROTATION,
1869 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001870
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001871 mParameters.gpsEnabled = false;
1872 mParameters.gpsProcessingMethod = "unknown";
1873 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001874
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001875 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1876 params.set(CameraParameters::KEY_WHITE_BALANCE,
1877 CameraParameters::WHITE_BALANCE_AUTO);
1878
1879 camera_metadata_entry_t availableWhiteBalanceModes =
1880 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001881 {
1882 String8 supportedWhiteBalance;
1883 bool addComma = false;
1884 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1885 if (addComma) supportedWhiteBalance += ",";
1886 addComma = true;
1887 switch (availableWhiteBalanceModes.data.u8[i]) {
1888 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001889 supportedWhiteBalance +=
1890 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001891 break;
1892 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001893 supportedWhiteBalance +=
1894 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001895 break;
1896 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001897 supportedWhiteBalance +=
1898 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001899 break;
1900 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001901 supportedWhiteBalance +=
1902 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001903 break;
1904 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001905 supportedWhiteBalance +=
1906 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001907 break;
1908 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001909 supportedWhiteBalance +=
1910 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001911 break;
1912 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001913 supportedWhiteBalance +=
1914 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915 break;
1916 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001917 supportedWhiteBalance +=
1918 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001919 break;
1920 // Skipping values not mappable to v1 API
1921 case ANDROID_CONTROL_AWB_OFF:
1922 addComma = false;
1923 break;
1924 default:
1925 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1926 __FUNCTION__, mCameraId,
1927 availableWhiteBalanceModes.data.u8[i]);
1928 addComma = false;
1929 break;
1930 }
1931 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001932 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001933 supportedWhiteBalance);
1934 }
1935
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001936 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1937 params.set(CameraParameters::KEY_EFFECT,
1938 CameraParameters::EFFECT_NONE);
1939
1940 camera_metadata_entry_t availableEffects =
1941 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1942 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001943 {
1944 String8 supportedEffects;
1945 bool addComma = false;
1946 for (size_t i=0; i < availableEffects.count; i++) {
1947 if (addComma) supportedEffects += ",";
1948 addComma = true;
1949 switch (availableEffects.data.u8[i]) {
1950 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001951 supportedEffects +=
1952 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001953 break;
1954 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001955 supportedEffects +=
1956 CameraParameters::EFFECT_MONO;
1957 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001958 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001959 supportedEffects +=
1960 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001961 break;
1962 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001963 supportedEffects +=
1964 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001965 break;
1966 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001967 supportedEffects +=
1968 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001969 break;
1970 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001971 supportedEffects +=
1972 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001973 break;
1974 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001975 supportedEffects +=
1976 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001977 break;
1978 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001979 supportedEffects +=
1980 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001981 break;
1982 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001983 supportedEffects +=
1984 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001985 break;
1986 default:
1987 ALOGW("%s: Camera %d: Unknown effect value: %d",
1988 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1989 addComma = false;
1990 break;
1991 }
1992 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001993 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001994 }
1995
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001996 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1997 params.set(CameraParameters::KEY_ANTIBANDING,
1998 CameraParameters::ANTIBANDING_AUTO);
1999
2000 camera_metadata_entry_t availableAntibandingModes =
2001 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2002 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002003 {
2004 String8 supportedAntibanding;
2005 bool addComma = false;
2006 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2007 if (addComma) supportedAntibanding += ",";
2008 addComma = true;
2009 switch (availableAntibandingModes.data.u8[i]) {
2010 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002011 supportedAntibanding +=
2012 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002013 break;
2014 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002015 supportedAntibanding +=
2016 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017 break;
2018 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002019 supportedAntibanding +=
2020 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002021 break;
2022 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002023 supportedAntibanding +=
2024 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002025 break;
2026 default:
2027 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2028 __FUNCTION__, mCameraId,
2029 availableAntibandingModes.data.u8[i]);
2030 addComma = false;
2031 break;
2032 }
2033 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002034 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002035 supportedAntibanding);
2036 }
2037
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002038 mParameters.sceneMode = ANDROID_CONTROL_OFF;
2039 params.set(CameraParameters::KEY_SCENE_MODE,
2040 CameraParameters::SCENE_MODE_AUTO);
2041
2042 camera_metadata_entry_t availableSceneModes =
2043 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2044 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002045 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002046 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002047 bool addComma = true;
2048 bool noSceneModes = false;
2049 for (size_t i=0; i < availableSceneModes.count; i++) {
2050 if (addComma) supportedSceneModes += ",";
2051 addComma = true;
2052 switch (availableSceneModes.data.u8[i]) {
2053 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2054 noSceneModes = true;
2055 break;
2056 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2057 // Not in old API
2058 addComma = false;
2059 break;
2060 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002061 supportedSceneModes +=
2062 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002063 break;
2064 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002065 supportedSceneModes +=
2066 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002067 break;
2068 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002069 supportedSceneModes +=
2070 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002071 break;
2072 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002073 supportedSceneModes +=
2074 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002075 break;
2076 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002077 supportedSceneModes +=
2078 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002079 break;
2080 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002081 supportedSceneModes +=
2082 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002083 break;
2084 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002085 supportedSceneModes +=
2086 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002087 break;
2088 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002089 supportedSceneModes +=
2090 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002091 break;
2092 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002093 supportedSceneModes +=
2094 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002095 break;
2096 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002097 supportedSceneModes +=
2098 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002099 break;
2100 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002101 supportedSceneModes +=
2102 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002103 break;
2104 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002105 supportedSceneModes +=
2106 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002107 break;
2108 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002109 supportedSceneModes +=
2110 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002111 break;
2112 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002113 supportedSceneModes +=
2114 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002115 break;
2116 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002117 supportedSceneModes +=
2118 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002119 break;
2120 default:
2121 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002122 __FUNCTION__, mCameraId,
2123 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002124 addComma = false;
2125 break;
2126 }
2127 }
2128 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002129 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002130 supportedSceneModes);
2131 }
2132 }
2133
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002134 camera_metadata_entry_t flashAvailable =
2135 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2136 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002137
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002138 camera_metadata_entry_t availableAeModes =
2139 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2140 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002141
2142 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002143 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
2144 params.set(CameraParameters::KEY_FLASH_MODE,
2145 CameraParameters::FLASH_MODE_AUTO);
2146
2147 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2148 supportedFlashModes = supportedFlashModes +
2149 "," + CameraParameters::FLASH_MODE_AUTO +
2150 "," + CameraParameters::FLASH_MODE_ON +
2151 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002152 for (size_t i=0; i < availableAeModes.count; i++) {
2153 if (availableAeModes.data.u8[i] ==
2154 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002155 supportedFlashModes = supportedFlashModes + "," +
2156 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002157 break;
2158 }
2159 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002160 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002161 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002162 } else {
2163 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
2164 params.set(CameraParameters::KEY_FLASH_MODE,
2165 CameraParameters::FLASH_MODE_OFF);
2166 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2167 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002168 }
2169
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002170 camera_metadata_entry_t minFocusDistance =
2171 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2172 if (!minFocusDistance.count) return NO_INIT;
2173
2174 camera_metadata_entry_t availableAfModes =
2175 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2176 if (!availableAfModes.count) return NO_INIT;
2177
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002178 if (minFocusDistance.data.f[0] == 0) {
2179 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002180 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
2181 params.set(CameraParameters::KEY_FOCUS_MODE,
2182 CameraParameters::FOCUS_MODE_FIXED);
2183 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2184 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002185 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002186 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
2187 params.set(CameraParameters::KEY_FOCUS_MODE,
2188 CameraParameters::FOCUS_MODE_AUTO);
2189 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2190 supportedFocusModes = supportedFocusModes + "," +
2191 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002192 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002193
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002194 for (size_t i=0; i < availableAfModes.count; i++) {
2195 if (addComma) supportedFocusModes += ",";
2196 addComma = true;
2197 switch (availableAfModes.data.u8[i]) {
2198 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002199 supportedFocusModes +=
2200 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002201 break;
2202 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002203 supportedFocusModes +=
2204 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002205 break;
2206 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002207 supportedFocusModes +=
2208 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002209 break;
2210 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002211 supportedFocusModes +=
2212 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002213 break;
2214 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002215 supportedFocusModes +=
2216 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002217 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002218 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002219 case ANDROID_CONTROL_AF_OFF:
2220 addComma = false;
2221 break;
2222 default:
2223 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2224 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2225 addComma = false;
2226 break;
2227 }
2228 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002229 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002230 supportedFocusModes);
2231 }
2232
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002233 camera_metadata_entry_t max3aRegions =
2234 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2235 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002236
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002237 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002238 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002239 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002240 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002241 mParameters.focusingAreas.clear();
2242 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002243
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002244 camera_metadata_entry_t availableFocalLengths =
2245 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2246 if (!availableFocalLengths.count) return NO_INIT;
2247
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002248 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002249 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002250
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002251 camera_metadata_entry_t sensorSize =
2252 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2253 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002254
2255 // The fields of view here assume infinity focus, maximum wide angle
2256 float horizFov = 180 / M_PI *
2257 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2258 float vertFov = 180 / M_PI *
2259 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002260 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2261 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002262
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002263 mParameters.exposureCompensation = 0;
2264 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
2265 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002266
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002267 camera_metadata_entry_t exposureCompensationRange =
2268 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2269 if (!exposureCompensationRange.count) return NO_INIT;
2270
2271 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002272 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002273 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002274 exposureCompensationRange.data.i32[0]);
2275
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002276 camera_metadata_entry_t exposureCompensationStep =
2277 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2278 if (!exposureCompensationStep.count) return NO_INIT;
2279
2280 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002281 exposureCompensationStep.data.r[0].numerator /
2282 exposureCompensationStep.data.r[0].denominator);
2283
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002284 mParameters.autoExposureLock = false;
2285 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2286 CameraParameters::FALSE);
2287 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2288 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002289
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002290 mParameters.autoWhiteBalanceLock = false;
2291 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2292 CameraParameters::FALSE);
2293 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2294 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002295
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002296 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
2297 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002298 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002299 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002300 "(0,0,0,0,0)");
2301
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002302 mParameters.zoom = 0;
2303 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
2304 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002306 camera_metadata_entry_t maxDigitalZoom =
2307 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2308 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002309
2310 {
2311 String8 zoomRatios;
2312 float zoom = 1.f;
2313 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002314 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002316 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002317 if (addComma) zoomRatios += ",";
2318 addComma = true;
2319 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2320 zoom += zoomIncrement;
2321 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002322 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002323 }
2324
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002325 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2326 CameraParameters::TRUE);
2327 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2328 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002329
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002330 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002331 "Infinity,Infinity,Infinity");
2332
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002333 camera_metadata_entry_t maxFacesDetected =
2334 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2335 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002336 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002337 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002338 0);
2339
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002340 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002341 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002342
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002343 params.set(CameraParameters::KEY_RECORDING_HINT,
2344 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002345
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002346 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2347 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002348
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002349 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2350 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002351
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002352 camera_metadata_entry_t availableVideoStabilizationModes =
2353 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2354 if (!availableVideoStabilizationModes.count) return NO_INIT;
2355
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002356 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002357 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2358 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002359 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002360 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2361 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002362 }
2363
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002364 // Always use metadata mode for recording
2365 mParameters.storeMetadataInBuffers = true;
2366
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002367 mParamsFlattened = params.flatten();
2368
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002369 return OK;
2370}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002371
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002372status_t Camera2Client::updatePreviewStream() {
2373 ATRACE_CALL();
2374 status_t res;
2375 if (mPreviewStreamId != NO_STREAM) {
2376 // Check if stream parameters have to change
2377 uint32_t currentWidth, currentHeight;
2378 res = mDevice->getStreamInfo(mPreviewStreamId,
2379 &currentWidth, &currentHeight, 0);
2380 if (res != OK) {
2381 ALOGE("%s: Camera %d: Error querying preview stream info: "
2382 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2383 return res;
2384 }
2385 if (currentWidth != (uint32_t)mParameters.previewWidth ||
2386 currentHeight != (uint32_t)mParameters.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002387 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2388 __FUNCTION__, mCameraId, currentWidth, currentHeight,
2389 mParameters.previewWidth, mParameters.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002390 res = mDevice->waitUntilDrained();
2391 if (res != OK) {
2392 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2393 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2394 return res;
2395 }
2396 res = mDevice->deleteStream(mPreviewStreamId);
2397 if (res != OK) {
2398 ALOGE("%s: Camera %d: Unable to delete old output stream "
2399 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2400 strerror(-res), res);
2401 return res;
2402 }
2403 mPreviewStreamId = NO_STREAM;
2404 }
2405 }
2406
2407 if (mPreviewStreamId == NO_STREAM) {
2408 res = mDevice->createStream(mPreviewWindow,
2409 mParameters.previewWidth, mParameters.previewHeight,
2410 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2411 &mPreviewStreamId);
2412 if (res != OK) {
2413 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2414 __FUNCTION__, mCameraId, strerror(-res), res);
2415 return res;
2416 }
2417 }
2418
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002419 res = mDevice->setStreamTransform(mPreviewStreamId,
2420 mParameters.previewTransform);
2421 if (res != OK) {
2422 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2423 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2424 return res;
2425 }
2426
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002427 return OK;
2428}
2429
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002430status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002431 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002432 status_t res;
2433 if (mPreviewRequest == NULL) {
2434 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2435 &mPreviewRequest);
2436 if (res != OK) {
2437 ALOGE("%s: Camera %d: Unable to create default preview request: "
2438 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2439 return res;
2440 }
2441 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002442
2443 res = updateRequestCommon(mPreviewRequest);
2444 if (res != OK) {
2445 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2446 "request: %s (%d)", __FUNCTION__, mCameraId,
2447 strerror(-res), res);
2448 return res;
2449 }
2450
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002451 return OK;
2452}
2453
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002454status_t Camera2Client::updateCaptureStream() {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002455 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002456 status_t res;
2457 // Find out buffer size for JPEG
2458 camera_metadata_entry_t maxJpegSize =
2459 staticInfo(ANDROID_JPEG_MAX_SIZE);
2460 if (maxJpegSize.count == 0) {
2461 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2462 __FUNCTION__, mCameraId);
2463 return INVALID_OPERATION;
2464 }
2465
2466 if (mCaptureConsumer == 0) {
2467 // Create CPU buffer queue endpoint
2468 mCaptureConsumer = new CpuConsumer(1);
2469 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2470 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2471 mCaptureWindow = new SurfaceTextureClient(
2472 mCaptureConsumer->getProducerInterface());
2473 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002474 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2475 "Camera2Client::CaptureHeap");
2476 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002477 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2478 __FUNCTION__, mCameraId);
2479 return NO_MEMORY;
2480 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002481 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002482
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002483 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002484 // Check if stream parameters have to change
2485 uint32_t currentWidth, currentHeight;
2486 res = mDevice->getStreamInfo(mCaptureStreamId,
2487 &currentWidth, &currentHeight, 0);
2488 if (res != OK) {
2489 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2490 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2491 return res;
2492 }
2493 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
2494 currentHeight != (uint32_t)mParameters.pictureHeight) {
2495 res = mDevice->deleteStream(mCaptureStreamId);
2496 if (res != OK) {
2497 ALOGE("%s: Camera %d: Unable to delete old output stream "
2498 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2499 strerror(-res), res);
2500 return res;
2501 }
2502 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002503 }
2504 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002505
2506 if (mCaptureStreamId == NO_STREAM) {
2507 // Create stream for HAL production
2508 res = mDevice->createStream(mCaptureWindow,
2509 mParameters.pictureWidth, mParameters.pictureHeight,
2510 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2511 &mCaptureStreamId);
2512 if (res != OK) {
2513 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2514 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2515 return res;
2516 }
2517
2518 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002519 return OK;
2520}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002521
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002522status_t Camera2Client::updateCaptureRequest() {
2523 ATRACE_CALL();
2524 status_t res;
2525 if (mCaptureRequest == NULL) {
2526 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2527 &mCaptureRequest);
2528 if (res != OK) {
2529 ALOGE("%s: Camera %d: Unable to create default still image request:"
2530 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2531 return res;
2532 }
2533 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002534
2535 res = updateRequestCommon(mCaptureRequest);
2536 if (res != OK) {
2537 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2538 "request: %s (%d)", __FUNCTION__, mCameraId,
2539 strerror(-res), res);
2540 return res;
2541 }
2542
2543 res = updateEntry(mCaptureRequest,
2544 ANDROID_JPEG_THUMBNAIL_SIZE,
2545 mParameters.jpegThumbSize, 2);
2546 if (res != OK) return res;
2547 res = updateEntry(mCaptureRequest,
2548 ANDROID_JPEG_THUMBNAIL_QUALITY,
2549 &mParameters.jpegThumbQuality, 1);
2550 if (res != OK) return res;
2551 res = updateEntry(mCaptureRequest,
2552 ANDROID_JPEG_QUALITY,
2553 &mParameters.jpegQuality, 1);
2554 if (res != OK) return res;
2555 res = updateEntry(mCaptureRequest,
2556 ANDROID_JPEG_ORIENTATION,
2557 &mParameters.jpegRotation, 1);
2558 if (res != OK) return res;
2559
2560 if (mParameters.gpsEnabled) {
2561 res = updateEntry(mCaptureRequest,
2562 ANDROID_JPEG_GPS_COORDINATES,
2563 mParameters.gpsCoordinates, 3);
2564 if (res != OK) return res;
2565 res = updateEntry(mCaptureRequest,
2566 ANDROID_JPEG_GPS_TIMESTAMP,
2567 &mParameters.gpsTimestamp, 1);
2568 if (res != OK) return res;
2569 res = updateEntry(mCaptureRequest,
2570 ANDROID_JPEG_GPS_PROCESSING_METHOD,
2571 mParameters.gpsProcessingMethod.string(),
2572 mParameters.gpsProcessingMethod.size());
2573 if (res != OK) return res;
2574 } else {
2575 res = deleteEntry(mCaptureRequest,
2576 ANDROID_JPEG_GPS_COORDINATES);
2577 if (res != OK) return res;
2578 res = deleteEntry(mCaptureRequest,
2579 ANDROID_JPEG_GPS_TIMESTAMP);
2580 if (res != OK) return res;
2581 res = deleteEntry(mCaptureRequest,
2582 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2583 if (res != OK) return res;
2584 }
2585
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002586 return OK;
2587}
2588
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002589status_t Camera2Client::updateRecordingRequest() {
2590 ATRACE_CALL();
2591 status_t res;
2592 if (mRecordingRequest == NULL) {
2593 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2594 &mRecordingRequest);
2595 if (res != OK) {
2596 ALOGE("%s: Camera %d: Unable to create default recording request:"
2597 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2598 return res;
2599 }
2600 }
2601
2602 res = updateRequestCommon(mRecordingRequest);
2603 if (res != OK) {
2604 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2605 "request: %s (%d)", __FUNCTION__, mCameraId,
2606 strerror(-res), res);
2607 return res;
2608 }
2609
2610 return OK;
2611}
2612
2613status_t Camera2Client::updateRecordingStream() {
2614 status_t res;
2615
2616 if (mRecordingConsumer == 0) {
2617 // Create CPU buffer queue endpoint
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002618 mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002619 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2620 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2621 mRecordingWindow = new SurfaceTextureClient(
2622 mRecordingConsumer->getProducerInterface());
2623 // Allocate memory later, since we don't know buffer size until receipt
2624 }
2625
2626 if (mRecordingStreamId != NO_STREAM) {
2627 // Check if stream parameters have to change
2628 uint32_t currentWidth, currentHeight;
2629 res = mDevice->getStreamInfo(mRecordingStreamId,
2630 &currentWidth, &currentHeight, 0);
2631 if (res != OK) {
2632 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2633 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2634 return res;
2635 }
2636 if (currentWidth != (uint32_t)mParameters.videoWidth ||
2637 currentHeight != (uint32_t)mParameters.videoHeight) {
2638 // TODO: Should wait to be sure previous recording has finished
2639 res = mDevice->deleteStream(mRecordingStreamId);
2640 if (res != OK) {
2641 ALOGE("%s: Camera %d: Unable to delete old output stream "
2642 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2643 strerror(-res), res);
2644 return res;
2645 }
2646 mRecordingStreamId = NO_STREAM;
2647 }
2648 }
2649
2650 if (mRecordingStreamId == NO_STREAM) {
2651 res = mDevice->createStream(mRecordingWindow,
2652 mParameters.videoWidth, mParameters.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002653 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002654 if (res != OK) {
2655 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2656 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2657 return res;
2658 }
2659 }
2660
2661 return OK;
2662}
2663
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002664status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
2665 ATRACE_CALL();
2666 status_t res;
2667 res = updateEntry(request,
2668 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
2669 if (res != OK) return res;
2670
2671 uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
2672 ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
2673 res = updateEntry(request,
2674 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2675 if (res != OK) return res;
2676 res = updateEntry(request,
2677 ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
2678 if (res != OK) return res;
2679 res = updateEntry(request,
2680 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
2681 &mParameters.antibandingMode, 1);
2682 if (res != OK) return res;
2683
2684 uint8_t controlMode =
2685 (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
2686 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2687 res = updateEntry(request,
2688 ANDROID_CONTROL_MODE, &controlMode, 1);
2689 if (res != OK) return res;
2690 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2691 res = updateEntry(request,
2692 ANDROID_CONTROL_SCENE_MODE,
2693 &mParameters.sceneMode, 1);
2694 if (res != OK) return res;
2695 }
2696
2697 uint8_t flashMode = ANDROID_FLASH_OFF;
2698 uint8_t aeMode;
2699 switch (mParameters.flashMode) {
2700 case Parameters::FLASH_MODE_OFF:
2701 aeMode = ANDROID_CONTROL_AE_ON; break;
2702 case Parameters::FLASH_MODE_AUTO:
2703 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2704 case Parameters::FLASH_MODE_ON:
2705 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2706 case Parameters::FLASH_MODE_TORCH:
2707 aeMode = ANDROID_CONTROL_AE_ON;
2708 flashMode = ANDROID_FLASH_TORCH;
2709 break;
2710 case Parameters::FLASH_MODE_RED_EYE:
2711 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2712 default:
2713 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
2714 mCameraId, mParameters.flashMode);
2715 return BAD_VALUE;
2716 }
2717 if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
2718
2719 res = updateEntry(request,
2720 ANDROID_FLASH_MODE, &flashMode, 1);
2721 if (res != OK) return res;
2722 res = updateEntry(request,
2723 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2724 if (res != OK) return res;
2725
2726 float focusDistance = 0; // infinity focus in diopters
2727 uint8_t focusMode;
2728 switch (mParameters.focusMode) {
2729 case Parameters::FOCUS_MODE_AUTO:
2730 case Parameters::FOCUS_MODE_MACRO:
2731 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2732 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2733 case Parameters::FOCUS_MODE_EDOF:
2734 focusMode = mParameters.focusMode;
2735 break;
2736 case Parameters::FOCUS_MODE_INFINITY:
2737 case Parameters::FOCUS_MODE_FIXED:
2738 focusMode = ANDROID_CONTROL_AF_OFF;
2739 break;
2740 default:
2741 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
2742 mCameraId, mParameters.focusMode);
2743 return BAD_VALUE;
2744 }
2745 res = updateEntry(request,
2746 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2747 if (res != OK) return res;
2748 res = updateEntry(request,
2749 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2750 if (res != OK) return res;
2751
2752 size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
2753 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2754 for (size_t i = 0; i < focusingAreasSize; i += 5) {
2755 focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
2756 focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
2757 focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
2758 focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
2759 focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
2760 }
2761 res = updateEntry(request,
2762 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2763 if (res != OK) return res;
2764 delete[] focusingAreas;
2765
2766 res = updateEntry(request,
2767 ANDROID_CONTROL_AE_EXP_COMPENSATION,
2768 &mParameters.exposureCompensation, 1);
2769 if (res != OK) return res;
2770
2771 size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
2772 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2773 for (size_t i = 0; i < meteringAreasSize; i += 5) {
2774 meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
2775 meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
2776 meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
2777 meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
2778 meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
2779 }
2780 res = updateEntry(request,
2781 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2782 if (res != OK) return res;
2783
2784 res = updateEntry(request,
2785 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2786 if (res != OK) return res;
2787 delete[] meteringAreas;
2788
2789 // Need to convert zoom index into a crop rectangle. The rectangle is
2790 // chosen to maximize its area on the sensor
2791
2792 camera_metadata_entry_t maxDigitalZoom =
2793 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2794 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2795 (NUM_ZOOM_STEPS-1);
2796 float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
2797
2798 camera_metadata_entry_t activePixelArraySize =
2799 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2800 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2801 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2802 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
2803 if (mParameters.previewWidth >= mParameters.previewHeight) {
2804 zoomWidth = arrayWidth / zoomRatio;
2805 zoomHeight = zoomWidth *
2806 mParameters.previewHeight / mParameters.previewWidth;
2807 } else {
2808 zoomHeight = arrayHeight / zoomRatio;
2809 zoomWidth = zoomHeight *
2810 mParameters.previewWidth / mParameters.previewHeight;
2811 }
2812 zoomLeft = (arrayWidth - zoomWidth) / 2;
2813 zoomTop = (arrayHeight - zoomHeight) / 2;
2814
2815 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2816 res = updateEntry(request,
2817 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2818 if (res != OK) return res;
2819
2820 // TODO: Decide how to map recordingHint, or whether just to ignore it
2821
2822 uint8_t vstabMode = mParameters.videoStabilization ?
2823 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2824 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2825 res = updateEntry(request,
2826 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2827 &vstabMode, 1);
2828 if (res != OK) return res;
2829
2830 return OK;
2831}
2832
2833status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2834 uint32_t tag, const void *data, size_t data_count) {
2835 camera_metadata_entry_t entry;
2836 status_t res;
2837 res = find_camera_metadata_entry(buffer, tag, &entry);
2838 if (res == NAME_NOT_FOUND) {
2839 res = add_camera_metadata_entry(buffer,
2840 tag, data, data_count);
2841 } else if (res == OK) {
2842 res = update_camera_metadata_entry(buffer,
2843 entry.index, data, data_count, NULL);
2844 }
2845
2846 if (res != OK) {
2847 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2848 __FUNCTION__, get_camera_metadata_section_name(tag),
2849 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2850 }
2851 return res;
2852}
2853
2854status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2855 camera_metadata_entry_t entry;
2856 status_t res;
2857 res = find_camera_metadata_entry(buffer, tag, &entry);
2858 if (res == NAME_NOT_FOUND) {
2859 return OK;
2860 } else if (res != OK) {
2861 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2862 __FUNCTION__,
2863 get_camera_metadata_section_name(tag),
2864 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2865 return res;
2866 }
2867 res = delete_camera_metadata_entry(buffer, entry.index);
2868 if (res != OK) {
2869 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2870 __FUNCTION__,
2871 get_camera_metadata_section_name(tag),
2872 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2873 }
2874 return res;
2875}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002876int Camera2Client::formatStringToEnum(const char *format) {
2877 return
2878 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2879 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2880 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2881 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2882 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2883 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2884 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2885 HAL_PIXEL_FORMAT_YV12 : // YV12
2886 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2887 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2888 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2889 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2890 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2891 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2892 -1;
2893}
2894
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002895const char* Camera2Client::formatEnumToString(int format) {
2896 const char *fmt;
2897 switch(format) {
2898 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2899 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2900 break;
2901 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2902 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2903 break;
2904 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2905 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2906 break;
2907 case HAL_PIXEL_FORMAT_YV12: // YV12
2908 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2909 break;
2910 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2911 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2912 break;
2913 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2914 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2915 break;
2916 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2917 ALOGW("Raw sensor preview format requested.");
2918 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2919 break;
2920 default:
2921 ALOGE("%s: Unknown preview format: %x",
2922 __FUNCTION__, format);
2923 fmt = NULL;
2924 break;
2925 }
2926 return fmt;
2927}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002928
2929int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2930 return
2931 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2932 ANDROID_CONTROL_AWB_AUTO :
2933 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2934 ANDROID_CONTROL_AWB_INCANDESCENT :
2935 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2936 ANDROID_CONTROL_AWB_FLUORESCENT :
2937 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2938 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2939 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2940 ANDROID_CONTROL_AWB_DAYLIGHT :
2941 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2942 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2943 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2944 ANDROID_CONTROL_AWB_TWILIGHT :
2945 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2946 ANDROID_CONTROL_AWB_SHADE :
2947 -1;
2948}
2949
2950int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2951 return
2952 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2953 ANDROID_CONTROL_EFFECT_OFF :
2954 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2955 ANDROID_CONTROL_EFFECT_MONO :
2956 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2957 ANDROID_CONTROL_EFFECT_NEGATIVE :
2958 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2959 ANDROID_CONTROL_EFFECT_SOLARIZE :
2960 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2961 ANDROID_CONTROL_EFFECT_SEPIA :
2962 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2963 ANDROID_CONTROL_EFFECT_POSTERIZE :
2964 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2965 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2966 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2967 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2968 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2969 ANDROID_CONTROL_EFFECT_AQUA :
2970 -1;
2971}
2972
2973int Camera2Client::abModeStringToEnum(const char *abMode) {
2974 return
2975 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2976 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2977 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2978 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2979 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2980 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2981 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2982 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2983 -1;
2984}
2985
2986int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2987 return
2988 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2989 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2990 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2991 ANDROID_CONTROL_SCENE_MODE_ACTION :
2992 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2993 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2994 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2995 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2996 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2997 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2998 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2999 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3000 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3001 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3002 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3003 ANDROID_CONTROL_SCENE_MODE_BEACH :
3004 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3005 ANDROID_CONTROL_SCENE_MODE_SNOW :
3006 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3007 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3008 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3009 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3010 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3011 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3012 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3013 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3014 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3015 ANDROID_CONTROL_SCENE_MODE_PARTY :
3016 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3017 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3018 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3019 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3020 -1;
3021}
3022
3023Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3024 const char *flashMode) {
3025 return
3026 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3027 Parameters::FLASH_MODE_OFF :
3028 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3029 Parameters::FLASH_MODE_AUTO :
3030 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3031 Parameters::FLASH_MODE_ON :
3032 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3033 Parameters::FLASH_MODE_RED_EYE :
3034 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3035 Parameters::FLASH_MODE_TORCH :
3036 Parameters::FLASH_MODE_INVALID;
3037}
3038
3039Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3040 const char *focusMode) {
3041 return
3042 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3043 Parameters::FOCUS_MODE_AUTO :
3044 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3045 Parameters::FOCUS_MODE_INFINITY :
3046 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3047 Parameters::FOCUS_MODE_MACRO :
3048 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3049 Parameters::FOCUS_MODE_FIXED :
3050 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3051 Parameters::FOCUS_MODE_EDOF :
3052 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3053 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3054 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3055 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3056 Parameters::FOCUS_MODE_INVALID;
3057}
3058
3059status_t Camera2Client::parseAreas(const char *areasCStr,
3060 Vector<Parameters::Area> *areas) {
3061 static const size_t NUM_FIELDS = 5;
3062 areas->clear();
3063 if (areasCStr == NULL) {
3064 // If no key exists, use default (0,0,0,0,0)
3065 areas->push();
3066 return OK;
3067 }
3068 String8 areasStr(areasCStr);
3069 ssize_t areaStart = areasStr.find("(", 0) + 1;
3070 while (areaStart != 0) {
3071 const char* area = areasStr.string() + areaStart;
3072 char *numEnd;
3073 int vals[NUM_FIELDS];
3074 for (size_t i = 0; i < NUM_FIELDS; i++) {
3075 errno = 0;
3076 vals[i] = strtol(area, &numEnd, 10);
3077 if (errno || numEnd == area) return BAD_VALUE;
3078 area = numEnd + 1;
3079 }
3080 areas->push(Parameters::Area(
3081 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3082 areaStart = areasStr.find("(", areaStart) + 1;
3083 }
3084 return OK;
3085}
3086
3087status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3088 size_t maxRegions) {
3089 // Definition of valid area can be found in
3090 // include/camera/CameraParameters.h
3091 if (areas.size() == 0) return BAD_VALUE;
3092 if (areas.size() == 1) {
3093 if (areas[0].left == 0 &&
3094 areas[0].top == 0 &&
3095 areas[0].right == 0 &&
3096 areas[0].bottom == 0 &&
3097 areas[0].weight == 0) {
3098 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3099 return OK;
3100 }
3101 }
3102 if (areas.size() > maxRegions) {
3103 ALOGE("%s: Too many areas requested: %d",
3104 __FUNCTION__, areas.size());
3105 return BAD_VALUE;
3106 }
3107
3108 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3109 a != areas.end(); a++) {
3110 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3111 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3112 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3113 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3114 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3115 if (a->left >= a->right) return BAD_VALUE;
3116 if (a->top >= a->bottom) return BAD_VALUE;
3117 }
3118 return OK;
3119}
3120
3121bool Camera2Client::boolFromString(const char *boolStr) {
3122 return !boolStr ? false :
3123 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3124 false;
3125}
3126
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003127int Camera2Client::degToTransform(int degrees, bool mirror) {
3128 if (!mirror) {
3129 if (degrees == 0) return 0;
3130 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3131 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3132 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3133 } else { // Do mirror (horizontal flip)
3134 if (degrees == 0) { // FLIP_H and ROT_0
3135 return HAL_TRANSFORM_FLIP_H;
3136 } else if (degrees == 90) { // FLIP_H and ROT_90
3137 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3138 } else if (degrees == 180) { // FLIP_H and ROT_180
3139 return HAL_TRANSFORM_FLIP_V;
3140 } else if (degrees == 270) { // FLIP_H and ROT_270
3141 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3142 }
3143 }
3144 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3145 return -1;
3146}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003147
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003148} // namespace android