blob: 92f4f0974a8411d9e24f3f5a28acc09791f04280 [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 Talvala3cc89792012-08-16 16:03:59 -07001305 if (sceneMode != k.mParameters.sceneMode &&
1306 sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001307 camera_metadata_entry_t availableSceneModes =
1308 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1309 for (i = 0; i < availableSceneModes.count; i++) {
1310 if (sceneMode == availableSceneModes.data.u8[i]) break;
1311 }
1312 if (i == availableSceneModes.count) {
1313 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1314 __FUNCTION__,
1315 newParams.get(CameraParameters::KEY_SCENE_MODE));
1316 return BAD_VALUE;
1317 }
1318 }
1319
1320 // FLASH_MODE
1321 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1322 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001323 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001324 camera_metadata_entry_t flashAvailable =
1325 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1326 if (!flashAvailable.data.u8[0] &&
1327 flashMode != Parameters::FLASH_MODE_OFF) {
1328 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1329 "No flash on device", __FUNCTION__,
1330 newParams.get(CameraParameters::KEY_FLASH_MODE));
1331 return BAD_VALUE;
1332 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1333 camera_metadata_entry_t availableAeModes =
1334 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1335 for (i = 0; i < availableAeModes.count; i++) {
1336 if (flashMode == availableAeModes.data.u8[i]) break;
1337 }
1338 if (i == availableAeModes.count) {
1339 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1340 __FUNCTION__,
1341 newParams.get(CameraParameters::KEY_FLASH_MODE));
1342 return BAD_VALUE;
1343 }
1344 } else if (flashMode == -1) {
1345 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1346 __FUNCTION__,
1347 newParams.get(CameraParameters::KEY_FLASH_MODE));
1348 return BAD_VALUE;
1349 }
1350 }
1351
1352 // FOCUS_MODE
1353 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1354 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001355 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001356 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1357 camera_metadata_entry_t minFocusDistance =
1358 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1359 if (minFocusDistance.data.f[0] == 0) {
1360 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1361 "fixed focus lens",
1362 __FUNCTION__,
1363 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1364 return BAD_VALUE;
1365 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1366 camera_metadata_entry_t availableFocusModes =
1367 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1368 for (i = 0; i < availableFocusModes.count; i++) {
1369 if (focusMode == availableFocusModes.data.u8[i]) break;
1370 }
1371 if (i == availableFocusModes.count) {
1372 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1373 __FUNCTION__,
1374 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1375 return BAD_VALUE;
1376 }
1377 }
1378 }
1379 }
1380
1381 // FOCUS_AREAS
1382 Vector<Parameters::Area> focusingAreas;
1383 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1384 &focusingAreas);
1385 size_t max3aRegions =
1386 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1387 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1388 if (res != OK) {
1389 ALOGE("%s: Requested focus areas are malformed: %s",
1390 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1391 return BAD_VALUE;
1392 }
1393
1394 // EXPOSURE_COMPENSATION
1395 int exposureCompensation =
1396 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1397 camera_metadata_entry_t exposureCompensationRange =
1398 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1399 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1400 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1401 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1402 __FUNCTION__, exposureCompensation);
1403 return BAD_VALUE;
1404 }
1405
1406 // AUTO_EXPOSURE_LOCK (always supported)
1407 bool autoExposureLock = boolFromString(
1408 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1409
1410 // AUTO_WHITEBALANCE_LOCK (always supported)
1411 bool autoWhiteBalanceLock = boolFromString(
1412 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1413
1414 // METERING_AREAS
1415 Vector<Parameters::Area> meteringAreas;
1416 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1417 &meteringAreas);
1418 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1419 if (res != OK) {
1420 ALOGE("%s: Requested metering areas are malformed: %s",
1421 __FUNCTION__,
1422 newParams.get(CameraParameters::KEY_METERING_AREAS));
1423 return BAD_VALUE;
1424 }
1425
1426 // ZOOM
1427 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1428 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1429 ALOGE("%s: Requested zoom level %d is not supported",
1430 __FUNCTION__, zoom);
1431 return BAD_VALUE;
1432 }
1433
1434 // VIDEO_SIZE
1435 int videoWidth, videoHeight;
1436 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001437 if (videoWidth != k.mParameters.videoWidth ||
1438 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001439 if (mState == RECORD) {
1440 ALOGE("%s: Video size cannot be updated when recording is active!",
1441 __FUNCTION__);
1442 return BAD_VALUE;
1443 }
1444 camera_metadata_entry_t availableVideoSizes =
1445 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1446 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1447 if (availableVideoSizes.data.i32[i] == videoWidth &&
1448 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1449 }
1450 if (i == availableVideoSizes.count) {
1451 ALOGE("%s: Requested video size %d x %d is not supported",
1452 __FUNCTION__, videoWidth, videoHeight);
1453 return BAD_VALUE;
1454 }
1455 }
1456
1457 // RECORDING_HINT (always supported)
1458 bool recordingHint = boolFromString(
1459 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1460
1461 // VIDEO_STABILIZATION
1462 bool videoStabilization = boolFromString(
1463 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1464 camera_metadata_entry_t availableVideoStabilizationModes =
1465 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1466 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1467 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1468 }
1469
1470 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001471
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001472 k.mParameters.previewWidth = previewWidth;
1473 k.mParameters.previewHeight = previewHeight;
1474 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1475 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1476 k.mParameters.previewFps = previewFps;
1477 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001478
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001479 k.mParameters.pictureWidth = pictureWidth;
1480 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001481
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001482 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1483 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1484 k.mParameters.jpegQuality = jpegQuality;
1485 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001486
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001487 k.mParameters.gpsEnabled = gpsEnabled;
1488 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1489 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1490 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1491 k.mParameters.gpsTimestamp = gpsTimestamp;
1492 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001493
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001494 k.mParameters.wbMode = wbMode;
1495 k.mParameters.effectMode = effectMode;
1496 k.mParameters.antibandingMode = antibandingMode;
1497 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001498
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001499 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001500 if (focusMode != k.mParameters.focusMode) {
1501 k.mParameters.currentAfTriggerId = -1;
1502 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001503 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001504
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001505 k.mParameters.focusingAreas = focusingAreas;
1506 k.mParameters.exposureCompensation = exposureCompensation;
1507 k.mParameters.autoExposureLock = autoExposureLock;
1508 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1509 k.mParameters.meteringAreas = meteringAreas;
1510 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001511
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001512 k.mParameters.videoWidth = videoWidth;
1513 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001514
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001515 k.mParameters.recordingHint = recordingHint;
1516 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001517
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001518 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001519
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001520 res = updateRequests(k.mParameters);
1521
1522 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001523}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001524
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001525String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001526 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001527 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001528 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001529
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001530 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001531
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001532 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001533 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001534}
1535
1536status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001537 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001538 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001539 status_t res;
1540 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001541
1542 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1543 cmd, arg1, arg2);
1544
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001545 switch (cmd) {
1546 case CAMERA_CMD_START_SMOOTH_ZOOM:
1547 return commandStartSmoothZoomL();
1548 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1549 return commandStopSmoothZoomL();
1550 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1551 return commandSetDisplayOrientationL(arg1);
1552 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1553 return commandEnableShutterSoundL(arg1 == 1);
1554 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1555 return commandPlayRecordingSoundL();
1556 case CAMERA_CMD_START_FACE_DETECTION:
1557 return commandStartFaceDetectionL(arg1);
1558 case CAMERA_CMD_STOP_FACE_DETECTION:
1559 return commandStopFaceDetectionL();
1560 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1561 return commandEnableFocusMoveMsgL(arg1 == 1);
1562 case CAMERA_CMD_PING:
1563 return commandPingL();
1564 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1565 return commandSetVideoBufferCountL(arg1);
1566 default:
1567 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1568 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001569 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001570 }
1571}
James Dong983cf232012-08-01 16:39:55 -07001572
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001573status_t Camera2Client::commandStartSmoothZoomL() {
1574 ALOGE("%s: Unimplemented!", __FUNCTION__);
1575 return OK;
1576}
James Dong983cf232012-08-01 16:39:55 -07001577
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001578status_t Camera2Client::commandStopSmoothZoomL() {
1579 ALOGE("%s: Unimplemented!", __FUNCTION__);
1580 return OK;
1581}
James Dong983cf232012-08-01 16:39:55 -07001582
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001583status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1584 LockedParameters::Key k(mParameters);
1585 int transform = degToTransform(degrees,
1586 mCameraFacing == CAMERA_FACING_FRONT);
1587 if (transform == -1) {
1588 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1589 __FUNCTION__, mCameraId, degrees);
1590 return BAD_VALUE;
1591 }
1592 if (transform != k.mParameters.previewTransform &&
1593 mPreviewStreamId != NO_STREAM) {
1594 mDevice->setStreamTransform(mPreviewStreamId, transform);
1595 }
1596 k.mParameters.previewTransform = transform;
1597 return OK;
1598}
1599
1600status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1601 LockedParameters::Key k(mParameters);
1602 if (enable) {
1603 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001604 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001605 }
1606
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001607 // Disabling shutter sound may not be allowed. In that case only
1608 // allow the mediaserver process to disable the sound.
1609 char value[PROPERTY_VALUE_MAX];
1610 property_get("ro.camera.sound.forced", value, "0");
1611 if (strncmp(value, "0", 2) != 0) {
1612 // Disabling shutter sound is not allowed. Deny if the current
1613 // process is not mediaserver.
1614 if (getCallingPid() != getpid()) {
1615 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1616 getCallingPid());
1617 return PERMISSION_DENIED;
1618 }
1619 }
1620
1621 k.mParameters.playShutterSound = false;
1622 return OK;
1623}
1624
1625status_t Camera2Client::commandPlayRecordingSoundL() {
1626 mCameraService->playSound(CameraService::SOUND_RECORDING);
1627 return OK;
1628}
1629
1630status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001631 ALOGV("%s: Camera %d: Starting face detection",
1632 __FUNCTION__, mCameraId);
1633 status_t res;
1634 switch (mState) {
1635 case DISCONNECTED:
1636 case STOPPED:
1637 case WAITING_FOR_PREVIEW_WINDOW:
1638 case STILL_CAPTURE:
1639 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1640 __FUNCTION__, mCameraId);
1641 return INVALID_OPERATION;
1642 case PREVIEW:
1643 case RECORD:
1644 case VIDEO_SNAPSHOT:
1645 // Good to go for starting face detect
1646 break;
1647 }
1648 // Ignoring type
1649 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1650 ALOGE("%s: Camera %d: Face detection not supported",
1651 __FUNCTION__, mCameraId);
1652 return INVALID_OPERATION;
1653 }
1654
1655 LockedParameters::Key k(mParameters);
1656 if (k.mParameters.enableFaceDetect) return OK;
1657
1658 k.mParameters.enableFaceDetect = true;
1659
1660 res = updateRequests(k.mParameters);
1661
1662 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001663}
1664
1665status_t Camera2Client::commandStopFaceDetectionL() {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001666 status_t res = OK;
1667 ALOGV("%s: Camera %d: Stopping face detection",
1668 __FUNCTION__, mCameraId);
1669
1670 LockedParameters::Key k(mParameters);
1671 if (!k.mParameters.enableFaceDetect) return OK;
1672
1673 k.mParameters.enableFaceDetect = false;
1674
1675 if (mState == PREVIEW || mState == RECORD || mState == VIDEO_SNAPSHOT) {
1676 res = updateRequests(k.mParameters);
1677 }
1678
1679 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001680}
1681
1682status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001683 LockedParameters::Key k(mParameters);
1684 k.mParameters.enableFocusMoveMessages = enable;
1685
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001686 return OK;
1687}
1688
1689status_t Camera2Client::commandPingL() {
1690 // Always ping back if access is proper and device is alive
1691 if (mState != DISCONNECTED) {
1692 return OK;
1693 } else {
1694 return NO_INIT;
1695 }
1696}
1697
1698status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001699 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001700 ALOGE("%s: Camera %d: Error setting video buffer count after "
1701 "recording was started", __FUNCTION__, mCameraId);
1702 return INVALID_OPERATION;
1703 }
1704
1705 // 32 is the current upper limit on the video buffer count for BufferQueue
1706 if (count > 32) {
1707 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1708 __FUNCTION__, mCameraId, count);
1709 return BAD_VALUE;
1710 }
1711
1712 // Need to reallocate memory for heap
1713 if (mRecordingHeapCount != count) {
1714 if (mRecordingHeap != 0) {
1715 mRecordingHeap.clear();
1716 mRecordingHeap = NULL;
1717 }
1718 mRecordingHeapCount = count;
1719 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001720
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001721 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001722}
1723
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001724/** Device-related methods */
1725
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001726void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1727 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1728}
1729
1730void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1731 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1732 frameNumber, timestamp);
1733}
1734
1735void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1736 ALOGV("%s: Autofocus state now %d, last trigger %d",
1737 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001738 bool sendCompletedMessage = false;
1739 bool sendMovingMessage = false;
1740
1741 bool success = false;
1742 bool afInMotion = false;
1743 {
1744 LockedParameters::Key k(mParameters);
1745 switch (k.mParameters.focusMode) {
1746 case Parameters::FOCUS_MODE_AUTO:
1747 case Parameters::FOCUS_MODE_MACRO:
1748 // Don't send notifications upstream if they're not for the current AF
1749 // trigger. For example, if cancel was called in between, or if we
1750 // already sent a notification about this AF call.
1751 if (triggerId != k.mParameters.currentAfTriggerId) break;
1752 switch (newState) {
1753 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1754 success = true;
1755 // no break
1756 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1757 sendCompletedMessage = true;
1758 k.mParameters.currentAfTriggerId = -1;
1759 break;
1760 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1761 // Just starting focusing, ignore
1762 break;
1763 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1764 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1765 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1766 default:
1767 // Unexpected in AUTO/MACRO mode
1768 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1769 __FUNCTION__, newState);
1770 break;
1771 }
1772 break;
1773 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1774 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1775 switch (newState) {
1776 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1777 success = true;
1778 // no break
1779 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1780 // Don't send notifications upstream if they're not for
1781 // the current AF trigger. For example, if cancel was
1782 // called in between, or if we already sent a
1783 // notification about this AF call.
1784 // Send both a 'AF done' callback and a 'AF move' callback
1785 if (triggerId != k.mParameters.currentAfTriggerId) break;
1786 sendCompletedMessage = true;
1787 afInMotion = false;
1788 if (k.mParameters.enableFocusMoveMessages &&
1789 k.mParameters.afInMotion) {
1790 sendMovingMessage = true;
1791 }
1792 k.mParameters.currentAfTriggerId = -1;
1793 break;
1794 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1795 // Cancel was called, or we switched state; care if
1796 // currently moving
1797 afInMotion = false;
1798 if (k.mParameters.enableFocusMoveMessages &&
1799 k.mParameters.afInMotion) {
1800 sendMovingMessage = true;
1801 }
1802 break;
1803 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1804 // Start passive scan, inform upstream
1805 afInMotion = true;
1806 // no break
1807 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1808 // Stop passive scan, inform upstream
1809 if (k.mParameters.enableFocusMoveMessages) {
1810 sendMovingMessage = true;
1811 }
1812 break;
1813 }
1814 k.mParameters.afInMotion = afInMotion;
1815 break;
1816 case Parameters::FOCUS_MODE_EDOF:
1817 case Parameters::FOCUS_MODE_INFINITY:
1818 case Parameters::FOCUS_MODE_FIXED:
1819 default:
1820 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1821 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1822 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1823 }
1824 }
1825 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001826 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001827 Mutex::Autolock iccl(mICameraClientLock);
1828 if (mCameraClient != 0) {
1829 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1830 afInMotion ? 1 : 0, 0);
1831 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001832 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001833 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001834 Mutex::Autolock iccl(mICameraClientLock);
1835 if (mCameraClient != 0) {
1836 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1837 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001838 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001839}
1840
1841void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1842 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1843 __FUNCTION__, newState, triggerId);
1844}
1845
1846void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1847 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1848 __FUNCTION__, newState, triggerId);
1849}
1850
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001851void Camera2Client::onNewFrameAvailable() {
1852 status_t res;
1853 camera_metadata_t *frame = NULL;
1854 do {
1855 res = mDevice->getNextFrame(&frame);
1856 if (res != OK) {
1857 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
1858 __FUNCTION__, mCameraId, strerror(-res), res);
1859 return;
1860 }
1861 if (frame != NULL) {
1862 camera_metadata_entry_t entry;
1863 res = find_camera_metadata_entry(frame, ANDROID_REQUEST_FRAME_COUNT,
1864 &entry);
1865 if (res != OK) {
1866 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
1867 __FUNCTION__, mCameraId, strerror(-res), res);
1868 break;
1869 }
1870
1871 res = processFrameFaceDetect(frame);
1872 if (res != OK) break;
1873
1874 free_camera_metadata(frame);
1875 }
1876 } while (frame != NULL);
1877
1878 if (frame != NULL) {
1879 free_camera_metadata(frame);
1880 }
1881 return;
1882}
1883
1884status_t Camera2Client::processFrameFaceDetect(camera_metadata_t *frame) {
1885 status_t res;
1886 camera_metadata_entry_t entry;
1887 bool enableFaceDetect;
1888 {
1889 LockedParameters::Key k(mParameters);
1890 enableFaceDetect = k.mParameters.enableFaceDetect;
1891 }
1892 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_DETECT_MODE,
1893 &entry);
1894 if (res != OK) {
1895 ALOGE("%s: Camera %d: Error reading face mode: %s (%d)",
1896 __FUNCTION__, mCameraId, strerror(-res), res);
1897 return res;
1898 }
1899 uint8_t faceDetectMode = entry.data.u8[0];
1900
1901 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
1902 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_RECTANGLES,
1903 &entry);
1904 if (res != OK) {
1905 ALOGE("%s: Camera %d: Error reading face rectangles: %s (%d)",
1906 __FUNCTION__, mCameraId, strerror(-res), res);
1907 return res;
1908 }
1909 camera_frame_metadata metadata;
1910 metadata.number_of_faces = entry.count / 4;
1911 if (metadata.number_of_faces >
1912 mDeviceInfo->maxFaces) {
1913 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
1914 __FUNCTION__, mCameraId,
1915 metadata.number_of_faces, mDeviceInfo->maxFaces);
1916 return res;
1917 }
1918 int32_t *faceRects = entry.data.i32;
1919
1920 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_SCORES,
1921 &entry);
1922 if (res != OK) {
1923 ALOGE("%s: Camera %d: Error reading face scores: %s (%d)",
1924 __FUNCTION__, mCameraId, strerror(-res), res);
1925 return res;
1926 }
1927 uint8_t *faceScores = entry.data.u8;
1928
1929 int32_t *faceLandmarks = NULL;
1930 int32_t *faceIds = NULL;
1931
1932 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
1933 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_LANDMARKS,
1934 &entry);
1935 if (res != OK) {
1936 ALOGE("%s: Camera %d: Error reading face landmarks: %s (%d)",
1937 __FUNCTION__, mCameraId, strerror(-res), res);
1938 return res;
1939 }
1940 faceLandmarks = entry.data.i32;
1941
1942 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_IDS,
1943 &entry);
1944 if (res != OK) {
1945 ALOGE("%s: Camera %d: Error reading face IDs: %s (%d)",
1946 __FUNCTION__, mCameraId, strerror(-res), res);
1947 return res;
1948 }
1949 faceIds = entry.data.i32;
1950 }
1951
1952 Vector<camera_face_t> faces;
1953 faces.setCapacity(metadata.number_of_faces);
1954
1955 for (int i = 0; i < metadata.number_of_faces; i++) {
1956 camera_face_t face;
1957
1958 face.rect[0] = arrayXToNormalized(faceRects[i*4 + 0]);
1959 face.rect[1] = arrayYToNormalized(faceRects[i*4 + 1]);
1960 face.rect[2] = arrayXToNormalized(faceRects[i*4 + 2]);
1961 face.rect[3] = arrayYToNormalized(faceRects[i*4 + 3]);
1962
1963 face.score = faceScores[i];
1964 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
1965 face.id = faceIds[i];
1966 face.left_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 0]);
1967 face.left_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 1]);
1968 face.right_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 2]);
1969 face.right_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 3]);
1970 face.mouth[0] = arrayXToNormalized(faceLandmarks[i*6 + 4]);
1971 face.mouth[1] = arrayYToNormalized(faceLandmarks[i*6 + 5]);
1972 } else {
1973 face.id = 0;
1974 face.left_eye[0] = face.left_eye[1] = -2000;
1975 face.right_eye[0] = face.right_eye[1] = -2000;
1976 face.mouth[0] = face.mouth[1] = -2000;
1977 }
1978 faces.push_back(face);
1979 }
1980
1981 metadata.faces = faces.editArray();
1982 {
1983 Mutex::Autolock iccl(mICameraClientLock);
1984 if (mCameraClient != NULL) {
1985 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
1986 NULL, &metadata);
1987 }
1988 }
1989 }
1990 return OK;
1991}
1992
1993
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001994void Camera2Client::onCaptureAvailable() {
1995 ATRACE_CALL();
1996 status_t res;
1997 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001998 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1999
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002000 CpuConsumer::LockedBuffer imgBuffer;
2001 {
2002 Mutex::Autolock icl(mICameraLock);
2003
2004 // TODO: Signal errors here upstream
2005 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
2006 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2007 __FUNCTION__, mCameraId);
2008 return;
2009 }
2010
2011 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2012 if (res != OK) {
2013 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2014 __FUNCTION__, mCameraId, strerror(-res), res);
2015 return;
2016 }
2017
2018 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2019 ALOGE("%s: Camera %d: Unexpected format for still image: "
2020 "%x, expected %x", __FUNCTION__, mCameraId,
2021 imgBuffer.format,
2022 HAL_PIXEL_FORMAT_BLOB);
2023 mCaptureConsumer->unlockBuffer(imgBuffer);
2024 return;
2025 }
2026
2027 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002028 void* captureMemory = mCaptureHeap->mHeap->getBase();
2029 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002030 memcpy(captureMemory, imgBuffer.data, size);
2031
2032 mCaptureConsumer->unlockBuffer(imgBuffer);
2033
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002034 switch (mState) {
2035 case STILL_CAPTURE:
2036 mState = STOPPED;
2037 break;
2038 case VIDEO_SNAPSHOT:
2039 mState = RECORD;
2040 break;
2041 default:
2042 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
2043 mCameraId, mState);
2044 break;
2045 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002046
2047 Mutex::Autolock iccl(mICameraClientLock);
2048 currentClient = mCameraClient;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002049 }
2050 // Call outside mICameraLock to allow re-entrancy from notification
2051 if (currentClient != 0) {
2052 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002053 mCaptureHeap->mBuffers[0], NULL);
2054 }
2055}
2056
2057void Camera2Client::onRecordingFrameAvailable() {
2058 ATRACE_CALL();
2059 status_t res;
2060 sp<ICameraClient> currentClient;
2061 size_t heapIdx = 0;
2062 nsecs_t timestamp;
2063 {
2064 Mutex::Autolock icl(mICameraLock);
2065 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002066 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002067 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002068 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2069 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002070 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002071 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002072 }
2073
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002074 buffer_handle_t imgBuffer;
2075 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002076 if (res != OK) {
2077 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2078 __FUNCTION__, mCameraId, strerror(-res), res);
2079 return;
2080 }
2081
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002082 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002083 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002084 return;
2085 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002086
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002087 if (mRecordingHeap == 0) {
2088 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002089 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2090 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002091 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002092 if (mRecordingHeap != 0) {
2093 ALOGV("%s: Camera %d: Previous heap has size %d "
2094 "(new will be %d) bytes", __FUNCTION__, mCameraId,
2095 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07002096 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002097 }
2098 // Need to allocate memory for heap
2099 mRecordingHeap.clear();
2100
James Dong983cf232012-08-01 16:39:55 -07002101 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002102 "Camera2Client::RecordingHeap");
2103 if (mRecordingHeap->mHeap->getSize() == 0) {
2104 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2105 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002106 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002107 return;
2108 }
2109 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002110 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002111 }
2112
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002113 if ( mRecordingHeapFree == 0) {
2114 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2115 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002116 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002117 return;
2118 }
2119 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002120 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002121 mRecordingHeapFree--;
2122
2123 ALOGV("%s: Camera %d: Timestamp %lld",
2124 __FUNCTION__, mCameraId, timestamp);
2125
2126 ssize_t offset;
2127 size_t size;
2128 sp<IMemoryHeap> heap =
2129 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2130 &size);
2131
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002132 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2133 uint32_t type = kMetadataBufferTypeGrallocSource;
2134 memcpy(data, &type, 4);
2135 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
2136 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002137 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002138 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002139 currentClient = mCameraClient;
2140 }
2141 // Call outside mICameraLock to allow re-entrancy from notification
2142 if (currentClient != 0) {
2143 currentClient->dataCallbackTimestamp(timestamp,
2144 CAMERA_MSG_VIDEO_FRAME,
2145 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002146 }
2147}
2148
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002149camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
2150 size_t minCount, size_t maxCount) {
2151 status_t res;
2152 camera_metadata_entry_t entry;
2153 res = find_camera_metadata_entry(mDevice->info(),
2154 tag,
2155 &entry);
2156 if (CC_UNLIKELY( res != OK )) {
2157 const char* tagSection = get_camera_metadata_section_name(tag);
2158 if (tagSection == NULL) tagSection = "<unknown>";
2159 const char* tagName = get_camera_metadata_tag_name(tag);
2160 if (tagName == NULL) tagName = "<unknown>";
2161
2162 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
2163 tagSection, tagName, tag, strerror(-res), res);
2164 entry.count = 0;
2165 entry.data.u8 = NULL;
2166 } else if (CC_UNLIKELY(
2167 (minCount != 0 && entry.count < minCount) ||
2168 (maxCount != 0 && entry.count > maxCount) ) ) {
2169 const char* tagSection = get_camera_metadata_section_name(tag);
2170 if (tagSection == NULL) tagSection = "<unknown>";
2171 const char* tagName = get_camera_metadata_tag_name(tag);
2172 if (tagName == NULL) tagName = "<unknown>";
2173 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2174 "Expected between %d and %d values, but got %d values",
2175 tagSection, tagName, tag, minCount, maxCount, entry.count);
2176 entry.count = 0;
2177 entry.data.u8 = NULL;
2178 }
2179
2180 return entry;
2181}
2182
2183/** Utility methods */
2184
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002185status_t Camera2Client::buildDeviceInfo() {
2186 if (mDeviceInfo != NULL) {
2187 delete mDeviceInfo;
2188 }
2189 DeviceInfo *deviceInfo = new DeviceInfo;
2190 mDeviceInfo = deviceInfo;
2191
2192 camera_metadata_entry_t activeArraySize =
2193 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2194 if (!activeArraySize.count) return NO_INIT;
2195 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2196 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2197
2198 camera_metadata_entry_t availableFaceDetectModes =
2199 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2200 if (!availableFaceDetectModes.count) return NO_INIT;
2201
2202 deviceInfo->bestFaceDetectMode =
2203 ANDROID_STATS_FACE_DETECTION_OFF;
2204 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2205 switch (availableFaceDetectModes.data.u8[i]) {
2206 case ANDROID_STATS_FACE_DETECTION_OFF:
2207 break;
2208 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2209 if (deviceInfo->bestFaceDetectMode !=
2210 ANDROID_STATS_FACE_DETECTION_FULL) {
2211 deviceInfo->bestFaceDetectMode =
2212 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2213 }
2214 break;
2215 case ANDROID_STATS_FACE_DETECTION_FULL:
2216 deviceInfo->bestFaceDetectMode =
2217 ANDROID_STATS_FACE_DETECTION_FULL;
2218 break;
2219 default:
2220 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2221 __FUNCTION__, mCameraId,
2222 availableFaceDetectModes.data.u8[i]);
2223 return NO_INIT;
2224 }
2225 }
2226
2227 camera_metadata_entry_t maxFacesDetected =
2228 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2229 if (!maxFacesDetected.count) return NO_INIT;
2230
2231 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2232
2233 return OK;
2234}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002235
2236status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002237 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002238 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002239
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002240 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002241 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002242
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002243 camera_metadata_entry_t availableProcessedSizes =
2244 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2245 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002246
2247 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002248 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2249 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2250 k.mParameters.videoWidth = k.mParameters.previewWidth;
2251 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002252
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002253 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2254 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002255 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2256 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002257 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002258 {
2259 String8 supportedPreviewSizes;
2260 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2261 if (i != 0) supportedPreviewSizes += ",";
2262 supportedPreviewSizes += String8::format("%dx%d",
2263 availableProcessedSizes.data.i32[i],
2264 availableProcessedSizes.data.i32[i+1]);
2265 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002266 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002267 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002268 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002269 supportedPreviewSizes);
2270 }
2271
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002272 camera_metadata_entry_t availableFpsRanges =
2273 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2274 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002275
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002276 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2277 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002278
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002279 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2280 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002281 k.mParameters.previewFpsRange[0],
2282 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002283
2284 {
2285 String8 supportedPreviewFpsRange;
2286 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2287 if (i != 0) supportedPreviewFpsRange += ",";
2288 supportedPreviewFpsRange += String8::format("(%d,%d)",
2289 availableFpsRanges.data.i32[i],
2290 availableFpsRanges.data.i32[i+1]);
2291 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002292 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002293 supportedPreviewFpsRange);
2294 }
2295
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002296 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002297 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002298 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002299
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002300 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002301 mCameraFacing == CAMERA_FACING_FRONT);
2302
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002303 camera_metadata_entry_t availableFormats =
2304 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2305
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002306 {
2307 String8 supportedPreviewFormats;
2308 bool addComma = false;
2309 for (size_t i=0; i < availableFormats.count; i++) {
2310 if (addComma) supportedPreviewFormats += ",";
2311 addComma = true;
2312 switch (availableFormats.data.i32[i]) {
2313 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002314 supportedPreviewFormats +=
2315 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002316 break;
2317 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002318 supportedPreviewFormats +=
2319 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002320 break;
2321 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002322 supportedPreviewFormats +=
2323 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002324 break;
2325 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002326 supportedPreviewFormats +=
2327 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002328 break;
2329 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002330 supportedPreviewFormats +=
2331 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002332 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002333 case HAL_PIXEL_FORMAT_RGBA_8888:
2334 supportedPreviewFormats +=
2335 CameraParameters::PIXEL_FORMAT_RGBA8888;
2336 break;
2337 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002338 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002339 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002340 addComma = false;
2341 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002342
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002343 default:
2344 ALOGW("%s: Camera %d: Unknown preview format: %x",
2345 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2346 addComma = false;
2347 break;
2348 }
2349 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002350 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002351 supportedPreviewFormats);
2352 }
2353
2354 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2355 // still have to do something sane for them
2356
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002357 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002358 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002359
2360 {
2361 String8 supportedPreviewFrameRates;
2362 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2363 if (i != 0) supportedPreviewFrameRates += ",";
2364 supportedPreviewFrameRates += String8::format("%d",
2365 availableFpsRanges.data.i32[i]);
2366 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002367 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002368 supportedPreviewFrameRates);
2369 }
2370
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002371 camera_metadata_entry_t availableJpegSizes =
2372 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2373 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002374
2375 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002376 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2377 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002378
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002379 params.setPictureSize(k.mParameters.pictureWidth,
2380 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002381
2382 {
2383 String8 supportedPictureSizes;
2384 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2385 if (i != 0) supportedPictureSizes += ",";
2386 supportedPictureSizes += String8::format("%dx%d",
2387 availableJpegSizes.data.i32[i],
2388 availableJpegSizes.data.i32[i+1]);
2389 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002390 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002391 supportedPictureSizes);
2392 }
2393
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002394 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2395 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2396 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002397
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002398 camera_metadata_entry_t availableJpegThumbnailSizes =
2399 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2400 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002401
2402 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002403 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2404 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002405
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002406 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002407 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002408 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002409 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002410
2411 {
2412 String8 supportedJpegThumbSizes;
2413 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2414 if (i != 0) supportedJpegThumbSizes += ",";
2415 supportedJpegThumbSizes += String8::format("%dx%d",
2416 availableJpegThumbnailSizes.data.i32[i],
2417 availableJpegThumbnailSizes.data.i32[i+1]);
2418 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002419 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002420 supportedJpegThumbSizes);
2421 }
2422
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002423 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002424 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002425 k.mParameters.jpegThumbQuality);
2426 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002427 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002428 k.mParameters.jpegQuality);
2429 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002430 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002431 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002432
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002433 k.mParameters.gpsEnabled = false;
2434 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002435 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002436
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002437 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002438 params.set(CameraParameters::KEY_WHITE_BALANCE,
2439 CameraParameters::WHITE_BALANCE_AUTO);
2440
2441 camera_metadata_entry_t availableWhiteBalanceModes =
2442 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002443 {
2444 String8 supportedWhiteBalance;
2445 bool addComma = false;
2446 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2447 if (addComma) supportedWhiteBalance += ",";
2448 addComma = true;
2449 switch (availableWhiteBalanceModes.data.u8[i]) {
2450 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002451 supportedWhiteBalance +=
2452 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002453 break;
2454 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002455 supportedWhiteBalance +=
2456 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002457 break;
2458 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002459 supportedWhiteBalance +=
2460 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002461 break;
2462 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002463 supportedWhiteBalance +=
2464 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002465 break;
2466 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002467 supportedWhiteBalance +=
2468 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002469 break;
2470 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002471 supportedWhiteBalance +=
2472 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002473 break;
2474 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002475 supportedWhiteBalance +=
2476 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002477 break;
2478 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002479 supportedWhiteBalance +=
2480 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002481 break;
2482 // Skipping values not mappable to v1 API
2483 case ANDROID_CONTROL_AWB_OFF:
2484 addComma = false;
2485 break;
2486 default:
2487 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2488 __FUNCTION__, mCameraId,
2489 availableWhiteBalanceModes.data.u8[i]);
2490 addComma = false;
2491 break;
2492 }
2493 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002494 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002495 supportedWhiteBalance);
2496 }
2497
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002498 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002499 params.set(CameraParameters::KEY_EFFECT,
2500 CameraParameters::EFFECT_NONE);
2501
2502 camera_metadata_entry_t availableEffects =
2503 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2504 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002505 {
2506 String8 supportedEffects;
2507 bool addComma = false;
2508 for (size_t i=0; i < availableEffects.count; i++) {
2509 if (addComma) supportedEffects += ",";
2510 addComma = true;
2511 switch (availableEffects.data.u8[i]) {
2512 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002513 supportedEffects +=
2514 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002515 break;
2516 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002517 supportedEffects +=
2518 CameraParameters::EFFECT_MONO;
2519 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002520 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002521 supportedEffects +=
2522 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002523 break;
2524 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002525 supportedEffects +=
2526 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002527 break;
2528 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002529 supportedEffects +=
2530 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002531 break;
2532 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002533 supportedEffects +=
2534 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002535 break;
2536 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002537 supportedEffects +=
2538 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002539 break;
2540 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002541 supportedEffects +=
2542 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002543 break;
2544 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002545 supportedEffects +=
2546 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002547 break;
2548 default:
2549 ALOGW("%s: Camera %d: Unknown effect value: %d",
2550 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2551 addComma = false;
2552 break;
2553 }
2554 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002555 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002556 }
2557
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002558 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002559 params.set(CameraParameters::KEY_ANTIBANDING,
2560 CameraParameters::ANTIBANDING_AUTO);
2561
2562 camera_metadata_entry_t availableAntibandingModes =
2563 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2564 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002565 {
2566 String8 supportedAntibanding;
2567 bool addComma = false;
2568 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2569 if (addComma) supportedAntibanding += ",";
2570 addComma = true;
2571 switch (availableAntibandingModes.data.u8[i]) {
2572 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002573 supportedAntibanding +=
2574 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002575 break;
2576 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002577 supportedAntibanding +=
2578 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002579 break;
2580 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002581 supportedAntibanding +=
2582 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002583 break;
2584 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002585 supportedAntibanding +=
2586 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002587 break;
2588 default:
2589 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2590 __FUNCTION__, mCameraId,
2591 availableAntibandingModes.data.u8[i]);
2592 addComma = false;
2593 break;
2594 }
2595 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002596 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002597 supportedAntibanding);
2598 }
2599
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002600 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002601 params.set(CameraParameters::KEY_SCENE_MODE,
2602 CameraParameters::SCENE_MODE_AUTO);
2603
2604 camera_metadata_entry_t availableSceneModes =
2605 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2606 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002607 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002608 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002609 bool addComma = true;
2610 bool noSceneModes = false;
2611 for (size_t i=0; i < availableSceneModes.count; i++) {
2612 if (addComma) supportedSceneModes += ",";
2613 addComma = true;
2614 switch (availableSceneModes.data.u8[i]) {
2615 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2616 noSceneModes = true;
2617 break;
2618 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2619 // Not in old API
2620 addComma = false;
2621 break;
2622 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002623 supportedSceneModes +=
2624 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002625 break;
2626 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002627 supportedSceneModes +=
2628 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002629 break;
2630 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002631 supportedSceneModes +=
2632 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002633 break;
2634 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002635 supportedSceneModes +=
2636 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002637 break;
2638 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002639 supportedSceneModes +=
2640 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002641 break;
2642 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002643 supportedSceneModes +=
2644 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002645 break;
2646 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002647 supportedSceneModes +=
2648 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002649 break;
2650 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002651 supportedSceneModes +=
2652 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002653 break;
2654 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002655 supportedSceneModes +=
2656 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002657 break;
2658 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002659 supportedSceneModes +=
2660 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002661 break;
2662 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002663 supportedSceneModes +=
2664 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002665 break;
2666 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002667 supportedSceneModes +=
2668 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002669 break;
2670 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002671 supportedSceneModes +=
2672 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002673 break;
2674 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002675 supportedSceneModes +=
2676 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002677 break;
2678 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002679 supportedSceneModes +=
2680 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002681 break;
2682 default:
2683 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002684 __FUNCTION__, mCameraId,
2685 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002686 addComma = false;
2687 break;
2688 }
2689 }
2690 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002691 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002692 supportedSceneModes);
2693 }
2694 }
2695
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002696 camera_metadata_entry_t flashAvailable =
2697 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2698 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002699
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002700 camera_metadata_entry_t availableAeModes =
2701 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2702 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002703
2704 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002705 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002706 params.set(CameraParameters::KEY_FLASH_MODE,
2707 CameraParameters::FLASH_MODE_AUTO);
2708
2709 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2710 supportedFlashModes = supportedFlashModes +
2711 "," + CameraParameters::FLASH_MODE_AUTO +
2712 "," + CameraParameters::FLASH_MODE_ON +
2713 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002714 for (size_t i=0; i < availableAeModes.count; i++) {
2715 if (availableAeModes.data.u8[i] ==
2716 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002717 supportedFlashModes = supportedFlashModes + "," +
2718 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002719 break;
2720 }
2721 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002722 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002723 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002724 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002725 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002726 params.set(CameraParameters::KEY_FLASH_MODE,
2727 CameraParameters::FLASH_MODE_OFF);
2728 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2729 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002730 }
2731
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002732 camera_metadata_entry_t minFocusDistance =
2733 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2734 if (!minFocusDistance.count) return NO_INIT;
2735
2736 camera_metadata_entry_t availableAfModes =
2737 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2738 if (!availableAfModes.count) return NO_INIT;
2739
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002740 if (minFocusDistance.data.f[0] == 0) {
2741 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002742 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002743 params.set(CameraParameters::KEY_FOCUS_MODE,
2744 CameraParameters::FOCUS_MODE_FIXED);
2745 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2746 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002747 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002748 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002749 params.set(CameraParameters::KEY_FOCUS_MODE,
2750 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002751 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002752 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002753
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002754 for (size_t i=0; i < availableAfModes.count; i++) {
2755 if (addComma) supportedFocusModes += ",";
2756 addComma = true;
2757 switch (availableAfModes.data.u8[i]) {
2758 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002759 supportedFocusModes +=
2760 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002761 break;
2762 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002763 supportedFocusModes +=
2764 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002765 break;
2766 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002767 supportedFocusModes +=
2768 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002769 break;
2770 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002771 supportedFocusModes +=
2772 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002773 break;
2774 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002775 supportedFocusModes +=
2776 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002777 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002778 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002779 case ANDROID_CONTROL_AF_OFF:
2780 addComma = false;
2781 break;
2782 default:
2783 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2784 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2785 addComma = false;
2786 break;
2787 }
2788 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002789 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002790 supportedFocusModes);
2791 }
2792
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002793 camera_metadata_entry_t max3aRegions =
2794 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2795 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002796
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002797 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002798 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002799 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002800 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002801 k.mParameters.focusingAreas.clear();
2802 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002803
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002804 camera_metadata_entry_t availableFocalLengths =
2805 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2806 if (!availableFocalLengths.count) return NO_INIT;
2807
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002808 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002809 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002810
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002811 camera_metadata_entry_t sensorSize =
2812 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2813 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002814
2815 // The fields of view here assume infinity focus, maximum wide angle
2816 float horizFov = 180 / M_PI *
2817 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2818 float vertFov = 180 / M_PI *
2819 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002820 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2821 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002822
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002823 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002824 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002825 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002826
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002827 camera_metadata_entry_t exposureCompensationRange =
2828 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2829 if (!exposureCompensationRange.count) return NO_INIT;
2830
2831 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002832 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002833 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002834 exposureCompensationRange.data.i32[0]);
2835
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002836 camera_metadata_entry_t exposureCompensationStep =
2837 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2838 if (!exposureCompensationStep.count) return NO_INIT;
2839
2840 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002841 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002842 exposureCompensationStep.data.r[0].denominator);
2843
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002844 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002845 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2846 CameraParameters::FALSE);
2847 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2848 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002849
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002850 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002851 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2852 CameraParameters::FALSE);
2853 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2854 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002855
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002856 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002857 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002858 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002859 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002860 "(0,0,0,0,0)");
2861
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002862 k.mParameters.zoom = 0;
2863 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002864 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002865
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002866 camera_metadata_entry_t maxDigitalZoom =
2867 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2868 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002869
2870 {
2871 String8 zoomRatios;
2872 float zoom = 1.f;
2873 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002874 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002875 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002876 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002877 if (addComma) zoomRatios += ",";
2878 addComma = true;
2879 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2880 zoom += zoomIncrement;
2881 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002882 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002883 }
2884
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002885 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2886 CameraParameters::TRUE);
2887 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2888 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002889
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002890 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002891 "Infinity,Infinity,Infinity");
2892
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002893 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002894 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002895 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002896 0);
2897
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002898 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002899 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002900
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002901 params.set(CameraParameters::KEY_RECORDING_HINT,
2902 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002903
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002904 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2905 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002906
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002907 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2908 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002909
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002910 camera_metadata_entry_t availableVideoStabilizationModes =
2911 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2912 if (!availableVideoStabilizationModes.count) return NO_INIT;
2913
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002914 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002915 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2916 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002917 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002918 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2919 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002920 }
2921
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002922 // Set up initial state for non-Camera.Parameters state variables
2923
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002924 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002925 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002926 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002927 k.mParameters.afTriggerCounter = 0;
2928 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002929
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002930 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002931
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002932 return OK;
2933}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002934
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002935status_t Camera2Client::updateRequests(const Parameters &params) {
2936 status_t res;
2937
2938 res = updatePreviewRequest(params);
2939 if (res != OK) {
2940 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
2941 __FUNCTION__, mCameraId, strerror(-res), res);
2942 return res;
2943 }
2944 res = updateCaptureRequest(params);
2945 if (res != OK) {
2946 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
2947 __FUNCTION__, mCameraId, strerror(-res), res);
2948 return res;
2949 }
2950
2951 res = updateRecordingRequest(params);
2952 if (res != OK) {
2953 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
2954 __FUNCTION__, mCameraId, strerror(-res), res);
2955 return res;
2956 }
2957
2958 if (mState == PREVIEW) {
2959 res = mDevice->setStreamingRequest(mPreviewRequest);
2960 if (res != OK) {
2961 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
2962 __FUNCTION__, mCameraId, strerror(-res), res);
2963 return res;
2964 }
2965 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
2966 res = mDevice->setStreamingRequest(mRecordingRequest);
2967 if (res != OK) {
2968 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
2969 __FUNCTION__, mCameraId, strerror(-res), res);
2970 return res;
2971 }
2972 }
2973 return res;
2974}
2975
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002976status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002977 ATRACE_CALL();
2978 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002979
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002980 if (mPreviewStreamId != NO_STREAM) {
2981 // Check if stream parameters have to change
2982 uint32_t currentWidth, currentHeight;
2983 res = mDevice->getStreamInfo(mPreviewStreamId,
2984 &currentWidth, &currentHeight, 0);
2985 if (res != OK) {
2986 ALOGE("%s: Camera %d: Error querying preview stream info: "
2987 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2988 return res;
2989 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002990 if (currentWidth != (uint32_t)params.previewWidth ||
2991 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002992 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2993 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002994 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002995 res = mDevice->waitUntilDrained();
2996 if (res != OK) {
2997 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2998 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2999 return res;
3000 }
3001 res = mDevice->deleteStream(mPreviewStreamId);
3002 if (res != OK) {
3003 ALOGE("%s: Camera %d: Unable to delete old output stream "
3004 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3005 strerror(-res), res);
3006 return res;
3007 }
3008 mPreviewStreamId = NO_STREAM;
3009 }
3010 }
3011
3012 if (mPreviewStreamId == NO_STREAM) {
3013 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003014 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003015 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3016 &mPreviewStreamId);
3017 if (res != OK) {
3018 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3019 __FUNCTION__, mCameraId, strerror(-res), res);
3020 return res;
3021 }
3022 }
3023
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003024 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003025 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003026 if (res != OK) {
3027 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3028 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3029 return res;
3030 }
3031
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003032 return OK;
3033}
3034
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003035status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003036 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003037 status_t res;
3038 if (mPreviewRequest == NULL) {
3039 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3040 &mPreviewRequest);
3041 if (res != OK) {
3042 ALOGE("%s: Camera %d: Unable to create default preview request: "
3043 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3044 return res;
3045 }
3046 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003047
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003048 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003049 if (res != OK) {
3050 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3051 "request: %s (%d)", __FUNCTION__, mCameraId,
3052 strerror(-res), res);
3053 return res;
3054 }
3055
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003056 return OK;
3057}
3058
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003059status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003060 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003061 status_t res;
3062 // Find out buffer size for JPEG
3063 camera_metadata_entry_t maxJpegSize =
3064 staticInfo(ANDROID_JPEG_MAX_SIZE);
3065 if (maxJpegSize.count == 0) {
3066 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3067 __FUNCTION__, mCameraId);
3068 return INVALID_OPERATION;
3069 }
3070
3071 if (mCaptureConsumer == 0) {
3072 // Create CPU buffer queue endpoint
3073 mCaptureConsumer = new CpuConsumer(1);
3074 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3075 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3076 mCaptureWindow = new SurfaceTextureClient(
3077 mCaptureConsumer->getProducerInterface());
3078 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003079 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3080 "Camera2Client::CaptureHeap");
3081 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003082 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3083 __FUNCTION__, mCameraId);
3084 return NO_MEMORY;
3085 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003086 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003087
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003088 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003089 // Check if stream parameters have to change
3090 uint32_t currentWidth, currentHeight;
3091 res = mDevice->getStreamInfo(mCaptureStreamId,
3092 &currentWidth, &currentHeight, 0);
3093 if (res != OK) {
3094 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3095 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3096 return res;
3097 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003098 if (currentWidth != (uint32_t)params.pictureWidth ||
3099 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003100 res = mDevice->deleteStream(mCaptureStreamId);
3101 if (res != OK) {
3102 ALOGE("%s: Camera %d: Unable to delete old output stream "
3103 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3104 strerror(-res), res);
3105 return res;
3106 }
3107 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003108 }
3109 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003110
3111 if (mCaptureStreamId == NO_STREAM) {
3112 // Create stream for HAL production
3113 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003114 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003115 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3116 &mCaptureStreamId);
3117 if (res != OK) {
3118 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3119 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3120 return res;
3121 }
3122
3123 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003124 return OK;
3125}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003126
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003127status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003128 ATRACE_CALL();
3129 status_t res;
3130 if (mCaptureRequest == NULL) {
3131 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3132 &mCaptureRequest);
3133 if (res != OK) {
3134 ALOGE("%s: Camera %d: Unable to create default still image request:"
3135 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3136 return res;
3137 }
3138 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003139
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003140 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003141 if (res != OK) {
3142 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3143 "request: %s (%d)", __FUNCTION__, mCameraId,
3144 strerror(-res), res);
3145 return res;
3146 }
3147
3148 res = updateEntry(mCaptureRequest,
3149 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003150 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003151 if (res != OK) return res;
3152 res = updateEntry(mCaptureRequest,
3153 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003154 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003155 if (res != OK) return res;
3156 res = updateEntry(mCaptureRequest,
3157 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003158 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003159 if (res != OK) return res;
3160 res = updateEntry(mCaptureRequest,
3161 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003162 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003163 if (res != OK) return res;
3164
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003165 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003166 res = updateEntry(mCaptureRequest,
3167 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003168 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003169 if (res != OK) return res;
3170 res = updateEntry(mCaptureRequest,
3171 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003172 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003173 if (res != OK) return res;
3174 res = updateEntry(mCaptureRequest,
3175 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003176 params.gpsProcessingMethod.string(),
3177 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003178 if (res != OK) return res;
3179 } else {
3180 res = deleteEntry(mCaptureRequest,
3181 ANDROID_JPEG_GPS_COORDINATES);
3182 if (res != OK) return res;
3183 res = deleteEntry(mCaptureRequest,
3184 ANDROID_JPEG_GPS_TIMESTAMP);
3185 if (res != OK) return res;
3186 res = deleteEntry(mCaptureRequest,
3187 ANDROID_JPEG_GPS_PROCESSING_METHOD);
3188 if (res != OK) return res;
3189 }
3190
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003191 return OK;
3192}
3193
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003194status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003195 ATRACE_CALL();
3196 status_t res;
3197 if (mRecordingRequest == NULL) {
3198 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3199 &mRecordingRequest);
3200 if (res != OK) {
3201 ALOGE("%s: Camera %d: Unable to create default recording request:"
3202 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3203 return res;
3204 }
3205 }
3206
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003207 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003208 if (res != OK) {
3209 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3210 "request: %s (%d)", __FUNCTION__, mCameraId,
3211 strerror(-res), res);
3212 return res;
3213 }
3214
3215 return OK;
3216}
3217
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003218status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003219 status_t res;
3220
3221 if (mRecordingConsumer == 0) {
3222 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07003223 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003224 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3225 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3226 mRecordingWindow = new SurfaceTextureClient(
3227 mRecordingConsumer->getProducerInterface());
3228 // Allocate memory later, since we don't know buffer size until receipt
3229 }
3230
3231 if (mRecordingStreamId != NO_STREAM) {
3232 // Check if stream parameters have to change
3233 uint32_t currentWidth, currentHeight;
3234 res = mDevice->getStreamInfo(mRecordingStreamId,
3235 &currentWidth, &currentHeight, 0);
3236 if (res != OK) {
3237 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3238 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3239 return res;
3240 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003241 if (currentWidth != (uint32_t)params.videoWidth ||
3242 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003243 // TODO: Should wait to be sure previous recording has finished
3244 res = mDevice->deleteStream(mRecordingStreamId);
3245 if (res != OK) {
3246 ALOGE("%s: Camera %d: Unable to delete old output stream "
3247 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3248 strerror(-res), res);
3249 return res;
3250 }
3251 mRecordingStreamId = NO_STREAM;
3252 }
3253 }
3254
3255 if (mRecordingStreamId == NO_STREAM) {
3256 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003257 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003258 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003259 if (res != OK) {
3260 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3261 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3262 return res;
3263 }
3264 }
3265
3266 return OK;
3267}
3268
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003269status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
3270 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003271 ATRACE_CALL();
3272 status_t res;
3273 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003274 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003275 if (res != OK) return res;
3276
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003277 uint8_t wbMode = params.autoWhiteBalanceLock ?
3278 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003279 res = updateEntry(request,
3280 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3281 if (res != OK) return res;
3282 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003283 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003284 if (res != OK) return res;
3285 res = updateEntry(request,
3286 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003287 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003288 if (res != OK) return res;
3289
3290 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003291 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003292 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3293 res = updateEntry(request,
3294 ANDROID_CONTROL_MODE, &controlMode, 1);
3295 if (res != OK) return res;
3296 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3297 res = updateEntry(request,
3298 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003299 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003300 if (res != OK) return res;
3301 }
3302
3303 uint8_t flashMode = ANDROID_FLASH_OFF;
3304 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003305 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003306 case Parameters::FLASH_MODE_OFF:
3307 aeMode = ANDROID_CONTROL_AE_ON; break;
3308 case Parameters::FLASH_MODE_AUTO:
3309 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3310 case Parameters::FLASH_MODE_ON:
3311 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3312 case Parameters::FLASH_MODE_TORCH:
3313 aeMode = ANDROID_CONTROL_AE_ON;
3314 flashMode = ANDROID_FLASH_TORCH;
3315 break;
3316 case Parameters::FLASH_MODE_RED_EYE:
3317 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3318 default:
3319 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003320 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003321 return BAD_VALUE;
3322 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003323 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003324
3325 res = updateEntry(request,
3326 ANDROID_FLASH_MODE, &flashMode, 1);
3327 if (res != OK) return res;
3328 res = updateEntry(request,
3329 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3330 if (res != OK) return res;
3331
3332 float focusDistance = 0; // infinity focus in diopters
3333 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003334 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003335 case Parameters::FOCUS_MODE_AUTO:
3336 case Parameters::FOCUS_MODE_MACRO:
3337 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3338 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3339 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003340 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003341 break;
3342 case Parameters::FOCUS_MODE_INFINITY:
3343 case Parameters::FOCUS_MODE_FIXED:
3344 focusMode = ANDROID_CONTROL_AF_OFF;
3345 break;
3346 default:
3347 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003348 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003349 return BAD_VALUE;
3350 }
3351 res = updateEntry(request,
3352 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3353 if (res != OK) return res;
3354 res = updateEntry(request,
3355 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3356 if (res != OK) return res;
3357
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003358 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003359 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3360 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003361 focusingAreas[i + 0] = params.focusingAreas[i].left;
3362 focusingAreas[i + 1] = params.focusingAreas[i].top;
3363 focusingAreas[i + 2] = params.focusingAreas[i].right;
3364 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3365 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003366 }
3367 res = updateEntry(request,
3368 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3369 if (res != OK) return res;
3370 delete[] focusingAreas;
3371
3372 res = updateEntry(request,
3373 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003374 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003375 if (res != OK) return res;
3376
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003377 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003378 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3379 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003380 meteringAreas[i + 0] = params.meteringAreas[i].left;
3381 meteringAreas[i + 1] = params.meteringAreas[i].top;
3382 meteringAreas[i + 2] = params.meteringAreas[i].right;
3383 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3384 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003385 }
3386 res = updateEntry(request,
3387 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3388 if (res != OK) return res;
3389
3390 res = updateEntry(request,
3391 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3392 if (res != OK) return res;
3393 delete[] meteringAreas;
3394
3395 // Need to convert zoom index into a crop rectangle. The rectangle is
3396 // chosen to maximize its area on the sensor
3397
3398 camera_metadata_entry_t maxDigitalZoom =
3399 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3400 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3401 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003402 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003403
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003404 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003405 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003406 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003407 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003408 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003409 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003410 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003411 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003412 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003413 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003414 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3415 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003416
3417 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3418 res = updateEntry(request,
3419 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3420 if (res != OK) return res;
3421
3422 // TODO: Decide how to map recordingHint, or whether just to ignore it
3423
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003424 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003425 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3426 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3427 res = updateEntry(request,
3428 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3429 &vstabMode, 1);
3430 if (res != OK) return res;
3431
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003432 uint8_t faceDetectMode = params.enableFaceDetect ?
3433 mDeviceInfo->bestFaceDetectMode :
3434 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
3435 res = updateEntry(request,
3436 ANDROID_STATS_FACE_DETECT_MODE,
3437 &faceDetectMode, 1);
3438 if (res != OK) return res;
3439
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003440 return OK;
3441}
3442
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003443int Camera2Client::arrayXToNormalized(int width) const {
3444 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3445}
3446
3447int Camera2Client::arrayYToNormalized(int height) const {
3448 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3449}
3450
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003451status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3452 uint32_t tag, const void *data, size_t data_count) {
3453 camera_metadata_entry_t entry;
3454 status_t res;
3455 res = find_camera_metadata_entry(buffer, tag, &entry);
3456 if (res == NAME_NOT_FOUND) {
3457 res = add_camera_metadata_entry(buffer,
3458 tag, data, data_count);
3459 } else if (res == OK) {
3460 res = update_camera_metadata_entry(buffer,
3461 entry.index, data, data_count, NULL);
3462 }
3463
3464 if (res != OK) {
3465 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3466 __FUNCTION__, get_camera_metadata_section_name(tag),
3467 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3468 }
3469 return res;
3470}
3471
3472status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3473 camera_metadata_entry_t entry;
3474 status_t res;
3475 res = find_camera_metadata_entry(buffer, tag, &entry);
3476 if (res == NAME_NOT_FOUND) {
3477 return OK;
3478 } else if (res != OK) {
3479 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3480 __FUNCTION__,
3481 get_camera_metadata_section_name(tag),
3482 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3483 return res;
3484 }
3485 res = delete_camera_metadata_entry(buffer, entry.index);
3486 if (res != OK) {
3487 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3488 __FUNCTION__,
3489 get_camera_metadata_section_name(tag),
3490 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3491 }
3492 return res;
3493}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003494
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003495int Camera2Client::formatStringToEnum(const char *format) {
3496 return
3497 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3498 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3499 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3500 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3501 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3502 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3503 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3504 HAL_PIXEL_FORMAT_YV12 : // YV12
3505 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3506 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3507 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3508 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3509 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3510 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3511 -1;
3512}
3513
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003514const char* Camera2Client::formatEnumToString(int format) {
3515 const char *fmt;
3516 switch(format) {
3517 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3518 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3519 break;
3520 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3521 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3522 break;
3523 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3524 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3525 break;
3526 case HAL_PIXEL_FORMAT_YV12: // YV12
3527 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3528 break;
3529 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3530 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3531 break;
3532 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3533 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3534 break;
3535 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3536 ALOGW("Raw sensor preview format requested.");
3537 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3538 break;
3539 default:
3540 ALOGE("%s: Unknown preview format: %x",
3541 __FUNCTION__, format);
3542 fmt = NULL;
3543 break;
3544 }
3545 return fmt;
3546}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003547
3548int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3549 return
3550 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3551 ANDROID_CONTROL_AWB_AUTO :
3552 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3553 ANDROID_CONTROL_AWB_INCANDESCENT :
3554 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3555 ANDROID_CONTROL_AWB_FLUORESCENT :
3556 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3557 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3558 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3559 ANDROID_CONTROL_AWB_DAYLIGHT :
3560 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3561 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3562 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3563 ANDROID_CONTROL_AWB_TWILIGHT :
3564 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3565 ANDROID_CONTROL_AWB_SHADE :
3566 -1;
3567}
3568
3569int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3570 return
3571 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3572 ANDROID_CONTROL_EFFECT_OFF :
3573 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3574 ANDROID_CONTROL_EFFECT_MONO :
3575 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3576 ANDROID_CONTROL_EFFECT_NEGATIVE :
3577 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3578 ANDROID_CONTROL_EFFECT_SOLARIZE :
3579 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3580 ANDROID_CONTROL_EFFECT_SEPIA :
3581 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3582 ANDROID_CONTROL_EFFECT_POSTERIZE :
3583 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3584 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3585 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3586 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3587 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3588 ANDROID_CONTROL_EFFECT_AQUA :
3589 -1;
3590}
3591
3592int Camera2Client::abModeStringToEnum(const char *abMode) {
3593 return
3594 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3595 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3596 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3597 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3598 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3599 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3600 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3601 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3602 -1;
3603}
3604
3605int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3606 return
3607 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3608 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3609 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3610 ANDROID_CONTROL_SCENE_MODE_ACTION :
3611 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3612 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3613 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3614 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3615 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3616 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3617 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3618 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3619 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3620 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3621 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3622 ANDROID_CONTROL_SCENE_MODE_BEACH :
3623 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3624 ANDROID_CONTROL_SCENE_MODE_SNOW :
3625 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3626 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3627 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3628 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3629 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3630 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3631 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3632 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3633 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3634 ANDROID_CONTROL_SCENE_MODE_PARTY :
3635 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3636 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3637 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3638 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3639 -1;
3640}
3641
3642Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3643 const char *flashMode) {
3644 return
3645 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3646 Parameters::FLASH_MODE_OFF :
3647 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3648 Parameters::FLASH_MODE_AUTO :
3649 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3650 Parameters::FLASH_MODE_ON :
3651 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3652 Parameters::FLASH_MODE_RED_EYE :
3653 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3654 Parameters::FLASH_MODE_TORCH :
3655 Parameters::FLASH_MODE_INVALID;
3656}
3657
3658Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3659 const char *focusMode) {
3660 return
3661 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3662 Parameters::FOCUS_MODE_AUTO :
3663 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3664 Parameters::FOCUS_MODE_INFINITY :
3665 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3666 Parameters::FOCUS_MODE_MACRO :
3667 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3668 Parameters::FOCUS_MODE_FIXED :
3669 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3670 Parameters::FOCUS_MODE_EDOF :
3671 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3672 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3673 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3674 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3675 Parameters::FOCUS_MODE_INVALID;
3676}
3677
3678status_t Camera2Client::parseAreas(const char *areasCStr,
3679 Vector<Parameters::Area> *areas) {
3680 static const size_t NUM_FIELDS = 5;
3681 areas->clear();
3682 if (areasCStr == NULL) {
3683 // If no key exists, use default (0,0,0,0,0)
3684 areas->push();
3685 return OK;
3686 }
3687 String8 areasStr(areasCStr);
3688 ssize_t areaStart = areasStr.find("(", 0) + 1;
3689 while (areaStart != 0) {
3690 const char* area = areasStr.string() + areaStart;
3691 char *numEnd;
3692 int vals[NUM_FIELDS];
3693 for (size_t i = 0; i < NUM_FIELDS; i++) {
3694 errno = 0;
3695 vals[i] = strtol(area, &numEnd, 10);
3696 if (errno || numEnd == area) return BAD_VALUE;
3697 area = numEnd + 1;
3698 }
3699 areas->push(Parameters::Area(
3700 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3701 areaStart = areasStr.find("(", areaStart) + 1;
3702 }
3703 return OK;
3704}
3705
3706status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3707 size_t maxRegions) {
3708 // Definition of valid area can be found in
3709 // include/camera/CameraParameters.h
3710 if (areas.size() == 0) return BAD_VALUE;
3711 if (areas.size() == 1) {
3712 if (areas[0].left == 0 &&
3713 areas[0].top == 0 &&
3714 areas[0].right == 0 &&
3715 areas[0].bottom == 0 &&
3716 areas[0].weight == 0) {
3717 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3718 return OK;
3719 }
3720 }
3721 if (areas.size() > maxRegions) {
3722 ALOGE("%s: Too many areas requested: %d",
3723 __FUNCTION__, areas.size());
3724 return BAD_VALUE;
3725 }
3726
3727 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3728 a != areas.end(); a++) {
3729 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3730 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3731 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3732 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3733 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3734 if (a->left >= a->right) return BAD_VALUE;
3735 if (a->top >= a->bottom) return BAD_VALUE;
3736 }
3737 return OK;
3738}
3739
3740bool Camera2Client::boolFromString(const char *boolStr) {
3741 return !boolStr ? false :
3742 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3743 false;
3744}
3745
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003746int Camera2Client::degToTransform(int degrees, bool mirror) {
3747 if (!mirror) {
3748 if (degrees == 0) return 0;
3749 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3750 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3751 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3752 } else { // Do mirror (horizontal flip)
3753 if (degrees == 0) { // FLIP_H and ROT_0
3754 return HAL_TRANSFORM_FLIP_H;
3755 } else if (degrees == 90) { // FLIP_H and ROT_90
3756 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3757 } else if (degrees == 180) { // FLIP_H and ROT_180
3758 return HAL_TRANSFORM_FLIP_V;
3759 } else if (degrees == 270) { // FLIP_H and ROT_270
3760 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3761 }
3762 }
3763 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3764 return -1;
3765}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003766
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003767
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003768} // namespace android