blob: 53e6638c88ee67c80e854abcbac3db2eb53ef453 [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) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070089 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
91 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070092 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070093 }
94
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070095 mState = STOPPED;
96
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070098}
99
100Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700101 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700102 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
103
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104 mDestructionStarted = true;
105
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700106 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700107
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700108}
109
110status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700111 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700112 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700113 mCameraId,
114 getCameraClient()->asBinder().get(),
115 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700116 result.append(" State: ");
117#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
118
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700119 const Parameters& p = mParameters.unsafeUnlock();
120
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700121 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700122
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700123 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700124 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700125 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700126 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700127 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700128 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700129 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700130 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700131 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700132 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700133 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700134 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700135 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700136 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700137 p.jpegQuality, p.jpegThumbQuality);
138 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700140 p.gpsEnabled ? "enabled" : "disabled");
141 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.gpsCoordinates[0], p.gpsCoordinates[1],
144 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700146 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 }
150
151 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
156 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
157 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
158 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
159 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
160 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
161 default: result.append("UNKNOWN\n");
162 }
163
164 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700165 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
175 default: result.append("UNKNOWN\n");
176 }
177
178 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700179 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700180 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
184 default: result.append("UNKNOWN\n");
185 }
186
187 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700188 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700189 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
190 result.append("AUTO\n"); break;
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
203 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
206 default: result.append("UNKNOWN\n");
207 }
208
209 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700210 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
212 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
213 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
214 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
215 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
216 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
217 default: result.append("UNKNOWN\n");
218 }
219
220 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700221 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
225 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
226 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
227 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
228 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
229 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
230 default: result.append("UNKNOWN\n");
231 }
232
233 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700234 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700235 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700236 p.focusingAreas[i].left,
237 p.focusingAreas[i].top,
238 p.focusingAreas[i].right,
239 p.focusingAreas[i].bottom,
240 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700241 }
242
243 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700244 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700245
246 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700247 p.autoExposureLock ? "enabled" : "disabled",
248 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700249
250 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700251 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700252 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700253 p.meteringAreas[i].left,
254 p.meteringAreas[i].top,
255 p.meteringAreas[i].right,
256 p.meteringAreas[i].bottom,
257 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 }
259
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700260 result.appendFormat(" Zoom index: %d\n", p.zoom);
261 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
262 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700264 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700266
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700267 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700268 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700269
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700270 result.append(" Current streams:\n");
271 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
272 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700273 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700274
275 result.append(" Current requests:\n");
276 if (mPreviewRequest != NULL) {
277 result.append(" Preview request:\n");
278 write(fd, result.string(), result.size());
279 dump_camera_metadata(mPreviewRequest, fd, 2);
280 } else {
281 result.append(" Preview request: undefined\n");
282 write(fd, result.string(), result.size());
283 }
284
285 if (mCaptureRequest != NULL) {
286 result = " Capture request:\n";
287 write(fd, result.string(), result.size());
288 dump_camera_metadata(mCaptureRequest, fd, 2);
289 } else {
290 result = " Capture request: undefined\n";
291 write(fd, result.string(), result.size());
292 }
293
294 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700295 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700296
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700297 status_t res = mDevice->dump(fd, args);
298 if (res != OK) {
299 result = String8::format(" Error dumping device: %s (%d)",
300 strerror(-res), res);
301 write(fd, result.string(), result.size());
302 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700303
304#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700305 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700306}
307
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700308const char* Camera2Client::getStateName(State state) {
309#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
310 switch(state) {
311 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
312 CASE_ENUM_TO_CHAR(STOPPED)
313 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
314 CASE_ENUM_TO_CHAR(PREVIEW)
315 CASE_ENUM_TO_CHAR(RECORD)
316 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
317 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
318 default:
319 return "Unknown state!";
320 break;
321 }
322#undef CASE_ENUM_TO_CHAR
323}
324
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700325// ICamera interface
326
327void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700328 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700329 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700330 Mutex::Autolock icl(mICameraLock);
331
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700332 if (mDevice == 0) return;
333
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700334 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700335
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700336 mDevice->waitUntilDrained();
337
338 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700339 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700340 mPreviewStreamId = NO_STREAM;
341 }
342
343 if (mCaptureStreamId != NO_STREAM) {
344 mDevice->deleteStream(mCaptureStreamId);
345 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700346 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700347
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700348 if (mRecordingStreamId != NO_STREAM) {
349 mDevice->deleteStream(mRecordingStreamId);
350 mRecordingStreamId = NO_STREAM;
351 }
352
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700353 CameraService::Client::disconnect();
354}
355
356status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700357 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700358 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700359 Mutex::Autolock icl(mICameraLock);
360
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700361 if (mClientPid != 0 && getCallingPid() != mClientPid) {
362 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
363 "current locked to pid %d", __FUNCTION__,
364 mCameraId, getCallingPid(), mClientPid);
365 return BAD_VALUE;
366 }
367
368 mClientPid = getCallingPid();
369 mCameraClient = client;
370
371 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700372}
373
374status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700375 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700376 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700377 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700378 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
379 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700380
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700381 if (mClientPid == 0) {
382 mClientPid = getCallingPid();
383 return OK;
384 }
385
386 if (mClientPid != getCallingPid()) {
387 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
388 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
389 return EBUSY;
390 }
391
392 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700393}
394
395status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700396 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700397 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700398 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700399 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
400 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700401
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700402 // TODO: Check for uninterruptable conditions
403
404 if (mClientPid == getCallingPid()) {
405 mClientPid = 0;
406 mCameraClient.clear();
407 return OK;
408 }
409
410 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
411 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
412 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700413}
414
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700415status_t Camera2Client::setPreviewDisplay(
416 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700417 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700418 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700419 Mutex::Autolock icl(mICameraLock);
420
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700421 sp<IBinder> binder;
422 sp<ANativeWindow> window;
423 if (surface != 0) {
424 binder = surface->asBinder();
425 window = surface;
426 }
427
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700428 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700429}
430
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700431status_t Camera2Client::setPreviewTexture(
432 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700433 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700434 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700435 Mutex::Autolock icl(mICameraLock);
436
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700437 sp<IBinder> binder;
438 sp<ANativeWindow> window;
439 if (surfaceTexture != 0) {
440 binder = surfaceTexture->asBinder();
441 window = new SurfaceTextureClient(surfaceTexture);
442 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700443 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700444}
445
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700446status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700447 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700448 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700449 status_t res;
450
451 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700452 ALOGV("%s: Camera %d: New window is same as old window",
453 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700454 return NO_ERROR;
455 }
456
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700457 switch (mState) {
458 case NOT_INITIALIZED:
459 case RECORD:
460 case STILL_CAPTURE:
461 case VIDEO_SNAPSHOT:
462 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
463 __FUNCTION__, mCameraId, getStateName(mState));
464 return INVALID_OPERATION;
465 case STOPPED:
466 case WAITING_FOR_PREVIEW_WINDOW:
467 // OK
468 break;
469 case PREVIEW:
470 // Already running preview - need to stop and create a new stream
471 // TODO: Optimize this so that we don't wait for old stream to drain
472 // before spinning up new stream
473 mDevice->setStreamingRequest(NULL);
474 mState = WAITING_FOR_PREVIEW_WINDOW;
475 break;
476 }
477
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700478 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700479 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700480 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700481 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
482 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 return res;
484 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700485 res = mDevice->deleteStream(mPreviewStreamId);
486 if (res != OK) {
487 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
488 __FUNCTION__, strerror(-res), res);
489 return res;
490 }
491 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700492 }
493
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700494 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700495 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700496
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700497 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700498 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700499 }
500
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700501 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700502}
503
504void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700505 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700506 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700507}
508
509status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700510 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700511 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700512 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700513 return startPreviewLocked();
514}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700515
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700516status_t Camera2Client::startPreviewLocked() {
517 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700518 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700519 if (mState >= PREVIEW) {
520 ALOGE("%s: Can't start preview in state %s",
521 __FUNCTION__, getStateName(mState));
522 return INVALID_OPERATION;
523 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700524
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700525 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700526 mState = WAITING_FOR_PREVIEW_WINDOW;
527 return OK;
528 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700529 mState = STOPPED;
530
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700531 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700532
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700533 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700534 if (res != OK) {
535 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
536 __FUNCTION__, mCameraId, strerror(-res), res);
537 return res;
538 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700539
540 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700541 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700542 if (res != OK) {
543 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
544 __FUNCTION__, mCameraId, strerror(-res), res);
545 return res;
546 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700547 }
548
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700549 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700550 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700551 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 if (res != OK) {
553 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
554 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700555 return res;
556 }
557 res = sort_camera_metadata(mPreviewRequest);
558 if (res != OK) {
559 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
560 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700561 return res;
562 }
563
564 res = mDevice->setStreamingRequest(mPreviewRequest);
565 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700566 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
567 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700568 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700569 return res;
570 }
571 mState = PREVIEW;
572
573 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700574}
575
576void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700577 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700578 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700579 Mutex::Autolock icl(mICameraLock);
580 stopPreviewLocked();
581}
582
583void Camera2Client::stopPreviewLocked() {
584 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700585 switch (mState) {
586 case NOT_INITIALIZED:
587 ALOGE("%s: Camera %d: Call before initialized",
588 __FUNCTION__, mCameraId);
589 break;
590 case STOPPED:
591 break;
592 case STILL_CAPTURE:
593 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
594 __FUNCTION__, mCameraId);
595 break;
596 case RECORD:
597 // TODO: Handle record stop here
598 case PREVIEW:
599 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700600 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700601 case WAITING_FOR_PREVIEW_WINDOW:
602 mState = STOPPED;
603 break;
604 default:
605 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
606 mState);
607 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700608}
609
610bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700611 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700612 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700614}
615
616status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700617 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700618 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700619 switch (mState) {
620 case RECORD:
621 case VIDEO_SNAPSHOT:
622 ALOGE("%s: Camera %d: Can't be called in state %s",
623 __FUNCTION__, mCameraId, getStateName(mState));
624 return INVALID_OPERATION;
625 default:
626 // OK
627 break;
628 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700629 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700630
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700631 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700632
633 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700634}
635
636status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700637 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700638 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700639 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700640 status_t res;
641 switch (mState) {
642 case STOPPED:
643 res = startPreviewLocked();
644 if (res != OK) return res;
645 break;
646 case PREVIEW:
647 // Ready to go
648 break;
649 case RECORD:
650 case VIDEO_SNAPSHOT:
651 // OK to call this when recording is already on
652 return OK;
653 break;
654 default:
655 ALOGE("%s: Camera %d: Can't start recording in state %s",
656 __FUNCTION__, mCameraId, getStateName(mState));
657 return INVALID_OPERATION;
658 };
659
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700660 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700661
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700662 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700663 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
664 "non-metadata recording mode requested!", __FUNCTION__,
665 mCameraId);
666 return INVALID_OPERATION;
667 }
668
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700669 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700670 if (res != OK) {
671 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
672 __FUNCTION__, mCameraId, strerror(-res), res);
673 return res;
674 }
675
676 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700677 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700678 if (res != OK) {
679 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
680 __FUNCTION__, mCameraId, strerror(-res), res);
681 return res;
682 }
683 }
684
685 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
686 res = updateEntry(mRecordingRequest,
687 ANDROID_REQUEST_OUTPUT_STREAMS,
688 outputStreams, 2);
689 if (res != OK) {
690 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
691 __FUNCTION__, mCameraId, strerror(-res), res);
692 return res;
693 }
694 res = sort_camera_metadata(mRecordingRequest);
695 if (res != OK) {
696 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
697 __FUNCTION__, mCameraId, strerror(-res), res);
698 return res;
699 }
700
701 res = mDevice->setStreamingRequest(mRecordingRequest);
702 if (res != OK) {
703 ALOGE("%s: Camera %d: Unable to set recording request to start "
704 "recording: %s (%d)", __FUNCTION__, mCameraId,
705 strerror(-res), res);
706 return res;
707 }
708 mState = RECORD;
709
710 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700711}
712
713void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700714 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700715 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700716 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700717 status_t res;
718 switch (mState) {
719 case RECORD:
720 // OK to stop
721 break;
722 case STOPPED:
723 case PREVIEW:
724 case STILL_CAPTURE:
725 case VIDEO_SNAPSHOT:
726 default:
727 ALOGE("%s: Camera %d: Can't stop recording in state %s",
728 __FUNCTION__, mCameraId, getStateName(mState));
729 return;
730 };
731
732 // Back to preview. Since record can only be reached through preview,
733 // all preview stream setup should be up to date.
734 res = mDevice->setStreamingRequest(mPreviewRequest);
735 if (res != OK) {
736 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
737 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
738 return;
739 }
740
741 // TODO: Should recording heap be freed? Can't do it yet since requests
742 // could still be in flight.
743
744 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700745}
746
747bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700748 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700749 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700750 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700751}
752
753void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700754 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700755 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700756 // Make sure this is for the current heap
757 ssize_t offset;
758 size_t size;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700759 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700760 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
761 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
762 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
763 "(got %x, expected %x)", __FUNCTION__, mCameraId,
764 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
765 return;
766 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700767 uint8_t *data = (uint8_t*)heap->getBase() + offset;
768 uint32_t type = *(uint32_t*)data;
769 if (type != kMetadataBufferTypeGrallocSource) {
770 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
771 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
772 return;
773 }
774 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
775 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700776 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700777 res = mRecordingConsumer->freeBuffer(imgBuffer);
778 if (res != OK) {
779 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
780 "%s (%d)",
781 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
782 return;
783 }
784
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700785 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700786}
787
788status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700789 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700790 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700791 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700792}
793
794status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700795 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700796 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700797 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700798}
799
800status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700801 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700802 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700803 status_t res;
804
805 switch (mState) {
806 case NOT_INITIALIZED:
807 case STOPPED:
808 case WAITING_FOR_PREVIEW_WINDOW:
809 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
810 __FUNCTION__, mCameraId);
811 return INVALID_OPERATION;
812 case PREVIEW:
813 case RECORD:
814 // Good to go for takePicture
815 break;
816 case STILL_CAPTURE:
817 case VIDEO_SNAPSHOT:
818 ALOGE("%s: Camera %d: Already taking a picture",
819 __FUNCTION__, mCameraId);
820 return INVALID_OPERATION;
821 }
822
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700823 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700824
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700825 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700826 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700827 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
828 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700829 return res;
830 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700831
832 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700833 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700834 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700835 ALOGE("%s: Camera %d: Can't create still image capture request: "
836 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700837 return res;
838 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700839 }
840
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700841 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700842 if (mState == PREVIEW) {
843 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
844 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
845 &streamIds, 2);
846 } else if (mState == RECORD) {
847 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
848 mCaptureStreamId };
849 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
850 &streamIds, 3);
851 }
852
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700853 if (res != OK) {
854 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
855 "%s (%d)",
856 __FUNCTION__, mCameraId, strerror(-res), res);
857 return res;
858 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700859 res = sort_camera_metadata(mCaptureRequest);
860 if (res != OK) {
861 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
862 __FUNCTION__, mCameraId, strerror(-res), res);
863 return res;
864 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700865
866 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
867 if (captureCopy == NULL) {
868 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
869 __FUNCTION__, mCameraId);
870 return NO_MEMORY;
871 }
872
873 if (mState == PREVIEW) {
874 res = mDevice->setStreamingRequest(NULL);
875 if (res != OK) {
876 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
877 "%s (%d)",
878 __FUNCTION__, mCameraId, strerror(-res), res);
879 return res;
880 }
881 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700882 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700883 res = mDevice->capture(captureCopy);
884 if (res != OK) {
885 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
886 "%s (%d)",
887 __FUNCTION__, mCameraId, strerror(-res), res);
888 return res;
889 }
890
891 switch (mState) {
892 case PREVIEW:
893 mState = STILL_CAPTURE;
894 break;
895 case RECORD:
896 mState = VIDEO_SNAPSHOT;
897 break;
898 default:
899 ALOGE("%s: Camera %d: Unknown state for still capture!",
900 __FUNCTION__, mCameraId);
901 return INVALID_OPERATION;
902 }
903
904 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700905}
906
907status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700908 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700909 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700910 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700911 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700912 status_t res;
913
914 CameraParameters newParams(params);
915
916 // TODO: Currently ignoring any changes to supposedly read-only
917 // parameters such as supported preview sizes, etc. Should probably
918 // produce an error if they're changed.
919
920 /** Extract and verify new parameters */
921
922 size_t i;
923
924 // PREVIEW_SIZE
925 int previewWidth, previewHeight;
926 newParams.getPreviewSize(&previewWidth, &previewHeight);
927
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700928 if (previewWidth != k.mParameters.previewWidth ||
929 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700930 if (mState >= PREVIEW) {
931 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700932 "is active! (Currently %d x %d, requested %d x %d",
933 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700934 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700935 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700936 return BAD_VALUE;
937 }
938 camera_metadata_entry_t availablePreviewSizes =
939 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
940 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
941 if (availablePreviewSizes.data.i32[i] == previewWidth &&
942 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
943 }
944 if (i == availablePreviewSizes.count) {
945 ALOGE("%s: Requested preview size %d x %d is not supported",
946 __FUNCTION__, previewWidth, previewHeight);
947 return BAD_VALUE;
948 }
949 }
950
951 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700952 int previewFpsRange[2];
953 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700954 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700955 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700956 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
957 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700958 fpsRangeChanged = true;
959 camera_metadata_entry_t availablePreviewFpsRanges =
960 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
961 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
962 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700963 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700964 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700965 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700966 break;
967 }
968 }
969 if (i == availablePreviewFpsRanges.count) {
970 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700971 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700972 return BAD_VALUE;
973 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700974 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700975 }
976
977 // PREVIEW_FORMAT
978 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700979 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700980 if (mState >= PREVIEW) {
981 ALOGE("%s: Preview format cannot be updated when preview "
982 "is active!", __FUNCTION__);
983 return BAD_VALUE;
984 }
985 camera_metadata_entry_t availableFormats =
986 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
987 for (i = 0; i < availableFormats.count; i++) {
988 if (availableFormats.data.i32[i] == previewFormat) break;
989 }
990 if (i == availableFormats.count) {
991 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
992 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
993 return BAD_VALUE;
994 }
995 }
996
997 // PREVIEW_FRAME_RATE
998 // Deprecated, only use if the preview fps range is unchanged this time.
999 // The single-value FPS is the same as the minimum of the range.
1000 if (!fpsRangeChanged) {
1001 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001002 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001003 camera_metadata_entry_t availableFrameRates =
1004 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1005 for (i = 0; i < availableFrameRates.count; i+=2) {
1006 if (availableFrameRates.data.i32[i] == previewFps) break;
1007 }
1008 if (i == availableFrameRates.count) {
1009 ALOGE("%s: Requested preview frame rate %d is not supported",
1010 __FUNCTION__, previewFps);
1011 return BAD_VALUE;
1012 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001013 previewFpsRange[0] = availableFrameRates.data.i32[i];
1014 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001015 }
1016 }
1017
1018 // PICTURE_SIZE
1019 int pictureWidth, pictureHeight;
1020 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001021 if (pictureWidth == k.mParameters.pictureWidth ||
1022 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001023 camera_metadata_entry_t availablePictureSizes =
1024 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1025 for (i = 0; i < availablePictureSizes.count; i+=2) {
1026 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1027 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1028 }
1029 if (i == availablePictureSizes.count) {
1030 ALOGE("%s: Requested picture size %d x %d is not supported",
1031 __FUNCTION__, pictureWidth, pictureHeight);
1032 return BAD_VALUE;
1033 }
1034 }
1035
1036 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001037 int jpegThumbSize[2];
1038 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001039 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001040 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001041 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001042 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1043 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001044 camera_metadata_entry_t availableJpegThumbSizes =
1045 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1046 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001047 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1048 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001049 break;
1050 }
1051 }
1052 if (i == availableJpegThumbSizes.count) {
1053 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001054 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001055 return BAD_VALUE;
1056 }
1057 }
1058
1059 // JPEG_THUMBNAIL_QUALITY
1060 int jpegThumbQuality =
1061 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1062 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1063 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1064 __FUNCTION__, jpegThumbQuality);
1065 return BAD_VALUE;
1066 }
1067
1068 // JPEG_QUALITY
1069 int jpegQuality =
1070 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1071 if (jpegQuality < 0 || jpegQuality > 100) {
1072 ALOGE("%s: Requested JPEG quality %d is not supported",
1073 __FUNCTION__, jpegQuality);
1074 return BAD_VALUE;
1075 }
1076
1077 // ROTATION
1078 int jpegRotation =
1079 newParams.getInt(CameraParameters::KEY_ROTATION);
1080 if (jpegRotation != 0 &&
1081 jpegRotation != 90 &&
1082 jpegRotation != 180 &&
1083 jpegRotation != 270) {
1084 ALOGE("%s: Requested picture rotation angle %d is not supported",
1085 __FUNCTION__, jpegRotation);
1086 return BAD_VALUE;
1087 }
1088
1089 // GPS
1090 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001091 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001092 int64_t gpsTimestamp = 0;
1093 String8 gpsProcessingMethod;
1094 const char *gpsLatStr =
1095 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1096 if (gpsLatStr != NULL) {
1097 const char *gpsLongStr =
1098 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1099 const char *gpsAltitudeStr =
1100 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1101 const char *gpsTimeStr =
1102 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1103 const char *gpsProcMethodStr =
1104 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1105 if (gpsLongStr == NULL ||
1106 gpsAltitudeStr == NULL ||
1107 gpsTimeStr == NULL ||
1108 gpsProcMethodStr == NULL) {
1109 ALOGE("%s: Incomplete set of GPS parameters provided",
1110 __FUNCTION__);
1111 return BAD_VALUE;
1112 }
1113 char *endPtr;
1114 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001115 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001116 if (errno || endPtr == gpsLatStr) {
1117 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1118 return BAD_VALUE;
1119 }
1120 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001121 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001122 if (errno || endPtr == gpsLongStr) {
1123 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1124 return BAD_VALUE;
1125 }
1126 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001127 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001128 if (errno || endPtr == gpsAltitudeStr) {
1129 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1130 gpsAltitudeStr);
1131 return BAD_VALUE;
1132 }
1133 errno = 0;
1134 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1135 if (errno || endPtr == gpsTimeStr) {
1136 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1137 return BAD_VALUE;
1138 }
1139 gpsProcessingMethod = gpsProcMethodStr;
1140
1141 gpsEnabled = true;
1142 }
1143
1144 // WHITE_BALANCE
1145 int wbMode = wbModeStringToEnum(
1146 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001147 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001148 camera_metadata_entry_t availableWbModes =
1149 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1150 for (i = 0; i < availableWbModes.count; i++) {
1151 if (wbMode == availableWbModes.data.u8[i]) break;
1152 }
1153 if (i == availableWbModes.count) {
1154 ALOGE("%s: Requested white balance mode %s is not supported",
1155 __FUNCTION__,
1156 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1157 return BAD_VALUE;
1158 }
1159 }
1160
1161 // EFFECT
1162 int effectMode = effectModeStringToEnum(
1163 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001164 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001165 camera_metadata_entry_t availableEffectModes =
1166 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1167 for (i = 0; i < availableEffectModes.count; i++) {
1168 if (effectMode == availableEffectModes.data.u8[i]) break;
1169 }
1170 if (i == availableEffectModes.count) {
1171 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1172 __FUNCTION__,
1173 newParams.get(CameraParameters::KEY_EFFECT) );
1174 return BAD_VALUE;
1175 }
1176 }
1177
1178 // ANTIBANDING
1179 int antibandingMode = abModeStringToEnum(
1180 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001181 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001182 camera_metadata_entry_t availableAbModes =
1183 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1184 for (i = 0; i < availableAbModes.count; i++) {
1185 if (antibandingMode == availableAbModes.data.u8[i]) break;
1186 }
1187 if (i == availableAbModes.count) {
1188 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1189 __FUNCTION__,
1190 newParams.get(CameraParameters::KEY_ANTIBANDING));
1191 return BAD_VALUE;
1192 }
1193 }
1194
1195 // SCENE_MODE
1196 int sceneMode = sceneModeStringToEnum(
1197 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001198 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001199 camera_metadata_entry_t availableSceneModes =
1200 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1201 for (i = 0; i < availableSceneModes.count; i++) {
1202 if (sceneMode == availableSceneModes.data.u8[i]) break;
1203 }
1204 if (i == availableSceneModes.count) {
1205 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1206 __FUNCTION__,
1207 newParams.get(CameraParameters::KEY_SCENE_MODE));
1208 return BAD_VALUE;
1209 }
1210 }
1211
1212 // FLASH_MODE
1213 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1214 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001215 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001216 camera_metadata_entry_t flashAvailable =
1217 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1218 if (!flashAvailable.data.u8[0] &&
1219 flashMode != Parameters::FLASH_MODE_OFF) {
1220 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1221 "No flash on device", __FUNCTION__,
1222 newParams.get(CameraParameters::KEY_FLASH_MODE));
1223 return BAD_VALUE;
1224 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1225 camera_metadata_entry_t availableAeModes =
1226 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1227 for (i = 0; i < availableAeModes.count; i++) {
1228 if (flashMode == availableAeModes.data.u8[i]) break;
1229 }
1230 if (i == availableAeModes.count) {
1231 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1232 __FUNCTION__,
1233 newParams.get(CameraParameters::KEY_FLASH_MODE));
1234 return BAD_VALUE;
1235 }
1236 } else if (flashMode == -1) {
1237 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1238 __FUNCTION__,
1239 newParams.get(CameraParameters::KEY_FLASH_MODE));
1240 return BAD_VALUE;
1241 }
1242 }
1243
1244 // FOCUS_MODE
1245 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1246 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001247 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001248 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1249 camera_metadata_entry_t minFocusDistance =
1250 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1251 if (minFocusDistance.data.f[0] == 0) {
1252 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1253 "fixed focus lens",
1254 __FUNCTION__,
1255 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1256 return BAD_VALUE;
1257 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1258 camera_metadata_entry_t availableFocusModes =
1259 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1260 for (i = 0; i < availableFocusModes.count; i++) {
1261 if (focusMode == availableFocusModes.data.u8[i]) break;
1262 }
1263 if (i == availableFocusModes.count) {
1264 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1265 __FUNCTION__,
1266 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1267 return BAD_VALUE;
1268 }
1269 }
1270 }
1271 }
1272
1273 // FOCUS_AREAS
1274 Vector<Parameters::Area> focusingAreas;
1275 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1276 &focusingAreas);
1277 size_t max3aRegions =
1278 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1279 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1280 if (res != OK) {
1281 ALOGE("%s: Requested focus areas are malformed: %s",
1282 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1283 return BAD_VALUE;
1284 }
1285
1286 // EXPOSURE_COMPENSATION
1287 int exposureCompensation =
1288 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1289 camera_metadata_entry_t exposureCompensationRange =
1290 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1291 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1292 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1293 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1294 __FUNCTION__, exposureCompensation);
1295 return BAD_VALUE;
1296 }
1297
1298 // AUTO_EXPOSURE_LOCK (always supported)
1299 bool autoExposureLock = boolFromString(
1300 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1301
1302 // AUTO_WHITEBALANCE_LOCK (always supported)
1303 bool autoWhiteBalanceLock = boolFromString(
1304 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1305
1306 // METERING_AREAS
1307 Vector<Parameters::Area> meteringAreas;
1308 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1309 &meteringAreas);
1310 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1311 if (res != OK) {
1312 ALOGE("%s: Requested metering areas are malformed: %s",
1313 __FUNCTION__,
1314 newParams.get(CameraParameters::KEY_METERING_AREAS));
1315 return BAD_VALUE;
1316 }
1317
1318 // ZOOM
1319 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1320 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1321 ALOGE("%s: Requested zoom level %d is not supported",
1322 __FUNCTION__, zoom);
1323 return BAD_VALUE;
1324 }
1325
1326 // VIDEO_SIZE
1327 int videoWidth, videoHeight;
1328 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001329 if (videoWidth != k.mParameters.videoWidth ||
1330 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001331 if (mState == RECORD) {
1332 ALOGE("%s: Video size cannot be updated when recording is active!",
1333 __FUNCTION__);
1334 return BAD_VALUE;
1335 }
1336 camera_metadata_entry_t availableVideoSizes =
1337 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1338 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1339 if (availableVideoSizes.data.i32[i] == videoWidth &&
1340 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1341 }
1342 if (i == availableVideoSizes.count) {
1343 ALOGE("%s: Requested video size %d x %d is not supported",
1344 __FUNCTION__, videoWidth, videoHeight);
1345 return BAD_VALUE;
1346 }
1347 }
1348
1349 // RECORDING_HINT (always supported)
1350 bool recordingHint = boolFromString(
1351 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1352
1353 // VIDEO_STABILIZATION
1354 bool videoStabilization = boolFromString(
1355 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1356 camera_metadata_entry_t availableVideoStabilizationModes =
1357 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1358 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1359 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1360 }
1361
1362 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001363
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001364 k.mParameters.previewWidth = previewWidth;
1365 k.mParameters.previewHeight = previewHeight;
1366 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1367 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1368 k.mParameters.previewFps = previewFps;
1369 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001370
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001371 k.mParameters.pictureWidth = pictureWidth;
1372 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001373
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001374 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1375 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1376 k.mParameters.jpegQuality = jpegQuality;
1377 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001378
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001379 k.mParameters.gpsEnabled = gpsEnabled;
1380 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1381 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1382 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1383 k.mParameters.gpsTimestamp = gpsTimestamp;
1384 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001385
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001386 k.mParameters.wbMode = wbMode;
1387 k.mParameters.effectMode = effectMode;
1388 k.mParameters.antibandingMode = antibandingMode;
1389 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001390
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001391 k.mParameters.flashMode = flashMode;
1392 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001393
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001394 k.mParameters.focusingAreas = focusingAreas;
1395 k.mParameters.exposureCompensation = exposureCompensation;
1396 k.mParameters.autoExposureLock = autoExposureLock;
1397 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1398 k.mParameters.meteringAreas = meteringAreas;
1399 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001400
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001401 k.mParameters.videoWidth = videoWidth;
1402 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001403
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001404 k.mParameters.recordingHint = recordingHint;
1405 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001406
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001407 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001408 if (res != OK) {
1409 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1410 __FUNCTION__, mCameraId, strerror(-res), res);
1411 return res;
1412 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001413 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001414 if (res != OK) {
1415 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1416 __FUNCTION__, mCameraId, strerror(-res), res);
1417 return res;
1418 }
1419
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001420 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001421 if (res != OK) {
1422 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1423 __FUNCTION__, mCameraId, strerror(-res), res);
1424 return res;
1425 }
1426
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001427 if (mState == PREVIEW) {
1428 res = mDevice->setStreamingRequest(mPreviewRequest);
1429 if (res != OK) {
1430 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1431 __FUNCTION__, mCameraId, strerror(-res), res);
1432 return res;
1433 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001434 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1435 res = mDevice->setStreamingRequest(mRecordingRequest);
1436 if (res != OK) {
1437 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1438 __FUNCTION__, mCameraId, strerror(-res), res);
1439 return res;
1440 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001441 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001442
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001443 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001444
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001445 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001446}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001447
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001448String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001449 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001450 Mutex::Autolock icl(mICameraLock);
1451
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001452 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001453
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001454 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001455 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001456}
1457
1458status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001459 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001460 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001461
1462 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1463 cmd, arg1, arg2);
1464
1465 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001466 LockedParameters::Key k(mParameters);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001467 int transform = degToTransform(arg1,
1468 mCameraFacing == CAMERA_FACING_FRONT);
1469 if (transform == -1) {
1470 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1471 __FUNCTION__, mCameraId, arg1);
1472 return BAD_VALUE;
1473 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001474 if (transform != k.mParameters.previewTransform &&
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001475 mPreviewStreamId != NO_STREAM) {
1476 mDevice->setStreamTransform(mPreviewStreamId, transform);
1477 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001478 k.mParameters.previewTransform = transform;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001479 return OK;
1480 }
1481
1482 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1483 mCameraId, cmd, arg1, arg2);
1484
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001485 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001486}
1487
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001488/** Device-related methods */
1489
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001490void Camera2Client::onCaptureAvailable() {
1491 ATRACE_CALL();
1492 status_t res;
1493 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001494 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1495
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001496 CpuConsumer::LockedBuffer imgBuffer;
1497 {
1498 Mutex::Autolock icl(mICameraLock);
1499
1500 // TODO: Signal errors here upstream
1501 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1502 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1503 __FUNCTION__, mCameraId);
1504 return;
1505 }
1506
1507 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1508 if (res != OK) {
1509 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1510 __FUNCTION__, mCameraId, strerror(-res), res);
1511 return;
1512 }
1513
1514 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1515 ALOGE("%s: Camera %d: Unexpected format for still image: "
1516 "%x, expected %x", __FUNCTION__, mCameraId,
1517 imgBuffer.format,
1518 HAL_PIXEL_FORMAT_BLOB);
1519 mCaptureConsumer->unlockBuffer(imgBuffer);
1520 return;
1521 }
1522
1523 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001524 void* captureMemory = mCaptureHeap->mHeap->getBase();
1525 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001526 memcpy(captureMemory, imgBuffer.data, size);
1527
1528 mCaptureConsumer->unlockBuffer(imgBuffer);
1529
1530 currentClient = mCameraClient;
1531 switch (mState) {
1532 case STILL_CAPTURE:
1533 mState = STOPPED;
1534 break;
1535 case VIDEO_SNAPSHOT:
1536 mState = RECORD;
1537 break;
1538 default:
1539 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1540 mCameraId, mState);
1541 break;
1542 }
1543 }
1544 // Call outside mICameraLock to allow re-entrancy from notification
1545 if (currentClient != 0) {
1546 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001547 mCaptureHeap->mBuffers[0], NULL);
1548 }
1549}
1550
1551void Camera2Client::onRecordingFrameAvailable() {
1552 ATRACE_CALL();
1553 status_t res;
1554 sp<ICameraClient> currentClient;
1555 size_t heapIdx = 0;
1556 nsecs_t timestamp;
1557 {
1558 Mutex::Autolock icl(mICameraLock);
1559 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001560 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001561 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001562 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1563 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001564 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001565 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001566 }
1567
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001568 buffer_handle_t imgBuffer;
1569 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001570 if (res != OK) {
1571 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1572 __FUNCTION__, mCameraId, strerror(-res), res);
1573 return;
1574 }
1575
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001576 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001577 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001578 return;
1579 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001580
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001581 if (mRecordingHeap == 0) {
1582 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001583 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1584 "size %d bytes", __FUNCTION__, mCameraId,
1585 kRecordingHeapCount, bufferSize);
1586 if (mRecordingHeap != 0) {
1587 ALOGV("%s: Camera %d: Previous heap has size %d "
1588 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1589 mRecordingHeap->mHeap->getSize(),
1590 bufferSize * kRecordingHeapCount);
1591 }
1592 // Need to allocate memory for heap
1593 mRecordingHeap.clear();
1594
1595 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1596 "Camera2Client::RecordingHeap");
1597 if (mRecordingHeap->mHeap->getSize() == 0) {
1598 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1599 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001600 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001601 return;
1602 }
1603 mRecordingHeapHead = 0;
1604 mRecordingHeapFree = kRecordingHeapCount;
1605 }
1606
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001607 if ( mRecordingHeapFree == 0) {
1608 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1609 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001610 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001611 return;
1612 }
1613 heapIdx = mRecordingHeapHead;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001614 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1615 mRecordingHeapFree--;
1616
1617 ALOGV("%s: Camera %d: Timestamp %lld",
1618 __FUNCTION__, mCameraId, timestamp);
1619
1620 ssize_t offset;
1621 size_t size;
1622 sp<IMemoryHeap> heap =
1623 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1624 &size);
1625
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001626 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1627 uint32_t type = kMetadataBufferTypeGrallocSource;
1628 memcpy(data, &type, 4);
1629 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1630 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001631 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001632 currentClient = mCameraClient;
1633 }
1634 // Call outside mICameraLock to allow re-entrancy from notification
1635 if (currentClient != 0) {
1636 currentClient->dataCallbackTimestamp(timestamp,
1637 CAMERA_MSG_VIDEO_FRAME,
1638 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001639 }
1640}
1641
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001642camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1643 size_t minCount, size_t maxCount) {
1644 status_t res;
1645 camera_metadata_entry_t entry;
1646 res = find_camera_metadata_entry(mDevice->info(),
1647 tag,
1648 &entry);
1649 if (CC_UNLIKELY( res != OK )) {
1650 const char* tagSection = get_camera_metadata_section_name(tag);
1651 if (tagSection == NULL) tagSection = "<unknown>";
1652 const char* tagName = get_camera_metadata_tag_name(tag);
1653 if (tagName == NULL) tagName = "<unknown>";
1654
1655 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1656 tagSection, tagName, tag, strerror(-res), res);
1657 entry.count = 0;
1658 entry.data.u8 = NULL;
1659 } else if (CC_UNLIKELY(
1660 (minCount != 0 && entry.count < minCount) ||
1661 (maxCount != 0 && entry.count > maxCount) ) ) {
1662 const char* tagSection = get_camera_metadata_section_name(tag);
1663 if (tagSection == NULL) tagSection = "<unknown>";
1664 const char* tagName = get_camera_metadata_tag_name(tag);
1665 if (tagName == NULL) tagName = "<unknown>";
1666 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1667 "Expected between %d and %d values, but got %d values",
1668 tagSection, tagName, tag, minCount, maxCount, entry.count);
1669 entry.count = 0;
1670 entry.data.u8 = NULL;
1671 }
1672
1673 return entry;
1674}
1675
1676/** Utility methods */
1677
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001678
1679status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001680 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001681 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001682
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001683 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001684 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001685
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001686 camera_metadata_entry_t availableProcessedSizes =
1687 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1688 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001689
1690 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001691 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1692 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1693 k.mParameters.videoWidth = k.mParameters.previewWidth;
1694 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001695
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001696 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1697 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001698 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1699 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001700 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001701 {
1702 String8 supportedPreviewSizes;
1703 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1704 if (i != 0) supportedPreviewSizes += ",";
1705 supportedPreviewSizes += String8::format("%dx%d",
1706 availableProcessedSizes.data.i32[i],
1707 availableProcessedSizes.data.i32[i+1]);
1708 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001709 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001710 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001711 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001712 supportedPreviewSizes);
1713 }
1714
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001715 camera_metadata_entry_t availableFpsRanges =
1716 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1717 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001718
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001719 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1720 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001721
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001722 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1723 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001724 k.mParameters.previewFpsRange[0],
1725 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001726
1727 {
1728 String8 supportedPreviewFpsRange;
1729 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1730 if (i != 0) supportedPreviewFpsRange += ",";
1731 supportedPreviewFpsRange += String8::format("(%d,%d)",
1732 availableFpsRanges.data.i32[i],
1733 availableFpsRanges.data.i32[i+1]);
1734 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001735 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001736 supportedPreviewFpsRange);
1737 }
1738
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001739 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001740 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001741 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001742
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001743 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001744 mCameraFacing == CAMERA_FACING_FRONT);
1745
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001746 camera_metadata_entry_t availableFormats =
1747 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1748
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001749 {
1750 String8 supportedPreviewFormats;
1751 bool addComma = false;
1752 for (size_t i=0; i < availableFormats.count; i++) {
1753 if (addComma) supportedPreviewFormats += ",";
1754 addComma = true;
1755 switch (availableFormats.data.i32[i]) {
1756 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001757 supportedPreviewFormats +=
1758 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001759 break;
1760 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001761 supportedPreviewFormats +=
1762 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001763 break;
1764 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001765 supportedPreviewFormats +=
1766 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001767 break;
1768 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001769 supportedPreviewFormats +=
1770 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001771 break;
1772 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001773 supportedPreviewFormats +=
1774 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001775 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001776 case HAL_PIXEL_FORMAT_RGBA_8888:
1777 supportedPreviewFormats +=
1778 CameraParameters::PIXEL_FORMAT_RGBA8888;
1779 break;
1780 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001781 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001782 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001783 addComma = false;
1784 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001785
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001786 default:
1787 ALOGW("%s: Camera %d: Unknown preview format: %x",
1788 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1789 addComma = false;
1790 break;
1791 }
1792 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001793 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001794 supportedPreviewFormats);
1795 }
1796
1797 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1798 // still have to do something sane for them
1799
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001800 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001801 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001802
1803 {
1804 String8 supportedPreviewFrameRates;
1805 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1806 if (i != 0) supportedPreviewFrameRates += ",";
1807 supportedPreviewFrameRates += String8::format("%d",
1808 availableFpsRanges.data.i32[i]);
1809 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001810 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001811 supportedPreviewFrameRates);
1812 }
1813
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001814 camera_metadata_entry_t availableJpegSizes =
1815 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1816 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001817
1818 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001819 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1820 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001821
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001822 params.setPictureSize(k.mParameters.pictureWidth,
1823 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001824
1825 {
1826 String8 supportedPictureSizes;
1827 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1828 if (i != 0) supportedPictureSizes += ",";
1829 supportedPictureSizes += String8::format("%dx%d",
1830 availableJpegSizes.data.i32[i],
1831 availableJpegSizes.data.i32[i+1]);
1832 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001833 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001834 supportedPictureSizes);
1835 }
1836
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001837 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1838 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1839 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001840
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001841 camera_metadata_entry_t availableJpegThumbnailSizes =
1842 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1843 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001844
1845 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001846 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1847 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001848
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001849 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001850 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001851 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001852 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001853
1854 {
1855 String8 supportedJpegThumbSizes;
1856 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1857 if (i != 0) supportedJpegThumbSizes += ",";
1858 supportedJpegThumbSizes += String8::format("%dx%d",
1859 availableJpegThumbnailSizes.data.i32[i],
1860 availableJpegThumbnailSizes.data.i32[i+1]);
1861 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001862 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001863 supportedJpegThumbSizes);
1864 }
1865
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001866 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001867 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001868 k.mParameters.jpegThumbQuality);
1869 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001870 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001871 k.mParameters.jpegQuality);
1872 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001873 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001874 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001875
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001876 k.mParameters.gpsEnabled = false;
1877 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001878 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001879
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001880 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001881 params.set(CameraParameters::KEY_WHITE_BALANCE,
1882 CameraParameters::WHITE_BALANCE_AUTO);
1883
1884 camera_metadata_entry_t availableWhiteBalanceModes =
1885 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001886 {
1887 String8 supportedWhiteBalance;
1888 bool addComma = false;
1889 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1890 if (addComma) supportedWhiteBalance += ",";
1891 addComma = true;
1892 switch (availableWhiteBalanceModes.data.u8[i]) {
1893 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001894 supportedWhiteBalance +=
1895 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001896 break;
1897 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001898 supportedWhiteBalance +=
1899 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001900 break;
1901 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001902 supportedWhiteBalance +=
1903 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001904 break;
1905 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001906 supportedWhiteBalance +=
1907 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001908 break;
1909 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001910 supportedWhiteBalance +=
1911 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001912 break;
1913 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001914 supportedWhiteBalance +=
1915 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001916 break;
1917 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001918 supportedWhiteBalance +=
1919 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001920 break;
1921 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001922 supportedWhiteBalance +=
1923 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001924 break;
1925 // Skipping values not mappable to v1 API
1926 case ANDROID_CONTROL_AWB_OFF:
1927 addComma = false;
1928 break;
1929 default:
1930 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1931 __FUNCTION__, mCameraId,
1932 availableWhiteBalanceModes.data.u8[i]);
1933 addComma = false;
1934 break;
1935 }
1936 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001937 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001938 supportedWhiteBalance);
1939 }
1940
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001941 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001942 params.set(CameraParameters::KEY_EFFECT,
1943 CameraParameters::EFFECT_NONE);
1944
1945 camera_metadata_entry_t availableEffects =
1946 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1947 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001948 {
1949 String8 supportedEffects;
1950 bool addComma = false;
1951 for (size_t i=0; i < availableEffects.count; i++) {
1952 if (addComma) supportedEffects += ",";
1953 addComma = true;
1954 switch (availableEffects.data.u8[i]) {
1955 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001956 supportedEffects +=
1957 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001958 break;
1959 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001960 supportedEffects +=
1961 CameraParameters::EFFECT_MONO;
1962 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001963 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001964 supportedEffects +=
1965 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001966 break;
1967 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001968 supportedEffects +=
1969 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001970 break;
1971 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001972 supportedEffects +=
1973 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001974 break;
1975 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001976 supportedEffects +=
1977 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001978 break;
1979 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001980 supportedEffects +=
1981 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001982 break;
1983 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001984 supportedEffects +=
1985 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001986 break;
1987 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001988 supportedEffects +=
1989 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001990 break;
1991 default:
1992 ALOGW("%s: Camera %d: Unknown effect value: %d",
1993 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1994 addComma = false;
1995 break;
1996 }
1997 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001998 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001999 }
2000
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002001 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002002 params.set(CameraParameters::KEY_ANTIBANDING,
2003 CameraParameters::ANTIBANDING_AUTO);
2004
2005 camera_metadata_entry_t availableAntibandingModes =
2006 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2007 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002008 {
2009 String8 supportedAntibanding;
2010 bool addComma = false;
2011 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2012 if (addComma) supportedAntibanding += ",";
2013 addComma = true;
2014 switch (availableAntibandingModes.data.u8[i]) {
2015 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002016 supportedAntibanding +=
2017 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002018 break;
2019 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002020 supportedAntibanding +=
2021 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002022 break;
2023 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002024 supportedAntibanding +=
2025 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002026 break;
2027 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002028 supportedAntibanding +=
2029 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002030 break;
2031 default:
2032 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2033 __FUNCTION__, mCameraId,
2034 availableAntibandingModes.data.u8[i]);
2035 addComma = false;
2036 break;
2037 }
2038 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002039 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002040 supportedAntibanding);
2041 }
2042
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002043 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002044 params.set(CameraParameters::KEY_SCENE_MODE,
2045 CameraParameters::SCENE_MODE_AUTO);
2046
2047 camera_metadata_entry_t availableSceneModes =
2048 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2049 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002050 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002051 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002052 bool addComma = true;
2053 bool noSceneModes = false;
2054 for (size_t i=0; i < availableSceneModes.count; i++) {
2055 if (addComma) supportedSceneModes += ",";
2056 addComma = true;
2057 switch (availableSceneModes.data.u8[i]) {
2058 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2059 noSceneModes = true;
2060 break;
2061 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2062 // Not in old API
2063 addComma = false;
2064 break;
2065 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002066 supportedSceneModes +=
2067 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002068 break;
2069 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002070 supportedSceneModes +=
2071 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002072 break;
2073 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002074 supportedSceneModes +=
2075 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002076 break;
2077 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002078 supportedSceneModes +=
2079 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002080 break;
2081 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002082 supportedSceneModes +=
2083 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002084 break;
2085 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002086 supportedSceneModes +=
2087 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002088 break;
2089 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002090 supportedSceneModes +=
2091 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002092 break;
2093 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002094 supportedSceneModes +=
2095 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002096 break;
2097 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002098 supportedSceneModes +=
2099 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002100 break;
2101 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002102 supportedSceneModes +=
2103 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002104 break;
2105 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002106 supportedSceneModes +=
2107 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002108 break;
2109 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002110 supportedSceneModes +=
2111 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002112 break;
2113 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002114 supportedSceneModes +=
2115 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002116 break;
2117 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002118 supportedSceneModes +=
2119 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002120 break;
2121 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002122 supportedSceneModes +=
2123 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002124 break;
2125 default:
2126 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002127 __FUNCTION__, mCameraId,
2128 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002129 addComma = false;
2130 break;
2131 }
2132 }
2133 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002134 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002135 supportedSceneModes);
2136 }
2137 }
2138
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002139 camera_metadata_entry_t flashAvailable =
2140 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2141 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002142
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002143 camera_metadata_entry_t availableAeModes =
2144 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2145 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002146
2147 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002148 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002149 params.set(CameraParameters::KEY_FLASH_MODE,
2150 CameraParameters::FLASH_MODE_AUTO);
2151
2152 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2153 supportedFlashModes = supportedFlashModes +
2154 "," + CameraParameters::FLASH_MODE_AUTO +
2155 "," + CameraParameters::FLASH_MODE_ON +
2156 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002157 for (size_t i=0; i < availableAeModes.count; i++) {
2158 if (availableAeModes.data.u8[i] ==
2159 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002160 supportedFlashModes = supportedFlashModes + "," +
2161 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002162 break;
2163 }
2164 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002165 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002166 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002167 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002168 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002169 params.set(CameraParameters::KEY_FLASH_MODE,
2170 CameraParameters::FLASH_MODE_OFF);
2171 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2172 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002173 }
2174
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002175 camera_metadata_entry_t minFocusDistance =
2176 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2177 if (!minFocusDistance.count) return NO_INIT;
2178
2179 camera_metadata_entry_t availableAfModes =
2180 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2181 if (!availableAfModes.count) return NO_INIT;
2182
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002183 if (minFocusDistance.data.f[0] == 0) {
2184 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002185 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002186 params.set(CameraParameters::KEY_FOCUS_MODE,
2187 CameraParameters::FOCUS_MODE_FIXED);
2188 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2189 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002190 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002191 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002192 params.set(CameraParameters::KEY_FOCUS_MODE,
2193 CameraParameters::FOCUS_MODE_AUTO);
2194 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2195 supportedFocusModes = supportedFocusModes + "," +
2196 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002197 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002198
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002199 for (size_t i=0; i < availableAfModes.count; i++) {
2200 if (addComma) supportedFocusModes += ",";
2201 addComma = true;
2202 switch (availableAfModes.data.u8[i]) {
2203 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002204 supportedFocusModes +=
2205 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002206 break;
2207 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002208 supportedFocusModes +=
2209 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002210 break;
2211 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002212 supportedFocusModes +=
2213 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002214 break;
2215 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002216 supportedFocusModes +=
2217 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002218 break;
2219 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002220 supportedFocusModes +=
2221 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002222 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002223 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002224 case ANDROID_CONTROL_AF_OFF:
2225 addComma = false;
2226 break;
2227 default:
2228 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2229 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2230 addComma = false;
2231 break;
2232 }
2233 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002234 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002235 supportedFocusModes);
2236 }
2237
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002238 camera_metadata_entry_t max3aRegions =
2239 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2240 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002241
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002242 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002243 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002244 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002245 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002246 k.mParameters.focusingAreas.clear();
2247 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002248
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002249 camera_metadata_entry_t availableFocalLengths =
2250 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2251 if (!availableFocalLengths.count) return NO_INIT;
2252
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002253 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002254 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002255
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002256 camera_metadata_entry_t sensorSize =
2257 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2258 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002259
2260 // The fields of view here assume infinity focus, maximum wide angle
2261 float horizFov = 180 / M_PI *
2262 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2263 float vertFov = 180 / M_PI *
2264 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002265 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2266 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002267
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002268 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002269 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002270 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002271
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002272 camera_metadata_entry_t exposureCompensationRange =
2273 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2274 if (!exposureCompensationRange.count) return NO_INIT;
2275
2276 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002278 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002279 exposureCompensationRange.data.i32[0]);
2280
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002281 camera_metadata_entry_t exposureCompensationStep =
2282 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2283 if (!exposureCompensationStep.count) return NO_INIT;
2284
2285 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002286 exposureCompensationStep.data.r[0].numerator /
2287 exposureCompensationStep.data.r[0].denominator);
2288
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002289 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002290 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2291 CameraParameters::FALSE);
2292 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2293 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002294
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002295 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002296 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2297 CameraParameters::FALSE);
2298 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2299 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002300
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002301 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002302 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002303 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002304 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305 "(0,0,0,0,0)");
2306
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002307 k.mParameters.zoom = 0;
2308 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002309 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002310
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002311 camera_metadata_entry_t maxDigitalZoom =
2312 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2313 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002314
2315 {
2316 String8 zoomRatios;
2317 float zoom = 1.f;
2318 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002319 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002320 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002321 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002322 if (addComma) zoomRatios += ",";
2323 addComma = true;
2324 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2325 zoom += zoomIncrement;
2326 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002327 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002328 }
2329
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002330 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2331 CameraParameters::TRUE);
2332 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2333 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002334
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002335 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002336 "Infinity,Infinity,Infinity");
2337
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002338 camera_metadata_entry_t maxFacesDetected =
2339 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2340 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002341 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002342 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002343 0);
2344
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002345 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002346 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002347
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002348 params.set(CameraParameters::KEY_RECORDING_HINT,
2349 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002350
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002351 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2352 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002353
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002354 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2355 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002356
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002357 camera_metadata_entry_t availableVideoStabilizationModes =
2358 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2359 if (!availableVideoStabilizationModes.count) return NO_INIT;
2360
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002361 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002362 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2363 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002364 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002365 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2366 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002367 }
2368
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002369 // Always use metadata mode for recording
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002370 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002371
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002372 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002373
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002374 return OK;
2375}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002376
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002377status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002378 ATRACE_CALL();
2379 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002380
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002381 if (mPreviewStreamId != NO_STREAM) {
2382 // Check if stream parameters have to change
2383 uint32_t currentWidth, currentHeight;
2384 res = mDevice->getStreamInfo(mPreviewStreamId,
2385 &currentWidth, &currentHeight, 0);
2386 if (res != OK) {
2387 ALOGE("%s: Camera %d: Error querying preview stream info: "
2388 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2389 return res;
2390 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002391 if (currentWidth != (uint32_t)params.previewWidth ||
2392 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002393 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2394 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002395 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002396 res = mDevice->waitUntilDrained();
2397 if (res != OK) {
2398 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2399 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2400 return res;
2401 }
2402 res = mDevice->deleteStream(mPreviewStreamId);
2403 if (res != OK) {
2404 ALOGE("%s: Camera %d: Unable to delete old output stream "
2405 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2406 strerror(-res), res);
2407 return res;
2408 }
2409 mPreviewStreamId = NO_STREAM;
2410 }
2411 }
2412
2413 if (mPreviewStreamId == NO_STREAM) {
2414 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002415 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002416 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2417 &mPreviewStreamId);
2418 if (res != OK) {
2419 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2420 __FUNCTION__, mCameraId, strerror(-res), res);
2421 return res;
2422 }
2423 }
2424
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002425 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002426 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002427 if (res != OK) {
2428 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2429 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2430 return res;
2431 }
2432
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002433 return OK;
2434}
2435
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002436status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002437 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002438 status_t res;
2439 if (mPreviewRequest == NULL) {
2440 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2441 &mPreviewRequest);
2442 if (res != OK) {
2443 ALOGE("%s: Camera %d: Unable to create default preview request: "
2444 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2445 return res;
2446 }
2447 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002448
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002449 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002450 if (res != OK) {
2451 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2452 "request: %s (%d)", __FUNCTION__, mCameraId,
2453 strerror(-res), res);
2454 return res;
2455 }
2456
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002457 return OK;
2458}
2459
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002460status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002461 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002462 status_t res;
2463 // Find out buffer size for JPEG
2464 camera_metadata_entry_t maxJpegSize =
2465 staticInfo(ANDROID_JPEG_MAX_SIZE);
2466 if (maxJpegSize.count == 0) {
2467 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2468 __FUNCTION__, mCameraId);
2469 return INVALID_OPERATION;
2470 }
2471
2472 if (mCaptureConsumer == 0) {
2473 // Create CPU buffer queue endpoint
2474 mCaptureConsumer = new CpuConsumer(1);
2475 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2476 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2477 mCaptureWindow = new SurfaceTextureClient(
2478 mCaptureConsumer->getProducerInterface());
2479 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002480 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2481 "Camera2Client::CaptureHeap");
2482 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002483 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2484 __FUNCTION__, mCameraId);
2485 return NO_MEMORY;
2486 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002487 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002488
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002489 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002490 // Check if stream parameters have to change
2491 uint32_t currentWidth, currentHeight;
2492 res = mDevice->getStreamInfo(mCaptureStreamId,
2493 &currentWidth, &currentHeight, 0);
2494 if (res != OK) {
2495 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2496 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2497 return res;
2498 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002499 if (currentWidth != (uint32_t)params.pictureWidth ||
2500 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002501 res = mDevice->deleteStream(mCaptureStreamId);
2502 if (res != OK) {
2503 ALOGE("%s: Camera %d: Unable to delete old output stream "
2504 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2505 strerror(-res), res);
2506 return res;
2507 }
2508 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002509 }
2510 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002511
2512 if (mCaptureStreamId == NO_STREAM) {
2513 // Create stream for HAL production
2514 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002515 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002516 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2517 &mCaptureStreamId);
2518 if (res != OK) {
2519 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2520 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2521 return res;
2522 }
2523
2524 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002525 return OK;
2526}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002527
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002528status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002529 ATRACE_CALL();
2530 status_t res;
2531 if (mCaptureRequest == NULL) {
2532 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2533 &mCaptureRequest);
2534 if (res != OK) {
2535 ALOGE("%s: Camera %d: Unable to create default still image request:"
2536 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2537 return res;
2538 }
2539 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002540
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002541 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002542 if (res != OK) {
2543 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2544 "request: %s (%d)", __FUNCTION__, mCameraId,
2545 strerror(-res), res);
2546 return res;
2547 }
2548
2549 res = updateEntry(mCaptureRequest,
2550 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002551 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002552 if (res != OK) return res;
2553 res = updateEntry(mCaptureRequest,
2554 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002555 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002556 if (res != OK) return res;
2557 res = updateEntry(mCaptureRequest,
2558 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002559 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002560 if (res != OK) return res;
2561 res = updateEntry(mCaptureRequest,
2562 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002563 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002564 if (res != OK) return res;
2565
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002566 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002567 res = updateEntry(mCaptureRequest,
2568 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002569 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002570 if (res != OK) return res;
2571 res = updateEntry(mCaptureRequest,
2572 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002573 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002574 if (res != OK) return res;
2575 res = updateEntry(mCaptureRequest,
2576 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002577 params.gpsProcessingMethod.string(),
2578 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002579 if (res != OK) return res;
2580 } else {
2581 res = deleteEntry(mCaptureRequest,
2582 ANDROID_JPEG_GPS_COORDINATES);
2583 if (res != OK) return res;
2584 res = deleteEntry(mCaptureRequest,
2585 ANDROID_JPEG_GPS_TIMESTAMP);
2586 if (res != OK) return res;
2587 res = deleteEntry(mCaptureRequest,
2588 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2589 if (res != OK) return res;
2590 }
2591
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002592 return OK;
2593}
2594
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002595status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002596 ATRACE_CALL();
2597 status_t res;
2598 if (mRecordingRequest == NULL) {
2599 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2600 &mRecordingRequest);
2601 if (res != OK) {
2602 ALOGE("%s: Camera %d: Unable to create default recording request:"
2603 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2604 return res;
2605 }
2606 }
2607
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002608 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002609 if (res != OK) {
2610 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2611 "request: %s (%d)", __FUNCTION__, mCameraId,
2612 strerror(-res), res);
2613 return res;
2614 }
2615
2616 return OK;
2617}
2618
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002619status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002620 status_t res;
2621
2622 if (mRecordingConsumer == 0) {
2623 // Create CPU buffer queue endpoint
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002624 mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002625 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2626 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2627 mRecordingWindow = new SurfaceTextureClient(
2628 mRecordingConsumer->getProducerInterface());
2629 // Allocate memory later, since we don't know buffer size until receipt
2630 }
2631
2632 if (mRecordingStreamId != NO_STREAM) {
2633 // Check if stream parameters have to change
2634 uint32_t currentWidth, currentHeight;
2635 res = mDevice->getStreamInfo(mRecordingStreamId,
2636 &currentWidth, &currentHeight, 0);
2637 if (res != OK) {
2638 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2639 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2640 return res;
2641 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002642 if (currentWidth != (uint32_t)params.videoWidth ||
2643 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002644 // TODO: Should wait to be sure previous recording has finished
2645 res = mDevice->deleteStream(mRecordingStreamId);
2646 if (res != OK) {
2647 ALOGE("%s: Camera %d: Unable to delete old output stream "
2648 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2649 strerror(-res), res);
2650 return res;
2651 }
2652 mRecordingStreamId = NO_STREAM;
2653 }
2654 }
2655
2656 if (mRecordingStreamId == NO_STREAM) {
2657 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002658 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002659 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002660 if (res != OK) {
2661 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2662 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2663 return res;
2664 }
2665 }
2666
2667 return OK;
2668}
2669
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002670status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2671 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002672 ATRACE_CALL();
2673 status_t res;
2674 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002675 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002676 if (res != OK) return res;
2677
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002678 uint8_t wbMode = params.autoWhiteBalanceLock ?
2679 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002680 res = updateEntry(request,
2681 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2682 if (res != OK) return res;
2683 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002684 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002685 if (res != OK) return res;
2686 res = updateEntry(request,
2687 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002688 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002689 if (res != OK) return res;
2690
2691 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002692 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002693 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2694 res = updateEntry(request,
2695 ANDROID_CONTROL_MODE, &controlMode, 1);
2696 if (res != OK) return res;
2697 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2698 res = updateEntry(request,
2699 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002700 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002701 if (res != OK) return res;
2702 }
2703
2704 uint8_t flashMode = ANDROID_FLASH_OFF;
2705 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002706 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002707 case Parameters::FLASH_MODE_OFF:
2708 aeMode = ANDROID_CONTROL_AE_ON; break;
2709 case Parameters::FLASH_MODE_AUTO:
2710 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2711 case Parameters::FLASH_MODE_ON:
2712 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2713 case Parameters::FLASH_MODE_TORCH:
2714 aeMode = ANDROID_CONTROL_AE_ON;
2715 flashMode = ANDROID_FLASH_TORCH;
2716 break;
2717 case Parameters::FLASH_MODE_RED_EYE:
2718 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2719 default:
2720 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002721 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002722 return BAD_VALUE;
2723 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002724 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002725
2726 res = updateEntry(request,
2727 ANDROID_FLASH_MODE, &flashMode, 1);
2728 if (res != OK) return res;
2729 res = updateEntry(request,
2730 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2731 if (res != OK) return res;
2732
2733 float focusDistance = 0; // infinity focus in diopters
2734 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002735 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002736 case Parameters::FOCUS_MODE_AUTO:
2737 case Parameters::FOCUS_MODE_MACRO:
2738 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2739 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2740 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002741 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002742 break;
2743 case Parameters::FOCUS_MODE_INFINITY:
2744 case Parameters::FOCUS_MODE_FIXED:
2745 focusMode = ANDROID_CONTROL_AF_OFF;
2746 break;
2747 default:
2748 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002749 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002750 return BAD_VALUE;
2751 }
2752 res = updateEntry(request,
2753 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2754 if (res != OK) return res;
2755 res = updateEntry(request,
2756 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2757 if (res != OK) return res;
2758
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002759 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002760 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2761 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002762 focusingAreas[i + 0] = params.focusingAreas[i].left;
2763 focusingAreas[i + 1] = params.focusingAreas[i].top;
2764 focusingAreas[i + 2] = params.focusingAreas[i].right;
2765 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2766 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002767 }
2768 res = updateEntry(request,
2769 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2770 if (res != OK) return res;
2771 delete[] focusingAreas;
2772
2773 res = updateEntry(request,
2774 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002775 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002776 if (res != OK) return res;
2777
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002778 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002779 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2780 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002781 meteringAreas[i + 0] = params.meteringAreas[i].left;
2782 meteringAreas[i + 1] = params.meteringAreas[i].top;
2783 meteringAreas[i + 2] = params.meteringAreas[i].right;
2784 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2785 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002786 }
2787 res = updateEntry(request,
2788 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2789 if (res != OK) return res;
2790
2791 res = updateEntry(request,
2792 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2793 if (res != OK) return res;
2794 delete[] meteringAreas;
2795
2796 // Need to convert zoom index into a crop rectangle. The rectangle is
2797 // chosen to maximize its area on the sensor
2798
2799 camera_metadata_entry_t maxDigitalZoom =
2800 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2801 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2802 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002803 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002804
2805 camera_metadata_entry_t activePixelArraySize =
2806 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2807 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2808 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2809 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002810 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002811 zoomWidth = arrayWidth / zoomRatio;
2812 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002813 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002814 } else {
2815 zoomHeight = arrayHeight / zoomRatio;
2816 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002817 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002818 }
2819 zoomLeft = (arrayWidth - zoomWidth) / 2;
2820 zoomTop = (arrayHeight - zoomHeight) / 2;
2821
2822 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2823 res = updateEntry(request,
2824 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2825 if (res != OK) return res;
2826
2827 // TODO: Decide how to map recordingHint, or whether just to ignore it
2828
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002829 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002830 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2831 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2832 res = updateEntry(request,
2833 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2834 &vstabMode, 1);
2835 if (res != OK) return res;
2836
2837 return OK;
2838}
2839
2840status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2841 uint32_t tag, const void *data, size_t data_count) {
2842 camera_metadata_entry_t entry;
2843 status_t res;
2844 res = find_camera_metadata_entry(buffer, tag, &entry);
2845 if (res == NAME_NOT_FOUND) {
2846 res = add_camera_metadata_entry(buffer,
2847 tag, data, data_count);
2848 } else if (res == OK) {
2849 res = update_camera_metadata_entry(buffer,
2850 entry.index, data, data_count, NULL);
2851 }
2852
2853 if (res != OK) {
2854 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2855 __FUNCTION__, get_camera_metadata_section_name(tag),
2856 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2857 }
2858 return res;
2859}
2860
2861status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2862 camera_metadata_entry_t entry;
2863 status_t res;
2864 res = find_camera_metadata_entry(buffer, tag, &entry);
2865 if (res == NAME_NOT_FOUND) {
2866 return OK;
2867 } else if (res != OK) {
2868 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2869 __FUNCTION__,
2870 get_camera_metadata_section_name(tag),
2871 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2872 return res;
2873 }
2874 res = delete_camera_metadata_entry(buffer, entry.index);
2875 if (res != OK) {
2876 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2877 __FUNCTION__,
2878 get_camera_metadata_section_name(tag),
2879 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2880 }
2881 return res;
2882}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002883
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002884int Camera2Client::formatStringToEnum(const char *format) {
2885 return
2886 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2887 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2888 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2889 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2890 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2891 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2892 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2893 HAL_PIXEL_FORMAT_YV12 : // YV12
2894 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2895 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2896 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2897 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2898 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2899 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2900 -1;
2901}
2902
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002903const char* Camera2Client::formatEnumToString(int format) {
2904 const char *fmt;
2905 switch(format) {
2906 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2907 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2908 break;
2909 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2910 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2911 break;
2912 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2913 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2914 break;
2915 case HAL_PIXEL_FORMAT_YV12: // YV12
2916 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2917 break;
2918 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2919 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2920 break;
2921 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2922 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2923 break;
2924 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2925 ALOGW("Raw sensor preview format requested.");
2926 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2927 break;
2928 default:
2929 ALOGE("%s: Unknown preview format: %x",
2930 __FUNCTION__, format);
2931 fmt = NULL;
2932 break;
2933 }
2934 return fmt;
2935}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002936
2937int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2938 return
2939 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2940 ANDROID_CONTROL_AWB_AUTO :
2941 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2942 ANDROID_CONTROL_AWB_INCANDESCENT :
2943 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2944 ANDROID_CONTROL_AWB_FLUORESCENT :
2945 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2946 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2947 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2948 ANDROID_CONTROL_AWB_DAYLIGHT :
2949 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2950 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2951 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2952 ANDROID_CONTROL_AWB_TWILIGHT :
2953 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2954 ANDROID_CONTROL_AWB_SHADE :
2955 -1;
2956}
2957
2958int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2959 return
2960 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2961 ANDROID_CONTROL_EFFECT_OFF :
2962 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2963 ANDROID_CONTROL_EFFECT_MONO :
2964 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2965 ANDROID_CONTROL_EFFECT_NEGATIVE :
2966 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2967 ANDROID_CONTROL_EFFECT_SOLARIZE :
2968 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2969 ANDROID_CONTROL_EFFECT_SEPIA :
2970 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2971 ANDROID_CONTROL_EFFECT_POSTERIZE :
2972 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2973 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2974 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2975 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2976 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2977 ANDROID_CONTROL_EFFECT_AQUA :
2978 -1;
2979}
2980
2981int Camera2Client::abModeStringToEnum(const char *abMode) {
2982 return
2983 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2984 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2985 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2986 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2987 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2988 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2989 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2990 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2991 -1;
2992}
2993
2994int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2995 return
2996 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2997 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2998 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2999 ANDROID_CONTROL_SCENE_MODE_ACTION :
3000 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3001 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3002 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3003 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3004 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3005 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3006 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3007 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3008 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3009 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3010 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3011 ANDROID_CONTROL_SCENE_MODE_BEACH :
3012 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3013 ANDROID_CONTROL_SCENE_MODE_SNOW :
3014 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3015 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3016 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3017 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3018 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3019 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3020 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3021 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3022 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3023 ANDROID_CONTROL_SCENE_MODE_PARTY :
3024 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3025 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3026 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3027 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3028 -1;
3029}
3030
3031Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3032 const char *flashMode) {
3033 return
3034 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3035 Parameters::FLASH_MODE_OFF :
3036 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3037 Parameters::FLASH_MODE_AUTO :
3038 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3039 Parameters::FLASH_MODE_ON :
3040 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3041 Parameters::FLASH_MODE_RED_EYE :
3042 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3043 Parameters::FLASH_MODE_TORCH :
3044 Parameters::FLASH_MODE_INVALID;
3045}
3046
3047Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3048 const char *focusMode) {
3049 return
3050 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3051 Parameters::FOCUS_MODE_AUTO :
3052 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3053 Parameters::FOCUS_MODE_INFINITY :
3054 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3055 Parameters::FOCUS_MODE_MACRO :
3056 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3057 Parameters::FOCUS_MODE_FIXED :
3058 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3059 Parameters::FOCUS_MODE_EDOF :
3060 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3061 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3062 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3063 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3064 Parameters::FOCUS_MODE_INVALID;
3065}
3066
3067status_t Camera2Client::parseAreas(const char *areasCStr,
3068 Vector<Parameters::Area> *areas) {
3069 static const size_t NUM_FIELDS = 5;
3070 areas->clear();
3071 if (areasCStr == NULL) {
3072 // If no key exists, use default (0,0,0,0,0)
3073 areas->push();
3074 return OK;
3075 }
3076 String8 areasStr(areasCStr);
3077 ssize_t areaStart = areasStr.find("(", 0) + 1;
3078 while (areaStart != 0) {
3079 const char* area = areasStr.string() + areaStart;
3080 char *numEnd;
3081 int vals[NUM_FIELDS];
3082 for (size_t i = 0; i < NUM_FIELDS; i++) {
3083 errno = 0;
3084 vals[i] = strtol(area, &numEnd, 10);
3085 if (errno || numEnd == area) return BAD_VALUE;
3086 area = numEnd + 1;
3087 }
3088 areas->push(Parameters::Area(
3089 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3090 areaStart = areasStr.find("(", areaStart) + 1;
3091 }
3092 return OK;
3093}
3094
3095status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3096 size_t maxRegions) {
3097 // Definition of valid area can be found in
3098 // include/camera/CameraParameters.h
3099 if (areas.size() == 0) return BAD_VALUE;
3100 if (areas.size() == 1) {
3101 if (areas[0].left == 0 &&
3102 areas[0].top == 0 &&
3103 areas[0].right == 0 &&
3104 areas[0].bottom == 0 &&
3105 areas[0].weight == 0) {
3106 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3107 return OK;
3108 }
3109 }
3110 if (areas.size() > maxRegions) {
3111 ALOGE("%s: Too many areas requested: %d",
3112 __FUNCTION__, areas.size());
3113 return BAD_VALUE;
3114 }
3115
3116 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3117 a != areas.end(); a++) {
3118 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3119 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3120 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3121 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3122 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3123 if (a->left >= a->right) return BAD_VALUE;
3124 if (a->top >= a->bottom) return BAD_VALUE;
3125 }
3126 return OK;
3127}
3128
3129bool Camera2Client::boolFromString(const char *boolStr) {
3130 return !boolStr ? false :
3131 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3132 false;
3133}
3134
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003135int Camera2Client::degToTransform(int degrees, bool mirror) {
3136 if (!mirror) {
3137 if (degrees == 0) return 0;
3138 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3139 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3140 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3141 } else { // Do mirror (horizontal flip)
3142 if (degrees == 0) { // FLIP_H and ROT_0
3143 return HAL_TRANSFORM_FLIP_H;
3144 } else if (degrees == 90) { // FLIP_H and ROT_90
3145 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3146 } else if (degrees == 180) { // FLIP_H and ROT_180
3147 return HAL_TRANSFORM_FLIP_V;
3148 } else if (degrees == 270) { // FLIP_H and ROT_270
3149 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3150 }
3151 }
3152 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3153 return -1;
3154}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003155
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003156} // namespace android