blob: aa3050168275dea0f485c9afa67bacc56d9c112a [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
Eino-Ville Talvala78822d72012-07-18 17:52:18 -070027#include <media/hardware/MetadataBufferType.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070028
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070029#include <math.h>
30
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#include "Camera2Client.h"
32
33namespace android {
34
35#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
36#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
37
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43 return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050 int cameraId,
51 int cameraFacing,
52 int clientPid):
53 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070055 mDeviceInfo(NULL),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070058 mCallbackStreamId(NO_STREAM),
59 mCallbackHeapId(0),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070060 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070061 mCaptureRequest(NULL),
62 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070063 mRecordingRequest(NULL),
64 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070066 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070067
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070069
70 LockedParameters::Key k(mParameters);
71 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072}
73
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070074status_t Camera2Client::checkPid(const char* checkLocation) const {
75 int callingPid = getCallingPid();
76 if (callingPid == mClientPid) return NO_ERROR;
77
78 ALOGE("%s: attempt to use a locked camera from a different process"
79 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
80 return PERMISSION_DENIED;
81}
82
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083status_t Camera2Client::initialize(camera_module_t *module)
84{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070085 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070086 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070087 status_t res;
88
89 res = mDevice->initialize(module);
90 if (res != OK) {
91 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
92 __FUNCTION__, mCameraId, strerror(-res), res);
93 return NO_INIT;
94 }
95
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070096 res = mDevice->setNotifyCallback(this);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070097 res = mDevice->setFrameListener(this);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070098
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -070099 res = buildDeviceInfo();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700100 res = buildDefaultParameters();
101 if (res != OK) {
102 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
103 __FUNCTION__, mCameraId, strerror(-res), res);
104 return NO_INIT;
105 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700106
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700108 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
110 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700111 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700112 }
113
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700115}
116
117Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700118 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700119 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
120
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700121 mDestructionStarted = true;
122
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700123 // Rewrite mClientPid to allow shutdown by CameraService
124 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700125 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700126}
127
128status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700129 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700130 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700131 mCameraId,
132 getCameraClient()->asBinder().get(),
133 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700134 result.append(" State: ");
135#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
136
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700137 const Parameters& p = mParameters.unsafeUnlock();
138
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700139 result.append(getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700141 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700144 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700145 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700146 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700147 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700148 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700149 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700150 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700151 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700152 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700153 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700154 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700155 p.jpegQuality, p.jpegThumbQuality);
156 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.gpsEnabled ? "enabled" : "disabled");
159 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700161 p.gpsCoordinates[0], p.gpsCoordinates[1],
162 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700163 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700164 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700166 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700167 }
168
169 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700170 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
175 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
176 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
179 default: result.append("UNKNOWN\n");
180 }
181
182 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700183 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
193 default: result.append("UNKNOWN\n");
194 }
195
196 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700197 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700198 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
202 default: result.append("UNKNOWN\n");
203 }
204
205 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700206 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700207 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
208 result.append("AUTO\n"); break;
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
224 default: result.append("UNKNOWN\n");
225 }
226
227 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700228 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700229 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
230 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
231 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
232 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
233 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
234 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
235 default: result.append("UNKNOWN\n");
236 }
237
238 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700239 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
242 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
243 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
244 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
245 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
246 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
247 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
248 default: result.append("UNKNOWN\n");
249 }
250
251 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700252 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700253 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700254 p.focusingAreas[i].left,
255 p.focusingAreas[i].top,
256 p.focusingAreas[i].right,
257 p.focusingAreas[i].bottom,
258 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700259 }
260
261 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700262 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263
264 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 p.autoExposureLock ? "enabled" : "disabled",
266 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700267
268 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700269 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700270 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700271 p.meteringAreas[i].left,
272 p.meteringAreas[i].top,
273 p.meteringAreas[i].right,
274 p.meteringAreas[i].bottom,
275 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700276 }
277
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700278 result.appendFormat(" Zoom index: %d\n", p.zoom);
279 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
280 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700282 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700284
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700285 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700286 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700287
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700288 result.append(" Current streams:\n");
289 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
290 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292
293 result.append(" Current requests:\n");
294 if (mPreviewRequest != NULL) {
295 result.append(" Preview request:\n");
296 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700297 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700298 } else {
299 result.append(" Preview request: undefined\n");
300 write(fd, result.string(), result.size());
301 }
302
303 if (mCaptureRequest != NULL) {
304 result = " Capture request:\n";
305 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700306 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700307 } else {
308 result = " Capture request: undefined\n";
309 write(fd, result.string(), result.size());
310 }
311
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700312 if (mRecordingRequest != NULL) {
313 result = " Recording request:\n";
314 write(fd, result.string(), result.size());
315 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
316 } else {
317 result = " Recording request: undefined\n";
318 write(fd, result.string(), result.size());
319 }
320
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700321 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700322 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700323
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700324 status_t res = mDevice->dump(fd, args);
325 if (res != OK) {
326 result = String8::format(" Error dumping device: %s (%d)",
327 strerror(-res), res);
328 write(fd, result.string(), result.size());
329 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700330
331#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700332 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700333}
334
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700335const char* Camera2Client::getStateName(State state) {
336#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
337 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700338 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700339 CASE_ENUM_TO_CHAR(STOPPED)
340 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
341 CASE_ENUM_TO_CHAR(PREVIEW)
342 CASE_ENUM_TO_CHAR(RECORD)
343 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
344 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
345 default:
346 return "Unknown state!";
347 break;
348 }
349#undef CASE_ENUM_TO_CHAR
350}
351
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700352// ICamera interface
353
354void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700355 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700356 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700357 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700358 status_t res;
359 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700360
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700361 if (mDevice == 0) return;
362
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700363 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700364
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700365 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700366 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700367 mPreviewStreamId = NO_STREAM;
368 }
369
370 if (mCaptureStreamId != NO_STREAM) {
371 mDevice->deleteStream(mCaptureStreamId);
372 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700373 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700374
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700375 if (mRecordingStreamId != NO_STREAM) {
376 mDevice->deleteStream(mRecordingStreamId);
377 mRecordingStreamId = NO_STREAM;
378 }
379
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700380 if (mCallbackStreamId != NO_STREAM) {
381 mDevice->deleteStream(mCallbackStreamId);
382 mCallbackStreamId = NO_STREAM;
383 }
384
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700385 mDevice.clear();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700386 LockedParameters::Key k(mParameters);
387 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700388
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700389 if (mDeviceInfo != NULL) {
390 delete mDeviceInfo;
391 mDeviceInfo = NULL;
392 }
393
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700394 CameraService::Client::disconnect();
395}
396
397status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700398 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700399 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700400 Mutex::Autolock icl(mICameraLock);
401
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700402 if (mClientPid != 0 && getCallingPid() != mClientPid) {
403 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
404 "current locked to pid %d", __FUNCTION__,
405 mCameraId, getCallingPid(), mClientPid);
406 return BAD_VALUE;
407 }
408
409 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700410
411 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700412 mCameraClient = client;
413
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700414 LockedParameters::Key k(mParameters);
415 k.mParameters.state = STOPPED;
416
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700417 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700418}
419
420status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700421 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700422 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700423 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700424 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
425 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700426
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700427 if (mClientPid == 0) {
428 mClientPid = getCallingPid();
429 return OK;
430 }
431
432 if (mClientPid != getCallingPid()) {
433 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
434 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
435 return EBUSY;
436 }
437
438 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700439}
440
441status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700442 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700443 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700444 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700445 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
446 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700447
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700448 // TODO: Check for uninterruptable conditions
449
450 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700451 Mutex::Autolock iccl(mICameraClientLock);
452
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700453 mClientPid = 0;
454 mCameraClient.clear();
455 return OK;
456 }
457
458 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
459 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
460 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700461}
462
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700463status_t Camera2Client::setPreviewDisplay(
464 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700465 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700466 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700467 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700468 status_t res;
469 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700470
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700471 sp<IBinder> binder;
472 sp<ANativeWindow> window;
473 if (surface != 0) {
474 binder = surface->asBinder();
475 window = surface;
476 }
477
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700478 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700479}
480
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700481status_t Camera2Client::setPreviewTexture(
482 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700483 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700484 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700485 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700486 status_t res;
487 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700488
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700489 sp<IBinder> binder;
490 sp<ANativeWindow> window;
491 if (surfaceTexture != 0) {
492 binder = surfaceTexture->asBinder();
493 window = new SurfaceTextureClient(surfaceTexture);
494 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700495 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700496}
497
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700498status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700499 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700500 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700501 status_t res;
502
503 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700504 ALOGV("%s: Camera %d: New window is same as old window",
505 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700506 return NO_ERROR;
507 }
508
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700509 LockedParameters::Key k(mParameters);
510 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700511 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700512 case RECORD:
513 case STILL_CAPTURE:
514 case VIDEO_SNAPSHOT:
515 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700516 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700517 return INVALID_OPERATION;
518 case STOPPED:
519 case WAITING_FOR_PREVIEW_WINDOW:
520 // OK
521 break;
522 case PREVIEW:
523 // Already running preview - need to stop and create a new stream
524 // TODO: Optimize this so that we don't wait for old stream to drain
525 // before spinning up new stream
526 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700527 k.mParameters.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700528 break;
529 }
530
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700531 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700532 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700534 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
535 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700536 return res;
537 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700538 res = mDevice->deleteStream(mPreviewStreamId);
539 if (res != OK) {
540 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
541 __FUNCTION__, strerror(-res), res);
542 return res;
543 }
544 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700545 }
546
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700547 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700548 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700549
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700550 if (k.mParameters.state == WAITING_FOR_PREVIEW_WINDOW) {
551 return startPreviewL(k.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 }
553
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700554 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700555}
556
557void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700558 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700559 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700560 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700561 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700562 if ( checkPid(__FUNCTION__) != OK) return;
563
564 LockedParameters::Key k(mParameters);
565 setPreviewCallbackFlagL(k.mParameters, flag);
566}
567
568void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
569 status_t res = OK;
570 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
571 ALOGV("%s: setting oneshot", __FUNCTION__);
572 params.previewCallbackOneShot = true;
573 }
574 if (params.previewCallbackFlags != (uint32_t)flag) {
575 params.previewCallbackFlags = flag;
576 switch(params.state) {
577 case PREVIEW:
578 res = startPreviewL(params, true);
579 break;
580 case RECORD:
581 case VIDEO_SNAPSHOT:
582 res = startRecordingL(params, true);
583 break;
584 default:
585 break;
586 }
587 if (res != OK) {
588 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
589 __FUNCTION__, mCameraId, getStateName(params.state));
590 }
591 }
592
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700593}
594
595status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700596 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700597 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700598 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700599 status_t res;
600 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700601 LockedParameters::Key k(mParameters);
602 return startPreviewL(k.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700603}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700604
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700605status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700606 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700607 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700608 if (params.state >= PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700609 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700610 __FUNCTION__, getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700611 return INVALID_OPERATION;
612 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700614 if (mPreviewWindow == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700615 params.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700616 return OK;
617 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700618 params.state = STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700619
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700620 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700621 if (res != OK) {
622 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
623 __FUNCTION__, mCameraId, strerror(-res), res);
624 return res;
625 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700626 bool callbacksEnabled = params.previewCallbackFlags &
627 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
628 if (callbacksEnabled) {
629 res = updateCallbackStream(params);
630 if (res != OK) {
631 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
632 __FUNCTION__, mCameraId, strerror(-res), res);
633 return res;
634 }
635 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700636
637 if (mPreviewRequest == NULL) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700638 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700639 if (res != OK) {
640 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
641 __FUNCTION__, mCameraId, strerror(-res), res);
642 return res;
643 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700644 }
645
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700646 if (callbacksEnabled) {
647 uint8_t outputStreams[2] =
648 { mPreviewStreamId, mCallbackStreamId };
649 res = updateEntry(mPreviewRequest,
650 ANDROID_REQUEST_OUTPUT_STREAMS,
651 outputStreams, 2);
652 } else {
653 res = updateEntry(mPreviewRequest,
654 ANDROID_REQUEST_OUTPUT_STREAMS,
655 &mPreviewStreamId, 1);
656 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700657 if (res != OK) {
658 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
659 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700660 return res;
661 }
662 res = sort_camera_metadata(mPreviewRequest);
663 if (res != OK) {
664 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
665 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666 return res;
667 }
668
669 res = mDevice->setStreamingRequest(mPreviewRequest);
670 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700671 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
672 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700673 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700674 return res;
675 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700676 params.state = PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700677
678 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700679}
680
681void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700682 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700683 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700684 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700685 status_t res;
686 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700687 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700688}
689
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700690void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700691 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700692 State state;
693 {
694 LockedParameters::Key k(mParameters);
695 state = k.mParameters.state;
696 }
697
698 switch (state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700699 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700700 ALOGE("%s: Camera %d: Call before initialized",
701 __FUNCTION__, mCameraId);
702 break;
703 case STOPPED:
704 break;
705 case STILL_CAPTURE:
706 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
707 __FUNCTION__, mCameraId);
708 break;
709 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700710 // no break - identical to preview
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700711 case PREVIEW:
712 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700713 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700714 // no break
715 case WAITING_FOR_PREVIEW_WINDOW: {
716 LockedParameters::Key k(mParameters);
717 k.mParameters.state = STOPPED;
718 commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700719 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700720 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700721 default:
722 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700723 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700724 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700725}
726
727bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700728 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700729 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700730 status_t res;
731 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
732
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700733 LockedParameters::Key k(mParameters);
734 return k.mParameters.state == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700735}
736
737status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700738 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700739 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700740 status_t res;
741 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
742
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700743 LockedParameters::Key k(mParameters);
744 switch (k.mParameters.state) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700745 case RECORD:
746 case VIDEO_SNAPSHOT:
747 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700748 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700749 return INVALID_OPERATION;
750 default:
751 // OK
752 break;
753 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700754
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700755 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700756
757 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700758}
759
760status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700761 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700762 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700763 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700764 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700765 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700766 LockedParameters::Key k(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700767
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700768 return startRecordingL(k.mParameters, false);
769}
770
771status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
772 status_t res;
773 switch (params.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 case STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700775 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700776 if (res != OK) return res;
777 break;
778 case PREVIEW:
779 // Ready to go
780 break;
781 case RECORD:
782 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700783 // OK to call this when recording is already on, just skip unless
784 // we're looking to restart
785 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700786 break;
787 default:
788 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700789 __FUNCTION__, mCameraId, getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700790 return INVALID_OPERATION;
791 };
792
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700793 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700794 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
795 "non-metadata recording mode requested!", __FUNCTION__,
796 mCameraId);
797 return INVALID_OPERATION;
798 }
799
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700800 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700801 if (res != OK) {
802 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
803 __FUNCTION__, mCameraId, strerror(-res), res);
804 return res;
805 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700806 bool callbacksEnabled = params.previewCallbackFlags &
807 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
808 if (callbacksEnabled) {
809 res = updateCallbackStream(params);
810 if (res != OK) {
811 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
812 __FUNCTION__, mCameraId, strerror(-res), res);
813 return res;
814 }
815 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700816
817 if (mRecordingRequest == NULL) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700818 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700819 if (res != OK) {
820 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
821 __FUNCTION__, mCameraId, strerror(-res), res);
822 return res;
823 }
824 }
825
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700826 if (callbacksEnabled) {
827 uint8_t outputStreams[3] =
828 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
829 res = updateEntry(mRecordingRequest,
830 ANDROID_REQUEST_OUTPUT_STREAMS,
831 outputStreams, 3);
832 } else {
833 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
834 res = updateEntry(mRecordingRequest,
835 ANDROID_REQUEST_OUTPUT_STREAMS,
836 outputStreams, 2);
837 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700838 if (res != OK) {
839 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
840 __FUNCTION__, mCameraId, strerror(-res), res);
841 return res;
842 }
843 res = sort_camera_metadata(mRecordingRequest);
844 if (res != OK) {
845 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
846 __FUNCTION__, mCameraId, strerror(-res), res);
847 return res;
848 }
849
850 res = mDevice->setStreamingRequest(mRecordingRequest);
851 if (res != OK) {
852 ALOGE("%s: Camera %d: Unable to set recording request to start "
853 "recording: %s (%d)", __FUNCTION__, mCameraId,
854 strerror(-res), res);
855 return res;
856 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700857 if (params.state < RECORD) {
858 params.state = RECORD;
859 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700860
861 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700862}
863
864void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700865 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700866 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700867 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700868 LockedParameters::Key k(mParameters);
869
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700870 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700871 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
872
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700873 switch (k.mParameters.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700874 case RECORD:
875 // OK to stop
876 break;
877 case STOPPED:
878 case PREVIEW:
879 case STILL_CAPTURE:
880 case VIDEO_SNAPSHOT:
881 default:
882 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700883 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700884 return;
885 };
886
887 // Back to preview. Since record can only be reached through preview,
888 // all preview stream setup should be up to date.
889 res = mDevice->setStreamingRequest(mPreviewRequest);
890 if (res != OK) {
891 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
892 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
893 return;
894 }
895
896 // TODO: Should recording heap be freed? Can't do it yet since requests
897 // could still be in flight.
898
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700899 k.mParameters.state = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700900}
901
902bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700903 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700904 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700905
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700906 if ( checkPid(__FUNCTION__) != OK) return false;
907
James Dong8da4cd72012-08-04 19:58:07 -0700908 return recordingEnabledL();
909}
910
911bool Camera2Client::recordingEnabledL() {
912 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700913 LockedParameters::Key k(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700914
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700915 return (k.mParameters.state == RECORD || k.mParameters.state == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700916}
917
918void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700919 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700920 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700921 status_t res;
922 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700923
924 LockedParameters::Key k(mParameters);
925
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700926 // Make sure this is for the current heap
927 ssize_t offset;
928 size_t size;
929 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
930 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
931 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
932 "(got %x, expected %x)", __FUNCTION__, mCameraId,
933 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
934 return;
935 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700936 uint8_t *data = (uint8_t*)heap->getBase() + offset;
937 uint32_t type = *(uint32_t*)data;
938 if (type != kMetadataBufferTypeGrallocSource) {
939 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
940 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
941 return;
942 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700943
944 // Release the buffer back to the recording queue
945
946 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
947
948 size_t itemIndex;
949 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
950 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
951 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
952 item.mGraphicBuffer->handle == imgHandle) {
953 break;
954 }
955 }
956 if (itemIndex == mRecordingBuffers.size()) {
957 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
958 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
959 return;
960 }
961
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700962 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700963 imgHandle);
964
965 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700966 if (res != OK) {
967 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
968 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700969 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700970 return;
971 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700972 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700973
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700974 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700975}
976
977status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700978 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700979 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700980 status_t res;
981 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
982
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700983 int triggerId;
984 {
985 LockedParameters::Key k(mParameters);
986 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
987 triggerId = k.mParameters.currentAfTriggerId;
988 }
989
990 mDevice->triggerAutofocus(triggerId);
991
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700992 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700993}
994
995status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700996 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700997 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700998 status_t res;
999 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1000
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001001 int triggerId;
1002 {
1003 LockedParameters::Key k(mParameters);
1004 triggerId = ++k.mParameters.afTriggerCounter;
1005 }
1006
1007 mDevice->triggerCancelAutofocus(triggerId);
1008
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001009 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001010}
1011
1012status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001013 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001014 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001015 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001016 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001017
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001018 LockedParameters::Key k(mParameters);
1019 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001020 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001021 case STOPPED:
1022 case WAITING_FOR_PREVIEW_WINDOW:
1023 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1024 __FUNCTION__, mCameraId);
1025 return INVALID_OPERATION;
1026 case PREVIEW:
1027 case RECORD:
1028 // Good to go for takePicture
1029 break;
1030 case STILL_CAPTURE:
1031 case VIDEO_SNAPSHOT:
1032 ALOGE("%s: Camera %d: Already taking a picture",
1033 __FUNCTION__, mCameraId);
1034 return INVALID_OPERATION;
1035 }
1036
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001037 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001038
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001039 res = updateCaptureStream(k.mParameters);
1040 if (res != OK) {
1041 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1042 __FUNCTION__, mCameraId, strerror(-res), res);
1043 return res;
1044 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001045
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001046 if (mCaptureRequest == NULL) {
1047 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001048 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001049 ALOGE("%s: Camera %d: Can't create still image capture request: "
1050 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001051 return res;
1052 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001053 }
1054
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001055 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001056
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001057 bool callbacksEnabled = k.mParameters.previewCallbackFlags &
1058 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
1059 bool recordingEnabled = (k.mParameters.state == RECORD);
1060
1061 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1062 (recordingEnabled ? 0x1 : 0x0);
1063 switch ( streamSwitch ) {
1064 case 0: { // No recording, callbacks
1065 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
1066 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1067 &streamIds, 2);
1068 break;
1069 }
1070 case 1: { // Recording
1071 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1072 mCaptureStreamId };
1073 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1074 &streamIds, 3);
1075 break;
1076 }
1077 case 2: { // Callbacks
1078 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1079 mCaptureStreamId };
1080 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1081 &streamIds, 3);
1082 break;
1083 }
1084 case 3: { // Both
1085 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1086 mRecordingStreamId, mCaptureStreamId };
1087 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
1088 &streamIds, 4);
1089 break;
1090 }
1091 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001092 if (res != OK) {
1093 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1094 "%s (%d)",
1095 __FUNCTION__, mCameraId, strerror(-res), res);
1096 return res;
1097 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001098 res = sort_camera_metadata(mCaptureRequest);
1099 if (res != OK) {
1100 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1101 __FUNCTION__, mCameraId, strerror(-res), res);
1102 return res;
1103 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001104
1105 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
1106 if (captureCopy == NULL) {
1107 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1108 __FUNCTION__, mCameraId);
1109 return NO_MEMORY;
1110 }
1111
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001112 if (k.mParameters.state == PREVIEW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001113 res = mDevice->setStreamingRequest(NULL);
1114 if (res != OK) {
1115 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1116 "%s (%d)",
1117 __FUNCTION__, mCameraId, strerror(-res), res);
1118 return res;
1119 }
1120 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001121 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001122 res = mDevice->capture(captureCopy);
1123 if (res != OK) {
1124 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1125 "%s (%d)",
1126 __FUNCTION__, mCameraId, strerror(-res), res);
1127 return res;
1128 }
1129
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001130 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001131 case PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001132 k.mParameters.state = STILL_CAPTURE;
1133 res = commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001134 if (res != OK) {
1135 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1136 __FUNCTION__, mCameraId);
1137 return res;
1138 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001139 break;
1140 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001141 k.mParameters.state = VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001142 break;
1143 default:
1144 ALOGE("%s: Camera %d: Unknown state for still capture!",
1145 __FUNCTION__, mCameraId);
1146 return INVALID_OPERATION;
1147 }
1148
1149 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001150}
1151
1152status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001153 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001154 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001155 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001156 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001157 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1158
1159 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001160
1161 CameraParameters newParams(params);
1162
1163 // TODO: Currently ignoring any changes to supposedly read-only
1164 // parameters such as supported preview sizes, etc. Should probably
1165 // produce an error if they're changed.
1166
1167 /** Extract and verify new parameters */
1168
1169 size_t i;
1170
1171 // PREVIEW_SIZE
1172 int previewWidth, previewHeight;
1173 newParams.getPreviewSize(&previewWidth, &previewHeight);
1174
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001175 if (previewWidth != k.mParameters.previewWidth ||
1176 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001177 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001178 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001179 "is active! (Currently %d x %d, requested %d x %d",
1180 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001181 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001182 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001183 return BAD_VALUE;
1184 }
1185 camera_metadata_entry_t availablePreviewSizes =
1186 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1187 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1188 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1189 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1190 }
1191 if (i == availablePreviewSizes.count) {
1192 ALOGE("%s: Requested preview size %d x %d is not supported",
1193 __FUNCTION__, previewWidth, previewHeight);
1194 return BAD_VALUE;
1195 }
1196 }
1197
1198 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001199 int previewFpsRange[2];
1200 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001201 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001202 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001203 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1204 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001205 fpsRangeChanged = true;
1206 camera_metadata_entry_t availablePreviewFpsRanges =
1207 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1208 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1209 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001210 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001211 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001212 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001213 break;
1214 }
1215 }
1216 if (i == availablePreviewFpsRanges.count) {
1217 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001218 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001219 return BAD_VALUE;
1220 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001221 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001222 }
1223
1224 // PREVIEW_FORMAT
1225 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001226 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001227 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001228 ALOGE("%s: Preview format cannot be updated when preview "
1229 "is active!", __FUNCTION__);
1230 return BAD_VALUE;
1231 }
1232 camera_metadata_entry_t availableFormats =
1233 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1234 for (i = 0; i < availableFormats.count; i++) {
1235 if (availableFormats.data.i32[i] == previewFormat) break;
1236 }
1237 if (i == availableFormats.count) {
1238 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1239 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1240 return BAD_VALUE;
1241 }
1242 }
1243
1244 // PREVIEW_FRAME_RATE
1245 // Deprecated, only use if the preview fps range is unchanged this time.
1246 // The single-value FPS is the same as the minimum of the range.
1247 if (!fpsRangeChanged) {
1248 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001249 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001250 camera_metadata_entry_t availableFrameRates =
1251 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1252 for (i = 0; i < availableFrameRates.count; i+=2) {
1253 if (availableFrameRates.data.i32[i] == previewFps) break;
1254 }
1255 if (i == availableFrameRates.count) {
1256 ALOGE("%s: Requested preview frame rate %d is not supported",
1257 __FUNCTION__, previewFps);
1258 return BAD_VALUE;
1259 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001260 previewFpsRange[0] = availableFrameRates.data.i32[i];
1261 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001262 }
1263 }
1264
1265 // PICTURE_SIZE
1266 int pictureWidth, pictureHeight;
1267 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001268 if (pictureWidth == k.mParameters.pictureWidth ||
1269 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001270 camera_metadata_entry_t availablePictureSizes =
1271 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1272 for (i = 0; i < availablePictureSizes.count; i+=2) {
1273 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1274 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1275 }
1276 if (i == availablePictureSizes.count) {
1277 ALOGE("%s: Requested picture size %d x %d is not supported",
1278 __FUNCTION__, pictureWidth, pictureHeight);
1279 return BAD_VALUE;
1280 }
1281 }
1282
1283 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001284 int jpegThumbSize[2];
1285 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001286 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001287 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001288 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001289 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1290 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001291 camera_metadata_entry_t availableJpegThumbSizes =
1292 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1293 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001294 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1295 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001296 break;
1297 }
1298 }
1299 if (i == availableJpegThumbSizes.count) {
1300 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001301 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001302 return BAD_VALUE;
1303 }
1304 }
1305
1306 // JPEG_THUMBNAIL_QUALITY
1307 int jpegThumbQuality =
1308 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1309 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1310 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1311 __FUNCTION__, jpegThumbQuality);
1312 return BAD_VALUE;
1313 }
1314
1315 // JPEG_QUALITY
1316 int jpegQuality =
1317 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1318 if (jpegQuality < 0 || jpegQuality > 100) {
1319 ALOGE("%s: Requested JPEG quality %d is not supported",
1320 __FUNCTION__, jpegQuality);
1321 return BAD_VALUE;
1322 }
1323
1324 // ROTATION
1325 int jpegRotation =
1326 newParams.getInt(CameraParameters::KEY_ROTATION);
1327 if (jpegRotation != 0 &&
1328 jpegRotation != 90 &&
1329 jpegRotation != 180 &&
1330 jpegRotation != 270) {
1331 ALOGE("%s: Requested picture rotation angle %d is not supported",
1332 __FUNCTION__, jpegRotation);
1333 return BAD_VALUE;
1334 }
1335
1336 // GPS
1337 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001338 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001339 int64_t gpsTimestamp = 0;
1340 String8 gpsProcessingMethod;
1341 const char *gpsLatStr =
1342 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1343 if (gpsLatStr != NULL) {
1344 const char *gpsLongStr =
1345 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1346 const char *gpsAltitudeStr =
1347 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1348 const char *gpsTimeStr =
1349 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1350 const char *gpsProcMethodStr =
1351 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1352 if (gpsLongStr == NULL ||
1353 gpsAltitudeStr == NULL ||
1354 gpsTimeStr == NULL ||
1355 gpsProcMethodStr == NULL) {
1356 ALOGE("%s: Incomplete set of GPS parameters provided",
1357 __FUNCTION__);
1358 return BAD_VALUE;
1359 }
1360 char *endPtr;
1361 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001362 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001363 if (errno || endPtr == gpsLatStr) {
1364 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1365 return BAD_VALUE;
1366 }
1367 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001368 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001369 if (errno || endPtr == gpsLongStr) {
1370 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1371 return BAD_VALUE;
1372 }
1373 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001374 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001375 if (errno || endPtr == gpsAltitudeStr) {
1376 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1377 gpsAltitudeStr);
1378 return BAD_VALUE;
1379 }
1380 errno = 0;
1381 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1382 if (errno || endPtr == gpsTimeStr) {
1383 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1384 return BAD_VALUE;
1385 }
1386 gpsProcessingMethod = gpsProcMethodStr;
1387
1388 gpsEnabled = true;
1389 }
1390
1391 // WHITE_BALANCE
1392 int wbMode = wbModeStringToEnum(
1393 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001394 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001395 camera_metadata_entry_t availableWbModes =
1396 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1397 for (i = 0; i < availableWbModes.count; i++) {
1398 if (wbMode == availableWbModes.data.u8[i]) break;
1399 }
1400 if (i == availableWbModes.count) {
1401 ALOGE("%s: Requested white balance mode %s is not supported",
1402 __FUNCTION__,
1403 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1404 return BAD_VALUE;
1405 }
1406 }
1407
1408 // EFFECT
1409 int effectMode = effectModeStringToEnum(
1410 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001411 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001412 camera_metadata_entry_t availableEffectModes =
1413 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1414 for (i = 0; i < availableEffectModes.count; i++) {
1415 if (effectMode == availableEffectModes.data.u8[i]) break;
1416 }
1417 if (i == availableEffectModes.count) {
1418 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1419 __FUNCTION__,
1420 newParams.get(CameraParameters::KEY_EFFECT) );
1421 return BAD_VALUE;
1422 }
1423 }
1424
1425 // ANTIBANDING
1426 int antibandingMode = abModeStringToEnum(
1427 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001428 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001429 camera_metadata_entry_t availableAbModes =
1430 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1431 for (i = 0; i < availableAbModes.count; i++) {
1432 if (antibandingMode == availableAbModes.data.u8[i]) break;
1433 }
1434 if (i == availableAbModes.count) {
1435 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1436 __FUNCTION__,
1437 newParams.get(CameraParameters::KEY_ANTIBANDING));
1438 return BAD_VALUE;
1439 }
1440 }
1441
1442 // SCENE_MODE
1443 int sceneMode = sceneModeStringToEnum(
1444 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala3cc89792012-08-16 16:03:59 -07001445 if (sceneMode != k.mParameters.sceneMode &&
1446 sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001447 camera_metadata_entry_t availableSceneModes =
1448 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1449 for (i = 0; i < availableSceneModes.count; i++) {
1450 if (sceneMode == availableSceneModes.data.u8[i]) break;
1451 }
1452 if (i == availableSceneModes.count) {
1453 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1454 __FUNCTION__,
1455 newParams.get(CameraParameters::KEY_SCENE_MODE));
1456 return BAD_VALUE;
1457 }
1458 }
1459
1460 // FLASH_MODE
1461 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1462 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001463 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001464 camera_metadata_entry_t flashAvailable =
1465 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1466 if (!flashAvailable.data.u8[0] &&
1467 flashMode != Parameters::FLASH_MODE_OFF) {
1468 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1469 "No flash on device", __FUNCTION__,
1470 newParams.get(CameraParameters::KEY_FLASH_MODE));
1471 return BAD_VALUE;
1472 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1473 camera_metadata_entry_t availableAeModes =
1474 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1475 for (i = 0; i < availableAeModes.count; i++) {
1476 if (flashMode == availableAeModes.data.u8[i]) break;
1477 }
1478 if (i == availableAeModes.count) {
1479 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1480 __FUNCTION__,
1481 newParams.get(CameraParameters::KEY_FLASH_MODE));
1482 return BAD_VALUE;
1483 }
1484 } else if (flashMode == -1) {
1485 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1486 __FUNCTION__,
1487 newParams.get(CameraParameters::KEY_FLASH_MODE));
1488 return BAD_VALUE;
1489 }
1490 }
1491
1492 // FOCUS_MODE
1493 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1494 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001495 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001496 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1497 camera_metadata_entry_t minFocusDistance =
1498 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1499 if (minFocusDistance.data.f[0] == 0) {
1500 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1501 "fixed focus lens",
1502 __FUNCTION__,
1503 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1504 return BAD_VALUE;
1505 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1506 camera_metadata_entry_t availableFocusModes =
1507 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1508 for (i = 0; i < availableFocusModes.count; i++) {
1509 if (focusMode == availableFocusModes.data.u8[i]) break;
1510 }
1511 if (i == availableFocusModes.count) {
1512 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1513 __FUNCTION__,
1514 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1515 return BAD_VALUE;
1516 }
1517 }
1518 }
1519 }
1520
1521 // FOCUS_AREAS
1522 Vector<Parameters::Area> focusingAreas;
1523 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1524 &focusingAreas);
1525 size_t max3aRegions =
1526 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1527 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1528 if (res != OK) {
1529 ALOGE("%s: Requested focus areas are malformed: %s",
1530 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1531 return BAD_VALUE;
1532 }
1533
1534 // EXPOSURE_COMPENSATION
1535 int exposureCompensation =
1536 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1537 camera_metadata_entry_t exposureCompensationRange =
1538 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1539 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1540 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1541 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1542 __FUNCTION__, exposureCompensation);
1543 return BAD_VALUE;
1544 }
1545
1546 // AUTO_EXPOSURE_LOCK (always supported)
1547 bool autoExposureLock = boolFromString(
1548 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1549
1550 // AUTO_WHITEBALANCE_LOCK (always supported)
1551 bool autoWhiteBalanceLock = boolFromString(
1552 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1553
1554 // METERING_AREAS
1555 Vector<Parameters::Area> meteringAreas;
1556 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1557 &meteringAreas);
1558 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1559 if (res != OK) {
1560 ALOGE("%s: Requested metering areas are malformed: %s",
1561 __FUNCTION__,
1562 newParams.get(CameraParameters::KEY_METERING_AREAS));
1563 return BAD_VALUE;
1564 }
1565
1566 // ZOOM
1567 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1568 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1569 ALOGE("%s: Requested zoom level %d is not supported",
1570 __FUNCTION__, zoom);
1571 return BAD_VALUE;
1572 }
1573
1574 // VIDEO_SIZE
1575 int videoWidth, videoHeight;
1576 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001577 if (videoWidth != k.mParameters.videoWidth ||
1578 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001579 if (k.mParameters.state == RECORD) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001580 ALOGE("%s: Video size cannot be updated when recording is active!",
1581 __FUNCTION__);
1582 return BAD_VALUE;
1583 }
1584 camera_metadata_entry_t availableVideoSizes =
1585 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1586 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1587 if (availableVideoSizes.data.i32[i] == videoWidth &&
1588 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1589 }
1590 if (i == availableVideoSizes.count) {
1591 ALOGE("%s: Requested video size %d x %d is not supported",
1592 __FUNCTION__, videoWidth, videoHeight);
1593 return BAD_VALUE;
1594 }
1595 }
1596
1597 // RECORDING_HINT (always supported)
1598 bool recordingHint = boolFromString(
1599 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1600
1601 // VIDEO_STABILIZATION
1602 bool videoStabilization = boolFromString(
1603 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1604 camera_metadata_entry_t availableVideoStabilizationModes =
1605 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1606 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1607 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1608 }
1609
1610 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001611
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001612 k.mParameters.previewWidth = previewWidth;
1613 k.mParameters.previewHeight = previewHeight;
1614 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1615 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1616 k.mParameters.previewFps = previewFps;
1617 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001618
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001619 k.mParameters.pictureWidth = pictureWidth;
1620 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001621
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001622 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1623 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1624 k.mParameters.jpegQuality = jpegQuality;
1625 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001626
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001627 k.mParameters.gpsEnabled = gpsEnabled;
1628 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1629 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1630 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1631 k.mParameters.gpsTimestamp = gpsTimestamp;
1632 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001633
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001634 k.mParameters.wbMode = wbMode;
1635 k.mParameters.effectMode = effectMode;
1636 k.mParameters.antibandingMode = antibandingMode;
1637 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001638
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001639 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001640 if (focusMode != k.mParameters.focusMode) {
1641 k.mParameters.currentAfTriggerId = -1;
1642 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001643 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001644
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001645 k.mParameters.focusingAreas = focusingAreas;
1646 k.mParameters.exposureCompensation = exposureCompensation;
1647 k.mParameters.autoExposureLock = autoExposureLock;
1648 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1649 k.mParameters.meteringAreas = meteringAreas;
1650 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001651
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001652 k.mParameters.videoWidth = videoWidth;
1653 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001654
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001655 k.mParameters.recordingHint = recordingHint;
1656 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001657
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001658 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001659
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001660 res = updateRequests(k.mParameters);
1661
1662 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001663}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001664
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001665String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001666 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001667 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001668 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001669
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001670 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001671
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001672 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001673 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001674}
1675
1676status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001677 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001678 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001679 status_t res;
1680 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001681
1682 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1683 cmd, arg1, arg2);
1684
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001685 switch (cmd) {
1686 case CAMERA_CMD_START_SMOOTH_ZOOM:
1687 return commandStartSmoothZoomL();
1688 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1689 return commandStopSmoothZoomL();
1690 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1691 return commandSetDisplayOrientationL(arg1);
1692 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1693 return commandEnableShutterSoundL(arg1 == 1);
1694 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1695 return commandPlayRecordingSoundL();
1696 case CAMERA_CMD_START_FACE_DETECTION:
1697 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001698 case CAMERA_CMD_STOP_FACE_DETECTION: {
1699 LockedParameters::Key k(mParameters);
1700 return commandStopFaceDetectionL(k.mParameters);
1701 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001702 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1703 return commandEnableFocusMoveMsgL(arg1 == 1);
1704 case CAMERA_CMD_PING:
1705 return commandPingL();
1706 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1707 return commandSetVideoBufferCountL(arg1);
1708 default:
1709 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1710 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001711 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001712 }
1713}
James Dong983cf232012-08-01 16:39:55 -07001714
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001715status_t Camera2Client::commandStartSmoothZoomL() {
1716 ALOGE("%s: Unimplemented!", __FUNCTION__);
1717 return OK;
1718}
James Dong983cf232012-08-01 16:39:55 -07001719
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001720status_t Camera2Client::commandStopSmoothZoomL() {
1721 ALOGE("%s: Unimplemented!", __FUNCTION__);
1722 return OK;
1723}
James Dong983cf232012-08-01 16:39:55 -07001724
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001725status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1726 LockedParameters::Key k(mParameters);
1727 int transform = degToTransform(degrees,
1728 mCameraFacing == CAMERA_FACING_FRONT);
1729 if (transform == -1) {
1730 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1731 __FUNCTION__, mCameraId, degrees);
1732 return BAD_VALUE;
1733 }
1734 if (transform != k.mParameters.previewTransform &&
1735 mPreviewStreamId != NO_STREAM) {
1736 mDevice->setStreamTransform(mPreviewStreamId, transform);
1737 }
1738 k.mParameters.previewTransform = transform;
1739 return OK;
1740}
1741
1742status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1743 LockedParameters::Key k(mParameters);
1744 if (enable) {
1745 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001746 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001747 }
1748
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001749 // Disabling shutter sound may not be allowed. In that case only
1750 // allow the mediaserver process to disable the sound.
1751 char value[PROPERTY_VALUE_MAX];
1752 property_get("ro.camera.sound.forced", value, "0");
1753 if (strncmp(value, "0", 2) != 0) {
1754 // Disabling shutter sound is not allowed. Deny if the current
1755 // process is not mediaserver.
1756 if (getCallingPid() != getpid()) {
1757 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1758 getCallingPid());
1759 return PERMISSION_DENIED;
1760 }
1761 }
1762
1763 k.mParameters.playShutterSound = false;
1764 return OK;
1765}
1766
1767status_t Camera2Client::commandPlayRecordingSoundL() {
1768 mCameraService->playSound(CameraService::SOUND_RECORDING);
1769 return OK;
1770}
1771
1772status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001773 ALOGV("%s: Camera %d: Starting face detection",
1774 __FUNCTION__, mCameraId);
1775 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001776 LockedParameters::Key k(mParameters);
1777 switch (k.mParameters.state) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001778 case DISCONNECTED:
1779 case STOPPED:
1780 case WAITING_FOR_PREVIEW_WINDOW:
1781 case STILL_CAPTURE:
1782 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1783 __FUNCTION__, mCameraId);
1784 return INVALID_OPERATION;
1785 case PREVIEW:
1786 case RECORD:
1787 case VIDEO_SNAPSHOT:
1788 // Good to go for starting face detect
1789 break;
1790 }
1791 // Ignoring type
1792 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1793 ALOGE("%s: Camera %d: Face detection not supported",
1794 __FUNCTION__, mCameraId);
1795 return INVALID_OPERATION;
1796 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001797 if (k.mParameters.enableFaceDetect) return OK;
1798
1799 k.mParameters.enableFaceDetect = true;
1800
1801 res = updateRequests(k.mParameters);
1802
1803 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001804}
1805
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001806status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001807 status_t res = OK;
1808 ALOGV("%s: Camera %d: Stopping face detection",
1809 __FUNCTION__, mCameraId);
1810
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001811 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001812
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001813 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001814
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001815 if (params.state == PREVIEW || params.state == RECORD ||
1816 params.state == VIDEO_SNAPSHOT) {
1817 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001818 }
1819
1820 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001821}
1822
1823status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001824 LockedParameters::Key k(mParameters);
1825 k.mParameters.enableFocusMoveMessages = enable;
1826
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001827 return OK;
1828}
1829
1830status_t Camera2Client::commandPingL() {
1831 // Always ping back if access is proper and device is alive
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001832 LockedParameters::Key k(mParameters);
1833 if (k.mParameters.state != DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001834 return OK;
1835 } else {
1836 return NO_INIT;
1837 }
1838}
1839
1840status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001841 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001842 ALOGE("%s: Camera %d: Error setting video buffer count after "
1843 "recording was started", __FUNCTION__, mCameraId);
1844 return INVALID_OPERATION;
1845 }
1846
1847 // 32 is the current upper limit on the video buffer count for BufferQueue
1848 if (count > 32) {
1849 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1850 __FUNCTION__, mCameraId, count);
1851 return BAD_VALUE;
1852 }
1853
1854 // Need to reallocate memory for heap
1855 if (mRecordingHeapCount != count) {
1856 if (mRecordingHeap != 0) {
1857 mRecordingHeap.clear();
1858 mRecordingHeap = NULL;
1859 }
1860 mRecordingHeapCount = count;
1861 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001862
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001863 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001864}
1865
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001866/** Device-related methods */
1867
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001868void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1869 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1870}
1871
1872void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1873 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1874 frameNumber, timestamp);
1875}
1876
1877void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1878 ALOGV("%s: Autofocus state now %d, last trigger %d",
1879 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001880 bool sendCompletedMessage = false;
1881 bool sendMovingMessage = false;
1882
1883 bool success = false;
1884 bool afInMotion = false;
1885 {
1886 LockedParameters::Key k(mParameters);
1887 switch (k.mParameters.focusMode) {
1888 case Parameters::FOCUS_MODE_AUTO:
1889 case Parameters::FOCUS_MODE_MACRO:
1890 // Don't send notifications upstream if they're not for the current AF
1891 // trigger. For example, if cancel was called in between, or if we
1892 // already sent a notification about this AF call.
1893 if (triggerId != k.mParameters.currentAfTriggerId) break;
1894 switch (newState) {
1895 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1896 success = true;
1897 // no break
1898 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1899 sendCompletedMessage = true;
1900 k.mParameters.currentAfTriggerId = -1;
1901 break;
1902 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1903 // Just starting focusing, ignore
1904 break;
1905 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1906 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1907 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1908 default:
1909 // Unexpected in AUTO/MACRO mode
1910 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1911 __FUNCTION__, newState);
1912 break;
1913 }
1914 break;
1915 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1916 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1917 switch (newState) {
1918 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1919 success = true;
1920 // no break
1921 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1922 // Don't send notifications upstream if they're not for
1923 // the current AF trigger. For example, if cancel was
1924 // called in between, or if we already sent a
1925 // notification about this AF call.
1926 // Send both a 'AF done' callback and a 'AF move' callback
1927 if (triggerId != k.mParameters.currentAfTriggerId) break;
1928 sendCompletedMessage = true;
1929 afInMotion = false;
1930 if (k.mParameters.enableFocusMoveMessages &&
1931 k.mParameters.afInMotion) {
1932 sendMovingMessage = true;
1933 }
1934 k.mParameters.currentAfTriggerId = -1;
1935 break;
1936 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1937 // Cancel was called, or we switched state; care if
1938 // currently moving
1939 afInMotion = false;
1940 if (k.mParameters.enableFocusMoveMessages &&
1941 k.mParameters.afInMotion) {
1942 sendMovingMessage = true;
1943 }
1944 break;
1945 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1946 // Start passive scan, inform upstream
1947 afInMotion = true;
1948 // no break
1949 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1950 // Stop passive scan, inform upstream
1951 if (k.mParameters.enableFocusMoveMessages) {
1952 sendMovingMessage = true;
1953 }
1954 break;
1955 }
1956 k.mParameters.afInMotion = afInMotion;
1957 break;
1958 case Parameters::FOCUS_MODE_EDOF:
1959 case Parameters::FOCUS_MODE_INFINITY:
1960 case Parameters::FOCUS_MODE_FIXED:
1961 default:
1962 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1963 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1964 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1965 }
1966 }
1967 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001968 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001969 Mutex::Autolock iccl(mICameraClientLock);
1970 if (mCameraClient != 0) {
1971 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1972 afInMotion ? 1 : 0, 0);
1973 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001974 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001975 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001976 Mutex::Autolock iccl(mICameraClientLock);
1977 if (mCameraClient != 0) {
1978 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1979 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001980 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001981}
1982
1983void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1984 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1985 __FUNCTION__, newState, triggerId);
1986}
1987
1988void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1989 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1990 __FUNCTION__, newState, triggerId);
1991}
1992
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001993void Camera2Client::onNewFrameAvailable() {
1994 status_t res;
1995 camera_metadata_t *frame = NULL;
1996 do {
1997 res = mDevice->getNextFrame(&frame);
1998 if (res != OK) {
1999 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
2000 __FUNCTION__, mCameraId, strerror(-res), res);
2001 return;
2002 }
2003 if (frame != NULL) {
2004 camera_metadata_entry_t entry;
2005 res = find_camera_metadata_entry(frame, ANDROID_REQUEST_FRAME_COUNT,
2006 &entry);
2007 if (res != OK) {
2008 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
2009 __FUNCTION__, mCameraId, strerror(-res), res);
2010 break;
2011 }
2012
2013 res = processFrameFaceDetect(frame);
2014 if (res != OK) break;
2015
2016 free_camera_metadata(frame);
2017 }
2018 } while (frame != NULL);
2019
2020 if (frame != NULL) {
2021 free_camera_metadata(frame);
2022 }
2023 return;
2024}
2025
2026status_t Camera2Client::processFrameFaceDetect(camera_metadata_t *frame) {
2027 status_t res;
2028 camera_metadata_entry_t entry;
2029 bool enableFaceDetect;
2030 {
2031 LockedParameters::Key k(mParameters);
2032 enableFaceDetect = k.mParameters.enableFaceDetect;
2033 }
2034 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_DETECT_MODE,
2035 &entry);
Eino-Ville Talvala76dc8da2012-08-21 16:09:31 -07002036 // TODO: Remove this check once things are more compliant. For now, assume that
2037 // if we can't find the face detect mode, then it's probably not working.
2038 if (res == NAME_NOT_FOUND) {
2039 return OK;
2040 } else if (res != OK) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002041 ALOGE("%s: Camera %d: Error reading face mode: %s (%d)",
2042 __FUNCTION__, mCameraId, strerror(-res), res);
2043 return res;
2044 }
2045 uint8_t faceDetectMode = entry.data.u8[0];
2046
2047 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
2048 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_RECTANGLES,
2049 &entry);
2050 if (res != OK) {
2051 ALOGE("%s: Camera %d: Error reading face rectangles: %s (%d)",
2052 __FUNCTION__, mCameraId, strerror(-res), res);
2053 return res;
2054 }
2055 camera_frame_metadata metadata;
2056 metadata.number_of_faces = entry.count / 4;
2057 if (metadata.number_of_faces >
2058 mDeviceInfo->maxFaces) {
2059 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
2060 __FUNCTION__, mCameraId,
2061 metadata.number_of_faces, mDeviceInfo->maxFaces);
2062 return res;
2063 }
2064 int32_t *faceRects = entry.data.i32;
2065
2066 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_SCORES,
2067 &entry);
2068 if (res != OK) {
2069 ALOGE("%s: Camera %d: Error reading face scores: %s (%d)",
2070 __FUNCTION__, mCameraId, strerror(-res), res);
2071 return res;
2072 }
2073 uint8_t *faceScores = entry.data.u8;
2074
2075 int32_t *faceLandmarks = NULL;
2076 int32_t *faceIds = NULL;
2077
2078 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2079 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_LANDMARKS,
2080 &entry);
2081 if (res != OK) {
2082 ALOGE("%s: Camera %d: Error reading face landmarks: %s (%d)",
2083 __FUNCTION__, mCameraId, strerror(-res), res);
2084 return res;
2085 }
2086 faceLandmarks = entry.data.i32;
2087
2088 res = find_camera_metadata_entry(frame, ANDROID_STATS_FACE_IDS,
2089 &entry);
2090 if (res != OK) {
2091 ALOGE("%s: Camera %d: Error reading face IDs: %s (%d)",
2092 __FUNCTION__, mCameraId, strerror(-res), res);
2093 return res;
2094 }
2095 faceIds = entry.data.i32;
2096 }
2097
2098 Vector<camera_face_t> faces;
2099 faces.setCapacity(metadata.number_of_faces);
2100
2101 for (int i = 0; i < metadata.number_of_faces; i++) {
2102 camera_face_t face;
2103
2104 face.rect[0] = arrayXToNormalized(faceRects[i*4 + 0]);
2105 face.rect[1] = arrayYToNormalized(faceRects[i*4 + 1]);
2106 face.rect[2] = arrayXToNormalized(faceRects[i*4 + 2]);
2107 face.rect[3] = arrayYToNormalized(faceRects[i*4 + 3]);
2108
2109 face.score = faceScores[i];
2110 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2111 face.id = faceIds[i];
2112 face.left_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 0]);
2113 face.left_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 1]);
2114 face.right_eye[0] = arrayXToNormalized(faceLandmarks[i*6 + 2]);
2115 face.right_eye[1] = arrayYToNormalized(faceLandmarks[i*6 + 3]);
2116 face.mouth[0] = arrayXToNormalized(faceLandmarks[i*6 + 4]);
2117 face.mouth[1] = arrayYToNormalized(faceLandmarks[i*6 + 5]);
2118 } else {
2119 face.id = 0;
2120 face.left_eye[0] = face.left_eye[1] = -2000;
2121 face.right_eye[0] = face.right_eye[1] = -2000;
2122 face.mouth[0] = face.mouth[1] = -2000;
2123 }
2124 faces.push_back(face);
2125 }
2126
2127 metadata.faces = faces.editArray();
2128 {
2129 Mutex::Autolock iccl(mICameraClientLock);
2130 if (mCameraClient != NULL) {
2131 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
2132 NULL, &metadata);
2133 }
2134 }
2135 }
2136 return OK;
2137}
2138
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002139void Camera2Client::onCallbackAvailable() {
2140 ATRACE_CALL();
2141 status_t res;
2142 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
2143
2144 int callbackHeapId;
2145 sp<Camera2Heap> callbackHeap;
2146 size_t heapIdx;
2147
2148 CpuConsumer::LockedBuffer imgBuffer;
2149 ALOGV("%s: Getting buffer", __FUNCTION__);
2150 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
2151 if (res != OK) {
2152 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
2153 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2154 return;
2155 }
2156
2157 {
2158 LockedParameters::Key k(mParameters);
2159
2160 if ( k.mParameters.state != PREVIEW && k.mParameters.state != RECORD
2161 && k.mParameters.state != VIDEO_SNAPSHOT) {
2162 ALOGV("%s: Camera %d: No longer streaming",
2163 __FUNCTION__, mCameraId);
2164 mCallbackConsumer->unlockBuffer(imgBuffer);
2165 return;
2166 }
2167
2168 if (! (k.mParameters.previewCallbackFlags &
2169 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
2170 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
2171 mCallbackConsumer->unlockBuffer(imgBuffer);
2172 return;
2173 }
2174 if ((k.mParameters.previewCallbackFlags &
2175 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
2176 !k.mParameters.previewCallbackOneShot) {
2177 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
2178 mCallbackConsumer->unlockBuffer(imgBuffer);
2179 return;
2180 }
2181
2182 if (imgBuffer.format != k.mParameters.previewFormat) {
2183 ALOGE("%s: Camera %d: Unexpected format for callback: "
2184 "%x, expected %x", __FUNCTION__, mCameraId,
2185 imgBuffer.format, k.mParameters.previewFormat);
2186 mCallbackConsumer->unlockBuffer(imgBuffer);
2187 return;
2188 }
2189
2190 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
2191 imgBuffer.format, imgBuffer.stride);
2192 size_t currentBufferSize = (mCallbackHeap == 0) ?
2193 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
2194 if (bufferSize != currentBufferSize) {
2195 mCallbackHeap.clear();
2196 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
2197 "Camera2Client::CallbackHeap");
2198 if (mCallbackHeap->mHeap->getSize() == 0) {
2199 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
2200 __FUNCTION__, mCameraId);
2201 mCallbackConsumer->unlockBuffer(imgBuffer);
2202 return;
2203 }
2204
2205 mCallbackHeapHead = 0;
2206 mCallbackHeapFree = kCallbackHeapCount;
2207 mCallbackHeapId++;
2208 }
2209
2210 if (mCallbackHeapFree == 0) {
2211 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
2212 __FUNCTION__, mCameraId);
2213 mCallbackConsumer->unlockBuffer(imgBuffer);
2214 return;
2215 }
2216 heapIdx = mCallbackHeapHead;
2217 callbackHeap = mCallbackHeap;
2218 callbackHeapId = mCallbackHeapId;
2219
2220 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
2221 mCallbackHeapFree--;
2222
2223 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
2224 // to app
2225
2226 ssize_t offset;
2227 size_t size;
2228 sp<IMemoryHeap> heap =
2229 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
2230 &size);
2231 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2232 memcpy(data, imgBuffer.data, bufferSize);
2233
2234 ALOGV("%s: Freeing buffer", __FUNCTION__);
2235 mCallbackConsumer->unlockBuffer(imgBuffer);
2236
2237 // In one-shot mode, stop sending callbacks after the first one
2238 if (k.mParameters.previewCallbackFlags &
2239 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
2240 ALOGV("%s: clearing oneshot", __FUNCTION__);
2241 k.mParameters.previewCallbackOneShot = false;
2242 }
2243 }
2244
2245 // Call outside parameter lock to allow re-entrancy from notification
2246 {
2247 Mutex::Autolock iccl(mICameraClientLock);
2248 if (mCameraClient != 0) {
2249 ALOGV("%s: Camera %d: Invoking client data callback",
2250 __FUNCTION__, mCameraId);
2251 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
2252 callbackHeap->mBuffers[heapIdx], NULL);
2253 }
2254 }
2255
2256 LockedParameters::Key k(mParameters);
2257 // Only increment free if we're still using the same heap
2258 if (mCallbackHeapId == callbackHeapId) {
2259 mCallbackHeapFree++;
2260 }
2261
2262 ALOGV("%s: exit", __FUNCTION__);
2263}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002264
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002265void Camera2Client::onCaptureAvailable() {
2266 ATRACE_CALL();
2267 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002268 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002269 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
2270
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002271 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002272 LockedParameters::Key k(mParameters);
2273 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002274
2275 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2276 if (res != OK) {
2277 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2278 __FUNCTION__, mCameraId, strerror(-res), res);
2279 return;
2280 }
2281
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002282 // TODO: Signal errors here upstream
2283 if (k.mParameters.state != STILL_CAPTURE &&
2284 k.mParameters.state != VIDEO_SNAPSHOT) {
2285 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2286 __FUNCTION__, mCameraId);
2287 mCaptureConsumer->unlockBuffer(imgBuffer);
2288 return;
2289 }
2290
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002291 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2292 ALOGE("%s: Camera %d: Unexpected format for still image: "
2293 "%x, expected %x", __FUNCTION__, mCameraId,
2294 imgBuffer.format,
2295 HAL_PIXEL_FORMAT_BLOB);
2296 mCaptureConsumer->unlockBuffer(imgBuffer);
2297 return;
2298 }
2299
2300 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002301 void* captureMemory = mCaptureHeap->mHeap->getBase();
2302 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002303 memcpy(captureMemory, imgBuffer.data, size);
2304
2305 mCaptureConsumer->unlockBuffer(imgBuffer);
2306
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002307 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002308 case STILL_CAPTURE:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002309 k.mParameters.state = STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002310 break;
2311 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002312 k.mParameters.state = RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002313 break;
2314 default:
2315 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002316 mCameraId, k.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002317 break;
2318 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002319
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002320 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002321 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002322 // Call outside parameter locks to allow re-entrancy from notification
2323 Mutex::Autolock iccl(mICameraClientLock);
2324 if (mCameraClient != 0) {
2325 mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
2326 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002327 }
2328}
2329
2330void Camera2Client::onRecordingFrameAvailable() {
2331 ATRACE_CALL();
2332 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002333 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002334 size_t heapIdx = 0;
2335 nsecs_t timestamp;
2336 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002337 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002338
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002339 BufferItemConsumer::BufferItem imgBuffer;
2340 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002341 if (res != OK) {
2342 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2343 __FUNCTION__, mCameraId, strerror(-res), res);
2344 return;
2345 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002346 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002347
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002348 mRecordingFrameCount++;
2349 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
2350
2351 // TODO: Signal errors here upstream
2352 if (k.mParameters.state != RECORD &&
2353 k.mParameters.state != VIDEO_SNAPSHOT) {
2354 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2355 "recording done",
2356 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002357 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002358 return;
2359 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002360
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002361 if (mRecordingHeap == 0) {
2362 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002363 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2364 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002365 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002366
James Dong983cf232012-08-01 16:39:55 -07002367 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002368 "Camera2Client::RecordingHeap");
2369 if (mRecordingHeap->mHeap->getSize() == 0) {
2370 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2371 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002372 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002373 return;
2374 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002375 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
2376 if (mRecordingBuffers[i].mBuf !=
2377 BufferItemConsumer::INVALID_BUFFER_SLOT) {
2378 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
2379 __FUNCTION__, mCameraId);
2380 }
2381 }
2382 mRecordingBuffers.clear();
2383 mRecordingBuffers.setCapacity(mRecordingHeapCount);
2384 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
2385
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002386 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002387 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002388 }
2389
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002390 if ( mRecordingHeapFree == 0) {
2391 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2392 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002393 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002394 return;
2395 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002396
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002397 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002398 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002399 mRecordingHeapFree--;
2400
2401 ALOGV("%s: Camera %d: Timestamp %lld",
2402 __FUNCTION__, mCameraId, timestamp);
2403
2404 ssize_t offset;
2405 size_t size;
2406 sp<IMemoryHeap> heap =
2407 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2408 &size);
2409
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002410 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2411 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002412 *((uint32_t*)data) = type;
2413 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002414 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002415 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
2416 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002417 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002418 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002419
2420 // Call outside locked parameters to allow re-entrancy from notification
2421 Mutex::Autolock iccl(mICameraClientLock);
2422 if (mCameraClient != 0) {
2423 mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002424 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002425 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002426 }
2427}
2428
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002429camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
2430 size_t minCount, size_t maxCount) {
2431 status_t res;
2432 camera_metadata_entry_t entry;
2433 res = find_camera_metadata_entry(mDevice->info(),
2434 tag,
2435 &entry);
2436 if (CC_UNLIKELY( res != OK )) {
2437 const char* tagSection = get_camera_metadata_section_name(tag);
2438 if (tagSection == NULL) tagSection = "<unknown>";
2439 const char* tagName = get_camera_metadata_tag_name(tag);
2440 if (tagName == NULL) tagName = "<unknown>";
2441
2442 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
2443 tagSection, tagName, tag, strerror(-res), res);
2444 entry.count = 0;
2445 entry.data.u8 = NULL;
2446 } else if (CC_UNLIKELY(
2447 (minCount != 0 && entry.count < minCount) ||
2448 (maxCount != 0 && entry.count > maxCount) ) ) {
2449 const char* tagSection = get_camera_metadata_section_name(tag);
2450 if (tagSection == NULL) tagSection = "<unknown>";
2451 const char* tagName = get_camera_metadata_tag_name(tag);
2452 if (tagName == NULL) tagName = "<unknown>";
2453 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2454 "Expected between %d and %d values, but got %d values",
2455 tagSection, tagName, tag, minCount, maxCount, entry.count);
2456 entry.count = 0;
2457 entry.data.u8 = NULL;
2458 }
2459
2460 return entry;
2461}
2462
2463/** Utility methods */
2464
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002465status_t Camera2Client::buildDeviceInfo() {
2466 if (mDeviceInfo != NULL) {
2467 delete mDeviceInfo;
2468 }
2469 DeviceInfo *deviceInfo = new DeviceInfo;
2470 mDeviceInfo = deviceInfo;
2471
2472 camera_metadata_entry_t activeArraySize =
2473 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2474 if (!activeArraySize.count) return NO_INIT;
2475 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2476 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2477
2478 camera_metadata_entry_t availableFaceDetectModes =
2479 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2480 if (!availableFaceDetectModes.count) return NO_INIT;
2481
2482 deviceInfo->bestFaceDetectMode =
2483 ANDROID_STATS_FACE_DETECTION_OFF;
2484 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2485 switch (availableFaceDetectModes.data.u8[i]) {
2486 case ANDROID_STATS_FACE_DETECTION_OFF:
2487 break;
2488 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2489 if (deviceInfo->bestFaceDetectMode !=
2490 ANDROID_STATS_FACE_DETECTION_FULL) {
2491 deviceInfo->bestFaceDetectMode =
2492 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2493 }
2494 break;
2495 case ANDROID_STATS_FACE_DETECTION_FULL:
2496 deviceInfo->bestFaceDetectMode =
2497 ANDROID_STATS_FACE_DETECTION_FULL;
2498 break;
2499 default:
2500 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2501 __FUNCTION__, mCameraId,
2502 availableFaceDetectModes.data.u8[i]);
2503 return NO_INIT;
2504 }
2505 }
2506
2507 camera_metadata_entry_t maxFacesDetected =
2508 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2509 if (!maxFacesDetected.count) return NO_INIT;
2510
2511 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2512
2513 return OK;
2514}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002515
2516status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002517 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002518 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002519
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002520 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002521 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002522
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002523 camera_metadata_entry_t availableProcessedSizes =
2524 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2525 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002526
2527 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002528 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2529 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2530 k.mParameters.videoWidth = k.mParameters.previewWidth;
2531 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002532
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002533 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2534 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002535 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2536 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002537 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002538 {
2539 String8 supportedPreviewSizes;
2540 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2541 if (i != 0) supportedPreviewSizes += ",";
2542 supportedPreviewSizes += String8::format("%dx%d",
2543 availableProcessedSizes.data.i32[i],
2544 availableProcessedSizes.data.i32[i+1]);
2545 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002546 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002547 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002548 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002549 supportedPreviewSizes);
2550 }
2551
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002552 camera_metadata_entry_t availableFpsRanges =
2553 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2554 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002555
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002556 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2557 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002558
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002559 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2560 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002561 k.mParameters.previewFpsRange[0],
2562 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002563
2564 {
2565 String8 supportedPreviewFpsRange;
2566 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2567 if (i != 0) supportedPreviewFpsRange += ",";
2568 supportedPreviewFpsRange += String8::format("(%d,%d)",
2569 availableFpsRanges.data.i32[i],
2570 availableFpsRanges.data.i32[i+1]);
2571 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002572 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002573 supportedPreviewFpsRange);
2574 }
2575
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002576 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002577 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002578 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002579
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002580 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002581 mCameraFacing == CAMERA_FACING_FRONT);
2582
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002583 camera_metadata_entry_t availableFormats =
2584 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2585
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002586 {
2587 String8 supportedPreviewFormats;
2588 bool addComma = false;
2589 for (size_t i=0; i < availableFormats.count; i++) {
2590 if (addComma) supportedPreviewFormats += ",";
2591 addComma = true;
2592 switch (availableFormats.data.i32[i]) {
2593 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002594 supportedPreviewFormats +=
2595 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002596 break;
2597 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002598 supportedPreviewFormats +=
2599 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002600 break;
2601 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002602 supportedPreviewFormats +=
2603 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002604 break;
2605 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002606 supportedPreviewFormats +=
2607 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002608 break;
2609 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002610 supportedPreviewFormats +=
2611 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002612 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002613 case HAL_PIXEL_FORMAT_RGBA_8888:
2614 supportedPreviewFormats +=
2615 CameraParameters::PIXEL_FORMAT_RGBA8888;
2616 break;
2617 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002618 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002619 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002620 addComma = false;
2621 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002622
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002623 default:
2624 ALOGW("%s: Camera %d: Unknown preview format: %x",
2625 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2626 addComma = false;
2627 break;
2628 }
2629 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002630 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002631 supportedPreviewFormats);
2632 }
2633
2634 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2635 // still have to do something sane for them
2636
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002637 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002638 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002639
2640 {
2641 String8 supportedPreviewFrameRates;
2642 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2643 if (i != 0) supportedPreviewFrameRates += ",";
2644 supportedPreviewFrameRates += String8::format("%d",
2645 availableFpsRanges.data.i32[i]);
2646 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002647 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002648 supportedPreviewFrameRates);
2649 }
2650
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002651 camera_metadata_entry_t availableJpegSizes =
2652 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2653 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002654
2655 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002656 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2657 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002658
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002659 params.setPictureSize(k.mParameters.pictureWidth,
2660 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002661
2662 {
2663 String8 supportedPictureSizes;
2664 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2665 if (i != 0) supportedPictureSizes += ",";
2666 supportedPictureSizes += String8::format("%dx%d",
2667 availableJpegSizes.data.i32[i],
2668 availableJpegSizes.data.i32[i+1]);
2669 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002670 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002671 supportedPictureSizes);
2672 }
2673
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002674 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2675 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2676 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002677
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002678 camera_metadata_entry_t availableJpegThumbnailSizes =
2679 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2680 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002681
2682 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002683 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2684 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002685
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002686 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002687 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002688 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002689 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002690
2691 {
2692 String8 supportedJpegThumbSizes;
2693 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2694 if (i != 0) supportedJpegThumbSizes += ",";
2695 supportedJpegThumbSizes += String8::format("%dx%d",
2696 availableJpegThumbnailSizes.data.i32[i],
2697 availableJpegThumbnailSizes.data.i32[i+1]);
2698 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002699 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002700 supportedJpegThumbSizes);
2701 }
2702
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002703 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002704 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002705 k.mParameters.jpegThumbQuality);
2706 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002707 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002708 k.mParameters.jpegQuality);
2709 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002710 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002711 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002712
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002713 k.mParameters.gpsEnabled = false;
2714 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002715 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002716
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002717 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002718 params.set(CameraParameters::KEY_WHITE_BALANCE,
2719 CameraParameters::WHITE_BALANCE_AUTO);
2720
2721 camera_metadata_entry_t availableWhiteBalanceModes =
2722 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002723 {
2724 String8 supportedWhiteBalance;
2725 bool addComma = false;
2726 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2727 if (addComma) supportedWhiteBalance += ",";
2728 addComma = true;
2729 switch (availableWhiteBalanceModes.data.u8[i]) {
2730 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002731 supportedWhiteBalance +=
2732 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002733 break;
2734 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002735 supportedWhiteBalance +=
2736 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002737 break;
2738 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002739 supportedWhiteBalance +=
2740 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002741 break;
2742 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002743 supportedWhiteBalance +=
2744 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002745 break;
2746 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002747 supportedWhiteBalance +=
2748 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002749 break;
2750 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002751 supportedWhiteBalance +=
2752 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002753 break;
2754 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002755 supportedWhiteBalance +=
2756 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002757 break;
2758 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002759 supportedWhiteBalance +=
2760 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002761 break;
2762 // Skipping values not mappable to v1 API
2763 case ANDROID_CONTROL_AWB_OFF:
2764 addComma = false;
2765 break;
2766 default:
2767 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2768 __FUNCTION__, mCameraId,
2769 availableWhiteBalanceModes.data.u8[i]);
2770 addComma = false;
2771 break;
2772 }
2773 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002774 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002775 supportedWhiteBalance);
2776 }
2777
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002778 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002779 params.set(CameraParameters::KEY_EFFECT,
2780 CameraParameters::EFFECT_NONE);
2781
2782 camera_metadata_entry_t availableEffects =
2783 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2784 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002785 {
2786 String8 supportedEffects;
2787 bool addComma = false;
2788 for (size_t i=0; i < availableEffects.count; i++) {
2789 if (addComma) supportedEffects += ",";
2790 addComma = true;
2791 switch (availableEffects.data.u8[i]) {
2792 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002793 supportedEffects +=
2794 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002795 break;
2796 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002797 supportedEffects +=
2798 CameraParameters::EFFECT_MONO;
2799 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002800 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002801 supportedEffects +=
2802 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002803 break;
2804 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002805 supportedEffects +=
2806 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002807 break;
2808 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002809 supportedEffects +=
2810 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002811 break;
2812 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002813 supportedEffects +=
2814 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002815 break;
2816 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002817 supportedEffects +=
2818 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002819 break;
2820 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002821 supportedEffects +=
2822 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002823 break;
2824 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002825 supportedEffects +=
2826 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002827 break;
2828 default:
2829 ALOGW("%s: Camera %d: Unknown effect value: %d",
2830 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2831 addComma = false;
2832 break;
2833 }
2834 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002835 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002836 }
2837
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002838 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002839 params.set(CameraParameters::KEY_ANTIBANDING,
2840 CameraParameters::ANTIBANDING_AUTO);
2841
2842 camera_metadata_entry_t availableAntibandingModes =
2843 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2844 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002845 {
2846 String8 supportedAntibanding;
2847 bool addComma = false;
2848 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2849 if (addComma) supportedAntibanding += ",";
2850 addComma = true;
2851 switch (availableAntibandingModes.data.u8[i]) {
2852 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002853 supportedAntibanding +=
2854 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002855 break;
2856 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002857 supportedAntibanding +=
2858 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002859 break;
2860 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002861 supportedAntibanding +=
2862 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002863 break;
2864 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002865 supportedAntibanding +=
2866 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002867 break;
2868 default:
2869 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2870 __FUNCTION__, mCameraId,
2871 availableAntibandingModes.data.u8[i]);
2872 addComma = false;
2873 break;
2874 }
2875 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002876 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002877 supportedAntibanding);
2878 }
2879
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002880 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002881 params.set(CameraParameters::KEY_SCENE_MODE,
2882 CameraParameters::SCENE_MODE_AUTO);
2883
2884 camera_metadata_entry_t availableSceneModes =
2885 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2886 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002887 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002888 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002889 bool addComma = true;
2890 bool noSceneModes = false;
2891 for (size_t i=0; i < availableSceneModes.count; i++) {
2892 if (addComma) supportedSceneModes += ",";
2893 addComma = true;
2894 switch (availableSceneModes.data.u8[i]) {
2895 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2896 noSceneModes = true;
2897 break;
2898 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2899 // Not in old API
2900 addComma = false;
2901 break;
2902 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002903 supportedSceneModes +=
2904 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002905 break;
2906 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002907 supportedSceneModes +=
2908 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002909 break;
2910 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002911 supportedSceneModes +=
2912 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002913 break;
2914 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002915 supportedSceneModes +=
2916 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002917 break;
2918 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002919 supportedSceneModes +=
2920 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002921 break;
2922 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002923 supportedSceneModes +=
2924 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002925 break;
2926 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002927 supportedSceneModes +=
2928 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002929 break;
2930 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002931 supportedSceneModes +=
2932 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002933 break;
2934 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002935 supportedSceneModes +=
2936 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002937 break;
2938 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002939 supportedSceneModes +=
2940 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002941 break;
2942 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002943 supportedSceneModes +=
2944 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002945 break;
2946 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002947 supportedSceneModes +=
2948 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002949 break;
2950 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002951 supportedSceneModes +=
2952 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002953 break;
2954 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002955 supportedSceneModes +=
2956 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002957 break;
2958 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002959 supportedSceneModes +=
2960 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002961 break;
2962 default:
2963 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002964 __FUNCTION__, mCameraId,
2965 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002966 addComma = false;
2967 break;
2968 }
2969 }
2970 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002971 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002972 supportedSceneModes);
2973 }
2974 }
2975
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002976 camera_metadata_entry_t flashAvailable =
2977 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2978 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002979
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002980 camera_metadata_entry_t availableAeModes =
2981 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2982 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002983
2984 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002985 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002986 params.set(CameraParameters::KEY_FLASH_MODE,
2987 CameraParameters::FLASH_MODE_AUTO);
2988
2989 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2990 supportedFlashModes = supportedFlashModes +
2991 "," + CameraParameters::FLASH_MODE_AUTO +
2992 "," + CameraParameters::FLASH_MODE_ON +
2993 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002994 for (size_t i=0; i < availableAeModes.count; i++) {
2995 if (availableAeModes.data.u8[i] ==
2996 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002997 supportedFlashModes = supportedFlashModes + "," +
2998 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002999 break;
3000 }
3001 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003002 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003003 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003004 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003005 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003006 params.set(CameraParameters::KEY_FLASH_MODE,
3007 CameraParameters::FLASH_MODE_OFF);
3008 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
3009 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003010 }
3011
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003012 camera_metadata_entry_t minFocusDistance =
3013 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
3014 if (!minFocusDistance.count) return NO_INIT;
3015
3016 camera_metadata_entry_t availableAfModes =
3017 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
3018 if (!availableAfModes.count) return NO_INIT;
3019
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003020 if (minFocusDistance.data.f[0] == 0) {
3021 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003022 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003023 params.set(CameraParameters::KEY_FOCUS_MODE,
3024 CameraParameters::FOCUS_MODE_FIXED);
3025 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
3026 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003027 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003028 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003029 params.set(CameraParameters::KEY_FOCUS_MODE,
3030 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003031 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003032 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003033
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003034 for (size_t i=0; i < availableAfModes.count; i++) {
3035 if (addComma) supportedFocusModes += ",";
3036 addComma = true;
3037 switch (availableAfModes.data.u8[i]) {
3038 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003039 supportedFocusModes +=
3040 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003041 break;
3042 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003043 supportedFocusModes +=
3044 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003045 break;
3046 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003047 supportedFocusModes +=
3048 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003049 break;
3050 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003051 supportedFocusModes +=
3052 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003053 break;
3054 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003055 supportedFocusModes +=
3056 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003057 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003058 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003059 case ANDROID_CONTROL_AF_OFF:
3060 addComma = false;
3061 break;
3062 default:
3063 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
3064 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
3065 addComma = false;
3066 break;
3067 }
3068 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003069 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003070 supportedFocusModes);
3071 }
3072
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003073 camera_metadata_entry_t max3aRegions =
3074 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
3075 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003076
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003077 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003078 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003079 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003080 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003081 k.mParameters.focusingAreas.clear();
3082 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003083
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003084 camera_metadata_entry_t availableFocalLengths =
3085 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
3086 if (!availableFocalLengths.count) return NO_INIT;
3087
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003088 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003089 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003090
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003091 camera_metadata_entry_t sensorSize =
3092 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
3093 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003094
3095 // The fields of view here assume infinity focus, maximum wide angle
3096 float horizFov = 180 / M_PI *
3097 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
3098 float vertFov = 180 / M_PI *
3099 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003100 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
3101 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003102
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003103 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003104 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003105 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003106
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003107 camera_metadata_entry_t exposureCompensationRange =
3108 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
3109 if (!exposureCompensationRange.count) return NO_INIT;
3110
3111 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003112 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003113 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003114 exposureCompensationRange.data.i32[0]);
3115
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003116 camera_metadata_entry_t exposureCompensationStep =
3117 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
3118 if (!exposureCompensationStep.count) return NO_INIT;
3119
3120 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07003121 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003122 exposureCompensationStep.data.r[0].denominator);
3123
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003124 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003125 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
3126 CameraParameters::FALSE);
3127 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
3128 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003129
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003130 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003131 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
3132 CameraParameters::FALSE);
3133 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
3134 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003135
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003136 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003137 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003138 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003139 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003140 "(0,0,0,0,0)");
3141
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003142 k.mParameters.zoom = 0;
3143 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003144 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003145
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003146 camera_metadata_entry_t maxDigitalZoom =
3147 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
3148 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003149
3150 {
3151 String8 zoomRatios;
3152 float zoom = 1.f;
3153 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003154 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003155 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003156 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003157 if (addComma) zoomRatios += ",";
3158 addComma = true;
3159 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
3160 zoom += zoomIncrement;
3161 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003162 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003163 }
3164
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003165 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
3166 CameraParameters::TRUE);
3167 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
3168 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003169
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003170 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003171 "Infinity,Infinity,Infinity");
3172
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003173 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003174 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003175 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003176 0);
3177
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003178 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003179 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003180
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003181 params.set(CameraParameters::KEY_RECORDING_HINT,
3182 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003183
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003184 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
3185 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003186
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003187 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
3188 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003189
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003190 camera_metadata_entry_t availableVideoStabilizationModes =
3191 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
3192 if (!availableVideoStabilizationModes.count) return NO_INIT;
3193
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003194 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003195 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3196 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003197 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003198 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3199 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003200 }
3201
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003202 // Set up initial state for non-Camera.Parameters state variables
3203
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003204 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003205 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003206 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003207
3208 k.mParameters.enableFocusMoveMessages = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003209 k.mParameters.afTriggerCounter = 0;
3210 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003211
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003212 k.mParameters.previewCallbackFlags = 0;
3213
3214 k.mParameters.state = STOPPED;
3215
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003216 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003217
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003218 return OK;
3219}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003220
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003221status_t Camera2Client::updateRequests(const Parameters &params) {
3222 status_t res;
3223
3224 res = updatePreviewRequest(params);
3225 if (res != OK) {
3226 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
3227 __FUNCTION__, mCameraId, strerror(-res), res);
3228 return res;
3229 }
3230 res = updateCaptureRequest(params);
3231 if (res != OK) {
3232 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
3233 __FUNCTION__, mCameraId, strerror(-res), res);
3234 return res;
3235 }
3236
3237 res = updateRecordingRequest(params);
3238 if (res != OK) {
3239 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
3240 __FUNCTION__, mCameraId, strerror(-res), res);
3241 return res;
3242 }
3243
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003244 if (params.state == PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003245 res = mDevice->setStreamingRequest(mPreviewRequest);
3246 if (res != OK) {
3247 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
3248 __FUNCTION__, mCameraId, strerror(-res), res);
3249 return res;
3250 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003251 } else if (params.state == RECORD || params.state == VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003252 res = mDevice->setStreamingRequest(mRecordingRequest);
3253 if (res != OK) {
3254 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
3255 __FUNCTION__, mCameraId, strerror(-res), res);
3256 return res;
3257 }
3258 }
3259 return res;
3260}
3261
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003262status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003263 ATRACE_CALL();
3264 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003265
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003266 if (mPreviewStreamId != NO_STREAM) {
3267 // Check if stream parameters have to change
3268 uint32_t currentWidth, currentHeight;
3269 res = mDevice->getStreamInfo(mPreviewStreamId,
3270 &currentWidth, &currentHeight, 0);
3271 if (res != OK) {
3272 ALOGE("%s: Camera %d: Error querying preview stream info: "
3273 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3274 return res;
3275 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003276 if (currentWidth != (uint32_t)params.previewWidth ||
3277 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07003278 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
3279 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003280 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003281 res = mDevice->waitUntilDrained();
3282 if (res != OK) {
3283 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
3284 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3285 return res;
3286 }
3287 res = mDevice->deleteStream(mPreviewStreamId);
3288 if (res != OK) {
3289 ALOGE("%s: Camera %d: Unable to delete old output stream "
3290 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3291 strerror(-res), res);
3292 return res;
3293 }
3294 mPreviewStreamId = NO_STREAM;
3295 }
3296 }
3297
3298 if (mPreviewStreamId == NO_STREAM) {
3299 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003300 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003301 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3302 &mPreviewStreamId);
3303 if (res != OK) {
3304 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3305 __FUNCTION__, mCameraId, strerror(-res), res);
3306 return res;
3307 }
3308 }
3309
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003310 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003311 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003312 if (res != OK) {
3313 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3314 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3315 return res;
3316 }
3317
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003318 return OK;
3319}
3320
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003321status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003322 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003323 status_t res;
3324 if (mPreviewRequest == NULL) {
3325 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3326 &mPreviewRequest);
3327 if (res != OK) {
3328 ALOGE("%s: Camera %d: Unable to create default preview request: "
3329 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3330 return res;
3331 }
3332 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003333
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003334 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003335 if (res != OK) {
3336 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3337 "request: %s (%d)", __FUNCTION__, mCameraId,
3338 strerror(-res), res);
3339 return res;
3340 }
3341
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003342 return OK;
3343}
3344
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003345status_t Camera2Client::updateCallbackStream(const Parameters &params) {
3346 status_t res;
3347
3348 if (mCallbackConsumer == 0) {
3349 // Create CPU buffer queue endpoint
3350 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
3351 mCallbackWaiter = new CallbackWaiter(this);
3352 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
3353 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
3354 mCallbackWindow = new SurfaceTextureClient(
3355 mCallbackConsumer->getProducerInterface());
3356 }
3357
3358 if (mCallbackStreamId != NO_STREAM) {
3359 // Check if stream parameters have to change
3360 uint32_t currentWidth, currentHeight, currentFormat;
3361 res = mDevice->getStreamInfo(mCallbackStreamId,
3362 &currentWidth, &currentHeight, &currentFormat);
3363 if (res != OK) {
3364 ALOGE("%s: Camera %d: Error querying callback output stream info: "
3365 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3366 return res;
3367 }
3368 if (currentWidth != (uint32_t)params.previewWidth ||
3369 currentHeight != (uint32_t)params.previewHeight ||
3370 currentFormat != (uint32_t)params.previewFormat) {
3371 // Since size should only change while preview is not running,
3372 // assuming that all existing use of old callback stream is
3373 // completed.
3374 res = mDevice->deleteStream(mCallbackStreamId);
3375 if (res != OK) {
3376 ALOGE("%s: Camera %d: Unable to delete old output stream "
3377 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
3378 strerror(-res), res);
3379 return res;
3380 }
3381 mCallbackStreamId = NO_STREAM;
3382 }
3383 }
3384
3385 if (mCallbackStreamId == NO_STREAM) {
3386 ALOGV("Creating callback stream: %d %d format 0x%x",
3387 params.previewWidth, params.previewHeight,
3388 params.previewFormat);
3389 res = mDevice->createStream(mCallbackWindow,
3390 params.previewWidth, params.previewHeight,
3391 params.previewFormat, 0, &mCallbackStreamId);
3392 if (res != OK) {
3393 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
3394 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3395 return res;
3396 }
3397 }
3398
3399 return OK;
3400}
3401
3402
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003403status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003404 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003405 status_t res;
3406 // Find out buffer size for JPEG
3407 camera_metadata_entry_t maxJpegSize =
3408 staticInfo(ANDROID_JPEG_MAX_SIZE);
3409 if (maxJpegSize.count == 0) {
3410 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3411 __FUNCTION__, mCameraId);
3412 return INVALID_OPERATION;
3413 }
3414
3415 if (mCaptureConsumer == 0) {
3416 // Create CPU buffer queue endpoint
3417 mCaptureConsumer = new CpuConsumer(1);
3418 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3419 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3420 mCaptureWindow = new SurfaceTextureClient(
3421 mCaptureConsumer->getProducerInterface());
3422 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003423 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3424 "Camera2Client::CaptureHeap");
3425 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003426 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3427 __FUNCTION__, mCameraId);
3428 return NO_MEMORY;
3429 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003430 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003431
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003432 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003433 // Check if stream parameters have to change
3434 uint32_t currentWidth, currentHeight;
3435 res = mDevice->getStreamInfo(mCaptureStreamId,
3436 &currentWidth, &currentHeight, 0);
3437 if (res != OK) {
3438 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3439 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3440 return res;
3441 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003442 if (currentWidth != (uint32_t)params.pictureWidth ||
3443 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003444 res = mDevice->deleteStream(mCaptureStreamId);
3445 if (res != OK) {
3446 ALOGE("%s: Camera %d: Unable to delete old output stream "
3447 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3448 strerror(-res), res);
3449 return res;
3450 }
3451 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003452 }
3453 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003454
3455 if (mCaptureStreamId == NO_STREAM) {
3456 // Create stream for HAL production
3457 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003458 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003459 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3460 &mCaptureStreamId);
3461 if (res != OK) {
3462 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3463 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3464 return res;
3465 }
3466
3467 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003468 return OK;
3469}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003470
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003471status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003472 ATRACE_CALL();
3473 status_t res;
3474 if (mCaptureRequest == NULL) {
3475 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3476 &mCaptureRequest);
3477 if (res != OK) {
3478 ALOGE("%s: Camera %d: Unable to create default still image request:"
3479 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3480 return res;
3481 }
3482 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003483
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003484 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003485 if (res != OK) {
3486 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3487 "request: %s (%d)", __FUNCTION__, mCameraId,
3488 strerror(-res), res);
3489 return res;
3490 }
3491
3492 res = updateEntry(mCaptureRequest,
3493 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003494 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003495 if (res != OK) return res;
3496 res = updateEntry(mCaptureRequest,
3497 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003498 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003499 if (res != OK) return res;
3500 res = updateEntry(mCaptureRequest,
3501 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003502 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003503 if (res != OK) return res;
3504 res = updateEntry(mCaptureRequest,
3505 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003506 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003507 if (res != OK) return res;
3508
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003509 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003510 res = updateEntry(mCaptureRequest,
3511 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003512 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003513 if (res != OK) return res;
3514 res = updateEntry(mCaptureRequest,
3515 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003516 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003517 if (res != OK) return res;
3518 res = updateEntry(mCaptureRequest,
3519 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003520 params.gpsProcessingMethod.string(),
3521 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003522 if (res != OK) return res;
3523 } else {
3524 res = deleteEntry(mCaptureRequest,
3525 ANDROID_JPEG_GPS_COORDINATES);
3526 if (res != OK) return res;
3527 res = deleteEntry(mCaptureRequest,
3528 ANDROID_JPEG_GPS_TIMESTAMP);
3529 if (res != OK) return res;
3530 res = deleteEntry(mCaptureRequest,
3531 ANDROID_JPEG_GPS_PROCESSING_METHOD);
3532 if (res != OK) return res;
3533 }
3534
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003535 return OK;
3536}
3537
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003538status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003539 ATRACE_CALL();
3540 status_t res;
3541 if (mRecordingRequest == NULL) {
3542 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3543 &mRecordingRequest);
3544 if (res != OK) {
3545 ALOGE("%s: Camera %d: Unable to create default recording request:"
3546 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3547 return res;
3548 }
3549 }
3550
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003551 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003552 if (res != OK) {
3553 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3554 "request: %s (%d)", __FUNCTION__, mCameraId,
3555 strerror(-res), res);
3556 return res;
3557 }
3558
3559 return OK;
3560}
3561
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003562status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003563 status_t res;
3564
3565 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003566 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
3567 // always acquire and free a buffer when the heap is full; otherwise the consumer
3568 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07003569 mRecordingConsumer = new BufferItemConsumer(
3570 GRALLOC_USAGE_HW_VIDEO_ENCODER,
3571 mRecordingHeapCount + 1,
3572 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003573 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3574 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3575 mRecordingWindow = new SurfaceTextureClient(
3576 mRecordingConsumer->getProducerInterface());
3577 // Allocate memory later, since we don't know buffer size until receipt
3578 }
3579
3580 if (mRecordingStreamId != NO_STREAM) {
3581 // Check if stream parameters have to change
3582 uint32_t currentWidth, currentHeight;
3583 res = mDevice->getStreamInfo(mRecordingStreamId,
3584 &currentWidth, &currentHeight, 0);
3585 if (res != OK) {
3586 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3587 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3588 return res;
3589 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003590 if (currentWidth != (uint32_t)params.videoWidth ||
3591 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003592 // TODO: Should wait to be sure previous recording has finished
3593 res = mDevice->deleteStream(mRecordingStreamId);
3594 if (res != OK) {
3595 ALOGE("%s: Camera %d: Unable to delete old output stream "
3596 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3597 strerror(-res), res);
3598 return res;
3599 }
3600 mRecordingStreamId = NO_STREAM;
3601 }
3602 }
3603
3604 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003605 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003606 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003607 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003608 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003609 if (res != OK) {
3610 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3611 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3612 return res;
3613 }
3614 }
3615
3616 return OK;
3617}
3618
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003619status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
3620 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003621 ATRACE_CALL();
3622 status_t res;
3623 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003624 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003625 if (res != OK) return res;
3626
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003627 uint8_t wbMode = params.autoWhiteBalanceLock ?
3628 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003629 res = updateEntry(request,
3630 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3631 if (res != OK) return res;
3632 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003633 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003634 if (res != OK) return res;
3635 res = updateEntry(request,
3636 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003637 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003638 if (res != OK) return res;
3639
3640 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003641 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003642 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3643 res = updateEntry(request,
3644 ANDROID_CONTROL_MODE, &controlMode, 1);
3645 if (res != OK) return res;
3646 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3647 res = updateEntry(request,
3648 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003649 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003650 if (res != OK) return res;
3651 }
3652
3653 uint8_t flashMode = ANDROID_FLASH_OFF;
3654 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003655 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003656 case Parameters::FLASH_MODE_OFF:
3657 aeMode = ANDROID_CONTROL_AE_ON; break;
3658 case Parameters::FLASH_MODE_AUTO:
3659 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3660 case Parameters::FLASH_MODE_ON:
3661 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3662 case Parameters::FLASH_MODE_TORCH:
3663 aeMode = ANDROID_CONTROL_AE_ON;
3664 flashMode = ANDROID_FLASH_TORCH;
3665 break;
3666 case Parameters::FLASH_MODE_RED_EYE:
3667 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3668 default:
3669 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003670 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003671 return BAD_VALUE;
3672 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003673 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003674
3675 res = updateEntry(request,
3676 ANDROID_FLASH_MODE, &flashMode, 1);
3677 if (res != OK) return res;
3678 res = updateEntry(request,
3679 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3680 if (res != OK) return res;
3681
3682 float focusDistance = 0; // infinity focus in diopters
3683 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003684 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003685 case Parameters::FOCUS_MODE_AUTO:
3686 case Parameters::FOCUS_MODE_MACRO:
3687 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3688 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3689 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003690 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003691 break;
3692 case Parameters::FOCUS_MODE_INFINITY:
3693 case Parameters::FOCUS_MODE_FIXED:
3694 focusMode = ANDROID_CONTROL_AF_OFF;
3695 break;
3696 default:
3697 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003698 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003699 return BAD_VALUE;
3700 }
3701 res = updateEntry(request,
3702 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3703 if (res != OK) return res;
3704 res = updateEntry(request,
3705 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3706 if (res != OK) return res;
3707
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003708 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003709 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3710 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003711 focusingAreas[i + 0] = params.focusingAreas[i].left;
3712 focusingAreas[i + 1] = params.focusingAreas[i].top;
3713 focusingAreas[i + 2] = params.focusingAreas[i].right;
3714 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3715 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003716 }
3717 res = updateEntry(request,
3718 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3719 if (res != OK) return res;
3720 delete[] focusingAreas;
3721
3722 res = updateEntry(request,
3723 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003724 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003725 if (res != OK) return res;
3726
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003727 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003728 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3729 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003730 meteringAreas[i + 0] = params.meteringAreas[i].left;
3731 meteringAreas[i + 1] = params.meteringAreas[i].top;
3732 meteringAreas[i + 2] = params.meteringAreas[i].right;
3733 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3734 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003735 }
3736 res = updateEntry(request,
3737 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3738 if (res != OK) return res;
3739
3740 res = updateEntry(request,
3741 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3742 if (res != OK) return res;
3743 delete[] meteringAreas;
3744
3745 // Need to convert zoom index into a crop rectangle. The rectangle is
3746 // chosen to maximize its area on the sensor
3747
3748 camera_metadata_entry_t maxDigitalZoom =
3749 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3750 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3751 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003752 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003753
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003754 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003755 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003756 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003757 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003758 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003759 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003760 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003761 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003762 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003763 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003764 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3765 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003766
3767 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3768 res = updateEntry(request,
3769 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3770 if (res != OK) return res;
3771
3772 // TODO: Decide how to map recordingHint, or whether just to ignore it
3773
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003774 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003775 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3776 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3777 res = updateEntry(request,
3778 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3779 &vstabMode, 1);
3780 if (res != OK) return res;
3781
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003782 uint8_t faceDetectMode = params.enableFaceDetect ?
3783 mDeviceInfo->bestFaceDetectMode :
3784 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
3785 res = updateEntry(request,
3786 ANDROID_STATS_FACE_DETECT_MODE,
3787 &faceDetectMode, 1);
3788 if (res != OK) return res;
3789
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003790 return OK;
3791}
3792
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003793int Camera2Client::arrayXToNormalized(int width) const {
3794 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3795}
3796
3797int Camera2Client::arrayYToNormalized(int height) const {
3798 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3799}
3800
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003801status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3802 uint32_t tag, const void *data, size_t data_count) {
3803 camera_metadata_entry_t entry;
3804 status_t res;
3805 res = find_camera_metadata_entry(buffer, tag, &entry);
3806 if (res == NAME_NOT_FOUND) {
3807 res = add_camera_metadata_entry(buffer,
3808 tag, data, data_count);
3809 } else if (res == OK) {
3810 res = update_camera_metadata_entry(buffer,
3811 entry.index, data, data_count, NULL);
3812 }
3813
3814 if (res != OK) {
3815 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3816 __FUNCTION__, get_camera_metadata_section_name(tag),
3817 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3818 }
3819 return res;
3820}
3821
3822status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3823 camera_metadata_entry_t entry;
3824 status_t res;
3825 res = find_camera_metadata_entry(buffer, tag, &entry);
3826 if (res == NAME_NOT_FOUND) {
3827 return OK;
3828 } else if (res != OK) {
3829 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3830 __FUNCTION__,
3831 get_camera_metadata_section_name(tag),
3832 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3833 return res;
3834 }
3835 res = delete_camera_metadata_entry(buffer, entry.index);
3836 if (res != OK) {
3837 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3838 __FUNCTION__,
3839 get_camera_metadata_section_name(tag),
3840 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3841 }
3842 return res;
3843}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003844
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003845int Camera2Client::formatStringToEnum(const char *format) {
3846 return
3847 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3848 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3849 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3850 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3851 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3852 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3853 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3854 HAL_PIXEL_FORMAT_YV12 : // YV12
3855 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3856 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3857 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3858 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3859 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3860 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3861 -1;
3862}
3863
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003864const char* Camera2Client::formatEnumToString(int format) {
3865 const char *fmt;
3866 switch(format) {
3867 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3868 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3869 break;
3870 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3871 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3872 break;
3873 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3874 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3875 break;
3876 case HAL_PIXEL_FORMAT_YV12: // YV12
3877 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3878 break;
3879 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3880 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3881 break;
3882 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3883 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3884 break;
3885 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3886 ALOGW("Raw sensor preview format requested.");
3887 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3888 break;
3889 default:
3890 ALOGE("%s: Unknown preview format: %x",
3891 __FUNCTION__, format);
3892 fmt = NULL;
3893 break;
3894 }
3895 return fmt;
3896}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003897
3898int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3899 return
3900 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3901 ANDROID_CONTROL_AWB_AUTO :
3902 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3903 ANDROID_CONTROL_AWB_INCANDESCENT :
3904 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3905 ANDROID_CONTROL_AWB_FLUORESCENT :
3906 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3907 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3908 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3909 ANDROID_CONTROL_AWB_DAYLIGHT :
3910 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3911 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3912 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3913 ANDROID_CONTROL_AWB_TWILIGHT :
3914 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3915 ANDROID_CONTROL_AWB_SHADE :
3916 -1;
3917}
3918
3919int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3920 return
3921 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3922 ANDROID_CONTROL_EFFECT_OFF :
3923 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3924 ANDROID_CONTROL_EFFECT_MONO :
3925 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3926 ANDROID_CONTROL_EFFECT_NEGATIVE :
3927 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3928 ANDROID_CONTROL_EFFECT_SOLARIZE :
3929 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3930 ANDROID_CONTROL_EFFECT_SEPIA :
3931 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3932 ANDROID_CONTROL_EFFECT_POSTERIZE :
3933 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3934 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3935 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3936 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3937 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3938 ANDROID_CONTROL_EFFECT_AQUA :
3939 -1;
3940}
3941
3942int Camera2Client::abModeStringToEnum(const char *abMode) {
3943 return
3944 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3945 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3946 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3947 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3948 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3949 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3950 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3951 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3952 -1;
3953}
3954
3955int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3956 return
3957 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3958 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3959 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3960 ANDROID_CONTROL_SCENE_MODE_ACTION :
3961 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3962 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3963 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3964 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3965 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3966 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3967 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3968 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3969 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3970 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3971 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3972 ANDROID_CONTROL_SCENE_MODE_BEACH :
3973 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3974 ANDROID_CONTROL_SCENE_MODE_SNOW :
3975 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3976 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3977 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3978 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3979 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3980 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3981 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3982 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3983 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3984 ANDROID_CONTROL_SCENE_MODE_PARTY :
3985 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3986 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3987 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3988 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3989 -1;
3990}
3991
3992Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3993 const char *flashMode) {
3994 return
3995 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3996 Parameters::FLASH_MODE_OFF :
3997 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3998 Parameters::FLASH_MODE_AUTO :
3999 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
4000 Parameters::FLASH_MODE_ON :
4001 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
4002 Parameters::FLASH_MODE_RED_EYE :
4003 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
4004 Parameters::FLASH_MODE_TORCH :
4005 Parameters::FLASH_MODE_INVALID;
4006}
4007
4008Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
4009 const char *focusMode) {
4010 return
4011 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
4012 Parameters::FOCUS_MODE_AUTO :
4013 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
4014 Parameters::FOCUS_MODE_INFINITY :
4015 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
4016 Parameters::FOCUS_MODE_MACRO :
4017 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
4018 Parameters::FOCUS_MODE_FIXED :
4019 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
4020 Parameters::FOCUS_MODE_EDOF :
4021 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
4022 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
4023 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
4024 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
4025 Parameters::FOCUS_MODE_INVALID;
4026}
4027
4028status_t Camera2Client::parseAreas(const char *areasCStr,
4029 Vector<Parameters::Area> *areas) {
4030 static const size_t NUM_FIELDS = 5;
4031 areas->clear();
4032 if (areasCStr == NULL) {
4033 // If no key exists, use default (0,0,0,0,0)
4034 areas->push();
4035 return OK;
4036 }
4037 String8 areasStr(areasCStr);
4038 ssize_t areaStart = areasStr.find("(", 0) + 1;
4039 while (areaStart != 0) {
4040 const char* area = areasStr.string() + areaStart;
4041 char *numEnd;
4042 int vals[NUM_FIELDS];
4043 for (size_t i = 0; i < NUM_FIELDS; i++) {
4044 errno = 0;
4045 vals[i] = strtol(area, &numEnd, 10);
4046 if (errno || numEnd == area) return BAD_VALUE;
4047 area = numEnd + 1;
4048 }
4049 areas->push(Parameters::Area(
4050 vals[0], vals[1], vals[2], vals[3], vals[4]) );
4051 areaStart = areasStr.find("(", areaStart) + 1;
4052 }
4053 return OK;
4054}
4055
4056status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
4057 size_t maxRegions) {
4058 // Definition of valid area can be found in
4059 // include/camera/CameraParameters.h
4060 if (areas.size() == 0) return BAD_VALUE;
4061 if (areas.size() == 1) {
4062 if (areas[0].left == 0 &&
4063 areas[0].top == 0 &&
4064 areas[0].right == 0 &&
4065 areas[0].bottom == 0 &&
4066 areas[0].weight == 0) {
4067 // Single (0,0,0,0,0) entry is always valid (== driver decides)
4068 return OK;
4069 }
4070 }
4071 if (areas.size() > maxRegions) {
4072 ALOGE("%s: Too many areas requested: %d",
4073 __FUNCTION__, areas.size());
4074 return BAD_VALUE;
4075 }
4076
4077 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
4078 a != areas.end(); a++) {
4079 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
4080 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
4081 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
4082 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
4083 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
4084 if (a->left >= a->right) return BAD_VALUE;
4085 if (a->top >= a->bottom) return BAD_VALUE;
4086 }
4087 return OK;
4088}
4089
4090bool Camera2Client::boolFromString(const char *boolStr) {
4091 return !boolStr ? false :
4092 !strcmp(boolStr, CameraParameters::TRUE) ? true :
4093 false;
4094}
4095
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07004096int Camera2Client::degToTransform(int degrees, bool mirror) {
4097 if (!mirror) {
4098 if (degrees == 0) return 0;
4099 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
4100 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
4101 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
4102 } else { // Do mirror (horizontal flip)
4103 if (degrees == 0) { // FLIP_H and ROT_0
4104 return HAL_TRANSFORM_FLIP_H;
4105 } else if (degrees == 90) { // FLIP_H and ROT_90
4106 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
4107 } else if (degrees == 180) { // FLIP_H and ROT_180
4108 return HAL_TRANSFORM_FLIP_V;
4109 } else if (degrees == 270) { // FLIP_H and ROT_270
4110 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
4111 }
4112 }
4113 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
4114 return -1;
4115}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07004116
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07004117size_t Camera2Client::calculateBufferSize(int width, int height,
4118 int format, int stride) {
4119 switch (format) {
4120 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
4121 return width * height * 2;
4122 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
4123 return width * height * 3 / 2;
4124 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
4125 return width * height * 2;
4126 case HAL_PIXEL_FORMAT_YV12: { // YV12
4127 size_t ySize = stride * height;
4128 size_t uvStride = (stride / 2 + 0xF) & ~0x10;
4129 size_t uvSize = uvStride * height / 2;
4130 return ySize + uvSize * 2;
4131 }
4132 case HAL_PIXEL_FORMAT_RGB_565:
4133 return width * height * 2;
4134 case HAL_PIXEL_FORMAT_RGBA_8888:
4135 return width * height * 4;
4136 case HAL_PIXEL_FORMAT_RAW_SENSOR:
4137 return width * height * 2;
4138 default:
4139 ALOGE("%s: Unknown preview format: %x",
4140 __FUNCTION__, format);
4141 return 0;
4142 }
4143}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07004144
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07004145} // namespace android