blob: 08a54c522dbce28f1218c1578a63fab6286b6ff2 [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 Talvala3a609142012-07-31 14:36:26 -070055 mState(DISCONNECTED),
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070056 mDeviceInfo(NULL),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070057 mPreviewStreamId(NO_STREAM),
58 mPreviewRequest(NULL),
59 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070060 mCaptureRequest(NULL),
61 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070062 mRecordingRequest(NULL),
63 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070064{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070065 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070066
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068}
69
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070070status_t Camera2Client::checkPid(const char* checkLocation) const {
71 int callingPid = getCallingPid();
72 if (callingPid == mClientPid) return NO_ERROR;
73
74 ALOGE("%s: attempt to use a locked camera from a different process"
75 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
76 return PERMISSION_DENIED;
77}
78
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079status_t Camera2Client::initialize(camera_module_t *module)
80{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070081 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070082 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083 status_t res;
84
85 res = mDevice->initialize(module);
86 if (res != OK) {
87 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
88 __FUNCTION__, mCameraId, strerror(-res), res);
89 return NO_INIT;
90 }
91
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070092 res = mDevice->setNotifyCallback(this);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070093 res = mDevice->setFrameListener(this);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070094
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070095 res = buildDeviceInfo();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070096 res = buildDefaultParameters();
97 if (res != OK) {
98 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
99 __FUNCTION__, mCameraId, strerror(-res), res);
100 return NO_INIT;
101 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700102
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700104 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700105 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
106 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700107 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700108 }
109
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700110 mState = STOPPED;
111
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700112 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700113}
114
115Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700116 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700117 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
118
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700119 mDestructionStarted = true;
120
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700121 // Rewrite mClientPid to allow shutdown by CameraService
122 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700123 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700124}
125
126status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700127 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700128 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700129 mCameraId,
130 getCameraClient()->asBinder().get(),
131 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700132 result.append(" State: ");
133#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
134
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700135 const Parameters& p = mParameters.unsafeUnlock();
136
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700137 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700138
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700139 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700141 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700144 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700145 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700146 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700147 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700148 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700149 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700150 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700151 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700152 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700153 p.jpegQuality, p.jpegThumbQuality);
154 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700155 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700156 p.gpsEnabled ? "enabled" : "disabled");
157 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700158 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700159 p.gpsCoordinates[0], p.gpsCoordinates[1],
160 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700161 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700162 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700163 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700164 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 }
166
167 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700168 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700169 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
177 default: result.append("UNKNOWN\n");
178 }
179
180 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700181 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700182 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
191 default: result.append("UNKNOWN\n");
192 }
193
194 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700195 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700196 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
200 default: result.append("UNKNOWN\n");
201 }
202
203 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700204 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700205 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
206 result.append("AUTO\n"); break;
207 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
208 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
222 default: result.append("UNKNOWN\n");
223 }
224
225 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700226 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700227 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
228 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
229 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
230 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
231 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
232 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
233 default: result.append("UNKNOWN\n");
234 }
235
236 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700237 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700238 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
239 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
242 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
243 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
244 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
245 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
246 default: result.append("UNKNOWN\n");
247 }
248
249 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700250 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700251 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700252 p.focusingAreas[i].left,
253 p.focusingAreas[i].top,
254 p.focusingAreas[i].right,
255 p.focusingAreas[i].bottom,
256 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700257 }
258
259 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700260 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700261
262 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700263 p.autoExposureLock ? "enabled" : "disabled",
264 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700265
266 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700267 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700268 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700269 p.meteringAreas[i].left,
270 p.meteringAreas[i].top,
271 p.meteringAreas[i].right,
272 p.meteringAreas[i].bottom,
273 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700274 }
275
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700276 result.appendFormat(" Zoom index: %d\n", p.zoom);
277 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
278 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700279
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700280 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700281 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700282
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700283 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700284 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700285
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700286 result.append(" Current streams:\n");
287 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
288 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700289 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700290
291 result.append(" Current requests:\n");
292 if (mPreviewRequest != NULL) {
293 result.append(" Preview request:\n");
294 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700295 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700296 } else {
297 result.append(" Preview request: undefined\n");
298 write(fd, result.string(), result.size());
299 }
300
301 if (mCaptureRequest != NULL) {
302 result = " Capture request:\n";
303 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700304 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700305 } else {
306 result = " Capture request: undefined\n";
307 write(fd, result.string(), result.size());
308 }
309
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700310 if (mRecordingRequest != NULL) {
311 result = " Recording request:\n";
312 write(fd, result.string(), result.size());
313 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
314 } else {
315 result = " Recording request: undefined\n";
316 write(fd, result.string(), result.size());
317 }
318
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700319 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700320 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700321
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700322 status_t res = mDevice->dump(fd, args);
323 if (res != OK) {
324 result = String8::format(" Error dumping device: %s (%d)",
325 strerror(-res), res);
326 write(fd, result.string(), result.size());
327 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700328
329#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700330 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700331}
332
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700333const char* Camera2Client::getStateName(State state) {
334#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
335 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700336 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700337 CASE_ENUM_TO_CHAR(STOPPED)
338 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
339 CASE_ENUM_TO_CHAR(PREVIEW)
340 CASE_ENUM_TO_CHAR(RECORD)
341 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
342 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
343 default:
344 return "Unknown state!";
345 break;
346 }
347#undef CASE_ENUM_TO_CHAR
348}
349
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700350// ICamera interface
351
352void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700353 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700354 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700355 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700356 status_t res;
357 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700358
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700359 if (mDevice == 0) return;
360
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700361 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700362
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700363 mDevice->waitUntilDrained();
364
365 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700366 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700367 mPreviewStreamId = NO_STREAM;
368 }
369
370 if (mCaptureStreamId != NO_STREAM) {
371 mDevice->deleteStream(mCaptureStreamId);
372 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700373 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700374
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700375 if (mRecordingStreamId != NO_STREAM) {
376 mDevice->deleteStream(mRecordingStreamId);
377 mRecordingStreamId = NO_STREAM;
378 }
379
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700380 mDevice.clear();
381 mState = DISCONNECTED;
382
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700383 if (mDeviceInfo != NULL) {
384 delete mDeviceInfo;
385 mDeviceInfo = NULL;
386 }
387
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700388 CameraService::Client::disconnect();
389}
390
391status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700392 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700393 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700394 Mutex::Autolock icl(mICameraLock);
395
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700396 if (mClientPid != 0 && getCallingPid() != mClientPid) {
397 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
398 "current locked to pid %d", __FUNCTION__,
399 mCameraId, getCallingPid(), mClientPid);
400 return BAD_VALUE;
401 }
402
403 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700404
405 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700406 mCameraClient = client;
407
408 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700409}
410
411status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700412 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700413 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700414 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700415 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
416 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700417
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700418 if (mClientPid == 0) {
419 mClientPid = getCallingPid();
420 return OK;
421 }
422
423 if (mClientPid != getCallingPid()) {
424 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
425 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
426 return EBUSY;
427 }
428
429 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700430}
431
432status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700433 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700434 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700435 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700436 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
437 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700438
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700439 // TODO: Check for uninterruptable conditions
440
441 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700442 Mutex::Autolock iccl(mICameraClientLock);
443
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700444 mClientPid = 0;
445 mCameraClient.clear();
446 return OK;
447 }
448
449 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
450 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
451 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700452}
453
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700454status_t Camera2Client::setPreviewDisplay(
455 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700456 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700457 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700458 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700459 status_t res;
460 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700461
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700462 sp<IBinder> binder;
463 sp<ANativeWindow> window;
464 if (surface != 0) {
465 binder = surface->asBinder();
466 window = surface;
467 }
468
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700469 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700470}
471
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700472status_t Camera2Client::setPreviewTexture(
473 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700474 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700475 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700476 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700477 status_t res;
478 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700479
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700480 sp<IBinder> binder;
481 sp<ANativeWindow> window;
482 if (surfaceTexture != 0) {
483 binder = surfaceTexture->asBinder();
484 window = new SurfaceTextureClient(surfaceTexture);
485 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700486 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700487}
488
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700489status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700490 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700491 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700492 status_t res;
493
494 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700495 ALOGV("%s: Camera %d: New window is same as old window",
496 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700497 return NO_ERROR;
498 }
499
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700500 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700501 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700502 case RECORD:
503 case STILL_CAPTURE:
504 case VIDEO_SNAPSHOT:
505 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
506 __FUNCTION__, mCameraId, getStateName(mState));
507 return INVALID_OPERATION;
508 case STOPPED:
509 case WAITING_FOR_PREVIEW_WINDOW:
510 // OK
511 break;
512 case PREVIEW:
513 // Already running preview - need to stop and create a new stream
514 // TODO: Optimize this so that we don't wait for old stream to drain
515 // before spinning up new stream
516 mDevice->setStreamingRequest(NULL);
517 mState = WAITING_FOR_PREVIEW_WINDOW;
518 break;
519 }
520
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700521 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700522 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700523 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700524 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
525 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700526 return res;
527 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700528 res = mDevice->deleteStream(mPreviewStreamId);
529 if (res != OK) {
530 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
531 __FUNCTION__, strerror(-res), res);
532 return res;
533 }
534 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700535 }
536
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700537 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700538 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700539
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700541 return startPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700542 }
543
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700544 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700545}
546
547void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700548 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700549 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700550 status_t res;
551 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700552}
553
554status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700555 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700556 ALOGV("%s: E", __FUNCTION__);
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;
559 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700560 return startPreviewL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700561}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700562
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700563status_t Camera2Client::startPreviewL() {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700564 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700565 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700566 if (mState >= PREVIEW) {
567 ALOGE("%s: Can't start preview in state %s",
568 __FUNCTION__, getStateName(mState));
569 return INVALID_OPERATION;
570 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700571
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700572 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700573 mState = WAITING_FOR_PREVIEW_WINDOW;
574 return OK;
575 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700576 mState = STOPPED;
577
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700578 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700579
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700580 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700581 if (res != OK) {
582 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
583 __FUNCTION__, mCameraId, strerror(-res), res);
584 return res;
585 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700586
587 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700588 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700589 if (res != OK) {
590 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
591 __FUNCTION__, mCameraId, strerror(-res), res);
592 return res;
593 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700594 }
595
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700596 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700597 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700598 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700599 if (res != OK) {
600 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
601 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700602 return res;
603 }
604 res = sort_camera_metadata(mPreviewRequest);
605 if (res != OK) {
606 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
607 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700608 return res;
609 }
610
611 res = mDevice->setStreamingRequest(mPreviewRequest);
612 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700613 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
614 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700615 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700616 return res;
617 }
618 mState = PREVIEW;
619
620 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700621}
622
623void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700624 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700625 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700626 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700627 status_t res;
628 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700629 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700630}
631
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700632void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700633 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700634 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700635 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700636 ALOGE("%s: Camera %d: Call before initialized",
637 __FUNCTION__, mCameraId);
638 break;
639 case STOPPED:
640 break;
641 case STILL_CAPTURE:
642 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
643 __FUNCTION__, mCameraId);
644 break;
645 case RECORD:
646 // TODO: Handle record stop here
647 case PREVIEW:
648 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700649 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700650 case WAITING_FOR_PREVIEW_WINDOW:
651 mState = STOPPED;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700652 commandStopFaceDetectionL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700653 break;
654 default:
655 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
656 mState);
657 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700658}
659
660bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700661 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700662 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700663 status_t res;
664 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
665
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700667}
668
669status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700670 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700671 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700672 status_t res;
673 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
674
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700675 switch (mState) {
676 case RECORD:
677 case VIDEO_SNAPSHOT:
678 ALOGE("%s: Camera %d: Can't be called in state %s",
679 __FUNCTION__, mCameraId, getStateName(mState));
680 return INVALID_OPERATION;
681 default:
682 // OK
683 break;
684 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700685 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700686
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700687 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700688
689 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700690}
691
692status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700693 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700694 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700695 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700696 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700697 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
698
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700699 switch (mState) {
700 case STOPPED:
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700701 res = startPreviewL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700702 if (res != OK) return res;
703 break;
704 case PREVIEW:
705 // Ready to go
706 break;
707 case RECORD:
708 case VIDEO_SNAPSHOT:
709 // OK to call this when recording is already on
710 return OK;
711 break;
712 default:
713 ALOGE("%s: Camera %d: Can't start recording in state %s",
714 __FUNCTION__, mCameraId, getStateName(mState));
715 return INVALID_OPERATION;
716 };
717
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700718 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700719
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700720 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700721 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
722 "non-metadata recording mode requested!", __FUNCTION__,
723 mCameraId);
724 return INVALID_OPERATION;
725 }
726
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700727 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700728 if (res != OK) {
729 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
730 __FUNCTION__, mCameraId, strerror(-res), res);
731 return res;
732 }
733
734 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700735 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700736 if (res != OK) {
737 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
738 __FUNCTION__, mCameraId, strerror(-res), res);
739 return res;
740 }
741 }
742
743 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
744 res = updateEntry(mRecordingRequest,
745 ANDROID_REQUEST_OUTPUT_STREAMS,
746 outputStreams, 2);
747 if (res != OK) {
748 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
749 __FUNCTION__, mCameraId, strerror(-res), res);
750 return res;
751 }
752 res = sort_camera_metadata(mRecordingRequest);
753 if (res != OK) {
754 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
755 __FUNCTION__, mCameraId, strerror(-res), res);
756 return res;
757 }
758
759 res = mDevice->setStreamingRequest(mRecordingRequest);
760 if (res != OK) {
761 ALOGE("%s: Camera %d: Unable to set recording request to start "
762 "recording: %s (%d)", __FUNCTION__, mCameraId,
763 strerror(-res), res);
764 return res;
765 }
766 mState = RECORD;
767
768 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700769}
770
771void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700772 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700773 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700774 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700775 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700776 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
777
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700778 switch (mState) {
779 case RECORD:
780 // OK to stop
781 break;
782 case STOPPED:
783 case PREVIEW:
784 case STILL_CAPTURE:
785 case VIDEO_SNAPSHOT:
786 default:
787 ALOGE("%s: Camera %d: Can't stop recording in state %s",
788 __FUNCTION__, mCameraId, getStateName(mState));
789 return;
790 };
791
792 // Back to preview. Since record can only be reached through preview,
793 // all preview stream setup should be up to date.
794 res = mDevice->setStreamingRequest(mPreviewRequest);
795 if (res != OK) {
796 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
797 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
798 return;
799 }
800
801 // TODO: Should recording heap be freed? Can't do it yet since requests
802 // could still be in flight.
803
804 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700805}
806
807bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700808 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700809 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700810
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700811 if ( checkPid(__FUNCTION__) != OK) return false;
812
James Dong8da4cd72012-08-04 19:58:07 -0700813 return recordingEnabledL();
814}
815
816bool Camera2Client::recordingEnabledL() {
817 ATRACE_CALL();
818
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700819 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700820}
821
822void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700823 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700824 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700825 status_t res;
826 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700827 // Make sure this is for the current heap
828 ssize_t offset;
829 size_t size;
830 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
831 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
832 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
833 "(got %x, expected %x)", __FUNCTION__, mCameraId,
834 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
835 return;
836 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700837 uint8_t *data = (uint8_t*)heap->getBase() + offset;
838 uint32_t type = *(uint32_t*)data;
839 if (type != kMetadataBufferTypeGrallocSource) {
840 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
841 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
842 return;
843 }
844 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
845 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700846 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700847 res = mRecordingConsumer->freeBuffer(imgBuffer);
848 if (res != OK) {
849 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
850 "%s (%d)",
851 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
852 return;
853 }
854
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700855 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700856}
857
858status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700859 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700860 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700861 status_t res;
862 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
863
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700864 int triggerId;
865 {
866 LockedParameters::Key k(mParameters);
867 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
868 triggerId = k.mParameters.currentAfTriggerId;
869 }
870
871 mDevice->triggerAutofocus(triggerId);
872
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700873 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700874}
875
876status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700877 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700878 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700879 status_t res;
880 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
881
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700882 int triggerId;
883 {
884 LockedParameters::Key k(mParameters);
885 triggerId = ++k.mParameters.afTriggerCounter;
886 }
887
888 mDevice->triggerCancelAutofocus(triggerId);
889
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700890 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700891}
892
893status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700894 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700895 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700896 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700897 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700898
899 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700900 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700901 case STOPPED:
902 case WAITING_FOR_PREVIEW_WINDOW:
903 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
904 __FUNCTION__, mCameraId);
905 return INVALID_OPERATION;
906 case PREVIEW:
907 case RECORD:
908 // Good to go for takePicture
909 break;
910 case STILL_CAPTURE:
911 case VIDEO_SNAPSHOT:
912 ALOGE("%s: Camera %d: Already taking a picture",
913 __FUNCTION__, mCameraId);
914 return INVALID_OPERATION;
915 }
916
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700917
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700918 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700919
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700920 {
921 LockedParameters::Key k(mParameters);
922
923 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700924 if (res != OK) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700925 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
926 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700927 return res;
928 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700929
930 if (mCaptureRequest == NULL) {
931 res = updateCaptureRequest(k.mParameters);
932 if (res != OK) {
933 ALOGE("%s: Camera %d: Can't create still image capture request: "
934 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
935 return res;
936 }
937 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700938 }
939
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700940 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700941 if (mState == PREVIEW) {
942 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
943 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
944 &streamIds, 2);
945 } else if (mState == RECORD) {
946 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
947 mCaptureStreamId };
948 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
949 &streamIds, 3);
950 }
951
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700952 if (res != OK) {
953 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
954 "%s (%d)",
955 __FUNCTION__, mCameraId, strerror(-res), res);
956 return res;
957 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700958 res = sort_camera_metadata(mCaptureRequest);
959 if (res != OK) {
960 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
961 __FUNCTION__, mCameraId, strerror(-res), res);
962 return res;
963 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700964
965 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
966 if (captureCopy == NULL) {
967 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
968 __FUNCTION__, mCameraId);
969 return NO_MEMORY;
970 }
971
972 if (mState == PREVIEW) {
973 res = mDevice->setStreamingRequest(NULL);
974 if (res != OK) {
975 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
976 "%s (%d)",
977 __FUNCTION__, mCameraId, strerror(-res), res);
978 return res;
979 }
980 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700981 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700982 res = mDevice->capture(captureCopy);
983 if (res != OK) {
984 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
985 "%s (%d)",
986 __FUNCTION__, mCameraId, strerror(-res), res);
987 return res;
988 }
989
990 switch (mState) {
991 case PREVIEW:
992 mState = STILL_CAPTURE;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700993 res = commandStopFaceDetectionL();
994 if (res != OK) {
995 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
996 __FUNCTION__, mCameraId);
997 return res;
998 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700999 break;
1000 case RECORD:
1001 mState = VIDEO_SNAPSHOT;
1002 break;
1003 default:
1004 ALOGE("%s: Camera %d: Unknown state for still capture!",
1005 __FUNCTION__, mCameraId);
1006 return INVALID_OPERATION;
1007 }
1008
1009 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001010}
1011
1012status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001013 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001014 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001015 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001016 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001017 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1018
1019 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001020
1021 CameraParameters newParams(params);
1022
1023 // TODO: Currently ignoring any changes to supposedly read-only
1024 // parameters such as supported preview sizes, etc. Should probably
1025 // produce an error if they're changed.
1026
1027 /** Extract and verify new parameters */
1028
1029 size_t i;
1030
1031 // PREVIEW_SIZE
1032 int previewWidth, previewHeight;
1033 newParams.getPreviewSize(&previewWidth, &previewHeight);
1034
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001035 if (previewWidth != k.mParameters.previewWidth ||
1036 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001037 if (mState >= PREVIEW) {
1038 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001039 "is active! (Currently %d x %d, requested %d x %d",
1040 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001041 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001042 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001043 return BAD_VALUE;
1044 }
1045 camera_metadata_entry_t availablePreviewSizes =
1046 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1047 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1048 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1049 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1050 }
1051 if (i == availablePreviewSizes.count) {
1052 ALOGE("%s: Requested preview size %d x %d is not supported",
1053 __FUNCTION__, previewWidth, previewHeight);
1054 return BAD_VALUE;
1055 }
1056 }
1057
1058 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001059 int previewFpsRange[2];
1060 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001061 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001062 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001063 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1064 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001065 fpsRangeChanged = true;
1066 camera_metadata_entry_t availablePreviewFpsRanges =
1067 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1068 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1069 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001070 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001071 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001072 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001073 break;
1074 }
1075 }
1076 if (i == availablePreviewFpsRanges.count) {
1077 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001078 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001079 return BAD_VALUE;
1080 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001081 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001082 }
1083
1084 // PREVIEW_FORMAT
1085 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001086 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001087 if (mState >= PREVIEW) {
1088 ALOGE("%s: Preview format cannot be updated when preview "
1089 "is active!", __FUNCTION__);
1090 return BAD_VALUE;
1091 }
1092 camera_metadata_entry_t availableFormats =
1093 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1094 for (i = 0; i < availableFormats.count; i++) {
1095 if (availableFormats.data.i32[i] == previewFormat) break;
1096 }
1097 if (i == availableFormats.count) {
1098 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1099 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1100 return BAD_VALUE;
1101 }
1102 }
1103
1104 // PREVIEW_FRAME_RATE
1105 // Deprecated, only use if the preview fps range is unchanged this time.
1106 // The single-value FPS is the same as the minimum of the range.
1107 if (!fpsRangeChanged) {
1108 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001109 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001110 camera_metadata_entry_t availableFrameRates =
1111 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1112 for (i = 0; i < availableFrameRates.count; i+=2) {
1113 if (availableFrameRates.data.i32[i] == previewFps) break;
1114 }
1115 if (i == availableFrameRates.count) {
1116 ALOGE("%s: Requested preview frame rate %d is not supported",
1117 __FUNCTION__, previewFps);
1118 return BAD_VALUE;
1119 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001120 previewFpsRange[0] = availableFrameRates.data.i32[i];
1121 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001122 }
1123 }
1124
1125 // PICTURE_SIZE
1126 int pictureWidth, pictureHeight;
1127 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001128 if (pictureWidth == k.mParameters.pictureWidth ||
1129 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001130 camera_metadata_entry_t availablePictureSizes =
1131 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1132 for (i = 0; i < availablePictureSizes.count; i+=2) {
1133 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1134 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1135 }
1136 if (i == availablePictureSizes.count) {
1137 ALOGE("%s: Requested picture size %d x %d is not supported",
1138 __FUNCTION__, pictureWidth, pictureHeight);
1139 return BAD_VALUE;
1140 }
1141 }
1142
1143 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001144 int jpegThumbSize[2];
1145 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001146 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001147 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001148 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001149 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1150 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001151 camera_metadata_entry_t availableJpegThumbSizes =
1152 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1153 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001154 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1155 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001156 break;
1157 }
1158 }
1159 if (i == availableJpegThumbSizes.count) {
1160 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001161 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001162 return BAD_VALUE;
1163 }
1164 }
1165
1166 // JPEG_THUMBNAIL_QUALITY
1167 int jpegThumbQuality =
1168 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1169 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1170 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1171 __FUNCTION__, jpegThumbQuality);
1172 return BAD_VALUE;
1173 }
1174
1175 // JPEG_QUALITY
1176 int jpegQuality =
1177 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1178 if (jpegQuality < 0 || jpegQuality > 100) {
1179 ALOGE("%s: Requested JPEG quality %d is not supported",
1180 __FUNCTION__, jpegQuality);
1181 return BAD_VALUE;
1182 }
1183
1184 // ROTATION
1185 int jpegRotation =
1186 newParams.getInt(CameraParameters::KEY_ROTATION);
1187 if (jpegRotation != 0 &&
1188 jpegRotation != 90 &&
1189 jpegRotation != 180 &&
1190 jpegRotation != 270) {
1191 ALOGE("%s: Requested picture rotation angle %d is not supported",
1192 __FUNCTION__, jpegRotation);
1193 return BAD_VALUE;
1194 }
1195
1196 // GPS
1197 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001198 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001199 int64_t gpsTimestamp = 0;
1200 String8 gpsProcessingMethod;
1201 const char *gpsLatStr =
1202 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1203 if (gpsLatStr != NULL) {
1204 const char *gpsLongStr =
1205 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1206 const char *gpsAltitudeStr =
1207 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1208 const char *gpsTimeStr =
1209 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1210 const char *gpsProcMethodStr =
1211 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1212 if (gpsLongStr == NULL ||
1213 gpsAltitudeStr == NULL ||
1214 gpsTimeStr == NULL ||
1215 gpsProcMethodStr == NULL) {
1216 ALOGE("%s: Incomplete set of GPS parameters provided",
1217 __FUNCTION__);
1218 return BAD_VALUE;
1219 }
1220 char *endPtr;
1221 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001222 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001223 if (errno || endPtr == gpsLatStr) {
1224 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1225 return BAD_VALUE;
1226 }
1227 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001228 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001229 if (errno || endPtr == gpsLongStr) {
1230 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1231 return BAD_VALUE;
1232 }
1233 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001234 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001235 if (errno || endPtr == gpsAltitudeStr) {
1236 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1237 gpsAltitudeStr);
1238 return BAD_VALUE;
1239 }
1240 errno = 0;
1241 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1242 if (errno || endPtr == gpsTimeStr) {
1243 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1244 return BAD_VALUE;
1245 }
1246 gpsProcessingMethod = gpsProcMethodStr;
1247
1248 gpsEnabled = true;
1249 }
1250
1251 // WHITE_BALANCE
1252 int wbMode = wbModeStringToEnum(
1253 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001254 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001255 camera_metadata_entry_t availableWbModes =
1256 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1257 for (i = 0; i < availableWbModes.count; i++) {
1258 if (wbMode == availableWbModes.data.u8[i]) break;
1259 }
1260 if (i == availableWbModes.count) {
1261 ALOGE("%s: Requested white balance mode %s is not supported",
1262 __FUNCTION__,
1263 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1264 return BAD_VALUE;
1265 }
1266 }
1267
1268 // EFFECT
1269 int effectMode = effectModeStringToEnum(
1270 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001271 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001272 camera_metadata_entry_t availableEffectModes =
1273 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1274 for (i = 0; i < availableEffectModes.count; i++) {
1275 if (effectMode == availableEffectModes.data.u8[i]) break;
1276 }
1277 if (i == availableEffectModes.count) {
1278 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1279 __FUNCTION__,
1280 newParams.get(CameraParameters::KEY_EFFECT) );
1281 return BAD_VALUE;
1282 }
1283 }
1284
1285 // ANTIBANDING
1286 int antibandingMode = abModeStringToEnum(
1287 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001288 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001289 camera_metadata_entry_t availableAbModes =
1290 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1291 for (i = 0; i < availableAbModes.count; i++) {
1292 if (antibandingMode == availableAbModes.data.u8[i]) break;
1293 }
1294 if (i == availableAbModes.count) {
1295 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1296 __FUNCTION__,
1297 newParams.get(CameraParameters::KEY_ANTIBANDING));
1298 return BAD_VALUE;
1299 }
1300 }
1301
1302 // SCENE_MODE
1303 int sceneMode = sceneModeStringToEnum(
1304 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001305 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001306 camera_metadata_entry_t availableSceneModes =
1307 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1308 for (i = 0; i < availableSceneModes.count; i++) {
1309 if (sceneMode == availableSceneModes.data.u8[i]) break;
1310 }
1311 if (i == availableSceneModes.count) {
1312 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1313 __FUNCTION__,
1314 newParams.get(CameraParameters::KEY_SCENE_MODE));
1315 return BAD_VALUE;
1316 }
1317 }
1318
1319 // FLASH_MODE
1320 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1321 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001322 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001323 camera_metadata_entry_t flashAvailable =
1324 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1325 if (!flashAvailable.data.u8[0] &&
1326 flashMode != Parameters::FLASH_MODE_OFF) {
1327 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1328 "No flash on device", __FUNCTION__,
1329 newParams.get(CameraParameters::KEY_FLASH_MODE));
1330 return BAD_VALUE;
1331 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1332 camera_metadata_entry_t availableAeModes =
1333 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1334 for (i = 0; i < availableAeModes.count; i++) {
1335 if (flashMode == availableAeModes.data.u8[i]) break;
1336 }
1337 if (i == availableAeModes.count) {
1338 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1339 __FUNCTION__,
1340 newParams.get(CameraParameters::KEY_FLASH_MODE));
1341 return BAD_VALUE;
1342 }
1343 } else if (flashMode == -1) {
1344 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1345 __FUNCTION__,
1346 newParams.get(CameraParameters::KEY_FLASH_MODE));
1347 return BAD_VALUE;
1348 }
1349 }
1350
1351 // FOCUS_MODE
1352 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1353 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001354 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001355 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1356 camera_metadata_entry_t minFocusDistance =
1357 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1358 if (minFocusDistance.data.f[0] == 0) {
1359 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1360 "fixed focus lens",
1361 __FUNCTION__,
1362 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1363 return BAD_VALUE;
1364 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1365 camera_metadata_entry_t availableFocusModes =
1366 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1367 for (i = 0; i < availableFocusModes.count; i++) {
1368 if (focusMode == availableFocusModes.data.u8[i]) break;
1369 }
1370 if (i == availableFocusModes.count) {
1371 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1372 __FUNCTION__,
1373 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1374 return BAD_VALUE;
1375 }
1376 }
1377 }
1378 }
1379
1380 // FOCUS_AREAS
1381 Vector<Parameters::Area> focusingAreas;
1382 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1383 &focusingAreas);
1384 size_t max3aRegions =
1385 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1386 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1387 if (res != OK) {
1388 ALOGE("%s: Requested focus areas are malformed: %s",
1389 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1390 return BAD_VALUE;
1391 }
1392
1393 // EXPOSURE_COMPENSATION
1394 int exposureCompensation =
1395 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1396 camera_metadata_entry_t exposureCompensationRange =
1397 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1398 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1399 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1400 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1401 __FUNCTION__, exposureCompensation);
1402 return BAD_VALUE;
1403 }
1404
1405 // AUTO_EXPOSURE_LOCK (always supported)
1406 bool autoExposureLock = boolFromString(
1407 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1408
1409 // AUTO_WHITEBALANCE_LOCK (always supported)
1410 bool autoWhiteBalanceLock = boolFromString(
1411 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1412
1413 // METERING_AREAS
1414 Vector<Parameters::Area> meteringAreas;
1415 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1416 &meteringAreas);
1417 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1418 if (res != OK) {
1419 ALOGE("%s: Requested metering areas are malformed: %s",
1420 __FUNCTION__,
1421 newParams.get(CameraParameters::KEY_METERING_AREAS));
1422 return BAD_VALUE;
1423 }
1424
1425 // ZOOM
1426 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1427 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1428 ALOGE("%s: Requested zoom level %d is not supported",
1429 __FUNCTION__, zoom);
1430 return BAD_VALUE;
1431 }
1432
1433 // VIDEO_SIZE
1434 int videoWidth, videoHeight;
1435 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001436 if (videoWidth != k.mParameters.videoWidth ||
1437 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001438 if (mState == RECORD) {
1439 ALOGE("%s: Video size cannot be updated when recording is active!",
1440 __FUNCTION__);
1441 return BAD_VALUE;
1442 }
1443 camera_metadata_entry_t availableVideoSizes =
1444 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1445 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1446 if (availableVideoSizes.data.i32[i] == videoWidth &&
1447 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1448 }
1449 if (i == availableVideoSizes.count) {
1450 ALOGE("%s: Requested video size %d x %d is not supported",
1451 __FUNCTION__, videoWidth, videoHeight);
1452 return BAD_VALUE;
1453 }
1454 }
1455
1456 // RECORDING_HINT (always supported)
1457 bool recordingHint = boolFromString(
1458 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1459
1460 // VIDEO_STABILIZATION
1461 bool videoStabilization = boolFromString(
1462 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1463 camera_metadata_entry_t availableVideoStabilizationModes =
1464 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1465 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1466 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1467 }
1468
1469 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001470
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001471 k.mParameters.previewWidth = previewWidth;
1472 k.mParameters.previewHeight = previewHeight;
1473 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1474 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1475 k.mParameters.previewFps = previewFps;
1476 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001477
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001478 k.mParameters.pictureWidth = pictureWidth;
1479 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001480
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001481 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1482 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1483 k.mParameters.jpegQuality = jpegQuality;
1484 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001485
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001486 k.mParameters.gpsEnabled = gpsEnabled;
1487 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1488 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1489 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1490 k.mParameters.gpsTimestamp = gpsTimestamp;
1491 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001492
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001493 k.mParameters.wbMode = wbMode;
1494 k.mParameters.effectMode = effectMode;
1495 k.mParameters.antibandingMode = antibandingMode;
1496 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001497
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001498 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001499 if (focusMode != k.mParameters.focusMode) {
1500 k.mParameters.currentAfTriggerId = -1;
1501 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001502 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001503
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001504 k.mParameters.focusingAreas = focusingAreas;
1505 k.mParameters.exposureCompensation = exposureCompensation;
1506 k.mParameters.autoExposureLock = autoExposureLock;
1507 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1508 k.mParameters.meteringAreas = meteringAreas;
1509 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001510
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001511 k.mParameters.videoWidth = videoWidth;
1512 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001513
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001514 k.mParameters.recordingHint = recordingHint;
1515 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001516
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001517 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001518
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001519 res = updateRequests(k.mParameters);
1520
1521 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001522}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001523
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001524String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001525 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001526 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001527 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001528
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001529 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001530
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001531 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001532 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001533}
1534
1535status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001536 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001537 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001538 status_t res;
1539 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001540
1541 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1542 cmd, arg1, arg2);
1543
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001544 switch (cmd) {
1545 case CAMERA_CMD_START_SMOOTH_ZOOM:
1546 return commandStartSmoothZoomL();
1547 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1548 return commandStopSmoothZoomL();
1549 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1550 return commandSetDisplayOrientationL(arg1);
1551 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1552 return commandEnableShutterSoundL(arg1 == 1);
1553 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1554 return commandPlayRecordingSoundL();
1555 case CAMERA_CMD_START_FACE_DETECTION:
1556 return commandStartFaceDetectionL(arg1);
1557 case CAMERA_CMD_STOP_FACE_DETECTION:
1558 return commandStopFaceDetectionL();
1559 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1560 return commandEnableFocusMoveMsgL(arg1 == 1);
1561 case CAMERA_CMD_PING:
1562 return commandPingL();
1563 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1564 return commandSetVideoBufferCountL(arg1);
1565 default:
1566 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1567 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001568 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001569 }
1570}
James Dong983cf232012-08-01 16:39:55 -07001571
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001572status_t Camera2Client::commandStartSmoothZoomL() {
1573 ALOGE("%s: Unimplemented!", __FUNCTION__);
1574 return OK;
1575}
James Dong983cf232012-08-01 16:39:55 -07001576
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001577status_t Camera2Client::commandStopSmoothZoomL() {
1578 ALOGE("%s: Unimplemented!", __FUNCTION__);
1579 return OK;
1580}
James Dong983cf232012-08-01 16:39:55 -07001581
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001582status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1583 LockedParameters::Key k(mParameters);
1584 int transform = degToTransform(degrees,
1585 mCameraFacing == CAMERA_FACING_FRONT);
1586 if (transform == -1) {
1587 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1588 __FUNCTION__, mCameraId, degrees);
1589 return BAD_VALUE;
1590 }
1591 if (transform != k.mParameters.previewTransform &&
1592 mPreviewStreamId != NO_STREAM) {
1593 mDevice->setStreamTransform(mPreviewStreamId, transform);
1594 }
1595 k.mParameters.previewTransform = transform;
1596 return OK;
1597}
1598
1599status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1600 LockedParameters::Key k(mParameters);
1601 if (enable) {
1602 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001603 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001604 }
1605
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001606 // Disabling shutter sound may not be allowed. In that case only
1607 // allow the mediaserver process to disable the sound.
1608 char value[PROPERTY_VALUE_MAX];
1609 property_get("ro.camera.sound.forced", value, "0");
1610 if (strncmp(value, "0", 2) != 0) {
1611 // Disabling shutter sound is not allowed. Deny if the current
1612 // process is not mediaserver.
1613 if (getCallingPid() != getpid()) {
1614 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1615 getCallingPid());
1616 return PERMISSION_DENIED;
1617 }
1618 }
1619
1620 k.mParameters.playShutterSound = false;
1621 return OK;
1622}
1623
1624status_t Camera2Client::commandPlayRecordingSoundL() {
1625 mCameraService->playSound(CameraService::SOUND_RECORDING);
1626 return OK;
1627}
1628
1629status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001630 ALOGV("%s: Camera %d: Starting face detection",
1631 __FUNCTION__, mCameraId);
1632 status_t res;
1633 switch (mState) {
1634 case DISCONNECTED:
1635 case STOPPED:
1636 case WAITING_FOR_PREVIEW_WINDOW:
1637 case STILL_CAPTURE:
1638 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1639 __FUNCTION__, mCameraId);
1640 return INVALID_OPERATION;
1641 case PREVIEW:
1642 case RECORD:
1643 case VIDEO_SNAPSHOT:
1644 // Good to go for starting face detect
1645 break;
1646 }
1647 // Ignoring type
1648 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1649 ALOGE("%s: Camera %d: Face detection not supported",
1650 __FUNCTION__, mCameraId);
1651 return INVALID_OPERATION;
1652 }
1653
1654 LockedParameters::Key k(mParameters);
1655 if (k.mParameters.enableFaceDetect) return OK;
1656
1657 k.mParameters.enableFaceDetect = true;
1658
1659 res = updateRequests(k.mParameters);
1660
1661 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001662}
1663
1664status_t Camera2Client::commandStopFaceDetectionL() {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001665 status_t res = OK;
1666 ALOGV("%s: Camera %d: Stopping face detection",
1667 __FUNCTION__, mCameraId);
1668
1669 LockedParameters::Key k(mParameters);
1670 if (!k.mParameters.enableFaceDetect) return OK;
1671
1672 k.mParameters.enableFaceDetect = false;
1673
1674 if (mState == PREVIEW || mState == RECORD || mState == VIDEO_SNAPSHOT) {
1675 res = updateRequests(k.mParameters);
1676 }
1677
1678 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001679}
1680
1681status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001682 LockedParameters::Key k(mParameters);
1683 k.mParameters.enableFocusMoveMessages = enable;
1684
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001685 return OK;
1686}
1687
1688status_t Camera2Client::commandPingL() {
1689 // Always ping back if access is proper and device is alive
1690 if (mState != DISCONNECTED) {
1691 return OK;
1692 } else {
1693 return NO_INIT;
1694 }
1695}
1696
1697status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001698 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001699 ALOGE("%s: Camera %d: Error setting video buffer count after "
1700 "recording was started", __FUNCTION__, mCameraId);
1701 return INVALID_OPERATION;
1702 }
1703
1704 // 32 is the current upper limit on the video buffer count for BufferQueue
1705 if (count > 32) {
1706 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1707 __FUNCTION__, mCameraId, count);
1708 return BAD_VALUE;
1709 }
1710
1711 // Need to reallocate memory for heap
1712 if (mRecordingHeapCount != count) {
1713 if (mRecordingHeap != 0) {
1714 mRecordingHeap.clear();
1715 mRecordingHeap = NULL;
1716 }
1717 mRecordingHeapCount = count;
1718 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001719
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001720 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001721}
1722
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001723/** Device-related methods */
1724
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001725void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1726 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1727}
1728
1729void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1730 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1731 frameNumber, timestamp);
1732}
1733
1734void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1735 ALOGV("%s: Autofocus state now %d, last trigger %d",
1736 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001737 bool sendCompletedMessage = false;
1738 bool sendMovingMessage = false;
1739
1740 bool success = false;
1741 bool afInMotion = false;
1742 {
1743 LockedParameters::Key k(mParameters);
1744 switch (k.mParameters.focusMode) {
1745 case Parameters::FOCUS_MODE_AUTO:
1746 case Parameters::FOCUS_MODE_MACRO:
1747 // Don't send notifications upstream if they're not for the current AF
1748 // trigger. For example, if cancel was called in between, or if we
1749 // already sent a notification about this AF call.
1750 if (triggerId != k.mParameters.currentAfTriggerId) break;
1751 switch (newState) {
1752 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1753 success = true;
1754 // no break
1755 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1756 sendCompletedMessage = true;
1757 k.mParameters.currentAfTriggerId = -1;
1758 break;
1759 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1760 // Just starting focusing, ignore
1761 break;
1762 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1763 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1764 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1765 default:
1766 // Unexpected in AUTO/MACRO mode
1767 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1768 __FUNCTION__, newState);
1769 break;
1770 }
1771 break;
1772 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1773 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1774 switch (newState) {
1775 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1776 success = true;
1777 // no break
1778 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1779 // Don't send notifications upstream if they're not for
1780 // the current AF trigger. For example, if cancel was
1781 // called in between, or if we already sent a
1782 // notification about this AF call.
1783 // Send both a 'AF done' callback and a 'AF move' callback
1784 if (triggerId != k.mParameters.currentAfTriggerId) break;
1785 sendCompletedMessage = true;
1786 afInMotion = false;
1787 if (k.mParameters.enableFocusMoveMessages &&
1788 k.mParameters.afInMotion) {
1789 sendMovingMessage = true;
1790 }
1791 k.mParameters.currentAfTriggerId = -1;
1792 break;
1793 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1794 // Cancel was called, or we switched state; care if
1795 // currently moving
1796 afInMotion = false;
1797 if (k.mParameters.enableFocusMoveMessages &&
1798 k.mParameters.afInMotion) {
1799 sendMovingMessage = true;
1800 }
1801 break;
1802 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1803 // Start passive scan, inform upstream
1804 afInMotion = true;
1805 // no break
1806 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1807 // Stop passive scan, inform upstream
1808 if (k.mParameters.enableFocusMoveMessages) {
1809 sendMovingMessage = true;
1810 }
1811 break;
1812 }
1813 k.mParameters.afInMotion = afInMotion;
1814 break;
1815 case Parameters::FOCUS_MODE_EDOF:
1816 case Parameters::FOCUS_MODE_INFINITY:
1817 case Parameters::FOCUS_MODE_FIXED:
1818 default:
1819 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1820 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1821 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1822 }
1823 }
1824 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001825 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001826 Mutex::Autolock iccl(mICameraClientLock);
1827 if (mCameraClient != 0) {
1828 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1829 afInMotion ? 1 : 0, 0);
1830 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001831 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001832 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001833 Mutex::Autolock iccl(mICameraClientLock);
1834 if (mCameraClient != 0) {
1835 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1836 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001837 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001838}
1839
1840void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1841 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1842 __FUNCTION__, newState, triggerId);
1843}
1844
1845void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1846 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1847 __FUNCTION__, newState, triggerId);
1848}
1849
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001850void Camera2Client::onNewFrameAvailable() {
1851 status_t res;
1852 camera_metadata_t *frame = NULL;
1853 do {
1854 res = mDevice->getNextFrame(&frame);
1855 if (res != OK) {
1856 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
1857 __FUNCTION__, mCameraId, strerror(-res), res);
1858 return;
1859 }
1860 if (frame != NULL) {
1861 camera_metadata_entry_t entry;
1862 res = find_camera_metadata_entry(frame, ANDROID_REQUEST_FRAME_COUNT,
1863 &entry);
1864 if (res != OK) {
1865 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
1866 __FUNCTION__, mCameraId, strerror(-res), res);
1867 break;
1868 }
1869
1870 res = processFrameFaceDetect(frame);
1871 if (res != OK) break;
1872
1873 free_camera_metadata(frame);
1874 }
1875 } while (frame != NULL);
1876
1877 if (frame != NULL) {
1878 free_camera_metadata(frame);
1879 }
1880 return;
1881}
1882
1883status_t Camera2Client::processFrameFaceDetect(camera_metadata_t *frame) {
1884 status_t res;
1885 camera_metadata_entry_t entry;
1886 bool enableFaceDetect;
1887 {
1888 LockedParameters::Key k(mParameters);
1889 enableFaceDetect = k.mParameters.enableFaceDetect;
1890 }
1891 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_DETECT_MODE,
1892 &entry);
1893 if (res != OK) {
1894 ALOGE("%s: Camera %d: Error reading face mode: %s (%d)",
1895 __FUNCTION__, mCameraId, strerror(-res), res);
1896 return res;
1897 }
1898 uint8_t faceDetectMode = entry.data.u8[0];
1899
1900 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
1901 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_RECTANGLES,
1902 &entry);
1903 if (res != OK) {
1904 ALOGE("%s: Camera %d: Error reading face rectangles: %s (%d)",
1905 __FUNCTION__, mCameraId, strerror(-res), res);
1906 return res;
1907 }
1908 camera_frame_metadata metadata;
1909 metadata.number_of_faces = entry.count / 4;
1910 if (metadata.number_of_faces >
1911 mDeviceInfo->maxFaces) {
1912 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
1913 __FUNCTION__, mCameraId,
1914 metadata.number_of_faces, mDeviceInfo->maxFaces);
1915 return res;
1916 }
1917 int32_t *faceRects = entry.data.i32;
1918
1919 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_SCORES,
1920 &entry);
1921 if (res != OK) {
1922 ALOGE("%s: Camera %d: Error reading face scores: %s (%d)",
1923 __FUNCTION__, mCameraId, strerror(-res), res);
1924 return res;
1925 }
1926 uint8_t *faceScores = entry.data.u8;
1927
1928 int32_t *faceLandmarks = NULL;
1929 int32_t *faceIds = NULL;
1930
1931 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
1932 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_LANDMARKS,
1933 &entry);
1934 if (res != OK) {
1935 ALOGE("%s: Camera %d: Error reading face landmarks: %s (%d)",
1936 __FUNCTION__, mCameraId, strerror(-res), res);
1937 return res;
1938 }
1939 faceLandmarks = entry.data.i32;
1940
1941 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_IDS,
1942 &entry);
1943 if (res != OK) {
1944 ALOGE("%s: Camera %d: Error reading face IDs: %s (%d)",
1945 __FUNCTION__, mCameraId, strerror(-res), res);
1946 return res;
1947 }
1948 faceIds = entry.data.i32;
1949 }
1950
1951 Vector<camera_face_t> faces;
1952 faces.setCapacity(metadata.number_of_faces);
1953
1954 for (int i = 0; i < metadata.number_of_faces; i++) {
1955 camera_face_t face;
1956
1957 face.rect[0] = arrayXToNormalized(faceRects[i*4 + 0]);
1958 face.rect[1] = arrayYToNormalized(faceRects[i*4 + 1]);
1959 face.rect[2] = arrayXToNormalized(faceRects[i*4 + 2]);
1960 face.rect[3] = arrayYToNormalized(faceRects[i*4 + 3]);
1961
1962 face.score = faceScores[i];
1963 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
1964 face.id = faceIds[i];
1965 face.left_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 0]);
1966 face.left_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 1]);
1967 face.right_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 2]);
1968 face.right_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 3]);
1969 face.mouth[0] = arrayXToNormalized(faceLandmarks[i*6 + 4]);
1970 face.mouth[1] = arrayYToNormalized(faceLandmarks[i*6 + 5]);
1971 } else {
1972 face.id = 0;
1973 face.left_eye[0] = face.left_eye[1] = -2000;
1974 face.right_eye[0] = face.right_eye[1] = -2000;
1975 face.mouth[0] = face.mouth[1] = -2000;
1976 }
1977 faces.push_back(face);
1978 }
1979
1980 metadata.faces = faces.editArray();
1981 {
1982 Mutex::Autolock iccl(mICameraClientLock);
1983 if (mCameraClient != NULL) {
1984 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
1985 NULL, &metadata);
1986 }
1987 }
1988 }
1989 return OK;
1990}
1991
1992
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001993void Camera2Client::onCaptureAvailable() {
1994 ATRACE_CALL();
1995 status_t res;
1996 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001997 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1998
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001999 CpuConsumer::LockedBuffer imgBuffer;
2000 {
2001 Mutex::Autolock icl(mICameraLock);
2002
2003 // TODO: Signal errors here upstream
2004 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
2005 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2006 __FUNCTION__, mCameraId);
2007 return;
2008 }
2009
2010 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2011 if (res != OK) {
2012 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2013 __FUNCTION__, mCameraId, strerror(-res), res);
2014 return;
2015 }
2016
2017 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2018 ALOGE("%s: Camera %d: Unexpected format for still image: "
2019 "%x, expected %x", __FUNCTION__, mCameraId,
2020 imgBuffer.format,
2021 HAL_PIXEL_FORMAT_BLOB);
2022 mCaptureConsumer->unlockBuffer(imgBuffer);
2023 return;
2024 }
2025
2026 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002027 void* captureMemory = mCaptureHeap->mHeap->getBase();
2028 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002029 memcpy(captureMemory, imgBuffer.data, size);
2030
2031 mCaptureConsumer->unlockBuffer(imgBuffer);
2032
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002033 switch (mState) {
2034 case STILL_CAPTURE:
2035 mState = STOPPED;
2036 break;
2037 case VIDEO_SNAPSHOT:
2038 mState = RECORD;
2039 break;
2040 default:
2041 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
2042 mCameraId, mState);
2043 break;
2044 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002045
2046 Mutex::Autolock iccl(mICameraClientLock);
2047 currentClient = mCameraClient;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002048 }
2049 // Call outside mICameraLock to allow re-entrancy from notification
2050 if (currentClient != 0) {
2051 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002052 mCaptureHeap->mBuffers[0], NULL);
2053 }
2054}
2055
2056void Camera2Client::onRecordingFrameAvailable() {
2057 ATRACE_CALL();
2058 status_t res;
2059 sp<ICameraClient> currentClient;
2060 size_t heapIdx = 0;
2061 nsecs_t timestamp;
2062 {
2063 Mutex::Autolock icl(mICameraLock);
2064 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002065 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002066 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002067 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2068 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002069 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002070 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002071 }
2072
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002073 buffer_handle_t imgBuffer;
2074 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002075 if (res != OK) {
2076 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2077 __FUNCTION__, mCameraId, strerror(-res), res);
2078 return;
2079 }
2080
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002081 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002082 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002083 return;
2084 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002085
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002086 if (mRecordingHeap == 0) {
2087 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002088 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2089 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002090 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002091 if (mRecordingHeap != 0) {
2092 ALOGV("%s: Camera %d: Previous heap has size %d "
2093 "(new will be %d) bytes", __FUNCTION__, mCameraId,
2094 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07002095 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002096 }
2097 // Need to allocate memory for heap
2098 mRecordingHeap.clear();
2099
James Dong983cf232012-08-01 16:39:55 -07002100 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002101 "Camera2Client::RecordingHeap");
2102 if (mRecordingHeap->mHeap->getSize() == 0) {
2103 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2104 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002105 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002106 return;
2107 }
2108 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002109 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002110 }
2111
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002112 if ( mRecordingHeapFree == 0) {
2113 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2114 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002115 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002116 return;
2117 }
2118 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002119 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002120 mRecordingHeapFree--;
2121
2122 ALOGV("%s: Camera %d: Timestamp %lld",
2123 __FUNCTION__, mCameraId, timestamp);
2124
2125 ssize_t offset;
2126 size_t size;
2127 sp<IMemoryHeap> heap =
2128 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2129 &size);
2130
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002131 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2132 uint32_t type = kMetadataBufferTypeGrallocSource;
2133 memcpy(data, &type, 4);
2134 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
2135 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002136 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002137 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002138 currentClient = mCameraClient;
2139 }
2140 // Call outside mICameraLock to allow re-entrancy from notification
2141 if (currentClient != 0) {
2142 currentClient->dataCallbackTimestamp(timestamp,
2143 CAMERA_MSG_VIDEO_FRAME,
2144 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002145 }
2146}
2147
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002148camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
2149 size_t minCount, size_t maxCount) {
2150 status_t res;
2151 camera_metadata_entry_t entry;
2152 res = find_camera_metadata_entry(mDevice->info(),
2153 tag,
2154 &entry);
2155 if (CC_UNLIKELY( res != OK )) {
2156 const char* tagSection = get_camera_metadata_section_name(tag);
2157 if (tagSection == NULL) tagSection = "<unknown>";
2158 const char* tagName = get_camera_metadata_tag_name(tag);
2159 if (tagName == NULL) tagName = "<unknown>";
2160
2161 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
2162 tagSection, tagName, tag, strerror(-res), res);
2163 entry.count = 0;
2164 entry.data.u8 = NULL;
2165 } else if (CC_UNLIKELY(
2166 (minCount != 0 && entry.count < minCount) ||
2167 (maxCount != 0 && entry.count > maxCount) ) ) {
2168 const char* tagSection = get_camera_metadata_section_name(tag);
2169 if (tagSection == NULL) tagSection = "<unknown>";
2170 const char* tagName = get_camera_metadata_tag_name(tag);
2171 if (tagName == NULL) tagName = "<unknown>";
2172 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2173 "Expected between %d and %d values, but got %d values",
2174 tagSection, tagName, tag, minCount, maxCount, entry.count);
2175 entry.count = 0;
2176 entry.data.u8 = NULL;
2177 }
2178
2179 return entry;
2180}
2181
2182/** Utility methods */
2183
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002184status_t Camera2Client::buildDeviceInfo() {
2185 if (mDeviceInfo != NULL) {
2186 delete mDeviceInfo;
2187 }
2188 DeviceInfo *deviceInfo = new DeviceInfo;
2189 mDeviceInfo = deviceInfo;
2190
2191 camera_metadata_entry_t activeArraySize =
2192 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2193 if (!activeArraySize.count) return NO_INIT;
2194 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2195 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2196
2197 camera_metadata_entry_t availableFaceDetectModes =
2198 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2199 if (!availableFaceDetectModes.count) return NO_INIT;
2200
2201 deviceInfo->bestFaceDetectMode =
2202 ANDROID_STATS_FACE_DETECTION_OFF;
2203 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2204 switch (availableFaceDetectModes.data.u8[i]) {
2205 case ANDROID_STATS_FACE_DETECTION_OFF:
2206 break;
2207 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2208 if (deviceInfo->bestFaceDetectMode !=
2209 ANDROID_STATS_FACE_DETECTION_FULL) {
2210 deviceInfo->bestFaceDetectMode =
2211 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2212 }
2213 break;
2214 case ANDROID_STATS_FACE_DETECTION_FULL:
2215 deviceInfo->bestFaceDetectMode =
2216 ANDROID_STATS_FACE_DETECTION_FULL;
2217 break;
2218 default:
2219 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2220 __FUNCTION__, mCameraId,
2221 availableFaceDetectModes.data.u8[i]);
2222 return NO_INIT;
2223 }
2224 }
2225
2226 camera_metadata_entry_t maxFacesDetected =
2227 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2228 if (!maxFacesDetected.count) return NO_INIT;
2229
2230 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2231
2232 return OK;
2233}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002234
2235status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002236 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002237 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002238
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002239 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002240 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002241
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002242 camera_metadata_entry_t availableProcessedSizes =
2243 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2244 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002245
2246 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002247 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2248 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2249 k.mParameters.videoWidth = k.mParameters.previewWidth;
2250 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002251
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002252 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2253 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002254 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2255 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002256 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257 {
2258 String8 supportedPreviewSizes;
2259 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2260 if (i != 0) supportedPreviewSizes += ",";
2261 supportedPreviewSizes += String8::format("%dx%d",
2262 availableProcessedSizes.data.i32[i],
2263 availableProcessedSizes.data.i32[i+1]);
2264 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002265 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002266 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002267 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002268 supportedPreviewSizes);
2269 }
2270
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002271 camera_metadata_entry_t availableFpsRanges =
2272 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2273 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002274
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002275 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2276 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002278 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2279 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002280 k.mParameters.previewFpsRange[0],
2281 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002282
2283 {
2284 String8 supportedPreviewFpsRange;
2285 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2286 if (i != 0) supportedPreviewFpsRange += ",";
2287 supportedPreviewFpsRange += String8::format("(%d,%d)",
2288 availableFpsRanges.data.i32[i],
2289 availableFpsRanges.data.i32[i+1]);
2290 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002291 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002292 supportedPreviewFpsRange);
2293 }
2294
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002295 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002296 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002297 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002298
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002299 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002300 mCameraFacing == CAMERA_FACING_FRONT);
2301
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002302 camera_metadata_entry_t availableFormats =
2303 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2304
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305 {
2306 String8 supportedPreviewFormats;
2307 bool addComma = false;
2308 for (size_t i=0; i < availableFormats.count; i++) {
2309 if (addComma) supportedPreviewFormats += ",";
2310 addComma = true;
2311 switch (availableFormats.data.i32[i]) {
2312 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002313 supportedPreviewFormats +=
2314 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315 break;
2316 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002317 supportedPreviewFormats +=
2318 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002319 break;
2320 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002321 supportedPreviewFormats +=
2322 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002323 break;
2324 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002325 supportedPreviewFormats +=
2326 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002327 break;
2328 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002329 supportedPreviewFormats +=
2330 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002331 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002332 case HAL_PIXEL_FORMAT_RGBA_8888:
2333 supportedPreviewFormats +=
2334 CameraParameters::PIXEL_FORMAT_RGBA8888;
2335 break;
2336 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002337 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002338 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002339 addComma = false;
2340 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002341
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002342 default:
2343 ALOGW("%s: Camera %d: Unknown preview format: %x",
2344 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2345 addComma = false;
2346 break;
2347 }
2348 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002349 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002350 supportedPreviewFormats);
2351 }
2352
2353 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2354 // still have to do something sane for them
2355
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002356 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002357 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002358
2359 {
2360 String8 supportedPreviewFrameRates;
2361 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2362 if (i != 0) supportedPreviewFrameRates += ",";
2363 supportedPreviewFrameRates += String8::format("%d",
2364 availableFpsRanges.data.i32[i]);
2365 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002366 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002367 supportedPreviewFrameRates);
2368 }
2369
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002370 camera_metadata_entry_t availableJpegSizes =
2371 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2372 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002373
2374 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002375 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2376 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002377
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002378 params.setPictureSize(k.mParameters.pictureWidth,
2379 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002380
2381 {
2382 String8 supportedPictureSizes;
2383 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2384 if (i != 0) supportedPictureSizes += ",";
2385 supportedPictureSizes += String8::format("%dx%d",
2386 availableJpegSizes.data.i32[i],
2387 availableJpegSizes.data.i32[i+1]);
2388 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002389 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002390 supportedPictureSizes);
2391 }
2392
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002393 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2394 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2395 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002396
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002397 camera_metadata_entry_t availableJpegThumbnailSizes =
2398 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2399 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002400
2401 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002402 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2403 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002404
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002405 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002406 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002407 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002408 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002409
2410 {
2411 String8 supportedJpegThumbSizes;
2412 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2413 if (i != 0) supportedJpegThumbSizes += ",";
2414 supportedJpegThumbSizes += String8::format("%dx%d",
2415 availableJpegThumbnailSizes.data.i32[i],
2416 availableJpegThumbnailSizes.data.i32[i+1]);
2417 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002418 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002419 supportedJpegThumbSizes);
2420 }
2421
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002422 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002423 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002424 k.mParameters.jpegThumbQuality);
2425 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002426 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002427 k.mParameters.jpegQuality);
2428 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002429 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002430 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002431
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002432 k.mParameters.gpsEnabled = false;
2433 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002434 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002435
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002436 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002437 params.set(CameraParameters::KEY_WHITE_BALANCE,
2438 CameraParameters::WHITE_BALANCE_AUTO);
2439
2440 camera_metadata_entry_t availableWhiteBalanceModes =
2441 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002442 {
2443 String8 supportedWhiteBalance;
2444 bool addComma = false;
2445 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2446 if (addComma) supportedWhiteBalance += ",";
2447 addComma = true;
2448 switch (availableWhiteBalanceModes.data.u8[i]) {
2449 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002450 supportedWhiteBalance +=
2451 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002452 break;
2453 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002454 supportedWhiteBalance +=
2455 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002456 break;
2457 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002458 supportedWhiteBalance +=
2459 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002460 break;
2461 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002462 supportedWhiteBalance +=
2463 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002464 break;
2465 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002466 supportedWhiteBalance +=
2467 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002468 break;
2469 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002470 supportedWhiteBalance +=
2471 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002472 break;
2473 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002474 supportedWhiteBalance +=
2475 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002476 break;
2477 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002478 supportedWhiteBalance +=
2479 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002480 break;
2481 // Skipping values not mappable to v1 API
2482 case ANDROID_CONTROL_AWB_OFF:
2483 addComma = false;
2484 break;
2485 default:
2486 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2487 __FUNCTION__, mCameraId,
2488 availableWhiteBalanceModes.data.u8[i]);
2489 addComma = false;
2490 break;
2491 }
2492 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002493 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002494 supportedWhiteBalance);
2495 }
2496
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002497 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002498 params.set(CameraParameters::KEY_EFFECT,
2499 CameraParameters::EFFECT_NONE);
2500
2501 camera_metadata_entry_t availableEffects =
2502 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2503 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002504 {
2505 String8 supportedEffects;
2506 bool addComma = false;
2507 for (size_t i=0; i < availableEffects.count; i++) {
2508 if (addComma) supportedEffects += ",";
2509 addComma = true;
2510 switch (availableEffects.data.u8[i]) {
2511 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002512 supportedEffects +=
2513 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002514 break;
2515 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002516 supportedEffects +=
2517 CameraParameters::EFFECT_MONO;
2518 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002519 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002520 supportedEffects +=
2521 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002522 break;
2523 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002524 supportedEffects +=
2525 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002526 break;
2527 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002528 supportedEffects +=
2529 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002530 break;
2531 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002532 supportedEffects +=
2533 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002534 break;
2535 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002536 supportedEffects +=
2537 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002538 break;
2539 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002540 supportedEffects +=
2541 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002542 break;
2543 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002544 supportedEffects +=
2545 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002546 break;
2547 default:
2548 ALOGW("%s: Camera %d: Unknown effect value: %d",
2549 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2550 addComma = false;
2551 break;
2552 }
2553 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002554 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002555 }
2556
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002557 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002558 params.set(CameraParameters::KEY_ANTIBANDING,
2559 CameraParameters::ANTIBANDING_AUTO);
2560
2561 camera_metadata_entry_t availableAntibandingModes =
2562 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2563 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002564 {
2565 String8 supportedAntibanding;
2566 bool addComma = false;
2567 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2568 if (addComma) supportedAntibanding += ",";
2569 addComma = true;
2570 switch (availableAntibandingModes.data.u8[i]) {
2571 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002572 supportedAntibanding +=
2573 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002574 break;
2575 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002576 supportedAntibanding +=
2577 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002578 break;
2579 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002580 supportedAntibanding +=
2581 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002582 break;
2583 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002584 supportedAntibanding +=
2585 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002586 break;
2587 default:
2588 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2589 __FUNCTION__, mCameraId,
2590 availableAntibandingModes.data.u8[i]);
2591 addComma = false;
2592 break;
2593 }
2594 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002595 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002596 supportedAntibanding);
2597 }
2598
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002599 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002600 params.set(CameraParameters::KEY_SCENE_MODE,
2601 CameraParameters::SCENE_MODE_AUTO);
2602
2603 camera_metadata_entry_t availableSceneModes =
2604 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2605 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002606 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002607 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002608 bool addComma = true;
2609 bool noSceneModes = false;
2610 for (size_t i=0; i < availableSceneModes.count; i++) {
2611 if (addComma) supportedSceneModes += ",";
2612 addComma = true;
2613 switch (availableSceneModes.data.u8[i]) {
2614 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2615 noSceneModes = true;
2616 break;
2617 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2618 // Not in old API
2619 addComma = false;
2620 break;
2621 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002622 supportedSceneModes +=
2623 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002624 break;
2625 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002626 supportedSceneModes +=
2627 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002628 break;
2629 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002630 supportedSceneModes +=
2631 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002632 break;
2633 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002634 supportedSceneModes +=
2635 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002636 break;
2637 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002638 supportedSceneModes +=
2639 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002640 break;
2641 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002642 supportedSceneModes +=
2643 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002644 break;
2645 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002646 supportedSceneModes +=
2647 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002648 break;
2649 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002650 supportedSceneModes +=
2651 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002652 break;
2653 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002654 supportedSceneModes +=
2655 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002656 break;
2657 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002658 supportedSceneModes +=
2659 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002660 break;
2661 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002662 supportedSceneModes +=
2663 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002664 break;
2665 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002666 supportedSceneModes +=
2667 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002668 break;
2669 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002670 supportedSceneModes +=
2671 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002672 break;
2673 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002674 supportedSceneModes +=
2675 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002676 break;
2677 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002678 supportedSceneModes +=
2679 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002680 break;
2681 default:
2682 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002683 __FUNCTION__, mCameraId,
2684 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002685 addComma = false;
2686 break;
2687 }
2688 }
2689 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002690 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002691 supportedSceneModes);
2692 }
2693 }
2694
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002695 camera_metadata_entry_t flashAvailable =
2696 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2697 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002698
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002699 camera_metadata_entry_t availableAeModes =
2700 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2701 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002702
2703 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002704 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002705 params.set(CameraParameters::KEY_FLASH_MODE,
2706 CameraParameters::FLASH_MODE_AUTO);
2707
2708 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2709 supportedFlashModes = supportedFlashModes +
2710 "," + CameraParameters::FLASH_MODE_AUTO +
2711 "," + CameraParameters::FLASH_MODE_ON +
2712 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002713 for (size_t i=0; i < availableAeModes.count; i++) {
2714 if (availableAeModes.data.u8[i] ==
2715 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002716 supportedFlashModes = supportedFlashModes + "," +
2717 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002718 break;
2719 }
2720 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002721 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002722 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002723 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002724 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002725 params.set(CameraParameters::KEY_FLASH_MODE,
2726 CameraParameters::FLASH_MODE_OFF);
2727 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2728 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002729 }
2730
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002731 camera_metadata_entry_t minFocusDistance =
2732 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2733 if (!minFocusDistance.count) return NO_INIT;
2734
2735 camera_metadata_entry_t availableAfModes =
2736 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2737 if (!availableAfModes.count) return NO_INIT;
2738
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002739 if (minFocusDistance.data.f[0] == 0) {
2740 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002741 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002742 params.set(CameraParameters::KEY_FOCUS_MODE,
2743 CameraParameters::FOCUS_MODE_FIXED);
2744 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2745 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002746 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002747 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002748 params.set(CameraParameters::KEY_FOCUS_MODE,
2749 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002750 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002751 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002752
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002753 for (size_t i=0; i < availableAfModes.count; i++) {
2754 if (addComma) supportedFocusModes += ",";
2755 addComma = true;
2756 switch (availableAfModes.data.u8[i]) {
2757 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002758 supportedFocusModes +=
2759 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002760 break;
2761 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002762 supportedFocusModes +=
2763 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002764 break;
2765 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002766 supportedFocusModes +=
2767 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002768 break;
2769 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002770 supportedFocusModes +=
2771 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002772 break;
2773 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002774 supportedFocusModes +=
2775 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002776 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002777 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002778 case ANDROID_CONTROL_AF_OFF:
2779 addComma = false;
2780 break;
2781 default:
2782 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2783 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2784 addComma = false;
2785 break;
2786 }
2787 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002788 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002789 supportedFocusModes);
2790 }
2791
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002792 camera_metadata_entry_t max3aRegions =
2793 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2794 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002795
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002796 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002797 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002798 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002799 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002800 k.mParameters.focusingAreas.clear();
2801 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002802
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002803 camera_metadata_entry_t availableFocalLengths =
2804 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2805 if (!availableFocalLengths.count) return NO_INIT;
2806
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002807 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002808 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002809
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002810 camera_metadata_entry_t sensorSize =
2811 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2812 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002813
2814 // The fields of view here assume infinity focus, maximum wide angle
2815 float horizFov = 180 / M_PI *
2816 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2817 float vertFov = 180 / M_PI *
2818 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002819 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2820 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002821
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002822 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002823 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002824 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002825
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002826 camera_metadata_entry_t exposureCompensationRange =
2827 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2828 if (!exposureCompensationRange.count) return NO_INIT;
2829
2830 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002831 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002832 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002833 exposureCompensationRange.data.i32[0]);
2834
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002835 camera_metadata_entry_t exposureCompensationStep =
2836 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2837 if (!exposureCompensationStep.count) return NO_INIT;
2838
2839 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002840 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002841 exposureCompensationStep.data.r[0].denominator);
2842
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002843 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002844 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2845 CameraParameters::FALSE);
2846 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2847 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002848
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002849 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002850 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2851 CameraParameters::FALSE);
2852 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2853 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002854
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002855 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002856 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002857 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002858 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002859 "(0,0,0,0,0)");
2860
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002861 k.mParameters.zoom = 0;
2862 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002863 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002864
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002865 camera_metadata_entry_t maxDigitalZoom =
2866 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2867 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002868
2869 {
2870 String8 zoomRatios;
2871 float zoom = 1.f;
2872 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002873 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002874 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002875 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002876 if (addComma) zoomRatios += ",";
2877 addComma = true;
2878 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2879 zoom += zoomIncrement;
2880 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002881 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002882 }
2883
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002884 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2885 CameraParameters::TRUE);
2886 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2887 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002888
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002889 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002890 "Infinity,Infinity,Infinity");
2891
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002892 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002893 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002894 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002895 0);
2896
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002897 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002898 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002899
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002900 params.set(CameraParameters::KEY_RECORDING_HINT,
2901 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002902
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002903 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2904 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002905
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002906 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2907 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002908
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002909 camera_metadata_entry_t availableVideoStabilizationModes =
2910 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2911 if (!availableVideoStabilizationModes.count) return NO_INIT;
2912
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002913 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002914 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2915 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002916 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002917 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2918 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002919 }
2920
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002921 // Set up initial state for non-Camera.Parameters state variables
2922
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002923 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002924 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002925 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002926 k.mParameters.afTriggerCounter = 0;
2927 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002928
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002929 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002930
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002931 return OK;
2932}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002933
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002934status_t Camera2Client::updateRequests(const Parameters &params) {
2935 status_t res;
2936
2937 res = updatePreviewRequest(params);
2938 if (res != OK) {
2939 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
2940 __FUNCTION__, mCameraId, strerror(-res), res);
2941 return res;
2942 }
2943 res = updateCaptureRequest(params);
2944 if (res != OK) {
2945 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
2946 __FUNCTION__, mCameraId, strerror(-res), res);
2947 return res;
2948 }
2949
2950 res = updateRecordingRequest(params);
2951 if (res != OK) {
2952 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
2953 __FUNCTION__, mCameraId, strerror(-res), res);
2954 return res;
2955 }
2956
2957 if (mState == PREVIEW) {
2958 res = mDevice->setStreamingRequest(mPreviewRequest);
2959 if (res != OK) {
2960 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
2961 __FUNCTION__, mCameraId, strerror(-res), res);
2962 return res;
2963 }
2964 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
2965 res = mDevice->setStreamingRequest(mRecordingRequest);
2966 if (res != OK) {
2967 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
2968 __FUNCTION__, mCameraId, strerror(-res), res);
2969 return res;
2970 }
2971 }
2972 return res;
2973}
2974
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002975status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002976 ATRACE_CALL();
2977 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002978
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002979 if (mPreviewStreamId != NO_STREAM) {
2980 // Check if stream parameters have to change
2981 uint32_t currentWidth, currentHeight;
2982 res = mDevice->getStreamInfo(mPreviewStreamId,
2983 &currentWidth, &currentHeight, 0);
2984 if (res != OK) {
2985 ALOGE("%s: Camera %d: Error querying preview stream info: "
2986 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2987 return res;
2988 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002989 if (currentWidth != (uint32_t)params.previewWidth ||
2990 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002991 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2992 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002993 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002994 res = mDevice->waitUntilDrained();
2995 if (res != OK) {
2996 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2997 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2998 return res;
2999 }
3000 res = mDevice->deleteStream(mPreviewStreamId);
3001 if (res != OK) {
3002 ALOGE("%s: Camera %d: Unable to delete old output stream "
3003 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3004 strerror(-res), res);
3005 return res;
3006 }
3007 mPreviewStreamId = NO_STREAM;
3008 }
3009 }
3010
3011 if (mPreviewStreamId == NO_STREAM) {
3012 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003013 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003014 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3015 &mPreviewStreamId);
3016 if (res != OK) {
3017 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3018 __FUNCTION__, mCameraId, strerror(-res), res);
3019 return res;
3020 }
3021 }
3022
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003023 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003024 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003025 if (res != OK) {
3026 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3027 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3028 return res;
3029 }
3030
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003031 return OK;
3032}
3033
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003034status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003035 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003036 status_t res;
3037 if (mPreviewRequest == NULL) {
3038 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3039 &mPreviewRequest);
3040 if (res != OK) {
3041 ALOGE("%s: Camera %d: Unable to create default preview request: "
3042 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3043 return res;
3044 }
3045 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003046
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003047 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003048 if (res != OK) {
3049 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3050 "request: %s (%d)", __FUNCTION__, mCameraId,
3051 strerror(-res), res);
3052 return res;
3053 }
3054
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003055 return OK;
3056}
3057
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003058status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003059 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003060 status_t res;
3061 // Find out buffer size for JPEG
3062 camera_metadata_entry_t maxJpegSize =
3063 staticInfo(ANDROID_JPEG_MAX_SIZE);
3064 if (maxJpegSize.count == 0) {
3065 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3066 __FUNCTION__, mCameraId);
3067 return INVALID_OPERATION;
3068 }
3069
3070 if (mCaptureConsumer == 0) {
3071 // Create CPU buffer queue endpoint
3072 mCaptureConsumer = new CpuConsumer(1);
3073 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3074 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3075 mCaptureWindow = new SurfaceTextureClient(
3076 mCaptureConsumer->getProducerInterface());
3077 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003078 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3079 "Camera2Client::CaptureHeap");
3080 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003081 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3082 __FUNCTION__, mCameraId);
3083 return NO_MEMORY;
3084 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003085 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003086
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003087 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003088 // Check if stream parameters have to change
3089 uint32_t currentWidth, currentHeight;
3090 res = mDevice->getStreamInfo(mCaptureStreamId,
3091 &currentWidth, &currentHeight, 0);
3092 if (res != OK) {
3093 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3094 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3095 return res;
3096 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003097 if (currentWidth != (uint32_t)params.pictureWidth ||
3098 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003099 res = mDevice->deleteStream(mCaptureStreamId);
3100 if (res != OK) {
3101 ALOGE("%s: Camera %d: Unable to delete old output stream "
3102 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3103 strerror(-res), res);
3104 return res;
3105 }
3106 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003107 }
3108 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003109
3110 if (mCaptureStreamId == NO_STREAM) {
3111 // Create stream for HAL production
3112 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003113 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003114 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3115 &mCaptureStreamId);
3116 if (res != OK) {
3117 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3118 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3119 return res;
3120 }
3121
3122 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003123 return OK;
3124}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003125
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003126status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003127 ATRACE_CALL();
3128 status_t res;
3129 if (mCaptureRequest == NULL) {
3130 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3131 &mCaptureRequest);
3132 if (res != OK) {
3133 ALOGE("%s: Camera %d: Unable to create default still image request:"
3134 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3135 return res;
3136 }
3137 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003138
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003139 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003140 if (res != OK) {
3141 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3142 "request: %s (%d)", __FUNCTION__, mCameraId,
3143 strerror(-res), res);
3144 return res;
3145 }
3146
3147 res = updateEntry(mCaptureRequest,
3148 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003149 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003150 if (res != OK) return res;
3151 res = updateEntry(mCaptureRequest,
3152 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003153 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003154 if (res != OK) return res;
3155 res = updateEntry(mCaptureRequest,
3156 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003157 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003158 if (res != OK) return res;
3159 res = updateEntry(mCaptureRequest,
3160 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003161 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003162 if (res != OK) return res;
3163
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003164 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003165 res = updateEntry(mCaptureRequest,
3166 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003167 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003168 if (res != OK) return res;
3169 res = updateEntry(mCaptureRequest,
3170 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003171 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003172 if (res != OK) return res;
3173 res = updateEntry(mCaptureRequest,
3174 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003175 params.gpsProcessingMethod.string(),
3176 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003177 if (res != OK) return res;
3178 } else {
3179 res = deleteEntry(mCaptureRequest,
3180 ANDROID_JPEG_GPS_COORDINATES);
3181 if (res != OK) return res;
3182 res = deleteEntry(mCaptureRequest,
3183 ANDROID_JPEG_GPS_TIMESTAMP);
3184 if (res != OK) return res;
3185 res = deleteEntry(mCaptureRequest,
3186 ANDROID_JPEG_GPS_PROCESSING_METHOD);
3187 if (res != OK) return res;
3188 }
3189
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003190 return OK;
3191}
3192
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003193status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003194 ATRACE_CALL();
3195 status_t res;
3196 if (mRecordingRequest == NULL) {
3197 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3198 &mRecordingRequest);
3199 if (res != OK) {
3200 ALOGE("%s: Camera %d: Unable to create default recording request:"
3201 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3202 return res;
3203 }
3204 }
3205
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003206 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003207 if (res != OK) {
3208 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3209 "request: %s (%d)", __FUNCTION__, mCameraId,
3210 strerror(-res), res);
3211 return res;
3212 }
3213
3214 return OK;
3215}
3216
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003217status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003218 status_t res;
3219
3220 if (mRecordingConsumer == 0) {
3221 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07003222 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003223 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3224 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3225 mRecordingWindow = new SurfaceTextureClient(
3226 mRecordingConsumer->getProducerInterface());
3227 // Allocate memory later, since we don't know buffer size until receipt
3228 }
3229
3230 if (mRecordingStreamId != NO_STREAM) {
3231 // Check if stream parameters have to change
3232 uint32_t currentWidth, currentHeight;
3233 res = mDevice->getStreamInfo(mRecordingStreamId,
3234 &currentWidth, &currentHeight, 0);
3235 if (res != OK) {
3236 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3237 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3238 return res;
3239 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003240 if (currentWidth != (uint32_t)params.videoWidth ||
3241 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003242 // TODO: Should wait to be sure previous recording has finished
3243 res = mDevice->deleteStream(mRecordingStreamId);
3244 if (res != OK) {
3245 ALOGE("%s: Camera %d: Unable to delete old output stream "
3246 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3247 strerror(-res), res);
3248 return res;
3249 }
3250 mRecordingStreamId = NO_STREAM;
3251 }
3252 }
3253
3254 if (mRecordingStreamId == NO_STREAM) {
3255 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003256 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003257 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003258 if (res != OK) {
3259 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3260 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3261 return res;
3262 }
3263 }
3264
3265 return OK;
3266}
3267
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003268status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
3269 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003270 ATRACE_CALL();
3271 status_t res;
3272 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003273 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003274 if (res != OK) return res;
3275
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003276 uint8_t wbMode = params.autoWhiteBalanceLock ?
3277 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003278 res = updateEntry(request,
3279 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3280 if (res != OK) return res;
3281 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003282 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003283 if (res != OK) return res;
3284 res = updateEntry(request,
3285 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003286 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003287 if (res != OK) return res;
3288
3289 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003290 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003291 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3292 res = updateEntry(request,
3293 ANDROID_CONTROL_MODE, &controlMode, 1);
3294 if (res != OK) return res;
3295 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3296 res = updateEntry(request,
3297 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003298 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003299 if (res != OK) return res;
3300 }
3301
3302 uint8_t flashMode = ANDROID_FLASH_OFF;
3303 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003304 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003305 case Parameters::FLASH_MODE_OFF:
3306 aeMode = ANDROID_CONTROL_AE_ON; break;
3307 case Parameters::FLASH_MODE_AUTO:
3308 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3309 case Parameters::FLASH_MODE_ON:
3310 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3311 case Parameters::FLASH_MODE_TORCH:
3312 aeMode = ANDROID_CONTROL_AE_ON;
3313 flashMode = ANDROID_FLASH_TORCH;
3314 break;
3315 case Parameters::FLASH_MODE_RED_EYE:
3316 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3317 default:
3318 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003319 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003320 return BAD_VALUE;
3321 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003322 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003323
3324 res = updateEntry(request,
3325 ANDROID_FLASH_MODE, &flashMode, 1);
3326 if (res != OK) return res;
3327 res = updateEntry(request,
3328 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3329 if (res != OK) return res;
3330
3331 float focusDistance = 0; // infinity focus in diopters
3332 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003333 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003334 case Parameters::FOCUS_MODE_AUTO:
3335 case Parameters::FOCUS_MODE_MACRO:
3336 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3337 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3338 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003339 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003340 break;
3341 case Parameters::FOCUS_MODE_INFINITY:
3342 case Parameters::FOCUS_MODE_FIXED:
3343 focusMode = ANDROID_CONTROL_AF_OFF;
3344 break;
3345 default:
3346 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003347 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003348 return BAD_VALUE;
3349 }
3350 res = updateEntry(request,
3351 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3352 if (res != OK) return res;
3353 res = updateEntry(request,
3354 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3355 if (res != OK) return res;
3356
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003357 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003358 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3359 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003360 focusingAreas[i + 0] = params.focusingAreas[i].left;
3361 focusingAreas[i + 1] = params.focusingAreas[i].top;
3362 focusingAreas[i + 2] = params.focusingAreas[i].right;
3363 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3364 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003365 }
3366 res = updateEntry(request,
3367 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3368 if (res != OK) return res;
3369 delete[] focusingAreas;
3370
3371 res = updateEntry(request,
3372 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003373 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003374 if (res != OK) return res;
3375
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003376 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003377 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3378 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003379 meteringAreas[i + 0] = params.meteringAreas[i].left;
3380 meteringAreas[i + 1] = params.meteringAreas[i].top;
3381 meteringAreas[i + 2] = params.meteringAreas[i].right;
3382 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3383 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003384 }
3385 res = updateEntry(request,
3386 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3387 if (res != OK) return res;
3388
3389 res = updateEntry(request,
3390 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3391 if (res != OK) return res;
3392 delete[] meteringAreas;
3393
3394 // Need to convert zoom index into a crop rectangle. The rectangle is
3395 // chosen to maximize its area on the sensor
3396
3397 camera_metadata_entry_t maxDigitalZoom =
3398 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3399 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3400 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003401 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003402
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003403 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003404 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003405 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003406 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003407 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003408 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003409 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003410 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003411 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003412 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003413 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3414 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003415
3416 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3417 res = updateEntry(request,
3418 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3419 if (res != OK) return res;
3420
3421 // TODO: Decide how to map recordingHint, or whether just to ignore it
3422
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003423 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003424 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3425 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3426 res = updateEntry(request,
3427 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3428 &vstabMode, 1);
3429 if (res != OK) return res;
3430
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003431 uint8_t faceDetectMode = params.enableFaceDetect ?
3432 mDeviceInfo->bestFaceDetectMode :
3433 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
3434 res = updateEntry(request,
3435 ANDROID_STATS_FACE_DETECT_MODE,
3436 &faceDetectMode, 1);
3437 if (res != OK) return res;
3438
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003439 return OK;
3440}
3441
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003442int Camera2Client::arrayXToNormalized(int width) const {
3443 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3444}
3445
3446int Camera2Client::arrayYToNormalized(int height) const {
3447 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3448}
3449
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003450status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3451 uint32_t tag, const void *data, size_t data_count) {
3452 camera_metadata_entry_t entry;
3453 status_t res;
3454 res = find_camera_metadata_entry(buffer, tag, &entry);
3455 if (res == NAME_NOT_FOUND) {
3456 res = add_camera_metadata_entry(buffer,
3457 tag, data, data_count);
3458 } else if (res == OK) {
3459 res = update_camera_metadata_entry(buffer,
3460 entry.index, data, data_count, NULL);
3461 }
3462
3463 if (res != OK) {
3464 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3465 __FUNCTION__, get_camera_metadata_section_name(tag),
3466 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3467 }
3468 return res;
3469}
3470
3471status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3472 camera_metadata_entry_t entry;
3473 status_t res;
3474 res = find_camera_metadata_entry(buffer, tag, &entry);
3475 if (res == NAME_NOT_FOUND) {
3476 return OK;
3477 } else if (res != OK) {
3478 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3479 __FUNCTION__,
3480 get_camera_metadata_section_name(tag),
3481 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3482 return res;
3483 }
3484 res = delete_camera_metadata_entry(buffer, entry.index);
3485 if (res != OK) {
3486 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3487 __FUNCTION__,
3488 get_camera_metadata_section_name(tag),
3489 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3490 }
3491 return res;
3492}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003493
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003494int Camera2Client::formatStringToEnum(const char *format) {
3495 return
3496 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3497 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3498 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3499 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3500 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3501 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3502 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3503 HAL_PIXEL_FORMAT_YV12 : // YV12
3504 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3505 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3506 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3507 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3508 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3509 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3510 -1;
3511}
3512
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003513const char* Camera2Client::formatEnumToString(int format) {
3514 const char *fmt;
3515 switch(format) {
3516 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3517 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3518 break;
3519 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3520 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3521 break;
3522 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3523 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3524 break;
3525 case HAL_PIXEL_FORMAT_YV12: // YV12
3526 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3527 break;
3528 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3529 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3530 break;
3531 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3532 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3533 break;
3534 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3535 ALOGW("Raw sensor preview format requested.");
3536 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3537 break;
3538 default:
3539 ALOGE("%s: Unknown preview format: %x",
3540 __FUNCTION__, format);
3541 fmt = NULL;
3542 break;
3543 }
3544 return fmt;
3545}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003546
3547int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3548 return
3549 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3550 ANDROID_CONTROL_AWB_AUTO :
3551 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3552 ANDROID_CONTROL_AWB_INCANDESCENT :
3553 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3554 ANDROID_CONTROL_AWB_FLUORESCENT :
3555 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3556 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3557 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3558 ANDROID_CONTROL_AWB_DAYLIGHT :
3559 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3560 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3561 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3562 ANDROID_CONTROL_AWB_TWILIGHT :
3563 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3564 ANDROID_CONTROL_AWB_SHADE :
3565 -1;
3566}
3567
3568int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3569 return
3570 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3571 ANDROID_CONTROL_EFFECT_OFF :
3572 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3573 ANDROID_CONTROL_EFFECT_MONO :
3574 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3575 ANDROID_CONTROL_EFFECT_NEGATIVE :
3576 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3577 ANDROID_CONTROL_EFFECT_SOLARIZE :
3578 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3579 ANDROID_CONTROL_EFFECT_SEPIA :
3580 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3581 ANDROID_CONTROL_EFFECT_POSTERIZE :
3582 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3583 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3584 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3585 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3586 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3587 ANDROID_CONTROL_EFFECT_AQUA :
3588 -1;
3589}
3590
3591int Camera2Client::abModeStringToEnum(const char *abMode) {
3592 return
3593 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3594 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3595 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3596 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3597 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3598 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3599 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3600 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3601 -1;
3602}
3603
3604int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3605 return
3606 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3607 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3608 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3609 ANDROID_CONTROL_SCENE_MODE_ACTION :
3610 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3611 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3612 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3613 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3614 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3615 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3616 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3617 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3618 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3619 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3620 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3621 ANDROID_CONTROL_SCENE_MODE_BEACH :
3622 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3623 ANDROID_CONTROL_SCENE_MODE_SNOW :
3624 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3625 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3626 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3627 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3628 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3629 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3630 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3631 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3632 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3633 ANDROID_CONTROL_SCENE_MODE_PARTY :
3634 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3635 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3636 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3637 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3638 -1;
3639}
3640
3641Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3642 const char *flashMode) {
3643 return
3644 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3645 Parameters::FLASH_MODE_OFF :
3646 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3647 Parameters::FLASH_MODE_AUTO :
3648 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3649 Parameters::FLASH_MODE_ON :
3650 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3651 Parameters::FLASH_MODE_RED_EYE :
3652 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3653 Parameters::FLASH_MODE_TORCH :
3654 Parameters::FLASH_MODE_INVALID;
3655}
3656
3657Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3658 const char *focusMode) {
3659 return
3660 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3661 Parameters::FOCUS_MODE_AUTO :
3662 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3663 Parameters::FOCUS_MODE_INFINITY :
3664 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3665 Parameters::FOCUS_MODE_MACRO :
3666 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3667 Parameters::FOCUS_MODE_FIXED :
3668 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3669 Parameters::FOCUS_MODE_EDOF :
3670 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3671 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3672 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3673 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3674 Parameters::FOCUS_MODE_INVALID;
3675}
3676
3677status_t Camera2Client::parseAreas(const char *areasCStr,
3678 Vector<Parameters::Area> *areas) {
3679 static const size_t NUM_FIELDS = 5;
3680 areas->clear();
3681 if (areasCStr == NULL) {
3682 // If no key exists, use default (0,0,0,0,0)
3683 areas->push();
3684 return OK;
3685 }
3686 String8 areasStr(areasCStr);
3687 ssize_t areaStart = areasStr.find("(", 0) + 1;
3688 while (areaStart != 0) {
3689 const char* area = areasStr.string() + areaStart;
3690 char *numEnd;
3691 int vals[NUM_FIELDS];
3692 for (size_t i = 0; i < NUM_FIELDS; i++) {
3693 errno = 0;
3694 vals[i] = strtol(area, &numEnd, 10);
3695 if (errno || numEnd == area) return BAD_VALUE;
3696 area = numEnd + 1;
3697 }
3698 areas->push(Parameters::Area(
3699 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3700 areaStart = areasStr.find("(", areaStart) + 1;
3701 }
3702 return OK;
3703}
3704
3705status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3706 size_t maxRegions) {
3707 // Definition of valid area can be found in
3708 // include/camera/CameraParameters.h
3709 if (areas.size() == 0) return BAD_VALUE;
3710 if (areas.size() == 1) {
3711 if (areas[0].left == 0 &&
3712 areas[0].top == 0 &&
3713 areas[0].right == 0 &&
3714 areas[0].bottom == 0 &&
3715 areas[0].weight == 0) {
3716 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3717 return OK;
3718 }
3719 }
3720 if (areas.size() > maxRegions) {
3721 ALOGE("%s: Too many areas requested: %d",
3722 __FUNCTION__, areas.size());
3723 return BAD_VALUE;
3724 }
3725
3726 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3727 a != areas.end(); a++) {
3728 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3729 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3730 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3731 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3732 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3733 if (a->left >= a->right) return BAD_VALUE;
3734 if (a->top >= a->bottom) return BAD_VALUE;
3735 }
3736 return OK;
3737}
3738
3739bool Camera2Client::boolFromString(const char *boolStr) {
3740 return !boolStr ? false :
3741 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3742 false;
3743}
3744
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003745int Camera2Client::degToTransform(int degrees, bool mirror) {
3746 if (!mirror) {
3747 if (degrees == 0) return 0;
3748 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3749 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3750 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3751 } else { // Do mirror (horizontal flip)
3752 if (degrees == 0) { // FLIP_H and ROT_0
3753 return HAL_TRANSFORM_FLIP_H;
3754 } else if (degrees == 90) { // FLIP_H and ROT_90
3755 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3756 } else if (degrees == 180) { // FLIP_H and ROT_180
3757 return HAL_TRANSFORM_FLIP_V;
3758 } else if (degrees == 270) { // FLIP_H and ROT_270
3759 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3760 }
3761 }
3762 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3763 return -1;
3764}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003765
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003766
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003767} // namespace android