blob: c06f6ba41be26e9dc19780dea98548705e691430 [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),
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070057 mCallbackStreamId(NO_STREAM),
58 mCallbackHeapId(0),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070059 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070060 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070066
67 LockedParameters::Key k(mParameters);
68 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070069}
70
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070071status_t Camera2Client::checkPid(const char* checkLocation) const {
72 int callingPid = getCallingPid();
73 if (callingPid == mClientPid) return NO_ERROR;
74
75 ALOGE("%s: attempt to use a locked camera from a different process"
76 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
77 return PERMISSION_DENIED;
78}
79
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070080status_t Camera2Client::initialize(camera_module_t *module)
81{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070082 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070083 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070084 status_t res;
85
86 res = mDevice->initialize(module);
87 if (res != OK) {
88 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
89 __FUNCTION__, mCameraId, strerror(-res), res);
90 return NO_INIT;
91 }
92
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070093 res = mDevice->setNotifyCallback(this);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070094 res = mDevice->setFrameListener(this);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070095
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070096 res = buildDeviceInfo();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 res = buildDefaultParameters();
98 if (res != OK) {
99 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
100 __FUNCTION__, mCameraId, strerror(-res), res);
101 return NO_INIT;
102 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700103
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700105 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700106 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
107 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700108 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109 }
110
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700111 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700112}
113
114Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700115 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700116 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
117
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700118 mDestructionStarted = true;
119
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700120 // Rewrite mClientPid to allow shutdown by CameraService
121 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700122 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700123}
124
125status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700126 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700127 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700128 mCameraId,
129 getCameraClient()->asBinder().get(),
130 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700131 result.append(" State: ");
132#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
133
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700134 const Parameters& p = mParameters.unsafeUnlock();
135
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700136 result.append(getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700137
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700138 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700140 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700141 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700142 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700143 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700144 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700145 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700146 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700150 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700151 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 p.jpegQuality, p.jpegThumbQuality);
153 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700154 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700155 p.gpsEnabled ? "enabled" : "disabled");
156 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.gpsCoordinates[0], p.gpsCoordinates[1],
159 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700161 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700162 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700163 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700164 }
165
166 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700167 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700168 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
176 default: result.append("UNKNOWN\n");
177 }
178
179 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700180 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700181 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
190 default: result.append("UNKNOWN\n");
191 }
192
193 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700194 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700195 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
199 default: result.append("UNKNOWN\n");
200 }
201
202 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700203 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700204 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
205 result.append("AUTO\n"); break;
206 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
207 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
208 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
221 default: result.append("UNKNOWN\n");
222 }
223
224 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700225 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700226 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
227 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
228 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
229 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
230 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
231 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
232 default: result.append("UNKNOWN\n");
233 }
234
235 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700236 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700237 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
238 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
239 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
242 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
243 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
244 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
245 default: result.append("UNKNOWN\n");
246 }
247
248 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700249 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700250 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700251 p.focusingAreas[i].left,
252 p.focusingAreas[i].top,
253 p.focusingAreas[i].right,
254 p.focusingAreas[i].bottom,
255 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700256 }
257
258 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700259 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700260
261 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700262 p.autoExposureLock ? "enabled" : "disabled",
263 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700264
265 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700266 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700267 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700268 p.meteringAreas[i].left,
269 p.meteringAreas[i].top,
270 p.meteringAreas[i].right,
271 p.meteringAreas[i].bottom,
272 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700273 }
274
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700275 result.appendFormat(" Zoom index: %d\n", p.zoom);
276 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
277 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700278
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700279 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700280 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700282 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700284
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700285 result.append(" Current streams:\n");
286 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
287 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700288 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700289
290 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700291 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292 result.append(" Preview request:\n");
293 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700294 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700295 } else {
296 result.append(" Preview request: undefined\n");
297 write(fd, result.string(), result.size());
298 }
299
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700300 if (mCaptureRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700301 result = " Capture request:\n";
302 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700303 mCaptureRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700304 } else {
305 result = " Capture request: undefined\n";
306 write(fd, result.string(), result.size());
307 }
308
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700309 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700310 result = " Recording request:\n";
311 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700312 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700313 } else {
314 result = " Recording request: undefined\n";
315 write(fd, result.string(), result.size());
316 }
317
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700318 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700319 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700320
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700321 status_t res = mDevice->dump(fd, args);
322 if (res != OK) {
323 result = String8::format(" Error dumping device: %s (%d)",
324 strerror(-res), res);
325 write(fd, result.string(), result.size());
326 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700327
328#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700329 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700330}
331
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700332const char* Camera2Client::getStateName(State state) {
333#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
334 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700335 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700336 CASE_ENUM_TO_CHAR(STOPPED)
337 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
338 CASE_ENUM_TO_CHAR(PREVIEW)
339 CASE_ENUM_TO_CHAR(RECORD)
340 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
341 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
342 default:
343 return "Unknown state!";
344 break;
345 }
346#undef CASE_ENUM_TO_CHAR
347}
348
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700349// ICamera interface
350
351void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700352 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700353 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700354 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700355 status_t res;
356 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700357
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700358 if (mDevice == 0) return;
359
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700360 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700361
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700362 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700363 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700364 mPreviewStreamId = NO_STREAM;
365 }
366
367 if (mCaptureStreamId != NO_STREAM) {
368 mDevice->deleteStream(mCaptureStreamId);
369 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700370 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700371
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700372 if (mRecordingStreamId != NO_STREAM) {
373 mDevice->deleteStream(mRecordingStreamId);
374 mRecordingStreamId = NO_STREAM;
375 }
376
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700377 if (mCallbackStreamId != NO_STREAM) {
378 mDevice->deleteStream(mCallbackStreamId);
379 mCallbackStreamId = NO_STREAM;
380 }
381
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700382 mDevice.clear();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700383 LockedParameters::Key k(mParameters);
384 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700385
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700386 if (mDeviceInfo != NULL) {
387 delete mDeviceInfo;
388 mDeviceInfo = NULL;
389 }
390
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700391 CameraService::Client::disconnect();
392}
393
394status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700395 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700396 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700397 Mutex::Autolock icl(mICameraLock);
398
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700399 if (mClientPid != 0 && getCallingPid() != mClientPid) {
400 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
401 "current locked to pid %d", __FUNCTION__,
402 mCameraId, getCallingPid(), mClientPid);
403 return BAD_VALUE;
404 }
405
406 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700407
408 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700409 mCameraClient = client;
410
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700411 LockedParameters::Key k(mParameters);
412 k.mParameters.state = STOPPED;
413
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700414 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700415}
416
417status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700418 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700419 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700420 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700421 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
422 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700423
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700424 if (mClientPid == 0) {
425 mClientPid = getCallingPid();
426 return OK;
427 }
428
429 if (mClientPid != getCallingPid()) {
430 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
431 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
432 return EBUSY;
433 }
434
435 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700436}
437
438status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700439 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700440 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700441 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700442 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
443 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700444
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700445 // TODO: Check for uninterruptable conditions
446
447 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700448 Mutex::Autolock iccl(mICameraClientLock);
449
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700450 mClientPid = 0;
451 mCameraClient.clear();
452 return OK;
453 }
454
455 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
456 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
457 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700458}
459
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700460status_t Camera2Client::setPreviewDisplay(
461 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700462 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700463 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700464 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700465 status_t res;
466 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700467
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700468 sp<IBinder> binder;
469 sp<ANativeWindow> window;
470 if (surface != 0) {
471 binder = surface->asBinder();
472 window = surface;
473 }
474
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700475 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700476}
477
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700478status_t Camera2Client::setPreviewTexture(
479 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700480 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700481 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700482 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700483 status_t res;
484 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700485
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700486 sp<IBinder> binder;
487 sp<ANativeWindow> window;
488 if (surfaceTexture != 0) {
489 binder = surfaceTexture->asBinder();
490 window = new SurfaceTextureClient(surfaceTexture);
491 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700492 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700493}
494
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700495status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700496 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700497 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700498 status_t res;
499
500 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700501 ALOGV("%s: Camera %d: New window is same as old window",
502 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700503 return NO_ERROR;
504 }
505
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700506 LockedParameters::Key k(mParameters);
507 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700508 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700509 case RECORD:
510 case STILL_CAPTURE:
511 case VIDEO_SNAPSHOT:
512 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700513 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700514 return INVALID_OPERATION;
515 case STOPPED:
516 case WAITING_FOR_PREVIEW_WINDOW:
517 // OK
518 break;
519 case PREVIEW:
520 // Already running preview - need to stop and create a new stream
521 // TODO: Optimize this so that we don't wait for old stream to drain
522 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700523 mDevice->clearStreamingRequest();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700524 k.mParameters.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700525 break;
526 }
527
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700528 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700529 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700530 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700531 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
532 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 return res;
534 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700535 res = mDevice->deleteStream(mPreviewStreamId);
536 if (res != OK) {
537 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
538 __FUNCTION__, strerror(-res), res);
539 return res;
540 }
541 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700542 }
543
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700544 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700545 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700546
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700547 if (k.mParameters.state == WAITING_FOR_PREVIEW_WINDOW) {
548 return startPreviewL(k.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700549 }
550
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700551 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700552}
553
554void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700555 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700556 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700557 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700558 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700559 if ( checkPid(__FUNCTION__) != OK) return;
560
561 LockedParameters::Key k(mParameters);
562 setPreviewCallbackFlagL(k.mParameters, flag);
563}
564
565void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
566 status_t res = OK;
567 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
568 ALOGV("%s: setting oneshot", __FUNCTION__);
569 params.previewCallbackOneShot = true;
570 }
571 if (params.previewCallbackFlags != (uint32_t)flag) {
572 params.previewCallbackFlags = flag;
573 switch(params.state) {
574 case PREVIEW:
575 res = startPreviewL(params, true);
576 break;
577 case RECORD:
578 case VIDEO_SNAPSHOT:
579 res = startRecordingL(params, true);
580 break;
581 default:
582 break;
583 }
584 if (res != OK) {
585 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
586 __FUNCTION__, mCameraId, getStateName(params.state));
587 }
588 }
589
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700590}
591
592status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700593 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700594 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700595 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700596 status_t res;
597 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700598 LockedParameters::Key k(mParameters);
599 return startPreviewL(k.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700600}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700601
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700602status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700603 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700605 if (params.state >= PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700606 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700607 __FUNCTION__, getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700608 return INVALID_OPERATION;
609 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700610
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700611 if (mPreviewWindow == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700612 params.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613 return OK;
614 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700615 params.state = STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700616
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700617 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700618 if (res != OK) {
619 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
620 __FUNCTION__, mCameraId, strerror(-res), res);
621 return res;
622 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700623 bool callbacksEnabled = params.previewCallbackFlags &
624 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
625 if (callbacksEnabled) {
626 res = updateCallbackStream(params);
627 if (res != OK) {
628 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
629 __FUNCTION__, mCameraId, strerror(-res), res);
630 return res;
631 }
632 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700633
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700634 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700635 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700636 if (res != OK) {
637 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
638 __FUNCTION__, mCameraId, strerror(-res), res);
639 return res;
640 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700641 }
642
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700643 if (callbacksEnabled) {
644 uint8_t outputStreams[2] =
645 { mPreviewStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700646 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700647 ANDROID_REQUEST_OUTPUT_STREAMS,
648 outputStreams, 2);
649 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700650 uint8_t outputStreams[1] = { mPreviewStreamId };
651 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700652 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700653 outputStreams, 1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700654 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700655 if (res != OK) {
656 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
657 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700658 return res;
659 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700660 res = mPreviewRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700661 if (res != OK) {
662 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
663 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700664 return res;
665 }
666
667 res = mDevice->setStreamingRequest(mPreviewRequest);
668 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700669 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
670 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700671 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700672 return res;
673 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700674 params.state = PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700675
676 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700677}
678
679void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700680 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700681 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700682 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700683 status_t res;
684 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700685 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700686}
687
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700688void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700689 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700690 State state;
691 {
692 LockedParameters::Key k(mParameters);
693 state = k.mParameters.state;
694 }
695
696 switch (state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700697 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700698 ALOGE("%s: Camera %d: Call before initialized",
699 __FUNCTION__, mCameraId);
700 break;
701 case STOPPED:
702 break;
703 case STILL_CAPTURE:
704 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
705 __FUNCTION__, mCameraId);
706 break;
707 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700708 // no break - identical to preview
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700709 case PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700710 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700711 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700712 // no break
713 case WAITING_FOR_PREVIEW_WINDOW: {
714 LockedParameters::Key k(mParameters);
715 k.mParameters.state = STOPPED;
716 commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700717 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700718 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700719 default:
720 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700721 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700722 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700723}
724
725bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700726 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700727 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700728 status_t res;
729 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
730
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700731 LockedParameters::Key k(mParameters);
732 return k.mParameters.state == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700733}
734
735status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700736 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700737 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700738 status_t res;
739 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
740
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700741 LockedParameters::Key k(mParameters);
742 switch (k.mParameters.state) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700743 case RECORD:
744 case VIDEO_SNAPSHOT:
745 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700746 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700747 return INVALID_OPERATION;
748 default:
749 // OK
750 break;
751 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700752
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700753 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700754
755 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700756}
757
758status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700759 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700760 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700761 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700762 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700763 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700764 LockedParameters::Key k(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700765
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700766 return startRecordingL(k.mParameters, false);
767}
768
769status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
770 status_t res;
771 switch (params.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700772 case STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700773 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 if (res != OK) return res;
775 break;
776 case PREVIEW:
777 // Ready to go
778 break;
779 case RECORD:
780 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700781 // OK to call this when recording is already on, just skip unless
782 // we're looking to restart
783 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700784 break;
785 default:
786 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700787 __FUNCTION__, mCameraId, getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700788 return INVALID_OPERATION;
789 };
790
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700791 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700792 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
793 "non-metadata recording mode requested!", __FUNCTION__,
794 mCameraId);
795 return INVALID_OPERATION;
796 }
797
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700798 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700799 if (res != OK) {
800 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
801 __FUNCTION__, mCameraId, strerror(-res), res);
802 return res;
803 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700804 bool callbacksEnabled = params.previewCallbackFlags &
805 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
806 if (callbacksEnabled) {
807 res = updateCallbackStream(params);
808 if (res != OK) {
809 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
810 __FUNCTION__, mCameraId, strerror(-res), res);
811 return res;
812 }
813 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700814
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700815 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700816 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700817 if (res != OK) {
818 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
819 __FUNCTION__, mCameraId, strerror(-res), res);
820 return res;
821 }
822 }
823
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700824 if (callbacksEnabled) {
825 uint8_t outputStreams[3] =
826 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700827 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700828 ANDROID_REQUEST_OUTPUT_STREAMS,
829 outputStreams, 3);
830 } else {
831 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700832 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700833 ANDROID_REQUEST_OUTPUT_STREAMS,
834 outputStreams, 2);
835 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700836 if (res != OK) {
837 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
838 __FUNCTION__, mCameraId, strerror(-res), res);
839 return res;
840 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700841 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700842 if (res != OK) {
843 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
844 __FUNCTION__, mCameraId, strerror(-res), res);
845 return res;
846 }
847
848 res = mDevice->setStreamingRequest(mRecordingRequest);
849 if (res != OK) {
850 ALOGE("%s: Camera %d: Unable to set recording request to start "
851 "recording: %s (%d)", __FUNCTION__, mCameraId,
852 strerror(-res), res);
853 return res;
854 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700855 if (params.state < RECORD) {
856 params.state = RECORD;
857 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700858
859 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700860}
861
862void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700863 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700864 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700865 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700866 LockedParameters::Key k(mParameters);
867
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700868 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700869 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
870
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700871 switch (k.mParameters.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700872 case RECORD:
873 // OK to stop
874 break;
875 case STOPPED:
876 case PREVIEW:
877 case STILL_CAPTURE:
878 case VIDEO_SNAPSHOT:
879 default:
880 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700881 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700882 return;
883 };
884
885 // Back to preview. Since record can only be reached through preview,
886 // all preview stream setup should be up to date.
887 res = mDevice->setStreamingRequest(mPreviewRequest);
888 if (res != OK) {
889 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
890 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
891 return;
892 }
893
894 // TODO: Should recording heap be freed? Can't do it yet since requests
895 // could still be in flight.
896
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700897 k.mParameters.state = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700898}
899
900bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700901 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700902 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700903
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700904 if ( checkPid(__FUNCTION__) != OK) return false;
905
James Dong8da4cd72012-08-04 19:58:07 -0700906 return recordingEnabledL();
907}
908
909bool Camera2Client::recordingEnabledL() {
910 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700911 LockedParameters::Key k(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700912
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700913 return (k.mParameters.state == RECORD || k.mParameters.state == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700914}
915
916void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700917 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700918 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700919 status_t res;
920 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700921
922 LockedParameters::Key k(mParameters);
923
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700924 // Make sure this is for the current heap
925 ssize_t offset;
926 size_t size;
927 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
928 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
929 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
930 "(got %x, expected %x)", __FUNCTION__, mCameraId,
931 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
932 return;
933 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700934 uint8_t *data = (uint8_t*)heap->getBase() + offset;
935 uint32_t type = *(uint32_t*)data;
936 if (type != kMetadataBufferTypeGrallocSource) {
937 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
938 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
939 return;
940 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700941
942 // Release the buffer back to the recording queue
943
944 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
945
946 size_t itemIndex;
947 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
948 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
949 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
950 item.mGraphicBuffer->handle == imgHandle) {
951 break;
952 }
953 }
954 if (itemIndex == mRecordingBuffers.size()) {
955 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
956 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
957 return;
958 }
959
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700960 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700961 imgHandle);
962
963 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700964 if (res != OK) {
965 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
966 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700967 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700968 return;
969 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700970 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700971
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700972 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700973}
974
975status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700976 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700977 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700978 status_t res;
979 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
980
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700981 int triggerId;
982 {
983 LockedParameters::Key k(mParameters);
984 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
985 triggerId = k.mParameters.currentAfTriggerId;
986 }
987
988 mDevice->triggerAutofocus(triggerId);
989
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700990 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700991}
992
993status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700994 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700995 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700996 status_t res;
997 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
998
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700999 int triggerId;
1000 {
1001 LockedParameters::Key k(mParameters);
1002 triggerId = ++k.mParameters.afTriggerCounter;
1003 }
1004
1005 mDevice->triggerCancelAutofocus(triggerId);
1006
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001007 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001008}
1009
1010status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001011 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001012 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001013 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001014 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001015
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001016 LockedParameters::Key k(mParameters);
1017 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001018 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001019 case STOPPED:
1020 case WAITING_FOR_PREVIEW_WINDOW:
1021 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1022 __FUNCTION__, mCameraId);
1023 return INVALID_OPERATION;
1024 case PREVIEW:
1025 case RECORD:
1026 // Good to go for takePicture
1027 break;
1028 case STILL_CAPTURE:
1029 case VIDEO_SNAPSHOT:
1030 ALOGE("%s: Camera %d: Already taking a picture",
1031 __FUNCTION__, mCameraId);
1032 return INVALID_OPERATION;
1033 }
1034
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001035 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001036
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001037 res = updateCaptureStream(k.mParameters);
1038 if (res != OK) {
1039 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1040 __FUNCTION__, mCameraId, strerror(-res), res);
1041 return res;
1042 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001043
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001044 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001045 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001046 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001047 ALOGE("%s: Camera %d: Can't create still image capture request: "
1048 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001049 return res;
1050 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001051 }
1052
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001053 bool callbacksEnabled = k.mParameters.previewCallbackFlags &
1054 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
1055 bool recordingEnabled = (k.mParameters.state == RECORD);
1056
1057 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1058 (recordingEnabled ? 0x1 : 0x0);
1059 switch ( streamSwitch ) {
1060 case 0: { // No recording, callbacks
1061 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001062 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1063 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001064 break;
1065 }
1066 case 1: { // Recording
1067 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1068 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001069 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1070 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001071 break;
1072 }
1073 case 2: { // Callbacks
1074 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1075 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001076 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1077 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001078 break;
1079 }
1080 case 3: { // Both
1081 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1082 mRecordingStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001083 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1084 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001085 break;
1086 }
1087 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001088 if (res != OK) {
1089 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1090 "%s (%d)",
1091 __FUNCTION__, mCameraId, strerror(-res), res);
1092 return res;
1093 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001094 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001095 if (res != OK) {
1096 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1097 __FUNCTION__, mCameraId, strerror(-res), res);
1098 return res;
1099 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001100
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001101 CameraMetadata captureCopy = mCaptureRequest;
1102 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001103 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1104 __FUNCTION__, mCameraId);
1105 return NO_MEMORY;
1106 }
1107
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001108 if (k.mParameters.state == PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001109 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001110 if (res != OK) {
1111 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1112 "%s (%d)",
1113 __FUNCTION__, mCameraId, strerror(-res), res);
1114 return res;
1115 }
1116 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001117 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001118 res = mDevice->capture(captureCopy);
1119 if (res != OK) {
1120 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1121 "%s (%d)",
1122 __FUNCTION__, mCameraId, strerror(-res), res);
1123 return res;
1124 }
1125
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001126 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001127 case PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001128 k.mParameters.state = STILL_CAPTURE;
1129 res = commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001130 if (res != OK) {
1131 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1132 __FUNCTION__, mCameraId);
1133 return res;
1134 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001135 break;
1136 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001137 k.mParameters.state = VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001138 break;
1139 default:
1140 ALOGE("%s: Camera %d: Unknown state for still capture!",
1141 __FUNCTION__, mCameraId);
1142 return INVALID_OPERATION;
1143 }
1144
1145 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001146}
1147
1148status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001149 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001150 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001151 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001152 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001153 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1154
1155 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001156
1157 CameraParameters newParams(params);
1158
1159 // TODO: Currently ignoring any changes to supposedly read-only
1160 // parameters such as supported preview sizes, etc. Should probably
1161 // produce an error if they're changed.
1162
1163 /** Extract and verify new parameters */
1164
1165 size_t i;
1166
1167 // PREVIEW_SIZE
1168 int previewWidth, previewHeight;
1169 newParams.getPreviewSize(&previewWidth, &previewHeight);
1170
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001171 if (previewWidth != k.mParameters.previewWidth ||
1172 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001173 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001174 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001175 "is active! (Currently %d x %d, requested %d x %d",
1176 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001177 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001178 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001179 return BAD_VALUE;
1180 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001181 camera_metadata_ro_entry_t availablePreviewSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001182 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1183 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1184 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1185 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1186 }
1187 if (i == availablePreviewSizes.count) {
1188 ALOGE("%s: Requested preview size %d x %d is not supported",
1189 __FUNCTION__, previewWidth, previewHeight);
1190 return BAD_VALUE;
1191 }
1192 }
1193
1194 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001195 int previewFpsRange[2];
1196 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001197 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001198 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001199 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1200 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001201 fpsRangeChanged = true;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001202 camera_metadata_ro_entry_t availablePreviewFpsRanges =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001203 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1204 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1205 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001206 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001207 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001208 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001209 break;
1210 }
1211 }
1212 if (i == availablePreviewFpsRanges.count) {
1213 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001214 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001215 return BAD_VALUE;
1216 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001217 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001218 }
1219
1220 // PREVIEW_FORMAT
1221 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001222 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001223 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001224 ALOGE("%s: Preview format cannot be updated when preview "
1225 "is active!", __FUNCTION__);
1226 return BAD_VALUE;
1227 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001228 camera_metadata_ro_entry_t availableFormats =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001229 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1230 for (i = 0; i < availableFormats.count; i++) {
1231 if (availableFormats.data.i32[i] == previewFormat) break;
1232 }
1233 if (i == availableFormats.count) {
1234 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1235 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1236 return BAD_VALUE;
1237 }
1238 }
1239
1240 // PREVIEW_FRAME_RATE
1241 // Deprecated, only use if the preview fps range is unchanged this time.
1242 // The single-value FPS is the same as the minimum of the range.
1243 if (!fpsRangeChanged) {
1244 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001245 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001246 camera_metadata_ro_entry_t availableFrameRates =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001247 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1248 for (i = 0; i < availableFrameRates.count; i+=2) {
1249 if (availableFrameRates.data.i32[i] == previewFps) break;
1250 }
1251 if (i == availableFrameRates.count) {
1252 ALOGE("%s: Requested preview frame rate %d is not supported",
1253 __FUNCTION__, previewFps);
1254 return BAD_VALUE;
1255 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001256 previewFpsRange[0] = availableFrameRates.data.i32[i];
1257 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001258 }
1259 }
1260
1261 // PICTURE_SIZE
1262 int pictureWidth, pictureHeight;
1263 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001264 if (pictureWidth == k.mParameters.pictureWidth ||
1265 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001266 camera_metadata_ro_entry_t availablePictureSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001267 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1268 for (i = 0; i < availablePictureSizes.count; i+=2) {
1269 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1270 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1271 }
1272 if (i == availablePictureSizes.count) {
1273 ALOGE("%s: Requested picture size %d x %d is not supported",
1274 __FUNCTION__, pictureWidth, pictureHeight);
1275 return BAD_VALUE;
1276 }
1277 }
1278
1279 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001280 int jpegThumbSize[2];
1281 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001282 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001283 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001284 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001285 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1286 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001287 camera_metadata_ro_entry_t availableJpegThumbSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001288 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1289 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001290 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1291 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001292 break;
1293 }
1294 }
1295 if (i == availableJpegThumbSizes.count) {
1296 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001297 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001298 return BAD_VALUE;
1299 }
1300 }
1301
1302 // JPEG_THUMBNAIL_QUALITY
1303 int jpegThumbQuality =
1304 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1305 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1306 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1307 __FUNCTION__, jpegThumbQuality);
1308 return BAD_VALUE;
1309 }
1310
1311 // JPEG_QUALITY
1312 int jpegQuality =
1313 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1314 if (jpegQuality < 0 || jpegQuality > 100) {
1315 ALOGE("%s: Requested JPEG quality %d is not supported",
1316 __FUNCTION__, jpegQuality);
1317 return BAD_VALUE;
1318 }
1319
1320 // ROTATION
1321 int jpegRotation =
1322 newParams.getInt(CameraParameters::KEY_ROTATION);
1323 if (jpegRotation != 0 &&
1324 jpegRotation != 90 &&
1325 jpegRotation != 180 &&
1326 jpegRotation != 270) {
1327 ALOGE("%s: Requested picture rotation angle %d is not supported",
1328 __FUNCTION__, jpegRotation);
1329 return BAD_VALUE;
1330 }
1331
1332 // GPS
1333 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001334 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001335 int64_t gpsTimestamp = 0;
1336 String8 gpsProcessingMethod;
1337 const char *gpsLatStr =
1338 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1339 if (gpsLatStr != NULL) {
1340 const char *gpsLongStr =
1341 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1342 const char *gpsAltitudeStr =
1343 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1344 const char *gpsTimeStr =
1345 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1346 const char *gpsProcMethodStr =
1347 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1348 if (gpsLongStr == NULL ||
1349 gpsAltitudeStr == NULL ||
1350 gpsTimeStr == NULL ||
1351 gpsProcMethodStr == NULL) {
1352 ALOGE("%s: Incomplete set of GPS parameters provided",
1353 __FUNCTION__);
1354 return BAD_VALUE;
1355 }
1356 char *endPtr;
1357 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001358 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001359 if (errno || endPtr == gpsLatStr) {
1360 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1361 return BAD_VALUE;
1362 }
1363 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001364 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001365 if (errno || endPtr == gpsLongStr) {
1366 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1367 return BAD_VALUE;
1368 }
1369 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001370 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001371 if (errno || endPtr == gpsAltitudeStr) {
1372 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1373 gpsAltitudeStr);
1374 return BAD_VALUE;
1375 }
1376 errno = 0;
1377 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1378 if (errno || endPtr == gpsTimeStr) {
1379 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1380 return BAD_VALUE;
1381 }
1382 gpsProcessingMethod = gpsProcMethodStr;
1383
1384 gpsEnabled = true;
1385 }
1386
1387 // WHITE_BALANCE
1388 int wbMode = wbModeStringToEnum(
1389 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001390 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001391 camera_metadata_ro_entry_t availableWbModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001392 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1393 for (i = 0; i < availableWbModes.count; i++) {
1394 if (wbMode == availableWbModes.data.u8[i]) break;
1395 }
1396 if (i == availableWbModes.count) {
1397 ALOGE("%s: Requested white balance mode %s is not supported",
1398 __FUNCTION__,
1399 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1400 return BAD_VALUE;
1401 }
1402 }
1403
1404 // EFFECT
1405 int effectMode = effectModeStringToEnum(
1406 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001407 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001408 camera_metadata_ro_entry_t availableEffectModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001409 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1410 for (i = 0; i < availableEffectModes.count; i++) {
1411 if (effectMode == availableEffectModes.data.u8[i]) break;
1412 }
1413 if (i == availableEffectModes.count) {
1414 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1415 __FUNCTION__,
1416 newParams.get(CameraParameters::KEY_EFFECT) );
1417 return BAD_VALUE;
1418 }
1419 }
1420
1421 // ANTIBANDING
1422 int antibandingMode = abModeStringToEnum(
1423 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001424 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001425 camera_metadata_ro_entry_t availableAbModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001426 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1427 for (i = 0; i < availableAbModes.count; i++) {
1428 if (antibandingMode == availableAbModes.data.u8[i]) break;
1429 }
1430 if (i == availableAbModes.count) {
1431 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1432 __FUNCTION__,
1433 newParams.get(CameraParameters::KEY_ANTIBANDING));
1434 return BAD_VALUE;
1435 }
1436 }
1437
1438 // SCENE_MODE
1439 int sceneMode = sceneModeStringToEnum(
1440 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala3cc89792012-08-16 16:03:59 -07001441 if (sceneMode != k.mParameters.sceneMode &&
1442 sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001443 camera_metadata_ro_entry_t availableSceneModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001444 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1445 for (i = 0; i < availableSceneModes.count; i++) {
1446 if (sceneMode == availableSceneModes.data.u8[i]) break;
1447 }
1448 if (i == availableSceneModes.count) {
1449 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1450 __FUNCTION__,
1451 newParams.get(CameraParameters::KEY_SCENE_MODE));
1452 return BAD_VALUE;
1453 }
1454 }
1455
1456 // FLASH_MODE
1457 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1458 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001459 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001460 camera_metadata_ro_entry_t flashAvailable =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001461 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1462 if (!flashAvailable.data.u8[0] &&
1463 flashMode != Parameters::FLASH_MODE_OFF) {
1464 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1465 "No flash on device", __FUNCTION__,
1466 newParams.get(CameraParameters::KEY_FLASH_MODE));
1467 return BAD_VALUE;
1468 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001469 camera_metadata_ro_entry_t availableAeModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001470 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1471 for (i = 0; i < availableAeModes.count; i++) {
1472 if (flashMode == availableAeModes.data.u8[i]) break;
1473 }
1474 if (i == availableAeModes.count) {
1475 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1476 __FUNCTION__,
1477 newParams.get(CameraParameters::KEY_FLASH_MODE));
1478 return BAD_VALUE;
1479 }
1480 } else if (flashMode == -1) {
1481 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1482 __FUNCTION__,
1483 newParams.get(CameraParameters::KEY_FLASH_MODE));
1484 return BAD_VALUE;
1485 }
1486 }
1487
1488 // FOCUS_MODE
1489 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1490 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001491 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001492 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001493 camera_metadata_ro_entry_t minFocusDistance =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001494 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1495 if (minFocusDistance.data.f[0] == 0) {
1496 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1497 "fixed focus lens",
1498 __FUNCTION__,
1499 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1500 return BAD_VALUE;
1501 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001502 camera_metadata_ro_entry_t availableFocusModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001503 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1504 for (i = 0; i < availableFocusModes.count; i++) {
1505 if (focusMode == availableFocusModes.data.u8[i]) break;
1506 }
1507 if (i == availableFocusModes.count) {
1508 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1509 __FUNCTION__,
1510 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1511 return BAD_VALUE;
1512 }
1513 }
1514 }
1515 }
1516
1517 // FOCUS_AREAS
1518 Vector<Parameters::Area> focusingAreas;
1519 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1520 &focusingAreas);
1521 size_t max3aRegions =
1522 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1523 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1524 if (res != OK) {
1525 ALOGE("%s: Requested focus areas are malformed: %s",
1526 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1527 return BAD_VALUE;
1528 }
1529
1530 // EXPOSURE_COMPENSATION
1531 int exposureCompensation =
1532 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001533 camera_metadata_ro_entry_t exposureCompensationRange =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001534 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1535 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1536 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1537 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1538 __FUNCTION__, exposureCompensation);
1539 return BAD_VALUE;
1540 }
1541
1542 // AUTO_EXPOSURE_LOCK (always supported)
1543 bool autoExposureLock = boolFromString(
1544 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1545
1546 // AUTO_WHITEBALANCE_LOCK (always supported)
1547 bool autoWhiteBalanceLock = boolFromString(
1548 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1549
1550 // METERING_AREAS
1551 Vector<Parameters::Area> meteringAreas;
1552 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1553 &meteringAreas);
1554 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1555 if (res != OK) {
1556 ALOGE("%s: Requested metering areas are malformed: %s",
1557 __FUNCTION__,
1558 newParams.get(CameraParameters::KEY_METERING_AREAS));
1559 return BAD_VALUE;
1560 }
1561
1562 // ZOOM
1563 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1564 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1565 ALOGE("%s: Requested zoom level %d is not supported",
1566 __FUNCTION__, zoom);
1567 return BAD_VALUE;
1568 }
1569
1570 // VIDEO_SIZE
1571 int videoWidth, videoHeight;
1572 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001573 if (videoWidth != k.mParameters.videoWidth ||
1574 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001575 if (k.mParameters.state == RECORD) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001576 ALOGE("%s: Video size cannot be updated when recording is active!",
1577 __FUNCTION__);
1578 return BAD_VALUE;
1579 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001580 camera_metadata_ro_entry_t availableVideoSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001581 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1582 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1583 if (availableVideoSizes.data.i32[i] == videoWidth &&
1584 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1585 }
1586 if (i == availableVideoSizes.count) {
1587 ALOGE("%s: Requested video size %d x %d is not supported",
1588 __FUNCTION__, videoWidth, videoHeight);
1589 return BAD_VALUE;
1590 }
1591 }
1592
1593 // RECORDING_HINT (always supported)
1594 bool recordingHint = boolFromString(
1595 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1596
1597 // VIDEO_STABILIZATION
1598 bool videoStabilization = boolFromString(
1599 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001600 camera_metadata_ro_entry_t availableVideoStabilizationModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001601 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1602 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1603 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1604 }
1605
1606 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001607
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001608 k.mParameters.previewWidth = previewWidth;
1609 k.mParameters.previewHeight = previewHeight;
1610 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1611 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1612 k.mParameters.previewFps = previewFps;
1613 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001614
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001615 k.mParameters.pictureWidth = pictureWidth;
1616 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001617
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001618 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1619 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1620 k.mParameters.jpegQuality = jpegQuality;
1621 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001622
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001623 k.mParameters.gpsEnabled = gpsEnabled;
1624 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1625 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1626 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1627 k.mParameters.gpsTimestamp = gpsTimestamp;
1628 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001629
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001630 k.mParameters.wbMode = wbMode;
1631 k.mParameters.effectMode = effectMode;
1632 k.mParameters.antibandingMode = antibandingMode;
1633 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001634
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001635 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001636 if (focusMode != k.mParameters.focusMode) {
1637 k.mParameters.currentAfTriggerId = -1;
1638 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001639 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001640
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001641 k.mParameters.focusingAreas = focusingAreas;
1642 k.mParameters.exposureCompensation = exposureCompensation;
1643 k.mParameters.autoExposureLock = autoExposureLock;
1644 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1645 k.mParameters.meteringAreas = meteringAreas;
1646 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001647
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001648 k.mParameters.videoWidth = videoWidth;
1649 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001650
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001651 k.mParameters.recordingHint = recordingHint;
1652 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001653
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001654 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001655
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001656 res = updateRequests(k.mParameters);
1657
1658 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001659}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001660
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001661String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001662 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001663 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001664 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001665
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001666 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001667
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001668 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001669 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001670}
1671
1672status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001673 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001674 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001675 status_t res;
1676 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001677
1678 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1679 cmd, arg1, arg2);
1680
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001681 switch (cmd) {
1682 case CAMERA_CMD_START_SMOOTH_ZOOM:
1683 return commandStartSmoothZoomL();
1684 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1685 return commandStopSmoothZoomL();
1686 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1687 return commandSetDisplayOrientationL(arg1);
1688 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1689 return commandEnableShutterSoundL(arg1 == 1);
1690 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1691 return commandPlayRecordingSoundL();
1692 case CAMERA_CMD_START_FACE_DETECTION:
1693 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001694 case CAMERA_CMD_STOP_FACE_DETECTION: {
1695 LockedParameters::Key k(mParameters);
1696 return commandStopFaceDetectionL(k.mParameters);
1697 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001698 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1699 return commandEnableFocusMoveMsgL(arg1 == 1);
1700 case CAMERA_CMD_PING:
1701 return commandPingL();
1702 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1703 return commandSetVideoBufferCountL(arg1);
1704 default:
1705 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1706 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001707 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001708 }
1709}
James Dong983cf232012-08-01 16:39:55 -07001710
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001711status_t Camera2Client::commandStartSmoothZoomL() {
1712 ALOGE("%s: Unimplemented!", __FUNCTION__);
1713 return OK;
1714}
James Dong983cf232012-08-01 16:39:55 -07001715
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001716status_t Camera2Client::commandStopSmoothZoomL() {
1717 ALOGE("%s: Unimplemented!", __FUNCTION__);
1718 return OK;
1719}
James Dong983cf232012-08-01 16:39:55 -07001720
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001721status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1722 LockedParameters::Key k(mParameters);
1723 int transform = degToTransform(degrees,
1724 mCameraFacing == CAMERA_FACING_FRONT);
1725 if (transform == -1) {
1726 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1727 __FUNCTION__, mCameraId, degrees);
1728 return BAD_VALUE;
1729 }
1730 if (transform != k.mParameters.previewTransform &&
1731 mPreviewStreamId != NO_STREAM) {
1732 mDevice->setStreamTransform(mPreviewStreamId, transform);
1733 }
1734 k.mParameters.previewTransform = transform;
1735 return OK;
1736}
1737
1738status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1739 LockedParameters::Key k(mParameters);
1740 if (enable) {
1741 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001742 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001743 }
1744
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001745 // Disabling shutter sound may not be allowed. In that case only
1746 // allow the mediaserver process to disable the sound.
1747 char value[PROPERTY_VALUE_MAX];
1748 property_get("ro.camera.sound.forced", value, "0");
1749 if (strncmp(value, "0", 2) != 0) {
1750 // Disabling shutter sound is not allowed. Deny if the current
1751 // process is not mediaserver.
1752 if (getCallingPid() != getpid()) {
1753 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1754 getCallingPid());
1755 return PERMISSION_DENIED;
1756 }
1757 }
1758
1759 k.mParameters.playShutterSound = false;
1760 return OK;
1761}
1762
1763status_t Camera2Client::commandPlayRecordingSoundL() {
1764 mCameraService->playSound(CameraService::SOUND_RECORDING);
1765 return OK;
1766}
1767
1768status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001769 ALOGV("%s: Camera %d: Starting face detection",
1770 __FUNCTION__, mCameraId);
1771 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001772 LockedParameters::Key k(mParameters);
1773 switch (k.mParameters.state) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001774 case DISCONNECTED:
1775 case STOPPED:
1776 case WAITING_FOR_PREVIEW_WINDOW:
1777 case STILL_CAPTURE:
1778 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1779 __FUNCTION__, mCameraId);
1780 return INVALID_OPERATION;
1781 case PREVIEW:
1782 case RECORD:
1783 case VIDEO_SNAPSHOT:
1784 // Good to go for starting face detect
1785 break;
1786 }
1787 // Ignoring type
1788 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1789 ALOGE("%s: Camera %d: Face detection not supported",
1790 __FUNCTION__, mCameraId);
1791 return INVALID_OPERATION;
1792 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001793 if (k.mParameters.enableFaceDetect) return OK;
1794
1795 k.mParameters.enableFaceDetect = true;
1796
1797 res = updateRequests(k.mParameters);
1798
1799 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001800}
1801
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001802status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001803 status_t res = OK;
1804 ALOGV("%s: Camera %d: Stopping face detection",
1805 __FUNCTION__, mCameraId);
1806
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001807 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001808
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001809 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001810
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001811 if (params.state == PREVIEW || params.state == RECORD ||
1812 params.state == VIDEO_SNAPSHOT) {
1813 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001814 }
1815
1816 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001817}
1818
1819status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001820 LockedParameters::Key k(mParameters);
1821 k.mParameters.enableFocusMoveMessages = enable;
1822
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001823 return OK;
1824}
1825
1826status_t Camera2Client::commandPingL() {
1827 // Always ping back if access is proper and device is alive
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001828 LockedParameters::Key k(mParameters);
1829 if (k.mParameters.state != DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001830 return OK;
1831 } else {
1832 return NO_INIT;
1833 }
1834}
1835
1836status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001837 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001838 ALOGE("%s: Camera %d: Error setting video buffer count after "
1839 "recording was started", __FUNCTION__, mCameraId);
1840 return INVALID_OPERATION;
1841 }
1842
1843 // 32 is the current upper limit on the video buffer count for BufferQueue
1844 if (count > 32) {
1845 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1846 __FUNCTION__, mCameraId, count);
1847 return BAD_VALUE;
1848 }
1849
1850 // Need to reallocate memory for heap
1851 if (mRecordingHeapCount != count) {
1852 if (mRecordingHeap != 0) {
1853 mRecordingHeap.clear();
1854 mRecordingHeap = NULL;
1855 }
1856 mRecordingHeapCount = count;
1857 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001858
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001859 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001860}
1861
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001862/** Device-related methods */
1863
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001864void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1865 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1866}
1867
1868void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1869 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1870 frameNumber, timestamp);
1871}
1872
1873void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1874 ALOGV("%s: Autofocus state now %d, last trigger %d",
1875 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001876 bool sendCompletedMessage = false;
1877 bool sendMovingMessage = false;
1878
1879 bool success = false;
1880 bool afInMotion = false;
1881 {
1882 LockedParameters::Key k(mParameters);
1883 switch (k.mParameters.focusMode) {
1884 case Parameters::FOCUS_MODE_AUTO:
1885 case Parameters::FOCUS_MODE_MACRO:
1886 // Don't send notifications upstream if they're not for the current AF
1887 // trigger. For example, if cancel was called in between, or if we
1888 // already sent a notification about this AF call.
1889 if (triggerId != k.mParameters.currentAfTriggerId) break;
1890 switch (newState) {
1891 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1892 success = true;
1893 // no break
1894 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1895 sendCompletedMessage = true;
1896 k.mParameters.currentAfTriggerId = -1;
1897 break;
1898 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1899 // Just starting focusing, ignore
1900 break;
1901 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1902 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1903 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1904 default:
1905 // Unexpected in AUTO/MACRO mode
1906 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1907 __FUNCTION__, newState);
1908 break;
1909 }
1910 break;
1911 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1912 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1913 switch (newState) {
1914 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1915 success = true;
1916 // no break
1917 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1918 // Don't send notifications upstream if they're not for
1919 // the current AF trigger. For example, if cancel was
1920 // called in between, or if we already sent a
1921 // notification about this AF call.
1922 // Send both a 'AF done' callback and a 'AF move' callback
1923 if (triggerId != k.mParameters.currentAfTriggerId) break;
1924 sendCompletedMessage = true;
1925 afInMotion = false;
1926 if (k.mParameters.enableFocusMoveMessages &&
1927 k.mParameters.afInMotion) {
1928 sendMovingMessage = true;
1929 }
1930 k.mParameters.currentAfTriggerId = -1;
1931 break;
1932 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1933 // Cancel was called, or we switched state; care if
1934 // currently moving
1935 afInMotion = false;
1936 if (k.mParameters.enableFocusMoveMessages &&
1937 k.mParameters.afInMotion) {
1938 sendMovingMessage = true;
1939 }
1940 break;
1941 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1942 // Start passive scan, inform upstream
1943 afInMotion = true;
1944 // no break
1945 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1946 // Stop passive scan, inform upstream
1947 if (k.mParameters.enableFocusMoveMessages) {
1948 sendMovingMessage = true;
1949 }
1950 break;
1951 }
1952 k.mParameters.afInMotion = afInMotion;
1953 break;
1954 case Parameters::FOCUS_MODE_EDOF:
1955 case Parameters::FOCUS_MODE_INFINITY:
1956 case Parameters::FOCUS_MODE_FIXED:
1957 default:
1958 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1959 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1960 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1961 }
1962 }
1963 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001964 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001965 Mutex::Autolock iccl(mICameraClientLock);
1966 if (mCameraClient != 0) {
1967 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1968 afInMotion ? 1 : 0, 0);
1969 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001970 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001971 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001972 Mutex::Autolock iccl(mICameraClientLock);
1973 if (mCameraClient != 0) {
1974 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1975 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001976 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001977}
1978
1979void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1980 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1981 __FUNCTION__, newState, triggerId);
1982}
1983
1984void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1985 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1986 __FUNCTION__, newState, triggerId);
1987}
1988
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001989void Camera2Client::onNewFrameAvailable() {
1990 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001991 CameraMetadata frame;
1992 while ( (res = mDevice->getNextFrame(&frame)) == OK) {
1993 camera_metadata_entry_t entry;
1994 entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
1995 if (entry.count == 0) {
1996 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001997 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001998 break;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001999 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002000
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002001 res = processFrameFaceDetect(frame);
2002 if (res != OK) break;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002003 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002004 if (res != NOT_ENOUGH_DATA) {
2005 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
2006 __FUNCTION__, mCameraId, strerror(-res), res);
2007 return;
2008 }
2009
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002010 return;
2011}
2012
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002013status_t Camera2Client::processFrameFaceDetect(const CameraMetadata &frame) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002014 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002015 camera_metadata_ro_entry_t entry;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002016 bool enableFaceDetect;
2017 {
2018 LockedParameters::Key k(mParameters);
2019 enableFaceDetect = k.mParameters.enableFaceDetect;
2020 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002021 entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE);
2022
2023 // TODO: This should be an error once implementations are compliant
2024 if (entry.count == 0) {
Eino-Ville Talvala76dc8da2012-08-21 16:09:31 -07002025 return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002026 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002027
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002028 uint8_t faceDetectMode = entry.data.u8[0];
2029
2030 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002031 entry = frame.find(ANDROID_STATS_FACE_RECTANGLES);
2032 if (entry.count == 0) {
2033 ALOGE("%s: Camera %d: Unable to read face rectangles",
2034 __FUNCTION__, mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002035 return res;
2036 }
2037 camera_frame_metadata metadata;
2038 metadata.number_of_faces = entry.count / 4;
2039 if (metadata.number_of_faces >
2040 mDeviceInfo->maxFaces) {
2041 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
2042 __FUNCTION__, mCameraId,
2043 metadata.number_of_faces, mDeviceInfo->maxFaces);
2044 return res;
2045 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002046 const int32_t *faceRects = entry.data.i32;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002047
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002048 entry = frame.find(ANDROID_STATS_FACE_SCORES);
2049 if (entry.count == 0) {
2050 ALOGE("%s: Camera %d: Unable to read face scores",
2051 __FUNCTION__, mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002052 return res;
2053 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002054 const uint8_t *faceScores = entry.data.u8;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002055
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002056 const int32_t *faceLandmarks = NULL;
2057 const int32_t *faceIds = NULL;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002058
2059 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002060 entry = frame.find(ANDROID_STATS_FACE_LANDMARKS);
2061 if (entry.count == 0) {
2062 ALOGE("%s: Camera %d: Unable to read face landmarks",
2063 __FUNCTION__, mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002064 return res;
2065 }
2066 faceLandmarks = entry.data.i32;
2067
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002068 entry = frame.find(ANDROID_STATS_FACE_IDS);
2069
2070 if (entry.count == 0) {
2071 ALOGE("%s: Camera %d: Unable to read face IDs",
2072 __FUNCTION__, mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002073 return res;
2074 }
2075 faceIds = entry.data.i32;
2076 }
2077
2078 Vector<camera_face_t> faces;
2079 faces.setCapacity(metadata.number_of_faces);
2080
2081 for (int i = 0; i < metadata.number_of_faces; i++) {
2082 camera_face_t face;
2083
2084 face.rect[0] = arrayXToNormalized(faceRects[i*4 + 0]);
2085 face.rect[1] = arrayYToNormalized(faceRects[i*4 + 1]);
2086 face.rect[2] = arrayXToNormalized(faceRects[i*4 + 2]);
2087 face.rect[3] = arrayYToNormalized(faceRects[i*4 + 3]);
2088
2089 face.score = faceScores[i];
2090 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2091 face.id = faceIds[i];
2092 face.left_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 0]);
2093 face.left_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 1]);
2094 face.right_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 2]);
2095 face.right_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 3]);
2096 face.mouth[0] = arrayXToNormalized(faceLandmarks[i*6 + 4]);
2097 face.mouth[1] = arrayYToNormalized(faceLandmarks[i*6 + 5]);
2098 } else {
2099 face.id = 0;
2100 face.left_eye[0] = face.left_eye[1] = -2000;
2101 face.right_eye[0] = face.right_eye[1] = -2000;
2102 face.mouth[0] = face.mouth[1] = -2000;
2103 }
2104 faces.push_back(face);
2105 }
2106
2107 metadata.faces = faces.editArray();
2108 {
2109 Mutex::Autolock iccl(mICameraClientLock);
2110 if (mCameraClient != NULL) {
2111 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
2112 NULL, &metadata);
2113 }
2114 }
2115 }
2116 return OK;
2117}
2118
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002119void Camera2Client::onCallbackAvailable() {
2120 ATRACE_CALL();
2121 status_t res;
2122 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
2123
2124 int callbackHeapId;
2125 sp<Camera2Heap> callbackHeap;
2126 size_t heapIdx;
2127
2128 CpuConsumer::LockedBuffer imgBuffer;
2129 ALOGV("%s: Getting buffer", __FUNCTION__);
2130 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
2131 if (res != OK) {
2132 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
2133 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2134 return;
2135 }
2136
2137 {
2138 LockedParameters::Key k(mParameters);
2139
2140 if ( k.mParameters.state != PREVIEW && k.mParameters.state != RECORD
2141 && k.mParameters.state != VIDEO_SNAPSHOT) {
2142 ALOGV("%s: Camera %d: No longer streaming",
2143 __FUNCTION__, mCameraId);
2144 mCallbackConsumer->unlockBuffer(imgBuffer);
2145 return;
2146 }
2147
2148 if (! (k.mParameters.previewCallbackFlags &
2149 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
2150 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
2151 mCallbackConsumer->unlockBuffer(imgBuffer);
2152 return;
2153 }
2154 if ((k.mParameters.previewCallbackFlags &
2155 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
2156 !k.mParameters.previewCallbackOneShot) {
2157 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
2158 mCallbackConsumer->unlockBuffer(imgBuffer);
2159 return;
2160 }
2161
2162 if (imgBuffer.format != k.mParameters.previewFormat) {
2163 ALOGE("%s: Camera %d: Unexpected format for callback: "
2164 "%x, expected %x", __FUNCTION__, mCameraId,
2165 imgBuffer.format, k.mParameters.previewFormat);
2166 mCallbackConsumer->unlockBuffer(imgBuffer);
2167 return;
2168 }
2169
2170 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
2171 imgBuffer.format, imgBuffer.stride);
2172 size_t currentBufferSize = (mCallbackHeap == 0) ?
2173 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
2174 if (bufferSize != currentBufferSize) {
2175 mCallbackHeap.clear();
2176 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
2177 "Camera2Client::CallbackHeap");
2178 if (mCallbackHeap->mHeap->getSize() == 0) {
2179 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
2180 __FUNCTION__, mCameraId);
2181 mCallbackConsumer->unlockBuffer(imgBuffer);
2182 return;
2183 }
2184
2185 mCallbackHeapHead = 0;
2186 mCallbackHeapFree = kCallbackHeapCount;
2187 mCallbackHeapId++;
2188 }
2189
2190 if (mCallbackHeapFree == 0) {
2191 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
2192 __FUNCTION__, mCameraId);
2193 mCallbackConsumer->unlockBuffer(imgBuffer);
2194 return;
2195 }
2196 heapIdx = mCallbackHeapHead;
2197 callbackHeap = mCallbackHeap;
2198 callbackHeapId = mCallbackHeapId;
2199
2200 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
2201 mCallbackHeapFree--;
2202
2203 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
2204 // to app
2205
2206 ssize_t offset;
2207 size_t size;
2208 sp<IMemoryHeap> heap =
2209 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
2210 &size);
2211 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2212 memcpy(data, imgBuffer.data, bufferSize);
2213
2214 ALOGV("%s: Freeing buffer", __FUNCTION__);
2215 mCallbackConsumer->unlockBuffer(imgBuffer);
2216
2217 // In one-shot mode, stop sending callbacks after the first one
2218 if (k.mParameters.previewCallbackFlags &
2219 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
2220 ALOGV("%s: clearing oneshot", __FUNCTION__);
2221 k.mParameters.previewCallbackOneShot = false;
2222 }
2223 }
2224
2225 // Call outside parameter lock to allow re-entrancy from notification
2226 {
2227 Mutex::Autolock iccl(mICameraClientLock);
2228 if (mCameraClient != 0) {
2229 ALOGV("%s: Camera %d: Invoking client data callback",
2230 __FUNCTION__, mCameraId);
2231 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
2232 callbackHeap->mBuffers[heapIdx], NULL);
2233 }
2234 }
2235
2236 LockedParameters::Key k(mParameters);
2237 // Only increment free if we're still using the same heap
2238 if (mCallbackHeapId == callbackHeapId) {
2239 mCallbackHeapFree++;
2240 }
2241
2242 ALOGV("%s: exit", __FUNCTION__);
2243}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002244
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002245void Camera2Client::onCaptureAvailable() {
2246 ATRACE_CALL();
2247 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002248 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002249 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
2250
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002251 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002252 LockedParameters::Key k(mParameters);
2253 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002254
2255 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2256 if (res != OK) {
2257 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2258 __FUNCTION__, mCameraId, strerror(-res), res);
2259 return;
2260 }
2261
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002262 // TODO: Signal errors here upstream
2263 if (k.mParameters.state != STILL_CAPTURE &&
2264 k.mParameters.state != VIDEO_SNAPSHOT) {
2265 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2266 __FUNCTION__, mCameraId);
2267 mCaptureConsumer->unlockBuffer(imgBuffer);
2268 return;
2269 }
2270
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002271 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2272 ALOGE("%s: Camera %d: Unexpected format for still image: "
2273 "%x, expected %x", __FUNCTION__, mCameraId,
2274 imgBuffer.format,
2275 HAL_PIXEL_FORMAT_BLOB);
2276 mCaptureConsumer->unlockBuffer(imgBuffer);
2277 return;
2278 }
2279
2280 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002281 void* captureMemory = mCaptureHeap->mHeap->getBase();
2282 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002283 memcpy(captureMemory, imgBuffer.data, size);
2284
2285 mCaptureConsumer->unlockBuffer(imgBuffer);
2286
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002287 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002288 case STILL_CAPTURE:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002289 k.mParameters.state = STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002290 break;
2291 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002292 k.mParameters.state = RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002293 break;
2294 default:
2295 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002296 mCameraId, k.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002297 break;
2298 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002299
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002300 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002301 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002302 // Call outside parameter locks to allow re-entrancy from notification
2303 Mutex::Autolock iccl(mICameraClientLock);
2304 if (mCameraClient != 0) {
2305 mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
2306 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002307 }
2308}
2309
2310void Camera2Client::onRecordingFrameAvailable() {
2311 ATRACE_CALL();
2312 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002313 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002314 size_t heapIdx = 0;
2315 nsecs_t timestamp;
2316 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002317 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002318
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002319 BufferItemConsumer::BufferItem imgBuffer;
2320 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002321 if (res != OK) {
2322 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2323 __FUNCTION__, mCameraId, strerror(-res), res);
2324 return;
2325 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002326 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002327
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002328 mRecordingFrameCount++;
2329 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
2330
2331 // TODO: Signal errors here upstream
2332 if (k.mParameters.state != RECORD &&
2333 k.mParameters.state != VIDEO_SNAPSHOT) {
2334 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2335 "recording done",
2336 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002337 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002338 return;
2339 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002340
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002341 if (mRecordingHeap == 0) {
2342 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002343 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2344 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002345 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002346
James Dong983cf232012-08-01 16:39:55 -07002347 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002348 "Camera2Client::RecordingHeap");
2349 if (mRecordingHeap->mHeap->getSize() == 0) {
2350 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2351 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002352 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002353 return;
2354 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002355 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
2356 if (mRecordingBuffers[i].mBuf !=
2357 BufferItemConsumer::INVALID_BUFFER_SLOT) {
2358 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
2359 __FUNCTION__, mCameraId);
2360 }
2361 }
2362 mRecordingBuffers.clear();
2363 mRecordingBuffers.setCapacity(mRecordingHeapCount);
2364 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
2365
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002366 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002367 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002368 }
2369
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002370 if ( mRecordingHeapFree == 0) {
2371 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2372 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002373 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002374 return;
2375 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002376
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002377 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002378 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002379 mRecordingHeapFree--;
2380
2381 ALOGV("%s: Camera %d: Timestamp %lld",
2382 __FUNCTION__, mCameraId, timestamp);
2383
2384 ssize_t offset;
2385 size_t size;
2386 sp<IMemoryHeap> heap =
2387 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2388 &size);
2389
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002390 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2391 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002392 *((uint32_t*)data) = type;
2393 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002394 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002395 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
2396 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002397 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002398 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002399
2400 // Call outside locked parameters to allow re-entrancy from notification
2401 Mutex::Autolock iccl(mICameraClientLock);
2402 if (mCameraClient != 0) {
2403 mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002404 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002405 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002406 }
2407}
2408
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002409camera_metadata_ro_entry_t Camera2Client::staticInfo(uint32_t tag,
2410 size_t minCount, size_t maxCount) const {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002411 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002412 camera_metadata_ro_entry_t entry = mDevice->info().find(tag);
2413
2414 if (CC_UNLIKELY( entry.count == 0 )) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002415 const char* tagSection = get_camera_metadata_section_name(tag);
2416 if (tagSection == NULL) tagSection = "<unknown>";
2417 const char* tagName = get_camera_metadata_tag_name(tag);
2418 if (tagName == NULL) tagName = "<unknown>";
2419
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002420 ALOGE("Error finding static metadata entry '%s.%s' (%x)",
2421 tagSection, tagName, tag);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002422 } else if (CC_UNLIKELY(
2423 (minCount != 0 && entry.count < minCount) ||
2424 (maxCount != 0 && entry.count > maxCount) ) ) {
2425 const char* tagSection = get_camera_metadata_section_name(tag);
2426 if (tagSection == NULL) tagSection = "<unknown>";
2427 const char* tagName = get_camera_metadata_tag_name(tag);
2428 if (tagName == NULL) tagName = "<unknown>";
2429 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2430 "Expected between %d and %d values, but got %d values",
2431 tagSection, tagName, tag, minCount, maxCount, entry.count);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002432 }
2433
2434 return entry;
2435}
2436
2437/** Utility methods */
2438
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002439status_t Camera2Client::buildDeviceInfo() {
2440 if (mDeviceInfo != NULL) {
2441 delete mDeviceInfo;
2442 }
2443 DeviceInfo *deviceInfo = new DeviceInfo;
2444 mDeviceInfo = deviceInfo;
2445
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002446 camera_metadata_ro_entry_t activeArraySize =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002447 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2448 if (!activeArraySize.count) return NO_INIT;
2449 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2450 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2451
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002452 camera_metadata_ro_entry_t availableFaceDetectModes =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002453 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2454 if (!availableFaceDetectModes.count) return NO_INIT;
2455
2456 deviceInfo->bestFaceDetectMode =
2457 ANDROID_STATS_FACE_DETECTION_OFF;
2458 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2459 switch (availableFaceDetectModes.data.u8[i]) {
2460 case ANDROID_STATS_FACE_DETECTION_OFF:
2461 break;
2462 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2463 if (deviceInfo->bestFaceDetectMode !=
2464 ANDROID_STATS_FACE_DETECTION_FULL) {
2465 deviceInfo->bestFaceDetectMode =
2466 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2467 }
2468 break;
2469 case ANDROID_STATS_FACE_DETECTION_FULL:
2470 deviceInfo->bestFaceDetectMode =
2471 ANDROID_STATS_FACE_DETECTION_FULL;
2472 break;
2473 default:
2474 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2475 __FUNCTION__, mCameraId,
2476 availableFaceDetectModes.data.u8[i]);
2477 return NO_INIT;
2478 }
2479 }
2480
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002481 camera_metadata_ro_entry_t maxFacesDetected =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002482 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2483 if (!maxFacesDetected.count) return NO_INIT;
2484
2485 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2486
2487 return OK;
2488}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002489
2490status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002491 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002492 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002493
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002494 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002495 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002496
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002497 camera_metadata_ro_entry_t availableProcessedSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002498 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2499 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002500
2501 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002502 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2503 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2504 k.mParameters.videoWidth = k.mParameters.previewWidth;
2505 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002506
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002507 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2508 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002509 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2510 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002511 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002512 {
2513 String8 supportedPreviewSizes;
2514 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2515 if (i != 0) supportedPreviewSizes += ",";
2516 supportedPreviewSizes += String8::format("%dx%d",
2517 availableProcessedSizes.data.i32[i],
2518 availableProcessedSizes.data.i32[i+1]);
2519 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002520 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002521 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002522 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002523 supportedPreviewSizes);
2524 }
2525
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002526 camera_metadata_ro_entry_t availableFpsRanges =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002527 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2528 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002529
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002530 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2531 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002532
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002533 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2534 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002535 k.mParameters.previewFpsRange[0],
2536 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002537
2538 {
2539 String8 supportedPreviewFpsRange;
2540 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2541 if (i != 0) supportedPreviewFpsRange += ",";
2542 supportedPreviewFpsRange += String8::format("(%d,%d)",
2543 availableFpsRanges.data.i32[i],
2544 availableFpsRanges.data.i32[i+1]);
2545 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002546 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002547 supportedPreviewFpsRange);
2548 }
2549
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002550 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002551 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002552 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002553
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002554 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002555 mCameraFacing == CAMERA_FACING_FRONT);
2556
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002557 camera_metadata_ro_entry_t availableFormats =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002558 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2559
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002560 {
2561 String8 supportedPreviewFormats;
2562 bool addComma = false;
2563 for (size_t i=0; i < availableFormats.count; i++) {
2564 if (addComma) supportedPreviewFormats += ",";
2565 addComma = true;
2566 switch (availableFormats.data.i32[i]) {
2567 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002568 supportedPreviewFormats +=
2569 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002570 break;
2571 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002572 supportedPreviewFormats +=
2573 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002574 break;
2575 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002576 supportedPreviewFormats +=
2577 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002578 break;
2579 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002580 supportedPreviewFormats +=
2581 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002582 break;
2583 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002584 supportedPreviewFormats +=
2585 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002586 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002587 case HAL_PIXEL_FORMAT_RGBA_8888:
2588 supportedPreviewFormats +=
2589 CameraParameters::PIXEL_FORMAT_RGBA8888;
2590 break;
2591 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002592 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002593 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002594 addComma = false;
2595 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002596
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002597 default:
2598 ALOGW("%s: Camera %d: Unknown preview format: %x",
2599 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2600 addComma = false;
2601 break;
2602 }
2603 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002604 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002605 supportedPreviewFormats);
2606 }
2607
2608 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2609 // still have to do something sane for them
2610
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002611 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002612 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002613
2614 {
2615 String8 supportedPreviewFrameRates;
2616 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2617 if (i != 0) supportedPreviewFrameRates += ",";
2618 supportedPreviewFrameRates += String8::format("%d",
2619 availableFpsRanges.data.i32[i]);
2620 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002621 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002622 supportedPreviewFrameRates);
2623 }
2624
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002625 camera_metadata_ro_entry_t availableJpegSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002626 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2627 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002628
2629 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002630 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2631 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002632
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002633 params.setPictureSize(k.mParameters.pictureWidth,
2634 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002635
2636 {
2637 String8 supportedPictureSizes;
2638 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2639 if (i != 0) supportedPictureSizes += ",";
2640 supportedPictureSizes += String8::format("%dx%d",
2641 availableJpegSizes.data.i32[i],
2642 availableJpegSizes.data.i32[i+1]);
2643 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002644 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002645 supportedPictureSizes);
2646 }
2647
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002648 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2649 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2650 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002651
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002652 camera_metadata_ro_entry_t availableJpegThumbnailSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002653 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2654 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002655
2656 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002657 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2658 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002659
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002660 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002661 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002662 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002663 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002664
2665 {
2666 String8 supportedJpegThumbSizes;
2667 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2668 if (i != 0) supportedJpegThumbSizes += ",";
2669 supportedJpegThumbSizes += String8::format("%dx%d",
2670 availableJpegThumbnailSizes.data.i32[i],
2671 availableJpegThumbnailSizes.data.i32[i+1]);
2672 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002673 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002674 supportedJpegThumbSizes);
2675 }
2676
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002677 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002678 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002679 k.mParameters.jpegThumbQuality);
2680 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002681 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002682 k.mParameters.jpegQuality);
2683 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002684 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002685 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002686
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002687 k.mParameters.gpsEnabled = false;
2688 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002689 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002690
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002691 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002692 params.set(CameraParameters::KEY_WHITE_BALANCE,
2693 CameraParameters::WHITE_BALANCE_AUTO);
2694
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002695 camera_metadata_ro_entry_t availableWhiteBalanceModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002696 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002697 {
2698 String8 supportedWhiteBalance;
2699 bool addComma = false;
2700 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2701 if (addComma) supportedWhiteBalance += ",";
2702 addComma = true;
2703 switch (availableWhiteBalanceModes.data.u8[i]) {
2704 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002705 supportedWhiteBalance +=
2706 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002707 break;
2708 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002709 supportedWhiteBalance +=
2710 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002711 break;
2712 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002713 supportedWhiteBalance +=
2714 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002715 break;
2716 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002717 supportedWhiteBalance +=
2718 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002719 break;
2720 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002721 supportedWhiteBalance +=
2722 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002723 break;
2724 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002725 supportedWhiteBalance +=
2726 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002727 break;
2728 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002729 supportedWhiteBalance +=
2730 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002731 break;
2732 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002733 supportedWhiteBalance +=
2734 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002735 break;
2736 // Skipping values not mappable to v1 API
2737 case ANDROID_CONTROL_AWB_OFF:
2738 addComma = false;
2739 break;
2740 default:
2741 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2742 __FUNCTION__, mCameraId,
2743 availableWhiteBalanceModes.data.u8[i]);
2744 addComma = false;
2745 break;
2746 }
2747 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002748 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002749 supportedWhiteBalance);
2750 }
2751
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002752 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002753 params.set(CameraParameters::KEY_EFFECT,
2754 CameraParameters::EFFECT_NONE);
2755
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002756 camera_metadata_ro_entry_t availableEffects =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002757 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2758 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002759 {
2760 String8 supportedEffects;
2761 bool addComma = false;
2762 for (size_t i=0; i < availableEffects.count; i++) {
2763 if (addComma) supportedEffects += ",";
2764 addComma = true;
2765 switch (availableEffects.data.u8[i]) {
2766 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002767 supportedEffects +=
2768 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002769 break;
2770 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002771 supportedEffects +=
2772 CameraParameters::EFFECT_MONO;
2773 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002774 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002775 supportedEffects +=
2776 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002777 break;
2778 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002779 supportedEffects +=
2780 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002781 break;
2782 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002783 supportedEffects +=
2784 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002785 break;
2786 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002787 supportedEffects +=
2788 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002789 break;
2790 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002791 supportedEffects +=
2792 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002793 break;
2794 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002795 supportedEffects +=
2796 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002797 break;
2798 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002799 supportedEffects +=
2800 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002801 break;
2802 default:
2803 ALOGW("%s: Camera %d: Unknown effect value: %d",
2804 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2805 addComma = false;
2806 break;
2807 }
2808 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002809 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002810 }
2811
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002812 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002813 params.set(CameraParameters::KEY_ANTIBANDING,
2814 CameraParameters::ANTIBANDING_AUTO);
2815
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002816 camera_metadata_ro_entry_t availableAntibandingModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002817 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2818 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002819 {
2820 String8 supportedAntibanding;
2821 bool addComma = false;
2822 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2823 if (addComma) supportedAntibanding += ",";
2824 addComma = true;
2825 switch (availableAntibandingModes.data.u8[i]) {
2826 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002827 supportedAntibanding +=
2828 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002829 break;
2830 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002831 supportedAntibanding +=
2832 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002833 break;
2834 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002835 supportedAntibanding +=
2836 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002837 break;
2838 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002839 supportedAntibanding +=
2840 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002841 break;
2842 default:
2843 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2844 __FUNCTION__, mCameraId,
2845 availableAntibandingModes.data.u8[i]);
2846 addComma = false;
2847 break;
2848 }
2849 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002850 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002851 supportedAntibanding);
2852 }
2853
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002854 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002855 params.set(CameraParameters::KEY_SCENE_MODE,
2856 CameraParameters::SCENE_MODE_AUTO);
2857
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002858 camera_metadata_ro_entry_t availableSceneModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002859 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2860 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002861 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002862 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002863 bool addComma = true;
2864 bool noSceneModes = false;
2865 for (size_t i=0; i < availableSceneModes.count; i++) {
2866 if (addComma) supportedSceneModes += ",";
2867 addComma = true;
2868 switch (availableSceneModes.data.u8[i]) {
2869 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2870 noSceneModes = true;
2871 break;
2872 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2873 // Not in old API
2874 addComma = false;
2875 break;
2876 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002877 supportedSceneModes +=
2878 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002879 break;
2880 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002881 supportedSceneModes +=
2882 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002883 break;
2884 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002885 supportedSceneModes +=
2886 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002887 break;
2888 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002889 supportedSceneModes +=
2890 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002891 break;
2892 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002893 supportedSceneModes +=
2894 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002895 break;
2896 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002897 supportedSceneModes +=
2898 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002899 break;
2900 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002901 supportedSceneModes +=
2902 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002903 break;
2904 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002905 supportedSceneModes +=
2906 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002907 break;
2908 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002909 supportedSceneModes +=
2910 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002911 break;
2912 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002913 supportedSceneModes +=
2914 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002915 break;
2916 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002917 supportedSceneModes +=
2918 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002919 break;
2920 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002921 supportedSceneModes +=
2922 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002923 break;
2924 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002925 supportedSceneModes +=
2926 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002927 break;
2928 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002929 supportedSceneModes +=
2930 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002931 break;
2932 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002933 supportedSceneModes +=
2934 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002935 break;
2936 default:
2937 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002938 __FUNCTION__, mCameraId,
2939 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002940 addComma = false;
2941 break;
2942 }
2943 }
2944 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002945 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002946 supportedSceneModes);
2947 }
2948 }
2949
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002950 camera_metadata_ro_entry_t flashAvailable =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002951 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2952 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002953
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002954 camera_metadata_ro_entry_t availableAeModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002955 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2956 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002957
2958 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002959 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002960 params.set(CameraParameters::KEY_FLASH_MODE,
2961 CameraParameters::FLASH_MODE_AUTO);
2962
2963 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2964 supportedFlashModes = supportedFlashModes +
2965 "," + CameraParameters::FLASH_MODE_AUTO +
2966 "," + CameraParameters::FLASH_MODE_ON +
2967 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002968 for (size_t i=0; i < availableAeModes.count; i++) {
2969 if (availableAeModes.data.u8[i] ==
2970 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002971 supportedFlashModes = supportedFlashModes + "," +
2972 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002973 break;
2974 }
2975 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002976 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002977 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002978 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002979 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002980 params.set(CameraParameters::KEY_FLASH_MODE,
2981 CameraParameters::FLASH_MODE_OFF);
2982 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2983 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002984 }
2985
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002986 camera_metadata_ro_entry_t minFocusDistance =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002987 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2988 if (!minFocusDistance.count) return NO_INIT;
2989
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002990 camera_metadata_ro_entry_t availableAfModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002991 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2992 if (!availableAfModes.count) return NO_INIT;
2993
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002994 if (minFocusDistance.data.f[0] == 0) {
2995 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002996 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002997 params.set(CameraParameters::KEY_FOCUS_MODE,
2998 CameraParameters::FOCUS_MODE_FIXED);
2999 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
3000 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003001 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003002 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003003 params.set(CameraParameters::KEY_FOCUS_MODE,
3004 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003005 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003006 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003007
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003008 for (size_t i=0; i < availableAfModes.count; i++) {
3009 if (addComma) supportedFocusModes += ",";
3010 addComma = true;
3011 switch (availableAfModes.data.u8[i]) {
3012 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003013 supportedFocusModes +=
3014 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003015 break;
3016 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003017 supportedFocusModes +=
3018 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003019 break;
3020 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003021 supportedFocusModes +=
3022 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003023 break;
3024 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003025 supportedFocusModes +=
3026 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003027 break;
3028 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003029 supportedFocusModes +=
3030 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003031 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003032 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003033 case ANDROID_CONTROL_AF_OFF:
3034 addComma = false;
3035 break;
3036 default:
3037 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
3038 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
3039 addComma = false;
3040 break;
3041 }
3042 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003043 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003044 supportedFocusModes);
3045 }
3046
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003047 camera_metadata_ro_entry_t max3aRegions =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003048 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
3049 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003050
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003051 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003052 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003053 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003054 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003055 k.mParameters.focusingAreas.clear();
3056 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003057
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003058 camera_metadata_ro_entry_t availableFocalLengths =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003059 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
3060 if (!availableFocalLengths.count) return NO_INIT;
3061
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003062 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003063 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003064
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003065 camera_metadata_ro_entry_t sensorSize =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003066 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
3067 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003068
3069 // The fields of view here assume infinity focus, maximum wide angle
3070 float horizFov = 180 / M_PI *
3071 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
3072 float vertFov = 180 / M_PI *
3073 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003074 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
3075 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003076
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003077 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003078 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003079 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003080
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003081 camera_metadata_ro_entry_t exposureCompensationRange =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003082 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
3083 if (!exposureCompensationRange.count) return NO_INIT;
3084
3085 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003086 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003087 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003088 exposureCompensationRange.data.i32[0]);
3089
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003090 camera_metadata_ro_entry_t exposureCompensationStep =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003091 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
3092 if (!exposureCompensationStep.count) return NO_INIT;
3093
3094 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07003095 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003096 exposureCompensationStep.data.r[0].denominator);
3097
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003098 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003099 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
3100 CameraParameters::FALSE);
3101 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
3102 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003103
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003104 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003105 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
3106 CameraParameters::FALSE);
3107 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
3108 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003109
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003110 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003111 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003112 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003113 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003114 "(0,0,0,0,0)");
3115
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003116 k.mParameters.zoom = 0;
3117 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003118 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003119
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003120 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003121 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
3122 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003123
3124 {
3125 String8 zoomRatios;
3126 float zoom = 1.f;
3127 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003128 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003129 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003130 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003131 if (addComma) zoomRatios += ",";
3132 addComma = true;
3133 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
3134 zoom += zoomIncrement;
3135 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003136 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003137 }
3138
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003139 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
3140 CameraParameters::TRUE);
3141 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
3142 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003143
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003144 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003145 "Infinity,Infinity,Infinity");
3146
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003147 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003148 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003149 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003150 0);
3151
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003152 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003153 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003154
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003155 params.set(CameraParameters::KEY_RECORDING_HINT,
3156 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003157
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003158 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
3159 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003160
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003161 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
3162 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003163
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003164 camera_metadata_ro_entry_t availableVideoStabilizationModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003165 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
3166 if (!availableVideoStabilizationModes.count) return NO_INIT;
3167
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003168 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003169 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3170 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003171 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003172 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3173 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003174 }
3175
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003176 // Set up initial state for non-Camera.Parameters state variables
3177
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003178 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003179 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003180 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003181
3182 k.mParameters.enableFocusMoveMessages = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003183 k.mParameters.afTriggerCounter = 0;
3184 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003185
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003186 k.mParameters.previewCallbackFlags = 0;
3187
3188 k.mParameters.state = STOPPED;
3189
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003190 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003191
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003192 return OK;
3193}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003194
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003195status_t Camera2Client::updateRequests(const Parameters &params) {
3196 status_t res;
3197
3198 res = updatePreviewRequest(params);
3199 if (res != OK) {
3200 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
3201 __FUNCTION__, mCameraId, strerror(-res), res);
3202 return res;
3203 }
3204 res = updateCaptureRequest(params);
3205 if (res != OK) {
3206 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
3207 __FUNCTION__, mCameraId, strerror(-res), res);
3208 return res;
3209 }
3210
3211 res = updateRecordingRequest(params);
3212 if (res != OK) {
3213 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
3214 __FUNCTION__, mCameraId, strerror(-res), res);
3215 return res;
3216 }
3217
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003218 if (params.state == PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003219 res = mDevice->setStreamingRequest(mPreviewRequest);
3220 if (res != OK) {
3221 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
3222 __FUNCTION__, mCameraId, strerror(-res), res);
3223 return res;
3224 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003225 } else if (params.state == RECORD || params.state == VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003226 res = mDevice->setStreamingRequest(mRecordingRequest);
3227 if (res != OK) {
3228 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
3229 __FUNCTION__, mCameraId, strerror(-res), res);
3230 return res;
3231 }
3232 }
3233 return res;
3234}
3235
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003236status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003237 ATRACE_CALL();
3238 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003239
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003240 if (mPreviewStreamId != NO_STREAM) {
3241 // Check if stream parameters have to change
3242 uint32_t currentWidth, currentHeight;
3243 res = mDevice->getStreamInfo(mPreviewStreamId,
3244 &currentWidth, &currentHeight, 0);
3245 if (res != OK) {
3246 ALOGE("%s: Camera %d: Error querying preview stream info: "
3247 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3248 return res;
3249 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003250 if (currentWidth != (uint32_t)params.previewWidth ||
3251 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07003252 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
3253 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003254 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003255 res = mDevice->waitUntilDrained();
3256 if (res != OK) {
3257 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
3258 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3259 return res;
3260 }
3261 res = mDevice->deleteStream(mPreviewStreamId);
3262 if (res != OK) {
3263 ALOGE("%s: Camera %d: Unable to delete old output stream "
3264 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3265 strerror(-res), res);
3266 return res;
3267 }
3268 mPreviewStreamId = NO_STREAM;
3269 }
3270 }
3271
3272 if (mPreviewStreamId == NO_STREAM) {
3273 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003274 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003275 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3276 &mPreviewStreamId);
3277 if (res != OK) {
3278 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3279 __FUNCTION__, mCameraId, strerror(-res), res);
3280 return res;
3281 }
3282 }
3283
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003284 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003285 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003286 if (res != OK) {
3287 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3288 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3289 return res;
3290 }
3291
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003292 return OK;
3293}
3294
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003295status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003296 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003297 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003298 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003299 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3300 &mPreviewRequest);
3301 if (res != OK) {
3302 ALOGE("%s: Camera %d: Unable to create default preview request: "
3303 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3304 return res;
3305 }
3306 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003307
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003308 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003309 if (res != OK) {
3310 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3311 "request: %s (%d)", __FUNCTION__, mCameraId,
3312 strerror(-res), res);
3313 return res;
3314 }
3315
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003316 return OK;
3317}
3318
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003319status_t Camera2Client::updateCallbackStream(const Parameters &params) {
3320 status_t res;
3321
3322 if (mCallbackConsumer == 0) {
3323 // Create CPU buffer queue endpoint
3324 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
3325 mCallbackWaiter = new CallbackWaiter(this);
3326 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
3327 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
3328 mCallbackWindow = new SurfaceTextureClient(
3329 mCallbackConsumer->getProducerInterface());
3330 }
3331
3332 if (mCallbackStreamId != NO_STREAM) {
3333 // Check if stream parameters have to change
3334 uint32_t currentWidth, currentHeight, currentFormat;
3335 res = mDevice->getStreamInfo(mCallbackStreamId,
3336 &currentWidth, &currentHeight, &currentFormat);
3337 if (res != OK) {
3338 ALOGE("%s: Camera %d: Error querying callback output stream info: "
3339 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3340 return res;
3341 }
3342 if (currentWidth != (uint32_t)params.previewWidth ||
3343 currentHeight != (uint32_t)params.previewHeight ||
3344 currentFormat != (uint32_t)params.previewFormat) {
3345 // Since size should only change while preview is not running,
3346 // assuming that all existing use of old callback stream is
3347 // completed.
3348 res = mDevice->deleteStream(mCallbackStreamId);
3349 if (res != OK) {
3350 ALOGE("%s: Camera %d: Unable to delete old output stream "
3351 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
3352 strerror(-res), res);
3353 return res;
3354 }
3355 mCallbackStreamId = NO_STREAM;
3356 }
3357 }
3358
3359 if (mCallbackStreamId == NO_STREAM) {
3360 ALOGV("Creating callback stream: %d %d format 0x%x",
3361 params.previewWidth, params.previewHeight,
3362 params.previewFormat);
3363 res = mDevice->createStream(mCallbackWindow,
3364 params.previewWidth, params.previewHeight,
3365 params.previewFormat, 0, &mCallbackStreamId);
3366 if (res != OK) {
3367 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
3368 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3369 return res;
3370 }
3371 }
3372
3373 return OK;
3374}
3375
3376
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003377status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003378 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003379 status_t res;
3380 // Find out buffer size for JPEG
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003381 camera_metadata_ro_entry_t maxJpegSize =
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003382 staticInfo(ANDROID_JPEG_MAX_SIZE);
3383 if (maxJpegSize.count == 0) {
3384 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3385 __FUNCTION__, mCameraId);
3386 return INVALID_OPERATION;
3387 }
3388
3389 if (mCaptureConsumer == 0) {
3390 // Create CPU buffer queue endpoint
3391 mCaptureConsumer = new CpuConsumer(1);
3392 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3393 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3394 mCaptureWindow = new SurfaceTextureClient(
3395 mCaptureConsumer->getProducerInterface());
3396 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003397 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3398 "Camera2Client::CaptureHeap");
3399 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003400 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3401 __FUNCTION__, mCameraId);
3402 return NO_MEMORY;
3403 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003404 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003405
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003406 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003407 // Check if stream parameters have to change
3408 uint32_t currentWidth, currentHeight;
3409 res = mDevice->getStreamInfo(mCaptureStreamId,
3410 &currentWidth, &currentHeight, 0);
3411 if (res != OK) {
3412 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3413 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3414 return res;
3415 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003416 if (currentWidth != (uint32_t)params.pictureWidth ||
3417 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003418 res = mDevice->deleteStream(mCaptureStreamId);
3419 if (res != OK) {
3420 ALOGE("%s: Camera %d: Unable to delete old output stream "
3421 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3422 strerror(-res), res);
3423 return res;
3424 }
3425 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003426 }
3427 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003428
3429 if (mCaptureStreamId == NO_STREAM) {
3430 // Create stream for HAL production
3431 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003432 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003433 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3434 &mCaptureStreamId);
3435 if (res != OK) {
3436 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3437 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3438 return res;
3439 }
3440
3441 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003442 return OK;
3443}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003444
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003445status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003446 ATRACE_CALL();
3447 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003448 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003449 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3450 &mCaptureRequest);
3451 if (res != OK) {
3452 ALOGE("%s: Camera %d: Unable to create default still image request:"
3453 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3454 return res;
3455 }
3456 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003457
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003458 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003459 if (res != OK) {
3460 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3461 "request: %s (%d)", __FUNCTION__, mCameraId,
3462 strerror(-res), res);
3463 return res;
3464 }
3465
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003466 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003467 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003468 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003469 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003470 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003471 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003472 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003473 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003474 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003475 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003476 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003477 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003478 if (res != OK) return res;
3479
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003480 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003481 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003482 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003483 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003484 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003485 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003486 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003487 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003488 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003489 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003490 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003491 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003492 if (res != OK) return res;
3493 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003494 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003495 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003496 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003497 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003498 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003499 if (res != OK) return res;
3500 }
3501
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003502 return OK;
3503}
3504
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003505status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003506 ATRACE_CALL();
3507 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003508 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003509 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3510 &mRecordingRequest);
3511 if (res != OK) {
3512 ALOGE("%s: Camera %d: Unable to create default recording request:"
3513 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3514 return res;
3515 }
3516 }
3517
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003518 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003519 if (res != OK) {
3520 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3521 "request: %s (%d)", __FUNCTION__, mCameraId,
3522 strerror(-res), res);
3523 return res;
3524 }
3525
3526 return OK;
3527}
3528
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003529status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003530 status_t res;
3531
3532 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003533 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
3534 // always acquire and free a buffer when the heap is full; otherwise the consumer
3535 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07003536 mRecordingConsumer = new BufferItemConsumer(
3537 GRALLOC_USAGE_HW_VIDEO_ENCODER,
3538 mRecordingHeapCount + 1,
3539 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003540 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3541 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3542 mRecordingWindow = new SurfaceTextureClient(
3543 mRecordingConsumer->getProducerInterface());
3544 // Allocate memory later, since we don't know buffer size until receipt
3545 }
3546
3547 if (mRecordingStreamId != NO_STREAM) {
3548 // Check if stream parameters have to change
3549 uint32_t currentWidth, currentHeight;
3550 res = mDevice->getStreamInfo(mRecordingStreamId,
3551 &currentWidth, &currentHeight, 0);
3552 if (res != OK) {
3553 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3554 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3555 return res;
3556 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003557 if (currentWidth != (uint32_t)params.videoWidth ||
3558 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003559 // TODO: Should wait to be sure previous recording has finished
3560 res = mDevice->deleteStream(mRecordingStreamId);
3561 if (res != OK) {
3562 ALOGE("%s: Camera %d: Unable to delete old output stream "
3563 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3564 strerror(-res), res);
3565 return res;
3566 }
3567 mRecordingStreamId = NO_STREAM;
3568 }
3569 }
3570
3571 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003572 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003573 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003574 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003575 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003576 if (res != OK) {
3577 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3578 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3579 return res;
3580 }
3581 }
3582
3583 return OK;
3584}
3585
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003586status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003587 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003588 ATRACE_CALL();
3589 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003590 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
3591 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003592 if (res != OK) return res;
3593
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003594 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003595 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
3596 res = request->update(ANDROID_CONTROL_AWB_MODE,
3597 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003598 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003599 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
3600 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003601 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003602 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003603 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003604 if (res != OK) return res;
3605
3606 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003607 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003608 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003609 res = request->update(ANDROID_CONTROL_MODE,
3610 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003611 if (res != OK) return res;
3612 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003613 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003614 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003615 if (res != OK) return res;
3616 }
3617
3618 uint8_t flashMode = ANDROID_FLASH_OFF;
3619 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003620 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003621 case Parameters::FLASH_MODE_OFF:
3622 aeMode = ANDROID_CONTROL_AE_ON; break;
3623 case Parameters::FLASH_MODE_AUTO:
3624 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3625 case Parameters::FLASH_MODE_ON:
3626 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3627 case Parameters::FLASH_MODE_TORCH:
3628 aeMode = ANDROID_CONTROL_AE_ON;
3629 flashMode = ANDROID_FLASH_TORCH;
3630 break;
3631 case Parameters::FLASH_MODE_RED_EYE:
3632 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3633 default:
3634 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003635 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003636 return BAD_VALUE;
3637 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003638 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003639
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003640 res = request->update(ANDROID_FLASH_MODE,
3641 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003642 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003643 res = request->update(ANDROID_CONTROL_AE_MODE,
3644 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003645 if (res != OK) return res;
3646
3647 float focusDistance = 0; // infinity focus in diopters
3648 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003649 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003650 case Parameters::FOCUS_MODE_AUTO:
3651 case Parameters::FOCUS_MODE_MACRO:
3652 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3653 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3654 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003655 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003656 break;
3657 case Parameters::FOCUS_MODE_INFINITY:
3658 case Parameters::FOCUS_MODE_FIXED:
3659 focusMode = ANDROID_CONTROL_AF_OFF;
3660 break;
3661 default:
3662 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003663 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003664 return BAD_VALUE;
3665 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003666 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
3667 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003668 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003669 res = request->update(ANDROID_CONTROL_AF_MODE,
3670 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003671 if (res != OK) return res;
3672
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003673 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003674 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3675 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003676 focusingAreas[i + 0] = params.focusingAreas[i].left;
3677 focusingAreas[i + 1] = params.focusingAreas[i].top;
3678 focusingAreas[i + 2] = params.focusingAreas[i].right;
3679 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3680 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003681 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003682 res = request->update(ANDROID_CONTROL_AF_REGIONS,
3683 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003684 if (res != OK) return res;
3685 delete[] focusingAreas;
3686
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003687 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003688 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003689 if (res != OK) return res;
3690
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003691 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003692 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3693 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003694 meteringAreas[i + 0] = params.meteringAreas[i].left;
3695 meteringAreas[i + 1] = params.meteringAreas[i].top;
3696 meteringAreas[i + 2] = params.meteringAreas[i].right;
3697 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3698 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003699 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003700 res = request->update(ANDROID_CONTROL_AE_REGIONS,
3701 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003702 if (res != OK) return res;
3703
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003704 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
3705 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003706 if (res != OK) return res;
3707 delete[] meteringAreas;
3708
3709 // Need to convert zoom index into a crop rectangle. The rectangle is
3710 // chosen to maximize its area on the sensor
3711
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003712 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003713 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3714 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3715 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003716 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003717
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003718 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003719 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003720 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003721 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003722 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003723 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003724 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003725 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003726 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003727 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003728 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3729 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003730
3731 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003732 res = request->update(ANDROID_SCALER_CROP_REGION,
3733 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003734 if (res != OK) return res;
3735
3736 // TODO: Decide how to map recordingHint, or whether just to ignore it
3737
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003738 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003739 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3740 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003741 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003742 &vstabMode, 1);
3743 if (res != OK) return res;
3744
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003745 uint8_t faceDetectMode = params.enableFaceDetect ?
3746 mDeviceInfo->bestFaceDetectMode :
3747 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003748 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003749 &faceDetectMode, 1);
3750 if (res != OK) return res;
3751
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003752 return OK;
3753}
3754
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003755int Camera2Client::arrayXToNormalized(int width) const {
3756 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3757}
3758
3759int Camera2Client::arrayYToNormalized(int height) const {
3760 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3761}
3762
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003763int Camera2Client::formatStringToEnum(const char *format) {
3764 return
3765 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3766 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3767 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3768 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3769 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3770 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3771 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3772 HAL_PIXEL_FORMAT_YV12 : // YV12
3773 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3774 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3775 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3776 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3777 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3778 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3779 -1;
3780}
3781
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003782const char* Camera2Client::formatEnumToString(int format) {
3783 const char *fmt;
3784 switch(format) {
3785 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3786 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3787 break;
3788 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3789 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3790 break;
3791 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3792 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3793 break;
3794 case HAL_PIXEL_FORMAT_YV12: // YV12
3795 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3796 break;
3797 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3798 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3799 break;
3800 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3801 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3802 break;
3803 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3804 ALOGW("Raw sensor preview format requested.");
3805 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3806 break;
3807 default:
3808 ALOGE("%s: Unknown preview format: %x",
3809 __FUNCTION__, format);
3810 fmt = NULL;
3811 break;
3812 }
3813 return fmt;
3814}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003815
3816int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3817 return
3818 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3819 ANDROID_CONTROL_AWB_AUTO :
3820 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3821 ANDROID_CONTROL_AWB_INCANDESCENT :
3822 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3823 ANDROID_CONTROL_AWB_FLUORESCENT :
3824 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3825 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3826 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3827 ANDROID_CONTROL_AWB_DAYLIGHT :
3828 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3829 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3830 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3831 ANDROID_CONTROL_AWB_TWILIGHT :
3832 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3833 ANDROID_CONTROL_AWB_SHADE :
3834 -1;
3835}
3836
3837int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3838 return
3839 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3840 ANDROID_CONTROL_EFFECT_OFF :
3841 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3842 ANDROID_CONTROL_EFFECT_MONO :
3843 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3844 ANDROID_CONTROL_EFFECT_NEGATIVE :
3845 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3846 ANDROID_CONTROL_EFFECT_SOLARIZE :
3847 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3848 ANDROID_CONTROL_EFFECT_SEPIA :
3849 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3850 ANDROID_CONTROL_EFFECT_POSTERIZE :
3851 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3852 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3853 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3854 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3855 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3856 ANDROID_CONTROL_EFFECT_AQUA :
3857 -1;
3858}
3859
3860int Camera2Client::abModeStringToEnum(const char *abMode) {
3861 return
3862 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3863 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3864 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3865 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3866 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3867 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3868 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3869 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3870 -1;
3871}
3872
3873int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3874 return
3875 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3876 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3877 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3878 ANDROID_CONTROL_SCENE_MODE_ACTION :
3879 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3880 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3881 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3882 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3883 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3884 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3885 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3886 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3887 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3888 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3889 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3890 ANDROID_CONTROL_SCENE_MODE_BEACH :
3891 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3892 ANDROID_CONTROL_SCENE_MODE_SNOW :
3893 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3894 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3895 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3896 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3897 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3898 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3899 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3900 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3901 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3902 ANDROID_CONTROL_SCENE_MODE_PARTY :
3903 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3904 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3905 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3906 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3907 -1;
3908}
3909
3910Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3911 const char *flashMode) {
3912 return
3913 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3914 Parameters::FLASH_MODE_OFF :
3915 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3916 Parameters::FLASH_MODE_AUTO :
3917 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3918 Parameters::FLASH_MODE_ON :
3919 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3920 Parameters::FLASH_MODE_RED_EYE :
3921 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3922 Parameters::FLASH_MODE_TORCH :
3923 Parameters::FLASH_MODE_INVALID;
3924}
3925
3926Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3927 const char *focusMode) {
3928 return
3929 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3930 Parameters::FOCUS_MODE_AUTO :
3931 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3932 Parameters::FOCUS_MODE_INFINITY :
3933 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3934 Parameters::FOCUS_MODE_MACRO :
3935 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3936 Parameters::FOCUS_MODE_FIXED :
3937 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3938 Parameters::FOCUS_MODE_EDOF :
3939 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3940 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3941 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3942 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3943 Parameters::FOCUS_MODE_INVALID;
3944}
3945
3946status_t Camera2Client::parseAreas(const char *areasCStr,
3947 Vector<Parameters::Area> *areas) {
3948 static const size_t NUM_FIELDS = 5;
3949 areas->clear();
3950 if (areasCStr == NULL) {
3951 // If no key exists, use default (0,0,0,0,0)
3952 areas->push();
3953 return OK;
3954 }
3955 String8 areasStr(areasCStr);
3956 ssize_t areaStart = areasStr.find("(", 0) + 1;
3957 while (areaStart != 0) {
3958 const char* area = areasStr.string() + areaStart;
3959 char *numEnd;
3960 int vals[NUM_FIELDS];
3961 for (size_t i = 0; i < NUM_FIELDS; i++) {
3962 errno = 0;
3963 vals[i] = strtol(area, &numEnd, 10);
3964 if (errno || numEnd == area) return BAD_VALUE;
3965 area = numEnd + 1;
3966 }
3967 areas->push(Parameters::Area(
3968 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3969 areaStart = areasStr.find("(", areaStart) + 1;
3970 }
3971 return OK;
3972}
3973
3974status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3975 size_t maxRegions) {
3976 // Definition of valid area can be found in
3977 // include/camera/CameraParameters.h
3978 if (areas.size() == 0) return BAD_VALUE;
3979 if (areas.size() == 1) {
3980 if (areas[0].left == 0 &&
3981 areas[0].top == 0 &&
3982 areas[0].right == 0 &&
3983 areas[0].bottom == 0 &&
3984 areas[0].weight == 0) {
3985 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3986 return OK;
3987 }
3988 }
3989 if (areas.size() > maxRegions) {
3990 ALOGE("%s: Too many areas requested: %d",
3991 __FUNCTION__, areas.size());
3992 return BAD_VALUE;
3993 }
3994
3995 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3996 a != areas.end(); a++) {
3997 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3998 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3999 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
4000 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
4001 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
4002 if (a->left >= a->right) return BAD_VALUE;
4003 if (a->top >= a->bottom) return BAD_VALUE;
4004 }
4005 return OK;
4006}
4007
4008bool Camera2Client::boolFromString(const char *boolStr) {
4009 return !boolStr ? false :
4010 !strcmp(boolStr, CameraParameters::TRUE) ? true :
4011 false;
4012}
4013
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07004014int Camera2Client::degToTransform(int degrees, bool mirror) {
4015 if (!mirror) {
4016 if (degrees == 0) return 0;
4017 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
4018 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
4019 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
4020 } else { // Do mirror (horizontal flip)
4021 if (degrees == 0) { // FLIP_H and ROT_0
4022 return HAL_TRANSFORM_FLIP_H;
4023 } else if (degrees == 90) { // FLIP_H and ROT_90
4024 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
4025 } else if (degrees == 180) { // FLIP_H and ROT_180
4026 return HAL_TRANSFORM_FLIP_V;
4027 } else if (degrees == 270) { // FLIP_H and ROT_270
4028 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
4029 }
4030 }
4031 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
4032 return -1;
4033}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07004034
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07004035size_t Camera2Client::calculateBufferSize(int width, int height,
4036 int format, int stride) {
4037 switch (format) {
4038 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
4039 return width * height * 2;
4040 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
4041 return width * height * 3 / 2;
4042 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
4043 return width * height * 2;
4044 case HAL_PIXEL_FORMAT_YV12: { // YV12
4045 size_t ySize = stride * height;
4046 size_t uvStride = (stride / 2 + 0xF) & ~0x10;
4047 size_t uvSize = uvStride * height / 2;
4048 return ySize + uvSize * 2;
4049 }
4050 case HAL_PIXEL_FORMAT_RGB_565:
4051 return width * height * 2;
4052 case HAL_PIXEL_FORMAT_RGBA_8888:
4053 return width * height * 4;
4054 case HAL_PIXEL_FORMAT_RAW_SENSOR:
4055 return width * height * 2;
4056 default:
4057 ALOGE("%s: Unknown preview format: %x",
4058 __FUNCTION__, format);
4059 return 0;
4060 }
4061}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07004062
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07004063} // namespace android