blob: 66d8a5077cb51ca9d2cab3adafd4f54c7835b34b [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 Talvala8ce89d92012-08-10 08:40:26 -070055 mDeviceInfo(NULL),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070058 mCallbackStreamId(NO_STREAM),
59 mCallbackHeapId(0),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070060 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070061 mCaptureRequest(NULL),
62 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070063 mRecordingRequest(NULL),
64 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070066 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070067
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070069
70 LockedParameters::Key k(mParameters);
71 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072}
73
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070074status_t Camera2Client::checkPid(const char* checkLocation) const {
75 int callingPid = getCallingPid();
76 if (callingPid == mClientPid) return NO_ERROR;
77
78 ALOGE("%s: attempt to use a locked camera from a different process"
79 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
80 return PERMISSION_DENIED;
81}
82
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083status_t Camera2Client::initialize(camera_module_t *module)
84{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070085 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070086 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070087 status_t res;
88
89 res = mDevice->initialize(module);
90 if (res != OK) {
91 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
92 __FUNCTION__, mCameraId, strerror(-res), res);
93 return NO_INIT;
94 }
95
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070096 res = mDevice->setNotifyCallback(this);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070097 res = mDevice->setFrameListener(this);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070098
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070099 res = buildDeviceInfo();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700100 res = buildDefaultParameters();
101 if (res != OK) {
102 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
103 __FUNCTION__, mCameraId, strerror(-res), res);
104 return NO_INIT;
105 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700106
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700108 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
110 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700111 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700112 }
113
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700115}
116
117Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700118 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700119 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
120
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700121 mDestructionStarted = true;
122
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700123 // Rewrite mClientPid to allow shutdown by CameraService
124 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700125 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700126}
127
128status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700129 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700130 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700131 mCameraId,
132 getCameraClient()->asBinder().get(),
133 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700134 result.append(" State: ");
135#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
136
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700137 const Parameters& p = mParameters.unsafeUnlock();
138
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700139 result.append(getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700141 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700144 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700145 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700146 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700147 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700148 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700149 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700150 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700151 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700152 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700153 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700154 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700155 p.jpegQuality, p.jpegThumbQuality);
156 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.gpsEnabled ? "enabled" : "disabled");
159 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700161 p.gpsCoordinates[0], p.gpsCoordinates[1],
162 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700163 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700164 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700166 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700167 }
168
169 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700170 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
179 default: result.append("UNKNOWN\n");
180 }
181
182 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700183 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
193 default: result.append("UNKNOWN\n");
194 }
195
196 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700197 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700198 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
202 default: result.append("UNKNOWN\n");
203 }
204
205 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700206 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700207 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
208 result.append("AUTO\n"); break;
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
224 default: result.append("UNKNOWN\n");
225 }
226
227 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700228 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700229 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
230 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
231 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
232 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
233 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
234 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
235 default: result.append("UNKNOWN\n");
236 }
237
238 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700239 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
242 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
243 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
244 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
245 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
246 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
247 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
248 default: result.append("UNKNOWN\n");
249 }
250
251 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700252 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700253 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700254 p.focusingAreas[i].left,
255 p.focusingAreas[i].top,
256 p.focusingAreas[i].right,
257 p.focusingAreas[i].bottom,
258 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700259 }
260
261 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700262 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263
264 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 p.autoExposureLock ? "enabled" : "disabled",
266 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700267
268 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700269 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700270 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700271 p.meteringAreas[i].left,
272 p.meteringAreas[i].top,
273 p.meteringAreas[i].right,
274 p.meteringAreas[i].bottom,
275 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700276 }
277
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700278 result.appendFormat(" Zoom index: %d\n", p.zoom);
279 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
280 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700282 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700284
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700285 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700286 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700287
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700288 result.append(" Current streams:\n");
289 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
290 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292
293 result.append(" Current requests:\n");
294 if (mPreviewRequest != NULL) {
295 result.append(" Preview request:\n");
296 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700297 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700298 } else {
299 result.append(" Preview request: undefined\n");
300 write(fd, result.string(), result.size());
301 }
302
303 if (mCaptureRequest != NULL) {
304 result = " Capture request:\n";
305 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700306 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700307 } else {
308 result = " Capture request: undefined\n";
309 write(fd, result.string(), result.size());
310 }
311
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700312 if (mRecordingRequest != NULL) {
313 result = " Recording request:\n";
314 write(fd, result.string(), result.size());
315 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
316 } else {
317 result = " Recording request: undefined\n";
318 write(fd, result.string(), result.size());
319 }
320
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700321 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700322 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700323
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700324 status_t res = mDevice->dump(fd, args);
325 if (res != OK) {
326 result = String8::format(" Error dumping device: %s (%d)",
327 strerror(-res), res);
328 write(fd, result.string(), result.size());
329 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700330
331#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700332 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700333}
334
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700335const char* Camera2Client::getStateName(State state) {
336#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
337 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700338 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700339 CASE_ENUM_TO_CHAR(STOPPED)
340 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
341 CASE_ENUM_TO_CHAR(PREVIEW)
342 CASE_ENUM_TO_CHAR(RECORD)
343 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
344 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
345 default:
346 return "Unknown state!";
347 break;
348 }
349#undef CASE_ENUM_TO_CHAR
350}
351
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700352// ICamera interface
353
354void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700355 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700356 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700357 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700358 status_t res;
359 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700360
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700361 if (mDevice == 0) return;
362
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700363 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700364
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700365 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700366 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700367 mPreviewStreamId = NO_STREAM;
368 }
369
370 if (mCaptureStreamId != NO_STREAM) {
371 mDevice->deleteStream(mCaptureStreamId);
372 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700373 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700374
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700375 if (mRecordingStreamId != NO_STREAM) {
376 mDevice->deleteStream(mRecordingStreamId);
377 mRecordingStreamId = NO_STREAM;
378 }
379
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700380 if (mCallbackStreamId != NO_STREAM) {
381 mDevice->deleteStream(mCallbackStreamId);
382 mCallbackStreamId = NO_STREAM;
383 }
384
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700385 mDevice.clear();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700386 LockedParameters::Key k(mParameters);
387 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700388
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700389 if (mDeviceInfo != NULL) {
390 delete mDeviceInfo;
391 mDeviceInfo = NULL;
392 }
393
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700394 CameraService::Client::disconnect();
395}
396
397status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700398 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700399 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700400 Mutex::Autolock icl(mICameraLock);
401
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700402 if (mClientPid != 0 && getCallingPid() != mClientPid) {
403 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
404 "current locked to pid %d", __FUNCTION__,
405 mCameraId, getCallingPid(), mClientPid);
406 return BAD_VALUE;
407 }
408
409 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700410
411 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700412 mCameraClient = client;
413
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700414 LockedParameters::Key k(mParameters);
415 k.mParameters.state = STOPPED;
416
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700417 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700418}
419
420status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700421 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700422 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700423 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700424 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
425 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700426
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700427 if (mClientPid == 0) {
428 mClientPid = getCallingPid();
429 return OK;
430 }
431
432 if (mClientPid != getCallingPid()) {
433 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
434 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
435 return EBUSY;
436 }
437
438 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700439}
440
441status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700442 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700443 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700444 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700445 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
446 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700447
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700448 // TODO: Check for uninterruptable conditions
449
450 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700451 Mutex::Autolock iccl(mICameraClientLock);
452
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700453 mClientPid = 0;
454 mCameraClient.clear();
455 return OK;
456 }
457
458 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
459 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
460 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700461}
462
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700463status_t Camera2Client::setPreviewDisplay(
464 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700465 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700466 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700467 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700468 status_t res;
469 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700470
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700471 sp<IBinder> binder;
472 sp<ANativeWindow> window;
473 if (surface != 0) {
474 binder = surface->asBinder();
475 window = surface;
476 }
477
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700478 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700479}
480
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700481status_t Camera2Client::setPreviewTexture(
482 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700483 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700484 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700485 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700486 status_t res;
487 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700488
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700489 sp<IBinder> binder;
490 sp<ANativeWindow> window;
491 if (surfaceTexture != 0) {
492 binder = surfaceTexture->asBinder();
493 window = new SurfaceTextureClient(surfaceTexture);
494 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700495 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700496}
497
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700498status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700499 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700500 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700501 status_t res;
502
503 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700504 ALOGV("%s: Camera %d: New window is same as old window",
505 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700506 return NO_ERROR;
507 }
508
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700509 LockedParameters::Key k(mParameters);
510 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700511 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700512 case RECORD:
513 case STILL_CAPTURE:
514 case VIDEO_SNAPSHOT:
515 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700516 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700517 return INVALID_OPERATION;
518 case STOPPED:
519 case WAITING_FOR_PREVIEW_WINDOW:
520 // OK
521 break;
522 case PREVIEW:
523 // Already running preview - need to stop and create a new stream
524 // TODO: Optimize this so that we don't wait for old stream to drain
525 // before spinning up new stream
526 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700527 k.mParameters.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700528 break;
529 }
530
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700531 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700532 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700534 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
535 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700536 return res;
537 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700538 res = mDevice->deleteStream(mPreviewStreamId);
539 if (res != OK) {
540 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
541 __FUNCTION__, strerror(-res), res);
542 return res;
543 }
544 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700545 }
546
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700547 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700548 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700549
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700550 if (k.mParameters.state == WAITING_FOR_PREVIEW_WINDOW) {
551 return startPreviewL(k.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 }
553
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700554 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700555}
556
557void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700558 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700559 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700560 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700561 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700562 if ( checkPid(__FUNCTION__) != OK) return;
563
564 LockedParameters::Key k(mParameters);
565 setPreviewCallbackFlagL(k.mParameters, flag);
566}
567
568void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
569 status_t res = OK;
570 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
571 ALOGV("%s: setting oneshot", __FUNCTION__);
572 params.previewCallbackOneShot = true;
573 }
574 if (params.previewCallbackFlags != (uint32_t)flag) {
575 params.previewCallbackFlags = flag;
576 switch(params.state) {
577 case PREVIEW:
578 res = startPreviewL(params, true);
579 break;
580 case RECORD:
581 case VIDEO_SNAPSHOT:
582 res = startRecordingL(params, true);
583 break;
584 default:
585 break;
586 }
587 if (res != OK) {
588 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
589 __FUNCTION__, mCameraId, getStateName(params.state));
590 }
591 }
592
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700593}
594
595status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700596 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700597 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700598 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700599 status_t res;
600 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700601 LockedParameters::Key k(mParameters);
602 return startPreviewL(k.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700603}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700604
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700605status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700606 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700607 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700608 if (params.state >= PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700609 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700610 __FUNCTION__, getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700611 return INVALID_OPERATION;
612 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700614 if (mPreviewWindow == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700615 params.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700616 return OK;
617 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700618 params.state = STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700619
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700620 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700621 if (res != OK) {
622 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
623 __FUNCTION__, mCameraId, strerror(-res), res);
624 return res;
625 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700626 bool callbacksEnabled = params.previewCallbackFlags &
627 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
628 if (callbacksEnabled) {
629 res = updateCallbackStream(params);
630 if (res != OK) {
631 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
632 __FUNCTION__, mCameraId, strerror(-res), res);
633 return res;
634 }
635 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700636
637 if (mPreviewRequest == NULL) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700638 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700639 if (res != OK) {
640 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
641 __FUNCTION__, mCameraId, strerror(-res), res);
642 return res;
643 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700644 }
645
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700646 if (callbacksEnabled) {
647 uint8_t outputStreams[2] =
648 { mPreviewStreamId, mCallbackStreamId };
649 res = updateEntry(mPreviewRequest,
650 ANDROID_REQUEST_OUTPUT_STREAMS,
651 outputStreams, 2);
652 } else {
653 res = updateEntry(mPreviewRequest,
654 ANDROID_REQUEST_OUTPUT_STREAMS,
655 &mPreviewStreamId, 1);
656 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700657 if (res != OK) {
658 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
659 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700660 return res;
661 }
662 res = sort_camera_metadata(mPreviewRequest);
663 if (res != OK) {
664 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
665 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666 return res;
667 }
668
669 res = mDevice->setStreamingRequest(mPreviewRequest);
670 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700671 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
672 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700673 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700674 return res;
675 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700676 params.state = PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700677
678 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700679}
680
681void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700682 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700683 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700684 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700685 status_t res;
686 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700687 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700688}
689
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700690void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700691 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700692 State state;
693 {
694 LockedParameters::Key k(mParameters);
695 state = k.mParameters.state;
696 }
697
698 switch (state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700699 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700700 ALOGE("%s: Camera %d: Call before initialized",
701 __FUNCTION__, mCameraId);
702 break;
703 case STOPPED:
704 break;
705 case STILL_CAPTURE:
706 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
707 __FUNCTION__, mCameraId);
708 break;
709 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700710 // no break - identical to preview
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700711 case PREVIEW:
712 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700713 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700714 // no break
715 case WAITING_FOR_PREVIEW_WINDOW: {
716 LockedParameters::Key k(mParameters);
717 k.mParameters.state = STOPPED;
718 commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700719 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700720 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700721 default:
722 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700723 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700724 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700725}
726
727bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700728 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700729 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700730 status_t res;
731 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
732
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700733 LockedParameters::Key k(mParameters);
734 return k.mParameters.state == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700735}
736
737status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700738 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700739 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700740 status_t res;
741 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
742
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700743 LockedParameters::Key k(mParameters);
744 switch (k.mParameters.state) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700745 case RECORD:
746 case VIDEO_SNAPSHOT:
747 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700748 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700749 return INVALID_OPERATION;
750 default:
751 // OK
752 break;
753 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700754
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700755 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700756
757 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700758}
759
760status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700761 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700762 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700763 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700764 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700765 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700766 LockedParameters::Key k(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700767
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700768 return startRecordingL(k.mParameters, false);
769}
770
771status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
772 status_t res;
773 switch (params.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 case STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700775 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700776 if (res != OK) return res;
777 break;
778 case PREVIEW:
779 // Ready to go
780 break;
781 case RECORD:
782 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700783 // OK to call this when recording is already on, just skip unless
784 // we're looking to restart
785 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700786 break;
787 default:
788 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700789 __FUNCTION__, mCameraId, getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700790 return INVALID_OPERATION;
791 };
792
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700793 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700794 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
795 "non-metadata recording mode requested!", __FUNCTION__,
796 mCameraId);
797 return INVALID_OPERATION;
798 }
799
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700800 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700801 if (res != OK) {
802 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
803 __FUNCTION__, mCameraId, strerror(-res), res);
804 return res;
805 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700806 bool callbacksEnabled = params.previewCallbackFlags &
807 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
808 if (callbacksEnabled) {
809 res = updateCallbackStream(params);
810 if (res != OK) {
811 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
812 __FUNCTION__, mCameraId, strerror(-res), res);
813 return res;
814 }
815 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700816
817 if (mRecordingRequest == NULL) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700818 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700819 if (res != OK) {
820 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
821 __FUNCTION__, mCameraId, strerror(-res), res);
822 return res;
823 }
824 }
825
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700826 if (callbacksEnabled) {
827 uint8_t outputStreams[3] =
828 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
829 res = updateEntry(mRecordingRequest,
830 ANDROID_REQUEST_OUTPUT_STREAMS,
831 outputStreams, 3);
832 } else {
833 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
834 res = updateEntry(mRecordingRequest,
835 ANDROID_REQUEST_OUTPUT_STREAMS,
836 outputStreams, 2);
837 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700838 if (res != OK) {
839 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
840 __FUNCTION__, mCameraId, strerror(-res), res);
841 return res;
842 }
843 res = sort_camera_metadata(mRecordingRequest);
844 if (res != OK) {
845 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
846 __FUNCTION__, mCameraId, strerror(-res), res);
847 return res;
848 }
849
850 res = mDevice->setStreamingRequest(mRecordingRequest);
851 if (res != OK) {
852 ALOGE("%s: Camera %d: Unable to set recording request to start "
853 "recording: %s (%d)", __FUNCTION__, mCameraId,
854 strerror(-res), res);
855 return res;
856 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700857 if (params.state < RECORD) {
858 params.state = RECORD;
859 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700860
861 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700862}
863
864void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700865 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700866 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700867 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700868 LockedParameters::Key k(mParameters);
869
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700870 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700871 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
872
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700873 switch (k.mParameters.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700874 case RECORD:
875 // OK to stop
876 break;
877 case STOPPED:
878 case PREVIEW:
879 case STILL_CAPTURE:
880 case VIDEO_SNAPSHOT:
881 default:
882 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700883 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700884 return;
885 };
886
887 // Back to preview. Since record can only be reached through preview,
888 // all preview stream setup should be up to date.
889 res = mDevice->setStreamingRequest(mPreviewRequest);
890 if (res != OK) {
891 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
892 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
893 return;
894 }
895
896 // TODO: Should recording heap be freed? Can't do it yet since requests
897 // could still be in flight.
898
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700899 k.mParameters.state = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700900}
901
902bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700903 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700904 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700905
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700906 if ( checkPid(__FUNCTION__) != OK) return false;
907
James Dong8da4cd72012-08-04 19:58:07 -0700908 return recordingEnabledL();
909}
910
911bool Camera2Client::recordingEnabledL() {
912 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700913 LockedParameters::Key k(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700914
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700915 return (k.mParameters.state == RECORD || k.mParameters.state == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700916}
917
918void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700919 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700920 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700921 status_t res;
922 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700923 // Make sure this is for the current heap
924 ssize_t offset;
925 size_t size;
926 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
927 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
928 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
929 "(got %x, expected %x)", __FUNCTION__, mCameraId,
930 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
931 return;
932 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700933 uint8_t *data = (uint8_t*)heap->getBase() + offset;
934 uint32_t type = *(uint32_t*)data;
935 if (type != kMetadataBufferTypeGrallocSource) {
936 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
937 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
938 return;
939 }
940 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
941 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700942 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700943 res = mRecordingConsumer->freeBuffer(imgBuffer);
944 if (res != OK) {
945 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
946 "%s (%d)",
947 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
948 return;
949 }
950
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700951 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700952}
953
954status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700955 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700956 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700957 status_t res;
958 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
959
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700960 int triggerId;
961 {
962 LockedParameters::Key k(mParameters);
963 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
964 triggerId = k.mParameters.currentAfTriggerId;
965 }
966
967 mDevice->triggerAutofocus(triggerId);
968
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700969 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700970}
971
972status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700973 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700974 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700975 status_t res;
976 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
977
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700978 int triggerId;
979 {
980 LockedParameters::Key k(mParameters);
981 triggerId = ++k.mParameters.afTriggerCounter;
982 }
983
984 mDevice->triggerCancelAutofocus(triggerId);
985
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700986 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700987}
988
989status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700990 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700991 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700992 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700993 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700994
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700995 LockedParameters::Key k(mParameters);
996 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700997 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700998 case STOPPED:
999 case WAITING_FOR_PREVIEW_WINDOW:
1000 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1001 __FUNCTION__, mCameraId);
1002 return INVALID_OPERATION;
1003 case PREVIEW:
1004 case RECORD:
1005 // Good to go for takePicture
1006 break;
1007 case STILL_CAPTURE:
1008 case VIDEO_SNAPSHOT:
1009 ALOGE("%s: Camera %d: Already taking a picture",
1010 __FUNCTION__, mCameraId);
1011 return INVALID_OPERATION;
1012 }
1013
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001014 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001015
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001016 res = updateCaptureStream(k.mParameters);
1017 if (res != OK) {
1018 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1019 __FUNCTION__, mCameraId, strerror(-res), res);
1020 return res;
1021 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001022
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001023 if (mCaptureRequest == NULL) {
1024 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001025 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001026 ALOGE("%s: Camera %d: Can't create still image capture request: "
1027 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001028 return res;
1029 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001030 }
1031
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001032 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001033
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001034 bool callbacksEnabled = k.mParameters.previewCallbackFlags &
1035 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
1036 bool recordingEnabled = (k.mParameters.state == RECORD);
1037
1038 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1039 (recordingEnabled ? 0x1 : 0x0);
1040 switch ( streamSwitch ) {
1041 case 0: { // No recording, callbacks
1042 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
1043 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1044 &streamIds, 2);
1045 break;
1046 }
1047 case 1: { // Recording
1048 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1049 mCaptureStreamId };
1050 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1051 &streamIds, 3);
1052 break;
1053 }
1054 case 2: { // Callbacks
1055 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1056 mCaptureStreamId };
1057 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1058 &streamIds, 3);
1059 break;
1060 }
1061 case 3: { // Both
1062 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1063 mRecordingStreamId, mCaptureStreamId };
1064 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1065 &streamIds, 4);
1066 break;
1067 }
1068 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001069 if (res != OK) {
1070 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1071 "%s (%d)",
1072 __FUNCTION__, mCameraId, strerror(-res), res);
1073 return res;
1074 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001075 res = sort_camera_metadata(mCaptureRequest);
1076 if (res != OK) {
1077 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1078 __FUNCTION__, mCameraId, strerror(-res), res);
1079 return res;
1080 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001081
1082 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
1083 if (captureCopy == NULL) {
1084 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1085 __FUNCTION__, mCameraId);
1086 return NO_MEMORY;
1087 }
1088
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001089 if (k.mParameters.state == PREVIEW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001090 res = mDevice->setStreamingRequest(NULL);
1091 if (res != OK) {
1092 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1093 "%s (%d)",
1094 __FUNCTION__, mCameraId, strerror(-res), res);
1095 return res;
1096 }
1097 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001098 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001099 res = mDevice->capture(captureCopy);
1100 if (res != OK) {
1101 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1102 "%s (%d)",
1103 __FUNCTION__, mCameraId, strerror(-res), res);
1104 return res;
1105 }
1106
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001107 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001108 case PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001109 k.mParameters.state = STILL_CAPTURE;
1110 res = commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001111 if (res != OK) {
1112 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1113 __FUNCTION__, mCameraId);
1114 return res;
1115 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001116 break;
1117 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001118 k.mParameters.state = VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001119 break;
1120 default:
1121 ALOGE("%s: Camera %d: Unknown state for still capture!",
1122 __FUNCTION__, mCameraId);
1123 return INVALID_OPERATION;
1124 }
1125
1126 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001127}
1128
1129status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001130 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001131 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001132 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001133 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001134 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1135
1136 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001137
1138 CameraParameters newParams(params);
1139
1140 // TODO: Currently ignoring any changes to supposedly read-only
1141 // parameters such as supported preview sizes, etc. Should probably
1142 // produce an error if they're changed.
1143
1144 /** Extract and verify new parameters */
1145
1146 size_t i;
1147
1148 // PREVIEW_SIZE
1149 int previewWidth, previewHeight;
1150 newParams.getPreviewSize(&previewWidth, &previewHeight);
1151
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001152 if (previewWidth != k.mParameters.previewWidth ||
1153 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001154 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001155 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001156 "is active! (Currently %d x %d, requested %d x %d",
1157 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001158 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001159 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001160 return BAD_VALUE;
1161 }
1162 camera_metadata_entry_t availablePreviewSizes =
1163 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1164 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1165 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1166 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1167 }
1168 if (i == availablePreviewSizes.count) {
1169 ALOGE("%s: Requested preview size %d x %d is not supported",
1170 __FUNCTION__, previewWidth, previewHeight);
1171 return BAD_VALUE;
1172 }
1173 }
1174
1175 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001176 int previewFpsRange[2];
1177 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001178 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001179 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001180 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1181 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001182 fpsRangeChanged = true;
1183 camera_metadata_entry_t availablePreviewFpsRanges =
1184 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1185 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1186 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001187 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001188 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001189 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001190 break;
1191 }
1192 }
1193 if (i == availablePreviewFpsRanges.count) {
1194 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001195 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001196 return BAD_VALUE;
1197 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001198 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001199 }
1200
1201 // PREVIEW_FORMAT
1202 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001203 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001204 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001205 ALOGE("%s: Preview format cannot be updated when preview "
1206 "is active!", __FUNCTION__);
1207 return BAD_VALUE;
1208 }
1209 camera_metadata_entry_t availableFormats =
1210 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1211 for (i = 0; i < availableFormats.count; i++) {
1212 if (availableFormats.data.i32[i] == previewFormat) break;
1213 }
1214 if (i == availableFormats.count) {
1215 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1216 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1217 return BAD_VALUE;
1218 }
1219 }
1220
1221 // PREVIEW_FRAME_RATE
1222 // Deprecated, only use if the preview fps range is unchanged this time.
1223 // The single-value FPS is the same as the minimum of the range.
1224 if (!fpsRangeChanged) {
1225 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001226 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001227 camera_metadata_entry_t availableFrameRates =
1228 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1229 for (i = 0; i < availableFrameRates.count; i+=2) {
1230 if (availableFrameRates.data.i32[i] == previewFps) break;
1231 }
1232 if (i == availableFrameRates.count) {
1233 ALOGE("%s: Requested preview frame rate %d is not supported",
1234 __FUNCTION__, previewFps);
1235 return BAD_VALUE;
1236 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001237 previewFpsRange[0] = availableFrameRates.data.i32[i];
1238 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001239 }
1240 }
1241
1242 // PICTURE_SIZE
1243 int pictureWidth, pictureHeight;
1244 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001245 if (pictureWidth == k.mParameters.pictureWidth ||
1246 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001247 camera_metadata_entry_t availablePictureSizes =
1248 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1249 for (i = 0; i < availablePictureSizes.count; i+=2) {
1250 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1251 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1252 }
1253 if (i == availablePictureSizes.count) {
1254 ALOGE("%s: Requested picture size %d x %d is not supported",
1255 __FUNCTION__, pictureWidth, pictureHeight);
1256 return BAD_VALUE;
1257 }
1258 }
1259
1260 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001261 int jpegThumbSize[2];
1262 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001263 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001264 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001265 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001266 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1267 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001268 camera_metadata_entry_t availableJpegThumbSizes =
1269 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1270 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001271 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1272 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001273 break;
1274 }
1275 }
1276 if (i == availableJpegThumbSizes.count) {
1277 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001278 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001279 return BAD_VALUE;
1280 }
1281 }
1282
1283 // JPEG_THUMBNAIL_QUALITY
1284 int jpegThumbQuality =
1285 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1286 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1287 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1288 __FUNCTION__, jpegThumbQuality);
1289 return BAD_VALUE;
1290 }
1291
1292 // JPEG_QUALITY
1293 int jpegQuality =
1294 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1295 if (jpegQuality < 0 || jpegQuality > 100) {
1296 ALOGE("%s: Requested JPEG quality %d is not supported",
1297 __FUNCTION__, jpegQuality);
1298 return BAD_VALUE;
1299 }
1300
1301 // ROTATION
1302 int jpegRotation =
1303 newParams.getInt(CameraParameters::KEY_ROTATION);
1304 if (jpegRotation != 0 &&
1305 jpegRotation != 90 &&
1306 jpegRotation != 180 &&
1307 jpegRotation != 270) {
1308 ALOGE("%s: Requested picture rotation angle %d is not supported",
1309 __FUNCTION__, jpegRotation);
1310 return BAD_VALUE;
1311 }
1312
1313 // GPS
1314 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001315 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001316 int64_t gpsTimestamp = 0;
1317 String8 gpsProcessingMethod;
1318 const char *gpsLatStr =
1319 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1320 if (gpsLatStr != NULL) {
1321 const char *gpsLongStr =
1322 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1323 const char *gpsAltitudeStr =
1324 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1325 const char *gpsTimeStr =
1326 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1327 const char *gpsProcMethodStr =
1328 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1329 if (gpsLongStr == NULL ||
1330 gpsAltitudeStr == NULL ||
1331 gpsTimeStr == NULL ||
1332 gpsProcMethodStr == NULL) {
1333 ALOGE("%s: Incomplete set of GPS parameters provided",
1334 __FUNCTION__);
1335 return BAD_VALUE;
1336 }
1337 char *endPtr;
1338 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001339 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001340 if (errno || endPtr == gpsLatStr) {
1341 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1342 return BAD_VALUE;
1343 }
1344 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001345 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001346 if (errno || endPtr == gpsLongStr) {
1347 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1348 return BAD_VALUE;
1349 }
1350 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001351 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001352 if (errno || endPtr == gpsAltitudeStr) {
1353 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1354 gpsAltitudeStr);
1355 return BAD_VALUE;
1356 }
1357 errno = 0;
1358 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1359 if (errno || endPtr == gpsTimeStr) {
1360 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1361 return BAD_VALUE;
1362 }
1363 gpsProcessingMethod = gpsProcMethodStr;
1364
1365 gpsEnabled = true;
1366 }
1367
1368 // WHITE_BALANCE
1369 int wbMode = wbModeStringToEnum(
1370 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001371 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001372 camera_metadata_entry_t availableWbModes =
1373 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1374 for (i = 0; i < availableWbModes.count; i++) {
1375 if (wbMode == availableWbModes.data.u8[i]) break;
1376 }
1377 if (i == availableWbModes.count) {
1378 ALOGE("%s: Requested white balance mode %s is not supported",
1379 __FUNCTION__,
1380 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1381 return BAD_VALUE;
1382 }
1383 }
1384
1385 // EFFECT
1386 int effectMode = effectModeStringToEnum(
1387 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001388 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001389 camera_metadata_entry_t availableEffectModes =
1390 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1391 for (i = 0; i < availableEffectModes.count; i++) {
1392 if (effectMode == availableEffectModes.data.u8[i]) break;
1393 }
1394 if (i == availableEffectModes.count) {
1395 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1396 __FUNCTION__,
1397 newParams.get(CameraParameters::KEY_EFFECT) );
1398 return BAD_VALUE;
1399 }
1400 }
1401
1402 // ANTIBANDING
1403 int antibandingMode = abModeStringToEnum(
1404 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001405 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001406 camera_metadata_entry_t availableAbModes =
1407 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1408 for (i = 0; i < availableAbModes.count; i++) {
1409 if (antibandingMode == availableAbModes.data.u8[i]) break;
1410 }
1411 if (i == availableAbModes.count) {
1412 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1413 __FUNCTION__,
1414 newParams.get(CameraParameters::KEY_ANTIBANDING));
1415 return BAD_VALUE;
1416 }
1417 }
1418
1419 // SCENE_MODE
1420 int sceneMode = sceneModeStringToEnum(
1421 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala3cc89792012-08-16 16:03:59 -07001422 if (sceneMode != k.mParameters.sceneMode &&
1423 sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001424 camera_metadata_entry_t availableSceneModes =
1425 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1426 for (i = 0; i < availableSceneModes.count; i++) {
1427 if (sceneMode == availableSceneModes.data.u8[i]) break;
1428 }
1429 if (i == availableSceneModes.count) {
1430 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1431 __FUNCTION__,
1432 newParams.get(CameraParameters::KEY_SCENE_MODE));
1433 return BAD_VALUE;
1434 }
1435 }
1436
1437 // FLASH_MODE
1438 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1439 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001440 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001441 camera_metadata_entry_t flashAvailable =
1442 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1443 if (!flashAvailable.data.u8[0] &&
1444 flashMode != Parameters::FLASH_MODE_OFF) {
1445 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1446 "No flash on device", __FUNCTION__,
1447 newParams.get(CameraParameters::KEY_FLASH_MODE));
1448 return BAD_VALUE;
1449 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1450 camera_metadata_entry_t availableAeModes =
1451 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1452 for (i = 0; i < availableAeModes.count; i++) {
1453 if (flashMode == availableAeModes.data.u8[i]) break;
1454 }
1455 if (i == availableAeModes.count) {
1456 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1457 __FUNCTION__,
1458 newParams.get(CameraParameters::KEY_FLASH_MODE));
1459 return BAD_VALUE;
1460 }
1461 } else if (flashMode == -1) {
1462 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1463 __FUNCTION__,
1464 newParams.get(CameraParameters::KEY_FLASH_MODE));
1465 return BAD_VALUE;
1466 }
1467 }
1468
1469 // FOCUS_MODE
1470 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1471 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001472 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001473 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1474 camera_metadata_entry_t minFocusDistance =
1475 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1476 if (minFocusDistance.data.f[0] == 0) {
1477 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1478 "fixed focus lens",
1479 __FUNCTION__,
1480 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1481 return BAD_VALUE;
1482 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1483 camera_metadata_entry_t availableFocusModes =
1484 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1485 for (i = 0; i < availableFocusModes.count; i++) {
1486 if (focusMode == availableFocusModes.data.u8[i]) break;
1487 }
1488 if (i == availableFocusModes.count) {
1489 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1490 __FUNCTION__,
1491 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1492 return BAD_VALUE;
1493 }
1494 }
1495 }
1496 }
1497
1498 // FOCUS_AREAS
1499 Vector<Parameters::Area> focusingAreas;
1500 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1501 &focusingAreas);
1502 size_t max3aRegions =
1503 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1504 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1505 if (res != OK) {
1506 ALOGE("%s: Requested focus areas are malformed: %s",
1507 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1508 return BAD_VALUE;
1509 }
1510
1511 // EXPOSURE_COMPENSATION
1512 int exposureCompensation =
1513 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1514 camera_metadata_entry_t exposureCompensationRange =
1515 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1516 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1517 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1518 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1519 __FUNCTION__, exposureCompensation);
1520 return BAD_VALUE;
1521 }
1522
1523 // AUTO_EXPOSURE_LOCK (always supported)
1524 bool autoExposureLock = boolFromString(
1525 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1526
1527 // AUTO_WHITEBALANCE_LOCK (always supported)
1528 bool autoWhiteBalanceLock = boolFromString(
1529 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1530
1531 // METERING_AREAS
1532 Vector<Parameters::Area> meteringAreas;
1533 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1534 &meteringAreas);
1535 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1536 if (res != OK) {
1537 ALOGE("%s: Requested metering areas are malformed: %s",
1538 __FUNCTION__,
1539 newParams.get(CameraParameters::KEY_METERING_AREAS));
1540 return BAD_VALUE;
1541 }
1542
1543 // ZOOM
1544 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1545 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1546 ALOGE("%s: Requested zoom level %d is not supported",
1547 __FUNCTION__, zoom);
1548 return BAD_VALUE;
1549 }
1550
1551 // VIDEO_SIZE
1552 int videoWidth, videoHeight;
1553 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001554 if (videoWidth != k.mParameters.videoWidth ||
1555 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001556 if (k.mParameters.state == RECORD) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001557 ALOGE("%s: Video size cannot be updated when recording is active!",
1558 __FUNCTION__);
1559 return BAD_VALUE;
1560 }
1561 camera_metadata_entry_t availableVideoSizes =
1562 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1563 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1564 if (availableVideoSizes.data.i32[i] == videoWidth &&
1565 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1566 }
1567 if (i == availableVideoSizes.count) {
1568 ALOGE("%s: Requested video size %d x %d is not supported",
1569 __FUNCTION__, videoWidth, videoHeight);
1570 return BAD_VALUE;
1571 }
1572 }
1573
1574 // RECORDING_HINT (always supported)
1575 bool recordingHint = boolFromString(
1576 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1577
1578 // VIDEO_STABILIZATION
1579 bool videoStabilization = boolFromString(
1580 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1581 camera_metadata_entry_t availableVideoStabilizationModes =
1582 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1583 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1584 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1585 }
1586
1587 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001588
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001589 k.mParameters.previewWidth = previewWidth;
1590 k.mParameters.previewHeight = previewHeight;
1591 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1592 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1593 k.mParameters.previewFps = previewFps;
1594 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001595
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001596 k.mParameters.pictureWidth = pictureWidth;
1597 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001598
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001599 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1600 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1601 k.mParameters.jpegQuality = jpegQuality;
1602 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001603
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001604 k.mParameters.gpsEnabled = gpsEnabled;
1605 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1606 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1607 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1608 k.mParameters.gpsTimestamp = gpsTimestamp;
1609 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001610
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001611 k.mParameters.wbMode = wbMode;
1612 k.mParameters.effectMode = effectMode;
1613 k.mParameters.antibandingMode = antibandingMode;
1614 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001615
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001616 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001617 if (focusMode != k.mParameters.focusMode) {
1618 k.mParameters.currentAfTriggerId = -1;
1619 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001620 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001621
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001622 k.mParameters.focusingAreas = focusingAreas;
1623 k.mParameters.exposureCompensation = exposureCompensation;
1624 k.mParameters.autoExposureLock = autoExposureLock;
1625 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1626 k.mParameters.meteringAreas = meteringAreas;
1627 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001628
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001629 k.mParameters.videoWidth = videoWidth;
1630 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001631
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001632 k.mParameters.recordingHint = recordingHint;
1633 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001634
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001635 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001636
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001637 res = updateRequests(k.mParameters);
1638
1639 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001640}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001641
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001642String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001643 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001644 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001645 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001646
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001647 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001648
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001649 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001650 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001651}
1652
1653status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001654 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001655 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001656 status_t res;
1657 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001658
1659 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1660 cmd, arg1, arg2);
1661
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001662 switch (cmd) {
1663 case CAMERA_CMD_START_SMOOTH_ZOOM:
1664 return commandStartSmoothZoomL();
1665 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1666 return commandStopSmoothZoomL();
1667 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1668 return commandSetDisplayOrientationL(arg1);
1669 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1670 return commandEnableShutterSoundL(arg1 == 1);
1671 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1672 return commandPlayRecordingSoundL();
1673 case CAMERA_CMD_START_FACE_DETECTION:
1674 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001675 case CAMERA_CMD_STOP_FACE_DETECTION: {
1676 LockedParameters::Key k(mParameters);
1677 return commandStopFaceDetectionL(k.mParameters);
1678 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001679 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1680 return commandEnableFocusMoveMsgL(arg1 == 1);
1681 case CAMERA_CMD_PING:
1682 return commandPingL();
1683 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1684 return commandSetVideoBufferCountL(arg1);
1685 default:
1686 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1687 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001688 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001689 }
1690}
James Dong983cf232012-08-01 16:39:55 -07001691
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001692status_t Camera2Client::commandStartSmoothZoomL() {
1693 ALOGE("%s: Unimplemented!", __FUNCTION__);
1694 return OK;
1695}
James Dong983cf232012-08-01 16:39:55 -07001696
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001697status_t Camera2Client::commandStopSmoothZoomL() {
1698 ALOGE("%s: Unimplemented!", __FUNCTION__);
1699 return OK;
1700}
James Dong983cf232012-08-01 16:39:55 -07001701
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001702status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1703 LockedParameters::Key k(mParameters);
1704 int transform = degToTransform(degrees,
1705 mCameraFacing == CAMERA_FACING_FRONT);
1706 if (transform == -1) {
1707 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1708 __FUNCTION__, mCameraId, degrees);
1709 return BAD_VALUE;
1710 }
1711 if (transform != k.mParameters.previewTransform &&
1712 mPreviewStreamId != NO_STREAM) {
1713 mDevice->setStreamTransform(mPreviewStreamId, transform);
1714 }
1715 k.mParameters.previewTransform = transform;
1716 return OK;
1717}
1718
1719status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1720 LockedParameters::Key k(mParameters);
1721 if (enable) {
1722 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001723 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001724 }
1725
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001726 // Disabling shutter sound may not be allowed. In that case only
1727 // allow the mediaserver process to disable the sound.
1728 char value[PROPERTY_VALUE_MAX];
1729 property_get("ro.camera.sound.forced", value, "0");
1730 if (strncmp(value, "0", 2) != 0) {
1731 // Disabling shutter sound is not allowed. Deny if the current
1732 // process is not mediaserver.
1733 if (getCallingPid() != getpid()) {
1734 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1735 getCallingPid());
1736 return PERMISSION_DENIED;
1737 }
1738 }
1739
1740 k.mParameters.playShutterSound = false;
1741 return OK;
1742}
1743
1744status_t Camera2Client::commandPlayRecordingSoundL() {
1745 mCameraService->playSound(CameraService::SOUND_RECORDING);
1746 return OK;
1747}
1748
1749status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001750 ALOGV("%s: Camera %d: Starting face detection",
1751 __FUNCTION__, mCameraId);
1752 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001753 LockedParameters::Key k(mParameters);
1754 switch (k.mParameters.state) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001755 case DISCONNECTED:
1756 case STOPPED:
1757 case WAITING_FOR_PREVIEW_WINDOW:
1758 case STILL_CAPTURE:
1759 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1760 __FUNCTION__, mCameraId);
1761 return INVALID_OPERATION;
1762 case PREVIEW:
1763 case RECORD:
1764 case VIDEO_SNAPSHOT:
1765 // Good to go for starting face detect
1766 break;
1767 }
1768 // Ignoring type
1769 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1770 ALOGE("%s: Camera %d: Face detection not supported",
1771 __FUNCTION__, mCameraId);
1772 return INVALID_OPERATION;
1773 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001774 if (k.mParameters.enableFaceDetect) return OK;
1775
1776 k.mParameters.enableFaceDetect = true;
1777
1778 res = updateRequests(k.mParameters);
1779
1780 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001781}
1782
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001783status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001784 status_t res = OK;
1785 ALOGV("%s: Camera %d: Stopping face detection",
1786 __FUNCTION__, mCameraId);
1787
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001788 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001789
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001790 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001791
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001792 if (params.state == PREVIEW || params.state == RECORD ||
1793 params.state == VIDEO_SNAPSHOT) {
1794 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001795 }
1796
1797 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001798}
1799
1800status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001801 LockedParameters::Key k(mParameters);
1802 k.mParameters.enableFocusMoveMessages = enable;
1803
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001804 return OK;
1805}
1806
1807status_t Camera2Client::commandPingL() {
1808 // Always ping back if access is proper and device is alive
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001809 LockedParameters::Key k(mParameters);
1810 if (k.mParameters.state != DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001811 return OK;
1812 } else {
1813 return NO_INIT;
1814 }
1815}
1816
1817status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001818 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001819 ALOGE("%s: Camera %d: Error setting video buffer count after "
1820 "recording was started", __FUNCTION__, mCameraId);
1821 return INVALID_OPERATION;
1822 }
1823
1824 // 32 is the current upper limit on the video buffer count for BufferQueue
1825 if (count > 32) {
1826 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1827 __FUNCTION__, mCameraId, count);
1828 return BAD_VALUE;
1829 }
1830
1831 // Need to reallocate memory for heap
1832 if (mRecordingHeapCount != count) {
1833 if (mRecordingHeap != 0) {
1834 mRecordingHeap.clear();
1835 mRecordingHeap = NULL;
1836 }
1837 mRecordingHeapCount = count;
1838 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001839
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001840 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001841}
1842
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001843/** Device-related methods */
1844
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001845void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1846 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1847}
1848
1849void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1850 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1851 frameNumber, timestamp);
1852}
1853
1854void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1855 ALOGV("%s: Autofocus state now %d, last trigger %d",
1856 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001857 bool sendCompletedMessage = false;
1858 bool sendMovingMessage = false;
1859
1860 bool success = false;
1861 bool afInMotion = false;
1862 {
1863 LockedParameters::Key k(mParameters);
1864 switch (k.mParameters.focusMode) {
1865 case Parameters::FOCUS_MODE_AUTO:
1866 case Parameters::FOCUS_MODE_MACRO:
1867 // Don't send notifications upstream if they're not for the current AF
1868 // trigger. For example, if cancel was called in between, or if we
1869 // already sent a notification about this AF call.
1870 if (triggerId != k.mParameters.currentAfTriggerId) break;
1871 switch (newState) {
1872 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1873 success = true;
1874 // no break
1875 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1876 sendCompletedMessage = true;
1877 k.mParameters.currentAfTriggerId = -1;
1878 break;
1879 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1880 // Just starting focusing, ignore
1881 break;
1882 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1883 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1884 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1885 default:
1886 // Unexpected in AUTO/MACRO mode
1887 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1888 __FUNCTION__, newState);
1889 break;
1890 }
1891 break;
1892 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1893 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1894 switch (newState) {
1895 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1896 success = true;
1897 // no break
1898 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1899 // Don't send notifications upstream if they're not for
1900 // the current AF trigger. For example, if cancel was
1901 // called in between, or if we already sent a
1902 // notification about this AF call.
1903 // Send both a 'AF done' callback and a 'AF move' callback
1904 if (triggerId != k.mParameters.currentAfTriggerId) break;
1905 sendCompletedMessage = true;
1906 afInMotion = false;
1907 if (k.mParameters.enableFocusMoveMessages &&
1908 k.mParameters.afInMotion) {
1909 sendMovingMessage = true;
1910 }
1911 k.mParameters.currentAfTriggerId = -1;
1912 break;
1913 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1914 // Cancel was called, or we switched state; care if
1915 // currently moving
1916 afInMotion = false;
1917 if (k.mParameters.enableFocusMoveMessages &&
1918 k.mParameters.afInMotion) {
1919 sendMovingMessage = true;
1920 }
1921 break;
1922 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1923 // Start passive scan, inform upstream
1924 afInMotion = true;
1925 // no break
1926 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1927 // Stop passive scan, inform upstream
1928 if (k.mParameters.enableFocusMoveMessages) {
1929 sendMovingMessage = true;
1930 }
1931 break;
1932 }
1933 k.mParameters.afInMotion = afInMotion;
1934 break;
1935 case Parameters::FOCUS_MODE_EDOF:
1936 case Parameters::FOCUS_MODE_INFINITY:
1937 case Parameters::FOCUS_MODE_FIXED:
1938 default:
1939 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1940 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1941 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1942 }
1943 }
1944 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001945 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001946 Mutex::Autolock iccl(mICameraClientLock);
1947 if (mCameraClient != 0) {
1948 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1949 afInMotion ? 1 : 0, 0);
1950 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001951 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001952 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001953 Mutex::Autolock iccl(mICameraClientLock);
1954 if (mCameraClient != 0) {
1955 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1956 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001957 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001958}
1959
1960void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1961 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1962 __FUNCTION__, newState, triggerId);
1963}
1964
1965void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1966 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1967 __FUNCTION__, newState, triggerId);
1968}
1969
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001970void Camera2Client::onNewFrameAvailable() {
1971 status_t res;
1972 camera_metadata_t *frame = NULL;
1973 do {
1974 res = mDevice->getNextFrame(&frame);
1975 if (res != OK) {
1976 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
1977 __FUNCTION__, mCameraId, strerror(-res), res);
1978 return;
1979 }
1980 if (frame != NULL) {
1981 camera_metadata_entry_t entry;
1982 res = find_camera_metadata_entry(frame, ANDROID_REQUEST_FRAME_COUNT,
1983 &entry);
1984 if (res != OK) {
1985 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
1986 __FUNCTION__, mCameraId, strerror(-res), res);
1987 break;
1988 }
1989
1990 res = processFrameFaceDetect(frame);
1991 if (res != OK) break;
1992
1993 free_camera_metadata(frame);
1994 }
1995 } while (frame != NULL);
1996
1997 if (frame != NULL) {
1998 free_camera_metadata(frame);
1999 }
2000 return;
2001}
2002
2003status_t Camera2Client::processFrameFaceDetect(camera_metadata_t *frame) {
2004 status_t res;
2005 camera_metadata_entry_t entry;
2006 bool enableFaceDetect;
2007 {
2008 LockedParameters::Key k(mParameters);
2009 enableFaceDetect = k.mParameters.enableFaceDetect;
2010 }
2011 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_DETECT_MODE,
2012 &entry);
Eino-Ville Talvala76dc8da2012-08-21 16:09:31 -07002013 // TODO: Remove this check once things are more compliant. For now, assume that
2014 // if we can't find the face detect mode, then it's probably not working.
2015 if (res == NAME_NOT_FOUND) {
2016 return OK;
2017 } else if (res != OK) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002018 ALOGE("%s: Camera %d: Error reading face mode: %s (%d)",
2019 __FUNCTION__, mCameraId, strerror(-res), res);
2020 return res;
2021 }
2022 uint8_t faceDetectMode = entry.data.u8[0];
2023
2024 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
2025 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_RECTANGLES,
2026 &entry);
2027 if (res != OK) {
2028 ALOGE("%s: Camera %d: Error reading face rectangles: %s (%d)",
2029 __FUNCTION__, mCameraId, strerror(-res), res);
2030 return res;
2031 }
2032 camera_frame_metadata metadata;
2033 metadata.number_of_faces = entry.count / 4;
2034 if (metadata.number_of_faces >
2035 mDeviceInfo->maxFaces) {
2036 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
2037 __FUNCTION__, mCameraId,
2038 metadata.number_of_faces, mDeviceInfo->maxFaces);
2039 return res;
2040 }
2041 int32_t *faceRects = entry.data.i32;
2042
2043 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_SCORES,
2044 &entry);
2045 if (res != OK) {
2046 ALOGE("%s: Camera %d: Error reading face scores: %s (%d)",
2047 __FUNCTION__, mCameraId, strerror(-res), res);
2048 return res;
2049 }
2050 uint8_t *faceScores = entry.data.u8;
2051
2052 int32_t *faceLandmarks = NULL;
2053 int32_t *faceIds = NULL;
2054
2055 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2056 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_LANDMARKS,
2057 &entry);
2058 if (res != OK) {
2059 ALOGE("%s: Camera %d: Error reading face landmarks: %s (%d)",
2060 __FUNCTION__, mCameraId, strerror(-res), res);
2061 return res;
2062 }
2063 faceLandmarks = entry.data.i32;
2064
2065 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_IDS,
2066 &entry);
2067 if (res != OK) {
2068 ALOGE("%s: Camera %d: Error reading face IDs: %s (%d)",
2069 __FUNCTION__, mCameraId, strerror(-res), res);
2070 return res;
2071 }
2072 faceIds = entry.data.i32;
2073 }
2074
2075 Vector<camera_face_t> faces;
2076 faces.setCapacity(metadata.number_of_faces);
2077
2078 for (int i = 0; i < metadata.number_of_faces; i++) {
2079 camera_face_t face;
2080
2081 face.rect[0] = arrayXToNormalized(faceRects[i*4 + 0]);
2082 face.rect[1] = arrayYToNormalized(faceRects[i*4 + 1]);
2083 face.rect[2] = arrayXToNormalized(faceRects[i*4 + 2]);
2084 face.rect[3] = arrayYToNormalized(faceRects[i*4 + 3]);
2085
2086 face.score = faceScores[i];
2087 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2088 face.id = faceIds[i];
2089 face.left_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 0]);
2090 face.left_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 1]);
2091 face.right_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 2]);
2092 face.right_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 3]);
2093 face.mouth[0] = arrayXToNormalized(faceLandmarks[i*6 + 4]);
2094 face.mouth[1] = arrayYToNormalized(faceLandmarks[i*6 + 5]);
2095 } else {
2096 face.id = 0;
2097 face.left_eye[0] = face.left_eye[1] = -2000;
2098 face.right_eye[0] = face.right_eye[1] = -2000;
2099 face.mouth[0] = face.mouth[1] = -2000;
2100 }
2101 faces.push_back(face);
2102 }
2103
2104 metadata.faces = faces.editArray();
2105 {
2106 Mutex::Autolock iccl(mICameraClientLock);
2107 if (mCameraClient != NULL) {
2108 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
2109 NULL, &metadata);
2110 }
2111 }
2112 }
2113 return OK;
2114}
2115
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002116void Camera2Client::onCallbackAvailable() {
2117 ATRACE_CALL();
2118 status_t res;
2119 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
2120
2121 int callbackHeapId;
2122 sp<Camera2Heap> callbackHeap;
2123 size_t heapIdx;
2124
2125 CpuConsumer::LockedBuffer imgBuffer;
2126 ALOGV("%s: Getting buffer", __FUNCTION__);
2127 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
2128 if (res != OK) {
2129 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
2130 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2131 return;
2132 }
2133
2134 {
2135 LockedParameters::Key k(mParameters);
2136
2137 if ( k.mParameters.state != PREVIEW && k.mParameters.state != RECORD
2138 && k.mParameters.state != VIDEO_SNAPSHOT) {
2139 ALOGV("%s: Camera %d: No longer streaming",
2140 __FUNCTION__, mCameraId);
2141 mCallbackConsumer->unlockBuffer(imgBuffer);
2142 return;
2143 }
2144
2145 if (! (k.mParameters.previewCallbackFlags &
2146 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
2147 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
2148 mCallbackConsumer->unlockBuffer(imgBuffer);
2149 return;
2150 }
2151 if ((k.mParameters.previewCallbackFlags &
2152 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
2153 !k.mParameters.previewCallbackOneShot) {
2154 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
2155 mCallbackConsumer->unlockBuffer(imgBuffer);
2156 return;
2157 }
2158
2159 if (imgBuffer.format != k.mParameters.previewFormat) {
2160 ALOGE("%s: Camera %d: Unexpected format for callback: "
2161 "%x, expected %x", __FUNCTION__, mCameraId,
2162 imgBuffer.format, k.mParameters.previewFormat);
2163 mCallbackConsumer->unlockBuffer(imgBuffer);
2164 return;
2165 }
2166
2167 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
2168 imgBuffer.format, imgBuffer.stride);
2169 size_t currentBufferSize = (mCallbackHeap == 0) ?
2170 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
2171 if (bufferSize != currentBufferSize) {
2172 mCallbackHeap.clear();
2173 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
2174 "Camera2Client::CallbackHeap");
2175 if (mCallbackHeap->mHeap->getSize() == 0) {
2176 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
2177 __FUNCTION__, mCameraId);
2178 mCallbackConsumer->unlockBuffer(imgBuffer);
2179 return;
2180 }
2181
2182 mCallbackHeapHead = 0;
2183 mCallbackHeapFree = kCallbackHeapCount;
2184 mCallbackHeapId++;
2185 }
2186
2187 if (mCallbackHeapFree == 0) {
2188 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
2189 __FUNCTION__, mCameraId);
2190 mCallbackConsumer->unlockBuffer(imgBuffer);
2191 return;
2192 }
2193 heapIdx = mCallbackHeapHead;
2194 callbackHeap = mCallbackHeap;
2195 callbackHeapId = mCallbackHeapId;
2196
2197 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
2198 mCallbackHeapFree--;
2199
2200 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
2201 // to app
2202
2203 ssize_t offset;
2204 size_t size;
2205 sp<IMemoryHeap> heap =
2206 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
2207 &size);
2208 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2209 memcpy(data, imgBuffer.data, bufferSize);
2210
2211 ALOGV("%s: Freeing buffer", __FUNCTION__);
2212 mCallbackConsumer->unlockBuffer(imgBuffer);
2213
2214 // In one-shot mode, stop sending callbacks after the first one
2215 if (k.mParameters.previewCallbackFlags &
2216 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
2217 ALOGV("%s: clearing oneshot", __FUNCTION__);
2218 k.mParameters.previewCallbackOneShot = false;
2219 }
2220 }
2221
2222 // Call outside parameter lock to allow re-entrancy from notification
2223 {
2224 Mutex::Autolock iccl(mICameraClientLock);
2225 if (mCameraClient != 0) {
2226 ALOGV("%s: Camera %d: Invoking client data callback",
2227 __FUNCTION__, mCameraId);
2228 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
2229 callbackHeap->mBuffers[heapIdx], NULL);
2230 }
2231 }
2232
2233 LockedParameters::Key k(mParameters);
2234 // Only increment free if we're still using the same heap
2235 if (mCallbackHeapId == callbackHeapId) {
2236 mCallbackHeapFree++;
2237 }
2238
2239 ALOGV("%s: exit", __FUNCTION__);
2240}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002241
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002242void Camera2Client::onCaptureAvailable() {
2243 ATRACE_CALL();
2244 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002245 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002246 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
2247
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002248 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002249 LockedParameters::Key k(mParameters);
2250 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002251
2252 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2253 if (res != OK) {
2254 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2255 __FUNCTION__, mCameraId, strerror(-res), res);
2256 return;
2257 }
2258
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002259 // TODO: Signal errors here upstream
2260 if (k.mParameters.state != STILL_CAPTURE &&
2261 k.mParameters.state != VIDEO_SNAPSHOT) {
2262 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2263 __FUNCTION__, mCameraId);
2264 mCaptureConsumer->unlockBuffer(imgBuffer);
2265 return;
2266 }
2267
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002268 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2269 ALOGE("%s: Camera %d: Unexpected format for still image: "
2270 "%x, expected %x", __FUNCTION__, mCameraId,
2271 imgBuffer.format,
2272 HAL_PIXEL_FORMAT_BLOB);
2273 mCaptureConsumer->unlockBuffer(imgBuffer);
2274 return;
2275 }
2276
2277 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002278 void* captureMemory = mCaptureHeap->mHeap->getBase();
2279 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002280 memcpy(captureMemory, imgBuffer.data, size);
2281
2282 mCaptureConsumer->unlockBuffer(imgBuffer);
2283
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002284 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002285 case STILL_CAPTURE:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002286 k.mParameters.state = STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002287 break;
2288 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002289 k.mParameters.state = RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002290 break;
2291 default:
2292 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002293 mCameraId, k.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002294 break;
2295 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002296
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002297 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002298 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002299 // Call outside parameter locks to allow re-entrancy from notification
2300 Mutex::Autolock iccl(mICameraClientLock);
2301 if (mCameraClient != 0) {
2302 mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
2303 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002304 }
2305}
2306
2307void Camera2Client::onRecordingFrameAvailable() {
2308 ATRACE_CALL();
2309 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002310 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002311 size_t heapIdx = 0;
2312 nsecs_t timestamp;
2313 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002314 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002315
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002316 buffer_handle_t imgBuffer;
2317 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002318 if (res != OK) {
2319 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2320 __FUNCTION__, mCameraId, strerror(-res), res);
2321 return;
2322 }
2323
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002324 mRecordingFrameCount++;
2325 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
2326
2327 // TODO: Signal errors here upstream
2328 if (k.mParameters.state != RECORD &&
2329 k.mParameters.state != VIDEO_SNAPSHOT) {
2330 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2331 "recording done",
2332 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002333 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002334 return;
2335 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002336
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002337 if (mRecordingHeap == 0) {
2338 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002339 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2340 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002341 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002342
James Dong983cf232012-08-01 16:39:55 -07002343 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002344 "Camera2Client::RecordingHeap");
2345 if (mRecordingHeap->mHeap->getSize() == 0) {
2346 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2347 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002348 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002349 return;
2350 }
2351 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002352 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002353 }
2354
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002355 if ( mRecordingHeapFree == 0) {
2356 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2357 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002358 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002359 return;
2360 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002361
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002362 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002363 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002364 mRecordingHeapFree--;
2365
2366 ALOGV("%s: Camera %d: Timestamp %lld",
2367 __FUNCTION__, mCameraId, timestamp);
2368
2369 ssize_t offset;
2370 size_t size;
2371 sp<IMemoryHeap> heap =
2372 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2373 &size);
2374
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002375 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2376 uint32_t type = kMetadataBufferTypeGrallocSource;
2377 memcpy(data, &type, 4);
2378 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
2379 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002380 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002381 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002382 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002383
2384 // Call outside locked parameters to allow re-entrancy from notification
2385 Mutex::Autolock iccl(mICameraClientLock);
2386 if (mCameraClient != 0) {
2387 mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002388 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002389 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002390 }
2391}
2392
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002393camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
2394 size_t minCount, size_t maxCount) {
2395 status_t res;
2396 camera_metadata_entry_t entry;
2397 res = find_camera_metadata_entry(mDevice->info(),
2398 tag,
2399 &entry);
2400 if (CC_UNLIKELY( res != OK )) {
2401 const char* tagSection = get_camera_metadata_section_name(tag);
2402 if (tagSection == NULL) tagSection = "<unknown>";
2403 const char* tagName = get_camera_metadata_tag_name(tag);
2404 if (tagName == NULL) tagName = "<unknown>";
2405
2406 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
2407 tagSection, tagName, tag, strerror(-res), res);
2408 entry.count = 0;
2409 entry.data.u8 = NULL;
2410 } else if (CC_UNLIKELY(
2411 (minCount != 0 && entry.count < minCount) ||
2412 (maxCount != 0 && entry.count > maxCount) ) ) {
2413 const char* tagSection = get_camera_metadata_section_name(tag);
2414 if (tagSection == NULL) tagSection = "<unknown>";
2415 const char* tagName = get_camera_metadata_tag_name(tag);
2416 if (tagName == NULL) tagName = "<unknown>";
2417 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2418 "Expected between %d and %d values, but got %d values",
2419 tagSection, tagName, tag, minCount, maxCount, entry.count);
2420 entry.count = 0;
2421 entry.data.u8 = NULL;
2422 }
2423
2424 return entry;
2425}
2426
2427/** Utility methods */
2428
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002429status_t Camera2Client::buildDeviceInfo() {
2430 if (mDeviceInfo != NULL) {
2431 delete mDeviceInfo;
2432 }
2433 DeviceInfo *deviceInfo = new DeviceInfo;
2434 mDeviceInfo = deviceInfo;
2435
2436 camera_metadata_entry_t activeArraySize =
2437 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2438 if (!activeArraySize.count) return NO_INIT;
2439 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2440 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2441
2442 camera_metadata_entry_t availableFaceDetectModes =
2443 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2444 if (!availableFaceDetectModes.count) return NO_INIT;
2445
2446 deviceInfo->bestFaceDetectMode =
2447 ANDROID_STATS_FACE_DETECTION_OFF;
2448 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2449 switch (availableFaceDetectModes.data.u8[i]) {
2450 case ANDROID_STATS_FACE_DETECTION_OFF:
2451 break;
2452 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2453 if (deviceInfo->bestFaceDetectMode !=
2454 ANDROID_STATS_FACE_DETECTION_FULL) {
2455 deviceInfo->bestFaceDetectMode =
2456 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2457 }
2458 break;
2459 case ANDROID_STATS_FACE_DETECTION_FULL:
2460 deviceInfo->bestFaceDetectMode =
2461 ANDROID_STATS_FACE_DETECTION_FULL;
2462 break;
2463 default:
2464 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2465 __FUNCTION__, mCameraId,
2466 availableFaceDetectModes.data.u8[i]);
2467 return NO_INIT;
2468 }
2469 }
2470
2471 camera_metadata_entry_t maxFacesDetected =
2472 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2473 if (!maxFacesDetected.count) return NO_INIT;
2474
2475 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2476
2477 return OK;
2478}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002479
2480status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002481 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002482 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002483
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002484 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002485 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002486
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002487 camera_metadata_entry_t availableProcessedSizes =
2488 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2489 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002490
2491 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002492 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2493 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2494 k.mParameters.videoWidth = k.mParameters.previewWidth;
2495 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002496
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002497 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2498 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002499 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2500 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002501 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002502 {
2503 String8 supportedPreviewSizes;
2504 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2505 if (i != 0) supportedPreviewSizes += ",";
2506 supportedPreviewSizes += String8::format("%dx%d",
2507 availableProcessedSizes.data.i32[i],
2508 availableProcessedSizes.data.i32[i+1]);
2509 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002510 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002511 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002512 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002513 supportedPreviewSizes);
2514 }
2515
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002516 camera_metadata_entry_t availableFpsRanges =
2517 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2518 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002519
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002520 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2521 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002522
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002523 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2524 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002525 k.mParameters.previewFpsRange[0],
2526 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002527
2528 {
2529 String8 supportedPreviewFpsRange;
2530 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2531 if (i != 0) supportedPreviewFpsRange += ",";
2532 supportedPreviewFpsRange += String8::format("(%d,%d)",
2533 availableFpsRanges.data.i32[i],
2534 availableFpsRanges.data.i32[i+1]);
2535 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002536 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002537 supportedPreviewFpsRange);
2538 }
2539
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002540 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002541 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002542 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002543
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002544 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002545 mCameraFacing == CAMERA_FACING_FRONT);
2546
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002547 camera_metadata_entry_t availableFormats =
2548 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2549
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002550 {
2551 String8 supportedPreviewFormats;
2552 bool addComma = false;
2553 for (size_t i=0; i < availableFormats.count; i++) {
2554 if (addComma) supportedPreviewFormats += ",";
2555 addComma = true;
2556 switch (availableFormats.data.i32[i]) {
2557 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002558 supportedPreviewFormats +=
2559 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002560 break;
2561 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002562 supportedPreviewFormats +=
2563 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002564 break;
2565 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002566 supportedPreviewFormats +=
2567 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002568 break;
2569 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002570 supportedPreviewFormats +=
2571 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002572 break;
2573 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002574 supportedPreviewFormats +=
2575 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002576 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002577 case HAL_PIXEL_FORMAT_RGBA_8888:
2578 supportedPreviewFormats +=
2579 CameraParameters::PIXEL_FORMAT_RGBA8888;
2580 break;
2581 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002582 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002583 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002584 addComma = false;
2585 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002586
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002587 default:
2588 ALOGW("%s: Camera %d: Unknown preview format: %x",
2589 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2590 addComma = false;
2591 break;
2592 }
2593 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002594 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002595 supportedPreviewFormats);
2596 }
2597
2598 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2599 // still have to do something sane for them
2600
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002601 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002602 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002603
2604 {
2605 String8 supportedPreviewFrameRates;
2606 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2607 if (i != 0) supportedPreviewFrameRates += ",";
2608 supportedPreviewFrameRates += String8::format("%d",
2609 availableFpsRanges.data.i32[i]);
2610 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002611 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002612 supportedPreviewFrameRates);
2613 }
2614
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002615 camera_metadata_entry_t availableJpegSizes =
2616 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2617 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002618
2619 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002620 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2621 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002622
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002623 params.setPictureSize(k.mParameters.pictureWidth,
2624 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002625
2626 {
2627 String8 supportedPictureSizes;
2628 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2629 if (i != 0) supportedPictureSizes += ",";
2630 supportedPictureSizes += String8::format("%dx%d",
2631 availableJpegSizes.data.i32[i],
2632 availableJpegSizes.data.i32[i+1]);
2633 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002634 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002635 supportedPictureSizes);
2636 }
2637
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002638 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2639 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2640 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002641
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002642 camera_metadata_entry_t availableJpegThumbnailSizes =
2643 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2644 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002645
2646 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002647 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2648 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002649
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002650 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002651 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002652 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002653 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002654
2655 {
2656 String8 supportedJpegThumbSizes;
2657 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2658 if (i != 0) supportedJpegThumbSizes += ",";
2659 supportedJpegThumbSizes += String8::format("%dx%d",
2660 availableJpegThumbnailSizes.data.i32[i],
2661 availableJpegThumbnailSizes.data.i32[i+1]);
2662 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002663 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002664 supportedJpegThumbSizes);
2665 }
2666
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002667 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002668 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002669 k.mParameters.jpegThumbQuality);
2670 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002671 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002672 k.mParameters.jpegQuality);
2673 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002674 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002675 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002676
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002677 k.mParameters.gpsEnabled = false;
2678 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002679 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002680
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002681 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002682 params.set(CameraParameters::KEY_WHITE_BALANCE,
2683 CameraParameters::WHITE_BALANCE_AUTO);
2684
2685 camera_metadata_entry_t availableWhiteBalanceModes =
2686 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002687 {
2688 String8 supportedWhiteBalance;
2689 bool addComma = false;
2690 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2691 if (addComma) supportedWhiteBalance += ",";
2692 addComma = true;
2693 switch (availableWhiteBalanceModes.data.u8[i]) {
2694 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002695 supportedWhiteBalance +=
2696 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002697 break;
2698 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002699 supportedWhiteBalance +=
2700 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002701 break;
2702 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002703 supportedWhiteBalance +=
2704 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002705 break;
2706 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002707 supportedWhiteBalance +=
2708 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002709 break;
2710 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002711 supportedWhiteBalance +=
2712 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002713 break;
2714 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002715 supportedWhiteBalance +=
2716 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002717 break;
2718 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002719 supportedWhiteBalance +=
2720 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002721 break;
2722 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002723 supportedWhiteBalance +=
2724 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002725 break;
2726 // Skipping values not mappable to v1 API
2727 case ANDROID_CONTROL_AWB_OFF:
2728 addComma = false;
2729 break;
2730 default:
2731 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2732 __FUNCTION__, mCameraId,
2733 availableWhiteBalanceModes.data.u8[i]);
2734 addComma = false;
2735 break;
2736 }
2737 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002738 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002739 supportedWhiteBalance);
2740 }
2741
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002742 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002743 params.set(CameraParameters::KEY_EFFECT,
2744 CameraParameters::EFFECT_NONE);
2745
2746 camera_metadata_entry_t availableEffects =
2747 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2748 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002749 {
2750 String8 supportedEffects;
2751 bool addComma = false;
2752 for (size_t i=0; i < availableEffects.count; i++) {
2753 if (addComma) supportedEffects += ",";
2754 addComma = true;
2755 switch (availableEffects.data.u8[i]) {
2756 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002757 supportedEffects +=
2758 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002759 break;
2760 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002761 supportedEffects +=
2762 CameraParameters::EFFECT_MONO;
2763 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002764 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002765 supportedEffects +=
2766 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002767 break;
2768 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002769 supportedEffects +=
2770 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002771 break;
2772 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002773 supportedEffects +=
2774 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002775 break;
2776 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002777 supportedEffects +=
2778 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002779 break;
2780 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002781 supportedEffects +=
2782 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002783 break;
2784 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002785 supportedEffects +=
2786 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002787 break;
2788 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002789 supportedEffects +=
2790 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002791 break;
2792 default:
2793 ALOGW("%s: Camera %d: Unknown effect value: %d",
2794 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2795 addComma = false;
2796 break;
2797 }
2798 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002799 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002800 }
2801
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002802 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002803 params.set(CameraParameters::KEY_ANTIBANDING,
2804 CameraParameters::ANTIBANDING_AUTO);
2805
2806 camera_metadata_entry_t availableAntibandingModes =
2807 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2808 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002809 {
2810 String8 supportedAntibanding;
2811 bool addComma = false;
2812 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2813 if (addComma) supportedAntibanding += ",";
2814 addComma = true;
2815 switch (availableAntibandingModes.data.u8[i]) {
2816 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002817 supportedAntibanding +=
2818 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002819 break;
2820 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002821 supportedAntibanding +=
2822 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002823 break;
2824 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002825 supportedAntibanding +=
2826 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002827 break;
2828 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002829 supportedAntibanding +=
2830 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002831 break;
2832 default:
2833 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2834 __FUNCTION__, mCameraId,
2835 availableAntibandingModes.data.u8[i]);
2836 addComma = false;
2837 break;
2838 }
2839 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002840 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002841 supportedAntibanding);
2842 }
2843
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002844 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002845 params.set(CameraParameters::KEY_SCENE_MODE,
2846 CameraParameters::SCENE_MODE_AUTO);
2847
2848 camera_metadata_entry_t availableSceneModes =
2849 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2850 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002851 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002852 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002853 bool addComma = true;
2854 bool noSceneModes = false;
2855 for (size_t i=0; i < availableSceneModes.count; i++) {
2856 if (addComma) supportedSceneModes += ",";
2857 addComma = true;
2858 switch (availableSceneModes.data.u8[i]) {
2859 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2860 noSceneModes = true;
2861 break;
2862 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2863 // Not in old API
2864 addComma = false;
2865 break;
2866 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002867 supportedSceneModes +=
2868 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002869 break;
2870 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002871 supportedSceneModes +=
2872 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002873 break;
2874 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002875 supportedSceneModes +=
2876 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002877 break;
2878 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002879 supportedSceneModes +=
2880 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002881 break;
2882 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002883 supportedSceneModes +=
2884 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002885 break;
2886 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002887 supportedSceneModes +=
2888 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002889 break;
2890 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002891 supportedSceneModes +=
2892 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002893 break;
2894 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002895 supportedSceneModes +=
2896 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002897 break;
2898 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002899 supportedSceneModes +=
2900 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002901 break;
2902 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002903 supportedSceneModes +=
2904 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002905 break;
2906 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002907 supportedSceneModes +=
2908 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002909 break;
2910 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002911 supportedSceneModes +=
2912 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002913 break;
2914 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002915 supportedSceneModes +=
2916 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002917 break;
2918 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002919 supportedSceneModes +=
2920 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002921 break;
2922 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002923 supportedSceneModes +=
2924 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002925 break;
2926 default:
2927 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002928 __FUNCTION__, mCameraId,
2929 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002930 addComma = false;
2931 break;
2932 }
2933 }
2934 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002935 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002936 supportedSceneModes);
2937 }
2938 }
2939
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002940 camera_metadata_entry_t flashAvailable =
2941 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2942 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002943
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002944 camera_metadata_entry_t availableAeModes =
2945 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2946 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002947
2948 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002949 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002950 params.set(CameraParameters::KEY_FLASH_MODE,
2951 CameraParameters::FLASH_MODE_AUTO);
2952
2953 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2954 supportedFlashModes = supportedFlashModes +
2955 "," + CameraParameters::FLASH_MODE_AUTO +
2956 "," + CameraParameters::FLASH_MODE_ON +
2957 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002958 for (size_t i=0; i < availableAeModes.count; i++) {
2959 if (availableAeModes.data.u8[i] ==
2960 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002961 supportedFlashModes = supportedFlashModes + "," +
2962 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002963 break;
2964 }
2965 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002966 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002967 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002968 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002969 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002970 params.set(CameraParameters::KEY_FLASH_MODE,
2971 CameraParameters::FLASH_MODE_OFF);
2972 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2973 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002974 }
2975
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002976 camera_metadata_entry_t minFocusDistance =
2977 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2978 if (!minFocusDistance.count) return NO_INIT;
2979
2980 camera_metadata_entry_t availableAfModes =
2981 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2982 if (!availableAfModes.count) return NO_INIT;
2983
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002984 if (minFocusDistance.data.f[0] == 0) {
2985 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002986 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002987 params.set(CameraParameters::KEY_FOCUS_MODE,
2988 CameraParameters::FOCUS_MODE_FIXED);
2989 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2990 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002991 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002992 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002993 params.set(CameraParameters::KEY_FOCUS_MODE,
2994 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002995 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002996 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002997
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002998 for (size_t i=0; i < availableAfModes.count; i++) {
2999 if (addComma) supportedFocusModes += ",";
3000 addComma = true;
3001 switch (availableAfModes.data.u8[i]) {
3002 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003003 supportedFocusModes +=
3004 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003005 break;
3006 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003007 supportedFocusModes +=
3008 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003009 break;
3010 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003011 supportedFocusModes +=
3012 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003013 break;
3014 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003015 supportedFocusModes +=
3016 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003017 break;
3018 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003019 supportedFocusModes +=
3020 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003021 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003022 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003023 case ANDROID_CONTROL_AF_OFF:
3024 addComma = false;
3025 break;
3026 default:
3027 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
3028 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
3029 addComma = false;
3030 break;
3031 }
3032 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003033 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003034 supportedFocusModes);
3035 }
3036
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003037 camera_metadata_entry_t max3aRegions =
3038 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
3039 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003040
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003041 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003042 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003043 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003044 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003045 k.mParameters.focusingAreas.clear();
3046 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003047
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003048 camera_metadata_entry_t availableFocalLengths =
3049 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
3050 if (!availableFocalLengths.count) return NO_INIT;
3051
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003052 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003053 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003054
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003055 camera_metadata_entry_t sensorSize =
3056 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
3057 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003058
3059 // The fields of view here assume infinity focus, maximum wide angle
3060 float horizFov = 180 / M_PI *
3061 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
3062 float vertFov = 180 / M_PI *
3063 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003064 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
3065 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003066
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003067 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003068 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003069 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003070
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003071 camera_metadata_entry_t exposureCompensationRange =
3072 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
3073 if (!exposureCompensationRange.count) return NO_INIT;
3074
3075 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003076 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003077 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003078 exposureCompensationRange.data.i32[0]);
3079
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003080 camera_metadata_entry_t exposureCompensationStep =
3081 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
3082 if (!exposureCompensationStep.count) return NO_INIT;
3083
3084 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07003085 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003086 exposureCompensationStep.data.r[0].denominator);
3087
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003088 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003089 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
3090 CameraParameters::FALSE);
3091 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
3092 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003093
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003094 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003095 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
3096 CameraParameters::FALSE);
3097 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
3098 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003099
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003100 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003101 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003102 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003103 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003104 "(0,0,0,0,0)");
3105
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003106 k.mParameters.zoom = 0;
3107 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003108 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003109
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003110 camera_metadata_entry_t maxDigitalZoom =
3111 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
3112 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003113
3114 {
3115 String8 zoomRatios;
3116 float zoom = 1.f;
3117 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003118 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003119 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003120 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003121 if (addComma) zoomRatios += ",";
3122 addComma = true;
3123 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
3124 zoom += zoomIncrement;
3125 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003126 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003127 }
3128
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003129 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
3130 CameraParameters::TRUE);
3131 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
3132 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003133
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003134 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003135 "Infinity,Infinity,Infinity");
3136
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003137 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003138 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003139 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003140 0);
3141
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003142 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003143 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003144
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003145 params.set(CameraParameters::KEY_RECORDING_HINT,
3146 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003147
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003148 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
3149 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003150
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003151 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
3152 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003153
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003154 camera_metadata_entry_t availableVideoStabilizationModes =
3155 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
3156 if (!availableVideoStabilizationModes.count) return NO_INIT;
3157
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003158 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003159 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3160 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003161 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003162 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3163 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003164 }
3165
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003166 // Set up initial state for non-Camera.Parameters state variables
3167
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003168 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003169 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003170 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003171
3172 k.mParameters.enableFocusMoveMessages = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003173 k.mParameters.afTriggerCounter = 0;
3174 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003175
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003176 k.mParameters.previewCallbackFlags = 0;
3177
3178 k.mParameters.state = STOPPED;
3179
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003180 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003181
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003182 return OK;
3183}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003184
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003185status_t Camera2Client::updateRequests(const Parameters &params) {
3186 status_t res;
3187
3188 res = updatePreviewRequest(params);
3189 if (res != OK) {
3190 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
3191 __FUNCTION__, mCameraId, strerror(-res), res);
3192 return res;
3193 }
3194 res = updateCaptureRequest(params);
3195 if (res != OK) {
3196 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
3197 __FUNCTION__, mCameraId, strerror(-res), res);
3198 return res;
3199 }
3200
3201 res = updateRecordingRequest(params);
3202 if (res != OK) {
3203 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
3204 __FUNCTION__, mCameraId, strerror(-res), res);
3205 return res;
3206 }
3207
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003208 if (params.state == PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003209 res = mDevice->setStreamingRequest(mPreviewRequest);
3210 if (res != OK) {
3211 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
3212 __FUNCTION__, mCameraId, strerror(-res), res);
3213 return res;
3214 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003215 } else if (params.state == RECORD || params.state == VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003216 res = mDevice->setStreamingRequest(mRecordingRequest);
3217 if (res != OK) {
3218 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
3219 __FUNCTION__, mCameraId, strerror(-res), res);
3220 return res;
3221 }
3222 }
3223 return res;
3224}
3225
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003226status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003227 ATRACE_CALL();
3228 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003229
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003230 if (mPreviewStreamId != NO_STREAM) {
3231 // Check if stream parameters have to change
3232 uint32_t currentWidth, currentHeight;
3233 res = mDevice->getStreamInfo(mPreviewStreamId,
3234 &currentWidth, &currentHeight, 0);
3235 if (res != OK) {
3236 ALOGE("%s: Camera %d: Error querying preview stream info: "
3237 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3238 return res;
3239 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003240 if (currentWidth != (uint32_t)params.previewWidth ||
3241 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07003242 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
3243 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003244 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003245 res = mDevice->waitUntilDrained();
3246 if (res != OK) {
3247 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
3248 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3249 return res;
3250 }
3251 res = mDevice->deleteStream(mPreviewStreamId);
3252 if (res != OK) {
3253 ALOGE("%s: Camera %d: Unable to delete old output stream "
3254 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3255 strerror(-res), res);
3256 return res;
3257 }
3258 mPreviewStreamId = NO_STREAM;
3259 }
3260 }
3261
3262 if (mPreviewStreamId == NO_STREAM) {
3263 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003264 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003265 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3266 &mPreviewStreamId);
3267 if (res != OK) {
3268 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3269 __FUNCTION__, mCameraId, strerror(-res), res);
3270 return res;
3271 }
3272 }
3273
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003274 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003275 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003276 if (res != OK) {
3277 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3278 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3279 return res;
3280 }
3281
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003282 return OK;
3283}
3284
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003285status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003286 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003287 status_t res;
3288 if (mPreviewRequest == NULL) {
3289 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3290 &mPreviewRequest);
3291 if (res != OK) {
3292 ALOGE("%s: Camera %d: Unable to create default preview request: "
3293 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3294 return res;
3295 }
3296 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003297
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003298 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003299 if (res != OK) {
3300 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3301 "request: %s (%d)", __FUNCTION__, mCameraId,
3302 strerror(-res), res);
3303 return res;
3304 }
3305
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003306 return OK;
3307}
3308
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003309status_t Camera2Client::updateCallbackStream(const Parameters &params) {
3310 status_t res;
3311
3312 if (mCallbackConsumer == 0) {
3313 // Create CPU buffer queue endpoint
3314 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
3315 mCallbackWaiter = new CallbackWaiter(this);
3316 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
3317 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
3318 mCallbackWindow = new SurfaceTextureClient(
3319 mCallbackConsumer->getProducerInterface());
3320 }
3321
3322 if (mCallbackStreamId != NO_STREAM) {
3323 // Check if stream parameters have to change
3324 uint32_t currentWidth, currentHeight, currentFormat;
3325 res = mDevice->getStreamInfo(mCallbackStreamId,
3326 &currentWidth, &currentHeight, &currentFormat);
3327 if (res != OK) {
3328 ALOGE("%s: Camera %d: Error querying callback output stream info: "
3329 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3330 return res;
3331 }
3332 if (currentWidth != (uint32_t)params.previewWidth ||
3333 currentHeight != (uint32_t)params.previewHeight ||
3334 currentFormat != (uint32_t)params.previewFormat) {
3335 // Since size should only change while preview is not running,
3336 // assuming that all existing use of old callback stream is
3337 // completed.
3338 res = mDevice->deleteStream(mCallbackStreamId);
3339 if (res != OK) {
3340 ALOGE("%s: Camera %d: Unable to delete old output stream "
3341 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
3342 strerror(-res), res);
3343 return res;
3344 }
3345 mCallbackStreamId = NO_STREAM;
3346 }
3347 }
3348
3349 if (mCallbackStreamId == NO_STREAM) {
3350 ALOGV("Creating callback stream: %d %d format 0x%x",
3351 params.previewWidth, params.previewHeight,
3352 params.previewFormat);
3353 res = mDevice->createStream(mCallbackWindow,
3354 params.previewWidth, params.previewHeight,
3355 params.previewFormat, 0, &mCallbackStreamId);
3356 if (res != OK) {
3357 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
3358 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3359 return res;
3360 }
3361 }
3362
3363 return OK;
3364}
3365
3366
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003367status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003368 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003369 status_t res;
3370 // Find out buffer size for JPEG
3371 camera_metadata_entry_t maxJpegSize =
3372 staticInfo(ANDROID_JPEG_MAX_SIZE);
3373 if (maxJpegSize.count == 0) {
3374 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3375 __FUNCTION__, mCameraId);
3376 return INVALID_OPERATION;
3377 }
3378
3379 if (mCaptureConsumer == 0) {
3380 // Create CPU buffer queue endpoint
3381 mCaptureConsumer = new CpuConsumer(1);
3382 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3383 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3384 mCaptureWindow = new SurfaceTextureClient(
3385 mCaptureConsumer->getProducerInterface());
3386 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003387 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3388 "Camera2Client::CaptureHeap");
3389 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003390 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3391 __FUNCTION__, mCameraId);
3392 return NO_MEMORY;
3393 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003394 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003395
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003396 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003397 // Check if stream parameters have to change
3398 uint32_t currentWidth, currentHeight;
3399 res = mDevice->getStreamInfo(mCaptureStreamId,
3400 &currentWidth, &currentHeight, 0);
3401 if (res != OK) {
3402 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3403 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3404 return res;
3405 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003406 if (currentWidth != (uint32_t)params.pictureWidth ||
3407 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003408 res = mDevice->deleteStream(mCaptureStreamId);
3409 if (res != OK) {
3410 ALOGE("%s: Camera %d: Unable to delete old output stream "
3411 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3412 strerror(-res), res);
3413 return res;
3414 }
3415 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003416 }
3417 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003418
3419 if (mCaptureStreamId == NO_STREAM) {
3420 // Create stream for HAL production
3421 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003422 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003423 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3424 &mCaptureStreamId);
3425 if (res != OK) {
3426 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3427 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3428 return res;
3429 }
3430
3431 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003432 return OK;
3433}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003434
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003435status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003436 ATRACE_CALL();
3437 status_t res;
3438 if (mCaptureRequest == NULL) {
3439 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3440 &mCaptureRequest);
3441 if (res != OK) {
3442 ALOGE("%s: Camera %d: Unable to create default still image request:"
3443 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3444 return res;
3445 }
3446 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003447
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003448 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003449 if (res != OK) {
3450 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3451 "request: %s (%d)", __FUNCTION__, mCameraId,
3452 strerror(-res), res);
3453 return res;
3454 }
3455
3456 res = updateEntry(mCaptureRequest,
3457 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003458 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003459 if (res != OK) return res;
3460 res = updateEntry(mCaptureRequest,
3461 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003462 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003463 if (res != OK) return res;
3464 res = updateEntry(mCaptureRequest,
3465 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003466 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003467 if (res != OK) return res;
3468 res = updateEntry(mCaptureRequest,
3469 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003470 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003471 if (res != OK) return res;
3472
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003473 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003474 res = updateEntry(mCaptureRequest,
3475 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003476 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003477 if (res != OK) return res;
3478 res = updateEntry(mCaptureRequest,
3479 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003480 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003481 if (res != OK) return res;
3482 res = updateEntry(mCaptureRequest,
3483 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003484 params.gpsProcessingMethod.string(),
3485 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003486 if (res != OK) return res;
3487 } else {
3488 res = deleteEntry(mCaptureRequest,
3489 ANDROID_JPEG_GPS_COORDINATES);
3490 if (res != OK) return res;
3491 res = deleteEntry(mCaptureRequest,
3492 ANDROID_JPEG_GPS_TIMESTAMP);
3493 if (res != OK) return res;
3494 res = deleteEntry(mCaptureRequest,
3495 ANDROID_JPEG_GPS_PROCESSING_METHOD);
3496 if (res != OK) return res;
3497 }
3498
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003499 return OK;
3500}
3501
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003502status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003503 ATRACE_CALL();
3504 status_t res;
3505 if (mRecordingRequest == NULL) {
3506 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3507 &mRecordingRequest);
3508 if (res != OK) {
3509 ALOGE("%s: Camera %d: Unable to create default recording request:"
3510 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3511 return res;
3512 }
3513 }
3514
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003515 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003516 if (res != OK) {
3517 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3518 "request: %s (%d)", __FUNCTION__, mCameraId,
3519 strerror(-res), res);
3520 return res;
3521 }
3522
3523 return OK;
3524}
3525
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003526status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003527 status_t res;
3528
3529 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003530 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
3531 // always acquire and free a buffer when the heap is full; otherwise the consumer
3532 // will have buffers in flight we'll never clear out.
3533 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount + 1);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003534 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3535 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3536 mRecordingWindow = new SurfaceTextureClient(
3537 mRecordingConsumer->getProducerInterface());
3538 // Allocate memory later, since we don't know buffer size until receipt
3539 }
3540
3541 if (mRecordingStreamId != NO_STREAM) {
3542 // Check if stream parameters have to change
3543 uint32_t currentWidth, currentHeight;
3544 res = mDevice->getStreamInfo(mRecordingStreamId,
3545 &currentWidth, &currentHeight, 0);
3546 if (res != OK) {
3547 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3548 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3549 return res;
3550 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003551 if (currentWidth != (uint32_t)params.videoWidth ||
3552 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003553 // TODO: Should wait to be sure previous recording has finished
3554 res = mDevice->deleteStream(mRecordingStreamId);
3555 if (res != OK) {
3556 ALOGE("%s: Camera %d: Unable to delete old output stream "
3557 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3558 strerror(-res), res);
3559 return res;
3560 }
3561 mRecordingStreamId = NO_STREAM;
3562 }
3563 }
3564
3565 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003566 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003567 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003568 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003569 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003570 if (res != OK) {
3571 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3572 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3573 return res;
3574 }
3575 }
3576
3577 return OK;
3578}
3579
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003580status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
3581 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003582 ATRACE_CALL();
3583 status_t res;
3584 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003585 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003586 if (res != OK) return res;
3587
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003588 uint8_t wbMode = params.autoWhiteBalanceLock ?
3589 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003590 res = updateEntry(request,
3591 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3592 if (res != OK) return res;
3593 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003594 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003595 if (res != OK) return res;
3596 res = updateEntry(request,
3597 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003598 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003599 if (res != OK) return res;
3600
3601 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003602 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003603 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3604 res = updateEntry(request,
3605 ANDROID_CONTROL_MODE, &controlMode, 1);
3606 if (res != OK) return res;
3607 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3608 res = updateEntry(request,
3609 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003610 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003611 if (res != OK) return res;
3612 }
3613
3614 uint8_t flashMode = ANDROID_FLASH_OFF;
3615 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003616 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003617 case Parameters::FLASH_MODE_OFF:
3618 aeMode = ANDROID_CONTROL_AE_ON; break;
3619 case Parameters::FLASH_MODE_AUTO:
3620 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3621 case Parameters::FLASH_MODE_ON:
3622 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3623 case Parameters::FLASH_MODE_TORCH:
3624 aeMode = ANDROID_CONTROL_AE_ON;
3625 flashMode = ANDROID_FLASH_TORCH;
3626 break;
3627 case Parameters::FLASH_MODE_RED_EYE:
3628 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3629 default:
3630 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003631 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003632 return BAD_VALUE;
3633 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003634 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003635
3636 res = updateEntry(request,
3637 ANDROID_FLASH_MODE, &flashMode, 1);
3638 if (res != OK) return res;
3639 res = updateEntry(request,
3640 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3641 if (res != OK) return res;
3642
3643 float focusDistance = 0; // infinity focus in diopters
3644 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003645 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003646 case Parameters::FOCUS_MODE_AUTO:
3647 case Parameters::FOCUS_MODE_MACRO:
3648 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3649 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3650 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003651 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003652 break;
3653 case Parameters::FOCUS_MODE_INFINITY:
3654 case Parameters::FOCUS_MODE_FIXED:
3655 focusMode = ANDROID_CONTROL_AF_OFF;
3656 break;
3657 default:
3658 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003659 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003660 return BAD_VALUE;
3661 }
3662 res = updateEntry(request,
3663 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3664 if (res != OK) return res;
3665 res = updateEntry(request,
3666 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3667 if (res != OK) return res;
3668
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003669 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003670 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3671 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003672 focusingAreas[i + 0] = params.focusingAreas[i].left;
3673 focusingAreas[i + 1] = params.focusingAreas[i].top;
3674 focusingAreas[i + 2] = params.focusingAreas[i].right;
3675 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3676 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003677 }
3678 res = updateEntry(request,
3679 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3680 if (res != OK) return res;
3681 delete[] focusingAreas;
3682
3683 res = updateEntry(request,
3684 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003685 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003686 if (res != OK) return res;
3687
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003688 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003689 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3690 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003691 meteringAreas[i + 0] = params.meteringAreas[i].left;
3692 meteringAreas[i + 1] = params.meteringAreas[i].top;
3693 meteringAreas[i + 2] = params.meteringAreas[i].right;
3694 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3695 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003696 }
3697 res = updateEntry(request,
3698 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3699 if (res != OK) return res;
3700
3701 res = updateEntry(request,
3702 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3703 if (res != OK) return res;
3704 delete[] meteringAreas;
3705
3706 // Need to convert zoom index into a crop rectangle. The rectangle is
3707 // chosen to maximize its area on the sensor
3708
3709 camera_metadata_entry_t maxDigitalZoom =
3710 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3711 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3712 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003713 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003714
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003715 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003716 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003717 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003718 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003719 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003720 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003721 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003722 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003723 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003724 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003725 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3726 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003727
3728 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3729 res = updateEntry(request,
3730 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3731 if (res != OK) return res;
3732
3733 // TODO: Decide how to map recordingHint, or whether just to ignore it
3734
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003735 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003736 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3737 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3738 res = updateEntry(request,
3739 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3740 &vstabMode, 1);
3741 if (res != OK) return res;
3742
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003743 uint8_t faceDetectMode = params.enableFaceDetect ?
3744 mDeviceInfo->bestFaceDetectMode :
3745 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
3746 res = updateEntry(request,
3747 ANDROID_STATS_FACE_DETECT_MODE,
3748 &faceDetectMode, 1);
3749 if (res != OK) return res;
3750
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003751 return OK;
3752}
3753
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003754int Camera2Client::arrayXToNormalized(int width) const {
3755 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3756}
3757
3758int Camera2Client::arrayYToNormalized(int height) const {
3759 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3760}
3761
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003762status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3763 uint32_t tag, const void *data, size_t data_count) {
3764 camera_metadata_entry_t entry;
3765 status_t res;
3766 res = find_camera_metadata_entry(buffer, tag, &entry);
3767 if (res == NAME_NOT_FOUND) {
3768 res = add_camera_metadata_entry(buffer,
3769 tag, data, data_count);
3770 } else if (res == OK) {
3771 res = update_camera_metadata_entry(buffer,
3772 entry.index, data, data_count, NULL);
3773 }
3774
3775 if (res != OK) {
3776 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3777 __FUNCTION__, get_camera_metadata_section_name(tag),
3778 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3779 }
3780 return res;
3781}
3782
3783status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3784 camera_metadata_entry_t entry;
3785 status_t res;
3786 res = find_camera_metadata_entry(buffer, tag, &entry);
3787 if (res == NAME_NOT_FOUND) {
3788 return OK;
3789 } else if (res != OK) {
3790 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3791 __FUNCTION__,
3792 get_camera_metadata_section_name(tag),
3793 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3794 return res;
3795 }
3796 res = delete_camera_metadata_entry(buffer, entry.index);
3797 if (res != OK) {
3798 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3799 __FUNCTION__,
3800 get_camera_metadata_section_name(tag),
3801 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3802 }
3803 return res;
3804}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003805
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003806int Camera2Client::formatStringToEnum(const char *format) {
3807 return
3808 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3809 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3810 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3811 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3812 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3813 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3814 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3815 HAL_PIXEL_FORMAT_YV12 : // YV12
3816 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3817 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3818 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3819 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3820 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3821 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3822 -1;
3823}
3824
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003825const char* Camera2Client::formatEnumToString(int format) {
3826 const char *fmt;
3827 switch(format) {
3828 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3829 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3830 break;
3831 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3832 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3833 break;
3834 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3835 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3836 break;
3837 case HAL_PIXEL_FORMAT_YV12: // YV12
3838 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3839 break;
3840 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3841 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3842 break;
3843 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3844 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3845 break;
3846 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3847 ALOGW("Raw sensor preview format requested.");
3848 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3849 break;
3850 default:
3851 ALOGE("%s: Unknown preview format: %x",
3852 __FUNCTION__, format);
3853 fmt = NULL;
3854 break;
3855 }
3856 return fmt;
3857}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003858
3859int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3860 return
3861 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3862 ANDROID_CONTROL_AWB_AUTO :
3863 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3864 ANDROID_CONTROL_AWB_INCANDESCENT :
3865 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3866 ANDROID_CONTROL_AWB_FLUORESCENT :
3867 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3868 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3869 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3870 ANDROID_CONTROL_AWB_DAYLIGHT :
3871 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3872 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3873 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3874 ANDROID_CONTROL_AWB_TWILIGHT :
3875 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3876 ANDROID_CONTROL_AWB_SHADE :
3877 -1;
3878}
3879
3880int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3881 return
3882 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3883 ANDROID_CONTROL_EFFECT_OFF :
3884 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3885 ANDROID_CONTROL_EFFECT_MONO :
3886 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3887 ANDROID_CONTROL_EFFECT_NEGATIVE :
3888 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3889 ANDROID_CONTROL_EFFECT_SOLARIZE :
3890 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3891 ANDROID_CONTROL_EFFECT_SEPIA :
3892 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3893 ANDROID_CONTROL_EFFECT_POSTERIZE :
3894 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3895 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3896 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3897 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3898 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3899 ANDROID_CONTROL_EFFECT_AQUA :
3900 -1;
3901}
3902
3903int Camera2Client::abModeStringToEnum(const char *abMode) {
3904 return
3905 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3906 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3907 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3908 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3909 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3910 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3911 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3912 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3913 -1;
3914}
3915
3916int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3917 return
3918 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3919 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3920 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3921 ANDROID_CONTROL_SCENE_MODE_ACTION :
3922 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3923 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3924 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3925 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3926 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3927 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3928 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3929 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3930 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3931 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3932 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3933 ANDROID_CONTROL_SCENE_MODE_BEACH :
3934 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3935 ANDROID_CONTROL_SCENE_MODE_SNOW :
3936 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3937 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3938 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3939 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3940 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3941 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3942 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3943 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3944 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3945 ANDROID_CONTROL_SCENE_MODE_PARTY :
3946 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3947 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3948 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3949 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3950 -1;
3951}
3952
3953Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3954 const char *flashMode) {
3955 return
3956 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3957 Parameters::FLASH_MODE_OFF :
3958 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3959 Parameters::FLASH_MODE_AUTO :
3960 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3961 Parameters::FLASH_MODE_ON :
3962 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3963 Parameters::FLASH_MODE_RED_EYE :
3964 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3965 Parameters::FLASH_MODE_TORCH :
3966 Parameters::FLASH_MODE_INVALID;
3967}
3968
3969Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3970 const char *focusMode) {
3971 return
3972 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3973 Parameters::FOCUS_MODE_AUTO :
3974 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3975 Parameters::FOCUS_MODE_INFINITY :
3976 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3977 Parameters::FOCUS_MODE_MACRO :
3978 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3979 Parameters::FOCUS_MODE_FIXED :
3980 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3981 Parameters::FOCUS_MODE_EDOF :
3982 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3983 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3984 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3985 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3986 Parameters::FOCUS_MODE_INVALID;
3987}
3988
3989status_t Camera2Client::parseAreas(const char *areasCStr,
3990 Vector<Parameters::Area> *areas) {
3991 static const size_t NUM_FIELDS = 5;
3992 areas->clear();
3993 if (areasCStr == NULL) {
3994 // If no key exists, use default (0,0,0,0,0)
3995 areas->push();
3996 return OK;
3997 }
3998 String8 areasStr(areasCStr);
3999 ssize_t areaStart = areasStr.find("(", 0) + 1;
4000 while (areaStart != 0) {
4001 const char* area = areasStr.string() + areaStart;
4002 char *numEnd;
4003 int vals[NUM_FIELDS];
4004 for (size_t i = 0; i < NUM_FIELDS; i++) {
4005 errno = 0;
4006 vals[i] = strtol(area, &numEnd, 10);
4007 if (errno || numEnd == area) return BAD_VALUE;
4008 area = numEnd + 1;
4009 }
4010 areas->push(Parameters::Area(
4011 vals[0], vals[1], vals[2], vals[3], vals[4]) );
4012 areaStart = areasStr.find("(", areaStart) + 1;
4013 }
4014 return OK;
4015}
4016
4017status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
4018 size_t maxRegions) {
4019 // Definition of valid area can be found in
4020 // include/camera/CameraParameters.h
4021 if (areas.size() == 0) return BAD_VALUE;
4022 if (areas.size() == 1) {
4023 if (areas[0].left == 0 &&
4024 areas[0].top == 0 &&
4025 areas[0].right == 0 &&
4026 areas[0].bottom == 0 &&
4027 areas[0].weight == 0) {
4028 // Single (0,0,0,0,0) entry is always valid (== driver decides)
4029 return OK;
4030 }
4031 }
4032 if (areas.size() > maxRegions) {
4033 ALOGE("%s: Too many areas requested: %d",
4034 __FUNCTION__, areas.size());
4035 return BAD_VALUE;
4036 }
4037
4038 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
4039 a != areas.end(); a++) {
4040 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
4041 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
4042 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
4043 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
4044 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
4045 if (a->left >= a->right) return BAD_VALUE;
4046 if (a->top >= a->bottom) return BAD_VALUE;
4047 }
4048 return OK;
4049}
4050
4051bool Camera2Client::boolFromString(const char *boolStr) {
4052 return !boolStr ? false :
4053 !strcmp(boolStr, CameraParameters::TRUE) ? true :
4054 false;
4055}
4056
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07004057int Camera2Client::degToTransform(int degrees, bool mirror) {
4058 if (!mirror) {
4059 if (degrees == 0) return 0;
4060 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
4061 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
4062 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
4063 } else { // Do mirror (horizontal flip)
4064 if (degrees == 0) { // FLIP_H and ROT_0
4065 return HAL_TRANSFORM_FLIP_H;
4066 } else if (degrees == 90) { // FLIP_H and ROT_90
4067 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
4068 } else if (degrees == 180) { // FLIP_H and ROT_180
4069 return HAL_TRANSFORM_FLIP_V;
4070 } else if (degrees == 270) { // FLIP_H and ROT_270
4071 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
4072 }
4073 }
4074 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
4075 return -1;
4076}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07004077
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07004078size_t Camera2Client::calculateBufferSize(int width, int height,
4079 int format, int stride) {
4080 switch (format) {
4081 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
4082 return width * height * 2;
4083 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
4084 return width * height * 3 / 2;
4085 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
4086 return width * height * 2;
4087 case HAL_PIXEL_FORMAT_YV12: { // YV12
4088 size_t ySize = stride * height;
4089 size_t uvStride = (stride / 2 + 0xF) & ~0x10;
4090 size_t uvSize = uvStride * height / 2;
4091 return ySize + uvSize * 2;
4092 }
4093 case HAL_PIXEL_FORMAT_RGB_565:
4094 return width * height * 2;
4095 case HAL_PIXEL_FORMAT_RGBA_8888:
4096 return width * height * 4;
4097 case HAL_PIXEL_FORMAT_RAW_SENSOR:
4098 return width * height * 2;
4099 default:
4100 ALOGE("%s: Unknown preview format: %x",
4101 __FUNCTION__, format);
4102 return 0;
4103 }
4104}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07004105
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07004106} // namespace android